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 static NTSTATUS (WINAPI
*pNtNotifyChangeDirectoryFile
)(
31 HANDLE
,HANDLE
,PIO_APC_ROUTINE
,PVOID
,
32 PIO_STATUS_BLOCK
,PVOID
,ULONG
,ULONG
,BOOLEAN
);
34 static NTSTATUS (WINAPI
*pNtCancelIoFile
)(HANDLE
,PIO_STATUS_BLOCK
);
37 static void test_ntncdf(void)
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 };
47 PFILE_NOTIFY_INFORMATION pfni
;
49 r
= GetTempPathW( MAX_PATH
, path
);
50 ok( r
!= 0, "temp path failed\n");
54 lstrcatW( path
, szBoo
);
55 lstrcpyW( subdir
, path
);
56 lstrcatW( subdir
, szHoo
);
58 RemoveDirectoryW( subdir
);
59 RemoveDirectoryW( path
);
61 r
= CreateDirectoryW(path
, NULL
);
62 ok( r
== TRUE
, "failed to create directory\n");
64 r
= pNtNotifyChangeDirectoryFile(NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,0,0,0);
65 ok(r
==STATUS_ACCESS_VIOLATION
, "should return access violation\n");
67 fflags
= FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OVERLAPPED
;
68 hdir
= CreateFileW(path
, GENERIC_READ
|SYNCHRONIZE
, FILE_SHARE_READ
, NULL
,
69 OPEN_EXISTING
, fflags
, NULL
);
70 ok( hdir
!= INVALID_HANDLE_VALUE
, "failed to open directory\n");
72 hEvent
= CreateEvent( NULL
, 0, 0, NULL
);
74 r
= pNtNotifyChangeDirectoryFile(hdir
,NULL
,NULL
,NULL
,&iosb
,NULL
,0,0,0);
75 ok(r
==STATUS_INVALID_PARAMETER
, "should return invalid parameter\n");
77 r
= pNtNotifyChangeDirectoryFile(hdir
,hEvent
,NULL
,NULL
,&iosb
,NULL
,0,0,0);
78 ok(r
==STATUS_INVALID_PARAMETER
, "should return invalid parameter\n");
80 filter
= FILE_NOTIFY_CHANGE_FILE_NAME
;
81 filter
|= FILE_NOTIFY_CHANGE_DIR_NAME
;
82 filter
|= FILE_NOTIFY_CHANGE_ATTRIBUTES
;
83 filter
|= FILE_NOTIFY_CHANGE_SIZE
;
84 filter
|= FILE_NOTIFY_CHANGE_LAST_WRITE
;
85 filter
|= FILE_NOTIFY_CHANGE_LAST_ACCESS
;
86 filter
|= FILE_NOTIFY_CHANGE_CREATION
;
87 filter
|= FILE_NOTIFY_CHANGE_SECURITY
;
91 r
= pNtNotifyChangeDirectoryFile(hdir
,hEvent
,NULL
,NULL
,&iosb
,buffer
,sizeof buffer
,-1,0);
92 ok(r
==STATUS_INVALID_PARAMETER
, "should return invalid parameter\n");
94 ok( U(iosb
).Status
== 1, "information wrong\n");
95 ok( iosb
.Information
== 1, "information wrong\n");
99 r
= pNtNotifyChangeDirectoryFile(hdir
,hEvent
,NULL
,NULL
,&iosb
,buffer
,sizeof buffer
,filter
,0);
100 ok(r
==STATUS_PENDING
, "should return status pending\n");
102 r
= WaitForSingleObject( hEvent
, 0 );
103 ok( r
== STATUS_TIMEOUT
, "should timeout\n" );
105 r
= WaitForSingleObject( hdir
, 0 );
106 ok( r
== STATUS_TIMEOUT
, "should timeout\n" );
108 r
= CreateDirectoryW( subdir
, NULL
);
109 ok( r
== TRUE
, "failed to create directory\n");
111 r
= WaitForSingleObject( hdir
, 0 );
112 ok( r
== STATUS_TIMEOUT
, "should timeout\n" );
114 r
= WaitForSingleObject( hEvent
, 0 );
115 ok( r
== WAIT_OBJECT_0
, "event should be ready\n" );
117 ok( U(iosb
).Status
== STATUS_SUCCESS
, "information wrong\n");
118 ok( iosb
.Information
== 0x12, "information wrong\n");
120 pfni
= (PFILE_NOTIFY_INFORMATION
) buffer
;
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" );
126 r
= pNtNotifyChangeDirectoryFile(hdir
,0,NULL
,NULL
,&iosb
,buffer
,sizeof buffer
,0,0);
127 ok(r
==STATUS_INVALID_PARAMETER
, "should return invalid parameter\n");
129 r
= pNtNotifyChangeDirectoryFile(hdir
,hEvent
,NULL
,NULL
,&iosb
,buffer
,sizeof buffer
,0,0);
130 ok(r
==STATUS_INVALID_PARAMETER
, "should return invalid parameter\n");
132 filter
= FILE_NOTIFY_CHANGE_SIZE
;
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");
139 ok( U(iosb
).Status
== 1, "information wrong\n");
140 ok( iosb
.Information
== 1, "information wrong\n");
142 r
= WaitForSingleObject( hdir
, 0 );
143 ok( r
== STATUS_TIMEOUT
, "should timeout\n" );
145 r
= RemoveDirectoryW( subdir
);
146 ok( r
== TRUE
, "failed to remove directory\n");
148 r
= WaitForSingleObject( hdir
, 100 );
149 ok( r
== WAIT_OBJECT_0
, "should be ready\n" );
151 r
= WaitForSingleObject( hdir
, 100 );
152 ok( r
== WAIT_OBJECT_0
, "should be ready\n" );
154 ok( U(iosb
).Status
== STATUS_NOTIFY_ENUM_DIR
, "information wrong\n");
155 ok( iosb
.Information
== 0, "information wrong\n");
160 r
= RemoveDirectoryW( path
);
161 ok( r
== TRUE
, "failed to remove directory\n");
165 static void test_ntncdf_async(void)
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 };
175 PFILE_NOTIFY_INFORMATION pfni
;
177 r
= GetTempPathW( MAX_PATH
, path
);
178 ok( r
!= 0, "temp path failed\n");
182 lstrcatW( path
, szBoo
);
183 lstrcpyW( subdir
, path
);
184 lstrcatW( subdir
, szHoo
);
186 RemoveDirectoryW( subdir
);
187 RemoveDirectoryW( path
);
189 r
= CreateDirectoryW(path
, NULL
);
190 ok( r
== TRUE
, "failed to create directory\n");
192 r
= pNtNotifyChangeDirectoryFile(NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,0,0,0);
193 ok(r
==STATUS_ACCESS_VIOLATION
, "should return access violation\n");
195 fflags
= FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OVERLAPPED
;
196 hdir
= CreateFileW(path
, GENERIC_READ
|SYNCHRONIZE
, FILE_SHARE_READ
, NULL
,
197 OPEN_EXISTING
, fflags
, NULL
);
198 ok( hdir
!= INVALID_HANDLE_VALUE
, "failed to open directory\n");
200 hEvent
= CreateEvent( NULL
, 0, 0, NULL
);
202 filter
= FILE_NOTIFY_CHANGE_FILE_NAME
;
203 filter
|= FILE_NOTIFY_CHANGE_DIR_NAME
;
204 filter
|= FILE_NOTIFY_CHANGE_ATTRIBUTES
;
205 filter
|= FILE_NOTIFY_CHANGE_SIZE
;
206 filter
|= FILE_NOTIFY_CHANGE_LAST_WRITE
;
207 filter
|= FILE_NOTIFY_CHANGE_LAST_ACCESS
;
208 filter
|= FILE_NOTIFY_CHANGE_CREATION
;
209 filter
|= FILE_NOTIFY_CHANGE_SECURITY
;
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");
219 r
= CreateDirectoryW( subdir
, NULL
);
220 ok( r
== TRUE
, "failed to create directory\n");
222 r
= WaitForSingleObject( hdir
, 100 );
223 ok( r
== WAIT_OBJECT_0
, "should be ready\n" );
225 ok(U(iosb
).Status
== STATUS_SUCCESS
, "status not successful\n");
226 ok(iosb
.Information
== 0x12, "info not set\n");
228 pfni
= (PFILE_NOTIFY_INFORMATION
) buffer
;
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" );
234 r
= pNtNotifyChangeDirectoryFile(hdir
,0,NULL
,NULL
,&iosb
,buffer
,sizeof buffer
,filter
,0);
235 ok(r
==STATUS_PENDING
, "should status pending\n");
237 r
= RemoveDirectoryW( subdir
);
238 ok( r
== TRUE
, "failed to remove directory\n");
240 r
= WaitForSingleObject( hdir
, 0 );
241 ok( r
== WAIT_OBJECT_0
, "should be ready\n" );
243 ok(U(iosb
).Status
== STATUS_SUCCESS
, "status not successful\n");
244 ok(iosb
.Information
== 0x12, "info not set\n");
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" );
253 iosb
.Information
= 0;
255 r
= pNtNotifyChangeDirectoryFile(hdir
,0,NULL
,NULL
,&iosb
,NULL
,0,filter
,0);
256 ok(r
==STATUS_PENDING
, "should status pending\n");
258 r
= CreateDirectoryW( subdir
, NULL
);
259 ok( r
== TRUE
, "failed to create directory\n");
261 r
= WaitForSingleObject( hdir
, 0 );
262 ok( r
== WAIT_OBJECT_0
, "should be ready\n" );
264 ok(U(iosb
).Status
== STATUS_NOTIFY_ENUM_DIR
, "status not successful\n");
265 ok(iosb
.Information
== 0, "info not set\n");
268 iosb
.Information
= 0;
270 r
= pNtNotifyChangeDirectoryFile(hdir
,hEvent
,NULL
,NULL
,&iosb
,buffer
,sizeof buffer
,filter
,0);
271 ok(r
==STATUS_PENDING
, "should status pending\n");
273 r
= RemoveDirectoryW( subdir
);
274 ok( r
== TRUE
, "failed to remove directory\n");
276 r
= WaitForSingleObject( hEvent
, 0 );
277 ok( r
== WAIT_OBJECT_0
, "should be ready\n" );
279 ok(U(iosb
).Status
== STATUS_SUCCESS
, "status not successful\n");
280 ok(iosb
.Information
== 0x12, "info not set\n");
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");
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");
293 ok(U(iosb
).Status
== 0x01234567, "status set too soon\n");
294 ok(iosb
.Information
== 0x12345678, "info set too soon\n");
296 r
= pNtCancelIoFile(hdir
, &iosb
);
297 ok( r
== STATUS_SUCCESS
, "cancel failed\n");
301 ok(U(iosb
).Status
== STATUS_SUCCESS
, "status wrong\n");
302 todo_wine
ok(U(iosb2
).Status
== STATUS_CANCELLED
, "status wrong\n");
304 ok(iosb
.Information
== 0, "info wrong\n");
305 ok(iosb2
.Information
== 0, "info wrong\n");
307 r
= RemoveDirectoryW( path
);
308 ok( r
== TRUE
, "failed to remove directory\n");
315 HMODULE hntdll
= GetModuleHandle("ntdll");
318 win_skip("not running on NT, skipping test\n");
322 pNtNotifyChangeDirectoryFile
= (void *)GetProcAddress(hntdll
, "NtNotifyChangeDirectoryFile");
323 pNtCancelIoFile
= (void *)GetProcAddress(hntdll
, "NtCancelIoFile");
325 if (!pNtNotifyChangeDirectoryFile
|| !pNtCancelIoFile
)
327 win_skip("missing functions, skipping test\n");