[SHELL32]
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 15 Mar 2014 13:59:22 +0000 (13:59 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 15 Mar 2014 13:59:22 +0000 (13:59 +0000)
* Implement support for file formats' drop target shell extensions.
* Implement a shell extension for executable files.
* Implement a shell extension for lnk files.
* Change the shell notifications for moving files and folders, as they were all conflated with renaming files.
* Fix up SHChangeNotification so the desktop receives notifications when files are added to common or user desktop directories.
* Fix up SHChangeNotification such that folder pidls are not incorrectly assumed to be file pidls and displayed incorrectly.
* Implement a drop target for My Documents.
* Fix up the desktop's drop target resolution so files can be dropped on the recycle bin and my documents etc properly.
* Stub IDragSourceHelper in CLSID_DragDropHelper.
* Add a few additional shell change notifications.
* Silence a few FIXMEs to TRACEs.
* Some code clean up.
* Brought to you by Huw Campbell.
CORE-3760

svn path=/trunk/; revision=62502

26 files changed:
reactos/boot/bootdata/hivecls.inf
reactos/dll/win32/shell32/CMakeLists.txt
reactos/dll/win32/shell32/changenotify.cpp
reactos/dll/win32/shell32/defcontextmenu.cpp
reactos/dll/win32/shell32/dragdrophelper.cpp
reactos/dll/win32/shell32/dragdrophelper.h
reactos/dll/win32/shell32/droptargets/CexeDropHandler.cpp [new file with mode: 0644]
reactos/dll/win32/shell32/droptargets/CexeDropHandler.h [new file with mode: 0644]
reactos/dll/win32/shell32/folders/desktop.cpp
reactos/dll/win32/shell32/folders/desktop.h
reactos/dll/win32/shell32/folders/fs.cpp
reactos/dll/win32/shell32/folders/fs.h
reactos/dll/win32/shell32/folders/mydocuments.cpp
reactos/dll/win32/shell32/folders/mydocuments.h
reactos/dll/win32/shell32/folders/recyclebin.cpp
reactos/dll/win32/shell32/precomp.h
reactos/dll/win32/shell32/res/rgs/exedrophandler.rgs [new file with mode: 0644]
reactos/dll/win32/shell32/rgs_res.rc
reactos/dll/win32/shell32/shell32_main.cpp
reactos/dll/win32/shell32/shelllink.cpp
reactos/dll/win32/shell32/shelllink.h
reactos/dll/win32/shell32/shfldr.h
reactos/dll/win32/shell32/shlfileop.cpp
reactos/dll/win32/shell32/shlview.cpp
reactos/dll/win32/shell32/shresdef.h
reactos/include/psdk/shlguid_undoc.h

index 9807180..10db21b 100644 (file)
@@ -100,6 +100,7 @@ HKCR,"exefile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll
 HKCR,"exefile\Defaulticon","",0x00000000,"%1"
 HKCR,"exefile\shell\open\command","",0x00000000,"""%1"" %*"
 HKCR,"exefile\shell\runas\command","",0x00020000,"""%1"" %*"
 HKCR,"exefile\Defaulticon","",0x00000000,"%1"
 HKCR,"exefile\shell\open\command","",0x00000000,"""%1"" %*"
 HKCR,"exefile\shell\runas\command","",0x00020000,"""%1"" %*"
+HKCR,"exefile\shellex\DropHandler","",0x00020000,"{86C86720-42A0-1069-A2E8-08002B30309D}"
 
 ; Fonts
 HKCR,".fon","",0x00000000,"fonfile"
 
 ; Fonts
 HKCR,".fon","",0x00000000,"fonfile"
@@ -191,6 +192,7 @@ HKCR,"lnkfile","NeverShowExt",0x00000000,""
 HKCR,"lnkfile","IsShortcut",0x00000000,"yes"
 HKCR,"lnkfile\CLSID","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
 HKCR,"lnkfile\shellex\IconHandler","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
 HKCR,"lnkfile","IsShortcut",0x00000000,"yes"
 HKCR,"lnkfile\CLSID","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
 HKCR,"lnkfile\shellex\IconHandler","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
+HKCR,"lnkfile\shellex\DropHandler","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
 HKCR,"lnkfile\shellex\ContextMenuHandlers\{00021401-0000-0000-C000-000000000046}","",0x00000000,""
 HKCR,"lnkfile\shellex\PropertySheetHandlers\Shellink Property Page", "", 0x00000000, "{00021401-0000-0000-C000-000000000046}"
 
 HKCR,"lnkfile\shellex\ContextMenuHandlers\{00021401-0000-0000-C000-000000000046}","",0x00000000,""
 HKCR,"lnkfile\shellex\PropertySheetHandlers\Shellink Property Page", "", 0x00000000, "{00021401-0000-0000-C000-000000000046}"
 
index 89c5417..b59b679 100644 (file)
@@ -54,6 +54,7 @@ list(APPEND SOURCE
     folders/fonts.cpp
     folders/cpanel.cpp
     folders/recyclebin.cpp
     folders/fonts.cpp
     folders/cpanel.cpp
     folders/recyclebin.cpp
+    droptargets/CexeDropHandler.cpp
     shlexec.cpp
     shlfileop.cpp
     shlfolder.cpp
     shlexec.cpp
     shlfileop.cpp
     shlfolder.cpp
index e776158..71eee58 100644 (file)
@@ -264,6 +264,25 @@ static BOOL should_notify( LPCITEMIDLIST changed, LPCITEMIDLIST watched, BOOL su
         return TRUE;
     if( sub && ILIsParent( watched, changed, TRUE ) )
         return TRUE;
         return TRUE;
     if( sub && ILIsParent( watched, changed, TRUE ) )
         return TRUE;
+    if (sub && _ILIsDesktop(watched)) {
+        WCHAR wszPath[MAX_PATH];
+        SHGetSpecialFolderPathW(0, wszPath, CSIDL_DESKTOPDIRECTORY, FALSE);
+        LPITEMIDLIST deskpidl = SHSimpleIDListFromPathW(wszPath);
+        if (ILIsParent(deskpidl, changed, TRUE))
+        {
+            ILFree(deskpidl);
+            return TRUE;
+        }
+        ILFree(deskpidl);
+        SHGetSpecialFolderPathW(0, wszPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
+        deskpidl = SHSimpleIDListFromPathW(wszPath);
+        if (ILIsParent(deskpidl, changed, TRUE))
+        {
+            ILFree(deskpidl);
+            return TRUE;
+        }
+        ILFree(deskpidl);
+    }
     return FALSE;
 }
 
     return FALSE;
 }
 
@@ -272,7 +291,7 @@ static BOOL should_notify( LPCITEMIDLIST changed, LPCITEMIDLIST watched, BOOL su
  */
 void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
 {
  */
 void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
 {
-    LPCITEMIDLIST Pidls[2];
+    LPITEMIDLIST Pidls[2];
     LPNOTIFICATIONLIST ptr;
     UINT typeFlag = uFlags & SHCNF_TYPE;
 
     LPNOTIFICATIONLIST ptr;
     UINT typeFlag = uFlags & SHCNF_TYPE;
 
@@ -316,10 +335,43 @@ void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID
     case SHCNF_PATHW:
         if (dwItem1) Pidls[0] = SHSimpleIDListFromPathW((LPCWSTR)dwItem1);
         if (dwItem2) Pidls[1] = SHSimpleIDListFromPathW((LPCWSTR)dwItem2);
     case SHCNF_PATHW:
         if (dwItem1) Pidls[0] = SHSimpleIDListFromPathW((LPCWSTR)dwItem1);
         if (dwItem2) Pidls[1] = SHSimpleIDListFromPathW((LPCWSTR)dwItem2);
+        if (wEventId & (SHCNE_MKDIR | SHCNE_RMDIR | SHCNE_UPDATEDIR | SHCNE_RENAMEFOLDER))
+        {
+            /*
+             * The last items in the ID are currently files. So we chop off the last
+             * entry, and create a new one using a find data struct.
+             */
+            if (dwItem1 && Pidls[0]){
+                ILRemoveLastID(Pidls[0]);
+                WIN32_FIND_DATAW wfd;
+                LPWSTR p = PathFindFileNameW((LPCWSTR)dwItem1);
+                lstrcpynW(&wfd.cFileName[0], p, MAX_PATH);
+                wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
+                LPITEMIDLIST newpidl = _ILCreateFromFindDataW(&wfd);
+                LPITEMIDLIST oldpidl = ILClone(Pidls[0]);
+                ILFree(Pidls[0]);
+                Pidls[0] = ILCombine(oldpidl, newpidl);
+                ILFree(newpidl);
+                ILFree(oldpidl);
+            }
+            if (dwItem2 && Pidls[1]){
+                ILRemoveLastID(Pidls[1]);
+                WIN32_FIND_DATAW wfd;
+                LPWSTR p = PathFindFileNameW((LPCWSTR)dwItem2);
+                lstrcpynW(&wfd.cFileName[0], p, MAX_PATH);
+                wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
+                LPITEMIDLIST newpidl = _ILCreateFromFindDataW(&wfd);
+                LPITEMIDLIST oldpidl = ILClone(Pidls[0]);
+                ILFree(Pidls[1]);
+                Pidls[1] = ILCombine(oldpidl, newpidl);
+                ILFree(newpidl);
+                ILFree(oldpidl);
+            }
+        }
         break;
     case SHCNF_IDLIST:
         break;
     case SHCNF_IDLIST:
-        Pidls[0] = (LPCITEMIDLIST)dwItem1;
-        Pidls[1] = (LPCITEMIDLIST)dwItem2;
+        Pidls[0] = (LPITEMIDLIST)dwItem1;
+        Pidls[1] = (LPITEMIDLIST)dwItem2;
         break;
     case SHCNF_PRINTERA:
     case SHCNF_PRINTERW:
         break;
     case SHCNF_PRINTERA:
     case SHCNF_PRINTERW:
index 72988d1..6c5b2b8 100644 (file)
@@ -61,6 +61,7 @@ class CDefaultContextMenu :
         HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink);
         HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi);
         HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi);
         HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink);
         HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi);
         HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi);
+        HRESULT DoRefresh(LPCMINVOKECOMMANDINFO lpcmi);
         HRESULT DoDelete(LPCMINVOKECOMMANDINFO lpcmi);
         HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy);
         HRESULT DoRename(LPCMINVOKECOMMANDINFO lpcmi);
         HRESULT DoDelete(LPCMINVOKECOMMANDINFO lpcmi);
         HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy);
         HRESULT DoRename(LPCMINVOKECOMMANDINFO lpcmi);
@@ -931,19 +932,34 @@ NotifyShellViewWindow(LPCMINVOKECOMMANDINFO lpcmi, BOOL bRefresh)
     if (FAILED(lpSB->QueryActiveShellView(&lpSV)))
         return E_FAIL;
 
     if (FAILED(lpSB->QueryActiveShellView(&lpSV)))
         return E_FAIL;
 
-    if (LOWORD(lpcmi->lpVerb) == FCIDM_SHVIEW_REFRESH || bRefresh)
-        lpSV->Refresh();
-    else
-    {
-        HWND hwndSV = NULL;
-        if (SUCCEEDED(lpSV->GetWindow(&hwndSV)))
-            SendMessageW(hwndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0), 0);
-    }
+    HWND hwndSV = NULL;
+    if (SUCCEEDED(lpSV->GetWindow(&hwndSV)))
+        SendMessageW(hwndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0), 0);
 
     lpSV->Release();
     return S_OK;
 }
 
 
     lpSV->Release();
     return S_OK;
 }
 
+HRESULT
+CDefaultContextMenu::DoRefresh(
+    LPCMINVOKECOMMANDINFO lpcmi)
+{
+    CComPtr<IPersistFolder2> ppf2 = NULL;
+    LPITEMIDLIST pidl;
+    HRESULT hr = m_Dcm.psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
+    if (SUCCEEDED(hr))
+    {
+        hr = ppf2->GetCurFolder(&pidl);
+        if (SUCCEEDED(hr))
+        {
+            SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, pidl, NULL);
+            ILFree(pidl);
+        }
+        ppf2->Release();
+    }
+    return hr;
+}
+
 HRESULT
 CDefaultContextMenu::DoPaste(
     LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink)
 HRESULT
 CDefaultContextMenu::DoPaste(
     LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink)
@@ -1512,8 +1528,9 @@ CDefaultContextMenu::InvokeCommand(
         case 0x33:
         case FCIDM_SHVIEW_AUTOARRANGE:
         case FCIDM_SHVIEW_SNAPTOGRID:
         case 0x33:
         case FCIDM_SHVIEW_AUTOARRANGE:
         case FCIDM_SHVIEW_SNAPTOGRID:
-        case FCIDM_SHVIEW_REFRESH:
             return NotifyShellViewWindow(lpcmi, FALSE);
             return NotifyShellViewWindow(lpcmi, FALSE);
+        case FCIDM_SHVIEW_REFRESH:
+            return DoRefresh(lpcmi);
         case FCIDM_SHVIEW_INSERT:
             return DoPaste(lpcmi, FALSE);
         case FCIDM_SHVIEW_INSERTLINK:
         case FCIDM_SHVIEW_INSERT:
             return DoPaste(lpcmi, FALSE);
         case FCIDM_SHVIEW_INSERTLINK:
index 51a46dd..b042f2d 100644 (file)
@@ -36,6 +36,18 @@ CDropTargetHelper::~CDropTargetHelper()
 {
 }
 
 {
 }
 
+HRESULT WINAPI CDropTargetHelper::InitializeFromBitmap(LPSHDRAGIMAGE pshdi, IDataObject *pDataObject)
+{
+    FIXME ("(%p)->()\n", this);
+    return E_NOTIMPL;
+}
+HRESULT WINAPI CDropTargetHelper::InitializeFromWindow(HWND hwnd, POINT *ppt, IDataObject *pDataObject)
+{
+    FIXME ("(%p)->()\n", this);
+    return E_NOTIMPL;
+}
+
+
 HRESULT WINAPI CDropTargetHelper::DragEnter (HWND hwndTarget, IDataObject* pDataObject, POINT* ppt, DWORD dwEffect)
 {
     FIXME ("(%p)->(%p %p %p 0x%08x)\n", this, hwndTarget, pDataObject, ppt, dwEffect);
 HRESULT WINAPI CDropTargetHelper::DragEnter (HWND hwndTarget, IDataObject* pDataObject, POINT* ppt, DWORD dwEffect)
 {
     FIXME ("(%p)->(%p %p %p 0x%08x)\n", this, hwndTarget, pDataObject, ppt, dwEffect);
index a520ed6..5cc7de9 100644 (file)
@@ -26,6 +26,7 @@
 class CDropTargetHelper :
        public CComCoClass<CDropTargetHelper, &CLSID_DragDropHelper>,
        public CComObjectRootEx<CComMultiThreadModelNoCS>,
 class CDropTargetHelper :
        public CComCoClass<CDropTargetHelper, &CLSID_DragDropHelper>,
        public CComObjectRootEx<CComMultiThreadModelNoCS>,
+       public IDragSourceHelper,
        public IDropTargetHelper
 {
 private:
        public IDropTargetHelper
 {
 private:
@@ -33,7 +34,9 @@ public:
        CDropTargetHelper();
        ~CDropTargetHelper();
 
        CDropTargetHelper();
        ~CDropTargetHelper();
 
-       ////////
+       virtual HRESULT WINAPI InitializeFromBitmap(LPSHDRAGIMAGE pshdi, IDataObject *pDataObject);
+       virtual HRESULT WINAPI InitializeFromWindow(HWND hwnd, POINT *ppt, IDataObject *pDataObject);
+
        virtual HRESULT WINAPI DragEnter (HWND hwndTarget, IDataObject* pDataObject, POINT* ppt, DWORD dwEffect);
        virtual HRESULT WINAPI DragLeave();
        virtual HRESULT WINAPI DragOver(POINT *ppt, DWORD dwEffect);
        virtual HRESULT WINAPI DragEnter (HWND hwndTarget, IDataObject* pDataObject, POINT* ppt, DWORD dwEffect);
        virtual HRESULT WINAPI DragLeave();
        virtual HRESULT WINAPI DragOver(POINT *ppt, DWORD dwEffect);
@@ -46,6 +49,7 @@ DECLARE_NOT_AGGREGATABLE(CDropTargetHelper)
 DECLARE_PROTECT_FINAL_CONSTRUCT()
 
 BEGIN_COM_MAP(CDropTargetHelper)
 DECLARE_PROTECT_FINAL_CONSTRUCT()
 
 BEGIN_COM_MAP(CDropTargetHelper)
+       COM_INTERFACE_ENTRY_IID(IID_IDragSourceHelper, IDragSourceHelper)
        COM_INTERFACE_ENTRY_IID(IID_IDropTargetHelper, IDropTargetHelper)
 END_COM_MAP()
 };
        COM_INTERFACE_ENTRY_IID(IID_IDropTargetHelper, IDropTargetHelper)
 END_COM_MAP()
 };
diff --git a/reactos/dll/win32/shell32/droptargets/CexeDropHandler.cpp b/reactos/dll/win32/shell32/droptargets/CexeDropHandler.cpp
new file mode 100644 (file)
index 0000000..06052fc
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * executable drop target handler
+ *
+ * Copyright 2014              Huw Campbell
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <precomp.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL (shell);
+
+CExeDropHandler::CExeDropHandler()
+{
+    pclsid = (CLSID *)&CLSID_ExeDropHandler;
+}
+
+CExeDropHandler::~CExeDropHandler()
+{
+
+}
+
+// IDropTarget
+HRESULT WINAPI CExeDropHandler::DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
+{
+    TRACE ("(%p)\n", this);
+    *pdwEffect = DROPEFFECT_COPY;
+    return S_OK;
+}
+
+HRESULT WINAPI CExeDropHandler::DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
+{
+    TRACE ("(%p)\n", this);
+    *pdwEffect = DROPEFFECT_COPY;
+    return S_OK;
+}
+
+HRESULT WINAPI CExeDropHandler::DragLeave()
+{
+    TRACE ("(%p)\n", this);
+    return S_OK;
+}
+
+HRESULT WINAPI CExeDropHandler::Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
+{
+    TRACE ("(%p)\n", this);    
+    FORMATETC fmt;
+    STGMEDIUM medium;
+    LPWSTR pszSrcList;
+    InitFormatEtc (fmt, CF_HDROP, TYMED_HGLOBAL);
+    WCHAR wszBuf[MAX_PATH * 2 + 8], *pszEnd = wszBuf;
+    size_t cchRemaining = _countof(wszBuf);
+
+    if (SUCCEEDED(pDataObject->GetData(&fmt, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/)
+    {
+        LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
+        if (!lpdf)
+        {
+            ERR("Error locking global\n");
+            return E_FAIL;
+        }
+        pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
+        while (*pszSrcList)
+        {
+            if (StrChrW(pszSrcList, L' ') && cchRemaining > 3)
+                StringCchPrintfExW(pszEnd, cchRemaining, &pszEnd, &cchRemaining, 0, L"\"%ls\" ", pszSrcList);
+            else
+                StringCchPrintfExW(pszEnd, cchRemaining, &pszEnd, &cchRemaining, 0, L"%ls ", pszSrcList);
+            
+            pszSrcList += wcslen(pszSrcList) + 1;
+        }
+    }
+
+    ShellExecute(NULL, L"open", sPathTarget, wszBuf, NULL,SW_SHOWNORMAL);
+
+    return S_OK;
+}
+
+
+// IPersistFile
+HRESULT WINAPI CExeDropHandler::GetCurFile(LPOLESTR *ppszFileName)
+{
+    FIXME ("(%p)\n", this);
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI CExeDropHandler::IsDirty()
+{
+    FIXME ("(%p)\n", this);
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI CExeDropHandler::Load(LPCOLESTR pszFileName, DWORD dwMode)
+{
+    UINT len = strlenW(pszFileName);
+    sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR));
+    memcpy(sPathTarget, pszFileName, (len + 1) * sizeof(WCHAR));
+    return S_OK;
+}
+
+HRESULT WINAPI CExeDropHandler::Save(LPCOLESTR pszFileName, BOOL fRemember)
+{
+    FIXME ("(%p)\n", this);
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI CExeDropHandler::SaveCompleted(LPCOLESTR pszFileName)
+{
+    FIXME ("(%p)\n", this);
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * CFSFolder::GetClassID
+ */
+HRESULT WINAPI CExeDropHandler::GetClassID(CLSID * lpClassId)
+{
+    TRACE ("(%p)\n", this);
+
+    if (!lpClassId)
+        return E_POINTER;
+
+    *lpClassId = *pclsid;
+
+    return S_OK;
+}
\ No newline at end of file
diff --git a/reactos/dll/win32/shell32/droptargets/CexeDropHandler.h b/reactos/dll/win32/shell32/droptargets/CexeDropHandler.h
new file mode 100644 (file)
index 0000000..7a79f94
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * executable drop target handler
+ *
+ * Copyright 2014              Huw Campbell
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _CEXEDROPHANDLER_H_
+#define _CEXEDROPHANDLER_H_
+
+class CExeDropHandler :
+    public CComCoClass<CExeDropHandler, &CLSID_ExeDropHandler>,
+    public CComObjectRootEx<CComMultiThreadModelNoCS>,
+    public IDropTarget,
+    public IPersistFile
+{
+private:
+    CLSID *pclsid;
+    LPWSTR sPathTarget;
+public:
+    CExeDropHandler();
+    ~CExeDropHandler();
+
+    // IDropTarget
+    virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+    virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+    virtual HRESULT WINAPI DragLeave();
+    virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+
+    // IPersist
+    virtual HRESULT WINAPI GetClassID(CLSID *lpClassId);
+
+    //////// IPersistFile
+    virtual HRESULT WINAPI GetCurFile(LPOLESTR *ppszFileName);
+    virtual HRESULT WINAPI IsDirty();
+    virtual HRESULT WINAPI Load(LPCOLESTR pszFileName, DWORD dwMode);
+    virtual HRESULT WINAPI Save(LPCOLESTR pszFileName, BOOL fRemember);
+    virtual HRESULT WINAPI SaveCompleted(LPCOLESTR pszFileName);
+
+
+DECLARE_REGISTRY_RESOURCEID(IDR_EXEDROPHANDLER)
+DECLARE_NOT_AGGREGATABLE(CExeDropHandler)
+
+DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+BEGIN_COM_MAP(CExeDropHandler)
+    COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
+    COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
+    COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
+END_COM_MAP()
+};
+
+#endif /* _CEXEDROPHANDLER_H_ */
index 968bc35..4f5ca9f 100644 (file)
@@ -651,7 +651,7 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
     else if (IsEqualIID (riid, IID_IDropTarget))
     {
         /* only interested in attempting to bind to shell folders, not files, semicolon intentionate */
     else if (IsEqualIID (riid, IID_IDropTarget))
     {
         /* only interested in attempting to bind to shell folders, not files, semicolon intentionate */
-        if (cidl == 1 && SUCCEEDED(this->BindToObject(apidl[0], NULL, IID_IDropTarget, (LPVOID*)&pObj)));
+        if (cidl == 1 && SUCCEEDED(hr = this->_GetDropTarget(apidl[0], (LPVOID*)&pObj)));
         else
             hr = this->QueryInterface(IID_IDropTarget, (LPVOID*)&pObj);
     }
         else
             hr = this->QueryInterface(IID_IDropTarget, (LPVOID*)&pObj);
     }
@@ -1451,7 +1451,7 @@ HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject,
     else
     {
         InitFormatEtc (formatetc, CF_HDROP, TYMED_HGLOBAL);
     else
     {
         InitFormatEtc (formatetc, CF_HDROP, TYMED_HGLOBAL);
-        if SUCCEEDED(pDataObject->QueryGetData(&formatetc));
+        if (SUCCEEDED(pDataObject->QueryGetData(&formatetc)))
         {
             passthroughtofs = TRUE;
         }
         {
             passthroughtofs = TRUE;
         }
@@ -1488,4 +1488,53 @@ HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject,
     /* Todo, rewrite the registry such that the icons are well placed.
     Blocked by no bags implementation. */
     return hr;
     /* Todo, rewrite the registry such that the icons are well placed.
     Blocked by no bags implementation. */
     return hr;
+}
+
+HRESULT WINAPI CDesktopFolder::_GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut) {
+    HRESULT hr;
+
+    TRACE("CFSFolder::_GetDropTarget entered\n");
+
+    if (_ILGetGUIDPointer (pidl) || _ILIsFolder (pidl))
+        return this->BindToObject(pidl, NULL, IID_IDropTarget, ppvOut);
+
+    LPITEMIDLIST pidlNext = NULL;
+
+    STRRET strFile;
+    hr = this->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strFile);
+    if (SUCCEEDED(hr))
+    {
+        WCHAR wszPath[MAX_PATH];
+        hr = StrRetToBufW(&strFile, pidl, wszPath, _countof(wszPath));
+
+        if (SUCCEEDED(hr))
+        {
+            PathRemoveFileSpecW (wszPath);
+            hr = this->ParseDisplayName(NULL, NULL, wszPath, NULL, &pidlNext, NULL);
+
+            if (SUCCEEDED(hr))
+            {
+                IShellFolder *psf;
+                hr = this->BindToObject(pidlNext, NULL, IID_IShellFolder, (LPVOID*)&psf);
+                CoTaskMemFree(pidlNext);
+                if (SUCCEEDED(hr))
+                {
+                    hr = psf->GetUIObjectOf(NULL, 1, &pidl, IID_IDropTarget, NULL, ppvOut);
+                    psf->Release();
+                    if (FAILED(hr))
+                        ERR("FS GetUIObjectOf failed: %x\n", hr);
+                }
+                else 
+                    ERR("BindToObject failed: %x\n", hr);
+            }
+            else
+                ERR("ParseDisplayName failed: %x\n", hr);
+        }
+        else
+            ERR("StrRetToBufW failed: %x\n", hr);
+    }    
+    else
+        ERR("GetDisplayNameOf failed: %x\n", hr);
+
+    return hr;
 }
\ No newline at end of file
 }
\ No newline at end of file
index 6f4c723..be62108 100644 (file)
@@ -40,6 +40,7 @@ class CDesktopFolder :
         BOOL fAcceptFmt;       /* flag for pending Drop */
         BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
         void SF_RegisterClipFmt();
         BOOL fAcceptFmt;       /* flag for pending Drop */
         BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
         void SF_RegisterClipFmt();
+        virtual HRESULT WINAPI _GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut);
 
     public:
         CDesktopFolder();
 
     public:
         CDesktopFolder();
index 5e61e71..76e19a0 100644 (file)
@@ -81,6 +81,7 @@ CFSFolder::CFSFolder()
     cfShellIDList = 0;
     SF_RegisterClipFmt();
     fAcceptFmt = FALSE;
     cfShellIDList = 0;
     SF_RegisterClipFmt();
     fAcceptFmt = FALSE;
+    m_bGroupPolicyActive = 0;
 }
 
 CFSFolder::~CFSFolder()
 }
 
 CFSFolder::~CFSFolder()
@@ -502,7 +503,7 @@ HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner,
         else if (IsEqualIID (riid, IID_IDropTarget))
         {
             /* only interested in attempting to bind to shell folders, not files (except exe), so if we fail, rebind to root */
         else if (IsEqualIID (riid, IID_IDropTarget))
         {
             /* only interested in attempting to bind to shell folders, not files (except exe), so if we fail, rebind to root */
-            if (cidl == 1 && SUCCEEDED(hr = this->BindToObject(apidl[0], NULL, IID_IDropTarget, (LPVOID*)&pObj)));
+            if (cidl == 1 && SUCCEEDED(hr = this->_GetDropTarget(apidl[0], (LPVOID*)&pObj)));
             else
                 hr = this->QueryInterface(IID_IDropTarget, (LPVOID*)&pObj);
         }
             else
                 hr = this->QueryInterface(IID_IDropTarget, (LPVOID*)&pObj);
         }
@@ -1617,6 +1618,9 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
                     }
 
                     hr = ppf->Save(wszTarget, FALSE);
                     }
 
                     hr = ppf->Save(wszTarget, FALSE);
+                                       if (FAILED(hr))
+                                               break;
+                                       SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, wszTarget, NULL);
                 }
                 else
                 {
                 }
                 else
                 {
@@ -1653,6 +1657,9 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
                         break;
 
                     hr = ppf->Save(wszTarget, TRUE);
                         break;
 
                     hr = ppf->Save(wszTarget, TRUE);
+                                       if (FAILED(hr))
+                                               break;
+                                       SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, wszTarget, NULL);
                 }
             }
         }
                 }
             }
         }
@@ -1748,4 +1755,114 @@ DWORD WINAPI CFSFolder::_DoDropThreadProc(LPVOID lpParameter) {
     //Release the parameter from the heap.
     HeapFree(GetProcessHeap(), 0, data);
     return 0;
     //Release the parameter from the heap.
     HeapFree(GetProcessHeap(), 0, data);
     return 0;
+}
+
+HRESULT WINAPI CFSFolder::_GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut) {
+    HKEY hKey;
+    HRESULT hr;
+
+    TRACE("CFSFolder::_GetDropTarget entered\n");
+
+    if (_ILGetGUIDPointer (pidl) || _ILIsFolder (pidl))
+        return this->BindToObject(pidl, NULL, IID_IDropTarget, ppvOut);
+
+    STRRET strFile;
+    hr = this->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strFile);
+    if (hr == S_OK)
+    {
+        WCHAR wszPath[MAX_PATH];
+        hr = StrRetToBufW(&strFile, pidl, wszPath, _countof(wszPath));
+
+        if (hr == S_OK)
+        {
+            LPCWSTR pwszExt = PathFindExtensionW(wszPath);
+            if (pwszExt[0])
+            {
+                /* enumerate dynamic/static for a given file class */
+                if (RegOpenKeyExW(HKEY_CLASSES_ROOT, pwszExt, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+                {
+                    /* load dynamic extensions from file extension key, for example .jpg */
+                    _LoadDynamicDropTargetHandlerForKey(hKey, wszPath, ppvOut);
+                    RegCloseKey(hKey);
+                }
+
+                WCHAR wszTemp[40];
+                DWORD dwSize = sizeof(wszTemp);
+                if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, NULL, RRF_RT_REG_SZ, NULL, wszTemp, &dwSize) == ERROR_SUCCESS)
+                {
+                    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszTemp, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+                    {
+                        /* load dynamic extensions from progid key, for example jpegfile */
+                        _LoadDynamicDropTargetHandlerForKey(hKey, wszPath, ppvOut);
+                        RegCloseKey(hKey);
+                    }
+                }
+            }
+        }
+    }
+    else
+        ERR("GetDisplayNameOf failed: %x\n", hr);
+
+    return hr;
+}
+
+HRESULT WINAPI CFSFolder::_LoadDynamicDropTargetHandlerForKey(HKEY hRootKey, LPCWSTR pwcsname, LPVOID *ppvOut) 
+{
+    TRACE("CFSFolder::_LoadDynamicDropTargetHandlerForKey entered\n");
+
+    WCHAR wszName[MAX_PATH], *pwszClsid;
+    DWORD dwSize = sizeof(wszName);
+    HRESULT hr;
+
+    if (RegGetValueW(hRootKey, L"shellex\\DropHandler", NULL, RRF_RT_REG_SZ, NULL, wszName, &dwSize) == ERROR_SUCCESS)
+    {
+        CLSID clsid;
+        hr = CLSIDFromString(wszName, &clsid);
+        if (hr == S_OK)
+            pwszClsid = wszName;
+
+        if (m_bGroupPolicyActive)
+        {
+            if (RegGetValueW(HKEY_LOCAL_MACHINE,
+                L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
+                pwszClsid,
+                RRF_RT_REG_SZ,
+                NULL,
+                NULL,
+                NULL) == ERROR_SUCCESS)
+            {
+                hr = _LoadDynamicDropTargetHandler(&clsid, pwcsname, ppvOut);
+            }
+        }
+        else
+        {
+            hr = _LoadDynamicDropTargetHandler(&clsid, pwcsname, ppvOut);
+        }
+    }
+    else
+        return E_FAIL;
+    return hr;
+}
+
+HRESULT WINAPI CFSFolder::_LoadDynamicDropTargetHandler(const CLSID *pclsid, LPCWSTR pwcsname, LPVOID *ppvOut)
+{
+    TRACE("CFSFolder::_LoadDynamicDropTargetHandler entered\n");
+    HRESULT hr;
+
+    IPersistFile *pp;
+    hr = SHCoCreateInstance(NULL, pclsid, NULL, IID_PPV_ARG(IPersistFile, &pp));
+    if (hr != S_OK)
+    {
+        ERR("SHCoCreateInstance failed %x\n", GetLastError());
+    }
+    pp->Load(pwcsname, 0);
+
+    hr = pp->QueryInterface(IID_PPV_ARG(IDropTarget, (IDropTarget**) ppvOut));
+    if (hr != S_OK)
+    {
+        ERR("Failed to query for interface IID_IShellExtInit hr %x pclsid %s\n", hr, wine_dbgstr_guid(pclsid));
+        return hr;
+    }
+    pp->Release();
+    return hr;
 }
\ No newline at end of file
 }
\ No newline at end of file
index e32ab2b..95ca362 100644 (file)
@@ -44,10 +44,14 @@ class CFSFolder :
         UINT cfShellIDList;    /* clipboardformat for IDropTarget */
         BOOL fAcceptFmt;       /* flag for pending Drop */
         BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
         UINT cfShellIDList;    /* clipboardformat for IDropTarget */
         BOOL fAcceptFmt;       /* flag for pending Drop */
         BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
+        DWORD m_bGroupPolicyActive;
         void SF_RegisterClipFmt();
         BOOL GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut);
         static DWORD WINAPI _DoDropThreadProc(LPVOID lpParameter);
         virtual HRESULT WINAPI _DoDrop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
         void SF_RegisterClipFmt();
         BOOL GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut);
         static DWORD WINAPI _DoDropThreadProc(LPVOID lpParameter);
         virtual HRESULT WINAPI _DoDrop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+        virtual HRESULT WINAPI _GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut);
+        virtual HRESULT WINAPI _LoadDynamicDropTargetHandlerForKey(HKEY hRootKey, LPCWSTR pwcsname, LPVOID *ppvOut);
+        virtual HRESULT WINAPI _LoadDynamicDropTargetHandler(const CLSID *pclsid, LPCWSTR pwcsname, LPVOID *ppvOut);
 
     public:
         CFSFolder();
 
     public:
         CFSFolder();
index 7c1cbd9..f1a0238 100644 (file)
@@ -78,6 +78,7 @@ CMyDocsFolder::CMyDocsFolder()
 {
     pidlRoot = NULL;
     sPathTarget = NULL;
 {
     pidlRoot = NULL;
     sPathTarget = NULL;
+    mFSDropTarget = NULL;
 }
 
 CMyDocsFolder::~CMyDocsFolder()
 }
 
 CMyDocsFolder::~CMyDocsFolder()
@@ -85,6 +86,7 @@ CMyDocsFolder::~CMyDocsFolder()
     TRACE ("-- destroying IShellFolder(%p)\n", this);
     SHFree(pidlRoot);
     HeapFree(GetProcessHeap(), 0, sPathTarget);
     TRACE ("-- destroying IShellFolder(%p)\n", this);
     SHFree(pidlRoot);
     HeapFree(GetProcessHeap(), 0, sPathTarget);
+    mFSDropTarget->Release();
 }
 
 HRESULT WINAPI CMyDocsFolder::FinalConstruct()
 }
 
 HRESULT WINAPI CMyDocsFolder::FinalConstruct()
@@ -98,6 +100,29 @@ HRESULT WINAPI CMyDocsFolder::FinalConstruct()
     sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
     wcscpy(sPathTarget, szMyPath);
 
     sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
     wcscpy(sPathTarget, szMyPath);
 
+    LPITEMIDLIST pidl = NULL;
+
+    WCHAR szPath[MAX_PATH];
+    lstrcpynW(szPath, sPathTarget, MAX_PATH);
+    PathAddBackslashW(szPath);
+    CComPtr<IShellFolder> psfDesktop = NULL;
+    
+    HRESULT hr = SHGetDesktopFolder(&psfDesktop);
+    if (SUCCEEDED(hr))
+        hr = psfDesktop->ParseDisplayName(NULL, NULL, szPath, NULL, &pidl, NULL);
+    else
+        ERR("Error getting desktop folder\n");
+
+    if (SUCCEEDED(hr))
+    {
+        hr = psfDesktop->BindToObject(pidl, NULL, IID_IDropTarget, (LPVOID*) &mFSDropTarget);
+        CoTaskMemFree(pidl);
+        if (FAILED(hr))
+            ERR("Error Binding");
+    }
+    else
+        ERR("Error creating from %s\n", debugstr_w(szPath));
+
     return S_OK;
 }
 
     return S_OK;
 }
 
@@ -271,8 +296,7 @@ HRESULT WINAPI CMyDocsFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVO
 
     if (IsEqualIID (riid, IID_IDropTarget))
     {
 
     if (IsEqualIID (riid, IID_IDropTarget))
     {
-        WARN ("IDropTarget not implemented\n");
-        hr = E_NOTIMPL;
+        hr = this->QueryInterface (IID_IDropTarget, ppvOut);
     }
     else if (IsEqualIID (riid, IID_IContextMenu))
     {
     }
     else if (IsEqualIID (riid, IID_IContextMenu))
     {
@@ -679,3 +703,26 @@ HRESULT WINAPI CMyDocsFolder::GetCurFolder(LPITEMIDLIST *pidl)
     *pidl = ILClone (pidlRoot);
     return S_OK;
 }
     *pidl = ILClone (pidlRoot);
     return S_OK;
 }
+
+HRESULT WINAPI CMyDocsFolder::DragEnter(IDataObject *pDataObject,
+                                    DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
+{
+    return mFSDropTarget->DragEnter(pDataObject, dwKeyState, pt, pdwEffect);
+}
+
+HRESULT WINAPI CMyDocsFolder::DragOver(DWORD dwKeyState, POINTL pt,
+                                   DWORD *pdwEffect)
+{
+    return mFSDropTarget->DragOver(dwKeyState, pt, pdwEffect);
+}
+
+HRESULT WINAPI CMyDocsFolder::DragLeave()
+{
+    return mFSDropTarget->DragLeave();
+}
+
+HRESULT WINAPI CMyDocsFolder::Drop(IDataObject *pDataObject,
+                               DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
+{
+    return mFSDropTarget->Drop(pDataObject, dwKeyState, pt, pdwEffect);
+}
\ No newline at end of file
index c52ffe5..3a70e8c 100644 (file)
@@ -26,12 +26,14 @@ class CMyDocsFolder :
     public CComCoClass<CMyDocsFolder, &CLSID_MyDocuments>,
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IShellFolder2,
     public CComCoClass<CMyDocsFolder, &CLSID_MyDocuments>,
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IShellFolder2,
-    public IPersistFolder2
+    public IPersistFolder2,
+    public IDropTarget
 {
     private:
         /* both paths are parsible from the MyDocuments */
         LPWSTR sPathTarget;     /* complete path to target used for enumeration and ChangeNotify */
         LPITEMIDLIST pidlRoot;  /* absolute pidl */
 {
     private:
         /* both paths are parsible from the MyDocuments */
         LPWSTR sPathTarget;     /* complete path to target used for enumeration and ChangeNotify */
         LPITEMIDLIST pidlRoot;  /* absolute pidl */
+        IDropTarget *mFSDropTarget;
     public:
         CMyDocsFolder();
         ~CMyDocsFolder();
     public:
         CMyDocsFolder();
         ~CMyDocsFolder();
@@ -67,6 +69,12 @@ class CMyDocsFolder :
         // IPersistFolder2
         virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl);
 
         // IPersistFolder2
         virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl);
 
+        // IDropTarget
+        virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+        virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+        virtual HRESULT WINAPI DragLeave();
+        virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+
         DECLARE_REGISTRY_RESOURCEID(IDR_MYDOCUMENTS)
         DECLARE_NOT_AGGREGATABLE(CMyDocsFolder)
 
         DECLARE_REGISTRY_RESOURCEID(IDR_MYDOCUMENTS)
         DECLARE_NOT_AGGREGATABLE(CMyDocsFolder)
 
@@ -78,6 +86,7 @@ class CMyDocsFolder :
         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
         COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
         COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
+        COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
         END_COM_MAP()
 };
 
         END_COM_MAP()
 };
 
index 733873a..648debf 100644 (file)
@@ -1416,7 +1416,7 @@ BOOL CRecycleBin::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
 HRESULT WINAPI CRecycleBin::DragEnter(IDataObject *pDataObject,
                                     DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
 {
 HRESULT WINAPI CRecycleBin::DragEnter(IDataObject *pDataObject,
                                     DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
 {
-    FIXME("Recycle bin drag over (%p)\n", this);
+    TRACE("Recycle bin drag over (%p)\n", this);
     /* The recycle bin accepts pretty much everything, and sets a CSIDL flag. */
     fAcceptFmt = TRUE;
 
     /* The recycle bin accepts pretty much everything, and sets a CSIDL flag. */
     fAcceptFmt = TRUE;
 
@@ -1449,7 +1449,7 @@ HRESULT WINAPI CRecycleBin::DragLeave()
 HRESULT WINAPI CRecycleBin::Drop(IDataObject *pDataObject,
                                DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
 {
 HRESULT WINAPI CRecycleBin::Drop(IDataObject *pDataObject,
                                DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
 {
-    FIXME("(%p) object dropped on recycle bin, effect %u\n", this, *pdwEffect);
+    TRACE("(%p) object dropped on recycle bin, effect %u\n", this, *pdwEffect);
     
     /* TODO: pdwEffect should be read and make the drop object be permanently deleted in the move case (shift held) */
 
     
     /* TODO: pdwEffect should be read and make the drop object be permanently deleted in the move case (shift held) */
 
index f464d09..a2a648b 100644 (file)
@@ -55,6 +55,7 @@
 #include "folders/printers.h"
 #include "folders/admintools.h"
 #include "folders/recyclebin.h"
 #include "folders/printers.h"
 #include "folders/admintools.h"
 #include "folders/recyclebin.h"
+#include "droptargets/CexeDropHandler.h"
 #include "openwithmenu.h"
 #include "newmenu.h"
 #include "startmenu.h"
 #include "openwithmenu.h"
 #include "newmenu.h"
 #include "startmenu.h"
diff --git a/reactos/dll/win32/shell32/res/rgs/exedrophandler.rgs b/reactos/dll/win32/shell32/res/rgs/exedrophandler.rgs
new file mode 100644 (file)
index 0000000..7e239c9
--- /dev/null
@@ -0,0 +1,13 @@
+HKCR
+{
+       NoRemove CLSID
+       {
+               ForceRemove {86C86720-42A0-1069-A2E8-08002B30309D} = s 'Executable Drag and Drop target'
+               {
+                       InprocServer32 = s '%MODULE%'
+                       {
+                               val ThreadingModel = s 'Apartment'
+                       }
+               }
+       }
+}
index 4ded01d..7cab216 100644 (file)
@@ -23,3 +23,4 @@ IDR_STARTMENU REGISTRY "res/rgs/startmenu.rgs"
 IDR_OPENWITHMENU REGISTRY "res/rgs/openwithmenu.rgs"
 IDR_FILEDEFEXT REGISTRY "res/rgs/shellfiledefext.rgs"
 IDR_DRVDEFEXT REGISTRY "res/rgs/shelldrvdefext.rgs"
 IDR_OPENWITHMENU REGISTRY "res/rgs/openwithmenu.rgs"
 IDR_FILEDEFEXT REGISTRY "res/rgs/shellfiledefext.rgs"
 IDR_DRVDEFEXT REGISTRY "res/rgs/shelldrvdefext.rgs"
+IDR_EXEDROPHANDLER REGISTRY "res/rgs/exedrophandler.rgs"
\ No newline at end of file
index 21ccb1a..beeff9d 100644 (file)
@@ -1371,6 +1371,7 @@ BEGIN_OBJECT_MAP(ObjectMap)
     OBJECT_ENTRY(CLSID_MenuBandSite, CMenuBandSite)
     OBJECT_ENTRY(CLSID_MenuBand, CMenuBand)
     OBJECT_ENTRY(CLSID_MenuDeskBar, CMenuDeskBar)
     OBJECT_ENTRY(CLSID_MenuBandSite, CMenuBandSite)
     OBJECT_ENTRY(CLSID_MenuBand, CMenuBand)
     OBJECT_ENTRY(CLSID_MenuDeskBar, CMenuDeskBar)
+    OBJECT_ENTRY(CLSID_ExeDropHandler, CExeDropHandler)
 END_OBJECT_MAP()
 
 CShell32Module                                gModule;
 END_OBJECT_MAP()
 
 CShell32Module                                gModule;
index fd54ee7..4982f7d 100644 (file)
@@ -2168,6 +2168,68 @@ HRESULT WINAPI CShellLink::GetSite(REFIID iid, void ** ppvSite)
     return site->QueryInterface(iid, ppvSite);
 }
 
     return site->QueryInterface(iid, ppvSite);
 }
 
+HRESULT WINAPI CShellLink::DragEnter(IDataObject *pDataObject,
+    DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
+{
+    TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
+    LPCITEMIDLIST pidlLast;
+    IShellFolder *psf;
+
+    HRESULT hr = SHBindToParent(pPidl, IID_PPV_ARG(IShellFolder, &psf), &pidlLast);
+
+    if (SUCCEEDED(hr))
+    {
+        hr = psf->GetUIObjectOf(0, 1, &pidlLast, IID_IDropTarget, NULL, (LPVOID*)&mDropTarget);
+
+        if (SUCCEEDED(hr))
+            hr = mDropTarget->DragEnter(pDataObject, dwKeyState, pt, pdwEffect);
+        else 
+            *pdwEffect = DROPEFFECT_NONE;
+
+        psf->Release();
+    }
+    else
+        *pdwEffect = DROPEFFECT_NONE;
+
+    return S_OK;
+}
+
+
+
+HRESULT WINAPI CShellLink::DragOver(DWORD dwKeyState, POINTL pt,
+    DWORD *pdwEffect)
+{
+    TRACE("(%p)\n", this);
+    HRESULT hr = S_OK;
+    if (mDropTarget)
+        hr = mDropTarget->DragOver(dwKeyState, pt, pdwEffect);
+    return hr;
+}
+
+HRESULT WINAPI CShellLink::DragLeave()
+{
+    TRACE("(%p)\n", this);
+    HRESULT hr = S_OK;
+    if (mDropTarget)
+    {
+        hr = mDropTarget->DragLeave();
+        mDropTarget->Release();
+    }
+
+    return hr;
+}
+
+HRESULT WINAPI CShellLink::Drop(IDataObject *pDataObject,
+    DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
+{
+    TRACE("(%p)\n", this);
+    HRESULT hr = S_OK;
+    if (mDropTarget)
+        hr = mDropTarget->Drop(pDataObject, dwKeyState, pt, pdwEffect);
+
+    return hr;
+}
+
 /**************************************************************************
  *      IShellLink_ConstructFromFile
  */
 /**************************************************************************
  *      IShellLink_ConstructFromFile
  */
index 47cb0fa..3ccfd3d 100644 (file)
 #define _SHELLLINK_H_
 
 class CShellLink :
 #define _SHELLLINK_H_
 
 class CShellLink :
-       public CComCoClass<CShellLink, &CLSID_ShellLink>,
-       public CComObjectRootEx<CComMultiThreadModelNoCS>,
-       public IShellLinkA,
-       public IShellLinkW,
-       public IPersistFile,
-       public IPersistStream,
-       public IShellLinkDataList,
-       public IShellExtInit,
-       public IContextMenu,
-       public IObjectWithSite,
-       public IShellPropSheetExt
+    public CComCoClass<CShellLink, &CLSID_ShellLink>,
+    public CComObjectRootEx<CComMultiThreadModelNoCS>,
+    public IShellLinkA,
+    public IShellLinkW,
+    public IPersistFile,
+    public IPersistStream,
+    public IShellLinkDataList,
+    public IShellExtInit,
+    public IContextMenu,
+    public IDropTarget,
+    public IObjectWithSite,
+    public IShellPropSheetExt
 {
 public:
 {
 public:
-       /* link file formats */
+    /* link file formats */
 
 
-       #include "pshpack1.h"
+    #include "pshpack1.h"
 
 
-       struct volume_info
-       {
-               DWORD           type;
-               DWORD           serial;
-               WCHAR           label[12];  /* assume 8.3 */
-       };
+    struct volume_info
+    {
+        DWORD        type;
+        DWORD        serial;
+        WCHAR        label[12];  /* assume 8.3 */
+    };
 
 
-       #include "poppack.h"
+    #include "poppack.h"
 
 private:
 
 private:
-       /* data structures according to the information in the link */
-       LPITEMIDLIST    pPidl;
-       WORD            wHotKey;
-       SYSTEMTIME      time1;
-       SYSTEMTIME      time2;
-       SYSTEMTIME      time3;
-
-       DWORD         iShowCmd;
-       LPWSTR        sIcoPath;
-       INT           iIcoNdx;
-       LPWSTR        sPath;
-       LPWSTR        sArgs;
-       LPWSTR        sWorkDir;
-       LPWSTR        sDescription;
-       LPWSTR        sPathRel;
-       LPWSTR        sProduct;
-       LPWSTR        sComponent;
-       volume_info   volume;
-       LPWSTR        sLinkPath;
-       BOOL          bRunAs;
-       BOOL          bDirty;
-       INT           iIdOpen;  /* id of the "Open" entry in the context menu */
-       CComPtr<IUnknown>               site;
+    /* data structures according to the information in the link */
+    LPITEMIDLIST    pPidl;
+    WORD        wHotKey;
+    SYSTEMTIME    time1;
+    SYSTEMTIME    time2;
+    SYSTEMTIME    time3;
+
+    DWORD         iShowCmd;
+    LPWSTR        sIcoPath;
+    INT           iIcoNdx;
+    LPWSTR        sPath;
+    LPWSTR        sArgs;
+    LPWSTR        sWorkDir;
+    LPWSTR        sDescription;
+    LPWSTR        sPathRel;
+    LPWSTR        sProduct;
+    LPWSTR        sComponent;
+    volume_info   volume;
+    LPWSTR        sLinkPath;
+    BOOL          bRunAs;
+    BOOL          bDirty;
+    INT           iIdOpen;  /* id of the "Open" entry in the context menu */
+    CComPtr<IUnknown>        site;
+    IDropTarget   *mDropTarget;
 public:
 public:
-       CShellLink();
-       ~CShellLink();
-       LPWSTR ShellLink_GetAdvertisedArg(LPCWSTR str);
-       HRESULT ShellLink_SetAdvertiseInfo(LPCWSTR str);
-       static INT_PTR CALLBACK SH_ShellLinkDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-
-       // IPersistFile
-       virtual HRESULT WINAPI GetClassID(CLSID *pclsid);
-       virtual HRESULT WINAPI IsDirty();
-       virtual HRESULT WINAPI Load(LPCOLESTR pszFileName, DWORD dwMode);
-       virtual HRESULT WINAPI Save(LPCOLESTR pszFileName, BOOL fRemember);
-       virtual HRESULT WINAPI SaveCompleted(LPCOLESTR pszFileName);
-       virtual HRESULT WINAPI GetCurFile(LPOLESTR *ppszFileName);
-
-       // IPersistStream
-//     virtual WINAPI HRESULT GetClassID(CLSID *pclsid);
-//     virtual HRESULT WINAPI IsDirty();
-       virtual HRESULT WINAPI Load(IStream *stm);
-       virtual HRESULT WINAPI Save(IStream *stm, BOOL fClearDirty);
-       virtual HRESULT WINAPI GetSizeMax(ULARGE_INTEGER *pcbSize);
-
-       // IShellLinkA
-       virtual HRESULT WINAPI GetPath(LPSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags);
-       virtual HRESULT WINAPI GetIDList(LPITEMIDLIST * ppidl);
-       virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
-       virtual HRESULT WINAPI GetDescription(LPSTR pszName,INT cchMaxName);
-       virtual HRESULT WINAPI SetDescription(LPCSTR pszName);
-       virtual HRESULT WINAPI GetWorkingDirectory(LPSTR pszDir,INT cchMaxPath);
-       virtual HRESULT WINAPI SetWorkingDirectory(LPCSTR pszDir);
-       virtual HRESULT WINAPI GetArguments(LPSTR pszArgs,INT cchMaxPath);
-       virtual HRESULT WINAPI SetArguments(LPCSTR pszArgs);
-       virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
-       virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
-       virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
-       virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
-       virtual HRESULT WINAPI GetIconLocation(LPSTR pszIconPath,INT cchIconPath,INT *piIcon);
-       virtual HRESULT WINAPI SetIconLocation(LPCSTR pszIconPath,INT iIcon);
-       virtual HRESULT WINAPI SetRelativePath(LPCSTR pszPathRel, DWORD dwReserved);
-       virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
-       virtual HRESULT WINAPI SetPath(LPCSTR pszFile);
-
-       // IShellLinkW
-       virtual HRESULT WINAPI GetPath(LPWSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAW *pfd, DWORD fFlags);
-//     virtual HRESULT WINAPI GetIDList(LPITEMIDLIST *ppidl);
-//     virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
-       virtual HRESULT WINAPI GetDescription(LPWSTR pszName, INT cchMaxName);
-       virtual HRESULT WINAPI SetDescription(LPCWSTR pszName);
-       virtual HRESULT WINAPI GetWorkingDirectory(LPWSTR pszDir, INT cchMaxPath);
-       virtual HRESULT WINAPI SetWorkingDirectory(LPCWSTR pszDir);
-       virtual HRESULT WINAPI GetArguments(LPWSTR pszArgs,INT cchMaxPath);
-       virtual HRESULT WINAPI SetArguments(LPCWSTR pszArgs);
-//     virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
-//     virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
-//     virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
-//     virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
-       virtual HRESULT WINAPI GetIconLocation(LPWSTR pszIconPath,INT cchIconPath,INT *piIcon);
-       virtual HRESULT WINAPI SetIconLocation(LPCWSTR pszIconPath,INT iIcon);
-       virtual HRESULT WINAPI SetRelativePath(LPCWSTR pszPathRel, DWORD dwReserved);
-//     virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
-       virtual HRESULT WINAPI SetPath(LPCWSTR pszFile);
-
-       // IShellLinkDataList
-       virtual HRESULT WINAPI AddDataBlock(void *pDataBlock);
-       virtual HRESULT WINAPI CopyDataBlock(DWORD dwSig, void **ppDataBlock);
-       virtual HRESULT WINAPI RemoveDataBlock(DWORD dwSig);
-       virtual HRESULT WINAPI GetFlags(DWORD *pdwFlags);
-       virtual HRESULT WINAPI SetFlags(DWORD dwFlags);
-
-       // IShellExtInit
-       virtual HRESULT WINAPI Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
-
-       // IContextMenu
-       virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
-       virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici);
-       virtual HRESULT WINAPI GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax);
-
-       // IShellPropSheetExt
-       virtual HRESULT WINAPI AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam);
-       virtual HRESULT WINAPI ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam);
-
-       // IObjectWithSite
-       virtual HRESULT WINAPI SetSite(IUnknown *punk);
-       virtual HRESULT WINAPI GetSite(REFIID iid, void **ppvSite);
+    CShellLink();
+    ~CShellLink();
+    LPWSTR ShellLink_GetAdvertisedArg(LPCWSTR str);
+    HRESULT ShellLink_SetAdvertiseInfo(LPCWSTR str);
+    static INT_PTR CALLBACK SH_ShellLinkDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+    // IPersistFile
+    virtual HRESULT WINAPI GetClassID(CLSID *pclsid);
+    virtual HRESULT WINAPI IsDirty();
+    virtual HRESULT WINAPI Load(LPCOLESTR pszFileName, DWORD dwMode);
+    virtual HRESULT WINAPI Save(LPCOLESTR pszFileName, BOOL fRemember);
+    virtual HRESULT WINAPI SaveCompleted(LPCOLESTR pszFileName);
+    virtual HRESULT WINAPI GetCurFile(LPOLESTR *ppszFileName);
+
+    // IPersistStream
+    // virtual WINAPI HRESULT GetClassID(CLSID *pclsid);
+    // virtual HRESULT WINAPI IsDirty();
+    virtual HRESULT WINAPI Load(IStream *stm);
+    virtual HRESULT WINAPI Save(IStream *stm, BOOL fClearDirty);
+    virtual HRESULT WINAPI GetSizeMax(ULARGE_INTEGER *pcbSize);
+
+    // IShellLinkA
+    virtual HRESULT WINAPI GetPath(LPSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags);
+    virtual HRESULT WINAPI GetIDList(LPITEMIDLIST * ppidl);
+    virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
+    virtual HRESULT WINAPI GetDescription(LPSTR pszName,INT cchMaxName);
+    virtual HRESULT WINAPI SetDescription(LPCSTR pszName);
+    virtual HRESULT WINAPI GetWorkingDirectory(LPSTR pszDir,INT cchMaxPath);
+    virtual HRESULT WINAPI SetWorkingDirectory(LPCSTR pszDir);
+    virtual HRESULT WINAPI GetArguments(LPSTR pszArgs,INT cchMaxPath);
+    virtual HRESULT WINAPI SetArguments(LPCSTR pszArgs);
+    virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
+    virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
+    virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
+    virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
+    virtual HRESULT WINAPI GetIconLocation(LPSTR pszIconPath,INT cchIconPath,INT *piIcon);
+    virtual HRESULT WINAPI SetIconLocation(LPCSTR pszIconPath,INT iIcon);
+    virtual HRESULT WINAPI SetRelativePath(LPCSTR pszPathRel, DWORD dwReserved);
+    virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
+    virtual HRESULT WINAPI SetPath(LPCSTR pszFile);
+
+    // IShellLinkW
+    virtual HRESULT WINAPI GetPath(LPWSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAW *pfd, DWORD fFlags);
+    // virtual HRESULT WINAPI GetIDList(LPITEMIDLIST *ppidl);
+    // virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
+    virtual HRESULT WINAPI GetDescription(LPWSTR pszName, INT cchMaxName);
+    virtual HRESULT WINAPI SetDescription(LPCWSTR pszName);
+    virtual HRESULT WINAPI GetWorkingDirectory(LPWSTR pszDir, INT cchMaxPath);
+    virtual HRESULT WINAPI SetWorkingDirectory(LPCWSTR pszDir);
+    virtual HRESULT WINAPI GetArguments(LPWSTR pszArgs,INT cchMaxPath);
+    virtual HRESULT WINAPI SetArguments(LPCWSTR pszArgs);
+    // virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
+    // virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
+    // virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
+    // virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
+    virtual HRESULT WINAPI GetIconLocation(LPWSTR pszIconPath,INT cchIconPath,INT *piIcon);
+    virtual HRESULT WINAPI SetIconLocation(LPCWSTR pszIconPath,INT iIcon);
+    virtual HRESULT WINAPI SetRelativePath(LPCWSTR pszPathRel, DWORD dwReserved);
+    // virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
+    virtual HRESULT WINAPI SetPath(LPCWSTR pszFile);
+
+    // IShellLinkDataList
+    virtual HRESULT WINAPI AddDataBlock(void *pDataBlock);
+    virtual HRESULT WINAPI CopyDataBlock(DWORD dwSig, void **ppDataBlock);
+    virtual HRESULT WINAPI RemoveDataBlock(DWORD dwSig);
+    virtual HRESULT WINAPI GetFlags(DWORD *pdwFlags);
+    virtual HRESULT WINAPI SetFlags(DWORD dwFlags);
+
+    // IShellExtInit
+    virtual HRESULT WINAPI Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
+
+    // IContextMenu
+    virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
+    virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici);
+    virtual HRESULT WINAPI GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax);
+
+    // IShellPropSheetExt
+    virtual HRESULT WINAPI AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam);
+    virtual HRESULT WINAPI ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam);
+
+    // IObjectWithSite
+    virtual HRESULT WINAPI SetSite(IUnknown *punk);
+    virtual HRESULT WINAPI GetSite(REFIID iid, void **ppvSite);
+
+    // IDropTarget
+    virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+    virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
+    virtual HRESULT WINAPI DragLeave();
+    virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
 
 DECLARE_REGISTRY_RESOURCEID(IDR_SHELLLINK)
 DECLARE_NOT_AGGREGATABLE(CShellLink)
 
 DECLARE_REGISTRY_RESOURCEID(IDR_SHELLLINK)
 DECLARE_NOT_AGGREGATABLE(CShellLink)
@@ -166,16 +174,17 @@ DECLARE_NOT_AGGREGATABLE(CShellLink)
 DECLARE_PROTECT_FINAL_CONSTRUCT()
 
 BEGIN_COM_MAP(CShellLink)
 DECLARE_PROTECT_FINAL_CONSTRUCT()
 
 BEGIN_COM_MAP(CShellLink)
-       COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistFile)
-       COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
-       COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
-       COM_INTERFACE_ENTRY_IID(IID_IShellLinkA, IShellLinkA)
-       COM_INTERFACE_ENTRY_IID(IID_IShellLinkW, IShellLinkW)
-       COM_INTERFACE_ENTRY_IID(IID_IShellLinkDataList, IShellLinkDataList)
-       COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
-       COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
-       COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt)
-       COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
+    COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistFile)
+    COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
+    COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
+    COM_INTERFACE_ENTRY_IID(IID_IShellLinkA, IShellLinkA)
+    COM_INTERFACE_ENTRY_IID(IID_IShellLinkW, IShellLinkW)
+    COM_INTERFACE_ENTRY_IID(IID_IShellLinkDataList, IShellLinkDataList)
+    COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
+    COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+    COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
+    COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt)
+    COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
 END_COM_MAP()
 };
 
 END_COM_MAP()
 };
 
index 8a194ce..81111ce 100644 (file)
@@ -1,10 +1,10 @@
 
 /*
 
 /*
- *     Virtual Folder
- *     common definitions
+ *  Virtual Folder
+ *  common definitions
  *
  *
- *     Copyright 1997                  Marcus Meissner
- *     Copyright 1998, 1999, 2002      Juergen Schmied
+ *  Copyright 1997 Marcus Meissner
+ *  Copyright 1998, 1999, 2002 Juergen Schmied
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -40,13 +40,13 @@ BOOL SHELL32_GetCustomFolderAttribute (LPCITEMIDLIST pidl, LPCWSTR pwszHeading,
 
 LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut);
 HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST * pidlInOut,
 
 LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut);
 HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST * pidlInOut,
-                                 LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes);
+                  LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes);
 HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
 HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPWSTR szOut,
 HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
 HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPWSTR szOut,
-                                      DWORD dwOutLen);
+                       DWORD dwOutLen);
 
 HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
 
 HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
-                            LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
+                 LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
 
 HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
 LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
 
 HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
 LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
index 1135afc..8fe73ff 100644 (file)
@@ -42,7 +42,7 @@ static const WCHAR wWildcardChars[] = {'*','?',0};
 static DWORD SHNotifyCreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec);
 static DWORD SHNotifyRemoveDirectoryW(LPCWSTR path);
 static DWORD SHNotifyDeleteFileW(LPCWSTR path);
 static DWORD SHNotifyCreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec);
 static DWORD SHNotifyRemoveDirectoryW(LPCWSTR path);
 static DWORD SHNotifyDeleteFileW(LPCWSTR path);
-static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest);
+static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest, BOOL isdir);
 static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists);
 static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly);
 
 static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists);
 static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly);
 
@@ -531,7 +531,7 @@ EXTERN_C DWORD WINAPI Win32DeleteFileW(LPCWSTR path)
  * RETURNS
  *  ERORR_SUCCESS if successful
  */
  * RETURNS
  *  ERORR_SUCCESS if successful
  */
-static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest)
+static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest, BOOL isdir)
 {
     BOOL ret;
 
 {
     BOOL ret;
 
@@ -559,7 +559,8 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest)
     }
     if (ret)
     {
     }
     if (ret)
     {
-        SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATHW, src, dest);
+        SHChangeNotify(isdir ? SHCNE_MKDIR : SHCNE_CREATE, SHCNF_PATHW, dest, NULL);
+        SHChangeNotify(isdir ? SHCNE_RMDIR : SHCNE_DELETE, SHCNF_PATHW, src, NULL);
         return ERROR_SUCCESS;
     }
     return GetLastError();
         return ERROR_SUCCESS;
     }
     return GetLastError();
@@ -1474,7 +1475,10 @@ static HRESULT delete_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom)
         {
             BOOL bDelete;
             if (TRASH_TrashFile(fileEntry->szFullPath))
         {
             BOOL bDelete;
             if (TRASH_TrashFile(fileEntry->szFullPath))
+            {
+                SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW, fileEntry->szFullPath, NULL);
                 continue;
                 continue;
+            }
 
             /* Note: Windows silently deletes the file in such a situation, we show a dialog */
             if (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_WANTNUKEWARNING))
 
             /* Note: Windows silently deletes the file in such a situation, we show a dialog */
             if (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_WANTNUKEWARNING))
@@ -1491,7 +1495,10 @@ static HRESULT delete_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom)
 
         /* delete the file or directory */
         if (IsAttribFile(fileEntry->attributes))
 
         /* delete the file or directory */
         if (IsAttribFile(fileEntry->attributes))
+        {
             bPathExists = DeleteFileW(fileEntry->szFullPath);
             bPathExists = DeleteFileW(fileEntry->szFullPath);
+            SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW, fileEntry->szFullPath, NULL);
+        }
         else
             bPathExists = SHELL_DeleteDirectoryW(lpFileOp->hwnd, fileEntry->szFullPath, FALSE);
 
         else
             bPathExists = SHELL_DeleteDirectoryW(lpFileOp->hwnd, fileEntry->szFullPath, FALSE);
 
@@ -1548,7 +1555,7 @@ static void move_to_dir(LPSHFILEOPSTRUCTW lpFileOp, const FILE_ENTRY *feFrom, co
     PathCombineW(szDestPath, feTo->szFullPath, feFrom->szFilename);
 
     if (IsAttribFile(feFrom->attributes))
     PathCombineW(szDestPath, feTo->szFullPath, feFrom->szFilename);
 
     if (IsAttribFile(feFrom->attributes))
-        SHNotifyMoveFileW(feFrom->szFullPath, szDestPath);
+        SHNotifyMoveFileW(feFrom->szFullPath, szDestPath, FALSE);
     else if (!(lpFileOp->fFlags & FOF_FILESONLY && feFrom->bFromWildcard))
         move_dir_to_dir(lpFileOp, feFrom, szDestPath);
 }
     else if (!(lpFileOp->fFlags & FOF_FILESONLY && feFrom->bFromWildcard))
         move_dir_to_dir(lpFileOp, feFrom, szDestPath);
 }
@@ -1599,7 +1606,7 @@ static HRESULT move_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom, c
         if (fileDest->bExists && IsAttribDir(fileDest->attributes))
             move_to_dir(lpFileOp, entryToMove, fileDest);
         else
         if (fileDest->bExists && IsAttribDir(fileDest->attributes))
             move_to_dir(lpFileOp, entryToMove, fileDest);
         else
-            SHNotifyMoveFileW(entryToMove->szFullPath, fileDest->szFullPath);
+            SHNotifyMoveFileW(entryToMove->szFullPath, fileDest->szFullPath, IsAttribDir(entryToMove->attributes));
     }
 
     return ERROR_SUCCESS;
     }
 
     return ERROR_SUCCESS;
@@ -1628,7 +1635,7 @@ static HRESULT rename_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom,
     if (feTo->bExists)
         return ERROR_ALREADY_EXISTS;
 
     if (feTo->bExists)
         return ERROR_ALREADY_EXISTS;
 
-    return SHNotifyMoveFileW(feFrom->szFullPath, feTo->szFullPath);
+    return SHNotifyMoveFileW(feFrom->szFullPath, feTo->szFullPath, IsAttribDir(feFrom->attributes));
 }
 
 /* alert the user if an unsupported flag is used */
 }
 
 /* alert the user if an unsupported flag is used */
index 5cf59f3..5afc0e8 100644 (file)
@@ -1807,9 +1807,13 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
             break;
 
         case SHCNE_UPDATEITEM:
             break;
 
         case SHCNE_UPDATEITEM:
+            LV_RenameItem(Pidls[0], Pidls[0]);
             break;
             break;
-    }
 
 
+        case SHCNE_UPDATEDIR:
+            Refresh();
+            break;
+    }
     return TRUE;
 }
 
     return TRUE;
 }
 
@@ -2493,12 +2497,10 @@ HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINT
     {
         m_pCurDropTarget->Drop(pDataObject, grfKeyState, pt, pdwEffect);
         m_pCurDropTarget.Release();
     {
         m_pCurDropTarget->Drop(pDataObject, grfKeyState, pt, pdwEffect);
         m_pCurDropTarget.Release();
-
-        this->Refresh();
     }
 
     }
 
-    m_pCurDataObject.Release();    m_iDragOverItem = 0;
-
+    m_pCurDataObject.Release();    
+    m_iDragOverItem = 0;
     return S_OK;
 }
 
     return S_OK;
 }
 
index deebecb..607a42f 100644 (file)
 #define IDR_DRVDEFEXT           148
 #define IDR_MENUBAND            149
 #define IDR_MENUDESKBAR         150
 #define IDR_DRVDEFEXT           148
 #define IDR_MENUBAND            149
 #define IDR_MENUDESKBAR         150
+#define IDR_EXEDROPHANDLER      151
index 24880ed..09eb323 100644 (file)
@@ -105,6 +105,8 @@ DEFINE_GUID(CLSID_ShellFileDefExt,         0x21B22460, 0x3AEA, 0x1069, 0xA2, 0xD
 DEFINE_GUID(CLSID_ShellDrvDefExt,          0x5F5295E0, 0x429F, 0x1069, 0xA2, 0xE2, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
 DEFINE_GUID(CLSID_ShellNetDefExt,          0x86422020, 0x42A0, 0x1069, 0xA2, 0xE5, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
 
 DEFINE_GUID(CLSID_ShellDrvDefExt,          0x5F5295E0, 0x429F, 0x1069, 0xA2, 0xE2, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
 DEFINE_GUID(CLSID_ShellNetDefExt,          0x86422020, 0x42A0, 0x1069, 0xA2, 0xE5, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
 
+DEFINE_GUID(CLSID_ExeDropHandler,                 0x86C86720, 0x42A0, 0x1069, 0xA2, 0xE8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
+
 #define CGID_IExplorerToolbar IID_IExplorerToolbar
 #define SID_IExplorerToolbar IID_IExplorerToolbar
 #define SID_ITargetFrame2 IID_ITargetFrame2
 #define CGID_IExplorerToolbar IID_IExplorerToolbar
 #define SID_IExplorerToolbar IID_IExplorerToolbar
 #define SID_ITargetFrame2 IID_ITargetFrame2