https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7c134e4d14efa98eac47e…
commit 7c134e4d14efa98eac47e8b6b4b3589d5db8f8ac
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu Sep 3 13:36:31 2020 +0900
Commit: GitHub <noreply(a)github.com>
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