2 * shell change notification
4 * Juergen Schmied <juergen.schmied@debitel.de>
10 #include "debugtools.h"
12 #include "shell32_main.h"
13 #include "winversion.h"
14 #include "wine/undocshell.h"
16 DEFAULT_DEBUG_CHANNEL(shell);
18 static CRITICAL_SECTION SHELL32_ChangenotifyCS = CRITICAL_SECTION_INIT;
20 /* internal list of notification clients (internal) */
21 typedef struct _NOTIFICATIONLIST
23 struct _NOTIFICATIONLIST *next;
24 struct _NOTIFICATIONLIST *prev;
25 HWND hwnd; /* window to notify */
26 DWORD uMsg; /* message to send */
27 LPNOTIFYREGISTER apidl; /* array of entrys to watch*/
28 UINT cidl; /* number of pidls in array */
29 LONG wEventMask; /* subscribed events */
30 DWORD dwFlags; /* client flags */
31 } NOTIFICATIONLIST, *LPNOTIFICATIONLIST;
33 static NOTIFICATIONLIST head;
34 static NOTIFICATIONLIST tail;
36 void InitChangeNotifications()
38 TRACE("head=%p tail=%p\n", &head, &tail);
43 void FreeChangeNotifications()
45 LPNOTIFICATIONLIST ptr, item;
49 EnterCriticalSection(&SHELL32_ChangenotifyCS);
58 TRACE("item=%p\n", item);
61 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
68 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
70 DeleteCriticalSection(&SHELL32_ChangenotifyCS);
73 static BOOL AddNode(LPNOTIFICATIONLIST item)
75 LPNOTIFICATIONLIST last;
77 EnterCriticalSection(&SHELL32_ChangenotifyCS);
87 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
89 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
94 static BOOL DeleteNode(LPNOTIFICATIONLIST item)
96 LPNOTIFICATIONLIST ptr;
99 TRACE("item=%p\n", item);
101 EnterCriticalSection(&SHELL32_ChangenotifyCS);
104 while((ptr != &tail) && (ret == FALSE))
106 TRACE("ptr=%p\n", ptr);
112 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
114 /* remove item from list */
115 item->prev->next = item->next;
116 item->next->prev = item->prev;
119 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
127 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
132 /*************************************************************************
133 * SHChangeNotifyRegister [SHELL32.2]
137 SHChangeNotifyRegister(
143 LPCNOTIFYREGISTER lpItems)
145 LPNOTIFICATIONLIST item;
148 item = SHAlloc(sizeof(NOTIFICATIONLIST));
150 TRACE("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p) item=%p\n",
151 hwnd,dwFlags,wEventMask,uMsg,cItems,lpItems,item);
156 item->apidl = SHAlloc(sizeof(NOTIFYREGISTER) * cItems);
157 for(i=0;i<cItems;i++)
159 item->apidl[i].pidlPath = ILClone(lpItems[i].pidlPath);
160 item->apidl[i].bWatchSubtree = lpItems[i].bWatchSubtree;
164 item->wEventMask = wEventMask;
165 item->dwFlags = dwFlags;
170 /*************************************************************************
171 * SHChangeNotifyDeregister [SHELL32.4]
174 SHChangeNotifyDeregister(
177 TRACE("(0x%08x)\n",hNotify);
179 return DeleteNode((LPNOTIFICATIONLIST)hNotify);;
182 /*************************************************************************
183 * SHChangeNotify [SHELL32.239]
185 void WINAPI SHChangeNotifyW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
187 LPITEMIDLIST pidl1=(LPITEMIDLIST)dwItem1, pidl2=(LPITEMIDLIST)dwItem2;
188 LPNOTIFICATIONLIST ptr;
190 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
192 /* convert paths in IDLists*/
193 if(uFlags & SHCNF_PATHA)
196 if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &pidl1, &dummy);
197 if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &pidl2, &dummy);
200 EnterCriticalSection(&SHELL32_ChangenotifyCS);
202 /* loop through the list */
206 TRACE("trying %p\n", ptr);
208 if(wEventId & ptr->wEventMask)
210 TRACE("notifying\n");
211 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)pidl1, (LPARAM)pidl2);
216 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
218 if(uFlags & SHCNF_PATHA)
220 if (pidl1) SHFree(pidl1);
221 if (pidl2) SHFree(pidl2);
225 /*************************************************************************
226 * SHChangeNotify [SHELL32.239]
228 void WINAPI SHChangeNotifyA (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
230 LPITEMIDLIST Pidls[2];
231 LPNOTIFICATIONLIST ptr;
233 Pidls[0] = (LPITEMIDLIST)dwItem1;
234 Pidls[1] = (LPITEMIDLIST)dwItem2;
236 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
238 /* convert paths in IDLists*/
239 if(uFlags & SHCNF_PATHA)
242 if (Pidls[0]) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy);
243 if (Pidls[1]) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy);
246 EnterCriticalSection(&SHELL32_ChangenotifyCS);
248 /* loop through the list */
252 TRACE("trying %p\n", ptr);
254 if(wEventId & ptr->wEventMask)
256 TRACE("notifying\n");
257 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)&Pidls, (LPARAM)wEventId);
262 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
264 /* if we allocated it, free it */
265 if(uFlags & SHCNF_PATHA)
267 if (Pidls[0]) SHFree(Pidls[0]);
268 if (Pidls[1]) SHFree(Pidls[1]);
272 /*************************************************************************
273 * SHChangeNotifyAW [SHELL32.239]
275 void WINAPI SHChangeNotifyAW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
277 if(VERSION_OsIsUnicode())
278 SHChangeNotifyW (wEventId, uFlags, dwItem1, dwItem2);
280 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
283 /*************************************************************************
284 * NTSHChangeNotifyRegister [SHELL32.640]
286 * Idlist is an array of structures and Count specifies how many items in the array
287 * (usually just one I think).
289 DWORD WINAPI NTSHChangeNotifyRegister(
295 LPNOTIFYREGISTER idlist)
297 FIXME("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n",
298 hwnd,events1,events2,msg,count,idlist);
302 /*************************************************************************
303 * SHChangeNotification_Lock [SHELL32.644]
305 HANDLE WINAPI SHChangeNotification_Lock(
308 LPCITEMIDLIST **lppidls,
315 /*************************************************************************
316 * SHChangeNotification_Unlock [SHELL32.645]
318 BOOL WINAPI SHChangeNotification_Unlock (
325 /*************************************************************************
326 * NTSHChangeNotifyDeregister [SHELL32.641]
328 DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
330 FIXME("(0x%08lx):stub.\n",x1);