Add a missing </sect3>.
[wine.git] / dlls / shell32 / changenotify.c
blob8169567e3aa5e2c8708432194c3224b4c819dd0c
1 /*
2 * shell change notification
4 * Juergen Schmied <juergen.schmied@debitel.de>
6 */
8 #include <string.h>
10 #include "debugtools.h"
11 #include "pidl.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);
38 head.next = &tail;
39 tail.prev = &head;
42 void FreeChangeNotifications()
44 LPNOTIFICATIONLIST ptr, item;
46 TRACE("\n");
48 EnterCriticalSection(&SHELL32_ChangenotifyCS);
49 ptr = head.next;
51 while(ptr != &tail)
53 int i;
54 item = ptr;
55 ptr = ptr->next;
57 TRACE("item=%p\n", item);
59 /* free the item */
60 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
61 SHFree(item->apidl);
62 SHFree(item);
64 head.next = NULL;
65 tail.prev = NULL;
67 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
69 DeleteCriticalSection(&SHELL32_ChangenotifyCS);
72 static BOOL AddNode(LPNOTIFICATIONLIST item)
74 LPNOTIFICATIONLIST last;
76 EnterCriticalSection(&SHELL32_ChangenotifyCS);
78 /* get last entry */
79 last = tail.prev;
81 /* link items */
82 last->next = item;
83 item->prev = last;
84 item->next = &tail;
85 tail.prev = item;
86 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
88 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
90 return TRUE;
93 static BOOL DeleteNode(LPNOTIFICATIONLIST item)
95 LPNOTIFICATIONLIST ptr;
96 int ret = FALSE;
98 TRACE("item=%p\n", item);
100 EnterCriticalSection(&SHELL32_ChangenotifyCS);
102 ptr = head.next;
103 while((ptr != &tail) && (ret == FALSE))
105 TRACE("ptr=%p\n", ptr);
107 if (ptr == item)
109 int i;
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;
117 /* free the item */
118 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
119 SHFree(item->apidl);
120 SHFree(item);
121 ret = TRUE;
123 ptr = ptr->next;
126 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
127 return ret;
131 /*************************************************************************
132 * SHChangeNotifyRegister [SHELL32.2]
135 HANDLE WINAPI
136 SHChangeNotifyRegister(
137 HWND hwnd,
138 LONG dwFlags,
139 LONG wEventMask,
140 DWORD uMsg,
141 int cItems,
142 LPCNOTIFYREGISTER lpItems)
144 LPNOTIFICATIONLIST item;
145 int i;
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);
152 item->next = NULL;
153 item->prev = NULL;
154 item->cidl = cItems;
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;
161 item->hwnd = hwnd;
162 item->uMsg = uMsg;
163 item->wEventMask = wEventMask;
164 item->dwFlags = dwFlags;
165 AddNode(item);
166 return (HANDLE)item;
169 /*************************************************************************
170 * SHChangeNotifyDeregister [SHELL32.4]
172 BOOL WINAPI
173 SHChangeNotifyDeregister(
174 HANDLE hNotify)
176 TRACE("(0x%08x)\n",hNotify);
178 return DeleteNode((LPNOTIFICATIONLIST)hNotify);;
181 /*************************************************************************
182 * SHChangeNotify [SHELL32.239]
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)
194 DWORD dummy;
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 */
202 ptr = head.next;
203 while(ptr != &tail)
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);
212 ptr = ptr->next;
215 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
217 if(uFlags & SHCNF_PATHA)
219 if (pidl1) SHFree(pidl1);
220 if (pidl2) SHFree(pidl2);
224 /*************************************************************************
225 * SHChangeNotify [SHELL32.239]
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)
240 DWORD dummy;
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 */
248 ptr = head.next;
249 while(ptr != &tail)
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);
258 ptr = ptr->next;
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 * SHChangeNotifyAW [SHELL32.239]
274 void WINAPI SHChangeNotifyAW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
276 if(SHELL_OsIsUnicode())
277 SHChangeNotifyW (wEventId, uFlags, dwItem1, dwItem2);
278 else
279 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
282 /*************************************************************************
283 * NTSHChangeNotifyRegister [SHELL32.640]
284 * NOTES
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(
289 HWND hwnd,
290 LONG events1,
291 LONG events2,
292 DWORD msg,
293 int count,
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);
298 return 0;
301 /*************************************************************************
302 * SHChangeNotification_Lock [SHELL32.644]
304 HANDLE WINAPI SHChangeNotification_Lock(
305 HANDLE hMemoryMap,
306 DWORD dwProcessId,
307 LPCITEMIDLIST **lppidls,
308 LPLONG lpwEventId)
310 FIXME("\n");
311 return 0;
314 /*************************************************************************
315 * SHChangeNotification_Unlock [SHELL32.645]
317 BOOL WINAPI SHChangeNotification_Unlock (
318 HANDLE hLock)
320 FIXME("\n");
321 return 0;
324 /*************************************************************************
325 * NTSHChangeNotifyDeregister [SHELL32.641]
327 DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
329 FIXME("(0x%08lx):stub.\n",x1);
330 return 0;