[SHELLEXT][MYDOCS][INF] Add mydocs.dll and .mydocs file extension (#2624)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Wed, 22 Apr 2020 10:34:15 +0000 (19:34 +0900)
committerGitHub <noreply@github.com>
Wed, 22 Apr 2020 10:34:15 +0000 (19:34 +0900)
I found "SendTo My Documents" is realized by .mydocs filename extension in WinXP/2k3. To implement this, I will add mydocs.dll file. CORE-12562

15 files changed:
dll/shellext/CMakeLists.txt
dll/shellext/mydocs/CMakeLists.txt [new file with mode: 0644]
dll/shellext/mydocs/CMyDocsDropHandler.cpp [new file with mode: 0644]
dll/shellext/mydocs/CMyDocsDropHandler.hpp [new file with mode: 0644]
dll/shellext/mydocs/lang/en-US.rc [new file with mode: 0644]
dll/shellext/mydocs/mydocs.cpp [new file with mode: 0644]
dll/shellext/mydocs/mydocs.rc [new file with mode: 0644]
dll/shellext/mydocs/mydocs.spec [new file with mode: 0644]
dll/shellext/mydocs/mydocs_version.h [new file with mode: 0644]
dll/shellext/mydocs/mydocs_version.rc [new file with mode: 0644]
dll/shellext/mydocs/precomp.hpp [new file with mode: 0644]
dll/shellext/mydocs/res/mydocs.rgs [new file with mode: 0644]
dll/shellext/mydocs/resource.h [new file with mode: 0644]
media/inf/syssetup.inf
sdk/include/reactos/shlguid_undoc.h

index 4baed6e..8d00531 100644 (file)
@@ -5,6 +5,7 @@ add_subdirectory(deskadp)
 add_subdirectory(deskmon)
 add_subdirectory(devcpux)
 add_subdirectory(fontext)
+add_subdirectory(mydocs)
 add_subdirectory(netplwiz)
 add_subdirectory(netshell)
 add_subdirectory(ntobjshex)
diff --git a/dll/shellext/mydocs/CMakeLists.txt b/dll/shellext/mydocs/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0c9649c
--- /dev/null
@@ -0,0 +1,35 @@
+set_cpp(WITH_RUNTIME)
+spec2def(mydocs.dll mydocs.spec)
+
+add_definitions(
+    -D_WINE
+    -D_ATL_NO_EXCEPTIONS)
+
+if(NOT MSVC)
+    # HACK: this should be enabled globally!
+    add_compile_flags_language("-std=c++11" "CXX")
+endif()
+
+include_directories(
+    ${REACTOS_SOURCE_DIR}/sdk/lib/atl
+    ${REACTOS_SOURCE_DIR})
+
+file(GLOB_RECURSE mydocs_rc_deps res/*.*)
+add_rc_deps(mydocs.rc ${mydocs_rc_deps})
+
+list(APPEND SOURCE
+    CMyDocsDropHandler.cpp
+    mydocs.cpp
+    precomp.hpp)
+
+add_library(mydocs MODULE
+    ${SOURCE}
+    mydocs.rc
+    ${CMAKE_CURRENT_BINARY_DIR}/mydocs.def)
+
+set_module_type(mydocs win32dll UNICODE)
+target_link_libraries(mydocs uuid wine)
+add_delay_importlibs(mydocs ole32 oleaut32)
+add_importlibs(mydocs advapi32 shell32 user32 comctl32 shlwapi msvcrt kernel32 ntdll)
+add_pch(mydocs precomp.hpp SOURCE)
+add_cd_file(TARGET mydocs DESTINATION reactos/system32 FOR all)
diff --git a/dll/shellext/mydocs/CMyDocsDropHandler.cpp b/dll/shellext/mydocs/CMyDocsDropHandler.cpp
new file mode 100644 (file)
index 0000000..c21be89
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * PROJECT:     mydocs
+ * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
+ * PURPOSE:     MyDocs implementation
+ * COPYRIGHT:   Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
+ */
+
+#include "precomp.hpp"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mydocs);
+
+static CLIPFORMAT g_cfHIDA = 0;
+
+CMyDocsDropHandler::CMyDocsDropHandler()
+{
+    InterlockedIncrement(&g_ModuleRefCnt);
+}
+
+CMyDocsDropHandler::~CMyDocsDropHandler()
+{
+    InterlockedDecrement(&g_ModuleRefCnt);
+}
+
+// IDropTarget
+STDMETHODIMP
+CMyDocsDropHandler::DragEnter(IDataObject *pDataObject, DWORD dwKeyState,
+                                POINTL pt, DWORD *pdwEffect)
+{
+    TRACE("(%p)\n", this);
+
+    *pdwEffect &= DROPEFFECT_COPY; // Copy only
+
+    return S_OK;
+}
+
+STDMETHODIMP
+CMyDocsDropHandler::DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
+{
+    TRACE("(%p)\n", this);
+
+    *pdwEffect &= DROPEFFECT_COPY; // Copy only
+
+    return S_OK;
+}
+
+STDMETHODIMP CMyDocsDropHandler::DragLeave()
+{
+    TRACE("(%p)\n", this);
+    return S_OK;
+}
+
+STDMETHODIMP
+CMyDocsDropHandler::Drop(IDataObject *pDataObject, DWORD dwKeyState,
+                         POINTL pt, DWORD *pdwEffect)
+{
+    TRACE("(%p)\n", this);
+
+    if (!pDataObject)
+    {
+        ERR("pDataObject is NULL\n");
+        *pdwEffect = 0;
+        DragLeave();
+        return E_POINTER;
+    }
+
+    CComPtr<IShellFolder> pDesktop;
+    HRESULT hr = SHGetDesktopFolder(&pDesktop);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    // get the clipboard format
+    if (g_cfHIDA == 0)
+        g_cfHIDA = ::RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
+
+    // Retrieve an HIDA (handle of IDA)
+    STGMEDIUM medium;
+    FORMATETC fmt = { g_cfHIDA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+    hr = pDataObject->GetData(&fmt, &medium);
+    if (FAILED_UNEXPECTEDLY(hr))
+    {
+        *pdwEffect = 0;
+        DragLeave();
+        return E_FAIL;
+    }
+
+    // lock HIDA
+    LPIDA pida = reinterpret_cast<LPIDA>(GlobalLock(medium.hGlobal));
+    UINT iItem, cItems = pida->cidl;
+
+    // get the path of "My Documents"
+    WCHAR szzDir[MAX_PATH + 1];
+    SHGetSpecialFolderPathW(NULL, szzDir, CSIDL_PERSONAL, FALSE);
+    szzDir[lstrlenW(szzDir) + 1] = 0; // ends with double NULs
+
+    // for all source items
+    CStringW strSrcList;
+    WCHAR szSrc[MAX_PATH];
+    const BYTE *pb = reinterpret_cast<BYTE *>(pida);
+    PCIDLIST_ABSOLUTE pidlParent = reinterpret_cast<PCIDLIST_ABSOLUTE>(pb + pida->aoffset[0]);
+    for (iItem = 0; iItem < cItems; ++iItem)
+    {
+        // query source pidl
+        PCITEMID_CHILD pidlChild = reinterpret_cast<PCITEMID_CHILD>(pb + pida->aoffset[iItem + 1]);
+        CComHeapPtr<ITEMIDLIST> pidl(ILCombine(pidlParent, pidlChild));
+
+        // can get path?
+        szSrc[0] = 0;
+        if (!SHGetPathFromIDListW(pidl, szSrc))
+        {
+            // try to retrieve path from desktop
+            STRRET strret;
+            hr = pDesktop->GetDisplayNameOf(pidl, SHGDN_INFOLDER, &strret);
+            if (FAILED_UNEXPECTEDLY(hr))
+                break;
+            hr = StrRetToBufW(&strret, pidl, szSrc, _countof(szSrc));
+            if (FAILED_UNEXPECTEDLY(hr))
+                break;
+            if (!PathFileExistsW(szSrc))
+                break;
+        }
+
+        if (iItem > 0)
+            strSrcList += L'|'; // separator is '|'
+        strSrcList += szSrc;
+    }
+
+    // unlock HIDA
+    GlobalUnlock(medium.hGlobal);
+
+    if (iItem != cItems)
+    {
+        // source not found
+        CStringW strText;
+        strText.Format(IDS_NOSRCFILEFOUND, szSrc[0] ? szSrc : L"(null)");
+        MessageBoxW(NULL, strText, NULL, MB_ICONERROR);
+
+        *pdwEffect = 0;
+        DragLeave();
+        return E_FAIL;
+    }
+
+    strSrcList += L"||"; // double separators
+
+    // lock the buffer
+    LPWSTR pszzSrcList = strSrcList.GetBuffer();
+
+    // convert every separator to a NUL
+    INT cch = strSrcList.GetLength();
+    for (INT i = 0; i < cch; ++i)
+    {
+        if (pszzSrcList[i] == L'|')
+            pszzSrcList[i] = L'\0';
+    }
+
+    // copy them
+    SHFILEOPSTRUCTW fileop = { NULL };
+    fileop.wFunc = FO_COPY;
+    fileop.pFrom = pszzSrcList;
+    fileop.pTo = szzDir;
+    fileop.fFlags = FOF_ALLOWUNDO | FOF_FILESONLY | FOF_MULTIDESTFILES | FOF_NOCONFIRMMKDIR;
+    SHFileOperationW(&fileop);
+
+    // unlock buffer
+    strSrcList.ReleaseBuffer();
+
+    DragLeave();
+    return hr;
+}
+
+// IPersistFile
+STDMETHODIMP CMyDocsDropHandler::GetCurFile(LPOLESTR *ppszFileName)
+{
+    FIXME("(%p)\n", this);
+    return E_NOTIMPL;
+}
+
+STDMETHODIMP CMyDocsDropHandler::IsDirty()
+{
+    FIXME("(%p)\n", this);
+    return E_NOTIMPL;
+}
+
+STDMETHODIMP CMyDocsDropHandler::Load(LPCOLESTR pszFileName, DWORD dwMode)
+{
+    return S_OK;
+}
+
+STDMETHODIMP CMyDocsDropHandler::Save(LPCOLESTR pszFileName, BOOL fRemember)
+{
+    FIXME("(%p)\n", this);
+    return E_NOTIMPL;
+}
+
+STDMETHODIMP CMyDocsDropHandler::SaveCompleted(LPCOLESTR pszFileName)
+{
+    FIXME("(%p)\n", this);
+    return E_NOTIMPL;
+}
+
+// IPersist
+STDMETHODIMP CMyDocsDropHandler::GetClassID(CLSID * lpClassId)
+{
+    TRACE("(%p)\n", this);
+
+    if (!lpClassId)
+    {
+        ERR("lpClassId is NULL\n");
+        return E_POINTER;
+    }
+
+    *lpClassId = CLSID_MyDocsDropHandler;
+
+    return S_OK;
+}
diff --git a/dll/shellext/mydocs/CMyDocsDropHandler.hpp b/dll/shellext/mydocs/CMyDocsDropHandler.hpp
new file mode 100644 (file)
index 0000000..f9993a8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * PROJECT:     mydocs
+ * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
+ * PURPOSE:     MyDocs implementation
+ * COPYRIGHT:   Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
+ */
+
+#pragma once
+
+#include "resource.h"
+
+class CMyDocsDropHandler :
+    public CComCoClass<CMyDocsDropHandler, &CLSID_MyDocsDropHandler>,
+    public CComObjectRootEx<CComMultiThreadModelNoCS>,
+    public IDropTarget,
+    public IPersistFile
+{
+public:
+    CMyDocsDropHandler();
+    ~CMyDocsDropHandler();
+
+    // IDropTarget
+    STDMETHODIMP DragEnter(IDataObject *pDataObject, DWORD dwKeyState,
+                           POINTL pt, DWORD *pdwEffect);
+    STDMETHODIMP DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+    STDMETHODIMP DragLeave();
+    STDMETHODIMP Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt,
+                      DWORD *pdwEffect);
+
+    // IPersist
+    STDMETHODIMP GetClassID(CLSID *lpClassId);
+
+    // IPersistFile
+    STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName);
+    STDMETHODIMP IsDirty();
+    STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode);
+    STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember);
+    STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName);
+
+    DECLARE_REGISTRY_RESOURCEID(IDR_MYDOCS)
+    DECLARE_NOT_AGGREGATABLE(CMyDocsDropHandler)
+
+    DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+    BEGIN_COM_MAP(CMyDocsDropHandler)
+        COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
+        COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
+        COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
+    END_COM_MAP()
+};
diff --git a/dll/shellext/mydocs/lang/en-US.rc b/dll/shellext/mydocs/lang/en-US.rc
new file mode 100644 (file)
index 0000000..f38a277
--- /dev/null
@@ -0,0 +1,6 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE
+{
+    IDS_NOSRCFILEFOUND "Source file or folder '%ls' is not found."
+}
diff --git a/dll/shellext/mydocs/mydocs.cpp b/dll/shellext/mydocs/mydocs.cpp
new file mode 100644 (file)
index 0000000..c5954c1
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * PROJECT:     mydocs
+ * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
+ * PURPOSE:     MyDocs implementation
+ * COPYRIGHT:   Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
+ */
+
+#include "precomp.hpp"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mydocs);
+
+BEGIN_OBJECT_MAP(ObjectMap)
+    OBJECT_ENTRY(CLSID_MyDocsDropHandler, CMyDocsDropHandler)
+END_OBJECT_MAP()
+
+CComModule gModule;
+LONG g_ModuleRefCnt = 0;
+
+STDAPI DllCanUnloadNow(void)
+{
+    if (g_ModuleRefCnt)
+        return S_FALSE;
+    return gModule.DllCanUnloadNow();
+}
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+    TRACE("CLSID:%s,IID:%s\n", wine_dbgstr_guid(&rclsid), wine_dbgstr_guid(&riid));
+
+    HRESULT hr = gModule.DllGetClassObject(rclsid, riid, ppv);
+
+    TRACE("-- pointer to class factory: %p\n", *ppv);
+
+    return hr;
+}
+
+STDAPI DllRegisterServer(void)
+{
+    HRESULT hr = gModule.DllRegisterServer(FALSE);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    return S_OK;
+}
+
+STDAPI DllUnregisterServer(void)
+{
+    HRESULT hr = gModule.DllUnregisterServer(FALSE);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    return S_OK;
+}
+
+STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad)
+{
+    TRACE("%p 0x%x %p\n", hInstance, dwReason, fImpLoad);
+    if (dwReason == DLL_PROCESS_ATTACH)
+    {
+        gModule.Init(ObjectMap, hInstance, NULL);
+        DisableThreadLibraryCalls(hInstance);
+    }
+    else if (dwReason == DLL_PROCESS_DETACH)
+    {
+        gModule.Term();
+    }
+    return TRUE;
+}
diff --git a/dll/shellext/mydocs/mydocs.rc b/dll/shellext/mydocs/mydocs.rc
new file mode 100644 (file)
index 0000000..8adeb54
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * PROJECT:     mydocs
+ * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
+ * PURPOSE:     MyDocs implementation
+ * COPYRIGHT:   Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
+ */
+
+#include <windef.h>
+#include <winuser.h>
+#include "resource.h"
+
+#include "mydocs_version.rc"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+IDR_MYDOCS REGISTRY "res/mydocs.rgs"
+
+#ifdef LANGUAGE_EN_US
+    #include "lang/en-US.rc"
+#endif
diff --git a/dll/shellext/mydocs/mydocs.spec b/dll/shellext/mydocs/mydocs.spec
new file mode 100644 (file)
index 0000000..b16365d
--- /dev/null
@@ -0,0 +1,4 @@
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
diff --git a/dll/shellext/mydocs/mydocs_version.h b/dll/shellext/mydocs/mydocs_version.h
new file mode 100644 (file)
index 0000000..4ce4d8b
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * PROJECT:     mydocs
+ * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
+ * PURPOSE:     MyDocs implementation
+ * COPYRIGHT:   Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
+ */
+
+#pragma once
+
+#define WINE_FILEVERSION_MAJOR         6
+#define WINE_FILEVERSION_MINOR         0
+#define WINE_FILEVERSION_BUILD      3790
+#define WINE_FILEVERSION_PLATFORMID 3959
+
+#define WINE_FILEVERSION_STR "6.0.3790.3959"
diff --git a/dll/shellext/mydocs/mydocs_version.rc b/dll/shellext/mydocs/mydocs_version.rc
new file mode 100644 (file)
index 0000000..937b119
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * PROJECT:     mydocs
+ * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
+ * PURPOSE:     MyDocs implementation
+ * COPYRIGHT:   Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
+ */
+
+#include "mydocs_version.h"
+
+#define WINE_OLESELFREGISTER
+#define WINE_FILEVERSION WINE_FILEVERSION_MAJOR,WINE_FILEVERSION_MINOR,WINE_FILEVERSION_BUILD,WINE_FILEVERSION_PLATFORMID
+#define WINE_FILENAME_STR "mydocs.dll"
+
+#include <wine/wine_common_ver.rc>
diff --git a/dll/shellext/mydocs/precomp.hpp b/dll/shellext/mydocs/precomp.hpp
new file mode 100644 (file)
index 0000000..4ad886e
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * PROJECT:     mydocs
+ * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
+ * PURPOSE:     MyDocs implementation
+ * COPYRIGHT:   Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
+ */
+
+#define COBJMACROS
+#define WIN32_NO_STATUS
+#include <windows.h>
+#include <shlwapi.h>
+#include <shlobj.h>
+#include <shobjidl.h>
+#include <atlbase.h>
+#include <atlcom.h>
+#include <atlwin.h>
+#include <atlstr.h>
+#include <shlguid_undoc.h>
+#include <shellapi.h>
+#include <shellutils.h>
+#include <strsafe.h>
+#include <wine/debug.h>
+
+#include "CMyDocsDropHandler.hpp"
+
+#include "mydocs_version.h"
+#include "resource.h"
+
+extern LONG g_ModuleRefCnt;
diff --git a/dll/shellext/mydocs/res/mydocs.rgs b/dll/shellext/mydocs/res/mydocs.rgs
new file mode 100644 (file)
index 0000000..40bbe0d
--- /dev/null
@@ -0,0 +1,35 @@
+HKCR
+{
+    NoRemove CLSID
+    {
+        '{ECF03A32-103D-11d2-854D-006008059367}' = s 'MyDocs Drop Target'
+        {
+            val 'NeverShowExt' = s ''
+            val 'NoOpen' = s 'Drag Files onto this icon to store them in My Documents'
+            val EditFlags = d '0x01'
+            DefaultIcon = e '%%SystemRoot%%\system32\shell32.dll,-235'
+            {
+            }
+            InprocServer32 = s '%MODULE%'
+            {
+                val ThreadingModel = s 'Apartment'
+            }
+            'shellex'
+            {
+                'DropHandler' = s '{ECF03A32-103D-11d2-854D-006008059367}'
+                {
+                }
+            }
+        }
+    }
+}
+HKLM
+{
+    NoRemove Software
+    {
+        NoRemove Classes
+        {
+            '.mydocs' = s 'CLSID\{ECF03A32-103D-11d2-854D-006008059367}'
+        }
+    }
+}
diff --git a/dll/shellext/mydocs/resource.h b/dll/shellext/mydocs/resource.h
new file mode 100644 (file)
index 0000000..0cbcb88
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * PROJECT:     mydocs
+ * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
+ * PURPOSE:     MyDocs implementation
+ * COPYRIGHT:   Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
+ */
+
+#ifndef RESOURCE_H_
+#define RESOURCE_H_
+
+#define IDR_MYDOCS 100
+
+#define IDS_NOSRCFILEFOUND 100
+
+#endif
index d70d83c..0de1dc9 100644 (file)
@@ -86,6 +86,7 @@ AddReg=Classes
 11,,msxml3.dll,1
 11,,msxml4.dll,1
 11,,msxml6.dll,1
+11,,mydocs.dll,1
 11,,netshell.dll,1
 11,,ntobjshex.dll,1
 11,,objsel.dll,1
index 7360ab5..42021b6 100644 (file)
@@ -112,6 +112,7 @@ DEFINE_GUID(CLSID_ShellNetDefExt,          0x86422020, 0x42A0, 0x1069, 0xA2, 0xE
 
 DEFINE_GUID(CLSID_ExeDropHandler,          0x86C86720, 0x42A0, 0x1069, 0xA2, 0xE8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
 DEFINE_GUID(CLSID_DeskLinkDropHandler,     0x9E56BE61, 0xC50F, 0x11CF, 0x9A, 0x2C, 0x00, 0xA0, 0xC9, 0x0A, 0x90, 0xCE);
+DEFINE_GUID(CLSID_MyDocsDropHandler,       0xECF03A32, 0x103D, 0x11d2, 0x85, 0x4D, 0x00, 0x60, 0x08, 0x05, 0x93, 0x67);
 
 DEFINE_GUID(CLSID_MergedFolder,            0x26FDC864, 0xBE88, 0x46E7, 0x92, 0x35, 0x03, 0x2D, 0x8E, 0xA5, 0x16, 0x2E);
 DEFINE_GUID(IID_IAugmentedShellFolder,     0x91EA3F8C, 0xC99B, 0x11D0, 0x98, 0x15, 0x00, 0xC0, 0x4F, 0xD9, 0x19, 0x72);