source: trunk/src/shell32/changenotify.c@ 9752

Last change on this file since 9752 was 9408, checked in by sandervl, 23 years ago

compile fixes

File size: 8.3 KB
Line 
1/* $Id: changenotify.c,v 1.8 2002-11-13 14:42:27 sandervl Exp $ */
2/*
3 * shell change notification
4 *
5 * Juergen Schmied <juergen.schmied@debitel.de>
6 *
7 */
8#ifdef __WIN32OS2__
9#define ICOM_CINTERFACE 1
10#include <odin.h>
11#endif
12
13#include <string.h>
14
15#include "debugtools.h"
16#include "pidl.h"
17#include "shell32_main.h"
18#include "undocshell.h"
19
20DEFAULT_DEBUG_CHANNEL(shell);
21
22static CRITICAL_SECTION SHELL32_ChangenotifyCS = CRITICAL_SECTION_INIT("SHELL32_ChangenotifyCS");
23
24/* internal list of notification clients (internal) */
25typedef struct _NOTIFICATIONLIST
26{
27 struct _NOTIFICATIONLIST *next;
28 struct _NOTIFICATIONLIST *prev;
29 HWND hwnd; /* window to notify */
30 DWORD uMsg; /* message to send */
31 LPNOTIFYREGISTER apidl; /* array of entries to watch*/
32 UINT cidl; /* number of pidls in array */
33 LONG wEventMask; /* subscribed events */
34 DWORD dwFlags; /* client flags */
35} NOTIFICATIONLIST, *LPNOTIFICATIONLIST;
36
37static NOTIFICATIONLIST head;
38static NOTIFICATIONLIST tail;
39
40void InitChangeNotifications()
41{
42 TRACE("head=%p tail=%p\n", &head, &tail);
43 head.next = &tail;
44 tail.prev = &head;
45}
46
47void FreeChangeNotifications()
48{
49 LPNOTIFICATIONLIST ptr, item;
50
51 TRACE("\n");
52
53 EnterCriticalSection(&SHELL32_ChangenotifyCS);
54 ptr = head.next;
55
56 while(ptr != &tail)
57 {
58 int i;
59 item = ptr;
60 ptr = ptr->next;
61
62 TRACE("item=%p\n", item);
63
64 /* free the item */
65 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
66 SHFree(item->apidl);
67 SHFree(item);
68 }
69 head.next = NULL;
70 tail.prev = NULL;
71
72 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
73
74 DeleteCriticalSection(&SHELL32_ChangenotifyCS);
75}
76
77static BOOL AddNode(LPNOTIFICATIONLIST item)
78{
79 LPNOTIFICATIONLIST last;
80
81 EnterCriticalSection(&SHELL32_ChangenotifyCS);
82
83 /* get last entry */
84 last = tail.prev;
85
86 /* link items */
87 last->next = item;
88 item->prev = last;
89 item->next = &tail;
90 tail.prev = item;
91 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
92
93 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
94
95 return TRUE;
96}
97
98static BOOL DeleteNode(LPNOTIFICATIONLIST item)
99{
100 LPNOTIFICATIONLIST ptr;
101 int ret = FALSE;
102
103 TRACE("item=%p\n", item);
104
105 EnterCriticalSection(&SHELL32_ChangenotifyCS);
106
107 ptr = head.next;
108#ifdef __WIN32OS2__
109 while((ptr != &tail)/* && (ret == FALSE) see the rant below */)
110#else
111 while((ptr != &tail) && (ret == FALSE))
112#endif
113 {
114 TRACE("ptr=%p\n", ptr);
115
116 if (ptr == item)
117 {
118 int i;
119
120 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
121
122 /* remove item from list */
123 item->prev->next = item->next;
124 item->next->prev = item->prev;
125
126 /* free the item */
127 for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
128 SHFree(item->apidl);
129 SHFree(item);
130#ifdef __WIN32OS2__
131 /*
132 * Anyway, ptr == item, we free item hence the memory shouldn't be
133 * accessed by us any longer. We have to break here so we do NOT do
134 * the next operation below!
135 * -bird-
136 */
137 ret = TRUE;
138 break;
139#else
140 ret = TRUE;
141#endif
142 }
143 ptr = ptr->next;
144 }
145
146 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
147 return ret;
148
149}
150
151/*************************************************************************
152 * SHChangeNotifyRegister [SHELL32.2]
153 *
154 */
155HANDLE WINAPI
156SHChangeNotifyRegister(
157 HWND hwnd,
158 LONG dwFlags,
159 LONG wEventMask,
160 DWORD uMsg,
161 int cItems,
162 LPCNOTIFYREGISTER lpItems)
163{
164 LPNOTIFICATIONLIST item;
165 int i;
166
167 item = SHAlloc(sizeof(NOTIFICATIONLIST));
168
169 TRACE("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p) item=%p\n",
170 hwnd,dwFlags,wEventMask,uMsg,cItems,lpItems,item);
171
172 item->next = NULL;
173 item->prev = NULL;
174 item->cidl = cItems;
175 item->apidl = SHAlloc(sizeof(NOTIFYREGISTER) * cItems);
176 for(i=0;i<cItems;i++)
177 {
178 item->apidl[i].pidlPath = ILClone(lpItems[i].pidlPath);
179 item->apidl[i].bWatchSubtree = lpItems[i].bWatchSubtree;
180 }
181 item->hwnd = hwnd;
182 item->uMsg = uMsg;
183 item->wEventMask = wEventMask;
184 item->dwFlags = dwFlags;
185 AddNode(item);
186 return (HANDLE)item;
187}
188
189/*************************************************************************
190 * SHChangeNotifyDeregister [SHELL32.4]
191 */
192BOOL WINAPI
193SHChangeNotifyDeregister(
194 HANDLE hNotify)
195{
196 TRACE("(0x%08x)\n",hNotify);
197
198 return DeleteNode((LPNOTIFICATIONLIST)hNotify);;
199}
200
201/*************************************************************************
202 * SHChangeNotifyUpdateEntryList [SHELL32.5]
203 */
204BOOL WINAPI
205SHChangeNotifyUpdateEntryList(DWORD unknown1, DWORD unknown2,
206 DWORD unknown3, DWORD unknown4)
207{
208 FIXME("(0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n",
209 unknown1, unknown2, unknown3, unknown4);
210
211 return -1;
212}
213
214/*************************************************************************
215 * SHChangeNotify [SHELL32.239]
216 */
217void WINAPI SHChangeNotifyW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
218{
219 LPITEMIDLIST pidl1=(LPITEMIDLIST)dwItem1, pidl2=(LPITEMIDLIST)dwItem2;
220 LPNOTIFICATIONLIST ptr;
221
222 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
223
224 /* convert paths in IDLists*/
225 if(uFlags & SHCNF_PATHA)
226 {
227 DWORD dummy;
228 if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &pidl1, &dummy);
229 if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &pidl2, &dummy);
230 }
231
232 EnterCriticalSection(&SHELL32_ChangenotifyCS);
233
234 /* loop through the list */
235 ptr = head.next;
236 while(ptr != &tail)
237 {
238 TRACE("trying %p\n", ptr);
239
240 if(wEventId & ptr->wEventMask)
241 {
242 TRACE("notifying\n");
243 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)pidl1, (LPARAM)pidl2);
244 }
245 ptr = ptr->next;
246 }
247
248 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
249
250 if(uFlags & SHCNF_PATHA)
251 {
252 if (pidl1) SHFree(pidl1);
253 if (pidl2) SHFree(pidl2);
254 }
255}
256
257/*************************************************************************
258 * SHChangeNotify [SHELL32.239]
259 */
260void WINAPI SHChangeNotifyA (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
261{
262 LPITEMIDLIST Pidls[2];
263 LPNOTIFICATIONLIST ptr;
264
265 Pidls[0] = (LPITEMIDLIST)dwItem1;
266 Pidls[1] = (LPITEMIDLIST)dwItem2;
267
268 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2);
269
270 /* convert paths in IDLists*/
271 if(uFlags & SHCNF_PATHA)
272 {
273 DWORD dummy;
274 if (Pidls[0]) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy);
275 if (Pidls[1]) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy);
276 }
277
278 EnterCriticalSection(&SHELL32_ChangenotifyCS);
279
280 /* loop through the list */
281 ptr = head.next;
282 while(ptr != &tail)
283 {
284 TRACE("trying %p\n", ptr);
285
286 if(wEventId & ptr->wEventMask)
287 {
288 TRACE("notifying\n");
289 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)&Pidls, (LPARAM)wEventId);
290 }
291 ptr = ptr->next;
292 }
293
294 LeaveCriticalSection(&SHELL32_ChangenotifyCS);
295
296 /* if we allocated it, free it */
297 if(uFlags & SHCNF_PATHA)
298 {
299 if (Pidls[0]) SHFree(Pidls[0]);
300 if (Pidls[1]) SHFree(Pidls[1]);
301 }
302}
303
304/*************************************************************************
305 * SHChangeNotifyAW [SHELL32.239]
306 */
307void WINAPI SHChangeNotifyAW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
308{
309 if(SHELL_OsIsUnicode())
310 SHChangeNotifyW (wEventId, uFlags, dwItem1, dwItem2);
311 else
312 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2);
313}
314
315/*************************************************************************
316 * NTSHChangeNotifyRegister [SHELL32.640]
317 * NOTES
318 * Idlist is an array of structures and Count specifies how many items in the array
319 * (usually just one I think).
320 */
321DWORD WINAPI NTSHChangeNotifyRegister(
322 HWND hwnd,
323 LONG events1,
324 LONG events2,
325 DWORD msg,
326 int count,
327 LPNOTIFYREGISTER idlist)
328{
329 FIXME("(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n",
330 hwnd,events1,events2,msg,count,idlist);
331 return 0;
332}
333
334/*************************************************************************
335 * SHChangeNotification_Lock [SHELL32.644]
336 */
337HANDLE WINAPI SHChangeNotification_Lock(
338 HANDLE hMemoryMap,
339 DWORD dwProcessId,
340 LPCITEMIDLIST **lppidls,
341 LPLONG lpwEventId)
342{
343 FIXME("\n");
344 return 0;
345}
346
347/*************************************************************************
348 * SHChangeNotification_Unlock [SHELL32.645]
349 */
350BOOL WINAPI SHChangeNotification_Unlock (
351 HANDLE hLock)
352{
353 FIXME("\n");
354 return 0;
355}
356
357/*************************************************************************
358 * NTSHChangeNotifyDeregister [SHELL32.641]
359 */
360DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
361{
362 FIXME("(0x%08lx):stub.\n",x1);
363 return 0;
364}
365
Note: See TracBrowser for help on using the repository browser.