Added DECL_GLOBAL_CONSTRUCTOR macro.
[wine/multimedia.git] / dlls / shell32 / changenotify.c
blobd2377e4cc999352b4ddfb62458ecbb9321c876a5
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 "winversion.h"
14 #include "wine/undocshell.h"
16 DEFAULT_DEBUG_CHANNEL(shell);
18 static CRITICAL_SECTION SHELL32_ChangenotifyCS = CRITICAL_SECTION_INIT;
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 static NOTIFICATIONLIST head;
34 static NOTIFICATIONLIST tail;
36 void InitChangeNotifications()
38 TRACE("head=%p tail=%p\n", &head, &tail);
39 head.next = &tail;
40 tail.prev = &head;
43 void FreeChangeNotifications()
45 LPNOTIFICATIONLIST ptr, item;
47 TRACE("\n");
49 EnterCriticalSection(&SHELL32_ChangenotifyCS);
50 ptr = head.next;
52 while(ptr != &tail)
54 int i;
55 item = ptr;
56 ptr = ptr->next;
58 TRACE("item=%p\n", item);
60 /* free the item */
61 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
62 SHFree(item->apidl);
63 SHFree(item);
65 head.next = NULL;
66 tail.prev = NULL;
68 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
70 DeleteCriticalSection(&SHELL32_ChangenotifyCS);
73 static BOOL AddNode(LPNOTIFICATIONLIST item)
75 LPNOTIFICATIONLIST last;
77 EnterCriticalSection(&SHELL32_ChangenotifyCS);
79 /* get last entry */
80 last = tail.prev;
82 /* link items */
83 last->next = item;
84 item->prev = last;
85 item->next = &tail;
86 tail.prev = item;
87 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
89 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
91 return TRUE;
94 static BOOL DeleteNode(LPNOTIFICATIONLIST item)
96 LPNOTIFICATIONLIST ptr;
97 int ret = FALSE;
99 TRACE("item=%p\n", item);
101 EnterCriticalSection(&SHELL32_ChangenotifyCS);
103 ptr = head.next;
104 while((ptr != &tail) && (ret == FALSE))
106 TRACE("ptr=%p\n", ptr);
108 if (ptr == item)
110 int i;
112 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
114 /* remove item from list */
115 item->prev->next = item->next;
116 item->next->prev = item->prev;
118 /* free the item */
119 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
120 SHFree(item->apidl);
121 SHFree(item);
122 ret = TRUE;
124 ptr = ptr->next;
127 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
128 return ret;
132 /*************************************************************************
133 * SHChangeNotifyRegister [SHELL32.2]
136 HANDLE WINAPI
137 SHChangeNotifyRegister(
138 HWND hwnd,
139 LONG dwFlags,
140 LONG wEventMask,
141 DWORD uMsg,
142 int cItems,
143 LPCNOTIFYREGISTER lpItems)
145 LPNOTIFICATIONLIST item;
146 int i;
148 item = SHAlloc(sizeof(NOTIFICATIONLIST));
150 TRACE("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p) item=%p\n",
151 hwnd,dwFlags,wEventMask,uMsg,cItems,lpItems,item);
153 item->next = NULL;
154 item->prev = NULL;
155 item->cidl = cItems;
156 item->apidl = SHAlloc(sizeof(NOTIFYREGISTER) * cItems);
157 for(i=0;i<cItems;i++)
159 item->apidl[i].pidlPath = ILClone(lpItems[i].pidlPath);
160 item->apidl[i].bWatchSubtree = lpItems[i].bWatchSubtree;
162 item->hwnd = hwnd;
163 item->uMsg = uMsg;
164 item->wEventMask = wEventMask;
165 item->dwFlags = dwFlags;
166 AddNode(item);
167 return (HANDLE)item;
170 /*************************************************************************
171 * SHChangeNotifyDeregister [SHELL32.4]
173 BOOL WINAPI
174 SHChangeNotifyDeregister(
175 HANDLE hNotify)
177 TRACE("(0x%08x)\n",hNotify);
179 return DeleteNode((LPNOTIFICATIONLIST)hNotify);;
182 /*************************************************************************
183 * SHChangeNotify [SHELL32.239]
185 void WINAPI SHChangeNotifyW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
187 LPITEMIDLIST pidl1=(LPITEMIDLIST)dwItem1, pidl2=(LPITEMIDLIST)dwItem2;
188 LPNOTIFICATIONLIST ptr;
190 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
192 /* convert paths in IDLists*/
193 if(uFlags & SHCNF_PATHA)
195 DWORD dummy;
196 if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &pidl1, &dummy);
197 if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &pidl2, &dummy);
200 EnterCriticalSection(&SHELL32_ChangenotifyCS);
202 /* loop through the list */
203 ptr = head.next;
204 while(ptr != &tail)
206 TRACE("trying %p\n", ptr);
208 if(wEventId & ptr->wEventMask)
210 TRACE("notifying\n");
211 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)pidl1, (LPARAM)pidl2);
213 ptr = ptr->next;
216 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
218 if(uFlags & SHCNF_PATHA)
220 if (pidl1) SHFree(pidl1);
221 if (pidl2) SHFree(pidl2);
225 /*************************************************************************
226 * SHChangeNotify [SHELL32.239]
228 void WINAPI SHChangeNotifyA (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
230 LPITEMIDLIST Pidls[2];
231 LPNOTIFICATIONLIST ptr;
233 Pidls[0] = (LPITEMIDLIST)dwItem1;
234 Pidls[1] = (LPITEMIDLIST)dwItem2;
236 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
238 /* convert paths in IDLists*/
239 if(uFlags & SHCNF_PATHA)
241 DWORD dummy;
242 if (Pidls[0]) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy);
243 if (Pidls[1]) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy);
246 EnterCriticalSection(&SHELL32_ChangenotifyCS);
248 /* loop through the list */
249 ptr = head.next;
250 while(ptr != &tail)
252 TRACE("trying %p\n", ptr);
254 if(wEventId & ptr->wEventMask)
256 TRACE("notifying\n");
257 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)&Pidls, (LPARAM)wEventId);
259 ptr = ptr->next;
262 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
264 /* if we allocated it, free it */
265 if(uFlags & SHCNF_PATHA)
267 if (Pidls[0]) SHFree(Pidls[0]);
268 if (Pidls[1]) SHFree(Pidls[1]);
272 /*************************************************************************
273 * SHChangeNotifyAW [SHELL32.239]
275 void WINAPI SHChangeNotifyAW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
277 if(VERSION_OsIsUnicode())
278 SHChangeNotifyW (wEventId, uFlags, dwItem1, dwItem2);
279 else
280 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
283 /*************************************************************************
284 * NTSHChangeNotifyRegister [SHELL32.640]
285 * NOTES
286 * Idlist is an array of structures and Count specifies how many items in the array
287 * (usually just one I think).
289 DWORD WINAPI NTSHChangeNotifyRegister(
290 HWND hwnd,
291 LONG events1,
292 LONG events2,
293 DWORD msg,
294 int count,
295 LPNOTIFYREGISTER idlist)
297 FIXME("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n",
298 hwnd,events1,events2,msg,count,idlist);
299 return 0;
302 /*************************************************************************
303 * SHChangeNotification_Lock [SHELL32.644]
305 HANDLE WINAPI SHChangeNotification_Lock(
306 HANDLE hMemoryMap,
307 DWORD dwProcessId,
308 LPCITEMIDLIST **lppidls,
309 LPLONG lpwEventId)
311 FIXME("\n");
312 return 0;
315 /*************************************************************************
316 * SHChangeNotification_Unlock [SHELL32.645]
318 BOOL WINAPI SHChangeNotification_Unlock (
319 HANDLE hLock)
321 FIXME("\n");
322 return 0;
325 /*************************************************************************
326 * NTSHChangeNotifyDeregister [SHELL32.641]
328 DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
330 FIXME("(0x%08lx):stub.\n",x1);
331 return 0;