ReactOS 0.4.16-dev-1493-ge7358c5
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
94 INT sources = 0;
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 }
180 }
181
183 if (s_uRegID == 0)
184 return FALSE;
185
186 return TRUE;
187}
188
189static void UnInitSHCN(HWND hwnd)
190{
191 if (s_uRegID)
192 {
194 s_uRegID = 0;
195 }
196}
197
198static void OnCommand(HWND hwnd, UINT id)
199{
200 switch (id)
201 {
202 case IDYES: // Start testing
203 {
205 if (!s_hMainWnd)
206 {
208 break;
209 }
210 s_iStage = 0;
211 InitSHCN(hwnd);
213 break;
214 }
215 case IDRETRY: // New stage
216 {
218 ++s_iStage;
219 InitSHCN(hwnd);
221 break;
222 }
223 case IDNO: // Quit
224 {
225 s_iStage = -1;
228 break;
229 }
230 }
231}
232
233static void OnDestroy(HWND hwnd)
234{
236
237 for (auto& pidl : s_pidl)
238 {
239 CoTaskMemFree(pidl);
240 pidl = NULL;
241 }
242
244
246}
247
249{
250 DWORD cbPidl1 = ILGetSize(pidl1), cbPidl2 = ILGetSize(pidl2);
251 DWORD cbTotal = sizeof(lEvent) + sizeof(cbPidl1) + sizeof(cbPidl2) + cbPidl1 + cbPidl2;
252 LPBYTE pbData = (LPBYTE)::LocalAlloc(LPTR, cbTotal);
253 if (!pbData)
254 return FALSE;
255
256 LPBYTE pb = pbData;
257
258 *(LONG*)pb = lEvent;
259 pb += sizeof(lEvent);
260
261 *(DWORD*)pb = cbPidl1;
262 pb += sizeof(cbPidl1);
263
264 *(DWORD*)pb = cbPidl2;
265 pb += sizeof(cbPidl2);
266
267 CopyMemory(pb, pidl1, cbPidl1);
268 pb += cbPidl1;
269
270 CopyMemory(pb, pidl2, cbPidl2);
271 pb += cbPidl2;
272
273 assert(INT(pb - pbData) == INT(cbTotal));
274
275 COPYDATASTRUCT CopyData;
276 CopyData.dwData = 0xBEEFCAFE;
277 CopyData.cbData = cbTotal;
278 CopyData.lpData = pbData;
280
281 ::LocalFree(pbData);
282 return ret;
283}
284
286{
287 if (s_iStage < 0)
288 return;
289
290 DoSendData(lEvent, pidl1, pidl2);
291}
292
294{
295 LONG lEvent;
296 PIDLIST_ABSOLUTE *pidlAbsolute;
297 HANDLE hLock = SHChangeNotification_Lock((HANDLE)wParam, (DWORD)lParam, &pidlAbsolute, &lEvent);
298 if (hLock)
299 {
300 DoShellNotify(hwnd, pidlAbsolute[0], pidlAbsolute[1], lEvent);
302 }
303 else
304 {
305 pidlAbsolute = (PIDLIST_ABSOLUTE *)wParam;
306 DoShellNotify(hwnd, pidlAbsolute[0], pidlAbsolute[1], lParam);
307 }
308 return TRUE;
309}
310
312{
313 switch (uMsg)
314 {
315 case WM_CREATE:
316 return (OnCreate(hwnd) ? 0 : -1);
317
318 case WM_COMMAND:
320 break;
321
322 case WM_SHELL_NOTIFY:
324
325 case WM_DESTROY:
327 break;
328
329 default:
330 return ::DefWindowProcW(hwnd, uMsg, wParam, lParam);
331 }
332 return 0;
333}
334
338 HINSTANCE hPrevInstance,
339 LPWSTR lpCmdLine,
340 INT nCmdShow)
341{
342 if (lstrcmpiW(lpCmdLine, L"") == 0 || lstrcmpiW(lpCmdLine, L"TEST") == 0)
343 return 0;
344
345 WNDCLASSW wc = { 0, SubWindowProc };
346 wc.hInstance = hInstance;
349 wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
351 if (!RegisterClassW(&wc))
352 {
353 assert(0);
354 return -1;
355 }
356
358 CW_USEDEFAULT, CW_USEDEFAULT, 400, 100,
360 if (!hwnd)
361 {
362 assert(0);
363 return -2;
364 }
365
368
369 MSG msg;
370 while (GetMessageW(&msg, NULL, 0, 0))
371 {
374 }
375
376 return 0;
377}
#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:4265
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3384
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3219
#define assert(x)
Definition: debug.h:53
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
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 DEFAULT_UNREACHABLE
#define PathAppendW
Definition: pathcch.h:310
#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:1102
#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:2194
#define SHCNRF_RecursiveInterrupt
Definition: shlobj.h:1943
#define CSIDL_PERSONAL
Definition: shlobj.h:2184
#define SHCNRF_NewDelivery
Definition: shlobj.h:1944
#define CSIDL_PRINTERS
Definition: shlobj.h:2183
#define SHCNRF_ShellLevel
Definition: shlobj.h:1942
#define CSIDL_DESKTOP
Definition: shlobj.h:2179
#define SHCNRF_InterruptLevel
Definition: shlobj.h:1941
#define CSIDL_DRIVES
Definition: shlobj.h:2195
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
LPCWSTR lpszClassName
Definition: winuser.h:3287
HBRUSH hbrBackground
Definition: winuser.h:3285
HICON hIcon
Definition: winuser.h:3283
HINSTANCE hInstance
Definition: winuser.h:3282
HCURSOR hCursor
Definition: winuser.h:3284
ULONG_PTR dwData
Definition: winuser.h:3103
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
#define LPTR
Definition: winbase.h:414
#define CopyMemory
Definition: winbase.h:1751
_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:781
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:5888
#define WM_CREATE
Definition: winuser.h:1636
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define WM_COMMAND
Definition: winuser.h:1768
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define IDC_ARROW
Definition: winuser.h:695
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2457
#define IDI_APPLICATION
Definition: winuser.h:712
#define IDNO
Definition: winuser.h:847
BOOL WINAPI UpdateWindow(_In_ HWND)
#define WM_COPYDATA
Definition: winuser.h:1692
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4418
#define CW_USEDEFAULT
Definition: winuser.h:225
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define WM_DESTROY
Definition: winuser.h:1637
#define IDYES
Definition: winuser.h:846
#define IDRETRY
Definition: winuser.h:844
BOOL WINAPI DestroyWindow(_In_ HWND)
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2427
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define COLOR_3DFACE
Definition: winuser.h:940
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184