https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7c134e4d14efa98eac47e8b6b4b3589d5db8f8ac

commit 7c134e4d14efa98eac47e8b6b4b3589d5db8f8ac
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Thu Sep 3 13:36:31 2020 +0900
Commit:     GitHub <[email protected]>
CommitDate: Thu Sep 3 13:36:31 2020 +0900

    [SHELL32] Big fix for change notification (#3048)
    
    - Reduced the failures of SHChangeNotify testcase.
    - Simplified change notification mechanism.
    - Realized PIDL aliasing.
    CORE-13950
---
 dll/win32/shell32/CDefView.cpp                     |  33 +---
 dll/win32/shell32/changenotify.cpp                 | 187 +++++++++++++++++++--
 .../shell32/shelldesktop/CChangeNotifyServer.cpp   | 117 +++++--------
 dll/win32/shell32/shelldesktop/CDirectoryList.cpp  |  10 ++
 .../shell32/shelldesktop/CDirectoryWatcher.cpp     |   5 +-
 dll/win32/shell32/stubs.cpp                        |  35 ----
 dll/win32/shell32/wine/pidl.c                      |   8 +-
 7 files changed, 244 insertions(+), 151 deletions(-)

diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp
index 6948e572958..6495b08610e 100644
--- a/dll/win32/shell32/CDefView.cpp
+++ b/dll/win32/shell32/CDefView.cpp
@@ -1166,39 +1166,14 @@ LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, 
LPARAM lParam, BOOL &bHandl
         SetShellWindowEx(hwndSB, m_ListView);
     }
 
-    INT nRegCount;
-    SHChangeNotifyEntry ntreg[3];
-    PIDLIST_ABSOLUTE pidls[3];
-    if (_ILIsDesktop(m_pidlParent))
-    {
-        nRegCount = 3;
-        SHGetSpecialFolderLocation(m_hWnd, CSIDL_DESKTOPDIRECTORY, &pidls[0]);
-        SHGetSpecialFolderLocation(m_hWnd, CSIDL_COMMON_DESKTOPDIRECTORY, 
&pidls[1]);
-        SHGetSpecialFolderLocation(m_hWnd, CSIDL_BITBUCKET, &pidls[2]);
-        ntreg[0].fRecursive = FALSE;
-        ntreg[0].pidl = pidls[0];
-        ntreg[1].fRecursive = FALSE;
-        ntreg[1].pidl = pidls[1];
-        ntreg[2].fRecursive = FALSE;
-        ntreg[2].pidl = pidls[2];
-    }
-    else
-    {
-        nRegCount = 1;
-        ntreg[0].fRecursive = FALSE;
-        ntreg[0].pidl = m_pidlParent;
-    }
+    SHChangeNotifyEntry ntreg[1];
+    ntreg[0].fRecursive = FALSE;
+    ntreg[0].pidl = m_pidlParent;
     m_hNotify = SHChangeNotifyRegister(m_hWnd,
                                        SHCNRF_InterruptLevel | 
SHCNRF_ShellLevel |
                                        SHCNRF_NewDelivery,
                                        SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY,
-                                       nRegCount, ntreg);
-    if (nRegCount == 3)
-    {
-        ILFree(pidls[0]);
-        ILFree(pidls[1]);
-        ILFree(pidls[2]);
-    }
+                                       1, ntreg);
 
     /* _DoFolderViewCB(SFVM_GETNOTIFY, ??  ??) */
 
diff --git a/dll/win32/shell32/changenotify.cpp 
b/dll/win32/shell32/changenotify.cpp
index ae5e0e8bdb4..08a7e632eba 100644
--- a/dll/win32/shell32/changenotify.cpp
+++ b/dll/win32/shell32/changenotify.cpp
@@ -294,13 +294,16 @@ CreateRegistrationParam(ULONG nRegID, HWND hwnd, UINT 
wMsg, INT fSources, LONG f
 // It creates a delivery ticket and send CN_DELIVER_NOTIFICATION message to
 // transport the change.
 static void
-CreateNotificationParamAndSend(LONG wEventId, UINT uFlags, LPITEMIDLIST pidl1, 
LPITEMIDLIST pidl2,
+CreateNotificationParamAndSend(LONG wEventId, UINT uFlags, LPCITEMIDLIST 
pidl1, LPCITEMIDLIST pidl2,
                                DWORD dwTick)
 {
     // get server window
     HWND hwndServer = GetNotificationServer(FALSE);
     if (hwndServer == NULL)
+    {
+        ERR("hwndServer == NULL\n");
         return;
+    }
 
     // the ticket owner is the process of the notification server
     DWORD pid;
@@ -314,10 +317,79 @@ CreateNotificationParamAndSend(LONG wEventId, UINT 
uFlags, LPITEMIDLIST pidl1, L
     TRACE("hTicket: %p, 0x%lx\n", hTicket, pid);
 
     // send the ticket by using CN_DELIVER_NOTIFICATION
-    if ((uFlags & (SHCNF_FLUSH | SHCNF_FLUSHNOWAIT)) == SHCNF_FLUSH)
+    if (pid != GetCurrentProcessId() ||
+        (uFlags & (SHCNF_FLUSH | SHCNF_FLUSHNOWAIT)) == SHCNF_FLUSH)
+    {
         SendMessageW(hwndServer, CN_DELIVER_NOTIFICATION, (WPARAM)hTicket, 
pid);
+    }
     else
+    {
         SendNotifyMessageW(hwndServer, CN_DELIVER_NOTIFICATION, 
(WPARAM)hTicket, pid);
+    }
+}
+
+struct ALIAS_PIDL
+{
+    INT csidl1; // from
+    INT csidl2; // to
+    LPITEMIDLIST pidl1; // from
+    LPITEMIDLIST pidl2; // to
+    WCHAR szPath1[MAX_PATH]; // from
+    WCHAR szPath2[MAX_PATH]; // to
+};
+
+static ALIAS_PIDL AliasPIDLs[] =
+{
+    { CSIDL_PERSONAL, CSIDL_PERSONAL },
+    { CSIDL_DESKTOP, CSIDL_COMMON_DESKTOPDIRECTORY, },
+    { CSIDL_DESKTOP, CSIDL_DESKTOPDIRECTORY },
+};
+
+static VOID DoInitAliasPIDLs(void)
+{
+    static BOOL s_bInit = FALSE;
+    if (!s_bInit)
+    {
+        for (SIZE_T i = 0; i < _countof(AliasPIDLs); ++i)
+        {
+            ALIAS_PIDL *alias = &AliasPIDLs[i];
+
+            SHGetSpecialFolderLocation(NULL, alias->csidl1, &alias->pidl1);
+            SHGetPathFromIDListW(alias->pidl1, alias->szPath1);
+
+            SHGetSpecialFolderLocation(NULL, alias->csidl2, &alias->pidl2);
+            SHGetPathFromIDListW(alias->pidl2, alias->szPath2);
+        }
+        s_bInit = TRUE;
+    }
+}
+
+static BOOL DoGetAliasPIDLs(LPITEMIDLIST apidls[2], PCIDLIST_ABSOLUTE pidl)
+{
+    DoInitAliasPIDLs();
+
+    apidls[0] = apidls[1] = NULL;
+
+    INT k = 0;
+    for (SIZE_T i = 0; i < _countof(AliasPIDLs); ++i)
+    {
+        const ALIAS_PIDL *alias = &AliasPIDLs[i];
+        if (ILIsEqual(pidl, alias->pidl1))
+        {
+            if (alias->csidl1 == alias->csidl2)
+            {
+                apidls[k++] = ILCreateFromPathW(alias->szPath2);
+            }
+            else
+            {
+                apidls[k++] = ILClone(alias->pidl2);
+            }
+            if (k >= 2)
+                break;
+        }
+    }
+
+    return k > 0;
 }
 
 /*************************************************************************
@@ -349,11 +421,10 @@ SHChangeNotifyRegister(HWND hwnd, INT fSources, LONG 
wEventMask, UINT uMsg,
     if (hwndServer == NULL)
         return INVALID_REG_ID;
 
-    // disable new delivery method in specific condition
-    if ((fSources & SHCNRF_RecursiveInterrupt) != 0 &&
-        (fSources & SHCNRF_InterruptLevel) == 0)
+    // disable recursive interrupt in specific condition
+    if ((fSources & SHCNRF_RecursiveInterrupt) && !(fSources & 
SHCNRF_InterruptLevel))
     {
-        fSources &= ~SHCNRF_NewDelivery;
+        fSources &= ~SHCNRF_RecursiveInterrupt;
     }
 
     // if it is old delivery method, then create a broker window
@@ -393,13 +464,62 @@ SHChangeNotifyRegister(HWND hwnd, INT fSources, LONG 
wEventMask, UINT uMsg,
             SHFreeShared(hRegEntry, dwOwnerPID);
         }
 
-        // if failed, then destroy the broker
-        if (nRegID == INVALID_REG_ID && (fSources & SHCNRF_NewDelivery) == 0)
+        if (nRegID == INVALID_REG_ID)
         {
             ERR("Delivery failed\n");
-            DestroyWindow(hwndBroker);
+
+            if (hwndBroker)
+            {
+                // destroy the broker
+                DestroyWindow(hwndBroker);
+            }
             break;
         }
+
+        // PIDL alias
+        LPITEMIDLIST apidlAlias[2];
+        if (DoGetAliasPIDLs(apidlAlias, lpItems[iItem].pidl))
+        {
+            if (apidlAlias[0])
+            {
+                // create another registration entry
+                hRegEntry = CreateRegistrationParam(nRegID, hwnd, uMsg, 
fSources, wEventMask,
+                                                    lpItems[iItem].fRecursive, 
apidlAlias[0],
+                                                    dwOwnerPID, hwndBroker);
+                if (hRegEntry)
+                {
+                    TRACE("CN_REGISTER: hwnd:%p, hRegEntry:%p, pid:0x%lx\n",
+                          hwndServer, hRegEntry, dwOwnerPID);
+
+                    // send CN_REGISTER to the server
+                    SendMessageW(hwndServer, CN_REGISTER, (WPARAM)hRegEntry, 
dwOwnerPID);
+
+                    // free registration entry
+                    SHFreeShared(hRegEntry, dwOwnerPID);
+                }
+                ILFree(apidlAlias[0]);
+            }
+
+            if (apidlAlias[1])
+            {
+                // create another registration entry
+                hRegEntry = CreateRegistrationParam(nRegID, hwnd, uMsg, 
fSources, wEventMask,
+                                                    lpItems[iItem].fRecursive, 
apidlAlias[1],
+                                                    dwOwnerPID, hwndBroker);
+                if (hRegEntry)
+                {
+                    TRACE("CN_REGISTER: hwnd:%p, hRegEntry:%p, pid:0x%lx\n",
+                          hwndServer, hRegEntry, dwOwnerPID);
+
+                    // send CN_REGISTER to the server
+                    SendMessageW(hwndServer, CN_REGISTER, (WPARAM)hRegEntry, 
dwOwnerPID);
+
+                    // free registration entry
+                    SHFreeShared(hRegEntry, dwOwnerPID);
+                }
+                ILFree(apidlAlias[1]);
+            }
+        }
     }
     LeaveCriticalSection(&SHELL32_ChangenotifyCS);
 
@@ -472,6 +592,39 @@ static LPCSTR DumpEvent(LONG event)
 #undef DUMPEV
 }
 
+/*************************************************************************
+ * SHChangeRegistrationReceive      [SHELL32.646]
+ */
+EXTERN_C BOOL WINAPI
+SHChangeRegistrationReceive(LPVOID lpUnknown1, DWORD dwUnknown2)
+{
+    FIXME("SHChangeRegistrationReceive() stub\n");
+    return FALSE;
+}
+
+EXTERN_C VOID WINAPI
+SHChangeNotifyReceiveEx(LONG lEvent, UINT uFlags,
+                        LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, DWORD dwTick)
+{
+    // TODO: Queueing notifications
+    CreateNotificationParamAndSend(lEvent, uFlags, pidl1, pidl2, dwTick);
+}
+
+/*************************************************************************
+ * SHChangeNotifyReceive        [SHELL32.643]
+ */
+EXTERN_C VOID WINAPI
+SHChangeNotifyReceive(LONG lEvent, UINT uFlags, LPCITEMIDLIST pidl1, 
LPCITEMIDLIST pidl2)
+{
+    SHChangeNotifyReceiveEx(lEvent, uFlags, pidl1, pidl2, GetTickCount());
+}
+
+EXTERN_C VOID WINAPI
+SHChangeNotifyTransmit(LONG lEvent, UINT uFlags, LPCITEMIDLIST pidl1, 
LPCITEMIDLIST pidl2, DWORD dwTick)
+{
+    SHChangeNotifyReceiveEx(lEvent, uFlags, pidl1, pidl2, dwTick);
+}
+
 /*************************************************************************
  * SHChangeNotify               [SHELL32.@]
  */
@@ -532,7 +685,7 @@ SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, 
LPCVOID dwItem2)
     if (wEventId == 0 || (wEventId & SHCNE_ASSOCCHANGED) || pidl1 != NULL)
     {
         TRACE("notifying event %s(%x)\n", DumpEvent(wEventId), wEventId);
-        CreateNotificationParamAndSend(wEventId, uFlags, pidl1, pidl2, dwTick);
+        SHChangeNotifyTransmit(wEventId, uFlags, pidl1, pidl2, dwTick);
     }
 
     if (pidlTemp1)
@@ -610,3 +763,17 @@ NTSHChangeNotifyDeregister(ULONG hNotify)
     FIXME("(0x%08x):semi stub.\n", hNotify);
     return SHChangeNotifyDeregister(hNotify);
 }
+
+/*************************************************************************
+ * SHChangeNotifySuspendResume          [SHELL32.277]
+ */
+EXTERN_C BOOL
+WINAPI
+SHChangeNotifySuspendResume(BOOL bSuspend,
+                            LPITEMIDLIST pidl,
+                            BOOL bRecursive,
+                            DWORD dwReserved)
+{
+    FIXME("SHChangeNotifySuspendResume() stub\n");
+    return FALSE;
+}
diff --git a/dll/win32/shell32/shelldesktop/CChangeNotifyServer.cpp 
b/dll/win32/shell32/shelldesktop/CChangeNotifyServer.cpp
index 2186fe20ca4..c0835faa919 100644
--- a/dll/win32/shell32/shelldesktop/CChangeNotifyServer.cpp
+++ b/dll/win32/shell32/shelldesktop/CChangeNotifyServer.cpp
@@ -11,8 +11,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(shcn);
 
-// TODO: SHCNRF_RecursiveInterrupt
-
 //////////////////////////////////////////////////////////////////////////////
 
 // notification target item
@@ -188,10 +186,6 @@ CreateDirectoryWatcherFromRegEntry(LPREGENTRY pRegEntry)
     if (pRegEntry->ibPidl == 0)
         return NULL;
 
-    // it must be interrupt level if pRegEntry is a filesystem watch
-    if (!(pRegEntry->fSources & SHCNRF_InterruptLevel))
-        return NULL;
-
     // get the path
     WCHAR szPath[MAX_PATH];
     LPITEMIDLIST pidl = (LPITEMIDLIST)((LPBYTE)pRegEntry + pRegEntry->ibPidl);
@@ -249,13 +243,18 @@ LRESULT CChangeNotifyServer::OnRegister(UINT uMsg, WPARAM 
wParam, LPARAM lParam,
     }
 
     // create a directory watch if necessary
-    CDirectoryWatcher *pDirWatch = 
CreateDirectoryWatcherFromRegEntry(pRegEntry);
-    if (pDirWatch && !pDirWatch->RequestAddWatcher())
+    CDirectoryWatcher *pDirWatch = NULL;
+    if (pRegEntry->ibPidl && (pRegEntry->fSources & SHCNRF_InterruptLevel))
     {
-        pRegEntry->nRegID = INVALID_REG_ID;
-        SHUnlockShared(pRegEntry);
-        delete pDirWatch;
-        return FALSE;
+        pDirWatch = CreateDirectoryWatcherFromRegEntry(pRegEntry);
+        if (pDirWatch && !pDirWatch->RequestAddWatcher())
+        {
+            ERR("RequestAddWatcher failed: %u\n", pRegEntry->nRegID);
+            pRegEntry->nRegID = INVALID_REG_ID;
+            SHUnlockShared(pRegEntry);
+            delete pDirWatch;
+            return FALSE;
+        }
     }
 
     // unlock the registry entry
@@ -386,6 +385,7 @@ BOOL CChangeNotifyServer::DeliverNotification(HANDLE 
hTicket, DWORD dwOwnerPID)
             TRACE("Notifying: %p, 0x%x, %p, %lu\n",
                   pRegEntry->hwnd, pRegEntry->uMsg, hTicket, dwOwnerPID);
             SendMessageW(pRegEntry->hwnd, pRegEntry->uMsg, (WPARAM)hTicket, 
dwOwnerPID);
+            TRACE("GetLastError(): %ld\n", ::GetLastError());
         }
 
         // unlock the registration entry
@@ -400,91 +400,58 @@ BOOL CChangeNotifyServer::DeliverNotification(HANDLE 
hTicket, DWORD dwOwnerPID)
 
 BOOL CChangeNotifyServer::ShouldNotify(LPDELITICKET pTicket, LPREGENTRY 
pRegEntry)
 {
-    LPITEMIDLIST pidl, pidl1 = NULL, pidl2 = NULL;
-    WCHAR szPath[MAX_PATH], szPath1[MAX_PATH], szPath2[MAX_PATH];
-    INT cch, cch1, cch2;
+#define RETURN(x) do { \
+    TRACE("ShouldNotify return %d\n", (x)); \
+    return (x); \
+} while (0)
 
-    // check fSources
-    if (pTicket->uFlags & SHCNE_INTERRUPT)
+    if (pTicket->wEventId & SHCNE_INTERRUPT)
     {
         if (!(pRegEntry->fSources & SHCNRF_InterruptLevel))
-            return FALSE;
+            RETURN(FALSE);
+        if (!pRegEntry->ibPidl)
+            RETURN(FALSE);
     }
     else
     {
         if (!(pRegEntry->fSources & SHCNRF_ShellLevel))
-            return FALSE;
+            RETURN(FALSE);
     }
 
-    if (pRegEntry->ibPidl == 0)
-        return TRUE; // there is no PIDL
-
-    // get the stored pidl
-    pidl = (LPITEMIDLIST)((LPBYTE)pRegEntry + pRegEntry->ibPidl);
-    if (pidl->mkid.cb == 0 && pRegEntry->fRecursive)
-        return TRUE;    // desktop is the root
+    if (!(pTicket->wEventId & pRegEntry->fEvents))
+        RETURN(FALSE);
 
-    // check pidl1
+    LPITEMIDLIST pidl = NULL, pidl1 = NULL, pidl2 = NULL;
+    if (pRegEntry->ibPidl)
+        pidl = (LPITEMIDLIST)((LPBYTE)pRegEntry + pRegEntry->ibPidl);
     if (pTicket->ibOffset1)
-    {
         pidl1 = (LPITEMIDLIST)((LPBYTE)pTicket + pTicket->ibOffset1);
-        if (ILIsEqual(pidl, pidl1) || ILIsParent(pidl, pidl1, 
!pRegEntry->fRecursive))
-            return TRUE;
-    }
-
-    // check pidl2
     if (pTicket->ibOffset2)
-    {
         pidl2 = (LPITEMIDLIST)((LPBYTE)pTicket + pTicket->ibOffset2);
-        if (ILIsEqual(pidl, pidl2) || ILIsParent(pidl, pidl2, 
!pRegEntry->fRecursive))
-            return TRUE;
-    }
 
-    // The paths:
-    //   "C:\\Path\\To\\File1"
-    //   "C:\\Path\\To\\File1Test"
-    // should be distinguished in comparison, so we add backslash at last as 
follows:
-    //   "C:\\Path\\To\\File1\\"
-    //   "C:\\Path\\To\\File1Test\\"
-    if (SHGetPathFromIDListW(pidl, szPath))
-    {
-        PathAddBackslashW(szPath);
-        cch = lstrlenW(szPath);
+    if (pidl == NULL || (pTicket->wEventId & SHCNE_GLOBALEVENTS))
+        RETURN(TRUE);
 
-        if (pidl1 && SHGetPathFromIDListW(pidl1, szPath1))
+    if (pRegEntry->fRecursive)
+    {
+        if (ILIsParent(pidl, pidl1, FALSE) ||
+            (pidl2 && ILIsParent(pidl, pidl2, FALSE)))
         {
-            PathAddBackslashW(szPath1);
-            cch1 = lstrlenW(szPath1);
-
-            // Is szPath1 a subfile or subdirectory of szPath?
-            if (cch < cch1 &&
-                (pRegEntry->fRecursive ||
-                 wcschr(&szPath1[cch], L'\\') == &szPath1[cch1 - 1]))
-            {
-                szPath1[cch] = 0;
-                if (lstrcmpiW(szPath, szPath1) == 0)
-                    return TRUE;
-            }
+            RETURN(TRUE);
         }
-
-        if (pidl2 && SHGetPathFromIDListW(pidl2, szPath2))
+    }
+    else
+    {
+        if (ILIsEqual(pidl, pidl1) ||
+            ILIsParent(pidl, pidl1, TRUE) ||
+            (pidl2 && ILIsParent(pidl, pidl2, TRUE)))
         {
-            PathAddBackslashW(szPath2);
-            cch2 = lstrlenW(szPath2);
-
-            // Is szPath2 a subfile or subdirectory of szPath?
-            if (cch < cch2 &&
-                (pRegEntry->fRecursive ||
-                 wcschr(&szPath2[cch], L'\\') == &szPath2[cch2 - 1]))
-            {
-                szPath2[cch] = 0;
-                if (lstrcmpiW(szPath, szPath2) == 0)
-                    return TRUE;
-            }
+            RETURN(TRUE);
         }
     }
 
-    return FALSE;
+    RETURN(FALSE);
+#undef RETURN
 }
 
 HRESULT WINAPI CChangeNotifyServer::GetWindow(HWND* phwnd)
diff --git a/dll/win32/shell32/shelldesktop/CDirectoryList.cpp 
b/dll/win32/shell32/shelldesktop/CDirectoryList.cpp
index eff446df467..2bdd36f0eb0 100644
--- a/dll/win32/shell32/shelldesktop/CDirectoryList.cpp
+++ b/dll/win32/shell32/shelldesktop/CDirectoryList.cpp
@@ -28,6 +28,16 @@ BOOL CDirectoryList::ContainsPath(LPCWSTR pszPath) const
 BOOL CDirectoryList::AddPath(LPCWSTR pszPath)
 {
     assert(!PathIsRelativeW(pszPath));
+    if (ContainsPath(pszPath))
+        return FALSE;
+    for (INT i = 0; i < m_items.GetSize(); ++i)
+    {
+        if (m_items[i].IsEmpty())
+        {
+            m_items[i].SetPath(pszPath);
+            return TRUE;
+        }
+    }
     return m_items.Add(pszPath);
 }
 
diff --git a/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp 
b/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp
index 9a206ac673a..1e4a7015287 100644
--- a/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp
+++ b/dll/win32/shell32/shelldesktop/CDirectoryWatcher.cpp
@@ -15,7 +15,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(shcn);
 static inline void
 NotifyFileSystemChange(LONG wEventId, LPCWSTR path1, LPCWSTR path2)
 {
-    SHChangeNotify(wEventId | SHCNE_INTERRUPT, SHCNF_PATHW, path1, path2);
+    SHChangeNotify(wEventId | SHCNE_INTERRUPT, SHCNF_PATHW | SHCNF_FLUSH, 
path1, path2);
 }
 
 // The handle of the APC thread
@@ -138,6 +138,7 @@ void CDirectoryWatcher::ProcessNotification()
     WCHAR szName[MAX_PATH], szPath[MAX_PATH], szTempPath[MAX_PATH];
     DWORD dwEvent, cbName;
     BOOL fDir;
+    TRACE("CDirectoryWatcher::ProcessNotification: enter\n");
 
     // for each entry in s_buffer
     szPath[0] = szTempPath[0] = 0;
@@ -225,6 +226,8 @@ void CDirectoryWatcher::ProcessNotification()
         // go next entry
         pInfo = (PFILE_NOTIFY_INFORMATION)((LPBYTE)pInfo + 
pInfo->NextEntryOffset);
     }
+
+    TRACE("CDirectoryWatcher::ProcessNotification: leave\n");
 }
 
 void CDirectoryWatcher::ReadCompletion(DWORD dwErrorCode, DWORD 
dwNumberOfBytesTransfered)
diff --git a/dll/win32/shell32/stubs.cpp b/dll/win32/shell32/stubs.cpp
index ebba2f3b298..a995e395509 100644
--- a/dll/win32/shell32/stubs.cpp
+++ b/dll/win32/shell32/stubs.cpp
@@ -329,17 +329,6 @@ CDefFolderMenu_Create(LPITEMIDLIST pidlFolder,
     return E_FAIL;
 }
 
-/*
- * Unimplemented
- */
-EXTERN_C BOOL
-WINAPI
-SHChangeRegistrationReceive(LPVOID lpUnknown1, DWORD dwUnknown2)
-{
-    FIXME("SHChangeRegistrationReceive() stub\n");
-    return FALSE;
-}
-
 /*
  * Unimplemented
  */
@@ -350,16 +339,6 @@ SHWaitOp_Operate(LPVOID lpUnknown1, DWORD dwUnknown2)
     FIXME("SHWaitOp_Operate() stub\n");
 }
 
-/*
- * Unimplemented
- */
-EXTERN_C VOID
-WINAPI
-SHChangeNotifyReceive(LONG lUnknown, UINT uUnknown, LPCITEMIDLIST pidl1, 
LPCITEMIDLIST pidl2)
-{
-    FIXME("SHChangeNotifyReceive() stub\n");
-}
-
 /*
  * Unimplemented
  */
@@ -625,20 +604,6 @@ SHCreateProcessAsUserW(PSHCREATEPROCESSINFOW pscpi)
     return FALSE;
 }
 
-/*
- * Unimplemented
- */
-EXTERN_C BOOL
-WINAPI
-SHChangeNotifySuspendResume(BOOL bSuspend,
-                            LPITEMIDLIST pidl,
-                            BOOL bRecursive,
-                            DWORD dwReserved)
-{
-    FIXME("SHChangeNotifySuspendResume() stub\n");
-    return FALSE;
-}
-
 /*
  * Unimplemented
  */
diff --git a/dll/win32/shell32/wine/pidl.c b/dll/win32/shell32/wine/pidl.c
index a813f9293cd..1f27557db9b 100644
--- a/dll/win32/shell32/wine/pidl.c
+++ b/dll/win32/shell32/wine/pidl.c
@@ -1101,8 +1101,13 @@ LPITEMIDLIST WINAPI SHSimpleIDListFromPathA(LPCSTR 
lpszPath)
         MultiByteToWideChar(CP_ACP, 0, lpszPath, -1, wPath, len);
     }
 #ifdef __REACTOS__
+    // FIXME: Needs folder attribute
     if (PathFileExistsW(wPath))
-        return ILCreateFromPathW(wPath);
+    {
+        pidl = ILCreateFromPathW(wPath);
+        HeapFree(GetProcessHeap(), 0, wPath);
+        return pidl;
+    }
 #endif
 
     _ILParsePathW(wPath, NULL, TRUE, &pidl, NULL);
@@ -1118,6 +1123,7 @@ LPITEMIDLIST WINAPI SHSimpleIDListFromPathW(LPCWSTR 
lpszPath)
 
     TRACE("%s\n", debugstr_w(lpszPath));
 #ifdef __REACTOS__
+    // FIXME: Needs folder attribute
     if (PathFileExistsW(lpszPath))
         return ILCreateFromPathW(lpszPath);
 #endif

Reply via email to