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