2 * File change notification tests
4 * Copyright 2006 Mike McCormack for CodeWeavers
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.
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.
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
22 #define WIN32_NO_STATUS
28 #include "wine/test.h"
30 typedef NTSTATUS (WINAPI *fnNtNotifyChangeDirectoryFile)(
31 HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,
32 PIO_STATUS_BLOCK,PVOID,ULONG,ULONG,BOOLEAN);
33 fnNtNotifyChangeDirectoryFile pNtNotifyChangeDirectoryFile;
35 typedef NTSTATUS (WINAPI *fnNtCancelIoFile)(HANDLE,PIO_STATUS_BLOCK);
36 fnNtCancelIoFile pNtCancelIoFile;
39 static void test_ntncdf(void)
44 DWORD fflags, filter = 0;
46 WCHAR path[MAX_PATH], subdir[MAX_PATH];
47 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
48 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
49 PFILE_NOTIFY_INFORMATION pfni;
51 r = GetTempPathW( MAX_PATH, path );
52 ok( r != 0, "temp path failed\n");
56 lstrcatW( path, szBoo );
57 lstrcpyW( subdir, path );
58 lstrcatW( subdir, szHoo );
60 RemoveDirectoryW( subdir );
61 RemoveDirectoryW( path );
63 r = CreateDirectoryW(path, NULL);
64 ok( r == TRUE, "failed to create directory\n");
66 r = pNtNotifyChangeDirectoryFile(NULL,NULL,NULL,NULL,NULL,NULL,0,0,0);
67 ok(r==STATUS_ACCESS_VIOLATION, "should return access violation\n");
69 fflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED;
70 hdir = CreateFileW(path, GENERIC_READ|SYNCHRONIZE, FILE_SHARE_READ, NULL,
71 OPEN_EXISTING, fflags, NULL);
72 ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
74 hEvent = CreateEvent( NULL, 0, 0, NULL );
76 r = pNtNotifyChangeDirectoryFile(hdir,NULL,NULL,NULL,&iosb,NULL,0,0,0);
77 ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
79 r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,NULL,0,0,0);
80 ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
82 filter = FILE_NOTIFY_CHANGE_FILE_NAME;
83 filter |= FILE_NOTIFY_CHANGE_DIR_NAME;
84 filter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
85 filter |= FILE_NOTIFY_CHANGE_SIZE;
86 filter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
87 filter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
88 filter |= FILE_NOTIFY_CHANGE_CREATION;
89 filter |= FILE_NOTIFY_CHANGE_SECURITY;
93 r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,-1,0);
94 ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
96 ok( U(iosb).Status == 1, "information wrong\n");
97 ok( iosb.Information == 1, "information wrong\n");
100 iosb.Information = 0;
101 r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
102 ok(r==STATUS_PENDING, "should return status pending\n");
104 r = WaitForSingleObject( hEvent, 0 );
105 ok( r == STATUS_TIMEOUT, "should timeout\n" );
107 r = WaitForSingleObject( hdir, 0 );
108 ok( r == STATUS_TIMEOUT, "should timeout\n" );
110 r = CreateDirectoryW( subdir, NULL );
111 ok( r == TRUE, "failed to create directory\n");
113 r = WaitForSingleObject( hdir, 0 );
114 ok( r == STATUS_TIMEOUT, "should timeout\n" );
116 r = WaitForSingleObject( hEvent, 0 );
117 ok( r == WAIT_OBJECT_0, "event should be ready\n" );
119 ok( U(iosb).Status == STATUS_SUCCESS, "information wrong\n");
120 ok( iosb.Information == 0x12, "information wrong\n");
122 pfni = (PFILE_NOTIFY_INFORMATION) buffer;
123 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
124 ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
125 ok( pfni->FileNameLength == 6, "len wrong\n" );
126 ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
128 r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,0,0);
129 ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
131 r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,0,0);
132 ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
134 filter = FILE_NOTIFY_CHANGE_SIZE;
137 iosb.Information = 1;
138 r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0);
139 ok(r==STATUS_PENDING, "should status pending\n");
141 ok( U(iosb).Status == 1, "information wrong\n");
142 ok( iosb.Information == 1, "information wrong\n");
144 r = WaitForSingleObject( hdir, 0 );
145 ok( r == STATUS_TIMEOUT, "should timeout\n" );
147 r = RemoveDirectoryW( subdir );
148 ok( r == TRUE, "failed to remove directory\n");
150 r = WaitForSingleObject( hdir, 100 );
151 ok( r == WAIT_OBJECT_0, "should be ready\n" );
153 r = WaitForSingleObject( hdir, 100 );
154 ok( r == WAIT_OBJECT_0, "should be ready\n" );
156 ok( U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "information wrong\n");
157 ok( iosb.Information == 0, "information wrong\n");
162 r = RemoveDirectoryW( path );
163 ok( r == TRUE, "failed to remove directory\n");
167 static void test_ntncdf_async(void)
172 DWORD fflags, filter = 0;
173 IO_STATUS_BLOCK iosb, iosb2;
174 WCHAR path[MAX_PATH], subdir[MAX_PATH];
175 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
176 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
177 PFILE_NOTIFY_INFORMATION pfni;
179 r = GetTempPathW( MAX_PATH, path );
180 ok( r != 0, "temp path failed\n");
184 lstrcatW( path, szBoo );
185 lstrcpyW( subdir, path );
186 lstrcatW( subdir, szHoo );
188 RemoveDirectoryW( subdir );
189 RemoveDirectoryW( path );
191 r = CreateDirectoryW(path, NULL);
192 ok( r == TRUE, "failed to create directory\n");
194 r = pNtNotifyChangeDirectoryFile(NULL,NULL,NULL,NULL,NULL,NULL,0,0,0);
195 ok(r==STATUS_ACCESS_VIOLATION, "should return access violation\n");
197 fflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED;
198 hdir = CreateFileW(path, GENERIC_READ|SYNCHRONIZE, FILE_SHARE_READ, NULL,
199 OPEN_EXISTING, fflags, NULL);
200 ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
202 hEvent = CreateEvent( NULL, 0, 0, NULL );
204 filter = FILE_NOTIFY_CHANGE_FILE_NAME;
205 filter |= FILE_NOTIFY_CHANGE_DIR_NAME;
206 filter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
207 filter |= FILE_NOTIFY_CHANGE_SIZE;
208 filter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
209 filter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
210 filter |= FILE_NOTIFY_CHANGE_CREATION;
211 filter |= FILE_NOTIFY_CHANGE_SECURITY;
214 U(iosb).Status = 0x01234567;
215 iosb.Information = 0x12345678;
216 r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
217 ok(r==STATUS_PENDING, "should status pending\n");
218 ok(U(iosb).Status == 0x01234567, "status set too soon\n");
219 ok(iosb.Information == 0x12345678, "info set too soon\n");
221 r = CreateDirectoryW( subdir, NULL );
222 ok( r == TRUE, "failed to create directory\n");
224 r = WaitForSingleObject( hdir, 100 );
225 ok( r == WAIT_OBJECT_0, "should be ready\n" );
227 ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
228 ok(iosb.Information == 0x12, "info not set\n");
230 pfni = (PFILE_NOTIFY_INFORMATION) buffer;
231 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
232 ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
233 ok( pfni->FileNameLength == 6, "len wrong\n" );
234 ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
236 r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
237 ok(r==STATUS_PENDING, "should status pending\n");
239 r = RemoveDirectoryW( subdir );
240 ok( r == TRUE, "failed to remove directory\n");
242 r = WaitForSingleObject( hdir, 0 );
243 ok( r == WAIT_OBJECT_0, "should be ready\n" );
245 ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
246 ok(iosb.Information == 0x12, "info not set\n");
248 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
249 ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong\n" );
250 ok( pfni->FileNameLength == 6, "len wrong\n" );
251 ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
255 iosb.Information = 0;
257 r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0);
258 ok(r==STATUS_PENDING, "should status pending\n");
260 r = CreateDirectoryW( subdir, NULL );
261 ok( r == TRUE, "failed to create directory\n");
263 r = WaitForSingleObject( hdir, 0 );
264 ok( r == WAIT_OBJECT_0, "should be ready\n" );
266 ok(U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "status not successful\n");
267 ok(iosb.Information == 0, "info not set\n");
270 iosb.Information = 0;
272 r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
273 ok(r==STATUS_PENDING, "should status pending\n");
275 r = RemoveDirectoryW( subdir );
276 ok( r == TRUE, "failed to remove directory\n");
278 r = WaitForSingleObject( hEvent, 0 );
279 ok( r == WAIT_OBJECT_0, "should be ready\n" );
281 ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
282 ok(iosb.Information == 0x12, "info not set\n");
285 U(iosb).Status = 0x01234567;
286 iosb.Information = 0x12345678;
287 r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
288 ok(r==STATUS_PENDING, "should status pending\n");
290 U(iosb2).Status = 0x01234567;
291 iosb2.Information = 0x12345678;
292 r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb2,buffer,sizeof buffer,filter,0);
293 ok(r==STATUS_PENDING, "should status pending\n");
295 ok(U(iosb).Status == 0x01234567, "status set too soon\n");
296 ok(iosb.Information == 0x12345678, "info set too soon\n");
299 r = pNtCancelIoFile(hdir, &iosb);
300 ok( r == STATUS_SUCCESS, "cancel failed\n");
304 ok(U(iosb).Status == STATUS_SUCCESS, "status wrong\n");
305 ok(U(iosb2).Status == STATUS_CANCELLED, "status wrong\n");
307 ok(iosb.Information == 0, "info wrong\n");
308 ok(iosb2.Information == 0, "info wrong\n");
310 r = RemoveDirectoryW( path );
311 ok( r == TRUE, "failed to remove directory\n");
318 HMODULE hntdll = GetModuleHandle("ntdll");
321 win_skip("not running on NT, skipping test\n");
325 pNtNotifyChangeDirectoryFile = (fnNtNotifyChangeDirectoryFile)
326 GetProcAddress(hntdll, "NtNotifyChangeDirectoryFile");
327 pNtCancelIoFile = (fnNtCancelIoFile)
328 GetProcAddress(hntdll, "NtCancelIoFile");
330 if (!pNtNotifyChangeDirectoryFile || !pNtCancelIoFile)
332 win_skip("missing functions, skipping test\n");