// Support back to Vista
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#include <sdkddkver.h>

// Use WRL to define a classic COM class
#define __WRL_CLASSIC_COM__
#include <wrl.h>

#include <windows.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <olectl.h>
#include <strsafe.h>

#define DDWM_UPDATEWINDOW (WM_USER+3)

static HINSTANCE hModule;
static CLIPFORMAT cfDropDescription;
static CLIPFORMAT cfDragWindow;

#define CLASS_GUID "{BEA218D2-6950-497B-9434-61683EC065FE}"
static const LPCWSTR CLASS_SUBKEY = L"Software\\Classes\\CLSID\\" CLASS_GUID;
static const LPCWSTR DRAG_MESSAGE = L"Open with %1";

using namespace Microsoft::WRL;

HRESULT FilenameListCchLengthA(LPCSTR pszSource, size_t cchMax, size_t *pcchLength, size_t *pcchCount) {
    HRESULT hr = S_OK;
    size_t count = 0;
    size_t length = 0;

    while (pszSource && pszSource[0]) {
        size_t oneLength;
        hr = StringCchLengthA(pszSource, cchMax - length, &oneLength);
        if (FAILED(hr)) {
            return hr;
        }
        count += 1;
        length += oneLength + (strchr(pszSource, ' ') ? 3 : 1);
        pszSource = &pszSource[oneLength + 1];
    }

    *pcchCount = count;
    *pcchLength = length;
    return hr;
}

HRESULT FilenameListCchLengthW(LPCWSTR pszSource, size_t cchMax, size_t *pcchLength, size_t *pcchCount) {
    HRESULT hr = S_OK;
    size_t count = 0;
    size_t length = 0;

    while (pszSource && pszSource[0]) {
        size_t oneLength;
        hr = StringCchLengthW(pszSource, cchMax - length, &oneLength);
        if (FAILED(hr)) {
            return hr;
        }
        count += 1;
        length += oneLength + (wcschr(pszSource, ' ') ? 3 : 1);
        pszSource = &pszSource[oneLength + 1];
    }

    *pcchCount = count;
    *pcchLength = length;
    return hr;
}

HRESULT FilenameListCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, LPCSTR pszSource, LPCSTR pszSeparator) {
    HRESULT hr = S_OK;
    size_t count = 0;
    size_t length = 0;

    while (pszSource[0]) {
        STRSAFE_LPSTR newDest;

        hr = StringCchCopyExA(pszDest, cchDest, pszSource, &newDest, &cchDest, 0);
        if (FAILED(hr)) {
            return hr;
        }
        pszSource += (newDest - pszDest) + 1;
        pszDest = PathQuoteSpacesA(pszDest) ? newDest + 2 : newDest;

        if (pszSource[0]) {
            hr = StringCchCopyExA(pszDest, cchDest, pszSeparator, &newDest, &cchDest, 0);
            if (FAILED(hr)) {
                return hr;
            }
            pszDest = newDest;
        }
    }

    return hr;
}

HRESULT FilenameListCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, LPCWSTR pszSource, LPCWSTR pszSeparator) {
    HRESULT hr = S_OK;
    size_t count = 0;
    size_t length = 0;

    while (pszSource[0]) {
        STRSAFE_LPWSTR newDest;

        hr = StringCchCopyExW(pszDest, cchDest, pszSource, &newDest, &cchDest, 0);
        if (FAILED(hr)) {
            return hr;
        }
        pszSource += (newDest - pszDest) + 1;
        pszDest = PathQuoteSpacesW(pszDest) ? newDest + 2 : newDest;

        if (pszSource[0]) {
            hr = StringCchCopyExW(pszDest, cchDest, pszSeparator, &newDest, &cchDest, 0);
            if (FAILED(hr)) {
                return hr;
            }
            pszDest = newDest;
        }
    }

    return hr;
}

class DECLSPEC_UUID(CLASS_GUID) PyShellExt : public RuntimeClass<
    RuntimeClassFlags<ClassicCom>,
    IDropTarget,
    IPersistFile
>
{
    LPOLESTR target, target_dir;
    DWORD target_mode;

    IDataObject *data_obj;

public:
    PyShellExt() : target(NULL), target_dir(NULL), target_mode(0), data_obj(NULL) {
        OutputDebugString(L"PyShellExt::PyShellExt");
    }

    ~PyShellExt() {
        if (target) {
            CoTaskMemFree(target);
        }
        if (target_dir) {
            CoTaskMemFree(target_dir);
        }
        if (data_obj) {
            data_obj->Release();
        }
    }

private:
    HRESULT UpdateDropDescription(IDataObject *pDataObj) {
        STGMEDIUM medium;
        FORMATETC fmt = {
            cfDropDescription,
            NULL,
            DVASPECT_CONTENT,
            -1,
            TYMED_HGLOBAL
        };

        auto hr = pDataObj->GetData(&fmt, &medium);
        if (FAILED(hr)) {
            OutputDebugString(L"PyShellExt::UpdateDropDescription - failed to get DROPDESCRIPTION format");
            return hr;
        }
        if (!medium.hGlobal) {
            OutputDebugString(L"PyShellExt::UpdateDropDescription - DROPDESCRIPTION format had NULL hGlobal");
            ReleaseStgMedium(&medium);
            return E_FAIL;
        }
        auto dd = (DROPDESCRIPTION*)GlobalLock(medium.hGlobal);
        if (!dd) {
            OutputDebugString(L"PyShellExt::UpdateDropDescription - failed to lock DROPDESCRIPTION hGlobal");
            ReleaseStgMedium(&medium);
            return E_FAIL;
        }
        StringCchCopy(dd->szMessage, sizeof(dd->szMessage) / sizeof(dd->szMessage[0]), DRAG_MESSAGE);
        StringCchCopy(dd->szInsert, sizeof(dd->szInsert) / sizeof(dd->szInsert[0]), PathFindFileNameW(target));
        dd->type = DROPIMAGE_MOVE;

        GlobalUnlock(medium.hGlobal);
        ReleaseStgMedium(&medium);

        return S_OK;
    }

    HRESULT GetDragWindow(IDataObject *pDataObj, HWND *phWnd) {
        HRESULT hr;
        HWND *pMem;
        STGMEDIUM medium;
        FORMATETC fmt = {
            cfDragWindow,
            NULL,
            DVASPECT_CONTENT,
            -1,
            TYMED_HGLOBAL
        };

        hr = pDataObj->GetData(&fmt, &medium);
        if (FAILED(hr)) {
            OutputDebugString(L"PyShellExt::GetDragWindow - failed to get DragWindow format");
            return hr;
        }
        if (!medium.hGlobal) {
            OutputDebugString(L"PyShellExt::GetDragWindow - DragWindow format had NULL hGlobal");
            ReleaseStgMedium(&medium);
            return E_FAIL;
        }

        pMem = (HWND*)GlobalLock(medium.hGlobal);
        if (!pMem) {
            OutputDebugString(L"PyShellExt::GetDragWindow - failed to lock DragWindow hGlobal");
            ReleaseStgMedium(&medium);
            return E_FAIL;
        }

        *phWnd = *pMem;

        GlobalUnlock(medium.hGlobal);
        ReleaseStgMedium(&medium);

        return S_OK;
    }

    HRESULT GetArguments(IDataObject *pDataObj, LPCWSTR *pArguments) {
        HRESULT hr;
        DROPFILES *pdropfiles;

        STGMEDIUM medium;
        FORMATETC fmt = {
            CF_HDROP,
            NULL,
            DVASPECT_CONTENT,
            -1,
            TYMED_HGLOBAL
        };

        hr = pDataObj->GetData(&fmt, &medium);
        if (FAILED(hr)) {
            OutputDebugString(L"PyShellExt::GetArguments - failed to get CF_HDROP format");
            return hr;
        }
        if (!medium.hGlobal) {
            OutputDebugString(L"PyShellExt::GetArguments - CF_HDROP format had NULL hGlobal");
            ReleaseStgMedium(&medium);
            return E_FAIL;
        }

        pdropfiles = (DROPFILES*)GlobalLock(medium.hGlobal);
        if (!pdropfiles) {
            OutputDebugString(L"PyShellExt::GetArguments - failed to lock CF_HDROP hGlobal");
            ReleaseStgMedium(&medium);
            return E_FAIL;
        }

        if (pdropfiles->fWide) {
            LPCWSTR files = (LPCWSTR)((char*)pdropfiles + pdropfiles->pFiles);
            size_t len, count;
            hr = FilenameListCchLengthW(files, 32767, &len, &count);
            if (SUCCEEDED(hr)) {
                LPWSTR args = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * (len + 1));
                if (args) {
                    hr = FilenameListCchCopyW(args, 32767, files, L" ");
                    if (SUCCEEDED(hr)) {
                        *pArguments = args;
                    } else {
                        CoTaskMemFree(args);
                    }
                } else {
                    hr = E_OUTOFMEMORY;
                }
            }
        } else {
            LPCSTR files = (LPCSTR)((char*)pdropfiles + pdropfiles->pFiles);
            size_t len, count;
            hr = FilenameListCchLengthA(files, 32767, &len, &count);
            if (SUCCEEDED(hr)) {
                LPSTR temp = (LPSTR)CoTaskMemAlloc(sizeof(CHAR) * (len + 1));
                if (temp) {
                    hr = FilenameListCchCopyA(temp, 32767, files, " ");
                    if (SUCCEEDED(hr)) {
                        int wlen = MultiByteToWideChar(CP_ACP, 0, temp, (int)len, NULL, 0);
                        if (wlen) {
                            LPWSTR args = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * (wlen + 1));
                            if (MultiByteToWideChar(CP_ACP, 0, temp, (int)len, args, wlen + 1)) {
                                *pArguments = args;
                            } else {
                                OutputDebugString(L"PyShellExt::GetArguments - failed to convert multi-byte to wide-char path");
                                CoTaskMemFree(args);
                                hr = E_FAIL;
                            }
                        } else {
                            OutputDebugString(L"PyShellExt::GetArguments - failed to get length of wide-char path");
                            hr = E_FAIL;
                        }
                    }
                    CoTaskMemFree(temp);
                } else {
                    hr = E_OUTOFMEMORY;
                }
            }
        }

        GlobalUnlock(medium.hGlobal);
        ReleaseStgMedium(&medium);

        return hr;
    }

    HRESULT NotifyDragWindow(HWND hwnd) {
        LRESULT res;

        if (!hwnd) {
            return S_FALSE;
        }

        res = SendMessage(hwnd, DDWM_UPDATEWINDOW, 0, NULL);

        if (res) {
            OutputDebugString(L"PyShellExt::NotifyDragWindow - failed to post DDWM_UPDATEWINDOW");
            return E_FAIL;
        }

        return S_OK;
    }

public:
    // IDropTarget implementation

    STDMETHODIMP DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) {
        HWND hwnd;

        OutputDebugString(L"PyShellExt::DragEnter");

        pDataObj->AddRef();
        data_obj = pDataObj;

        *pdwEffect = DROPEFFECT_MOVE;

        if (FAILED(UpdateDropDescription(data_obj))) {
            OutputDebugString(L"PyShellExt::DragEnter - failed to update drop description");
        }
        if (FAILED(GetDragWindow(data_obj, &hwnd))) {
            OutputDebugString(L"PyShellExt::DragEnter - failed to get drag window");
        }
        if (FAILED(NotifyDragWindow(hwnd))) {
            OutputDebugString(L"PyShellExt::DragEnter - failed to notify drag window");
        }

        return S_OK;
    }

    STDMETHODIMP DragLeave() {
        return S_OK;
    }

    STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) {
        return S_OK;
    }

    STDMETHODIMP Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) {
        LPCWSTR args;

        OutputDebugString(L"PyShellExt::Drop");
        *pdwEffect = DROPEFFECT_NONE;

        if (pDataObj != data_obj) {
            OutputDebugString(L"PyShellExt::Drop - unexpected data object");
            return E_FAIL;
        }

        data_obj->Release();
        data_obj = NULL;

        if (SUCCEEDED(GetArguments(pDataObj, &args))) {
            OutputDebugString(args);
            ShellExecute(NULL, NULL, target, args, target_dir, SW_NORMAL);

            CoTaskMemFree((LPVOID)args);
        } else {
            OutputDebugString(L"PyShellExt::Drop - failed to get launch arguments");
        }

        return S_OK;
    }

    // IPersistFile implementation

    STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName) {
        HRESULT hr;
        size_t len;

        if (!ppszFileName) {
            return E_POINTER;
        }

        hr = StringCchLength(target, STRSAFE_MAX_CCH - 1, &len);
        if (FAILED(hr)) {
            return E_FAIL;
        }

        *ppszFileName = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) * (len + 1));
        if (!*ppszFileName) {
            return E_OUTOFMEMORY;
        }

        hr = StringCchCopy(*ppszFileName, len + 1, target);
        if (FAILED(hr)) {
            CoTaskMemFree(*ppszFileName);
            *ppszFileName = NULL;
            return E_FAIL;
        }

        return S_OK;
    }

    STDMETHODIMP IsDirty() {
        return S_FALSE;
    }

    STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode) {
        HRESULT hr;
        size_t len;

        OutputDebugString(L"PyShellExt::Load");
        OutputDebugString(pszFileName);

        hr = StringCchLength(pszFileName, STRSAFE_MAX_CCH - 1, &len);
        if (FAILED(hr)) {
            OutputDebugString(L"PyShellExt::Load - failed to get string length");
            return hr;
        }

        if (target) {
            CoTaskMemFree(target);
        }
        if (target_dir) {
            CoTaskMemFree(target_dir);
        }

        target = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) * (len + 1));
        if (!target) {
            OutputDebugString(L"PyShellExt::Load - E_OUTOFMEMORY");
            return E_OUTOFMEMORY;
        }
        target_dir = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) * (len + 1));
        if (!target_dir) {
            OutputDebugString(L"PyShellExt::Load - E_OUTOFMEMORY");
            return E_OUTOFMEMORY;
        }

        hr = StringCchCopy(target, len + 1, pszFileName);
        if (FAILED(hr)) {
            OutputDebugString(L"PyShellExt::Load - failed to copy string");
            return hr;
        }

        hr = StringCchCopy(target_dir, len + 1, pszFileName);
        if (FAILED(hr)) {
            OutputDebugString(L"PyShellExt::Load - failed to copy string");
            return hr;
        }
        if (!PathRemoveFileSpecW(target_dir)) {
            OutputDebugStringW(L"PyShellExt::Load - failed to remove filespec from target");
            return E_FAIL;
        }

        OutputDebugString(target);
        target_mode = dwMode;
        OutputDebugString(L"PyShellExt::Load - S_OK");
        return S_OK;
    }

    STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember) {
        return E_NOTIMPL;
    }

    STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName) {
        return E_NOTIMPL;
    }

    STDMETHODIMP GetClassID(CLSID *pClassID) {
        *pClassID = __uuidof(PyShellExt);
        return S_OK;
    }
};

CoCreatableClass(PyShellExt);

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, _COM_Outptr_ void** ppv) {
    return Module<InProc>::GetModule().GetClassObject(rclsid, riid, ppv);
}

STDAPI DllCanUnloadNow() {
    return Module<InProc>::GetModule().Terminate() ? S_OK : S_FALSE;
}

STDAPI DllRegisterServer() {
    LONG res;
    SECURITY_ATTRIBUTES secattr = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
    LPSECURITY_ATTRIBUTES psecattr = NULL;
    HKEY key, ipsKey;
    WCHAR modname[MAX_PATH];
    DWORD modname_len;

    OutputDebugString(L"PyShellExt::DllRegisterServer");
    if (!hModule) {
        OutputDebugString(L"PyShellExt::DllRegisterServer - module handle was not set");
        return SELFREG_E_CLASS;
    }
    modname_len = GetModuleFileName(hModule, modname, MAX_PATH);
    if (modname_len == 0 ||
        (modname_len == MAX_PATH && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
        OutputDebugString(L"PyShellExt::DllRegisterServer - failed to get module file name");
        return SELFREG_E_CLASS;
    }

    DWORD disp;
    res = RegCreateKeyEx(HKEY_LOCAL_MACHINE, CLASS_SUBKEY, 0, NULL, 0,
        KEY_ALL_ACCESS, psecattr, &key, &disp);
    if (res == ERROR_ACCESS_DENIED) {
        OutputDebugString(L"PyShellExt::DllRegisterServer - failed to write per-machine registration. Attempting per-user instead.");
        res = RegCreateKeyEx(HKEY_CURRENT_USER, CLASS_SUBKEY, 0, NULL, 0,
            KEY_ALL_ACCESS, psecattr, &key, &disp);
    }
    if (res != ERROR_SUCCESS) {
        OutputDebugString(L"PyShellExt::DllRegisterServer - failed to create class key");
        return SELFREG_E_CLASS;
    }

    res = RegCreateKeyEx(key, L"InProcServer32", 0, NULL, 0,
        KEY_ALL_ACCESS, psecattr, &ipsKey, NULL);
    if (res != ERROR_SUCCESS) {
        RegCloseKey(key);
        OutputDebugString(L"PyShellExt::DllRegisterServer - failed to create InProcServer32 key");
        return SELFREG_E_CLASS;
    }

    res = RegSetValueEx(ipsKey, NULL, 0,
        REG_SZ, (LPBYTE)modname, modname_len * sizeof(modname[0]));

    if (res != ERROR_SUCCESS) {
        RegCloseKey(ipsKey);
        RegCloseKey(key);
        OutputDebugString(L"PyShellExt::DllRegisterServer - failed to set server path");
        return SELFREG_E_CLASS;
    }

    res = RegSetValueEx(ipsKey, L"ThreadingModel", 0,
        REG_SZ, (LPBYTE)(L"Apartment"), sizeof(L"Apartment"));

    RegCloseKey(ipsKey);
    RegCloseKey(key);
    if (res != ERROR_SUCCESS) {
        OutputDebugString(L"PyShellExt::DllRegisterServer - failed to set threading model");
        return SELFREG_E_CLASS;
    }

    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);

    OutputDebugString(L"PyShellExt::DllRegisterServer - S_OK");
    return S_OK;
}

STDAPI DllUnregisterServer() {
    LONG res_lm, res_cu;

    res_lm = RegDeleteTree(HKEY_LOCAL_MACHINE, CLASS_SUBKEY);
    if (res_lm != ERROR_SUCCESS && res_lm != ERROR_FILE_NOT_FOUND) {
        OutputDebugString(L"PyShellExt::DllUnregisterServer - failed to delete per-machine registration");
        return SELFREG_E_CLASS;
    }

    res_cu = RegDeleteTree(HKEY_CURRENT_USER, CLASS_SUBKEY);
    if (res_cu != ERROR_SUCCESS && res_cu != ERROR_FILE_NOT_FOUND) {
        OutputDebugString(L"PyShellExt::DllUnregisterServer - failed to delete per-user registration");
        return SELFREG_E_CLASS;
    }

    if (res_lm == ERROR_FILE_NOT_FOUND && res_cu == ERROR_FILE_NOT_FOUND) {
        OutputDebugString(L"PyShellExt::DllUnregisterServer - extension was not registered");
        return SELFREG_E_CLASS;
    }

    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);

    OutputDebugString(L"PyShellExt::DllUnregisterServer - S_OK");
    return S_OK;
}

STDAPI_(BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*) {
    if (reason == DLL_PROCESS_ATTACH) {
        hModule = hinst;

        cfDropDescription = RegisterClipboardFormat(CFSTR_DROPDESCRIPTION);
        if (!cfDropDescription) {
            OutputDebugString(L"PyShellExt::DllMain - failed to get CFSTR_DROPDESCRIPTION format");
        }
        cfDragWindow = RegisterClipboardFormat(L"DragWindow");
        if (!cfDragWindow) {
            OutputDebugString(L"PyShellExt::DllMain - failed to get DragWindow format");
        }

        DisableThreadLibraryCalls(hinst);
    }
    return TRUE;
}