2 * shell change notification
4 * Juergen Schmied <juergen.schmied@debitel.de>
10 #include "debugtools.h"
12 #include "shell32_main.h"
13 #include "wine/undocshell.h"
15 DEFAULT_DEBUG_CHANNEL(shell);
17 static CRITICAL_SECTION SHELL32_ChangenotifyCS = CRITICAL_SECTION_INIT;
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 * SHChangeNotify [SHELL32.@]
184 void WINAPI SHChangeNotifyW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
186 LPITEMIDLIST pidl1=(LPITEMIDLIST)dwItem1, pidl2=(LPITEMIDLIST)dwItem2;
187 LPNOTIFICATIONLIST ptr;
189 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
191 /* convert paths in IDLists*/
192 if(uFlags & SHCNF_PATHA)
195 if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &pidl1, &dummy);
196 if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &pidl2, &dummy);
199 EnterCriticalSection(&SHELL32_ChangenotifyCS);
201 /* loop through the list */
205 TRACE("trying %p\n", ptr);
207 if(wEventId & ptr->wEventMask)
209 TRACE("notifying\n");
210 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)pidl1, (LPARAM)pidl2);
215 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
217 if(uFlags & SHCNF_PATHA)
219 if (pidl1) SHFree(pidl1);
220 if (pidl2) SHFree(pidl2);
224 /*************************************************************************
225 * SHChangeNotify [SHELL32.@]
227 void WINAPI SHChangeNotifyA (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
229 LPITEMIDLIST Pidls[2];
230 LPNOTIFICATIONLIST ptr;
232 Pidls[0] = (LPITEMIDLIST)dwItem1;
233 Pidls[1] = (LPITEMIDLIST)dwItem2;
235 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
237 /* convert paths in IDLists*/
238 if(uFlags & SHCNF_PATHA)
241 if (Pidls[0]) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy);
242 if (Pidls[1]) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy);
245 EnterCriticalSection(&SHELL32_ChangenotifyCS);
247 /* loop through the list */
251 TRACE("trying %p\n", ptr);
253 if(wEventId & ptr->wEventMask)
255 TRACE("notifying\n");
256 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)&Pidls, (LPARAM)wEventId);
261 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
263 /* if we allocated it, free it */
264 if(uFlags & SHCNF_PATHA)
266 if (Pidls[0]) SHFree(Pidls[0]);
267 if (Pidls[1]) SHFree(Pidls[1]);
271 /*************************************************************************
272 * SHChangeNotify [SHELL32.@]
274 void WINAPI SHChangeNotifyAW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
276 if(SHELL_OsIsUnicode())
277 SHChangeNotifyW (wEventId, uFlags, dwItem1, dwItem2);
279 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
282 /*************************************************************************
283 * NTSHChangeNotifyRegister [SHELL32.640]
285 * Idlist is an array of structures and Count specifies how many items in the array
286 * (usually just one I think).
288 DWORD WINAPI NTSHChangeNotifyRegister(
294 LPNOTIFYREGISTER idlist)
296 FIXME("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n",
297 hwnd,events1,events2,msg,count,idlist);
301 /*************************************************************************
302 * SHChangeNotification_Lock [SHELL32.644]
304 HANDLE WINAPI SHChangeNotification_Lock(
307 LPCITEMIDLIST **lppidls,
314 /*************************************************************************
315 * SHChangeNotification_Unlock [SHELL32.645]
317 BOOL WINAPI SHChangeNotification_Unlock (
324 /*************************************************************************
325 * NTSHChangeNotifyDeregister [SHELL32.641]
327 DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
329 FIXME("(0x%08lx):stub.\n",x1);