Release 20000326.
[wine/gsoc-2012-control.git] / dlls / shell32 / changenotify.c
blob38aabd8812206356705de2f37275be2a71ab9bb6
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;
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));
44 head.next = &tail;
45 tail.prev = &head;
48 void FreeChangeNotifications()
50 LPNOTIFICATIONLIST ptr, item;
52 TRACE("\n");
54 EnterCriticalSection(&SHELL32_ChangenotifyCS);
55 ptr = head.next;
57 while(ptr != &tail)
59 int i;
60 item = ptr;
61 ptr = ptr->next;
63 TRACE("item=%p\n", item);
65 /* free the item */
66 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
67 SHFree(item->apidl);
68 SHFree(item);
70 head.next = NULL;
71 tail.prev = NULL;
73 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
75 DeleteCriticalSection(&SHELL32_ChangenotifyCS);
78 static BOOL AddNode(LPNOTIFICATIONLIST item)
80 LPNOTIFICATIONLIST last;
82 EnterCriticalSection(&SHELL32_ChangenotifyCS);
84 /* get last entry */
85 last = tail.prev;
87 /* link items */
88 last->next = item;
89 item->prev = last;
90 item->next = &tail;
91 tail.prev = item;
92 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
94 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
96 return TRUE;
99 static BOOL DeleteNode(LPNOTIFICATIONLIST item)
101 LPNOTIFICATIONLIST ptr;
102 int ret = FALSE;
104 TRACE("item=%p\n", item);
106 EnterCriticalSection(&SHELL32_ChangenotifyCS);
108 ptr = head.next;
109 while((ptr != &tail) && (ret == FALSE))
111 TRACE("ptr=%p\n", ptr);
113 if (ptr == item)
115 int i;
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;
123 /* free the item */
124 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
125 SHFree(item->apidl);
126 SHFree(item);
127 ret = TRUE;
129 ptr = ptr->next;
132 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
133 return ret;
137 /*************************************************************************
138 * SHChangeNotifyRegister [SHELL32.2]
141 HANDLE WINAPI
142 SHChangeNotifyRegister(
143 HWND hwnd,
144 LONG dwFlags,
145 LONG wEventMask,
146 DWORD uMsg,
147 int cItems,
148 LPCNOTIFYREGISTER lpItems)
150 LPNOTIFICATIONLIST item;
151 int i;
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);
158 item->next = NULL;
159 item->prev = NULL;
160 item->cidl = cItems;
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;
167 item->hwnd = hwnd;
168 item->uMsg = uMsg;
169 item->wEventMask = wEventMask;
170 item->dwFlags = dwFlags;
171 AddNode(item);
172 return (HANDLE)item;
175 /*************************************************************************
176 * SHChangeNotifyDeregister [SHELL32.4]
178 BOOL WINAPI
179 SHChangeNotifyDeregister(
180 HANDLE hNotify)
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)
200 DWORD dummy;
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 */
208 ptr = head.next;
209 while(ptr != &tail)
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);
218 ptr = ptr->next;
221 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
223 if(uFlags & SHCNF_PATHA)
225 if (pidl1) SHFree(pidl1);
226 if (pidl2) SHFree(pidl2);
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)
246 DWORD dummy;
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 */
254 ptr = head.next;
255 while(ptr != &tail)
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);
264 ptr = ptr->next;
267 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
269 /* if we allocated it, free it */
270 if(uFlags & SHCNF_PATHA)
272 if (Pidls[0]) SHFree(Pidls[0]);
273 if (Pidls[1]) SHFree(Pidls[1]);
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);
284 else
285 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
288 /*************************************************************************
289 * NTSHChangeNotifyRegister [SHELL32.640]
290 * NOTES
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(
295 HWND hwnd,
296 LONG events1,
297 LONG events2,
298 DWORD msg,
299 int count,
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);
304 return 0;
307 /*************************************************************************
308 * SHChangeNotification_Lock [SHELL32.644]
310 HANDLE WINAPI SHChangeNotification_Lock(
311 HANDLE hMemoryMap,
312 DWORD dwProcessId,
313 LPCITEMIDLIST **lppidls,
314 LPLONG lpwEventId)
316 FIXME("\n");
317 return 0;
320 /*************************************************************************
321 * SHChangeNotification_Unlock [SHELL32.645]
323 BOOL WINAPI SHChangeNotification_Unlock (
324 HANDLE hLock)
326 FIXME("\n");
327 return 0;
330 /*************************************************************************
331 * NTSHChangeNotifyDeregister [SHELL32.641]
333 DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
335 FIXME("(0x%08lx):stub.\n",x1);
336 return 0;