2 * shell change notification
4 * Juergen Schmied <juergen.schmied@debitel.de>
10 #include "debugtools.h"
12 #include "shell32_main.h"
13 #include "undocshell.h"
15 DEFAULT_DEBUG_CHANNEL(shell);
17 static CRITICAL_SECTION SHELL32_ChangenotifyCS = CRITICAL_SECTION_INIT("SHELL32_ChangenotifyCS");
19 /* internal list of notification clients (internal) */
20 typedef struct _NOTIFICATIONLIST
22 struct _NOTIFICATIONLIST *next;
23 struct _NOTIFICATIONLIST *prev;
24 HWND hwnd; /* window to notify */
25 DWORD uMsg; /* message to send */
26 LPNOTIFYREGISTER apidl; /* array of entrys to watch*/
27 UINT cidl; /* number of pidls in array */
28 LONG wEventMask; /* subscribed events */
29 DWORD dwFlags; /* client flags */
30 } NOTIFICATIONLIST, *LPNOTIFICATIONLIST;
32 static NOTIFICATIONLIST head;
33 static NOTIFICATIONLIST tail;
35 void InitChangeNotifications()
37 TRACE("head=%p tail=%p\n", &head, &tail);
42 void FreeChangeNotifications()
44 LPNOTIFICATIONLIST ptr, item;
48 EnterCriticalSection(&SHELL32_ChangenotifyCS);
57 TRACE("item=%p\n", item);
60 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
67 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
69 DeleteCriticalSection(&SHELL32_ChangenotifyCS);
72 static BOOL AddNode(LPNOTIFICATIONLIST item)
74 LPNOTIFICATIONLIST last;
76 EnterCriticalSection(&SHELL32_ChangenotifyCS);
86 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
88 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
93 static BOOL DeleteNode(LPNOTIFICATIONLIST item)
95 LPNOTIFICATIONLIST ptr;
98 TRACE("item=%p\n", item);
100 EnterCriticalSection(&SHELL32_ChangenotifyCS);
103 while((ptr != &tail) && (ret == FALSE))
105 TRACE("ptr=%p\n", ptr);
111 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
113 /* remove item from list */
114 item->prev->next = item->next;
115 item->next->prev = item->prev;
118 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
126 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
131 /*************************************************************************
132 * SHChangeNotifyRegister [SHELL32.2]
136 SHChangeNotifyRegister(
142 LPCNOTIFYREGISTER lpItems)
144 LPNOTIFICATIONLIST item;
147 item = SHAlloc(sizeof(NOTIFICATIONLIST));
149 TRACE("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p) item=%p\n",
150 hwnd,dwFlags,wEventMask,uMsg,cItems,lpItems,item);
155 item->apidl = SHAlloc(sizeof(NOTIFYREGISTER) * cItems);
156 for(i=0;i<cItems;i++)
158 item->apidl[i].pidlPath = ILClone(lpItems[i].pidlPath);
159 item->apidl[i].bWatchSubtree = lpItems[i].bWatchSubtree;
163 item->wEventMask = wEventMask;
164 item->dwFlags = dwFlags;
169 /*************************************************************************
170 * SHChangeNotifyDeregister [SHELL32.4]
173 SHChangeNotifyDeregister(
176 TRACE("(0x%08x)\n",hNotify);
178 return DeleteNode((LPNOTIFICATIONLIST)hNotify);;
181 /*************************************************************************
182 * SHChangeNotifyUpdateEntryList [SHELL32.5]
185 SHChangeNotifyUpdateEntryList(DWORD unknown1, DWORD unknown2,
186 DWORD unknown3, DWORD unknown4)
188 FIXME("(0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n",
189 unknown1, unknown2, unknown3, unknown4);
194 /*************************************************************************
195 * SHChangeNotify [SHELL32.@]
197 void WINAPI SHChangeNotifyW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
199 LPITEMIDLIST pidl1=(LPITEMIDLIST)dwItem1, pidl2=(LPITEMIDLIST)dwItem2;
200 LPNOTIFICATIONLIST ptr;
202 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
204 /* convert paths in IDLists*/
205 if(uFlags & SHCNF_PATHA)
208 if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &pidl1, &dummy);
209 if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &pidl2, &dummy);
212 EnterCriticalSection(&SHELL32_ChangenotifyCS);
214 /* loop through the list */
218 TRACE("trying %p\n", ptr);
220 if(wEventId & ptr->wEventMask)
222 TRACE("notifying\n");
223 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)pidl1, (LPARAM)pidl2);
228 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
230 if(uFlags & SHCNF_PATHA)
232 if (pidl1) SHFree(pidl1);
233 if (pidl2) SHFree(pidl2);
237 /*************************************************************************
238 * SHChangeNotify [SHELL32.@]
240 void WINAPI SHChangeNotifyA (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
242 LPITEMIDLIST Pidls[2];
243 LPNOTIFICATIONLIST ptr;
245 Pidls[0] = (LPITEMIDLIST)dwItem1;
246 Pidls[1] = (LPITEMIDLIST)dwItem2;
248 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
250 /* convert paths in IDLists*/
251 if(uFlags & SHCNF_PATHA)
254 if (Pidls[0]) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy);
255 if (Pidls[1]) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy);
258 EnterCriticalSection(&SHELL32_ChangenotifyCS);
260 /* loop through the list */
264 TRACE("trying %p\n", ptr);
266 if(wEventId & ptr->wEventMask)
268 TRACE("notifying\n");
269 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)&Pidls, (LPARAM)wEventId);
274 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
276 /* if we allocated it, free it */
277 if(uFlags & SHCNF_PATHA)
279 if (Pidls[0]) SHFree(Pidls[0]);
280 if (Pidls[1]) SHFree(Pidls[1]);
284 /*************************************************************************
285 * SHChangeNotify [SHELL32.@]
287 void WINAPI SHChangeNotifyAW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
289 if(SHELL_OsIsUnicode())
290 SHChangeNotifyW (wEventId, uFlags, dwItem1, dwItem2);
292 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
295 /*************************************************************************
296 * NTSHChangeNotifyRegister [SHELL32.640]
298 * Idlist is an array of structures and Count specifies how many items in the array
299 * (usually just one I think).
301 DWORD WINAPI NTSHChangeNotifyRegister(
307 LPNOTIFYREGISTER idlist)
309 FIXME("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n",
310 hwnd,events1,events2,msg,count,idlist);
314 /*************************************************************************
315 * SHChangeNotification_Lock [SHELL32.644]
317 HANDLE WINAPI SHChangeNotification_Lock(
320 LPCITEMIDLIST **lppidls,
327 /*************************************************************************
328 * SHChangeNotification_Unlock [SHELL32.645]
330 BOOL WINAPI SHChangeNotification_Unlock (
337 /*************************************************************************
338 * NTSHChangeNotifyDeregister [SHELL32.641]
340 DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
342 FIXME("(0x%08lx):stub.\n",x1);