ReactOS  0.4.15-dev-5488-ge316d61
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"
9 #include "shell32_apitest_sub.h"
10 
11 static HWND s_hwnd = NULL;
12 static UINT s_uRegID = 0;
15 static INT s_nSources = 0;
18 static BYTE s_counters[TYPE_MAX + 1];
19 static HANDLE s_hEvent = NULL;
20 
21 static BOOL
23 {
24  s_hwnd = hwnd;
26 
28  entry.pidl = s_pidl;
29  entry.fRecursive = s_fRecursive;
31  return s_uRegID != 0;
32 }
33 
34 static void
36 {
37  switch (id)
38  {
39  case IDOK:
40  case IDCANCEL:
42  break;
43  }
44 }
45 
46 static void
48 {
50  s_uRegID = 0;
51 
53  s_pidl = NULL;
54 
55  PostQuitMessage(0);
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 
88 static void
90 {
91  switch (lEvent)
92  {
93  case SHCNE_RENAMEITEM:
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;
108  case SHCNE_MEDIAINSERTED:
109  break;
110  case SHCNE_MEDIAREMOVED:
111  break;
112  case SHCNE_DRIVEREMOVED:
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;
129  case SHCNE_UPDATEIMAGE:
130  break;
131  case SHCNE_DRIVEADDGUI:
132  break;
133  case SHCNE_RENAMEFOLDER:
134  DoPathesAndFlags(TYPE_RENAMEFOLDER, pidl1, pidl2);
135  break;
136  case SHCNE_FREESPACE:
137  break;
139  break;
140  case SHCNE_ASSOCCHANGED:
141  break;
142  default:
143  break;
144  }
145 }
146 
147 static 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 
166 static 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 
181 static 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 
198 static 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:
211  return OnShellNotify(hwnd, wParam, lParam);
212 
213  case WM_DESTROY:
214  OnDestroy(hwnd);
215  break;
216 
217  case WM_GET_NOTIFY_FLAGS:
218  return OnGetNotifyFlags(hwnd);
219 
220  case WM_CLEAR_FLAGS:
221  ZeroMemory(&s_counters, sizeof(s_counters));
222  s_path1[0] = s_path2[0] = 0;
223  break;
224 
225  case WM_SET_PATHS:
226  DoSetPaths(hwnd);
227  break;
228 
229  default:
230  return DefWindowProcW(hwnd, uMsg, wParam, lParam);
231  }
232  return 0;
233 }
234 
235 static 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));
270  wc.lpfnWndProc = WindowProc;
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 SHCNE_MKDIR
Definition: shlobj.h:1745
#define SHCNE_ATTRIBUTES
Definition: shlobj.h:1753
BOOL WINAPI TranslateMessage(_In_ const MSG *)
static BOOL s_fRecursive
#define SHCNE_RMDIR
Definition: shlobj.h:1746
#define IDOK
Definition: winuser.h:824
#define CloseHandle
Definition: compat.h:739
static void OnDestroy(HWND hwnd)
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
static INT s_nSources
#define SHCNE_UPDATEIMAGE
Definition: shlobj.h:1757
EXTERN_C BOOL WINAPI SHChangeNotification_Unlock(HANDLE hLock)
#define SHCNE_NETUNSHARE
Definition: shlobj.h:1752
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
#define TRUE
Definition: types.h:120
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
static LRESULT OnGetNotifyFlags(HWND hwnd)
#define SHCNE_RENAMEFOLDER
Definition: shlobj.h:1759
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1294
#define CALLBACK
Definition: compat.h:35
BOOL WINAPI UpdateWindow(_In_ HWND)
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define ZeroMemory
Definition: winbase.h:1670
#define WM_CLEAR_FLAGS
#define IDI_APPLICATION
Definition: winuser.h:699
UINT_PTR WPARAM
Definition: windef.h:207
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
static BOOL OnCreate(HWND hwnd)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
int32_t INT_PTR
Definition: typedefs.h:64
_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)
#define SHCNE_RENAMEITEM
Definition: shlobj.h:1742
BOOL WINAPI DestroyWindow(_In_ HWND)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4306
int32_t INT
Definition: typedefs.h:58
WPARAM wParam
Definition: combotst.c:138
#define pch(ap)
Definition: match.c:418
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
static void OnCommand(HWND hwnd, UINT id)
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
HINSTANCE hInstance
Definition: charmap.c:19
#define L(x)
Definition: ntvdm.h:50
#define COLOR_3DFACE
Definition: winuser.h:923
#define FALSE
Definition: types.h:117
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
unsigned int BOOL
Definition: ntddk_ex.h:94
#define SHCNE_ALLEVENTS
Definition: shlobj.h:1766
long LONG
Definition: pedump.c:60
static VOID DoPathesAndFlags(UINT type, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
WNDPROC lpfnWndProc
Definition: winuser.h:3167
#define WM_GET_NOTIFY_FLAGS
#define CW_USEDEFAULT
Definition: winuser.h:225
LPCWSTR lpszClassName
Definition: winuser.h:3175
LONG_PTR LPARAM
Definition: windef.h:208
static WCHAR s_path1[MAX_PATH]
static void DoShellNotify(HWND hwnd, PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2, LONG lEvent)
#define WM_DESTROY
Definition: winuser.h:1599
#define EVENT_NAME
#define WM_SET_PATHS
static LPITEMIDLIST s_pidl
static DIRTYPE s_iWatchDir
#define SHCNE_MEDIAREMOVED
Definition: shlobj.h:1748
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
EXTERN_C BOOL WINAPI SHChangeNotifyDeregister(ULONG hNotify)
#define _countof(array)
Definition: sndvol32.h:68
#define MAX_PATH
Definition: compat.h:34
static BOOL ParseCommandLine(LPWSTR lpCmdLine)
static WCHAR s_path2[MAX_PATH]
unsigned long DWORD
Definition: ntddk_ex.h:95
HICON hIcon
Definition: winuser.h:3171
#define SHCNE_EXTENDED_EVENT
Definition: shlobj.h:1762
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define CLASSNAME
uint32_t entry
Definition: isohybrid.c:63
HANDLE lEvent
Definition: tftpd.cpp:56
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define WM_COMMAND
Definition: winuser.h:1730
#define SHCNE_FREESPACE
Definition: shlobj.h:1760
INT APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nCmdShow)
static BOOL DoPathes(PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
unsigned char BYTE
Definition: xxhash.c:193
#define LoadCursor
Definition: winuser.h:5802
HCURSOR hCursor
Definition: winuser.h:3172
#define SW_SHOWNORMAL
Definition: winuser.h:764
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
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
static BYTE s_counters[TYPE_MAX+1]
#define SHCNE_DELETE
Definition: shlobj.h:1744
HBRUSH hbrBackground
Definition: winuser.h:3173
#define TEMP_FILE
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#define SHCNE_UPDATEDIR
Definition: shlobj.h:1754
LPITEMIDLIST DoGetPidl(DIRTYPE iDir)
#define WM_SHELL_NOTIFY
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
EXTERN_C HANDLE WINAPI SHChangeNotification_Lock(HANDLE hTicket, DWORD dwOwnerPID, LPITEMIDLIST **lppidls, LPLONG lpwEventId)
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define SHCNE_NETSHARE
Definition: shlobj.h:1751
#define SHCNE_MEDIAINSERTED
Definition: shlobj.h:1747
HINSTANCE hInstance
Definition: winuser.h:3170
#define SHCNE_DRIVEADD
Definition: shlobj.h:1750
static UINT s_uRegID
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
#define WM_CREATE
Definition: winuser.h:1598
static INT_PTR OnShellNotify(HWND hwnd, WPARAM wParam, LPARAM lParam)
EXTERN_C ULONG WINAPI SHChangeNotifyRegister(HWND hwnd, INT fSources, LONG wEventMask, UINT uMsg, INT cItems, SHChangeNotifyEntry *lpItems)
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
static void DoSetPaths(HWND hwnd)
#define SHCNE_SERVERDISCONNECT
Definition: shlobj.h:1756
#define SHCNE_CREATE
Definition: shlobj.h:1743
#define LoadIcon
Definition: winuser.h:5803
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define SHCNE_UPDATEITEM
Definition: shlobj.h:1755
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IDCANCEL
Definition: winuser.h:825
static HWND s_hwnd
LONG_PTR LRESULT
Definition: windef.h:209
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
#define SHCNE_DRIVEADDGUI
Definition: shlobj.h:1758
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define SHCNE_DRIVEREMOVED
Definition: shlobj.h:1749
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define APIENTRY
Definition: api.h:79
static HANDLE s_hEvent
#define SHCNE_ASSOCCHANGED
Definition: shlobj.h:1763