diff --git a/dlls/shell32/changenotify.c b/dlls/shell32/changenotify.c index 43c81c334bc..96a20e21f09 100644 --- a/dlls/shell32/changenotify.c +++ b/dlls/shell32/changenotify.c @@ -253,14 +253,24 @@ static BOOL should_notify( LPCITEMIDLIST changed, LPCITEMIDLIST watched, BOOL su */ void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2) { - LPCITEMIDLIST Pidls[2]; + struct notification_recipients { + struct list entry; + HWND hwnd; + DWORD msg; + DWORD flags; + } *cur, *next; + + LPITEMIDLIST Pidls[2]; LPNOTIFICATIONLIST ptr; - UINT typeFlag = uFlags & SHCNF_TYPE; + struct list recipients; Pidls[0] = NULL; Pidls[1] = NULL; - TRACE("(0x%08x,0x%08x,%p,%p):stub.\n", wEventId, uFlags, dwItem1, dwItem2); + TRACE("(0x%08x,0x%08x,%p,%p)\n", wEventId, uFlags, dwItem1, dwItem2); + + if(uFlags & ~(SHCNF_TYPE|SHCNF_FLUSH)) + FIXME("ignoring unsupported flags: %x\n", uFlags); if( ( wEventId & SHCNE_NOITEMEVENTS ) && ( dwItem1 || dwItem2 ) ) { @@ -288,7 +298,7 @@ void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID } /* convert paths in IDLists*/ - switch (typeFlag) + switch (uFlags & SHCNF_TYPE) { case SHCNF_PATHA: if (dwItem1) Pidls[0] = SHSimpleIDListFromPathA(dwItem1); @@ -299,8 +309,8 @@ void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID if (dwItem2) Pidls[1] = SHSimpleIDListFromPathW(dwItem2); break; case SHCNF_IDLIST: - Pidls[0] = dwItem1; - Pidls[1] = dwItem2; + Pidls[0] = ILClone(dwItem1); + Pidls[1] = ILClone(dwItem2); break; case SHCNF_PRINTERA: case SHCNF_PRINTERW: @@ -308,32 +318,18 @@ void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID return; case SHCNF_DWORD: default: - FIXME("unknown type %08x\n",typeFlag); + FIXME("unknown type %08x\n", uFlags & SHCNF_TYPE); return; } - { - WCHAR path[MAX_PATH]; - - if( Pidls[0] && SHGetPathFromIDListW(Pidls[0], path )) - TRACE("notify %08x on item1 = %s\n", wEventId, debugstr_w(path)); - - if( Pidls[1] && SHGetPathFromIDListW(Pidls[1], path )) - TRACE("notify %08x on item2 = %s\n", wEventId, debugstr_w(path)); - } - + list_init(&recipients); EnterCriticalSection(&SHELL32_ChangenotifyCS); - - /* loop through the list */ LIST_FOR_EACH_ENTRY( ptr, ¬ifications, NOTIFICATIONLIST, entry ) { - BOOL notify; + struct notification_recipients *item; + BOOL notify = FALSE; DWORD i; - notify = FALSE; - - TRACE("trying %p\n", ptr); - for( i=0; (icidl) && !notify ; i++ ) { LPCITEMIDLIST pidl = ptr->apidl[i].pidl; @@ -355,24 +351,35 @@ void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID if( !notify ) continue; - ptr->pidlSignaled = ILClone(Pidls[0]); + item = SHAlloc(sizeof(struct notification_recipients)); + if(!item) { + ERR("out of memory\n"); + continue; + } - TRACE("notifying %s, event %s(%x) before\n", NodeName( ptr ), DumpEvent( - wEventId ),wEventId ); + item->hwnd = ptr->hwnd; + item->msg = ptr->uMsg; + item->flags = ptr->dwFlags; + list_add_tail(&recipients, &item->entry); + } + LeaveCriticalSection(&SHELL32_ChangenotifyCS); + + LIST_FOR_EACH_ENTRY_SAFE(cur, next, &recipients, struct notification_recipients, entry) + { + TRACE("notifying %p, event %s(%x)\n", cur->hwnd, DumpEvent(wEventId), wEventId); ptr->wSignalledEvent |= wEventId; - if (ptr->dwFlags & SHCNRF_NewDelivery) - SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM) ptr, GetCurrentProcessId()); + if (cur->flags & SHCNRF_NewDelivery) + FIXME("SHCNRF_NewDelivery flag is not supported\n"); else - SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)Pidls, wEventId); - - TRACE("notifying %s, event %s(%x) after\n", NodeName( ptr ), DumpEvent( - wEventId ),wEventId ); + SendMessageA(cur->hwnd, cur->msg, (WPARAM)Pidls, wEventId); + list_remove(&cur->entry); + SHFree(cur); } - TRACE("notify Done\n"); - LeaveCriticalSection(&SHELL32_ChangenotifyCS); + SHFree(Pidls[0]); + SHFree(Pidls[1]); if (wEventId & SHCNE_ASSOCCHANGED) { @@ -380,13 +387,6 @@ void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID TRACE("refreshing file type associations\n"); run_winemenubuilder( args ); } - - /* if we allocated it, free it. The ANSI flag is also set in its Unicode sibling. */ - if ((typeFlag & SHCNF_PATHA) || (typeFlag & SHCNF_PRINTERA)) - { - SHFree((LPITEMIDLIST)Pidls[0]); - SHFree((LPITEMIDLIST)Pidls[1]); - } } /*************************************************************************