2 * shell change notification
4 * Copyright 2000 Juergen Schmied
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/debug.h"
25 #include "shell32_main.h"
26 #include "undocshell.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(shell);
30 static CRITICAL_SECTION SHELL32_ChangenotifyCS = CRITICAL_SECTION_INIT("SHELL32_ChangenotifyCS");
32 /* internal list of notification clients (internal) */
33 typedef struct _NOTIFICATIONLIST
35 struct _NOTIFICATIONLIST *next;
36 struct _NOTIFICATIONLIST *prev;
37 HWND hwnd; /* window to notify */
38 DWORD uMsg; /* message to send */
39 LPNOTIFYREGISTER apidl; /* array of entries to watch*/
40 UINT cidl; /* number of pidls in array */
41 LONG wEventMask; /* subscribed events */
42 DWORD dwFlags; /* client flags */
43 } NOTIFICATIONLIST, *LPNOTIFICATIONLIST;
45 static NOTIFICATIONLIST head;
46 static NOTIFICATIONLIST tail;
48 void InitChangeNotifications()
50 TRACE("head=%p tail=%p\n", &head, &tail);
55 void FreeChangeNotifications()
57 LPNOTIFICATIONLIST ptr, item;
61 EnterCriticalSection(&SHELL32_ChangenotifyCS);
70 TRACE("item=%p\n", item);
73 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
80 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
82 DeleteCriticalSection(&SHELL32_ChangenotifyCS);
85 static BOOL AddNode(LPNOTIFICATIONLIST item)
87 LPNOTIFICATIONLIST last;
89 EnterCriticalSection(&SHELL32_ChangenotifyCS);
99 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
101 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
106 static BOOL DeleteNode(LPNOTIFICATIONLIST item)
108 LPNOTIFICATIONLIST ptr;
111 TRACE("item=%p\n", item);
113 EnterCriticalSection(&SHELL32_ChangenotifyCS);
116 while((ptr != &tail) && (ret == FALSE))
118 TRACE("ptr=%p\n", ptr);
124 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
126 /* remove item from list */
127 item->prev->next = item->next;
128 item->next->prev = item->prev;
131 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
139 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
144 /*************************************************************************
145 * SHChangeNotifyRegister [SHELL32.2]
149 SHChangeNotifyRegister(
155 LPCNOTIFYREGISTER lpItems)
157 LPNOTIFICATIONLIST item;
160 item = SHAlloc(sizeof(NOTIFICATIONLIST));
162 TRACE("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p) item=%p\n",
163 hwnd,dwFlags,wEventMask,uMsg,cItems,lpItems,item);
168 item->apidl = SHAlloc(sizeof(NOTIFYREGISTER) * cItems);
169 for(i=0;i<cItems;i++)
171 item->apidl[i].pidlPath = ILClone(lpItems[i].pidlPath);
172 item->apidl[i].bWatchSubtree = lpItems[i].bWatchSubtree;
176 item->wEventMask = wEventMask;
177 item->dwFlags = dwFlags;
182 /*************************************************************************
183 * SHChangeNotifyDeregister [SHELL32.4]
186 SHChangeNotifyDeregister(
189 TRACE("(0x%08x)\n",hNotify);
191 return DeleteNode((LPNOTIFICATIONLIST)hNotify);
194 /*************************************************************************
195 * SHChangeNotifyUpdateEntryList [SHELL32.5]
198 SHChangeNotifyUpdateEntryList(DWORD unknown1, DWORD unknown2,
199 DWORD unknown3, DWORD unknown4)
201 FIXME("(0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n",
202 unknown1, unknown2, unknown3, unknown4);
207 /*************************************************************************
208 * SHChangeNotify [SHELL32.@]
210 void WINAPI SHChangeNotifyW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
212 LPITEMIDLIST pidl1=(LPITEMIDLIST)dwItem1, pidl2=(LPITEMIDLIST)dwItem2;
213 LPNOTIFICATIONLIST ptr;
215 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
217 /* convert paths in IDLists*/
218 if(uFlags & SHCNF_PATHA)
221 if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &pidl1, &dummy);
222 if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &pidl2, &dummy);
225 EnterCriticalSection(&SHELL32_ChangenotifyCS);
227 /* loop through the list */
231 TRACE("trying %p\n", ptr);
233 if(wEventId & ptr->wEventMask)
235 TRACE("notifying\n");
236 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)pidl1, (LPARAM)pidl2);
241 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
243 if(uFlags & SHCNF_PATHA)
245 if (pidl1) SHFree(pidl1);
246 if (pidl2) SHFree(pidl2);
250 /*************************************************************************
251 * SHChangeNotify [SHELL32.@]
253 void WINAPI SHChangeNotifyA (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
255 LPITEMIDLIST Pidls[2];
256 LPNOTIFICATIONLIST ptr;
258 Pidls[0] = (LPITEMIDLIST)dwItem1;
259 Pidls[1] = (LPITEMIDLIST)dwItem2;
261 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
263 /* convert paths in IDLists*/
264 if(uFlags & SHCNF_PATHA)
267 if (Pidls[0]) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy);
268 if (Pidls[1]) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy);
271 EnterCriticalSection(&SHELL32_ChangenotifyCS);
273 /* loop through the list */
277 TRACE("trying %p\n", ptr);
279 if(wEventId & ptr->wEventMask)
281 TRACE("notifying\n");
282 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)&Pidls, (LPARAM)wEventId);
287 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
289 /* if we allocated it, free it */
290 if(uFlags & SHCNF_PATHA)
292 if (Pidls[0]) SHFree(Pidls[0]);
293 if (Pidls[1]) SHFree(Pidls[1]);
297 /*************************************************************************
298 * SHChangeNotify [SHELL32.@]
300 void WINAPI SHChangeNotifyAW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
302 if(SHELL_OsIsUnicode())
303 SHChangeNotifyW (wEventId, uFlags, dwItem1, dwItem2);
305 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
308 /*************************************************************************
309 * NTSHChangeNotifyRegister [SHELL32.640]
311 * Idlist is an array of structures and Count specifies how many items in the array
312 * (usually just one I think).
314 DWORD WINAPI NTSHChangeNotifyRegister(
320 LPNOTIFYREGISTER idlist)
322 FIXME("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n",
323 hwnd,events1,events2,msg,count,idlist);
327 /*************************************************************************
328 * SHChangeNotification_Lock [SHELL32.644]
330 HANDLE WINAPI SHChangeNotification_Lock(
333 LPCITEMIDLIST **lppidls,
340 /*************************************************************************
341 * SHChangeNotification_Unlock [SHELL32.645]
343 BOOL WINAPI SHChangeNotification_Unlock (
350 /*************************************************************************
351 * NTSHChangeNotifyDeregister [SHELL32.641]
353 DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
355 FIXME("(0x%08lx):stub.\n",x1);