Merged the two serializer and unserializer functions into one, cleaned
[wine.git] / dlls / shell32 / changenotify.c
blobf2d9c62903e6b8ade08fa7e7fcf5bace08623133
1 /*
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
21 #include <string.h>
23 #include "wine/debug.h"
24 #include "pidl.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);
51 head.next = &tail;
52 tail.prev = &head;
55 void FreeChangeNotifications()
57 LPNOTIFICATIONLIST ptr, item;
59 TRACE("\n");
61 EnterCriticalSection(&SHELL32_ChangenotifyCS);
62 ptr = head.next;
64 while(ptr != &tail)
66 int i;
67 item = ptr;
68 ptr = ptr->next;
70 TRACE("item=%p\n", item);
72 /* free the item */
73 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
74 SHFree(item->apidl);
75 SHFree(item);
77 head.next = NULL;
78 tail.prev = NULL;
80 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
82 DeleteCriticalSection(&SHELL32_ChangenotifyCS);
85 static BOOL AddNode(LPNOTIFICATIONLIST item)
87 LPNOTIFICATIONLIST last;
89 EnterCriticalSection(&SHELL32_ChangenotifyCS);
91 /* get last entry */
92 last = tail.prev;
94 /* link items */
95 last->next = item;
96 item->prev = last;
97 item->next = &tail;
98 tail.prev = item;
99 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
101 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
103 return TRUE;
106 static BOOL DeleteNode(LPNOTIFICATIONLIST item)
108 LPNOTIFICATIONLIST ptr;
109 int ret = FALSE;
111 TRACE("item=%p\n", item);
113 EnterCriticalSection(&SHELL32_ChangenotifyCS);
115 ptr = head.next;
116 while((ptr != &tail) && (ret == FALSE))
118 TRACE("ptr=%p\n", ptr);
120 if (ptr == item)
122 int i;
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;
130 /* free the item */
131 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
132 SHFree(item->apidl);
133 SHFree(item);
134 ret = TRUE;
136 ptr = ptr->next;
139 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
140 return ret;
144 /*************************************************************************
145 * SHChangeNotifyRegister [SHELL32.2]
148 HANDLE WINAPI
149 SHChangeNotifyRegister(
150 HWND hwnd,
151 LONG dwFlags,
152 LONG wEventMask,
153 DWORD uMsg,
154 int cItems,
155 LPCNOTIFYREGISTER lpItems)
157 LPNOTIFICATIONLIST item;
158 int i;
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);
165 item->next = NULL;
166 item->prev = NULL;
167 item->cidl = cItems;
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;
174 item->hwnd = hwnd;
175 item->uMsg = uMsg;
176 item->wEventMask = wEventMask;
177 item->dwFlags = dwFlags;
178 AddNode(item);
179 return (HANDLE)item;
182 /*************************************************************************
183 * SHChangeNotifyDeregister [SHELL32.4]
185 BOOL WINAPI
186 SHChangeNotifyDeregister(
187 HANDLE hNotify)
189 TRACE("(0x%08x)\n",hNotify);
191 return DeleteNode((LPNOTIFICATIONLIST)hNotify);
194 /*************************************************************************
195 * SHChangeNotifyUpdateEntryList [SHELL32.5]
197 BOOL WINAPI
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);
204 return -1;
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)
220 DWORD dummy;
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 */
228 ptr = head.next;
229 while(ptr != &tail)
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);
238 ptr = ptr->next;
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)
266 DWORD dummy;
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 */
274 ptr = head.next;
275 while(ptr != &tail)
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);
284 ptr = ptr->next;
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);
304 else
305 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
308 /*************************************************************************
309 * NTSHChangeNotifyRegister [SHELL32.640]
310 * NOTES
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(
315 HWND hwnd,
316 LONG events1,
317 LONG events2,
318 DWORD msg,
319 int count,
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);
324 return 0;
327 /*************************************************************************
328 * SHChangeNotification_Lock [SHELL32.644]
330 HANDLE WINAPI SHChangeNotification_Lock(
331 HANDLE hMemoryMap,
332 DWORD dwProcessId,
333 LPCITEMIDLIST **lppidls,
334 LPLONG lpwEventId)
336 FIXME("\n");
337 return 0;
340 /*************************************************************************
341 * SHChangeNotification_Unlock [SHELL32.645]
343 BOOL WINAPI SHChangeNotification_Unlock (
344 HANDLE hLock)
346 FIXME("\n");
347 return 0;
350 /*************************************************************************
351 * NTSHChangeNotifyDeregister [SHELL32.641]
353 DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
355 FIXME("(0x%08lx):stub.\n",x1);
356 return 0;