shell32: Add printers CLSID to test, clean up a bit.
[wine/testsucceed.git] / dlls / ntdll / tests / change.c
blobed7f22c9e618c8f6abddb7d3638edcde48a2b790
1 /*
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
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"
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)
41 NTSTATUS r;
42 HANDLE hdir, hEvent;
43 char buffer[0x1000];
44 DWORD fflags, filter = 0;
45 IO_STATUS_BLOCK iosb;
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");
53 if (!r)
54 return;
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;
91 U(iosb).Status = 1;
92 iosb.Information = 1;
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");
99 U(iosb).Status = 1;
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;
136 U(iosb).Status = 1;
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");
159 CloseHandle(hdir);
160 CloseHandle(hEvent);
162 r = RemoveDirectoryW( path );
163 ok( r == TRUE, "failed to remove directory\n");
167 static void test_ntncdf_async(void)
169 NTSTATUS r;
170 HANDLE hdir, hEvent;
171 char buffer[0x1000];
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");
181 if (!r)
182 return;
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" );
253 /* check APCs */
254 U(iosb).Status = 0;
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");
269 U(iosb).Status = 0;
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");
298 r = pNtCancelIoFile(hdir, &iosb);
299 ok( r == STATUS_SUCCESS, "cancel failed\n");
301 CloseHandle(hdir);
303 ok(U(iosb).Status == STATUS_SUCCESS, "status wrong\n");
304 todo_wine ok(U(iosb2).Status == STATUS_CANCELLED, "status wrong\n");
306 ok(iosb.Information == 0, "info wrong\n");
307 ok(iosb2.Information == 0, "info wrong\n");
309 r = RemoveDirectoryW( path );
310 ok( r == TRUE, "failed to remove directory\n");
312 CloseHandle(hEvent);
315 START_TEST(change)
317 HMODULE hntdll = GetModuleHandle("ntdll");
318 if (!hntdll)
320 win_skip("not running on NT, skipping test\n");
321 return;
324 pNtNotifyChangeDirectoryFile = (fnNtNotifyChangeDirectoryFile)
325 GetProcAddress(hntdll, "NtNotifyChangeDirectoryFile");
326 pNtCancelIoFile = (fnNtCancelIoFile)
327 GetProcAddress(hntdll, "NtCancelIoFile");
329 if (!pNtNotifyChangeDirectoryFile || !pNtCancelIoFile)
331 win_skip("missing functions, skipping test\n");
332 return;
335 test_ntncdf();
336 test_ntncdf_async();