source: trunk/src/shell32/changenotify.cpp@ 4032

Last change on this file since 4032 was 4032, checked in by phaller, 25 years ago

Synchronized shell32 with wine

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