[9805] | 1 | /* $Id: changenotify.c,v 1.9 2003-02-14 10:07:17 sandervl Exp $ */
|
---|
[4121] | 2 | /*
|
---|
| 3 | * shell change notification
|
---|
| 4 | *
|
---|
[9805] | 5 | * Copyright 2000 Juergen Schmied
|
---|
[4121] | 6 | *
|
---|
[9805] | 7 | * This library is free software; you can redistribute it and/or
|
---|
| 8 | * modify it under the terms of the GNU Lesser General Public
|
---|
| 9 | * License as published by the Free Software Foundation; either
|
---|
| 10 | * version 2.1 of the License, or (at your option) any later version.
|
---|
| 11 | *
|
---|
| 12 | * This library is distributed in the hope that it will be useful,
|
---|
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 15 | * Lesser General Public License for more details.
|
---|
| 16 | *
|
---|
| 17 | * You should have received a copy of the GNU Lesser General Public
|
---|
| 18 | * License along with this library; if not, write to the Free Software
|
---|
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
[4121] | 20 | */
|
---|
| 21 | #ifdef __WIN32OS2__
|
---|
[21494] | 22 | #define CINTERFACE
|
---|
[4121] | 23 | #include <odin.h>
|
---|
| 24 | #endif
|
---|
| 25 |
|
---|
| 26 | #include <string.h>
|
---|
| 27 |
|
---|
[9805] | 28 | #include "wine/debug.h"
|
---|
[4121] | 29 | #include "pidl.h"
|
---|
| 30 | #include "shell32_main.h"
|
---|
[8614] | 31 | #include "undocshell.h"
|
---|
[4121] | 32 |
|
---|
[9805] | 33 | WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
---|
[4121] | 34 |
|
---|
[9408] | 35 | static CRITICAL_SECTION SHELL32_ChangenotifyCS = CRITICAL_SECTION_INIT("SHELL32_ChangenotifyCS");
|
---|
[4121] | 36 |
|
---|
| 37 | /* internal list of notification clients (internal) */
|
---|
| 38 | typedef struct _NOTIFICATIONLIST
|
---|
| 39 | {
|
---|
| 40 | struct _NOTIFICATIONLIST *next;
|
---|
[8755] | 41 | struct _NOTIFICATIONLIST *prev;
|
---|
[4121] | 42 | HWND hwnd; /* window to notify */
|
---|
| 43 | DWORD uMsg; /* message to send */
|
---|
[8048] | 44 | LPNOTIFYREGISTER apidl; /* array of entries to watch*/
|
---|
[4121] | 45 | UINT cidl; /* number of pidls in array */
|
---|
| 46 | LONG wEventMask; /* subscribed events */
|
---|
| 47 | DWORD dwFlags; /* client flags */
|
---|
| 48 | } NOTIFICATIONLIST, *LPNOTIFICATIONLIST;
|
---|
| 49 |
|
---|
| 50 | static NOTIFICATIONLIST head;
|
---|
| 51 | static NOTIFICATIONLIST tail;
|
---|
| 52 |
|
---|
| 53 | void InitChangeNotifications()
|
---|
| 54 | {
|
---|
| 55 | TRACE("head=%p tail=%p\n", &head, &tail);
|
---|
| 56 | head.next = &tail;
|
---|
| 57 | tail.prev = &head;
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 | void FreeChangeNotifications()
|
---|
| 61 | {
|
---|
| 62 | LPNOTIFICATIONLIST ptr, item;
|
---|
| 63 |
|
---|
| 64 | TRACE("\n");
|
---|
| 65 |
|
---|
| 66 | EnterCriticalSection(&SHELL32_ChangenotifyCS);
|
---|
| 67 | ptr = head.next;
|
---|
| 68 |
|
---|
| 69 | while(ptr != &tail)
|
---|
[8755] | 70 | {
|
---|
[9805] | 71 | UINT i;
|
---|
[4121] | 72 | item = ptr;
|
---|
| 73 | ptr = ptr->next;
|
---|
| 74 |
|
---|
| 75 | TRACE("item=%p\n", item);
|
---|
[8755] | 76 |
|
---|
[4121] | 77 | /* free the item */
|
---|
| 78 | for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
|
---|
| 79 | SHFree(item->apidl);
|
---|
| 80 | SHFree(item);
|
---|
| 81 | }
|
---|
| 82 | head.next = NULL;
|
---|
| 83 | tail.prev = NULL;
|
---|
| 84 |
|
---|
| 85 | LeaveCriticalSection(&SHELL32_ChangenotifyCS);
|
---|
| 86 |
|
---|
| 87 | DeleteCriticalSection(&SHELL32_ChangenotifyCS);
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | static BOOL AddNode(LPNOTIFICATIONLIST item)
|
---|
| 91 | {
|
---|
| 92 | LPNOTIFICATIONLIST last;
|
---|
| 93 |
|
---|
| 94 | EnterCriticalSection(&SHELL32_ChangenotifyCS);
|
---|
| 95 |
|
---|
| 96 | /* get last entry */
|
---|
| 97 | last = tail.prev;
|
---|
| 98 |
|
---|
| 99 | /* link items */
|
---|
| 100 | last->next = item;
|
---|
| 101 | item->prev = last;
|
---|
| 102 | item->next = &tail;
|
---|
| 103 | tail.prev = item;
|
---|
| 104 | TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
|
---|
| 105 |
|
---|
| 106 | LeaveCriticalSection(&SHELL32_ChangenotifyCS);
|
---|
| 107 |
|
---|
| 108 | return TRUE;
|
---|
| 109 | }
|
---|
| 110 |
|
---|
| 111 | static BOOL DeleteNode(LPNOTIFICATIONLIST item)
|
---|
| 112 | {
|
---|
| 113 | LPNOTIFICATIONLIST ptr;
|
---|
| 114 | int ret = FALSE;
|
---|
| 115 |
|
---|
| 116 | TRACE("item=%p\n", item);
|
---|
| 117 |
|
---|
| 118 | EnterCriticalSection(&SHELL32_ChangenotifyCS);
|
---|
| 119 |
|
---|
| 120 | ptr = head.next;
|
---|
[9805] | 121 | while(ptr != &tail)
|
---|
[8755] | 122 | {
|
---|
[4121] | 123 | TRACE("ptr=%p\n", ptr);
|
---|
[8755] | 124 |
|
---|
[4121] | 125 | if (ptr == item)
|
---|
| 126 | {
|
---|
[9805] | 127 | UINT i;
|
---|
[8755] | 128 |
|
---|
[4121] | 129 | TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
|
---|
| 130 |
|
---|
| 131 | /* remove item from list */
|
---|
| 132 | item->prev->next = item->next;
|
---|
| 133 | item->next->prev = item->prev;
|
---|
| 134 |
|
---|
| 135 | /* free the item */
|
---|
| 136 | for (i=0; i<item->cidl;i++) SHFree(item->apidl[i].pidlPath);
|
---|
| 137 | SHFree(item->apidl);
|
---|
| 138 | SHFree(item);
|
---|
[9805] | 139 |
|
---|
| 140 | ret = TRUE;
|
---|
| 141 | break;
|
---|
[4121] | 142 | }
|
---|
| 143 | ptr = ptr->next;
|
---|
| 144 | }
|
---|
| 145 |
|
---|
| 146 | LeaveCriticalSection(&SHELL32_ChangenotifyCS);
|
---|
| 147 | return ret;
|
---|
| 148 |
|
---|
| 149 | }
|
---|
| 150 |
|
---|
| 151 | /*************************************************************************
|
---|
| 152 | * SHChangeNotifyRegister [SHELL32.2]
|
---|
| 153 | *
|
---|
| 154 | */
|
---|
| 155 | HANDLE WINAPI
|
---|
| 156 | SHChangeNotifyRegister(
|
---|
| 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 |
|
---|
[9805] | 169 | TRACE("(%p,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p) item=%p\n",
|
---|
[4121] | 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 | */
|
---|
| 192 | BOOL WINAPI
|
---|
[9805] | 193 | SHChangeNotifyDeregister(HANDLE hNotify)
|
---|
[4121] | 194 | {
|
---|
[9805] | 195 | TRACE("(%p)\n",hNotify);
|
---|
[4121] | 196 |
|
---|
[9805] | 197 | return DeleteNode((LPNOTIFICATIONLIST)hNotify);
|
---|
[4121] | 198 | }
|
---|
| 199 |
|
---|
| 200 | /*************************************************************************
|
---|
[8048] | 201 | * SHChangeNotifyUpdateEntryList [SHELL32.5]
|
---|
| 202 | */
|
---|
| 203 | BOOL WINAPI
|
---|
| 204 | SHChangeNotifyUpdateEntryList(DWORD unknown1, DWORD unknown2,
|
---|
| 205 | DWORD unknown3, DWORD unknown4)
|
---|
| 206 | {
|
---|
| 207 | FIXME("(0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n",
|
---|
| 208 | unknown1, unknown2, unknown3, unknown4);
|
---|
| 209 |
|
---|
| 210 | return -1;
|
---|
| 211 | }
|
---|
| 212 |
|
---|
| 213 | /*************************************************************************
|
---|
[4121] | 214 | * SHChangeNotify [SHELL32.239]
|
---|
| 215 | */
|
---|
[9805] | 216 | void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
|
---|
[4121] | 217 | {
|
---|
[9805] | 218 | LPITEMIDLIST Pidls[2];
|
---|
[4121] | 219 | LPNOTIFICATIONLIST ptr;
|
---|
[9805] | 220 | DWORD dummy;
|
---|
| 221 | UINT typeFlag = uFlags & SHCNF_TYPE;
|
---|
[4121] | 222 |
|
---|
| 223 | Pidls[0] = (LPITEMIDLIST)dwItem1;
|
---|
| 224 | Pidls[1] = (LPITEMIDLIST)dwItem2;
|
---|
| 225 |
|
---|
[9805] | 226 | TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId, uFlags, dwItem1, dwItem2);
|
---|
[4121] | 227 |
|
---|
| 228 | /* convert paths in IDLists*/
|
---|
[9805] | 229 | switch (typeFlag)
|
---|
[4121] | 230 | {
|
---|
[9805] | 231 | case SHCNF_PATHA:
|
---|
| 232 | if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy);
|
---|
| 233 | if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy);
|
---|
| 234 | break;
|
---|
| 235 | case SHCNF_PATHW:
|
---|
| 236 | if (dwItem1) SHILCreateFromPathW((LPCWSTR)dwItem1, &Pidls[0], &dummy);
|
---|
| 237 | if (dwItem2) SHILCreateFromPathW((LPCWSTR)dwItem2, &Pidls[1], &dummy);
|
---|
| 238 | break;
|
---|
| 239 | case SHCNF_PRINTERA:
|
---|
| 240 | case SHCNF_PRINTERW:
|
---|
| 241 | FIXME("SHChangeNotify with (uFlags & SHCNF_PRINTER)");
|
---|
| 242 | break;
|
---|
[4121] | 243 | }
|
---|
[9805] | 244 |
|
---|
[4121] | 245 | EnterCriticalSection(&SHELL32_ChangenotifyCS);
|
---|
[9805] | 246 |
|
---|
[4121] | 247 | /* loop through the list */
|
---|
| 248 | ptr = head.next;
|
---|
[9805] | 249 | while (ptr != &tail)
|
---|
[4121] | 250 | {
|
---|
| 251 | TRACE("trying %p\n", ptr);
|
---|
[9805] | 252 |
|
---|
| 253 | if (wEventId & ptr->wEventMask)
|
---|
[4121] | 254 | {
|
---|
| 255 | TRACE("notifying\n");
|
---|
| 256 | SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)&Pidls, (LPARAM)wEventId);
|
---|
| 257 | }
|
---|
| 258 | ptr = ptr->next;
|
---|
| 259 | }
|
---|
[9805] | 260 |
|
---|
[4121] | 261 | LeaveCriticalSection(&SHELL32_ChangenotifyCS);
|
---|
| 262 |
|
---|
| 263 | /* if we allocated it, free it */
|
---|
[9805] | 264 | if ((typeFlag == SHCNF_PATHA) || (typeFlag == SHCNF_PATHW))
|
---|
[4121] | 265 | {
|
---|
[9805] | 266 | if (Pidls[0]) SHFree(Pidls[0]);
|
---|
| 267 | if (Pidls[1]) SHFree(Pidls[1]);
|
---|
[4121] | 268 | }
|
---|
| 269 | }
|
---|
| 270 |
|
---|
| 271 | /*************************************************************************
|
---|
| 272 | * NTSHChangeNotifyRegister [SHELL32.640]
|
---|
| 273 | * NOTES
|
---|
| 274 | * Idlist is an array of structures and Count specifies how many items in the array
|
---|
| 275 | * (usually just one I think).
|
---|
| 276 | */
|
---|
| 277 | DWORD WINAPI NTSHChangeNotifyRegister(
|
---|
| 278 | HWND hwnd,
|
---|
| 279 | LONG events1,
|
---|
| 280 | LONG events2,
|
---|
| 281 | DWORD msg,
|
---|
| 282 | int count,
|
---|
| 283 | LPNOTIFYREGISTER idlist)
|
---|
| 284 | {
|
---|
[9805] | 285 | FIXME("(%p,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n",
|
---|
[4121] | 286 | hwnd,events1,events2,msg,count,idlist);
|
---|
| 287 | return 0;
|
---|
| 288 | }
|
---|
| 289 |
|
---|
| 290 | /*************************************************************************
|
---|
| 291 | * SHChangeNotification_Lock [SHELL32.644]
|
---|
| 292 | */
|
---|
| 293 | HANDLE WINAPI SHChangeNotification_Lock(
|
---|
| 294 | HANDLE hMemoryMap,
|
---|
| 295 | DWORD dwProcessId,
|
---|
| 296 | LPCITEMIDLIST **lppidls,
|
---|
| 297 | LPLONG lpwEventId)
|
---|
| 298 | {
|
---|
| 299 | FIXME("\n");
|
---|
| 300 | return 0;
|
---|
| 301 | }
|
---|
| 302 |
|
---|
| 303 | /*************************************************************************
|
---|
| 304 | * SHChangeNotification_Unlock [SHELL32.645]
|
---|
| 305 | */
|
---|
| 306 | BOOL WINAPI SHChangeNotification_Unlock (
|
---|
| 307 | HANDLE hLock)
|
---|
| 308 | {
|
---|
| 309 | FIXME("\n");
|
---|
| 310 | return 0;
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 | /*************************************************************************
|
---|
| 314 | * NTSHChangeNotifyDeregister [SHELL32.641]
|
---|
| 315 | */
|
---|
| 316 | DWORD WINAPI NTSHChangeNotifyDeregister(LONG x1)
|
---|
| 317 | {
|
---|
| 318 | FIXME("(0x%08lx):stub.\n",x1);
|
---|
| 319 | return 0;
|
---|
| 320 | }
|
---|
| 321 |
|
---|