ReactOS 0.4.15-dev-7887-g64a59a1
changenotify.cpp File Reference
#include "precomp.h"
Include dependency graph for changenotify.cpp:

Go to the source code of this file.

Classes

class  CChangeNotifyBroker
 
struct  ALIAS_PIDL
 

Macros

#define DUMPEV(x)   ,( event & SHCNE_##x )? #x " " : ""
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (shcn)
 
static HWND GetNotificationServer (BOOL bCreate)
 
EXTERN_C void InitChangeNotifications (void)
 
EXTERN_C void FreeChangeNotifications (void)
 
static HWND CreateNotificationBroker (HWND hwnd, UINT wMsg)
 
static HANDLE CreateNotificationParam (LONG wEventId, UINT uFlags, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, DWORD dwOwnerPID, DWORD dwTick)
 
static LPHANDBAG DoGetHandbagFromTicket (HANDLE hTicket, DWORD dwOwnerPID)
 
static HANDLE CreateRegistrationParam (ULONG nRegID, HWND hwnd, UINT wMsg, INT fSources, LONG fEvents, LONG fRecursive, LPCITEMIDLIST pidl, DWORD dwOwnerPID, HWND hwndBroker)
 
static void CreateNotificationParamAndSend (LONG wEventId, UINT uFlags, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, DWORD dwTick)
 
static VOID DoInitAliasPIDLs (void)
 
static BOOL DoGetAliasPIDLs (LPITEMIDLIST apidls[2], PCIDLIST_ABSOLUTE pidl)
 
EXTERN_C ULONG WINAPI SHChangeNotifyRegister (HWND hwnd, INT fSources, LONG wEventMask, UINT uMsg, INT cItems, SHChangeNotifyEntry *lpItems)
 
EXTERN_C BOOL WINAPI SHChangeNotifyDeregister (ULONG hNotify)
 
EXTERN_C BOOL WINAPI SHChangeNotifyUpdateEntryList (DWORD unknown1, DWORD unknown2, DWORD unknown3, DWORD unknown4)
 
static LPCSTR DumpEvent (LONG event)
 
EXTERN_C BOOL WINAPI SHChangeRegistrationReceive (LPVOID lpUnknown1, DWORD dwUnknown2)
 
EXTERN_C VOID WINAPI SHChangeNotifyReceiveEx (LONG lEvent, UINT uFlags, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, DWORD dwTick)
 
EXTERN_C VOID WINAPI SHChangeNotifyReceive (LONG lEvent, UINT uFlags, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 
EXTERN_C VOID WINAPI SHChangeNotifyTransmit (LONG lEvent, UINT uFlags, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, DWORD dwTick)
 
EXTERN_C void WINAPI SHChangeNotify (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
 
EXTERN_C ULONG WINAPI NTSHChangeNotifyRegister (HWND hwnd, INT fSources, LONG fEvents, UINT msg, INT count, SHChangeNotifyEntry *idlist)
 
EXTERN_C HANDLE WINAPI SHChangeNotification_Lock (HANDLE hTicket, DWORD dwOwnerPID, LPITEMIDLIST **lppidls, LPLONG lpwEventId)
 
EXTERN_C BOOL WINAPI SHChangeNotification_Unlock (HANDLE hLock)
 
EXTERN_C DWORD WINAPI NTSHChangeNotifyDeregister (ULONG hNotify)
 
EXTERN_C BOOL WINAPI SHChangeNotifySuspendResume (BOOL bSuspend, LPITEMIDLIST pidl, BOOL bRecursive, DWORD dwReserved)
 

Variables

CRITICAL_SECTION SHELL32_ChangenotifyCS
 
static ALIAS_PIDL AliasPIDLs []
 

Macro Definition Documentation

◆ DUMPEV

#define DUMPEV (   x)    ,( event & SHCNE_##x )? #x " " : ""

Function Documentation

◆ CreateNotificationBroker()

static HWND CreateNotificationBroker ( HWND  hwnd,
UINT  wMsg 
)
static

Definition at line 127 of file changenotify.cpp.

128{
129 // Create a new broker. It will be freed when the window gets destroyed
130 CChangeNotifyBroker* pBroker = new CChangeNotifyBroker(hwnd, wMsg);
131 if (pBroker == NULL)
132 {
133 ERR("Out of memory\n");
134 return NULL;
135 }
136
137 HWND hwndBroker = SHCreateDefaultWorkerWindow();
138 if (hwndBroker == NULL)
139 {
140 ERR("hwndBroker == NULL\n");
141 delete pBroker;
142 return NULL;
143 }
144
145 pBroker->SubclassWindow(hwndBroker);
146 return hwndBroker;
147}
HWND SHCreateDefaultWorkerWindow(VOID)
#define ERR(fmt,...)
Definition: debug.h:110
BOOL SubclassWindow(HWND hWnd)
Definition: atlwin.h:1552
#define NULL
Definition: types.h:112
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023

Referenced by SHChangeNotifyRegister().

◆ CreateNotificationParam()

static HANDLE CreateNotificationParam ( LONG  wEventId,
UINT  uFlags,
LPCITEMIDLIST  pidl1,
LPCITEMIDLIST  pidl2,
DWORD  dwOwnerPID,
DWORD  dwTick 
)
static

Definition at line 152 of file changenotify.cpp.

154{
155 // pidl1 and pidl2 have variable length. To store them into the delivery ticket,
156 // we have to consider the offsets and the sizes of pidl1 and pidl2.
157 DWORD cbPidl1 = 0, cbPidl2 = 0, ibOffset1 = 0, ibOffset2 = 0;
158 if (pidl1)
159 {
160 cbPidl1 = ILGetSize(pidl1);
161 ibOffset1 = DWORD_ALIGNMENT(sizeof(DELITICKET));
162 }
163 if (pidl2)
164 {
165 cbPidl2 = ILGetSize(pidl2);
166 ibOffset2 = DWORD_ALIGNMENT(ibOffset1 + cbPidl1);
167 }
168
169 // allocate the delivery ticket
170 DWORD cbSize = ibOffset2 + cbPidl2;
171 HANDLE hTicket = SHAllocShared(NULL, cbSize, dwOwnerPID);
172 if (hTicket == NULL)
173 {
174 ERR("Out of memory\n");
175 return NULL;
176 }
177
178 // lock the ticket
179 LPDELITICKET pTicket = (LPDELITICKET)SHLockSharedEx(hTicket, dwOwnerPID, TRUE);
180 if (pTicket == NULL)
181 {
182 ERR("SHLockSharedEx failed\n");
183 SHFreeShared(hTicket, dwOwnerPID);
184 return NULL;
185 }
186
187 // populate the ticket
188 pTicket->dwMagic = DELITICKET_MAGIC;
189 pTicket->wEventId = wEventId;
190 pTicket->uFlags = uFlags;
191 pTicket->ibOffset1 = ibOffset1;
192 pTicket->ibOffset2 = ibOffset2;
193 if (pidl1)
194 memcpy((LPBYTE)pTicket + ibOffset1, pidl1, cbPidl1);
195 if (pidl2)
196 memcpy((LPBYTE)pTicket + ibOffset2, pidl2, cbPidl2);
197
198 // unlock the ticket and return
199 SHUnlockShared(pTicket);
200 return hTicket;
201}
struct DELITICKET * LPDELITICKET
#define DELITICKET_MAGIC
#define DWORD_ALIGNMENT(offset)
#define TRUE
Definition: types.h:120
UINT uFlags
Definition: api.c:59
HANDLE WINAPI SHAllocShared(LPCVOID lpvData, DWORD dwSize, DWORD dwProcId)
Definition: ordinal.c:165
BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
Definition: ordinal.c:311
BOOL WINAPI SHUnlockShared(LPVOID lpView)
Definition: ordinal.c:291
unsigned long DWORD
Definition: ntddk_ex.h:95
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ILGetSize
Definition: shellclasses.h:638
PVOID WINAPI SHLockSharedEx(HANDLE hData, DWORD dwProcessId, BOOL bWriteAccess)
unsigned char * LPBYTE
Definition: typedefs.h:53

Referenced by CreateNotificationParamAndSend().

◆ CreateNotificationParamAndSend()

static void CreateNotificationParamAndSend ( LONG  wEventId,
UINT  uFlags,
LPCITEMIDLIST  pidl1,
LPCITEMIDLIST  pidl2,
DWORD  dwTick 
)
static

Definition at line 294 of file changenotify.cpp.

296{
297 // get server window
298 HWND hwndServer = GetNotificationServer(FALSE);
299 if (hwndServer == NULL)
300 return;
301
302 // the ticket owner is the process of the notification server
303 DWORD pid;
304 GetWindowThreadProcessId(hwndServer, &pid);
305
306 // create a delivery ticket
307 HANDLE hTicket = CreateNotificationParam(wEventId, uFlags, pidl1, pidl2, pid, dwTick);
308 if (hTicket == NULL)
309 return;
310
311 TRACE("hTicket: %p, 0x%lx\n", hTicket, pid);
312
313 // send the ticket by using CN_DELIVER_NOTIFICATION
314 if (pid != GetCurrentProcessId() ||
316 {
317 SendMessageW(hwndServer, CN_DELIVER_NOTIFICATION, (WPARAM)hTicket, pid);
318 }
319 else
320 {
322 }
323}
#define CN_DELIVER_NOTIFICATION
static HWND GetNotificationServer(BOOL bCreate)
static HANDLE CreateNotificationParam(LONG wEventId, UINT uFlags, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, DWORD dwOwnerPID, DWORD dwTick)
#define FALSE
Definition: types.h:117
#define SHCNF_FLUSH
Definition: shlobj.h:1913
#define SHCNF_FLUSHNOWAIT
Definition: shlobj.h:1914
#define TRACE(s)
Definition: solgame.cpp:4
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
UINT_PTR WPARAM
Definition: windef.h:207
BOOL WINAPI SendNotifyMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)

Referenced by SHChangeNotifyReceiveEx().

◆ CreateRegistrationParam()

static HANDLE CreateRegistrationParam ( ULONG  nRegID,
HWND  hwnd,
UINT  wMsg,
INT  fSources,
LONG  fEvents,
LONG  fRecursive,
LPCITEMIDLIST  pidl,
DWORD  dwOwnerPID,
HWND  hwndBroker 
)
static

Definition at line 243 of file changenotify.cpp.

246{
247 // pidl has variable length. To store it into the registration entry,
248 // we have to consider the length of pidl.
249 DWORD cbPidl = ILGetSize(pidl);
250 DWORD ibPidl = DWORD_ALIGNMENT(sizeof(REGENTRY));
251 DWORD cbSize = ibPidl + cbPidl;
252
253 // create the registration entry and lock it
254 HANDLE hRegEntry = SHAllocShared(NULL, cbSize, dwOwnerPID);
255 if (hRegEntry == NULL)
256 {
257 ERR("Out of memory\n");
258 return NULL;
259 }
260 LPREGENTRY pRegEntry = (LPREGENTRY)SHLockSharedEx(hRegEntry, dwOwnerPID, TRUE);
261 if (pRegEntry == NULL)
262 {
263 ERR("SHLockSharedEx failed\n");
264 SHFreeShared(hRegEntry, dwOwnerPID);
265 return NULL;
266 }
267
268 // populate the registration entry
269 pRegEntry->dwMagic = REGENTRY_MAGIC;
270 pRegEntry->cbSize = cbSize;
271 pRegEntry->nRegID = nRegID;
272 pRegEntry->hwnd = hwnd;
273 pRegEntry->uMsg = wMsg;
274 pRegEntry->fSources = fSources;
275 pRegEntry->fEvents = fEvents;
276 pRegEntry->fRecursive = fRecursive;
277 pRegEntry->hwndBroker = hwndBroker;
278 pRegEntry->ibPidl = 0;
279 if (pidl)
280 {
281 pRegEntry->ibPidl = ibPidl;
282 memcpy((LPBYTE)pRegEntry + ibPidl, pidl, cbPidl);
283 }
284
285 // unlock and return
286 SHUnlockShared(pRegEntry);
287 return hRegEntry;
288}
#define REGENTRY_MAGIC
struct REGENTRY * LPREGENTRY

Referenced by SHChangeNotifyRegister().

◆ DoGetAliasPIDLs()

static BOOL DoGetAliasPIDLs ( LPITEMIDLIST  apidls[2],
PCIDLIST_ABSOLUTE  pidl 
)
static

Definition at line 361 of file changenotify.cpp.

362{
364
365 apidls[0] = apidls[1] = NULL;
366
367 INT k = 0;
368 for (SIZE_T i = 0; i < _countof(AliasPIDLs); ++i)
369 {
370 const ALIAS_PIDL *alias = &AliasPIDLs[i];
371 if (ILIsEqual(pidl, alias->pidl1))
372 {
373 if (alias->csidl1 == alias->csidl2)
374 {
375 apidls[k++] = ILCreateFromPathW(alias->szPath2);
376 }
377 else
378 {
379 apidls[k++] = ILClone(alias->pidl2);
380 }
381 if (k >= 2)
382 break;
383 }
384 }
385
386 return k > 0;
387}
const WCHAR * alias
Definition: main.c:67
static VOID DoInitAliasPIDLs(void)
static ALIAS_PIDL AliasPIDLs[]
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
int k
Definition: mpi.c:3369
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:995
BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:548
#define _countof(array)
Definition: sndvol32.h:68
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58

Referenced by SHChangeNotifyRegister().

◆ DoGetHandbagFromTicket()

static LPHANDBAG DoGetHandbagFromTicket ( HANDLE  hTicket,
DWORD  dwOwnerPID 
)
static

Definition at line 208 of file changenotify.cpp.

209{
210 // lock and validate the delivery ticket
211 LPDELITICKET pTicket = (LPDELITICKET)SHLockSharedEx(hTicket, dwOwnerPID, FALSE);
212 if (pTicket == NULL || pTicket->dwMagic != DELITICKET_MAGIC)
213 {
214 ERR("pTicket is invalid\n");
215 SHUnlockShared(pTicket);
216 return NULL;
217 }
218
219 // allocate the handbag
220 LPHANDBAG pHandbag = (LPHANDBAG)LocalAlloc(LMEM_FIXED, sizeof(HANDBAG));
221 if (pHandbag == NULL)
222 {
223 ERR("Out of memory\n");
224 SHUnlockShared(pTicket);
225 return NULL;
226 }
227
228 // populate the handbag
229 pHandbag->dwMagic = HANDBAG_MAGIC;
230 pHandbag->pTicket = pTicket;
231
232 pHandbag->pidls[0] = pHandbag->pidls[1] = NULL;
233 if (pTicket->ibOffset1)
234 pHandbag->pidls[0] = (LPITEMIDLIST)((LPBYTE)pTicket + pTicket->ibOffset1);
235 if (pTicket->ibOffset2)
236 pHandbag->pidls[1] = (LPITEMIDLIST)((LPBYTE)pTicket + pTicket->ibOffset2);
237
238 return pHandbag;
239}
#define HANDBAG_MAGIC
struct HANDBAG * LPHANDBAG
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
LPDELITICKET pTicket
LPITEMIDLIST pidls[2]
#define LMEM_FIXED
Definition: winbase.h:368

Referenced by SHChangeNotification_Lock().

◆ DoInitAliasPIDLs()

static VOID DoInitAliasPIDLs ( void  )
static

Definition at line 342 of file changenotify.cpp.

343{
344 static BOOL s_bInit = FALSE;
345 if (!s_bInit)
346 {
347 for (SIZE_T i = 0; i < _countof(AliasPIDLs); ++i)
348 {
350
351 SHGetSpecialFolderLocation(NULL, alias->csidl1, &alias->pidl1);
352 SHGetPathFromIDListW(alias->pidl1, alias->szPath1);
353
354 SHGetSpecialFolderLocation(NULL, alias->csidl2, &alias->pidl2);
355 SHGetPathFromIDListW(alias->pidl2, alias->szPath2);
356 }
357 s_bInit = TRUE;
358 }
359}
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3225
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1353

Referenced by DoGetAliasPIDLs().

◆ DumpEvent()

static LPCSTR DumpEvent ( LONG  event)
static

Definition at line 557 of file changenotify.cpp.

558{
559 if (event == SHCNE_ALLEVENTS)
560 return "SHCNE_ALLEVENTS";
561#define DUMPEV(x) ,( event & SHCNE_##x )? #x " " : ""
562 return wine_dbg_sprintf( "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
563 DUMPEV(RENAMEITEM)
564 DUMPEV(CREATE)
567 DUMPEV(RMDIR)
568 DUMPEV(MEDIAINSERTED)
569 DUMPEV(MEDIAREMOVED)
570 DUMPEV(DRIVEREMOVED)
571 DUMPEV(DRIVEADD)
572 DUMPEV(NETSHARE)
573 DUMPEV(NETUNSHARE)
574 DUMPEV(ATTRIBUTES)
575 DUMPEV(UPDATEDIR)
576 DUMPEV(UPDATEITEM)
577 DUMPEV(SERVERDISCONNECT)
578 DUMPEV(UPDATEIMAGE)
579 DUMPEV(DRIVEADDGUI)
580 DUMPEV(RENAMEFOLDER)
581 DUMPEV(FREESPACE)
582 DUMPEV(EXTENDED_EVENT)
583 DUMPEV(ASSOCCHANGED)
584 DUMPEV(INTERRUPT)
585 );
586#undef DUMPEV
587}
#define DUMPEV(x)
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
struct _cl_event * event
Definition: glext.h:7739
#define DELETE
Definition: nt_native.h:57
#define MKDIR(d)
Definition: compat.h:27
#define SHCNE_ALLEVENTS
Definition: shlobj.h:1899

Referenced by SHChangeNotify().

◆ FreeChangeNotifications()

EXTERN_C void FreeChangeNotifications ( void  )

Definition at line 52 of file changenotify.cpp.

53{
54 HWND hwndServer = GetNotificationServer(FALSE);
55 if (hwndServer)
58}
#define CN_UNREGISTER_PROCESS
CRITICAL_SECTION SHELL32_ChangenotifyCS
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

◆ GetNotificationServer()

static HWND GetNotificationServer ( BOOL  bCreate)
static

Definition at line 16 of file changenotify.cpp.

17{
18 static HWND s_hwndServer = NULL;
19
20 // use cache if any
21 if (s_hwndServer && IsWindow(s_hwndServer))
22 return s_hwndServer;
23
24 // get the shell window
25 HWND hwndShell = GetShellWindow();
26 if (hwndShell == NULL)
27 {
28 TRACE("GetShellWindow() returned NULL\n");
29 return NULL;
30 }
31
32 // Get the window of the notification server that runs in explorer
33 HWND hwndServer = (HWND)SendMessageW(hwndShell, WM_DESKTOP_GET_CNOTIFY_SERVER, bCreate, 0);
34 if (!IsWindow(hwndServer))
35 {
36 ERR("Unable to get server window\n");
37 hwndServer = NULL;
38 }
39
40 // save and return
41 s_hwndServer = hwndServer;
42 return hwndServer;
43}
#define WM_DESKTOP_GET_CNOTIFY_SERVER
HANDLE HWND
Definition: compat.h:19
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1511
HWND WINAPI GetShellWindow(VOID)
Definition: desktop.c:651
BOOL WINAPI IsWindow(_In_opt_ HWND)

Referenced by CreateNotificationParamAndSend(), FreeChangeNotifications(), SHChangeNotifyDeregister(), and SHChangeNotifyRegister().

◆ InitChangeNotifications()

EXTERN_C void InitChangeNotifications ( void  )

Definition at line 46 of file changenotify.cpp.

47{
49}
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751

Referenced by if().

◆ NTSHChangeNotifyDeregister()

EXTERN_C DWORD WINAPI NTSHChangeNotifyDeregister ( ULONG  hNotify)

Definition at line 755 of file changenotify.cpp.

756{
757 FIXME("(0x%08x):semi stub.\n", hNotify);
758 return SHChangeNotifyDeregister(hNotify);
759}
#define FIXME(fmt,...)
Definition: debug.h:111
EXTERN_C BOOL WINAPI SHChangeNotifyDeregister(ULONG hNotify)

◆ NTSHChangeNotifyRegister()

EXTERN_C ULONG WINAPI NTSHChangeNotifyRegister ( HWND  hwnd,
INT  fSources,
LONG  fEvents,
UINT  msg,
INT  count,
SHChangeNotifyEntry idlist 
)

Definition at line 695 of file changenotify.cpp.

697{
699 fEvents, msg, count, idlist);
700}
#define msg(x)
Definition: auth_time.c:54
EXTERN_C ULONG WINAPI SHChangeNotifyRegister(HWND hwnd, INT fSources, LONG wEventMask, UINT uMsg, INT cItems, SHChangeNotifyEntry *lpItems)
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define SHCNRF_NewDelivery
Definition: shlobj.h:1923

◆ SHChangeNotification_Lock()

EXTERN_C HANDLE WINAPI SHChangeNotification_Lock ( HANDLE  hTicket,
DWORD  dwOwnerPID,
LPITEMIDLIST **  lppidls,
LPLONG  lpwEventId 
)

Definition at line 706 of file changenotify.cpp.

708{
709 TRACE("%p %08x %p %p\n", hTicket, dwOwnerPID, lppidls, lpwEventId);
710
711 // create a handbag from the ticket
712 LPHANDBAG pHandbag = DoGetHandbagFromTicket(hTicket, dwOwnerPID);
713 if (pHandbag == NULL || pHandbag->dwMagic != HANDBAG_MAGIC)
714 {
715 ERR("pHandbag is invalid\n");
716 return NULL;
717 }
718
719 // populate parameters from the handbag
720 if (lppidls)
721 *lppidls = pHandbag->pidls;
722 if (lpwEventId)
723 *lpwEventId = (pHandbag->pTicket->wEventId & ~SHCNE_INTERRUPT);
724
725 // return the handbag
726 return pHandbag;
727}
static LPHANDBAG DoGetHandbagFromTicket(HANDLE hTicket, DWORD dwOwnerPID)

Referenced by CChangeNotifyBroker::BrokerNotification(), CDefView::OnChangeNotify(), OnShellNotify(), and testwindow_wndproc().

◆ SHChangeNotification_Unlock()

EXTERN_C BOOL WINAPI SHChangeNotification_Unlock ( HANDLE  hLock)

Definition at line 733 of file changenotify.cpp.

734{
735 TRACE("%p\n", hLock);
736
737 // validate the handbag
738 LPHANDBAG pHandbag = (LPHANDBAG)hLock;
739 if (pHandbag == NULL || pHandbag->dwMagic != HANDBAG_MAGIC)
740 {
741 ERR("pHandbag is invalid\n");
742 return FALSE;
743 }
744
745 // free the handbag
746 BOOL ret = SHUnlockShared(pHandbag->pTicket);
747 LocalFree(hLock);
748 return ret;
749}
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
int ret

Referenced by CChangeNotifyBroker::BrokerNotification(), CDefView::OnChangeNotify(), OnShellNotify(), and testwindow_wndproc().

◆ SHChangeNotify()

EXTERN_C void WINAPI SHChangeNotify ( LONG  wEventId,
UINT  uFlags,
LPCVOID  dwItem1,
LPCVOID  dwItem2 
)

Definition at line 626 of file changenotify.cpp.

627{
628 LPITEMIDLIST pidl1 = NULL, pidl2 = NULL, pidlTemp1 = NULL, pidlTemp2 = NULL;
629 DWORD dwTick = GetTickCount();
630 WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH];
631 LPWSTR psz1, psz2;
632 TRACE("(0x%08x,0x%08x,%p,%p)\n", wEventId, uFlags, dwItem1, dwItem2);
633
634 switch (uFlags & SHCNF_TYPE)
635 {
636 case SHCNF_IDLIST:
637 pidl1 = (LPITEMIDLIST)dwItem1;
638 pidl2 = (LPITEMIDLIST)dwItem2;
639 break;
640
641 case SHCNF_PATHA:
642 psz1 = psz2 = NULL;
643 if (dwItem1)
644 {
645 SHAnsiToUnicode((LPCSTR)dwItem1, szPath1, _countof(szPath1));
646 psz1 = szPath1;
647 }
648 if (dwItem2)
649 {
650 SHAnsiToUnicode((LPCSTR)dwItem2, szPath2, _countof(szPath2));
651 psz2 = szPath2;
652 }
653 uFlags &= ~SHCNF_TYPE;
655 SHChangeNotify(wEventId, uFlags, psz1, psz2);
656 return;
657
658 case SHCNF_PATHW:
659 if (dwItem1)
660 {
661 pidl1 = pidlTemp1 = SHSimpleIDListFromPathW((LPCWSTR)dwItem1);
662 }
663 if (dwItem2)
664 {
665 pidl2 = pidlTemp2 = SHSimpleIDListFromPathW((LPCWSTR)dwItem2);
666 }
667 break;
668
669 case SHCNF_PRINTERA:
670 case SHCNF_PRINTERW:
671 FIXME("SHChangeNotify with (uFlags & SHCNF_PRINTER)\n");
672 return;
673
674 default:
675 FIXME("unknown type %08x\n", uFlags & SHCNF_TYPE);
676 return;
677 }
678
679 if (wEventId == 0 || (wEventId & SHCNE_ASSOCCHANGED) || pidl1 != NULL)
680 {
681 TRACE("notifying event %s(%x)\n", DumpEvent(wEventId), wEventId);
682 SHChangeNotifyTransmit(wEventId, uFlags, pidl1, pidl2, dwTick);
683 }
684
685 if (pidlTemp1)
686 ILFree(pidlTemp1);
687 if (pidlTemp2)
688 ILFree(pidlTemp2);
689}
EXTERN_C VOID WINAPI SHChangeNotifyTransmit(LONG lEvent, UINT uFlags, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, DWORD dwTick)
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
static LPCSTR DumpEvent(LONG event)
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:2667
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:938
LPITEMIDLIST WINAPI SHSimpleIDListFromPathW(LPCWSTR lpszPath)
Definition: pidl.c:1133
#define SHCNF_PRINTERW
Definition: shlobj.h:1911
#define SHCNF_PATHA
Definition: shlobj.h:1907
#define SHCNF_PRINTERA
Definition: shlobj.h:1908
#define SHCNF_TYPE
Definition: shlobj.h:1912
#define SHCNE_ASSOCCHANGED
Definition: shlobj.h:1896
#define SHCNF_PATHW
Definition: shlobj.h:1910
#define SHCNF_IDLIST
Definition: shlobj.h:1906
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by CFSDropTarget::_DoDrop(), delete_files(), DoAction10(), DoAction11(), DoAction12(), DoAction9(), CDefaultContextMenu::DoCreateNewFolder(), DrivesContextMenuCallback(), CFontExt::Drop(), EditTypeDlg_OnOK(), FinishDlgProc(), CZipCreatorImpl::JustDoIt(), NotifyFileSystemChange(), CLayerUIPropPage::OnApply(), CShellLink::OnNotify(), CShellLink::Save(), CNewMenu::SelectNewItem(), CFSFolder::SetNameOf(), SHChangeNotify(), SHChangeNotifyWrap(), SHNotifyCopyFileW(), SHNotifyCreateDirectoryW(), SHNotifyDeleteFileW(), SHNotifyMoveFileW(), SHNotifyRemoveDirectoryW(), test_SHChangeNotify(), VfdCloseImage(), VfdOpenImage(), WelcomeDlgProc(), and CIniPropertyBag::Write().

◆ SHChangeNotifyDeregister()

EXTERN_C BOOL WINAPI SHChangeNotifyDeregister ( ULONG  hNotify)

Definition at line 527 of file changenotify.cpp.

528{
529 TRACE("(0x%08x)\n", hNotify);
530
531 // get the server window
532 HWND hwndServer = GetNotificationServer(FALSE);
533 if (hwndServer == NULL)
534 return FALSE;
535
536 // send CN_UNREGISTER message and try to unregister
537 BOOL ret = (BOOL)SendMessageW(hwndServer, CN_UNREGISTER, hNotify, 0);
538 if (!ret)
539 ERR("CN_UNREGISTER failed\n");
540
541 return ret;
542}
#define CN_UNREGISTER
#define BOOL
Definition: nt_native.h:43

Referenced by BrsFolder_OnDestroy(), NTSHChangeNotifyDeregister(), OnDestroy(), CDefView::OnDestroy(), and test_SHChangeNotify().

◆ SHChangeNotifyReceive()

EXTERN_C VOID WINAPI SHChangeNotifyReceive ( LONG  lEvent,
UINT  uFlags,
LPCITEMIDLIST  pidl1,
LPCITEMIDLIST  pidl2 
)

Definition at line 611 of file changenotify.cpp.

612{
614}
EXTERN_C VOID WINAPI SHChangeNotifyReceiveEx(LONG lEvent, UINT uFlags, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, DWORD dwTick)
HANDLE lEvent
Definition: tftpd.cpp:56

◆ SHChangeNotifyReceiveEx()

EXTERN_C VOID WINAPI SHChangeNotifyReceiveEx ( LONG  lEvent,
UINT  uFlags,
LPCITEMIDLIST  pidl1,
LPCITEMIDLIST  pidl2,
DWORD  dwTick 
)

Definition at line 600 of file changenotify.cpp.

602{
603 // TODO: Queueing notifications
604 CreateNotificationParamAndSend(lEvent, uFlags, pidl1, pidl2, dwTick);
605}
static void CreateNotificationParamAndSend(LONG wEventId, UINT uFlags, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, DWORD dwTick)

Referenced by SHChangeNotifyReceive(), and SHChangeNotifyTransmit().

◆ SHChangeNotifyRegister()

EXTERN_C ULONG WINAPI SHChangeNotifyRegister ( HWND  hwnd,
INT  fSources,
LONG  wEventMask,
UINT  uMsg,
INT  cItems,
SHChangeNotifyEntry lpItems 
)

Definition at line 393 of file changenotify.cpp.

395{
396 HWND hwndServer, hwndBroker = NULL;
397 HANDLE hRegEntry;
398 INT iItem;
399 ULONG nRegID = INVALID_REG_ID;
400 DWORD dwOwnerPID;
401 LPREGENTRY pRegEntry;
402
403 TRACE("(%p,0x%08x,0x%08x,0x%08x,%d,%p)\n",
404 hwnd, fSources, wEventMask, uMsg, cItems, lpItems);
405
406 // sanity check
407 if (wEventMask == 0 || cItems <= 0 || cItems > 0x7FFF || lpItems == NULL ||
408 hwnd == NULL || !IsWindow(hwnd))
409 {
410 return INVALID_REG_ID;
411 }
412
413 // request the window of the server
414 hwndServer = GetNotificationServer(TRUE);
415 if (hwndServer == NULL)
416 return INVALID_REG_ID;
417
418 // disable recursive interrupt in specific condition
419 if ((fSources & SHCNRF_RecursiveInterrupt) && !(fSources & SHCNRF_InterruptLevel))
420 {
421 fSources &= ~SHCNRF_RecursiveInterrupt;
422 }
423
424 // if it is old delivery method, then create a broker window
425 if ((fSources & SHCNRF_NewDelivery) == 0)
426 {
427 hwndBroker = hwnd = CreateNotificationBroker(hwnd, uMsg);
429 }
430
431 // The owner PID is the process ID of the server
432 GetWindowThreadProcessId(hwndServer, &dwOwnerPID);
433
435 for (iItem = 0; iItem < cItems; ++iItem)
436 {
437 // create a registration entry
438 hRegEntry = CreateRegistrationParam(nRegID, hwnd, uMsg, fSources, wEventMask,
439 lpItems[iItem].fRecursive, lpItems[iItem].pidl,
440 dwOwnerPID, hwndBroker);
441 if (hRegEntry)
442 {
443 TRACE("CN_REGISTER: hwnd:%p, hRegEntry:%p, pid:0x%lx\n",
444 hwndServer, hRegEntry, dwOwnerPID);
445
446 // send CN_REGISTER to the server
447 SendMessageW(hwndServer, CN_REGISTER, (WPARAM)hRegEntry, dwOwnerPID);
448
449 // update nRegID
450 pRegEntry = (LPREGENTRY)SHLockSharedEx(hRegEntry, dwOwnerPID, FALSE);
451 if (pRegEntry)
452 {
453 nRegID = pRegEntry->nRegID;
454 SHUnlockShared(pRegEntry);
455 }
456
457 // free registration entry
458 SHFreeShared(hRegEntry, dwOwnerPID);
459 }
460
461 if (nRegID == INVALID_REG_ID)
462 {
463 ERR("Delivery failed\n");
464
465 if (hwndBroker)
466 {
467 // destroy the broker
468 DestroyWindow(hwndBroker);
469 }
470 break;
471 }
472
473 // PIDL alias
474 LPITEMIDLIST apidlAlias[2];
475 if (DoGetAliasPIDLs(apidlAlias, lpItems[iItem].pidl))
476 {
477 if (apidlAlias[0])
478 {
479 // create another registration entry
480 hRegEntry = CreateRegistrationParam(nRegID, hwnd, uMsg, fSources, wEventMask,
481 lpItems[iItem].fRecursive, apidlAlias[0],
482 dwOwnerPID, hwndBroker);
483 if (hRegEntry)
484 {
485 TRACE("CN_REGISTER: hwnd:%p, hRegEntry:%p, pid:0x%lx\n",
486 hwndServer, hRegEntry, dwOwnerPID);
487
488 // send CN_REGISTER to the server
489 SendMessageW(hwndServer, CN_REGISTER, (WPARAM)hRegEntry, dwOwnerPID);
490
491 // free registration entry
492 SHFreeShared(hRegEntry, dwOwnerPID);
493 }
494 ILFree(apidlAlias[0]);
495 }
496
497 if (apidlAlias[1])
498 {
499 // create another registration entry
500 hRegEntry = CreateRegistrationParam(nRegID, hwnd, uMsg, fSources, wEventMask,
501 lpItems[iItem].fRecursive, apidlAlias[1],
502 dwOwnerPID, hwndBroker);
503 if (hRegEntry)
504 {
505 TRACE("CN_REGISTER: hwnd:%p, hRegEntry:%p, pid:0x%lx\n",
506 hwndServer, hRegEntry, dwOwnerPID);
507
508 // send CN_REGISTER to the server
509 SendMessageW(hwndServer, CN_REGISTER, (WPARAM)hRegEntry, dwOwnerPID);
510
511 // free registration entry
512 SHFreeShared(hRegEntry, dwOwnerPID);
513 }
514 ILFree(apidlAlias[1]);
515 }
516 }
517 }
519
520 return nRegID;
521}
#define CN_REGISTER
#define WM_BROKER_NOTIFICATION
#define INVALID_REG_ID
static HWND CreateNotificationBroker(HWND hwnd, UINT wMsg)
static BOOL DoGetAliasPIDLs(LPITEMIDLIST apidls[2], PCIDLIST_ABSOLUTE pidl)
static HANDLE CreateRegistrationParam(ULONG nRegID, HWND hwnd, UINT wMsg, INT fSources, LONG fEvents, LONG fRecursive, LPCITEMIDLIST pidl, DWORD dwOwnerPID, HWND hwndBroker)
#define SHCNRF_RecursiveInterrupt
Definition: shlobj.h:1922
#define SHCNRF_InterruptLevel
Definition: shlobj.h:1920
uint32_t ULONG
Definition: typedefs.h:59
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
BOOL WINAPI DestroyWindow(_In_ HWND)

Referenced by BrsFolder_OnCreate(), CExplorerBand::InitializeExplorerBand(), NTSHChangeNotifyRegister(), OnCreate(), CDefView::OnCreate(), and test_SHChangeNotify().

◆ SHChangeNotifySuspendResume()

EXTERN_C BOOL WINAPI SHChangeNotifySuspendResume ( BOOL  bSuspend,
LPITEMIDLIST  pidl,
BOOL  bRecursive,
DWORD  dwReserved 
)

Definition at line 766 of file changenotify.cpp.

770{
771 FIXME("SHChangeNotifySuspendResume() stub\n");
772 return FALSE;
773}

◆ SHChangeNotifyTransmit()

EXTERN_C VOID WINAPI SHChangeNotifyTransmit ( LONG  lEvent,
UINT  uFlags,
LPCITEMIDLIST  pidl1,
LPCITEMIDLIST  pidl2,
DWORD  dwTick 
)

Definition at line 617 of file changenotify.cpp.

618{
619 SHChangeNotifyReceiveEx(lEvent, uFlags, pidl1, pidl2, dwTick);
620}

Referenced by SHChangeNotify().

◆ SHChangeNotifyUpdateEntryList()

EXTERN_C BOOL WINAPI SHChangeNotifyUpdateEntryList ( DWORD  unknown1,
DWORD  unknown2,
DWORD  unknown3,
DWORD  unknown4 
)

Definition at line 548 of file changenotify.cpp.

550{
551 FIXME("(0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
552 unknown1, unknown2, unknown3, unknown4);
553 return TRUE;
554}

◆ SHChangeRegistrationReceive()

EXTERN_C BOOL WINAPI SHChangeRegistrationReceive ( LPVOID  lpUnknown1,
DWORD  dwUnknown2 
)

Definition at line 593 of file changenotify.cpp.

594{
595 TRACE("\n");
596 return FALSE; /* Just return FALSE */
597}

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( shcn  )

Variable Documentation

◆ AliasPIDLs

ALIAS_PIDL AliasPIDLs[]
static
Initial value:
=
{
}
#define CSIDL_COMMON_DESKTOPDIRECTORY
Definition: shlobj.h:2182
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2173
#define CSIDL_PERSONAL
Definition: shlobj.h:2163
#define CSIDL_DESKTOP
Definition: shlobj.h:2158

Definition at line 335 of file changenotify.cpp.

Referenced by DoGetAliasPIDLs(), and DoInitAliasPIDLs().

◆ SHELL32_ChangenotifyCS

CRITICAL_SECTION SHELL32_ChangenotifyCS