ReactOS 0.4.16-dev-1489-g8fbbb41
SHChangeNotify.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// NOTE: This testcase requires shell32_apitest_sub.exe.
9
10#include "shelltest.h"
11#include "shell32_apitest_sub.h"
12#include <assert.h>
13
14#define NUM_STEP 8
15#define NUM_CHECKS 12
16#define INTERVAL 0
17#define MAX_EVENT_TYPE 6
18
20static WCHAR s_szSubProgram[MAX_PATH]; // shell32_apitest_sub.exe
22static INT s_iStage = -1, s_iStep = -1;
23static BYTE s_abChecks[NUM_CHECKS] = { 0 }; // Flags for testing
24static BOOL s_bGotUpdateDir = FALSE; // Got SHCNE_UPDATEDIR?
25
27{
32}
33
35{
37 ZeroMemory(szPath, sizeof(szPath));
38 StringCchCopyW(szPath, _countof(szPath), pszDir); // Double-NULL terminated
40 SHFileOperation(&FileOp);
41}
42
44{
45 switch (lEvent)
46 {
47 case SHCNE_CREATE: return 0;
48 case SHCNE_DELETE: return 1;
49 case SHCNE_RENAMEITEM: return 2;
50 case SHCNE_MKDIR: return 3;
51 case SHCNE_RMDIR: return 4;
52 case SHCNE_RENAMEFOLDER: return 5;
53 C_ASSERT(5 + 1 == MAX_EVENT_TYPE);
54 default: return -1;
55 }
56}
57
58#define FILE_1 L"_TESTFILE_1_.txt"
59#define FILE_2 L"_TESTFILE_2_.txt"
60#define DIR_1 L"_TESTDIR_1_"
61#define DIR_2 L"_TESTDIR_2_"
62
69
70static void DoDeleteFilesAndDirs(void)
71{
78}
79
80static void TEST_Quit(void)
81{
84
85 PostMessageW(s_hSubWnd, WM_COMMAND, IDNO, 0); // Finish
86 DoWaitForWindow(SUB_CLASSNAME, SUB_CLASSNAME, TRUE, TRUE); // Close sub-windows
87
89}
90
91static void DoBuildFilesAndDirs(void)
92{
93 WCHAR szPath1[MAX_PATH];
94 SHGetSpecialFolderPathW(NULL, szPath1, CSIDL_PERSONAL, FALSE); // My Documents
95 PathAppendW(szPath1, DIR_1);
97
98 PathAppendW(szPath1, DIR_1);
100 PathRemoveFileSpecW(szPath1);
101
102 PathAppendW(szPath1, DIR_2);
104 PathRemoveFileSpecW(szPath1);
105
106 PathAppendW(szPath1, DIR_1);
107 PathAppendW(szPath1, FILE_1);
109 PathRemoveFileSpecW(szPath1);
110 PathRemoveFileSpecW(szPath1);
111
112 PathAppendW(szPath1, FILE_1);
114 PathRemoveFileSpecW(szPath1);
115
116 PathAppendW(szPath1, FILE_2);
118 PathRemoveFileSpecW(szPath1);
119
120#define TRACE_PATH(path) trace(#path ": %ls\n", path)
126#undef TRACE_PATH
127
129
132
135}
136
138{
139 WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH];
140
141 szPath1[0] = szPath2[0] = 0;
142 SHGetPathFromIDListW(pidl1, szPath1);
143 SHGetPathFromIDListW(pidl2, szPath2);
144
145 trace("(0x%lX, '%ls', '%ls')\n", lEvent, szPath1, szPath2);
146
147 if (lEvent == SHCNE_UPDATEDIR)
148 {
149 trace("Got SHCNE_UPDATEDIR\n");
151 return;
152 }
153
154 INT iEventType = GetEventType(lEvent);
155 if (iEventType < 0)
156 return;
157
158 assert(iEventType < MAX_EVENT_TYPE);
159
160 INT i = 0;
161 s_abChecks[i++] |= (lstrcmpiW(szPath1, L"") == 0) << iEventType;
162 s_abChecks[i++] |= (lstrcmpiW(szPath1, s_szDir1) == 0) << iEventType;
163 s_abChecks[i++] |= (lstrcmpiW(szPath1, s_szDir2InDir1) == 0) << iEventType;
164 s_abChecks[i++] |= (lstrcmpiW(szPath1, s_szFile1InDir1) == 0) << iEventType;
165 s_abChecks[i++] |= (lstrcmpiW(szPath1, s_szFile2InDir1) == 0) << iEventType;
166 s_abChecks[i++] |= (lstrcmpiW(szPath1, s_szFile1InDir1InDir1) == 0) << iEventType;
167 s_abChecks[i++] |= (lstrcmpiW(szPath2, L"") == 0) << iEventType;
168 s_abChecks[i++] |= (lstrcmpiW(szPath2, s_szDir1) == 0) << iEventType;
169 s_abChecks[i++] |= (lstrcmpiW(szPath2, s_szDir2InDir1) == 0) << iEventType;
170 s_abChecks[i++] |= (lstrcmpiW(szPath2, s_szFile1InDir1) == 0) << iEventType;
171 s_abChecks[i++] |= (lstrcmpiW(szPath2, s_szFile2InDir1) == 0) << iEventType;
172 s_abChecks[i++] |= (lstrcmpiW(szPath2, s_szFile1InDir1InDir1) == 0) << iEventType;
173 assert(i == NUM_CHECKS);
174}
175
177{
178 static char s_sz[2 * NUM_CHECKS + 1];
179
180 char *pch = s_sz;
181 for (INT i = 0; i < NUM_CHECKS; ++i)
182 {
183 WCHAR sz[3];
184 StringCchPrintfW(sz, _countof(sz), L"%02X", s_abChecks[i]);
185 *pch++ = sz[0];
186 *pch++ = sz[1];
187 }
188
189 assert((pch - s_sz) + 1 == sizeof(s_sz));
190
191 *pch = 0;
192 return s_sz;
193}
194
196{
199};
200
201static void DoStepCheck(INT iStage, INT iStep, LPCSTR checks)
202{
203 assert(0 <= iStep);
204 assert(iStep < NUM_STEP);
205
206 assert(0 <= iStage);
207 assert(iStage < NUM_STAGE);
208
209 if (s_bGotUpdateDir)
210 {
211 ok_int(TRUE, TRUE);
212 return;
213 }
214
215 LPCSTR answer = NULL;
216 INT lineno = 0;
217 switch (iStage)
218 {
219 case 0:
220 case 1:
221 case 3:
222 case 6:
223 case 9:
224 {
225 static const TEST_ANSWER c_answers[] =
226 {
227 { __LINE__, "000000010000010000000000" }, // 0
228 { __LINE__, "000000040000000000000400" }, // 1
229 { __LINE__, "000000000200020000000000" }, // 2
230 { __LINE__, "000000000000080000000000" }, // 3
231 { __LINE__, "000000000001010000000000" }, // 4
232 { __LINE__, "000000000002020000000000" }, // 5
233 { __LINE__, "000000000000000020000000" }, // 6
234 { __LINE__, "000010000000100000000000" }, // 7
235 };
236 C_ASSERT(_countof(c_answers) == NUM_STEP);
237 lineno = c_answers[iStep].lineno;
238 answer = c_answers[iStep].answer;
239 break;
240 }
241 case 2:
242 case 4:
243 case 5:
244 case 7:
245 {
246 static const TEST_ANSWER c_answers[] =
247 {
248 { __LINE__, "000000000000000000000000" }, // 0
249 { __LINE__, "000000000000000000000000" }, // 1
250 { __LINE__, "000000000000000000000000" }, // 2
251 { __LINE__, "000000000000000000000000" }, // 3
252 { __LINE__, "000000000000000000000000" }, // 4
253 { __LINE__, "000000000000000000000000" }, // 5
254 { __LINE__, "000000000000000000000000" }, // 6
255 { __LINE__, "000000000000000000000000" }, // 7
256 };
257 C_ASSERT(_countof(c_answers) == NUM_STEP);
258 lineno = c_answers[iStep].lineno;
259 answer = c_answers[iStep].answer;
260 break;
261 }
262 case 8:
263 {
264 static const TEST_ANSWER c_answers[] =
265 {
266 { __LINE__, "000000010000010000000000" }, // 0
267 { __LINE__, "000000040000000000000400" }, // 1
268 { __LINE__, "000000000200020000000000" }, // 2
269 { __LINE__, "000000000000080000000000" }, // 3
270 { __LINE__, "000000000001010000000000" }, // 4 // Recursive case
271 { __LINE__, "000000000002020000000000" }, // 5 // Recursive case
272 { __LINE__, "000000000000000020000000" }, // 6
273 { __LINE__, "000010000000100000000000" }, // 7
274 };
275 C_ASSERT(_countof(c_answers) == NUM_STEP);
276 lineno = c_answers[iStep].lineno;
277 answer = c_answers[iStep].answer;
278 if (iStep == 4 || iStep == 5) // Recursive cases
279 {
280 if (lstrcmpA(checks, "000000000000000000000000") == 0)
281 {
282 trace("Warning! Recursive cases...\n");
283 answer = "000000000000000000000000";
284 }
285 }
286 break;
287 }
289 }
290
291 ok(lstrcmpA(checks, answer) == 0,
292 "Line %d: '%s' vs '%s' at Stage %d, Step %d\n", lineno, checks, answer, iStage, iStep);
293}
294
296{
297 BOOL ret;
298
299 trace("Stage %d\n", s_iStage);
300
301 // 0: Create file1 in dir1
302 s_iStep = 0;
303 trace("Step %d\n", s_iStep);
307 ok_int(ret, TRUE);
311
312 // 1: Rename file1 as file2 in dir1
313 ++s_iStep;
314 trace("Step %d\n", s_iStep);
317 ok_int(ret, TRUE);
321
322 // 2: Delete file2 in dir1
323 ++s_iStep;
324 trace("Step %d\n", s_iStep);
327 ok_int(ret, TRUE);
331
332 // 3: Create dir1 in dir1
333 ++s_iStep;
334 trace("Step %d\n", s_iStep);
337 ok_int(ret, TRUE);
341
342 // 4: Create file1 in dir1 in dir1
343 ++s_iStep;
344 trace("Step %d\n", s_iStep);
347 ok_int(ret, TRUE);
351
352 // 5: Delete file1 in dir1 in dir1
353 ++s_iStep;
354 trace("Step %d\n", s_iStep);
357 ok_int(ret, TRUE);
361
362 // 6: Rename dir1 as dir2 in dir1
363 ++s_iStep;
364 trace("Step %d\n", s_iStep);
367 ok_int(ret, TRUE);
371
372 // 7: Remove dir2 in dir1
373 ++s_iStep;
374 trace("Step %d\n", s_iStep);
377 ok_int(ret, TRUE);
381
382 // 8: Finish
383 ++s_iStep;
385 C_ASSERT(NUM_STEP == 8);
386 if (s_iStage + 1 < NUM_STAGE)
387 {
388 ::PostMessage(s_hSubWnd, WM_COMMAND, IDRETRY, 0); // Next stage
389 }
390 else
391 {
392 // Finish
395 }
396
397 s_iStep = -1;
398
399 return 0;
400}
401
402// WM_COPYDATA
403static BOOL OnCopyData(HWND hwnd, HWND hwndSender, COPYDATASTRUCT *pCopyData)
404{
405 if (pCopyData->dwData != 0xBEEFCAFE)
406 return FALSE;
407
408 LPBYTE pbData = (LPBYTE)pCopyData->lpData;
409 LPBYTE pb = pbData;
410
411 LONG cbTotal = pCopyData->cbData;
412 assert(cbTotal >= LONG(sizeof(LONG) + sizeof(DWORD) + sizeof(DWORD)));
413
414 LONG lEvent = *(LONG*)pb;
415 pb += sizeof(lEvent);
416
417 DWORD cbPidl1 = *(DWORD*)pb;
418 pb += sizeof(cbPidl1);
419
420 DWORD cbPidl2 = *(DWORD*)pb;
421 pb += sizeof(cbPidl2);
422
423 LPITEMIDLIST pidl1 = NULL;
424 if (cbPidl1)
425 {
426 pidl1 = (LPITEMIDLIST)CoTaskMemAlloc(cbPidl1);
427 CopyMemory(pidl1, pb, cbPidl1);
428 pb += cbPidl1;
429 }
430
431 LPITEMIDLIST pidl2 = NULL;
432 if (cbPidl2)
433 {
434 pidl2 = (LPITEMIDLIST)CoTaskMemAlloc(cbPidl2);
435 CopyMemory(pidl2, pb, cbPidl2);
436 pb += cbPidl2;
437 }
438
439 assert((pb - pbData) == cbTotal);
440
441 DoTestEntry(lEvent, pidl1, pidl2);
442
443 CoTaskMemFree(pidl1);
444 CoTaskMemFree(pidl2);
445
446 return TRUE;
447}
448
449static LRESULT CALLBACK
451{
452 switch (uMsg)
453 {
454 case WM_CREATE:
456 return 0;
457
458 case WM_COMMAND:
459 switch (LOWORD(wParam))
460 {
461 case IDYES: // Start testing
462 {
463 s_iStage = 0;
466 if (!s_hThread)
467 {
468 skip("!s_hThread\n");
470 }
471 break;
472 }
473 case IDRETRY: // New stage
474 {
476 ++s_iStage;
479 if (!s_hThread)
480 {
481 skip("!s_hThread\n");
483 }
484 break;
485 }
486 case IDNO: // Quit
487 {
488 s_iStage = -1;
490 break;
491 }
492 }
493 break;
494
495 case WM_COPYDATA:
496 if (s_iStage < 0 || s_iStep < 0)
497 break;
498
500 break;
501
502 case WM_DESTROY:
504 break;
505
506 default:
507 return ::DefWindowProcW(hwnd, uMsg, wParam, lParam);
508 }
509 return 0;
510}
511
512static BOOL TEST_Init(void)
513{
515 {
516 skip("shell32_apitest_sub.exe not found\n");
517 return FALSE;
518 }
519
520 // close the SUB_CLASSNAME windows
522
523 // Execute sub program
525 if ((INT_PTR)hinst <= 32)
526 {
527 skip("Unable to run shell32_apitest_sub.exe.\n");
528 return FALSE;
529 }
530
531 // prepare for files and dirs
533
534 // Register main window
535 WNDCLASSW wc = { 0, MainWndProc };
539 wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
541 if (!RegisterClassW(&wc))
542 {
543 skip("RegisterClassW failed\n");
544 return FALSE;
545 }
546
547 // Create main window
549 CW_USEDEFAULT, CW_USEDEFAULT, 400, 100,
551 if (!hwnd)
552 {
553 skip("CreateWindowW failed\n");
554 return FALSE;
555 }
558
559 // Find sub-window
561 if (!s_hSubWnd)
562 {
563 skip("Unable to find sub-program window.\n");
564 return FALSE;
565 }
566
567 // Start testing
569
570 return TRUE;
571}
572
573static void TEST_Main(void)
574{
575 if (!TEST_Init())
576 {
577 skip("Unable to start testing.\n");
578 TEST_Quit();
579 return;
580 }
581
582 // Message loop
583 MSG msg;
584 while (GetMessageW(&msg, NULL, 0, 0))
585 {
588 }
589
590 TEST_Quit();
591}
592
594{
595 trace("Please close all Explorer windows before testing.\n");
596 trace("Please don't operate your PC while testing.\n");
597
598 DWORD dwOldTick = GetTickCount();
599 TEST_Main();
600 DWORD dwNewTick = GetTickCount();
601
602 DWORD dwTick = dwNewTick - dwOldTick;
603 trace("SHChangeNotify: Total %lu.%lu sec\n", (dwTick / 1000), (dwTick / 100 % 10));
604}
#define MAX_EVENT_TYPE
#define TRACE_PATH(path)
#define FILE_1
static DWORD WINAPI StageThreadFunc(LPVOID arg)
#define DIR_1
static void TEST_Quit(void)
static WCHAR s_szDir1InDir1[MAX_PATH]
static WCHAR s_szFile1InDir1InDir1[MAX_PATH]
#define DIR_2
static void TEST_Main(void)
#define NUM_CHECKS
static HANDLE s_hThread
static HWND s_hSubWnd
static BOOL TEST_Init(void)
static BOOL OnCopyData(HWND hwnd, HWND hwndSender, COPYDATASTRUCT *pCopyData)
static INT GetEventType(LONG lEvent)
static BOOL s_bGotUpdateDir
static void DoDeleteFilesAndDirs(void)
static HWND s_hMainWnd
static BYTE s_abChecks[NUM_CHECKS]
#define NUM_STEP
static WCHAR s_szSubProgram[MAX_PATH]
static void DoDeleteDirectory(LPCWSTR pszDir)
static void DoStepCheck(INT iStage, INT iStep, LPCSTR checks)
#define INTERVAL
#define FILE_2
static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static void DoTestEntry(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
static LPCSTR StringFromChecks(void)
static WCHAR s_szDir2InDir1[MAX_PATH]
static WCHAR s_szDir1[MAX_PATH]
static INT s_iStage
static void DoBuildFilesAndDirs(void)
static WCHAR s_szFile1InDir1[MAX_PATH]
static BOOL DoCreateFile(LPCWSTR pszFileName)
static INT s_iStep
static WCHAR s_szFile2InDir1[MAX_PATH]
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
#define msg(x)
Definition: auth_time.c:54
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
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 CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI CreateDirectoryExW(IN LPCWSTR lpTemplateDirectory, IN LPCWSTR lpNewDirectory, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:193
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1104
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4198
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4265
BOOL WINAPI PathRemoveFileSpecW(WCHAR *path)
Definition: path.c:1145
ULONG WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
Definition: sync.c:182
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3219
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1729
#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 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
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
#define C_ASSERT(e)
Definition: intsafe.h:73
#define pch(ap)
Definition: match.c:418
#define CREATE_ALWAYS
Definition: disk.h:72
LPCWSTR szPath
Definition: env.c:37
static HINSTANCE hinst
Definition: edit.c:551
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
#define GENERIC_WRITE
Definition: nt_native.h:90
#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
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1490
static HWND DoWaitForWindow(LPCWSTR clsname, LPCWSTR text, BOOL bClosing, BOOL bForce)
static BOOL FindSubProgram(LPWSTR pszSubProgram, DWORD cchSubProgram)
#define SUB_CLASSNAME
#define NUM_STAGE
#define MAIN_CLASSNAME
#define FO_DELETE
Definition: shellapi.h:138
_In_ LPCSTR pszDir
Definition: shellapi.h:601
#define FOF_NOCONFIRMATION
Definition: shellapi.h:145
#define SHFileOperation
Definition: shellapi.h:735
#define FOF_SILENT
Definition: shellapi.h:143
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2607
#define SHCNE_RMDIR
Definition: shlobj.h:1899
#define SHCNE_DELETE
Definition: shlobj.h:1897
#define SHCNE_MKDIR
Definition: shlobj.h:1898
#define CSIDL_PERSONAL
Definition: shlobj.h:2184
#define SHCNE_RENAMEITEM
Definition: shlobj.h:1895
#define SHCNE_UPDATEDIR
Definition: shlobj.h:1907
#define SHCNE_CREATE
Definition: shlobj.h:1896
#define SHCNE_RENAMEFOLDER
Definition: shlobj.h:1912
#define SHCNF_FLUSH
Definition: shlobj.h:1934
#define SHCNF_PATHW
Definition: shlobj.h:1931
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
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
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
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
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44
#define ZeroMemory
Definition: winbase.h:1753
#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 WINAPI
Definition: msvc.h:6
#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 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 PostMessage
Definition: winuser.h:5943
#define CW_USEDEFAULT
Definition: winuser.h:225
#define WM_DESTROY
Definition: winuser.h:1637
#define DispatchMessage
Definition: winuser.h:5876
#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
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193