mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[SHELL32] Big fix for change notification (#3048)
- Reduced the failures of SHChangeNotify testcase. - Simplified change notification mechanism. - Realized PIDL aliasing. CORE-13950
This commit is contained in:
parent
7ffb6a09c3
commit
7c134e4d14
7 changed files with 244 additions and 151 deletions
|
@ -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, ?? ??) */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
if (!(pTicket->wEventId & pRegEntry->fEvents))
|
||||
RETURN(FALSE);
|
||||
|
||||
// get the stored pidl
|
||||
pidl = (LPITEMIDLIST)((LPBYTE)pRegEntry + pRegEntry->ibPidl);
|
||||
if (pidl->mkid.cb == 0 && pRegEntry->fRecursive)
|
||||
return TRUE; // desktop is the root
|
||||
|
||||
// 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))
|
||||
if (pidl == NULL || (pTicket->wEventId & SHCNE_GLOBALEVENTS))
|
||||
RETURN(TRUE);
|
||||
|
||||
if (pRegEntry->fRecursive)
|
||||
{
|
||||
PathAddBackslashW(szPath);
|
||||
cch = lstrlenW(szPath);
|
||||
|
||||
if (pidl1 && SHGetPathFromIDListW(pidl1, szPath1))
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue