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;
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 NOTIFICATIONLIST head;
34 NOTIFICATIONLIST tail;
36 void InitChangeNotifications()
38 TRACE("head=%p tail=%p\n", &head, &tail);
40 InitializeCriticalSection(&SHELL32_ChangenotifyCS);
41 MakeCriticalSectionGlobal(&SHELL32_ChangenotifyCS);
42 ZeroMemory(&head, sizeof(NOTIFICATIONLIST));
43 ZeroMemory(&tail, sizeof(NOTIFICATIONLIST));
48 void FreeChangeNotifications()
50 LPNOTIFICATIONLIST ptr, item;
54 EnterCriticalSection(&SHELL32_ChangenotifyCS);
63 TRACE("item=%p\n", item);
66 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
73 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
75 DeleteCriticalSection(&SHELL32_ChangenotifyCS);
78 static BOOL AddNode(LPNOTIFICATIONLIST item)
80 LPNOTIFICATIONLIST last;
82 EnterCriticalSection(&SHELL32_ChangenotifyCS);
92 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
94 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
99 static BOOL DeleteNode(LPNOTIFICATIONLIST item)
101 LPNOTIFICATIONLIST ptr;
104 TRACE("item=%p\n", item);
106 EnterCriticalSection(&SHELL32_ChangenotifyCS);
109 while((ptr != &tail) && (ret == FALSE))
111 TRACE("ptr=%p\n", ptr);
117 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
119 /* remove item from list */
120 item->prev->next = item->next;
121 item->next->prev = item->prev;
124 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
132 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
137 /*************************************************************************
138 * SHChangeNotifyRegister [SHELL32.2]
142 SHChangeNotifyRegister(
148 LPCNOTIFYREGISTER lpItems)
150 LPNOTIFICATIONLIST item;
153 item = SHAlloc(sizeof(NOTIFICATIONLIST));
155 TRACE("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p) item=%p\n",
156 hwnd,dwFlags,wEventMask,uMsg,cItems,lpItems,item);
161 item->apidl = SHAlloc(sizeof(NOTIFYREGISTER) * cItems);
162 for(i=0;i<cItems;i++)
164 item->apidl[i].pidlPath = ILClone(lpItems[i].pidlPath);
165 item->apidl[i].bWatchSubtree = lpItems[i].bWatchSubtree;
169 item->wEventMask = wEventMask;
170 item->dwFlags = dwFlags;
175 /*************************************************************************
176 * SHChangeNotifyDeregister [SHELL32.4]
179 SHChangeNotifyDeregister(
182 TRACE("(0x%08x)\n",hNotify);
184 return DeleteNode((LPNOTIFICATIONLIST)hNotify);;
187 /*************************************************************************
188 * SHChangeNotify [SHELL32.239]
190 void WINAPI SHChangeNotifyW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
192 LPITEMIDLIST pidl1=(LPITEMIDLIST)dwItem1, pidl2=(LPITEMIDLIST)dwItem2;
193 LPNOTIFICATIONLIST ptr;
195 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
197 /* convert paths in IDLists*/
198 if(uFlags & SHCNF_PATHA)
201 if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &pidl1, &dummy);
202 if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &pidl2, &dummy);
205 EnterCriticalSection(&SHELL32_ChangenotifyCS);
207 /* loop through the list */
211 TRACE("trying %p\n", ptr);
213 if(wEventId & ptr->wEventMask)
215 TRACE("notifying\n");
216 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)pidl1, (LPARAM)pidl2);
221 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
223 if(uFlags & SHCNF_PATHA)
230 /*************************************************************************
231 * SHChangeNotify [SHELL32.239]
233 void WINAPI SHChangeNotifyA (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
235 LPITEMIDLIST Pidls[2];
236 LPNOTIFICATIONLIST ptr;
238 Pidls[0] = (LPITEMIDLIST)dwItem1;
239 Pidls[1] = (LPITEMIDLIST)dwItem2;
241 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
243 /* convert paths in IDLists*/
244 if(uFlags & SHCNF_PATHA)
247 if (Pidls[0]) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy);
248 if (Pidls[1]) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy);
251 EnterCriticalSection(&SHELL32_ChangenotifyCS);
253 /* loop through the list */
257 TRACE("trying %p\n", ptr);
259 if(wEventId & ptr->wEventMask)
261 TRACE("notifying\n");
262 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)&Pidls, (LPARAM)wEventId);
267 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
269 /* if we allocated it, free it */
270 if(uFlags & SHCNF_PATHA)
277 /*************************************************************************
278 * SHChangeNotifyAW [SHELL32.239]
280 void WINAPI SHChangeNotifyAW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
282 if(VERSION_OsIsUnicode())
283 SHChangeNotifyW (wEventId, uFlags, dwItem1, dwItem2);
285 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
288 /*************************************************************************
289 * NTSHChangeNotifyRegister [SHELL32.640]
291 * Idlist is an array of structures and Count specifies how many items in the array
292 * (usually just one I think).
294 DWORD WINAPI NTSHChangeNotifyRegister(
300 LPNOTIFYREGISTER idlist)
302 FIXME("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n",
303 hwnd,events1,events2,msg,count,idlist);
307 /*************************************************************************
308 * SHChangeNotification_Lock [SHELL32.644]
310 HANDLE WINAPI SHChangeNotification_Lock(
313 LPCITEMIDLIST **lppidls,
320 /*************************************************************************
321 * SHChangeNotification_Unlock [SHELL32.645]
323 BOOL WINAPI SHChangeNotification_Unlock (
330 /*************************************************************************
331 * NTSHChangeNotifyDeregister [SHELL32.641]
333 DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
335 FIXME("(0x%08lx):stub.\n",x1);