Module: wine Branch: master Commit: 8bfc89ee7cd2ae8a432ce6aa58b956e24aa6f6e7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8bfc89ee7cd2ae8a432ce6aa58...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Apr 9 14:42:29 2010 +0200
shell32: Store an id in change notifications to avoid invalid pointer conversions.
---
dlls/shell32/changenotify.c | 56 +++++++++++++++++++++--------------------- 1 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/dlls/shell32/changenotify.c b/dlls/shell32/changenotify.c index 3e79b2e..95f2e42 100644 --- a/dlls/shell32/changenotify.c +++ b/dlls/shell32/changenotify.c @@ -54,10 +54,11 @@ typedef struct _NOTIFICATIONLIST LONG wSignalledEvent; /* event that occurred */ DWORD dwFlags; /* client flags */ LPCITEMIDLIST pidlSignaled; /*pidl of the path that caused the signal*/ - + ULONG id; } NOTIFICATIONLIST, *LPNOTIFICATIONLIST;
static struct list notifications = LIST_INIT( notifications ); +static LONG next_id;
#define SHCNE_NOITEMEVENTS ( \ SHCNE_ASSOCCHANGED ) @@ -117,15 +118,6 @@ static const char * NodeName(const NOTIFICATIONLIST *item) return str; }
-static LPNOTIFICATIONLIST FindNode( HANDLE hitem ) -{ - LPNOTIFICATIONLIST ptr; - LIST_FOR_EACH_ENTRY( ptr, ¬ifications, NOTIFICATIONLIST, entry ) - if( ptr == hitem ) - return ptr; - return NULL; -} - static void DeleteNode(LPNOTIFICATIONLIST item) { UINT i; @@ -195,6 +187,7 @@ SHChangeNotifyRegister( item->wEventMask = wEventMask; item->wSignalledEvent = 0; item->dwFlags = fSources; + item->id = InterlockedIncrement( &next_id );
TRACE("new node: %s\n", NodeName( item ));
@@ -204,7 +197,7 @@ SHChangeNotifyRegister(
LeaveCriticalSection(&SHELL32_ChangenotifyCS);
- return (ULONG)item; + return item->id; }
/************************************************************************* @@ -218,13 +211,17 @@ BOOL WINAPI SHChangeNotifyDeregister(ULONG hNotify)
EnterCriticalSection(&SHELL32_ChangenotifyCS);
- node = FindNode((HANDLE)hNotify); - if( node ) - DeleteNode(node); - + LIST_FOR_EACH_ENTRY( node, ¬ifications, NOTIFICATIONLIST, entry ) + { + if (node->id == hNotify) + { + DeleteNode( node ); + LeaveCriticalSection(&SHELL32_ChangenotifyCS); + return TRUE; + } + } LeaveCriticalSection(&SHELL32_ChangenotifyCS); - - return node?TRUE:FALSE; + return FALSE; }
/************************************************************************* @@ -429,22 +426,25 @@ HANDLE WINAPI SHChangeNotification_Lock(
/* EnterCriticalSection(&SHELL32_ChangenotifyCS); */
- node = FindNode( hChange ); - if( node ) + LIST_FOR_EACH_ENTRY( node, ¬ifications, NOTIFICATIONLIST, entry ) { - idlist = SHAlloc( sizeof(LPCITEMIDLIST *) * node->cidl ); - for(i=0; i<node->cidl; i++) - idlist[i] = node->pidlSignaled; - *lpwEventId = node->wSignalledEvent; - *lppidls = (LPITEMIDLIST*)idlist; - node->wSignalledEvent = 0; + if (node == hChange) + { + idlist = SHAlloc( sizeof(LPCITEMIDLIST *) * node->cidl ); + for(i=0; i<node->cidl; i++) + idlist[i] = node->pidlSignaled; + *lpwEventId = node->wSignalledEvent; + *lppidls = (LPITEMIDLIST*)idlist; + node->wSignalledEvent = 0; + /* LeaveCriticalSection(&SHELL32_ChangenotifyCS); */ + return node; + } } - else - ERR("Couldn't find %p\n", hChange ); + ERR("Couldn't find %p\n", hChange );
/* LeaveCriticalSection(&SHELL32_ChangenotifyCS); */
- return node; + return 0; }
/*************************************************************************