[PATCH 2/5] shell32: Factor shell notification code into separate function.
Nigel Baillie
metreckk at gmail.com
Tue Feb 26 18:19:23 CST 2019
Additionally, SendMessageTimeoutA is used instead of SendMessageA
because notify_recipient will be called from another thread and may need
to be canceled when the window is being destroyed.
Signed-off-by: Nigel Baillie <metreckk at gmaill.com>
---
dlls/shell32/changenotify.c | 106 +++++++++++++++++++++---------------
1 file changed, 62 insertions(+), 44 deletions(-)
diff --git a/dlls/shell32/changenotify.c b/dlls/shell32/changenotify.c
index 2efb297ad5..7656f43fee 100644
--- a/dlls/shell32/changenotify.c
+++ b/dlls/shell32/changenotify.c
@@ -56,6 +56,15 @@ typedef struct _NOTIFICATIONLIST
static struct list notifications = LIST_INIT( notifications );
static LONG next_id;
+struct new_delivery_notification
+{
+ LONG event;
+ DWORD pidl1_size;
+ DWORD pidl2_size;
+ LPITEMIDLIST pidls[2];
+ BYTE data[1];
+};
+
#define SHCNE_NOITEMEVENTS ( \
SHCNE_ASSOCCHANGED )
@@ -150,6 +159,58 @@ void FreeChangeNotifications(void)
DeleteCriticalSection(&SHELL32_ChangenotifyCS);
}
+static BOOL notify_recipient(
+ HWND hwnd, DWORD msg, DWORD flags, LONG event_id,
+ LPITEMIDLIST pidls[2], HANDLE *shared_data)
+{
+ LRESULT sendmsg_result = 0;
+ TRACE("notifying %p, event %s(%x)\n", hwnd, DumpEvent(event_id), event_id);
+
+ if (flags & SHCNRF_NewDelivery) {
+ if(!(*shared_data)) {
+ struct new_delivery_notification *notification;
+ UINT size1 = ILGetSize(pidls[0]), size2 = ILGetSize(pidls[1]);
+ UINT offset = (size1+sizeof(int)-1)/sizeof(int)*sizeof(int);
+
+ notification = SHAlloc(sizeof(struct new_delivery_notification)+offset+size2);
+ if(!notification) {
+ ERR("out of memory\n");
+ } else {
+ notification->event = event_id;
+ notification->pidl1_size = size1;
+ notification->pidl2_size = size2;
+ if(size1)
+ memcpy(notification->data, pidls[0], size1);
+ if(size2)
+ memcpy(notification->data+offset, pidls[1], size2);
+
+ *shared_data = SHAllocShared(notification,
+ sizeof(struct new_delivery_notification)+size1+size2,
+ GetCurrentProcessId());
+ SHFree(notification);
+ }
+ }
+
+ if(*shared_data) {
+ sendmsg_result = SendMessageTimeoutA(
+ hwnd, msg, (WPARAM)*shared_data, GetCurrentProcessId(),
+ SMTO_NOTIMEOUTIFNOTHUNG | SMTO_ERRORONEXIT,
+ 10000, NULL
+ );
+ }
+ else
+ ERR("out of memory\n");
+ } else {
+ sendmsg_result = SendMessageTimeoutA(
+ hwnd, msg, (WPARAM)pidls, event_id,
+ SMTO_NOTIMEOUTIFNOTHUNG | SMTO_ERRORONEXIT,
+ 10000, NULL
+ );
+ }
+
+ return sendmsg_result != 0;
+}
+
/*************************************************************************
* SHChangeNotifyRegister [SHELL32.2]
*
@@ -231,15 +292,6 @@ BOOL WINAPI SHChangeNotifyUpdateEntryList(DWORD unknown1, DWORD unknown2,
return TRUE;
}
-struct new_delivery_notification
-{
- LONG event;
- DWORD pidl1_size;
- DWORD pidl2_size;
- LPITEMIDLIST pidls[2];
- BYTE data[1];
-};
-
static BOOL should_notify( LPCITEMIDLIST changed, LPCITEMIDLIST watched, BOOL sub )
{
TRACE("%p %p %d\n", changed, watched, sub );
@@ -371,41 +423,7 @@ void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID
LIST_FOR_EACH_ENTRY_SAFE(cur, next, &recipients, struct notification_recipients, entry)
{
- TRACE("notifying %p, event %s(%x)\n", cur->hwnd, DumpEvent(wEventId), wEventId);
-
- if (cur->flags & SHCNRF_NewDelivery) {
- if(!shared_data) {
- struct new_delivery_notification *notification;
- UINT size1 = ILGetSize(Pidls[0]), size2 = ILGetSize(Pidls[1]);
- UINT offset = (size1+sizeof(int)-1)/sizeof(int)*sizeof(int);
-
- notification = SHAlloc(sizeof(struct new_delivery_notification)+offset+size2);
- if(!notification) {
- ERR("out of memory\n");
- } else {
- notification->event = wEventId;
- notification->pidl1_size = size1;
- notification->pidl2_size = size2;
- if(size1)
- memcpy(notification->data, Pidls[0], size1);
- if(size2)
- memcpy(notification->data+offset, Pidls[1], size2);
-
- shared_data = SHAllocShared(notification,
- sizeof(struct new_delivery_notification)+size1+size2,
- GetCurrentProcessId());
- SHFree(notification);
- }
- }
-
- if(shared_data)
- SendMessageA(cur->hwnd, cur->msg, (WPARAM)shared_data, GetCurrentProcessId());
- else
- ERR("out of memory\n");
- } else {
- SendMessageA(cur->hwnd, cur->msg, (WPARAM)Pidls, wEventId);
- }
-
+ notify_recipient(cur->hwnd, cur->msg, cur->flags, wEventId, Pidls, &shared_data);
list_remove(&cur->entry);
SHFree(cur);
}
--
2.20.1
More information about the wine-devel
mailing list