1 /* 2 * PROJECT: shell32 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Shell change notification 5 * COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 6 */ 7 #pragma once 8 9 ///////////////////////////////////////////////////////////////////////////// 10 // CChangeNotifyServer is a delivery worker window that is managed by CDesktopBrowser. 11 // The process of CChangeNotifyServer is same as the process of CDesktopBrowser. 12 // The caller process of SHChangeNotify function might be different from the 13 // process of CChangeNotifyServer. 14 ///////////////////////////////////////////////////////////////////////////// 15 16 ///////////////////////////////////////////////////////////////////////////// 17 // The shared memory block can be allocated by shlwapi!SHAllocShared function. 18 // 19 // HANDLE SHAllocShared(LPCVOID lpData, DWORD dwSize, DWORD dwProcessId); 20 // LPVOID SHLockShared(HANDLE hData, DWORD dwProcessId); 21 // LPVOID SHLockSharedEx(HANDLE hData, DWORD dwProcessId, BOOL bWriteAccess); 22 // BOOL SHUnlockShared(LPVOID lpData); 23 // BOOL SHFreeShared(HANDLE hData, DWORD dwProcessId); 24 // 25 // The shared memory block is managed by the pair of a HANDLE value and an owner PID. 26 // If the pair is known, it can be accessed by SHLockShared(Ex) function 27 // from another process. 28 ///////////////////////////////////////////////////////////////////////////// 29 30 #define INVALID_REG_ID 0 /* invalid registration ID */ 31 32 // This message is handled by CDesktopBrowser and returns 33 // the window of CChangeNotifyServer which responds to the CN_* messages 34 #define WM_DESKTOP_GET_CNOTIFY_SERVER (WM_USER + 25) /* 0x419 */ 35 36 // The following messages are implemented by CChangeNotifyServer 37 // CChangeNotifyServer lives in the context of explorer and delivers notifications 38 // across all processes that register themselves with the SHChangeNotifyRegister api 39 #define CN_REGISTER (WM_USER + 1) /* 0x401 */ 40 #define CN_UNREGISTER (WM_USER + 2) /* 0x402 */ 41 #define CN_DELIVER_NOTIFICATION (WM_USER + 3) /* 0x403 */ 42 #define CN_SUSPEND_RESUME (WM_USER + 6) /* 0x406 */ 43 #define CN_UNREGISTER_PROCESS (WM_USER + 7) /* 0x407 */ 44 45 // This message is implemented by the broker window which lives in the context of the client 46 #define WM_BROKER_NOTIFICATION (WM_USER + 1) /* 0x401 */ 47 48 #define DWORD_ALIGNMENT(offset) \ 49 ((((offset) + sizeof(DWORD) - 1) / sizeof(DWORD)) * sizeof(DWORD)) 50 51 /* delivery ticket */ 52 typedef struct DELITICKET 53 { 54 DWORD dwMagic; /* same as DELITICKET_MAGIC */ 55 LONG wEventId; /* event id of SHChangeNotify() */ 56 UINT uFlags; /* flags of SHChangeNotify() */ 57 DWORD dwTick; /* value of GetTickCount() */ 58 DWORD ibOffset1; /* offset to pidl1 */ 59 DWORD ibOffset2; /* offset to pidl2 */ 60 /* followed by pidl1 and pidl2 */ 61 } DELITICKET, *LPDELITICKET; 62 63 /* registration entry */ 64 typedef struct REGENTRY 65 { 66 DWORD dwMagic; /* same as REGENTRY_MAGIC */ 67 DWORD cbSize; /* the real size of this structure */ 68 UINT nRegID; /* the registration ID */ 69 HWND hwnd; /* the target window */ 70 UINT uMsg; /* the message ID used in notification */ 71 INT fSources; /* the source flags */ 72 LONG fEvents; /* the event flags */ 73 BOOL fRecursive; /* is it recursive? */ 74 HWND hwndBroker; /* broker window (if any) */ 75 UINT ibPidl; /* offset to the PIDL */ 76 /* followed by a PIDL */ 77 } REGENTRY, *LPREGENTRY; 78 79 /* handbag */ 80 typedef struct HANDBAG 81 { 82 DWORD dwMagic; /* same as HANDBAG_MAGIC */ 83 LPITEMIDLIST pidls[2]; /* two PIDLs */ 84 LPDELITICKET pTicket; /* the ticket */ 85 } HANDBAG, *LPHANDBAG; 86 87 #define DELITICKET_MAGIC 0xDEADFACE 88 #define REGENTRY_MAGIC 0xB0B32D1E 89 #define HANDBAG_MAGIC 0xFACEB00C 90 91 HRESULT CChangeNotifyServer_CreateInstance(REFIID riid, void **ppv); 92