ReactOS 0.4.16-dev-197-g92996da
change.c
Go to the documentation of this file.
1/*
2 * Tests for file change notification functions
3 *
4 * Copyright (c) 2004 Hans Leidekker
5 * Copyright 2006 Mike McCormack for CodeWeavers
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22/* TODO: - security attribute changes
23 * - compound filter and multiple notifications
24 * - subtree notifications
25 * - non-documented flags FILE_NOTIFY_CHANGE_LAST_ACCESS and
26 * FILE_NOTIFY_CHANGE_CREATION
27 */
28
29#include <stdarg.h>
30#include <stdio.h>
31
32#include "ntstatus.h"
33#define WIN32_NO_STATUS
34#include "wine/test.h"
35#include <windef.h>
36#include <winbase.h>
37#include <winternl.h>
38
40{
41 HANDLE change = arg;
43 BOOL ret = FALSE;
45
46 status = WaitForSingleObject(change, 100);
47
48 if (status == WAIT_OBJECT_0 ) {
49 notified = TRUE;
51 }
52
54 ok( ret, "FindCloseChangeNotification error: %d\n",
55 GetLastError());
56
58}
59
61{
62 HANDLE change, thread;
63 DWORD threadId;
64
65 change = FindFirstChangeNotificationA(path, subtree, flags);
66 ok(change != INVALID_HANDLE_VALUE, "FindFirstChangeNotification error: %d\n", GetLastError());
67
68 thread = CreateThread(NULL, 0, NotificationThread, change, 0, &threadId);
69 ok(thread != NULL, "CreateThread error: %d\n", GetLastError());
70
71 return thread;
72}
73
75{
76 DWORD status, exitcode;
77
79 ok(status == WAIT_OBJECT_0, "WaitForSingleObject status %d error %d\n", status, GetLastError());
80
81 ok(GetExitCodeThread(thread, &exitcode), "Could not retrieve thread exit code\n");
83
84 return exitcode;
85}
86
88{
89 HANDLE change, file, thread;
90 DWORD attributes, count;
91 BOOL ret;
92
93 char workdir[MAX_PATH], dirname1[MAX_PATH], dirname2[MAX_PATH];
94 char filename1[MAX_PATH], filename2[MAX_PATH];
95 static const char prefix[] = "FCN";
96 char buffer[2048];
97
98 /* pathetic checks */
99
101 ok(change == INVALID_HANDLE_VALUE, "Expected INVALID_HANDLE_VALUE, got %p\n", change);
103 GetLastError() == ERROR_NO_MORE_FILES, /* win95 */
104 "FindFirstChangeNotification error: %d\n", GetLastError());
105
106 if (0) /* This documents win2k behavior. It crashes on win98. */
107 {
109 ok(change == NULL && GetLastError() == ERROR_PATH_NOT_FOUND,
110 "FindFirstChangeNotification error: %d\n", GetLastError());
111 }
112
114 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindNextChangeNotification error: %d\n",
115 GetLastError());
116
118 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindCloseChangeNotification error: %d\n",
119 GetLastError());
120
122 ok(ret, "GetTempPathA error: %d\n", GetLastError());
123
124 lstrcatA(workdir, "testFileChangeNotification");
125
127 ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
128
129 ret = GetTempFileNameA(workdir, prefix, 0, filename1);
130 ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
131
134 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %d\n", GetLastError());
136 ok( ret, "CloseHandle error: %d\n", GetLastError());
137
138 /* Try to register notification for a file. win98 and win2k behave differently here */
142 "FindFirstChangeNotification error: %d\n", GetLastError());
143
144 lstrcpyA(dirname1, filename1);
145 lstrcatA(dirname1, "dir");
146
147 lstrcpyA(dirname2, dirname1);
148 lstrcatA(dirname2, "new");
149
150 ret = CreateDirectoryA(dirname1, NULL);
151 ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
152
153 /* What if we move the directory we registered notification for? */
155 ret = MoveFileA(dirname1, dirname2);
156 ok(ret, "MoveFileA error: %d\n", GetLastError());
157 /* win9x and win2k behave differently here, don't check result */
159
160 /* What if we remove the directory we registered notification for? */
162 ret = RemoveDirectoryA(dirname2);
163 ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
164 /* win9x and win2k behave differently here, don't check result */
166
167 /* functional checks */
168
169 /* Create a directory */
171 ret = CreateDirectoryA(dirname1, NULL);
172 ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
173 ok(FinishNotificationThread(thread), "Missed notification\n");
174
175 /* Rename a directory */
177 ret = MoveFileA(dirname1, dirname2);
178 ok(ret, "MoveFileA error: %d\n", GetLastError());
179 ok(FinishNotificationThread(thread), "Missed notification\n");
180
181 /* Delete a directory */
183 ret = RemoveDirectoryA(dirname2);
184 ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
185 ok(FinishNotificationThread(thread), "Missed notification\n");
186
187 lstrcpyA(filename2, filename1);
188 lstrcatA(filename2, "new");
189
190 /* Rename a file */
192 ret = MoveFileA(filename1, filename2);
193 ok(ret, "MoveFileA error: %d\n", GetLastError());
194 ok(FinishNotificationThread(thread), "Missed notification\n");
195
196 /* Delete a file */
199 ok(ret, "DeleteFileA error: %d\n", GetLastError());
200 ok(FinishNotificationThread(thread), "Missed notification\n");
201
202 /* Create a file */
206 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %d\n", GetLastError());
208 ok( ret, "CloseHandle error: %d\n", GetLastError());
209 ok(FinishNotificationThread(thread), "Missed notification\n");
210
211 attributes = GetFileAttributesA(filename2);
212 ok(attributes != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA error: %d\n", GetLastError());
213 attributes &= FILE_ATTRIBUTE_READONLY;
214
215 /* Change file attributes */
217 ret = SetFileAttributesA(filename2, attributes);
218 ok(ret, "SetFileAttributesA error: %d\n", GetLastError());
219 ok(FinishNotificationThread(thread), "Missed notification\n");
220
221 /* Change last write time by writing to a file */
225 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %d\n", GetLastError());
226 memset(buffer, 0, sizeof(buffer));
227 ret = WriteFile(file, buffer, sizeof(buffer), &count, NULL);
228 ok(ret && count == sizeof(buffer), "WriteFile error: %d\n", GetLastError());
230 ok( ret, "CloseHandle error: %d\n", GetLastError());
231 ok(FinishNotificationThread(thread), "Missed notification\n");
232
233 /* Change file size by truncating a file */
237 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %d\n", GetLastError());
238 ret = WriteFile(file, buffer, sizeof(buffer) / 2, &count, NULL);
239 ok(ret && count == sizeof(buffer) / 2, "WriteFileA error: %d\n", GetLastError());
241 ok( ret, "CloseHandle error: %d\n", GetLastError());
242 ok(FinishNotificationThread(thread), "Missed notification\n");
243
244 /* clean up */
245
247 ok(ret, "DeleteFileA error: %d\n", GetLastError());
248
250 ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
251}
252
253/* this test concentrates more on the wait behaviour of the handle */
254static void test_ffcn(void)
255{
258 LONG r;
259 WCHAR path[MAX_PATH], subdir[MAX_PATH];
260 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
261 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
262
263 SetLastError(0xdeadbeef);
266 {
267 win_skip("GetTempPathW is not implemented\n");
268 return;
269 }
270 ok( r != 0, "temp path failed\n");
271 if (!r)
272 return;
273
274 lstrcatW( path, szBoo );
275 lstrcpyW( subdir, path );
276 lstrcatW( subdir, szHoo );
277
278 RemoveDirectoryW( subdir );
280
282 ok( r == TRUE, "failed to create directory\n");
283
286
288 ok( handle != INVALID_HANDLE_VALUE, "invalid handle\n");
289
291 ok( r == STATUS_TIMEOUT, "should time out\n");
292
293 r = CreateDirectoryW( subdir, NULL );
294 ok( r == TRUE, "failed to create subdir\n");
295
297 ok( r == WAIT_OBJECT_0, "should be ready\n");
298
300 ok( r == WAIT_OBJECT_0, "should be ready\n");
301
303 ok( r == TRUE, "find next failed\n");
304
306 ok( r == STATUS_TIMEOUT, "should time out\n");
307
308 r = RemoveDirectoryW( subdir );
309 ok( r == TRUE, "failed to remove subdir\n");
310
312 ok( r == WAIT_OBJECT_0, "should be ready\n");
313
315 ok( r == WAIT_OBJECT_0, "should be ready\n");
316
318 ok( r == TRUE, "find next failed\n");
319
321 ok( r == TRUE, "find next failed\n");
322
324 ok( r == TRUE, "should succeed\n");
325
327 ok( r == TRUE, "failed to remove dir\n");
328}
329
330/* this test concentrates on the wait behavior when multiple threads are
331 * waiting on a change notification handle. */
333{
334 LONG r;
335 DWORD filter, threadId, status, exitcode;
336 HANDLE handles[2];
337 char path[MAX_PATH];
338
340 ok(r, "GetTempPathA error: %d\n", GetLastError());
341
342 lstrcatA(path, "ffcnTestMultipleThreads");
343
345
347 ok(r, "CreateDirectoryA error: %d\n", GetLastError());
348
351
353 ok(handles[0] != INVALID_HANDLE_VALUE, "FindFirstChangeNotification error: %d\n", GetLastError());
354
355 /* Test behavior if a waiting thread holds the last reference to a change
356 * directory object with an empty wine user APC queue for this thread (bug #7286) */
357
358 /* Create our notification thread */
360 &threadId);
361 ok(handles[1] != NULL, "CreateThread error: %d\n", GetLastError());
362
364 ok(status == WAIT_OBJECT_0 || status == WAIT_OBJECT_0+1, "WaitForMultipleObjects status %d error %d\n", status, GetLastError());
365 ok(GetExitCodeThread(handles[1], &exitcode), "Could not retrieve thread exit code\n");
366
367 /* Clean up */
369 ok( r == TRUE, "failed to remove dir\n");
370}
371
372static BOOL (WINAPI *pReadDirectoryChangesW)(HANDLE,LPVOID,DWORD,BOOL,DWORD,
374
376{
377 HANDLE hdir;
378 char buffer[0x1000];
379 DWORD fflags, filter = 0, r, dwCount;
380 OVERLAPPED ov;
381 WCHAR path[MAX_PATH], subdir[MAX_PATH], subsubdir[MAX_PATH];
382 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
383 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
384 static const WCHAR szGa[] = { '\\','h','o','o','\\','g','a',0 };
386 BOOL got_subdir_change = FALSE;
387
388 if (!pReadDirectoryChangesW)
389 {
390 win_skip("ReadDirectoryChangesW is not available\n");
391 return;
392 }
393
394 SetLastError(0xdeadbeef);
397 {
398 win_skip("GetTempPathW is not implemented\n");
399 return;
400 }
401 ok( r != 0, "temp path failed\n");
402 if (!r)
403 return;
404
405 lstrcatW( path, szBoo );
406 lstrcpyW( subdir, path );
407 lstrcatW( subdir, szHoo );
408
409 lstrcpyW( subsubdir, path );
410 lstrcatW( subsubdir, szGa );
411
412 RemoveDirectoryW( subsubdir );
413 RemoveDirectoryW( subdir );
415
417 ok( r == TRUE, "failed to create directory\n");
418
419 SetLastError(0xd0b00b00);
420 r = pReadDirectoryChangesW(NULL,NULL,0,FALSE,0,NULL,NULL,NULL);
421 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
422 ok(r==FALSE, "should return false\n");
423
427 OPEN_EXISTING, fflags, NULL);
428 ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
429
430 ov.hEvent = CreateEventW( NULL, 1, 0, NULL );
431
432 SetLastError(0xd0b00b00);
433 r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,0,NULL,NULL,NULL);
434 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
435 ok(r==FALSE, "should return false\n");
436
437 SetLastError(0xd0b00b00);
438 r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,0,NULL,&ov,NULL);
439 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
440 ok(r==FALSE, "should return false\n");
441
450
451 SetLastError(0xd0b00b00);
452 ov.Internal = 0;
453 ov.InternalHigh = 0;
454 memset( buffer, 0, sizeof buffer );
455
456 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,-1,NULL,&ov,NULL);
457 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
458 ok(r==FALSE, "should return false\n");
459
460 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,&ov,NULL);
461 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
462 ok(r==FALSE, "should return false\n");
463
464 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,TRUE,filter,NULL,&ov,NULL);
465 ok(r==TRUE, "should return true\n");
466
467 r = WaitForSingleObject( ov.hEvent, 10 );
468 ok( r == STATUS_TIMEOUT, "should timeout\n" );
469
470 r = CreateDirectoryW( subdir, NULL );
471 ok( r == TRUE, "failed to create directory\n");
472
473 r = WaitForSingleObject( ov.hEvent, 1000 );
474 ok( r == WAIT_OBJECT_0, "event should be ready\n" );
475
476 ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
477 ok( ov.InternalHigh == 0x12, "ov.InternalHigh wrong\n");
478
480 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
481 ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
482 ok( pfni->FileNameLength == 6, "len wrong\n" );
483 ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
484
485 ResetEvent(ov.hEvent);
486 SetLastError(0xd0b00b00);
487 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,NULL,NULL);
488 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
489 ok(r==FALSE, "should return false\n");
490
491 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,&ov,NULL);
492 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
493 ok(r==FALSE, "should return false\n");
494
496
497 SetEvent(ov.hEvent);
498 ov.Internal = 1;
499 ov.InternalHigh = 1;
500 S(U(ov)).Offset = 0;
501 S(U(ov)).OffsetHigh = 0;
502 memset( buffer, 0, sizeof buffer );
503 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
504 ok(r==TRUE, "should return true\n");
505
506 ok( (NTSTATUS)ov.Internal == STATUS_PENDING, "ov.Internal wrong\n");
507 ok( ov.InternalHigh == 1, "ov.InternalHigh wrong\n");
508
509 r = WaitForSingleObject( ov.hEvent, 0 );
510 ok( r == STATUS_TIMEOUT, "should timeout\n" );
511
512 r = RemoveDirectoryW( subdir );
513 ok( r == TRUE, "failed to remove directory\n");
514
515 r = WaitForSingleObject( ov.hEvent, 1000 );
516 ok( r == WAIT_OBJECT_0, "should be ready\n" );
517
518 ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
519 ok( ov.InternalHigh == 0x12, "ov.InternalHigh wrong\n");
520
522 {
523 r = GetOverlappedResult( hdir, &ov, &dwCount, TRUE );
524 ok( r == TRUE, "getoverlappedresult failed\n");
525 ok( dwCount == 0x12, "count wrong\n");
526 }
527
529 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
530 ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong\n" );
531 ok( pfni->FileNameLength == 6, "len wrong\n" );
532 ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
533
534 /* what happens if the buffer is too small? */
535 r = pReadDirectoryChangesW(hdir,buffer,0x10,FALSE,filter,NULL,&ov,NULL);
536 ok(r==TRUE, "should return true\n");
537
538 r = CreateDirectoryW( subdir, NULL );
539 ok( r == TRUE, "failed to create directory\n");
540
541 r = WaitForSingleObject( ov.hEvent, 1000 );
542 ok( r == WAIT_OBJECT_0, "should be ready\n" );
543
544 ok( (NTSTATUS)ov.Internal == STATUS_NOTIFY_ENUM_DIR, "ov.Internal wrong\n");
545 ok( ov.InternalHigh == 0, "ov.InternalHigh wrong\n");
546
547 /* test the recursive watch */
548 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
549 ok(r==TRUE, "should return true\n");
550
551 r = CreateDirectoryW( subsubdir, NULL );
552 ok( r == TRUE, "failed to create directory\n");
553
554 while (1)
555 {
556 r = WaitForSingleObject( ov.hEvent, 1000 );
557 ok(r == WAIT_OBJECT_0, "should be ready\n" );
558 if (r == WAIT_TIMEOUT) break;
559
560 ok((NTSTATUS) ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
561
563 while (1)
564 {
565 /* We might get one or more modified events on the parent dir */
566 if (pfni->Action == FILE_ACTION_MODIFIED)
567 {
568 ok(pfni->FileNameLength == 3 * sizeof(WCHAR), "len wrong\n" );
569 ok(!memcmp(pfni->FileName, &szGa[1], 3 * sizeof(WCHAR)), "name wrong\n");
570 }
571 else
572 {
573 ok(pfni->Action == FILE_ACTION_ADDED, "action wrong\n");
574 ok(pfni->FileNameLength == 6 * sizeof(WCHAR), "len wrong\n" );
575 ok(!memcmp(pfni->FileName, &szGa[1], 6 * sizeof(WCHAR)), "name wrong\n");
576 got_subdir_change = TRUE;
577 }
578 if (!pfni->NextEntryOffset) break;
579 pfni = (PFILE_NOTIFY_INFORMATION)((char *)pfni + pfni->NextEntryOffset);
580 }
581
582 if (got_subdir_change) break;
583
584 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
585 ok(r==TRUE, "should return true\n");
586 }
587 ok(got_subdir_change, "didn't get subdir change\n");
588
589 r = RemoveDirectoryW( subsubdir );
590 ok( r == TRUE, "failed to remove directory\n");
591
592 ov.Internal = 1;
593 ov.InternalHigh = 1;
594 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
595 ok(r==TRUE, "should return true\n");
596
597 r = RemoveDirectoryW( subdir );
598 ok( r == TRUE, "failed to remove directory\n");
599
600 r = WaitForSingleObject( ov.hEvent, 1000 );
601 ok( r == WAIT_OBJECT_0, "should be ready\n" );
602
604 /* we may get a notification for the parent dir too */
605 if (pfni->Action == FILE_ACTION_MODIFIED && pfni->NextEntryOffset)
606 {
607 ok( pfni->FileNameLength == 3*sizeof(WCHAR), "len wrong %u\n", pfni->FileNameLength );
608 ok( !memcmp(pfni->FileName,&szGa[1],3*sizeof(WCHAR)), "name wrong\n" );
609 pfni = (PFILE_NOTIFY_INFORMATION)((char *)pfni + pfni->NextEntryOffset);
610 }
611 ok( pfni->NextEntryOffset == 0, "offset wrong %u\n", pfni->NextEntryOffset );
612 ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong %u\n", pfni->Action );
613 ok( pfni->FileNameLength == 6*sizeof(WCHAR), "len wrong %u\n", pfni->FileNameLength );
614 ok( !memcmp(pfni->FileName,&szGa[1],6*sizeof(WCHAR)), "name wrong\n" );
615
616 ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
617 dwCount = (char *)&pfni->FileName[pfni->FileNameLength/sizeof(WCHAR)] - buffer;
618 ok( ov.InternalHigh == dwCount, "ov.InternalHigh wrong %lu/%u\n",ov.InternalHigh, dwCount );
619
620 CloseHandle(hdir);
621
623 ok( r == TRUE, "failed to remove directory\n");
624}
625
626/* show the behaviour when a null buffer is passed */
628{
629 NTSTATUS r;
630 HANDLE hdir;
631 char buffer[0x1000];
632 DWORD fflags, filter = 0;
633 OVERLAPPED ov;
634 WCHAR path[MAX_PATH], subdir[MAX_PATH];
635 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
636 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
638
639 if (!pReadDirectoryChangesW)
640 {
641 win_skip("ReadDirectoryChangesW is not available\n");
642 return;
643 }
644 SetLastError(0xdeadbeef);
647 {
648 win_skip("GetTempPathW is not implemented\n");
649 return;
650 }
651 ok( r != 0, "temp path failed\n");
652 if (!r)
653 return;
654
655 lstrcatW( path, szBoo );
656 lstrcpyW( subdir, path );
657 lstrcatW( subdir, szHoo );
658
659 RemoveDirectoryW( subdir );
661
663 ok( r == TRUE, "failed to create directory\n");
664
668 OPEN_EXISTING, fflags, NULL);
669 ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
670
671 ov.hEvent = CreateEventW( NULL, 1, 0, NULL );
672
675
676 SetLastError(0xd0b00b00);
677 ov.Internal = 0;
678 ov.InternalHigh = 0;
679 memset( buffer, 0, sizeof buffer );
680
681 r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,filter,NULL,&ov,NULL);
682 ok(r==TRUE, "should return true\n");
683
684 r = WaitForSingleObject( ov.hEvent, 0 );
685 ok( r == STATUS_TIMEOUT, "should timeout\n" );
686
687 r = CreateDirectoryW( subdir, NULL );
688 ok( r == TRUE, "failed to create directory\n");
689
690 r = WaitForSingleObject( ov.hEvent, 0 );
691 ok( r == WAIT_OBJECT_0, "event should be ready\n" );
692
693 ok( (NTSTATUS)ov.Internal == STATUS_NOTIFY_ENUM_DIR, "ov.Internal wrong\n");
694 ok( ov.InternalHigh == 0, "ov.InternalHigh wrong\n");
695
696 ov.Internal = 0;
697 ov.InternalHigh = 0;
698 S(U(ov)).Offset = 0;
699 S(U(ov)).OffsetHigh = 0;
700 memset( buffer, 0, sizeof buffer );
701
702 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
703 ok(r==TRUE, "should return true\n");
704
705 r = WaitForSingleObject( ov.hEvent, 0 );
706 ok( r == STATUS_TIMEOUT, "should timeout\n" );
707
708 r = RemoveDirectoryW( subdir );
709 ok( r == TRUE, "failed to remove directory\n");
710
711 r = WaitForSingleObject( ov.hEvent, 1000 );
712 ok( r == WAIT_OBJECT_0, "should be ready\n" );
713
714 ok( (NTSTATUS)ov.Internal == STATUS_NOTIFY_ENUM_DIR, "ov.Internal wrong\n");
715 ok( ov.InternalHigh == 0, "ov.InternalHigh wrong\n");
716
718 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
719
720 CloseHandle(hdir);
721
723 ok( r == TRUE, "failed to remove directory\n");
724}
725
727{
728 NTSTATUS r;
729 HANDLE hdir, hfile;
730 char buffer[0x1000];
731 DWORD fflags, filter = 0;
732 OVERLAPPED ov;
734 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
735 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
736 static const WCHAR szFoo[] = { '\\','f','o','o',0 };
738
739 SetLastError(0xdeadbeef);
742 {
743 win_skip("GetTempPathW is not implemented\n");
744 return;
745 }
746 ok( r != 0, "temp path failed\n");
747 if (!r)
748 return;
749
750 lstrcatW( path, szBoo );
751 lstrcpyW( subdir, path );
752 lstrcatW( subdir, szHoo );
753
754 lstrcpyW( file, path );
755 lstrcatW( file, szFoo );
756
757 DeleteFileW( file );
758 RemoveDirectoryW( subdir );
760
762 ok( r == TRUE, "failed to create directory\n");
763
767 OPEN_EXISTING, fflags, NULL);
768 ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
769
770 ov.hEvent = CreateEventW( NULL, 0, 0, NULL );
771
773
774 r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,TRUE,filter,NULL,&ov,NULL);
775 ok(r==TRUE, "should return true\n");
776
777 r = WaitForSingleObject( ov.hEvent, 10 );
778 ok( r == WAIT_TIMEOUT, "should timeout\n" );
779
780 r = CreateDirectoryW( subdir, NULL );
781 ok( r == TRUE, "failed to create directory\n");
782
784 ok( hfile != INVALID_HANDLE_VALUE, "failed to create file\n");
785 ok( CloseHandle(hfile), "failed to close file\n");
786
787 r = WaitForSingleObject( ov.hEvent, 1000 );
788 ok( r == WAIT_OBJECT_0, "event should be ready\n" );
789
790 ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
791 ok( ov.InternalHigh == 0x12, "ov.InternalHigh wrong\n");
792
794 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
795 ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
796 ok( pfni->FileNameLength == 6, "len wrong\n" );
797 ok( !memcmp(pfni->FileName,&szFoo[1],6), "name wrong\n" );
798
799 r = DeleteFileW( file );
800 ok( r == TRUE, "failed to delete file\n");
801
802 r = RemoveDirectoryW( subdir );
803 ok( r == TRUE, "failed to remove directory\n");
804
805 CloseHandle(hdir);
806
808 ok( r == TRUE, "failed to remove directory\n");
809}
810
812{
813 ok(error == 0, "ReadDirectoryChangesW error %d\n", error);
814 ok(ov->hEvent == (void*)0xdeadbeef, "hEvent should not have changed\n");
815}
816
818{
819 static const WCHAR szBoo[] = { '\\','b','o','o','\\',0 };
820 static const WCHAR szDir[] = { 'd','i','r',0 };
821 static const WCHAR szFile[] = { 'f','i','l','e',0 };
822 static const WCHAR szBackslash[] = { '\\',0 };
823
825 FILE_NOTIFY_INFORMATION fni[1024], *fni_next;
826 OVERLAPPED ov;
827 HANDLE hdir, hfile;
828 NTSTATUS r;
829
830 if (!pReadDirectoryChangesW)
831 {
832 win_skip("ReadDirectoryChangesW is not available\n");
833 return;
834 }
835
836 SetLastError(0xdeadbeef);
839 {
840 win_skip("GetTempPathW is not implemented\n");
841 return;
842 }
843 ok(r != 0, "temp path failed\n");
844 if (!r)
845 return;
846
847 lstrcatW(path, szBoo);
848 lstrcpyW(dir, path);
849 lstrcatW(dir, szDir);
851 lstrcatW(file, szFile);
852 lstrcpyW(sub_file, dir);
853 lstrcatW(sub_file, szBackslash);
854 lstrcatW(sub_file, szFile);
855
859
861 ok(r == TRUE, "failed to create directory\n");
862
866 ok(hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
867
868 memset(&ov, 0, sizeof(ov));
869 ov.hEvent = (void*)0xdeadbeef;
870 r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
872 ok(r == TRUE, "pReadDirectoryChangesW failed\n");
873
875 ok(hfile != INVALID_HANDLE_VALUE, "failed to create file\n");
876 CloseHandle(hfile);
877
878 r = SleepEx(1000, TRUE);
879 ok(r != 0, "failed to receive file creation event\n");
880 ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
881 ok(fni->Action == FILE_ACTION_ADDED, "Action = %d\n", fni->Action);
882 ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
883 "FileNameLength = %d\n", fni->FileNameLength);
884 ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
885 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
886
887 r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
889 ok(r == TRUE, "pReadDirectoryChangesW failed\n");
890
891 /* This event will not be reported */
893 ok(r == TRUE, "failed to create directory\n");
894
895 r = MoveFileW(file, sub_file);
896 ok(r == TRUE, "failed to move file\n");
897
898 r = SleepEx(1000, TRUE);
899 ok(r != 0, "failed to receive file move event\n");
900 ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
901 ok(fni->Action == FILE_ACTION_REMOVED, "Action = %d\n", fni->Action);
902 ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
903 "FileNameLength = %d\n", fni->FileNameLength);
904 ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
905 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
906
907 r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
909 ok(r == TRUE, "pReadDirectoryChangesW failed\n");
910
911 r = MoveFileW(sub_file, file);
912 ok(r == TRUE, "failed to move file\n");
913
914 r = SleepEx(1000, TRUE);
915 ok(r != 0, "failed to receive file move event\n");
916 ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
917 ok(fni->Action == FILE_ACTION_ADDED, "Action = %d\n", fni->Action);
918 ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
919 "FileNameLength = %d\n", fni->FileNameLength);
920 ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
921 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
922
923 r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
925 ok(r == TRUE, "pReadDirectoryChangesW failed\n");
926
927 r = DeleteFileW(file);
928 ok(r == TRUE, "failed to delete file\n");
929
930 r = SleepEx(1000, TRUE);
931 ok(r != 0, "failed to receive file removal event\n");
932 ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
933 ok(fni->Action == FILE_ACTION_REMOVED, "Action = %d\n", fni->Action);
934 ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
935 "FileNameLength = %d\n", fni->FileNameLength);
936 ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
937 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
938
939 CloseHandle(hdir);
940
944 ok(hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
945
946 r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
948 ok(r == TRUE, "pReadDirectoryChangesW failed\n");
949
950 r = MoveFileW(dir, file);
951 ok(r == TRUE, "failed to move directory\n");
952
953 r = SleepEx(1000, TRUE);
954 ok(r != 0, "failed to receive directory move event\n");
956 {
957 ok(fni->Action == FILE_ACTION_RENAMED_OLD_NAME, "Action = %d\n", fni->Action);
958 ok(fni->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR),
959 "FileNameLength = %d\n", fni->FileNameLength);
960 ok(!memcmp(fni->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)),
961 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
962 ok(fni->NextEntryOffset != 0, "no next entry in movement event\n");
963 fni_next = (FILE_NOTIFY_INFORMATION*)((char*)fni+fni->NextEntryOffset);
964 ok(fni_next->NextEntryOffset == 0, "there should be no more events in buffer\n");
965 ok(fni_next->Action == FILE_ACTION_RENAMED_NEW_NAME, "Action = %d\n", fni_next->Action);
966 ok(fni_next->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
967 "FileNameLength = %d\n", fni_next->FileNameLength);
968 ok(!memcmp(fni_next->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
969 "FileName = %s\n", wine_dbgstr_wn(fni_next->FileName, fni_next->FileNameLength/sizeof(WCHAR)));
970 }
971 else
972 {
973 todo_wine ok(0, "Expected rename event\n");
974
975 if (fni->NextEntryOffset == 0)
976 {
977 r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
979 ok(r == TRUE, "pReadDirectoryChangesW failed\n");
980
981 r = SleepEx(1000, TRUE);
982 ok(r != 0, "failed to receive directory move event\n");
983 }
984 }
985
987 ok(r == TRUE, "failed to create directory\n");
988
990 ok(r == TRUE, "failed to remove directory\n");
991
992 r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
994 ok(r == TRUE, "pReadDirectoryChangesW failed\n");
995
996 r = SleepEx(1000, TRUE);
997 ok(r != 0, "failed to receive directory creation event\n");
998 ok(fni->Action == FILE_ACTION_ADDED, "Action = %d\n", fni->Action);
999 ok(fni->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR),
1000 "FileNameLength = %d\n", fni->FileNameLength);
1001 ok(!memcmp(fni->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)),
1002 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
1003 if (fni->NextEntryOffset)
1004 fni_next = (FILE_NOTIFY_INFORMATION*)((char*)fni+fni->NextEntryOffset);
1005 else
1006 {
1007 r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
1009 ok(r == TRUE, "pReadDirectoryChangesW failed\n");
1010
1011 r = SleepEx(1000, TRUE);
1012 ok(r != 0, "failed to receive directory removal event\n");
1013 fni_next = fni;
1014 }
1015 ok(fni_next->NextEntryOffset == 0, "there should be no more events in buffer\n");
1016 ok(fni_next->Action == FILE_ACTION_REMOVED, "Action = %d\n", fni_next->Action);
1017 ok(fni_next->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR),
1018 "FileNameLength = %d\n", fni_next->FileNameLength);
1019 ok(!memcmp(fni_next->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)),
1020 "FileName = %s\n", wine_dbgstr_wn(fni_next->FileName, fni_next->FileNameLength/sizeof(WCHAR)));
1021
1022 CloseHandle(hdir);
1025}
1026
1028{
1029 HANDLE parent_watch, child_watch, parent_thread, child_thread;
1030 char workdir[MAX_PATH], parentdir[MAX_PATH], childdir[MAX_PATH];
1031 char tempfile[MAX_PATH];
1032 DWORD threadId;
1033 BOOL ret;
1034
1035 /* Setup directory hierarchy */
1037 ok((ret > 0) && (ret <= MAX_PATH),
1038 "GetTempPathA error: %d\n", GetLastError());
1039
1040 ret = GetTempFileNameA(workdir, "fcn", 0, tempfile);
1041 ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
1042 ret = DeleteFileA(tempfile);
1043 ok(ret, "DeleteFileA error: %d\n", GetLastError());
1044
1045 lstrcpyA(parentdir, tempfile);
1046 ret = CreateDirectoryA(parentdir, NULL);
1047 ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
1048
1049 lstrcpyA(childdir, parentdir);
1050 lstrcatA(childdir, "\\c");
1051 ret = CreateDirectoryA(childdir, NULL);
1052 ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
1053
1054
1055 /* When recursively watching overlapping directories, changes in child
1056 * should trigger notifications for both child and parent */
1057 parent_thread = StartNotificationThread(parentdir, TRUE,
1059 child_thread = StartNotificationThread(childdir, TRUE,
1061
1062 /* Create a file in child */
1063 ret = GetTempFileNameA(childdir, "fcn", 0, tempfile);
1064 ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
1065
1066 /* Both watches should trigger */
1067 ret = FinishNotificationThread(parent_thread);
1068 ok(ret, "Missed parent notification\n");
1069 ret = FinishNotificationThread(child_thread);
1070 ok(ret, "Missed child notification\n");
1071
1072 ret = DeleteFileA(tempfile);
1073 ok(ret, "DeleteFileA error: %d\n", GetLastError());
1074
1075
1076 /* Removing a recursive parent watch should not affect child watches. Doing
1077 * so used to crash wineserver. */
1078 parent_watch = FindFirstChangeNotificationA(parentdir, TRUE,
1080 ok(parent_watch != INVALID_HANDLE_VALUE,
1081 "FindFirstChangeNotification error: %d\n", GetLastError());
1082 child_watch = FindFirstChangeNotificationA(childdir, TRUE,
1084 ok(child_watch != INVALID_HANDLE_VALUE,
1085 "FindFirstChangeNotification error: %d\n", GetLastError());
1086
1087 ret = FindCloseChangeNotification(parent_watch);
1088 ok(ret, "FindCloseChangeNotification error: %d\n", GetLastError());
1089
1090 child_thread = CreateThread(NULL, 0, NotificationThread, child_watch, 0,
1091 &threadId);
1092 ok(child_thread != NULL, "CreateThread error: %d\n", GetLastError());
1093
1094 /* Create a file in child */
1095 ret = GetTempFileNameA(childdir, "fcn", 0, tempfile);
1096 ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
1097
1098 /* Child watch should trigger */
1099 ret = FinishNotificationThread(child_thread);
1100 ok(ret, "Missed child notification\n");
1101
1102 /* clean up */
1103 ret = DeleteFileA(tempfile);
1104 ok(ret, "DeleteFileA error: %d\n", GetLastError());
1105
1106 ret = RemoveDirectoryA(childdir);
1107 ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
1108
1109 ret = RemoveDirectoryA(parentdir);
1110 ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
1111}
1112
1114{
1115 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
1116 pReadDirectoryChangesW = (void *)GetProcAddress(hkernel32, "ReadDirectoryChangesW");
1117
1119 /* The above function runs a test that must occur before FindCloseChangeNotification is run in the
1120 current thread to preserve the emptiness of the wine user APC queue. To ensure this it should be
1121 placed first. */
1123 test_ffcn();
1129}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
unsigned int dir
Definition: maze.c:112
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define U(x)
Definition: wordpad.c:45
static HANDLE thread
Definition: service.c:33
BOOL WINAPI FindCloseChangeNotification(IN HANDLE hChangeHandle)
Definition: cnotify.c:106
BOOL WINAPI FindNextChangeNotification(IN HANDLE hChangeHandle)
Definition: cnotify.c:223
HANDLE WINAPI FindFirstChangeNotificationW(IN LPCWSTR lpPathName, IN BOOL bWatchSubtree, IN DWORD dwNotifyFilter)
Definition: cnotify.c:133
HANDLE WINAPI FindFirstChangeNotificationA(IN LPCSTR lpPathName, IN BOOL bWatchSubtree, IN DWORD dwNotifyFilter)
Definition: cnotify.c:117
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
const char * wine_dbgstr_wn(const WCHAR *str, int n)
Definition: compat.c:367
#define CloseHandle
Definition: compat.h:739
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define FILE_SHARE_READ
Definition: compat.h:136
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:776
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI MoveFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName)
Definition: move.c:1137
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1104
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint buffer
Definition: glext.h:5915
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:221
static void test_readdirectorychanges_cr(void)
Definition: change.c:817
static BOOL
Definition: change.c:372
static void test_ffcn(void)
Definition: change.c:254
static LPOVERLAPPED
Definition: change.c:373
static void test_ffcn_directory_overlap(void)
Definition: change.c:1027
static void test_FindFirstChangeNotification(void)
Definition: change.c:87
static void test_ffcnMultipleThreads(void)
Definition: change.c:332
static HANDLE StartNotificationThread(LPCSTR path, BOOL subtree, DWORD flags)
Definition: change.c:60
static DWORD
Definition: change.c:372
static void test_readdirectorychanges(void)
Definition: change.c:375
static LPVOID
Definition: change.c:372
static LPDWORD
Definition: change.c:373
static DWORD CALLBACK NotificationThread(LPVOID arg)
Definition: change.c:39
static void test_readdirectorychanges_filedir(void)
Definition: change.c:726
static void CALLBACK readdirectorychanges_cr(DWORD error, DWORD len, LPOVERLAPPED ov)
Definition: change.c:811
static DWORD FinishNotificationThread(HANDLE thread)
Definition: change.c:74
static LPOVERLAPPED_COMPLETION_ROUTINE
Definition: change.c:373
static void test_readdirectorychanges_null(void)
Definition: change.c:627
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
static char filename2[]
Definition: lzexpand_main.c:51
#define error(str)
Definition: mkdosfs.c:1605
#define CREATE_ALWAYS
Definition: disk.h:72
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static char workdir[MAX_PATH]
Definition: batch.c:26
static HINSTANCE hkernel32
Definition: process.c:66
#define todo_wine
Definition: custom.c:89
static int notified[MAX_INTERNET_STATUS]
Definition: http.c:111
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define GENERIC_WRITE
Definition: nt_native.h:90
#define STATUS_NOTIFY_ENUM_DIR
Definition: ntstatus.h:91
long LONG
Definition: pedump.c:60
#define win_skip
Definition: test.h:163
#define S(x)
Definition: test.h:220
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
HANDLE hEvent
Definition: winbase.h:844
ULONG_PTR Internal
Definition: winbase.h:835
ULONG_PTR InternalHigh
Definition: winbase.h:836
Definition: fci.c:127
Definition: ps.c:97
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
DWORD WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:802
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
PVOID HANDLE
Definition: typedefs.h:73
static EFI_HANDLE * handles
Definition: uefidisk.c:62
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WAIT_OBJECT_0
Definition: winbase.h:431
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_DIRECTORY
Definition: winerror.h:295
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
struct _FILE_NOTIFY_INFORMATION * PFILE_NOTIFY_INFORMATION
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_ACTION_MODIFIED
#define FILE_ACTION_RENAMED_OLD_NAME
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define FILE_ACTION_REMOVED
#define FILE_NOTIFY_CHANGE_SECURITY
#define FILE_NOTIFY_CHANGE_FILE_NAME
#define FILE_ACTION_RENAMED_NEW_NAME
#define FILE_NOTIFY_CHANGE_CREATION
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define FILE_ACTION_ADDED
#define FILE_NOTIFY_CHANGE_DIR_NAME
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180