Piotr Caban : shell32: Don't call SendMessage inside critical section.

Alexandre Julliard julliard at winehq.org
Wed Sep 21 13:35:14 CDT 2011


Module: wine
Branch: master
Commit: 155fb98306ecf76c2e54348bd0e76ee75b268d6a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=155fb98306ecf76c2e54348bd0e76ee75b268d6a

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Sep 21 09:52:28 2011 +0200

shell32: Don't call SendMessage inside critical section.

---

 dlls/shell32/changenotify.c |   84 +++++++++++++++++++++---------------------
 1 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/dlls/shell32/changenotify.c b/dlls/shell32/changenotify.c
index 43c81c3..96a20e2 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, &notifications, NOTIFICATIONLIST, entry )
     {
-        BOOL notify;
+        struct notification_recipients *item;
+        BOOL notify = FALSE;
         DWORD i;
 
-        notify = FALSE;
-
-        TRACE("trying %p\n", ptr);
-
         for( i=0; (i<ptr->cidl) && !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]);
-    }
 }
 
 /*************************************************************************




More information about the wine-cvs mailing list