ReactOS  0.4.13-dev-99-g7e18b6d
change.c
Go to the documentation of this file.
1 /*
2  * File change notification tests
3  *
4  * Copyright 2006 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <ntstatus.h>
22 #define WIN32_NO_STATUS
23 #include <windows.h>
24 #include <winnt.h>
25 #include <winternl.h>
26 #include <winerror.h>
27 #include <stdio.h>
28 #include "wine/test.h"
29 
30 static NTSTATUS (WINAPI *pNtNotifyChangeDirectoryFile)(
33 
34 static NTSTATUS (WINAPI *pNtCancelIoFile)(HANDLE,PIO_STATUS_BLOCK);
35 
36 
37 static void test_ntncdf(void)
38 {
39  NTSTATUS r;
40  HANDLE hdir, hEvent;
41  char buffer[0x1000];
42  DWORD fflags, filter = 0;
44  WCHAR path[MAX_PATH], subdir[MAX_PATH];
45  static const WCHAR szBoo[] = { '\\','b','o','o',0 };
46  static const WCHAR szHoo[] = { '\\','h','o','o',0 };
48 
50  ok( r != 0, "temp path failed\n");
51  if (!r)
52  return;
53 
54  lstrcatW( path, szBoo );
55  lstrcpyW( subdir, path );
56  lstrcatW( subdir, szHoo );
57 
58  RemoveDirectoryW( subdir );
60 
62  ok( r == TRUE, "failed to create directory\n");
63 
64  r = pNtNotifyChangeDirectoryFile(NULL,NULL,NULL,NULL,NULL,NULL,0,0,0);
65  ok(r==STATUS_ACCESS_VIOLATION, "should return access violation\n");
66 
69  OPEN_EXISTING, fflags, NULL);
70  ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
71 
72  hEvent = CreateEventA( NULL, 0, 0, NULL );
73 
74  r = pNtNotifyChangeDirectoryFile(hdir,NULL,NULL,NULL,&iosb,NULL,0,0,0);
75  ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
76 
77  r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,NULL,0,0,0);
78  ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
79 
88 
89  U(iosb).Status = 1;
90  iosb.Information = 1;
91  r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,-1,0);
92  ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
93 
94  ok( U(iosb).Status == 1, "information wrong\n");
95  ok( iosb.Information == 1, "information wrong\n");
96 
97  U(iosb).Status = 1;
98  iosb.Information = 0;
99  r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
100  ok(r==STATUS_PENDING, "should return status pending\n");
101 
102  r = WaitForSingleObject( hEvent, 100 );
103  ok( r == STATUS_TIMEOUT, "should timeout\n" );
104 
105  r = WaitForSingleObject( hdir, 100 );
106  ok( r == STATUS_TIMEOUT, "should timeout\n" );
107 
108  r = CreateDirectoryW( subdir, NULL );
109  ok( r == TRUE, "failed to create directory\n");
110 
111  r = WaitForSingleObject( hdir, 100 );
112  ok( r == STATUS_TIMEOUT, "should timeout\n" );
113 
114  r = WaitForSingleObject( hEvent, 100 );
115  ok( r == WAIT_OBJECT_0, "event should be ready\n" );
116 
117  ok( U(iosb).Status == STATUS_SUCCESS, "information wrong\n");
118  ok( iosb.Information == 0x12, "information wrong\n");
119 
121  ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
122  ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
123  ok( pfni->FileNameLength == 6, "len wrong\n" );
124  ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
125 
126  r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,0,0);
127  ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
128 
129  r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,0,0);
130  ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
131 
133 
134  U(iosb).Status = 1;
135  iosb.Information = 1;
136  r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0);
137  ok(r==STATUS_PENDING, "should status pending\n");
138 
139  ok( U(iosb).Status == 1, "information wrong\n");
140  ok( iosb.Information == 1, "information wrong\n");
141 
142  r = WaitForSingleObject( hdir, 0 );
143  ok( r == STATUS_TIMEOUT, "should timeout\n" );
144 
145  r = RemoveDirectoryW( subdir );
146  ok( r == TRUE, "failed to remove directory\n");
147 
148  r = WaitForSingleObject( hdir, 100 );
149  ok( r == WAIT_OBJECT_0, "should be ready\n" );
150 
151  r = WaitForSingleObject( hdir, 100 );
152  ok( r == WAIT_OBJECT_0, "should be ready\n" );
153 
154  ok( U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "information wrong\n");
155  ok( iosb.Information == 0, "information wrong\n");
156 
157  CloseHandle(hdir);
159 
160  r = RemoveDirectoryW( path );
161  ok( r == TRUE, "failed to remove directory\n");
162 }
163 
164 
165 static void test_ntncdf_async(void)
166 {
167  NTSTATUS r;
168  HANDLE hdir, hEvent;
169  char buffer[0x1000];
170  DWORD fflags, filter = 0;
171  IO_STATUS_BLOCK iosb, iosb2;
172  WCHAR path[MAX_PATH], subdir[MAX_PATH];
173  static const WCHAR szBoo[] = { '\\','b','o','o',0 };
174  static const WCHAR szHoo[] = { '\\','h','o','o',0 };
176 
177  r = GetTempPathW( MAX_PATH, path );
178  ok( r != 0, "temp path failed\n");
179  if (!r)
180  return;
181 
182  lstrcatW( path, szBoo );
183  lstrcpyW( subdir, path );
184  lstrcatW( subdir, szHoo );
185 
186  RemoveDirectoryW( subdir );
188 
190  ok( r == TRUE, "failed to create directory\n");
191 
192  r = pNtNotifyChangeDirectoryFile(NULL,NULL,NULL,NULL,NULL,NULL,0,0,0);
193  ok(r==STATUS_ACCESS_VIOLATION, "should return access violation\n");
194 
197  OPEN_EXISTING, fflags, NULL);
198  ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
199 
200  hEvent = CreateEventA( NULL, 0, 0, NULL );
201 
210 
211 
212  U(iosb).Status = 0x01234567;
213  iosb.Information = 0x12345678;
214  r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
215  ok(r==STATUS_PENDING, "should status pending\n");
216  ok(U(iosb).Status == 0x01234567, "status set too soon\n");
217  ok(iosb.Information == 0x12345678, "info set too soon\n");
218 
219  r = CreateDirectoryW( subdir, NULL );
220  ok( r == TRUE, "failed to create directory\n");
221 
222  r = WaitForSingleObject( hdir, 100 );
223  ok( r == WAIT_OBJECT_0, "should be ready\n" );
224 
225  ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
226  ok(iosb.Information == 0x12, "info not set\n");
227 
229  ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
230  ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
231  ok( pfni->FileNameLength == 6, "len wrong\n" );
232  ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
233 
234  r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
235  ok(r==STATUS_PENDING, "should status pending\n");
236 
237  r = RemoveDirectoryW( subdir );
238  ok( r == TRUE, "failed to remove directory\n");
239 
240  r = WaitForSingleObject( hdir, 0 );
241  ok( r == WAIT_OBJECT_0, "should be ready\n" );
242 
243  ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
244  ok(iosb.Information == 0x12, "info not set\n");
245 
246  ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
247  ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong\n" );
248  ok( pfni->FileNameLength == 6, "len wrong\n" );
249  ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
250 
251  /* check APCs */
252  U(iosb).Status = 0;
253  iosb.Information = 0;
254 
255  r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0);
256  ok(r==STATUS_PENDING, "should status pending\n");
257 
258  r = CreateDirectoryW( subdir, NULL );
259  ok( r == TRUE, "failed to create directory\n");
260 
261  r = WaitForSingleObject( hdir, 0 );
262  ok( r == WAIT_OBJECT_0, "should be ready\n" );
263 
264  ok(U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "status not successful\n");
265  ok(iosb.Information == 0, "info not set\n");
266 
267  U(iosb).Status = 0;
268  iosb.Information = 0;
269 
270  r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
271  ok(r==STATUS_PENDING, "should status pending\n");
272 
273  r = RemoveDirectoryW( subdir );
274  ok( r == TRUE, "failed to remove directory\n");
275 
276  r = WaitForSingleObject( hEvent, 0 );
277  ok( r == WAIT_OBJECT_0, "should be ready\n" );
278 
279  ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
280  ok(iosb.Information == 0x12, "info not set\n");
281 
282 
283  U(iosb).Status = 0x01234567;
284  iosb.Information = 0x12345678;
285  r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
286  ok(r==STATUS_PENDING, "should status pending\n");
287 
288  U(iosb2).Status = 0x01234567;
289  iosb2.Information = 0x12345678;
290  r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb2,buffer,sizeof buffer,filter,0);
291  ok(r==STATUS_PENDING, "should status pending\n");
292 
293  ok(U(iosb).Status == 0x01234567, "status set too soon\n");
294  ok(iosb.Information == 0x12345678, "info set too soon\n");
295 
296  r = pNtCancelIoFile(hdir, &iosb);
297  ok( r == STATUS_SUCCESS, "cancel failed\n");
298 
299  CloseHandle(hdir);
300 
301  ok(U(iosb).Status == STATUS_SUCCESS, "status wrong\n");
302  ok(U(iosb2).Status == STATUS_CANCELLED, "status wrong %x\n",U(iosb2).Status);
303 
304  ok(iosb.Information == 0, "info wrong\n");
305  ok(iosb2.Information == 0, "info wrong\n");
306 
307  r = RemoveDirectoryW( path );
308  ok( r == TRUE, "failed to remove directory\n");
309 
311 }
312 
313 START_TEST(change)
314 {
315  HMODULE hntdll = GetModuleHandleA("ntdll");
316  if (!hntdll)
317  {
318  win_skip("not running on NT, skipping test\n");
319  return;
320  }
321 
322  pNtNotifyChangeDirectoryFile = (void *)GetProcAddress(hntdll, "NtNotifyChangeDirectoryFile");
323  pNtCancelIoFile = (void *)GetProcAddress(hntdll, "NtCancelIoFile");
324 
325  if (!pNtNotifyChangeDirectoryFile || !pNtCancelIoFile)
326  {
327  win_skip("missing functions, skipping test\n");
328  return;
329  }
330 
331  test_ntncdf();
333 }
static PVOID
Definition: change.c:31
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define U(x)
Definition: wordpad.c:44
static ULONG
Definition: change.c:31
LONG NTSTATUS
Definition: precomp.h:26
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
GLuint buffer
Definition: glext.h:5915
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define FILE_NOTIFY_CHANGE_FILE_NAME
static void test_ntncdf(void)
Definition: change.c:37
#define FILE_NOTIFY_CHANGE_DIR_NAME
static HANDLE
Definition: change.c:31
#define FILE_SHARE_READ
Definition: compat.h:125
static HANDLE hEvent
Definition: comm.c:54
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static NTSTATUS(WINAPI *pNtNotifyChangeDirectoryFile)(HANDLE
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2079
#define ok(value,...)
smooth NULL
Definition: ftsmooth.c:416
#define FILE_ACTION_REMOVED
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:583
static BOOLEAN
Definition: change.c:31
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
#define STATUS_NOTIFY_ENUM_DIR
Definition: ntstatus.h:91
#define OPEN_EXISTING
Definition: compat.h:426
#define FILE_NOTIFY_CHANGE_CREATION
#define WAIT_OBJECT_0
Definition: winbase.h:387
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define STATUS_PENDING
Definition: ntstatus.h:82
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
unsigned long DWORD
Definition: ntddk_ex.h:95
static PIO_STATUS_BLOCK
Definition: change.c:31
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
#define GENERIC_READ
Definition: compat.h:124
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
#define lstrcpyW
Definition: compat.h:406
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define FILE_NOTIFY_CHANGE_SECURITY
Definition: services.c:325
static HINSTANCE hntdll
Definition: process.c:66
#define FILE_ACTION_ADDED
#define CreateFileW
Definition: compat.h:400
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
#define GetProcAddress(x, y)
Definition: compat.h:410
struct _FILE_NOTIFY_INFORMATION * PFILE_NOTIFY_INFORMATION
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
return STATUS_SUCCESS
Definition: btrfs.c:2725
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
#define win_skip
Definition: test.h:141
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
static void test_ntncdf_async(void)
Definition: change.c:165
START_TEST(change)
Definition: change.c:1113
static PIO_APC_ROUTINE
Definition: change.c:31