shell32: Store an id in change notifications to avoid invalid pointer conversions.

This commit is contained in:
Alexandre Julliard 2010-04-09 14:42:29 +02:00
parent 7d19601012
commit 8bfc89ee7c
1 changed files with 28 additions and 28 deletions

View File

@ -54,10 +54,11 @@ typedef struct _NOTIFICATIONLIST
LONG wSignalledEvent; /* event that occurred */ LONG wSignalledEvent; /* event that occurred */
DWORD dwFlags; /* client flags */ DWORD dwFlags; /* client flags */
LPCITEMIDLIST pidlSignaled; /*pidl of the path that caused the signal*/ LPCITEMIDLIST pidlSignaled; /*pidl of the path that caused the signal*/
ULONG id;
} NOTIFICATIONLIST, *LPNOTIFICATIONLIST; } NOTIFICATIONLIST, *LPNOTIFICATIONLIST;
static struct list notifications = LIST_INIT( notifications ); static struct list notifications = LIST_INIT( notifications );
static LONG next_id;
#define SHCNE_NOITEMEVENTS ( \ #define SHCNE_NOITEMEVENTS ( \
SHCNE_ASSOCCHANGED ) SHCNE_ASSOCCHANGED )
@ -117,15 +118,6 @@ static const char * NodeName(const NOTIFICATIONLIST *item)
return str; return str;
} }
static LPNOTIFICATIONLIST FindNode( HANDLE hitem )
{
LPNOTIFICATIONLIST ptr;
LIST_FOR_EACH_ENTRY( ptr, &notifications, NOTIFICATIONLIST, entry )
if( ptr == hitem )
return ptr;
return NULL;
}
static void DeleteNode(LPNOTIFICATIONLIST item) static void DeleteNode(LPNOTIFICATIONLIST item)
{ {
UINT i; UINT i;
@ -195,6 +187,7 @@ SHChangeNotifyRegister(
item->wEventMask = wEventMask; item->wEventMask = wEventMask;
item->wSignalledEvent = 0; item->wSignalledEvent = 0;
item->dwFlags = fSources; item->dwFlags = fSources;
item->id = InterlockedIncrement( &next_id );
TRACE("new node: %s\n", NodeName( item )); TRACE("new node: %s\n", NodeName( item ));
@ -204,7 +197,7 @@ SHChangeNotifyRegister(
LeaveCriticalSection(&SHELL32_ChangenotifyCS); LeaveCriticalSection(&SHELL32_ChangenotifyCS);
return (ULONG)item; return item->id;
} }
/************************************************************************* /*************************************************************************
@ -218,13 +211,17 @@ BOOL WINAPI SHChangeNotifyDeregister(ULONG hNotify)
EnterCriticalSection(&SHELL32_ChangenotifyCS); EnterCriticalSection(&SHELL32_ChangenotifyCS);
node = FindNode((HANDLE)hNotify); LIST_FOR_EACH_ENTRY( node, &notifications, NOTIFICATIONLIST, entry )
if( node ) {
DeleteNode(node); if (node->id == hNotify)
{
DeleteNode( node );
LeaveCriticalSection(&SHELL32_ChangenotifyCS);
return TRUE;
}
}
LeaveCriticalSection(&SHELL32_ChangenotifyCS); LeaveCriticalSection(&SHELL32_ChangenotifyCS);
return FALSE;
return node?TRUE:FALSE;
} }
/************************************************************************* /*************************************************************************
@ -429,22 +426,25 @@ HANDLE WINAPI SHChangeNotification_Lock(
/* EnterCriticalSection(&SHELL32_ChangenotifyCS); */ /* EnterCriticalSection(&SHELL32_ChangenotifyCS); */
node = FindNode( hChange ); LIST_FOR_EACH_ENTRY( node, &notifications, NOTIFICATIONLIST, entry )
if( node )
{ {
idlist = SHAlloc( sizeof(LPCITEMIDLIST *) * node->cidl ); if (node == hChange)
for(i=0; i<node->cidl; i++) {
idlist[i] = node->pidlSignaled; idlist = SHAlloc( sizeof(LPCITEMIDLIST *) * node->cidl );
*lpwEventId = node->wSignalledEvent; for(i=0; i<node->cidl; i++)
*lppidls = (LPITEMIDLIST*)idlist; idlist[i] = node->pidlSignaled;
node->wSignalledEvent = 0; *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); */ /* LeaveCriticalSection(&SHELL32_ChangenotifyCS); */
return node; return 0;
} }
/************************************************************************* /*************************************************************************