ReactOS 0.4.15-dev-8061-g57b775e
shell32_apitest_sub.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Test for SHChangeNotify
5 * COPYRIGHT: Copyright 2020-2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6 */
7
8// This program is used in SHChangeNotify and ShellExecCmdLine testcases.
9
10#include "shelltest.h"
11#include "shell32_apitest_sub.h"
12#include <assert.h>
13
14typedef enum DIRTYPE
15{
23
26static UINT s_uRegID = 0;
27static INT s_iStage = -1;
28
29#define EVENTS (SHCNE_CREATE | SHCNE_DELETE | SHCNE_MKDIR | SHCNE_RMDIR | \
30 SHCNE_RENAMEFOLDER | SHCNE_RENAMEITEM | SHCNE_UPDATEDIR | SHCNE_UPDATEITEM)
31
33{
35
36 switch (iDir)
37 {
38 case DIRTYPE_DESKTOP:
39 {
41 break;
42 }
44 {
45 WCHAR szPath1[MAX_PATH];
47 ret = ILCreateFromPathW(szPath1);
48 break;
49 }
50 case DIRTYPE_DRIVES:
51 {
53 break;
54 }
56 {
58 break;
59 }
60 case DIRTYPE_DIR1:
61 {
62 WCHAR szPath1[MAX_PATH];
63 SHGetSpecialFolderPathW(NULL, szPath1, CSIDL_PERSONAL, FALSE); // My Documents
64 PathAppendW(szPath1, L"_TESTDIR_1_");
65 ret = ILCreateFromPathW(szPath1);
66 break;
67 }
68 default:
69 {
70 assert(0);
71 break;
72 }
73 }
74
75 return ret;
76}
77
79{
81
82 for (INT i = 0; i < DIRTYPE_MAX; ++i)
83 s_pidl[i] = DoGetPidl(i);
84
85 return TRUE;
86}
87
89{
90 assert(0 <= s_iStage);
92
96 switch (s_iStage)
97 {
98 case 0:
99 {
100 entry.fRecursive = FALSE;
101 entry.pidl = NULL;
103 events = EVENTS;
104 break;
105 }
106 case 1:
107 {
108 entry.fRecursive = TRUE;
109 entry.pidl = NULL;
111 events = EVENTS;
112 break;
113 }
114 case 2:
115 {
116 entry.fRecursive = FALSE;
119 events = EVENTS;
120 break;
121 }
122 case 3:
123 {
124 entry.fRecursive = TRUE;
127 events = EVENTS;
128 break;
129 }
130 case 4:
131 {
132 entry.fRecursive = TRUE;
135 events = EVENTS;
136 break;
137 }
138 case 5:
139 {
140 entry.fRecursive = FALSE;
143 events = EVENTS;
144 break;
145 }
146 case 6:
147 {
148 entry.fRecursive = TRUE;
151 events = EVENTS;
152 break;
153 }
154 case 7:
155 {
156 entry.fRecursive = TRUE;
159 events = EVENTS;
160 break;
161 }
162 case 8:
163 {
164 entry.fRecursive = FALSE;
165 entry.pidl = s_pidl[DIRTYPE_DIR1];
167 events = EVENTS;
168 break;
169 }
170 case 9:
171 {
172 entry.fRecursive = TRUE;
173 entry.pidl = s_pidl[DIRTYPE_DIR1];
176 events = EVENTS;
177 break;
178 }
179 default:
180 {
181 assert(0);
182 break;
183 }
184 }
185
187 if (s_uRegID == 0)
188 return FALSE;
189
190 return TRUE;
191}
192
193static void UnInitSHCN(HWND hwnd)
194{
195 if (s_uRegID)
196 {
198 s_uRegID = 0;
199 }
200}
201
202static void OnCommand(HWND hwnd, UINT id)
203{
204 switch (id)
205 {
206 case IDYES: // Start testing
207 {
209 if (!s_hMainWnd)
210 {
212 break;
213 }
214 s_iStage = 0;
215 InitSHCN(hwnd);
217 break;
218 }
219 case IDRETRY: // New stage
220 {
222 ++s_iStage;
223 InitSHCN(hwnd);
225 break;
226 }
227 case IDNO: // Quit
228 {
229 s_iStage = -1;
232 break;
233 }
234 }
235}
236
237static void OnDestroy(HWND hwnd)
238{
240
241 for (auto& pidl : s_pidl)
242 {
243 CoTaskMemFree(pidl);
244 pidl = NULL;
245 }
246
248
250}
251
253{
254 DWORD cbPidl1 = ILGetSize(pidl1), cbPidl2 = ILGetSize(pidl2);
255 DWORD cbTotal = sizeof(lEvent) + sizeof(cbPidl1) + sizeof(cbPidl2) + cbPidl1 + cbPidl2;
256 LPBYTE pbData = (LPBYTE)::LocalAlloc(LPTR, cbTotal);
257 if (!pbData)
258 return FALSE;
259
260 LPBYTE pb = pbData;
261
262 *(LONG*)pb = lEvent;
263 pb += sizeof(lEvent);
264
265 *(DWORD*)pb = cbPidl1;
266 pb += sizeof(cbPidl1);
267
268 *(DWORD*)pb = cbPidl2;
269 pb += sizeof(cbPidl2);
270
271 CopyMemory(pb, pidl1, cbPidl1);
272 pb += cbPidl1;
273
274 CopyMemory(pb, pidl2, cbPidl2);
275 pb += cbPidl2;
276
277 assert(INT(pb - pbData) == INT(cbTotal));
278
279 COPYDATASTRUCT CopyData;
280 CopyData.dwData = 0xBEEFCAFE;
281 CopyData.cbData = cbTotal;
282 CopyData.lpData = pbData;
284
286 return ret;
287}
288
290{
291 if (s_iStage < 0)
292 return;
293
294 DoSendData(lEvent, pidl1, pidl2);
295}
296
298{
299 LONG lEvent;
300 PIDLIST_ABSOLUTE *pidlAbsolute;
301 HANDLE hLock = SHChangeNotification_Lock((HANDLE)wParam, (DWORD)lParam, &pidlAbsolute, &lEvent);
302 if (hLock)
303 {
304 DoShellNotify(hwnd, pidlAbsolute[0], pidlAbsolute[1], lEvent);
306 }
307 else
308 {
309 pidlAbsolute = (PIDLIST_ABSOLUTE *)wParam;
310 DoShellNotify(hwnd, pidlAbsolute[0], pidlAbsolute[1], lParam);
311 }
312 return TRUE;
313}
314
316{
317 switch (uMsg)
318 {
319 case WM_CREATE:
320 return (OnCreate(hwnd) ? 0 : -1);
321
322 case WM_COMMAND:
324 break;
325
326 case WM_SHELL_NOTIFY:
328
329 case WM_DESTROY:
331 break;
332
333 default:
334 return ::DefWindowProcW(hwnd, uMsg, wParam, lParam);
335 }
336 return 0;
337}
338
342 HINSTANCE hPrevInstance,
343 LPWSTR lpCmdLine,
344 INT nCmdShow)
345{
346 if (lstrcmpiW(lpCmdLine, L"") == 0 || lstrcmpiW(lpCmdLine, L"TEST") == 0)
347 return 0;
348
349 WNDCLASSW wc = { 0, SubWindowProc };
350 wc.hInstance = hInstance;
353 wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
355 if (!RegisterClassW(&wc))
356 {
357 assert(0);
358 return -1;
359 }
360
362 CW_USEDEFAULT, CW_USEDEFAULT, 400, 100,
364 if (!hwnd)
365 {
366 assert(0);
367 return -2;
368 }
369
372
373 MSG msg;
374 while (GetMessageW(&msg, NULL, 0, 0))
375 {
378 }
379
380 return 0;
381}
#define msg(x)
Definition: auth_time.c:54
EXTERN_C HANDLE WINAPI SHChangeNotification_Lock(HANDLE hTicket, DWORD dwOwnerPID, LPITEMIDLIST **lppidls, LPLONG lpwEventId)
EXTERN_C ULONG WINAPI SHChangeNotifyRegister(HWND hwnd, INT fSources, LONG wEventMask, UINT uMsg, INT cItems, SHChangeNotifyEntry *lpItems)
EXTERN_C BOOL WINAPI SHChangeNotification_Unlock(HANDLE hLock)
EXTERN_C BOOL WINAPI SHChangeNotifyDeregister(ULONG hNotify)
HINSTANCE hInstance
Definition: charmap.c:19
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define APIENTRY
Definition: api.h:79
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4261
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3225
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3092
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum * sources
Definition: glext.h:7753
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
uint32_t entry
Definition: isohybrid.c:63
HANDLE events[2]
Definition: event.c:4
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define L(x)
Definition: ntvdm.h:50
#define PathAppendW
Definition: pathcch.h:309
#define LOWORD(l)
Definition: pedump.c:82
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
long LONG
Definition: pedump.c:60
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:995
#define INT
Definition: polytest.cpp:20
LPITEMIDLIST DoGetPidl(INT iDir)
static void UnInitSHCN(HWND hwnd)
static LRESULT CALLBACK SubWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static BOOL OnCreate(HWND hwnd)
static void OnCommand(HWND hwnd, UINT id)
static void OnDestroy(HWND hwnd)
static BOOL InitSHCN(HWND hwnd)
static HWND s_hSubWnd
static HWND s_hMainWnd
static void DoShellNotify(HWND hwnd, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2, LONG lEvent)
static UINT s_uRegID
@ DIRTYPE_PRINTERS
@ DIRTYPE_DESKTOP
@ DIRTYPE_DRIVES
@ DIRTYPE_MAX
@ DIRTYPE_DESKTOP_DIR
@ DIRTYPE_DIR1
static LPITEMIDLIST s_pidl[DIRTYPE_MAX]
static BOOL DoSendData(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
#define EVENTS
static INT s_iStage
INT APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nCmdShow)
static INT_PTR OnShellNotify(HWND hwnd, WPARAM wParam, LPARAM lParam)
#define WM_SHELL_NOTIFY
#define SUB_CLASSNAME
#define NUM_STAGE
#define MAIN_CLASSNAME
#define ILGetSize
Definition: shellclasses.h:638
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2173
#define SHCNRF_RecursiveInterrupt
Definition: shlobj.h:1922
#define CSIDL_PERSONAL
Definition: shlobj.h:2163
#define SHCNRF_NewDelivery
Definition: shlobj.h:1923
#define CSIDL_PRINTERS
Definition: shlobj.h:2162
#define SHCNRF_ShellLevel
Definition: shlobj.h:1921
#define CSIDL_DESKTOP
Definition: shlobj.h:2158
#define SHCNRF_InterruptLevel
Definition: shlobj.h:1920
#define CSIDL_DRIVES
Definition: shlobj.h:2174
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
LPCWSTR lpszClassName
Definition: winuser.h:3185
HBRUSH hbrBackground
Definition: winuser.h:3183
HICON hIcon
Definition: winuser.h:3181
HINSTANCE hInstance
Definition: winuser.h:3180
HCURSOR hCursor
Definition: winuser.h:3182
ULONG_PTR dwData
Definition: winuser.h:3001
HANDLE lEvent
Definition: tftpd.cpp:56
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
int ret
#define LPTR
Definition: winbase.h:381
#define CopyMemory
Definition: winbase.h:1710
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_updates_bytes_to_ pdwDataLen BYTE * pbData
Definition: wincrypt.h:4201
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define SW_SHOWNORMAL
Definition: winuser.h:770
BOOL WINAPI TranslateMessage(_In_ const MSG *)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define FindWindow
Definition: winuser.h:5777
#define WM_CREATE
Definition: winuser.h:1608
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define WM_COMMAND
Definition: winuser.h:1740
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define IDC_ARROW
Definition: winuser.h:687
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2136
#define IDI_APPLICATION
Definition: winuser.h:704
#define IDNO
Definition: winuser.h:836
BOOL WINAPI UpdateWindow(_In_ HWND)
#define WM_COPYDATA
Definition: winuser.h:1664
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4316
#define CW_USEDEFAULT
Definition: winuser.h:225
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define WM_DESTROY
Definition: winuser.h:1609
#define IDYES
Definition: winuser.h:835
#define IDRETRY
Definition: winuser.h:833
BOOL WINAPI DestroyWindow(_In_ HWND)
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2106
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define COLOR_3DFACE
Definition: winuser.h:929
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184