ReactOS 0.4.15-dev-7931-gfd331f1
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 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6 */
7
8#include "shelltest.h"
10
11static HWND s_hwnd = NULL;
12static UINT s_uRegID = 0;
15static INT s_nSources = 0;
20
21static BOOL
23{
24 s_hwnd = hwnd;
26
28 entry.pidl = s_pidl;
29 entry.fRecursive = s_fRecursive;
31 return s_uRegID != 0;
32}
33
34static void
36{
37 switch (id)
38 {
39 case IDOK:
40 case IDCANCEL:
42 break;
43 }
44}
45
46static void
48{
50 s_uRegID = 0;
51
53 s_pidl = NULL;
54
56 s_hwnd = NULL;
57}
58
60{
62 if (!SHGetPathFromIDListW(pidl1, path))
63 {
64 s_path1[0] = s_path2[0] = 0;
65 return FALSE;
66 }
67
68 if (wcsstr(path, L"Recent") != NULL)
69 return FALSE;
70
72
73 if (!SHGetPathFromIDListW(pidl2, s_path2))
74 s_path2[0] = 0;
75
76 return TRUE;
77}
78
80{
81 if (DoPathes(pidl1, pidl2))
82 {
83 s_counters[type] = 1;
85 }
86}
87
88static void
90{
91 switch (lEvent)
92 {
94 DoPathesAndFlags(TYPE_RENAMEITEM, pidl1, pidl2);
95 break;
96 case SHCNE_CREATE:
97 DoPathesAndFlags(TYPE_CREATE, pidl1, pidl2);
98 break;
99 case SHCNE_DELETE:
100 DoPathesAndFlags(TYPE_DELETE, pidl1, pidl2);
101 break;
102 case SHCNE_MKDIR:
103 DoPathesAndFlags(TYPE_MKDIR, pidl1, pidl2);
104 break;
105 case SHCNE_RMDIR:
106 DoPathesAndFlags(TYPE_RMDIR, pidl1, pidl2);
107 break;
109 break;
111 break;
113 break;
114 case SHCNE_DRIVEADD:
115 break;
116 case SHCNE_NETSHARE:
117 break;
118 case SHCNE_NETUNSHARE:
119 break;
120 case SHCNE_ATTRIBUTES:
121 break;
122 case SHCNE_UPDATEDIR:
123 DoPathesAndFlags(TYPE_UPDATEDIR, pidl1, pidl2);
124 break;
125 case SHCNE_UPDATEITEM:
126 break;
128 break;
130 break;
132 break;
134 DoPathesAndFlags(TYPE_RENAMEFOLDER, pidl1, pidl2);
135 break;
136 case SHCNE_FREESPACE:
137 break;
139 break;
141 break;
142 default:
143 break;
144 }
145}
146
147static INT_PTR
149{
150 LONG lEvent;
151 PIDLIST_ABSOLUTE *pidlAbsolute;
152 HANDLE hLock = SHChangeNotification_Lock((HANDLE)wParam, (DWORD)lParam, &pidlAbsolute, &lEvent);
153 if (hLock)
154 {
155 DoShellNotify(hwnd, pidlAbsolute[0], pidlAbsolute[1], lEvent);
157 }
158 else
159 {
160 pidlAbsolute = (PIDLIST_ABSOLUTE *)wParam;
161 DoShellNotify(hwnd, pidlAbsolute[0], pidlAbsolute[1], lParam);
162 }
163 return TRUE;
164}
165
166static LRESULT
168{
169 if (s_uRegID == 0)
170 return 0xFFFFFFFF;
171
172 DWORD dwFlags = 0;
173 for (size_t i = 0; i < _countof(s_counters); ++i)
174 {
175 if (s_counters[i])
176 dwFlags |= (1 << i);
177 }
178 return dwFlags;
179}
180
181static void
183{
184 WCHAR szText[MAX_PATH * 2];
185 StringCchCopyW(szText, _countof(szText), s_path1);
186 StringCchCatW(szText, _countof(szText), L"|");
187 StringCchCatW(szText, _countof(szText), s_path2);
188
189 FILE *fp = _wfopen(TEMP_FILE, L"wb");
190 if (fp)
191 {
192 fwrite(szText, (wcslen(szText) + 1) * sizeof(WCHAR), 1, fp);
193 fflush(fp);
194 fclose(fp);
195 }
196}
197
198static LRESULT CALLBACK
200{
201 switch (uMsg)
202 {
203 case WM_CREATE:
204 return (OnCreate(hwnd) ? 0 : -1);
205
206 case WM_COMMAND:
208 break;
209
210 case WM_SHELL_NOTIFY:
212
213 case WM_DESTROY:
215 break;
216
218 return OnGetNotifyFlags(hwnd);
219
220 case WM_CLEAR_FLAGS:
222 s_path1[0] = s_path2[0] = 0;
223 break;
224
225 case WM_SET_PATHS:
227 break;
228
229 default:
230 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
231 }
232 return 0;
233}
234
235static BOOL ParseCommandLine(LPWSTR lpCmdLine)
236{
237 LPWSTR pch = lpCmdLine; // fRecursive,iWatchDir,nSources
238 s_fRecursive = !!wcstoul(pch, NULL, 0);
239 pch = wcschr(pch, L',');
240 if (!pch)
241 return FALSE;
242 ++pch;
243
245 pch = wcschr(pch, L',');
246 if (!pch)
247 return FALSE;
248 ++pch;
249
250 s_nSources = wcstoul(pch, NULL, 0);
251 return TRUE;
252}
253
256 HINSTANCE hPrevInstance,
257 LPWSTR lpCmdLine,
258 INT nCmdShow)
259{
260 if (lstrcmpiW(lpCmdLine, L"") == 0 || lstrcmpiW(lpCmdLine, L"TEST") == 0)
261 return 0;
262
263 if (!ParseCommandLine(lpCmdLine))
264 return -1;
265
267
268 WNDCLASSW wc;
269 ZeroMemory(&wc, sizeof(wc));
274 wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
276 if (!RegisterClassW(&wc))
277 return -1;
278
280 CW_USEDEFAULT, CW_USEDEFAULT, 400, 100,
282 if (!hwnd)
283 return -1;
284
287
288 MSG msg;
289 while (GetMessageW(&msg, NULL, 0, 0))
290 {
293 }
294
296
297 return 0;
298}
#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 CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
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
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
uint32_t entry
Definition: isohybrid.c:63
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define pch(ap)
Definition: match.c:418
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
#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:1353
static BOOL DoPathes(PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
static HWND s_hwnd
static void DoSetPaths(HWND hwnd)
static HANDLE s_hEvent
static BOOL OnCreate(HWND hwnd)
static LRESULT OnGetNotifyFlags(HWND hwnd)
static void OnCommand(HWND hwnd, UINT id)
static LPITEMIDLIST s_pidl
static void OnDestroy(HWND hwnd)
static WCHAR s_path1[MAX_PATH]
static VOID DoPathesAndFlags(UINT type, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static DIRTYPE s_iWatchDir
static void DoShellNotify(HWND hwnd, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2, LONG lEvent)
static UINT s_uRegID
static INT s_nSources
static BOOL ParseCommandLine(LPWSTR lpCmdLine)
static BOOL s_fRecursive
static BYTE s_counters[TYPE_MAX+1]
static WCHAR s_path2[MAX_PATH]
INT APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nCmdShow)
static INT_PTR OnShellNotify(HWND hwnd, WPARAM wParam, LPARAM lParam)
@ TYPE_RENAMEFOLDER
@ TYPE_RMDIR
@ TYPE_UPDATEDIR
@ TYPE_MKDIR
@ TYPE_DELETE
@ TYPE_MAX
@ TYPE_RENAMEITEM
@ TYPE_CREATE
#define EVENT_NAME
#define CLASSNAME
#define TEMP_FILE
#define WM_CLEAR_FLAGS
#define WM_GET_NOTIFY_FLAGS
LPITEMIDLIST DoGetPidl(DIRTYPE iDir)
@ DIRTYPE_NULL
#define WM_SHELL_NOTIFY
#define WM_SET_PATHS
#define SHCNE_DRIVEREMOVED
Definition: shlobj.h:1882
#define SHCNE_DRIVEADDGUI
Definition: shlobj.h:1891
#define SHCNE_RMDIR
Definition: shlobj.h:1879
#define SHCNE_DELETE
Definition: shlobj.h:1877
#define SHCNE_MKDIR
Definition: shlobj.h:1878
#define SHCNE_UPDATEITEM
Definition: shlobj.h:1888
#define SHCNE_RENAMEITEM
Definition: shlobj.h:1875
#define SHCNE_UPDATEDIR
Definition: shlobj.h:1887
#define SHCNE_MEDIAINSERTED
Definition: shlobj.h:1880
#define SHCNE_UPDATEIMAGE
Definition: shlobj.h:1890
#define SHCNE_CREATE
Definition: shlobj.h:1876
#define SHCNE_RENAMEFOLDER
Definition: shlobj.h:1892
#define SHCNE_SERVERDISCONNECT
Definition: shlobj.h:1889
#define SHCNE_MEDIAREMOVED
Definition: shlobj.h:1881
#define SHCNE_EXTENDED_EVENT
Definition: shlobj.h:1895
#define SHCNE_DRIVEADD
Definition: shlobj.h:1883
#define SHCNE_ASSOCCHANGED
Definition: shlobj.h:1896
#define SHCNE_ATTRIBUTES
Definition: shlobj.h:1886
#define SHCNE_ALLEVENTS
Definition: shlobj.h:1899
#define SHCNE_NETUNSHARE
Definition: shlobj.h:1885
#define SHCNE_FREESPACE
Definition: shlobj.h:1893
#define SHCNE_NETSHARE
Definition: shlobj.h:1884
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
#define _countof(array)
Definition: sndvol32.h:68
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
LPCWSTR lpszClassName
Definition: winuser.h:3185
HBRUSH hbrBackground
Definition: winuser.h:3183
HICON hIcon
Definition: winuser.h:3181
HINSTANCE hInstance
Definition: winuser.h:3180
WNDPROC lpfnWndProc
Definition: winuser.h:3177
HCURSOR hCursor
Definition: winuser.h:3182
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
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
int32_t INT
Definition: typedefs.h:58
#define ZeroMemory
Definition: winbase.h:1712
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_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)
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define IDCANCEL
Definition: winuser.h:831
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#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
#define IDOK
Definition: winuser.h:830
#define IDI_APPLICATION
Definition: winuser.h:704
#define LoadIcon
Definition: winuser.h:5813
BOOL WINAPI UpdateWindow(_In_ HWND)
#define LoadCursor
Definition: winuser.h:5812
#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
BOOL WINAPI DestroyWindow(_In_ HWND)
#define COLOR_3DFACE
Definition: winuser.h:929
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
unsigned char BYTE
Definition: xxhash.c:193