ReactOS 0.4.16-dev-2206-gc56950d
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: %ld\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: %ld\n", GetLastError());
67
68 thread = CreateThread(NULL, 0, NotificationThread, change, 0, &threadId);
69 ok(thread != NULL, "CreateThread error: %ld\n", GetLastError());
70
71 return thread;
72}
73
75{
76 DWORD status, exitcode;
77
79 ok(status == WAIT_OBJECT_0, "WaitForSingleObject status %ld error %ld\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 "FindFirstChangeNotification error: %ld\n", GetLastError());
104
106 ok(change == INVALID_HANDLE_VALUE || broken(change == NULL) /* < win7 */,
107 "Expected INVALID_HANDLE_VALUE, got %p\n", change);
109 "FindFirstChangeNotification error: %lu\n", GetLastError());
110
112 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindNextChangeNotification error: %ld\n",
113 GetLastError());
114
116 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindCloseChangeNotification error: %ld\n",
117 GetLastError());
118
119 ret = GetTempPathA(MAX_PATH, dirname1);
120 ok(ret, "GetTempPathA error: %ld\n", GetLastError());
121
122 ret = GetTempFileNameA(dirname1, "ffc", 0, workdir);
123 ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
125
127 ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
128
129 ret = GetTempFileNameA(workdir, prefix, 0, filename1);
130 ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
131
134 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
136 ok( ret, "CloseHandle error: %ld\n", GetLastError());
137
138 /* Try to register notification for a file */
140 ok(change == INVALID_HANDLE_VALUE, "Expected INVALID_HANDLE_VALUE, got %p\n", change);
142 "FindFirstChangeNotification error: %ld\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: %ld\n", GetLastError());
152
153 /* What if we move the directory we registered notification for? */
155 ret = MoveFileA(dirname1, dirname2);
156 ok(ret, "MoveFileA error: %ld\n", GetLastError());
157 ok(!FinishNotificationThread(thread), "Got notification\n");
158
159 /* What if we remove the directory we registered notification for? */
161 ret = RemoveDirectoryA(dirname2);
162 ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
164 todo_wine ok(ret, "Missed notification\n");
165
166 /* functional checks */
167
168 /* Create a directory */
170 ret = CreateDirectoryA(dirname1, NULL);
171 ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
172 ok(FinishNotificationThread(thread), "Missed notification\n");
173
174 /* Rename a directory */
176 ret = MoveFileA(dirname1, dirname2);
177 ok(ret, "MoveFileA error: %ld\n", GetLastError());
178 ok(FinishNotificationThread(thread), "Missed notification\n");
179
180 /* Delete a directory */
182 ret = RemoveDirectoryA(dirname2);
183 ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
184 ok(FinishNotificationThread(thread), "Missed notification\n");
185
186 lstrcpyA(filename2, filename1);
187 lstrcatA(filename2, "new");
188
189 /* Rename a file */
191 ret = MoveFileA(filename1, filename2);
192 ok(ret, "MoveFileA error: %ld\n", GetLastError());
193 ok(FinishNotificationThread(thread), "Missed notification\n");
194
195 /* Delete a file */
198 ok(ret, "DeleteFileA error: %ld\n", GetLastError());
199 ok(FinishNotificationThread(thread), "Missed notification\n");
200
201 /* Create a file */
205 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
207 ok( ret, "CloseHandle error: %ld\n", GetLastError());
208 ok(FinishNotificationThread(thread), "Missed notification\n");
209
210 attributes = GetFileAttributesA(filename2);
211 ok(attributes != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA error: %ld\n", GetLastError());
212 attributes &= FILE_ATTRIBUTE_READONLY;
213
214 /* Change file attributes */
216 ret = SetFileAttributesA(filename2, attributes);
217 ok(ret, "SetFileAttributesA error: %ld\n", GetLastError());
218 ok(FinishNotificationThread(thread), "Missed notification\n");
219
220 /* Change last write time by writing to a file */
224 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
225 memset(buffer, 0, sizeof(buffer));
226 ret = WriteFile(file, buffer, sizeof(buffer), &count, NULL);
227 ok(ret && count == sizeof(buffer), "WriteFile error: %ld\n", GetLastError());
229 ok( ret, "CloseHandle error: %ld\n", GetLastError());
230 ok(FinishNotificationThread(thread), "Missed notification\n");
231
232 /* Change file size by truncating a file */
236 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
237 ret = WriteFile(file, buffer, sizeof(buffer) / 2, &count, NULL);
238 ok(ret && count == sizeof(buffer) / 2, "WriteFileA error: %ld\n", GetLastError());
240 ok( ret, "CloseHandle error: %ld\n", GetLastError());
241 ok(FinishNotificationThread(thread), "Missed notification\n");
242
243 /* clean up */
244
246 ok(ret, "DeleteFileA error: %ld\n", GetLastError());
247
249 ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
250}
251
252/* this test concentrates more on the wait behaviour of the handle */
253static void test_ffcn(void)
254{
257 LONG r;
259 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
260 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
261 static const WCHAR szZoo[] = { '\\','z','o','o',0 };
262
264 ok( r != 0, "temp path failed\n");
265
266 lstrcatW( path, szBoo );
267 lstrcpyW( subdir, path );
268 lstrcatW( subdir, szHoo );
269
271 lstrcatW( filename, szZoo );
272
273 RemoveDirectoryW( subdir );
275
277 ok( r == TRUE, "failed to create directory\n");
278
281
283 ok( handle != INVALID_HANDLE_VALUE, "invalid handle\n");
284
286 ok( r == STATUS_TIMEOUT, "should time out\n");
287
290 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
292
293 r = WaitForSingleObject( handle, 1000 );
294 ok( r == WAIT_OBJECT_0, "should be ready\n");
295
297 ok( r == WAIT_OBJECT_0, "should be ready\n");
298
300 ok( r == TRUE, "find next failed\n");
301
303 ok( r == STATUS_TIMEOUT, "should time out\n");
304
306 ok( r == TRUE, "failed to remove file\n");
307
308 r = WaitForSingleObject( handle, 1000 );
309 ok( r == WAIT_OBJECT_0, "should be ready\n");
310
312 ok( r == WAIT_OBJECT_0, "should be ready\n");
313
315 ok( r == TRUE, "find next failed\n");
316
318 ok( r == STATUS_TIMEOUT, "should time out\n");
319
320 r = CreateDirectoryW( subdir, NULL );
321 ok( r == TRUE, "failed to create subdir\n");
322
323 r = WaitForSingleObject( handle, 1000 );
324 ok( r == WAIT_OBJECT_0, "should be ready\n");
325
327 ok( r == WAIT_OBJECT_0, "should be ready\n");
328
330 ok( r == TRUE, "find next failed\n");
331
333 ok( r == STATUS_TIMEOUT, "should time out\n");
334
335 r = RemoveDirectoryW( subdir );
336 ok( r == TRUE, "failed to remove subdir\n");
337
338 r = WaitForSingleObject( handle, 1000 );
339 ok( r == WAIT_OBJECT_0, "should be ready\n");
340
342 ok( r == WAIT_OBJECT_0, "should be ready\n");
343
345 ok( r == TRUE, "find next failed\n");
346
348 ok( r == TRUE, "find next failed\n");
349
351 ok( r == TRUE, "should succeed\n");
352
354 ok( r == TRUE, "failed to remove dir\n");
355}
356
357/* this test concentrates on the wait behavior when multiple threads are
358 * waiting on a change notification handle. */
360{
361 LONG r;
362 DWORD filter, threadId, status, exitcode;
363 HANDLE handles[2];
364 char tmp[MAX_PATH], path[MAX_PATH];
365
366 r = GetTempPathA(MAX_PATH, tmp);
367 ok(r, "GetTempPathA error: %ld\n", GetLastError());
368
369 r = GetTempFileNameA(tmp, "ffc", 0, path);
370 ok(r, "GetTempFileNameA error: %ld\n", GetLastError());
371 DeleteFileA( path );
372
374 ok(r, "CreateDirectoryA error: %ld\n", GetLastError());
375
378
380 ok(handles[0] != INVALID_HANDLE_VALUE, "FindFirstChangeNotification error: %ld\n", GetLastError());
381
382 /* Test behavior if a waiting thread holds the last reference to a change
383 * directory object with an empty wine user APC queue for this thread (bug #7286) */
384
385 /* Create our notification thread */
387 &threadId);
388 ok(handles[1] != NULL, "CreateThread error: %ld\n", GetLastError());
389
391 ok(status == WAIT_OBJECT_0 || status == WAIT_OBJECT_0+1, "WaitForMultipleObjects status %ld error %ld\n", status, GetLastError());
392 ok(GetExitCodeThread(handles[1], &exitcode), "Could not retrieve thread exit code\n");
393
394 /* Clean up */
396 ok( r == TRUE, "failed to remove dir\n");
397}
398
400{
401 HANDLE hdir;
402 char buffer[0x1000];
403 DWORD fflags, filter = 0, r, dwCount;
404 OVERLAPPED ov;
405 WCHAR path[MAX_PATH], subdir[MAX_PATH], subsubdir[MAX_PATH];
406 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
407 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
408 static const WCHAR szGa[] = { '\\','h','o','o','\\','g','a',0 };
410 BOOL got_subdir_change = FALSE;
411
413 ok( r != 0, "temp path failed\n");
414
415 lstrcatW( path, szBoo );
416 lstrcpyW( subdir, path );
417 lstrcatW( subdir, szHoo );
418
419 lstrcpyW( subsubdir, path );
420 lstrcatW( subsubdir, szGa );
421
422 RemoveDirectoryW( subsubdir );
423 RemoveDirectoryW( subdir );
425
427 ok( r == TRUE, "failed to create directory\n");
428
429 SetLastError(0xd0b00b00);
431 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
432 ok(r==FALSE, "should return false\n");
433
437 OPEN_EXISTING, fflags, NULL);
438 ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
439
440 ov.hEvent = CreateEventW( NULL, 1, 0, NULL );
441
442 SetLastError(0xd0b00b00);
444 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
445 ok(r==FALSE, "should return false\n");
446
447 SetLastError(0xd0b00b00);
448 r = ReadDirectoryChangesW(hdir,NULL,0,FALSE,0,NULL,&ov,NULL);
449 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
450 ok(r==FALSE, "should return false\n");
451
460
461 SetLastError(0xd0b00b00);
462 ov.Internal = 0;
463 ov.InternalHigh = 0;
464 memset( buffer, 0, sizeof buffer );
465
466 r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,-1,NULL,&ov,NULL);
467 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
468 ok(r==FALSE, "should return false\n");
469
470 r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,&ov,NULL);
471 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
472 ok(r==FALSE, "should return false\n");
473
475 ok(r==TRUE, "should return true\n");
476
477 r = WaitForSingleObject( ov.hEvent, 10 );
478 ok( r == STATUS_TIMEOUT, "should timeout\n" );
479
480 r = CreateDirectoryW( subdir, NULL );
481 ok( r == TRUE, "failed to create directory\n");
482
483 r = WaitForSingleObject( ov.hEvent, 1000 );
484 ok( r == WAIT_OBJECT_0, "event should be ready\n" );
485
486 ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
487 ok( ov.InternalHigh == 0x12, "ov.InternalHigh wrong\n");
488
490 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
491 ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
492 ok( pfni->FileNameLength == 6, "len wrong\n" );
493 ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
494
495 ResetEvent(ov.hEvent);
496 SetLastError(0xd0b00b00);
498 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
499 ok(r==FALSE, "should return false\n");
500
501 r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,&ov,NULL);
502 ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
503 ok(r==FALSE, "should return false\n");
504
506
507 SetEvent(ov.hEvent);
508 ov.Internal = 1;
509 ov.InternalHigh = 1;
510 ov.Offset = 0;
511 ov.OffsetHigh = 0;
512 memset( buffer, 0, sizeof buffer );
514 ok(r==TRUE, "should return true\n");
515
516 ok( (NTSTATUS)ov.Internal == STATUS_PENDING, "ov.Internal wrong\n");
517 ok( ov.InternalHigh == 1, "ov.InternalHigh wrong\n");
518
519 r = WaitForSingleObject( ov.hEvent, 0 );
520 ok( r == STATUS_TIMEOUT, "should timeout\n" );
521
522 r = RemoveDirectoryW( subdir );
523 ok( r == TRUE, "failed to remove directory\n");
524
525 r = WaitForSingleObject( ov.hEvent, 1000 );
526 ok( r == WAIT_OBJECT_0, "should be ready\n" );
527
528 ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
529 ok( ov.InternalHigh == 0x12, "ov.InternalHigh wrong\n");
530
532 {
533 r = GetOverlappedResult( hdir, &ov, &dwCount, TRUE );
534 ok( r == TRUE, "getoverlappedresult failed\n");
535 ok( dwCount == 0x12, "count wrong\n");
536 }
537
539 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
540 ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong\n" );
541 ok( pfni->FileNameLength == 6, "len wrong\n" );
542 ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
543
544 /* what happens if the buffer is too small? */
546 ok(r==TRUE, "should return true\n");
547
548 r = CreateDirectoryW( subdir, NULL );
549 ok( r == TRUE, "failed to create directory\n");
550
551 r = WaitForSingleObject( ov.hEvent, 1000 );
552 ok( r == WAIT_OBJECT_0, "should be ready\n" );
553
554 ok( (NTSTATUS)ov.Internal == STATUS_NOTIFY_ENUM_DIR, "ov.Internal wrong\n");
555 ok( ov.InternalHigh == 0, "ov.InternalHigh wrong\n");
556
557 /* test the recursive watch */
559 ok(r==TRUE, "should return true\n");
560
561 r = CreateDirectoryW( subsubdir, NULL );
562 ok( r == TRUE, "failed to create directory\n");
563
564 while (1)
565 {
566 r = WaitForSingleObject( ov.hEvent, 1000 );
567 ok(r == WAIT_OBJECT_0, "should be ready\n" );
568 if (r == WAIT_TIMEOUT) break;
569
570 ok((NTSTATUS) ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
571
573 while (1)
574 {
575 /* We might get one or more modified events on the parent dir */
576 if (pfni->Action == FILE_ACTION_MODIFIED)
577 {
578 ok(pfni->FileNameLength == 3 * sizeof(WCHAR), "len wrong\n" );
579 ok(!memcmp(pfni->FileName, &szGa[1], 3 * sizeof(WCHAR)), "name wrong\n");
580 }
581 else
582 {
583 ok(pfni->Action == FILE_ACTION_ADDED, "action wrong\n");
584 ok(pfni->FileNameLength == 6 * sizeof(WCHAR), "len wrong\n" );
585 ok(!memcmp(pfni->FileName, &szGa[1], 6 * sizeof(WCHAR)), "name wrong\n");
586 got_subdir_change = TRUE;
587 }
588 if (!pfni->NextEntryOffset) break;
589 pfni = (PFILE_NOTIFY_INFORMATION)((char *)pfni + pfni->NextEntryOffset);
590 }
591
592 if (got_subdir_change) break;
593
595 ok(r==TRUE, "should return true\n");
596 }
597 ok(got_subdir_change, "didn't get subdir change\n");
598
599 r = RemoveDirectoryW( subsubdir );
600 ok( r == TRUE, "failed to remove directory\n");
601
602 ov.Internal = 1;
603 ov.InternalHigh = 1;
605 ok(r==TRUE, "should return true\n");
606
607 r = RemoveDirectoryW( subdir );
608 ok( r == TRUE, "failed to remove directory\n");
609
610 r = WaitForSingleObject( ov.hEvent, 1000 );
611 ok( r == WAIT_OBJECT_0, "should be ready\n" );
612
614 /* we may get a notification for the parent dir too */
615 if (pfni->Action == FILE_ACTION_MODIFIED && pfni->NextEntryOffset)
616 {
617 ok( pfni->FileNameLength == 3*sizeof(WCHAR), "len wrong %lu\n", pfni->FileNameLength );
618 ok( !memcmp(pfni->FileName,&szGa[1],3*sizeof(WCHAR)), "name wrong\n" );
619 pfni = (PFILE_NOTIFY_INFORMATION)((char *)pfni + pfni->NextEntryOffset);
620 }
621 ok( pfni->NextEntryOffset == 0, "offset wrong %lu\n", pfni->NextEntryOffset );
622 ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong %lu\n", pfni->Action );
623 ok( pfni->FileNameLength == 6*sizeof(WCHAR), "len wrong %lu\n", pfni->FileNameLength );
624 ok( !memcmp(pfni->FileName,&szGa[1],6*sizeof(WCHAR)), "name wrong\n" );
625
626 ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
627 dwCount = (char *)&pfni->FileName[pfni->FileNameLength/sizeof(WCHAR)] - buffer;
628 ok( ov.InternalHigh == dwCount, "ov.InternalHigh wrong %Iu/%lu\n",ov.InternalHigh, dwCount );
629
630 CloseHandle(hdir);
631
633 ok( r == TRUE, "failed to remove directory\n");
634}
635
636/* show the behaviour when a null buffer is passed */
638{
639 NTSTATUS r;
640 HANDLE hdir;
641 char buffer[0x1000];
642 DWORD fflags, filter = 0;
643 OVERLAPPED ov;
644 WCHAR path[MAX_PATH], subdir[MAX_PATH];
645 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
646 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
648
650 ok( r != 0, "temp path failed\n");
651
652 lstrcatW( path, szBoo );
653 lstrcpyW( subdir, path );
654 lstrcatW( subdir, szHoo );
655
656 RemoveDirectoryW( subdir );
658
660 ok( r == TRUE, "failed to create directory\n");
661
665 OPEN_EXISTING, fflags, NULL);
666 ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
667
668 ov.hEvent = CreateEventW( NULL, 1, 0, NULL );
669
672
673 SetLastError(0xd0b00b00);
674 ov.Internal = 0;
675 ov.InternalHigh = 0;
676 memset( buffer, 0, sizeof buffer );
677
679 ok(r==TRUE, "should return true\n");
680
681 r = WaitForSingleObject( ov.hEvent, 0 );
682 ok( r == STATUS_TIMEOUT, "should timeout\n" );
683
684 r = CreateDirectoryW( subdir, NULL );
685 ok( r == TRUE, "failed to create directory\n");
686
687 r = WaitForSingleObject( ov.hEvent, 0 );
688 ok( r == WAIT_OBJECT_0, "event should be ready\n" );
689
690 ok( (NTSTATUS)ov.Internal == STATUS_NOTIFY_ENUM_DIR, "ov.Internal wrong\n");
691 ok( ov.InternalHigh == 0, "ov.InternalHigh wrong\n");
692
693 ov.Internal = 0;
694 ov.InternalHigh = 0;
695 ov.Offset = 0;
696 ov.OffsetHigh = 0;
697 memset( buffer, 0, sizeof buffer );
698
700 ok(r==TRUE, "should return true\n");
701
702 r = WaitForSingleObject( ov.hEvent, 0 );
703 ok( r == STATUS_TIMEOUT, "should timeout\n" );
704
705 r = RemoveDirectoryW( subdir );
706 ok( r == TRUE, "failed to remove directory\n");
707
708 r = WaitForSingleObject( ov.hEvent, 1000 );
709 ok( r == WAIT_OBJECT_0, "should be ready\n" );
710
711 ok( (NTSTATUS)ov.Internal == STATUS_NOTIFY_ENUM_DIR, "ov.Internal wrong\n");
712 ok( ov.InternalHigh == 0, "ov.InternalHigh wrong\n");
713
715 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
716
717 CloseHandle(hdir);
718
720 ok( r == TRUE, "failed to remove directory\n");
721}
722
724{
725 NTSTATUS r;
726 HANDLE hdir, hfile;
727 char buffer[0x1000];
728 DWORD fflags, filter = 0;
729 OVERLAPPED ov;
731 static const WCHAR szBoo[] = { '\\','b','o','o',0 };
732 static const WCHAR szHoo[] = { '\\','h','o','o',0 };
733 static const WCHAR szFoo[] = { '\\','f','o','o',0 };
735
737 ok( r != 0, "temp path failed\n");
738
739 lstrcatW( path, szBoo );
740 lstrcpyW( subdir, path );
741 lstrcatW( subdir, szHoo );
742
743 lstrcpyW( file, path );
744 lstrcatW( file, szFoo );
745
746 DeleteFileW( file );
747 RemoveDirectoryW( subdir );
749
751 ok( r == TRUE, "failed to create directory\n");
752
756 OPEN_EXISTING, fflags, NULL);
757 ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
758
759 ov.hEvent = CreateEventW( NULL, 0, 0, NULL );
760
762
764 ok(r==TRUE, "should return true\n");
765
766 r = WaitForSingleObject( ov.hEvent, 10 );
767 ok( r == WAIT_TIMEOUT, "should timeout\n" );
768
769 r = CreateDirectoryW( subdir, NULL );
770 ok( r == TRUE, "failed to create directory\n");
771
773 ok( hfile != INVALID_HANDLE_VALUE, "failed to create file\n");
774 ok( CloseHandle(hfile), "failed to close file\n");
775
776 r = WaitForSingleObject( ov.hEvent, 1000 );
777 ok( r == WAIT_OBJECT_0, "event should be ready\n" );
778
779 ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
780 ok( ov.InternalHigh == 0x12, "ov.InternalHigh wrong\n");
781
783 ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
784 ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
785 ok( pfni->FileNameLength == 6, "len wrong\n" );
786 ok( !memcmp(pfni->FileName,&szFoo[1],6), "name wrong\n" );
787
788 r = DeleteFileW( file );
789 ok( r == TRUE, "failed to delete file\n");
790
791 r = RemoveDirectoryW( subdir );
792 ok( r == TRUE, "failed to remove directory\n");
793
794 CloseHandle(hdir);
795
797 ok( r == TRUE, "failed to remove directory\n");
798}
799
801{
802 ok(error == 0, "ReadDirectoryChangesW error %ld\n", error);
803 ok(ov->hEvent == (void*)0xdeadbeef, "hEvent should not have changed\n");
804}
805
807{
808 static const WCHAR szBoo[] = { '\\','b','o','o','\\',0 };
809 static const WCHAR szDir[] = { 'd','i','r',0 };
810 static const WCHAR szFile[] = { 'f','i','l','e',0 };
811 static const WCHAR szBackslash[] = { '\\',0 };
812
814 FILE_NOTIFY_INFORMATION fni[1024], *fni_next;
815 OVERLAPPED ov;
816 HANDLE hdir, hfile;
817 NTSTATUS r;
818
820 ok(r != 0, "temp path failed\n");
821
822 lstrcatW(path, szBoo);
823 lstrcpyW(dir, path);
824 lstrcatW(dir, szDir);
826 lstrcatW(file, szFile);
827 lstrcpyW(sub_file, dir);
828 lstrcatW(sub_file, szBackslash);
829 lstrcatW(sub_file, szFile);
830
834
836 ok(r == TRUE, "failed to create directory\n");
837
841 ok(hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
842
843 memset(&ov, 0, sizeof(ov));
844 ov.hEvent = (void*)0xdeadbeef;
845 r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
847 ok(r == TRUE, "ReadDirectoryChangesW failed\n");
848
850 ok(hfile != INVALID_HANDLE_VALUE, "failed to create file\n");
851 CloseHandle(hfile);
852
853 r = SleepEx(1000, TRUE);
854 ok(r != 0, "failed to receive file creation event\n");
855 ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
856 ok(fni->Action == FILE_ACTION_ADDED, "Action = %ld\n", fni->Action);
857 ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
858 "FileNameLength = %ld\n", fni->FileNameLength);
859 ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
860 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
861
862 r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
864 ok(r == TRUE, "ReadDirectoryChangesW failed\n");
865
866 /* This event will not be reported */
868 ok(r == TRUE, "failed to create directory\n");
869
870 r = MoveFileW(file, sub_file);
871 ok(r == TRUE, "failed to move file\n");
872
873 r = SleepEx(1000, TRUE);
874 ok(r != 0, "failed to receive file move event\n");
875 ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
876 ok(fni->Action == FILE_ACTION_REMOVED, "Action = %ld\n", fni->Action);
877 ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
878 "FileNameLength = %ld\n", fni->FileNameLength);
879 ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
880 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
881
882 r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
884 ok(r == TRUE, "ReadDirectoryChangesW failed\n");
885
886 r = MoveFileW(sub_file, file);
887 ok(r == TRUE, "failed to move file\n");
888
889 r = SleepEx(1000, TRUE);
890 ok(r != 0, "failed to receive file move event\n");
891 ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
892 ok(fni->Action == FILE_ACTION_ADDED, "Action = %ld\n", fni->Action);
893 ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
894 "FileNameLength = %ld\n", fni->FileNameLength);
895 ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
896 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
897
898 r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
900 ok(r == TRUE, "ReadDirectoryChangesW failed\n");
901
902 r = DeleteFileW(file);
903 ok(r == TRUE, "failed to delete file\n");
904
905 r = SleepEx(1000, TRUE);
906 ok(r != 0, "failed to receive file removal event\n");
907 ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
908 ok(fni->Action == FILE_ACTION_REMOVED, "Action = %ld\n", fni->Action);
909 ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
910 "FileNameLength = %ld\n", fni->FileNameLength);
911 ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
912 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
913
914 CloseHandle(hdir);
915
919 ok(hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
920
921 r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
923 ok(r == TRUE, "ReadDirectoryChangesW failed\n");
924
925 r = MoveFileW(dir, file);
926 ok(r == TRUE, "failed to move directory\n");
927
928 r = SleepEx(1000, TRUE);
929 ok(r != 0, "failed to receive directory move event\n");
931 {
932 ok(fni->Action == FILE_ACTION_RENAMED_OLD_NAME, "Action = %ld\n", fni->Action);
933 ok(fni->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR),
934 "FileNameLength = %ld\n", fni->FileNameLength);
935 ok(!memcmp(fni->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)),
936 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
937 ok(fni->NextEntryOffset != 0, "no next entry in movement event\n");
938 fni_next = (FILE_NOTIFY_INFORMATION*)((char*)fni+fni->NextEntryOffset);
939 ok(fni_next->NextEntryOffset == 0, "there should be no more events in buffer\n");
940 ok(fni_next->Action == FILE_ACTION_RENAMED_NEW_NAME, "Action = %ld\n", fni_next->Action);
941 ok(fni_next->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
942 "FileNameLength = %ld\n", fni_next->FileNameLength);
943 ok(!memcmp(fni_next->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
944 "FileName = %s\n", wine_dbgstr_wn(fni_next->FileName, fni_next->FileNameLength/sizeof(WCHAR)));
945 }
946 else
947 {
948 todo_wine ok(0, "Expected rename event\n");
949
950 if (fni->NextEntryOffset == 0)
951 {
952 r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
954 ok(r == TRUE, "ReadDirectoryChangesW failed\n");
955
956 r = SleepEx(1000, TRUE);
957 ok(r != 0, "failed to receive directory move event\n");
958 }
959 }
960
962 ok(r == TRUE, "failed to create directory\n");
963
965 ok(r == TRUE, "failed to remove directory\n");
966
967 r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
969 ok(r == TRUE, "ReadDirectoryChangesW failed\n");
970
971 r = SleepEx(1000, TRUE);
972 ok(r != 0, "failed to receive directory creation event\n");
973 ok(fni->Action == FILE_ACTION_ADDED, "Action = %ld\n", fni->Action);
974 ok(fni->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR),
975 "FileNameLength = %ld\n", fni->FileNameLength);
976 ok(!memcmp(fni->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)),
977 "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
978 if (fni->NextEntryOffset)
979 fni_next = (FILE_NOTIFY_INFORMATION*)((char*)fni+fni->NextEntryOffset);
980 else
981 {
982 r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
984 ok(r == TRUE, "ReadDirectoryChangesW failed\n");
985
986 r = SleepEx(1000, TRUE);
987 ok(r != 0, "failed to receive directory removal event\n");
988 fni_next = fni;
989 }
990 ok(fni_next->NextEntryOffset == 0, "there should be no more events in buffer\n");
991 ok(fni_next->Action == FILE_ACTION_REMOVED, "Action = %ld\n", fni_next->Action);
992 ok(fni_next->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR),
993 "FileNameLength = %ld\n", fni_next->FileNameLength);
994 ok(!memcmp(fni_next->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)),
995 "FileName = %s\n", wine_dbgstr_wn(fni_next->FileName, fni_next->FileNameLength/sizeof(WCHAR)));
996
997 CloseHandle(hdir);
1000}
1001
1003{
1004 HANDLE parent_watch, child_watch, parent_thread, child_thread;
1005 char workdir[MAX_PATH], parentdir[MAX_PATH], childdir[MAX_PATH];
1006 char tempfile[MAX_PATH];
1007 DWORD threadId;
1008 BOOL ret;
1009
1010 /* Setup directory hierarchy */
1012 ok((ret > 0) && (ret <= MAX_PATH),
1013 "GetTempPathA error: %ld\n", GetLastError());
1014
1015 ret = GetTempFileNameA(workdir, "fcn", 0, tempfile);
1016 ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
1017 ret = DeleteFileA(tempfile);
1018 ok(ret, "DeleteFileA error: %ld\n", GetLastError());
1019
1020 lstrcpyA(parentdir, tempfile);
1021 ret = CreateDirectoryA(parentdir, NULL);
1022 ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
1023
1024 lstrcpyA(childdir, parentdir);
1025 lstrcatA(childdir, "\\c");
1026 ret = CreateDirectoryA(childdir, NULL);
1027 ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
1028
1029
1030 /* When recursively watching overlapping directories, changes in child
1031 * should trigger notifications for both child and parent */
1032 parent_thread = StartNotificationThread(parentdir, TRUE,
1034 child_thread = StartNotificationThread(childdir, TRUE,
1036
1037 /* Create a file in child */
1038 ret = GetTempFileNameA(childdir, "fcn", 0, tempfile);
1039 ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
1040
1041 /* Both watches should trigger */
1042 ret = FinishNotificationThread(parent_thread);
1043 ok(ret, "Missed parent notification\n");
1044 ret = FinishNotificationThread(child_thread);
1045 ok(ret, "Missed child notification\n");
1046
1047 ret = DeleteFileA(tempfile);
1048 ok(ret, "DeleteFileA error: %ld\n", GetLastError());
1049
1050
1051 /* Removing a recursive parent watch should not affect child watches. Doing
1052 * so used to crash wineserver. */
1053 parent_watch = FindFirstChangeNotificationA(parentdir, TRUE,
1055 ok(parent_watch != INVALID_HANDLE_VALUE,
1056 "FindFirstChangeNotification error: %ld\n", GetLastError());
1057 child_watch = FindFirstChangeNotificationA(childdir, TRUE,
1059 ok(child_watch != INVALID_HANDLE_VALUE,
1060 "FindFirstChangeNotification error: %ld\n", GetLastError());
1061
1062 ret = FindCloseChangeNotification(parent_watch);
1063 ok(ret, "FindCloseChangeNotification error: %ld\n", GetLastError());
1064
1065 child_thread = CreateThread(NULL, 0, NotificationThread, child_watch, 0,
1066 &threadId);
1067 ok(child_thread != NULL, "CreateThread error: %ld\n", GetLastError());
1068
1069 /* Create a file in child */
1070 ret = GetTempFileNameA(childdir, "fcn", 0, tempfile);
1071 ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
1072
1073 /* Child watch should trigger */
1074 ret = FinishNotificationThread(child_thread);
1075 ok(ret, "Missed child notification\n");
1076
1077 /* clean up */
1078 ret = DeleteFileA(tempfile);
1079 ok(ret, "DeleteFileA error: %ld\n", GetLastError());
1080
1081 ret = RemoveDirectoryA(childdir);
1082 ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
1083
1084 ret = RemoveDirectoryA(parentdir);
1085 ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
1086}
1087
1089{
1091 /* The above function runs a test that must occur before FindCloseChangeNotification is run in the
1092 current thread to preserve the emptiness of the wine user APC queue. To ensure this it should be
1093 placed first. */
1095 test_ffcn();
1101}
unsigned int dir
Definition: maze.c:112
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
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
BOOL WINAPI ReadDirectoryChangesW(IN HANDLE hDirectory, IN LPVOID lpBuffer OPTIONAL, IN DWORD nBufferLength, IN BOOL bWatchSubtree, IN DWORD dwNotifyFilter, OUT LPDWORD lpBytesReturned, IN LPOVERLAPPED lpOverlapped OPTIONAL, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: cnotify.c:253
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 WAIT_TIMEOUT
Definition: dderror.h:14
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#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
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
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
return ret
Definition: mutex.c:146
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
const char * filename
Definition: ioapi.h:137
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:806
static void test_ffcn(void)
Definition: change.c:253
static void test_ffcn_directory_overlap(void)
Definition: change.c:1002
static void test_FindFirstChangeNotification(void)
Definition: change.c:87
static void test_ffcnMultipleThreads(void)
Definition: change.c:359
static HANDLE StartNotificationThread(LPCSTR path, BOOL subtree, DWORD flags)
Definition: change.c:60
static void test_readdirectorychanges(void)
Definition: change.c:399
static DWORD CALLBACK NotificationThread(LPVOID arg)
Definition: change.c:39
static void test_readdirectorychanges_filedir(void)
Definition: change.c:723
static void CALLBACK readdirectorychanges_cr(DWORD error, DWORD len, LPOVERLAPPED ov)
Definition: change.c:800
static DWORD FinishNotificationThread(HANDLE thread)
Definition: change.c:74
static void test_readdirectorychanges_null(void)
Definition: change.c:637
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 todo_wine
Definition: minitest.h:80
#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 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:144
long LONG
Definition: pedump.c:60
#define wine_dbgstr_wn
Definition: testlist.c:2
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
DWORD OffsetHigh
Definition: minwinbase.h:226
DWORD Offset
Definition: minwinbase.h:225
HANDLE hEvent
Definition: minwinbase.h:230
ULONG_PTR Internal
Definition: minwinbase.h:219
ULONG_PTR InternalHigh
Definition: minwinbase.h:220
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
#define STATUS_PENDING
Definition: telnetd.h:14
Character const *const prefix
Definition: tempnam.cpp:195
static EFI_HANDLE * handles
Definition: uefidisk.c:117
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WAIT_OBJECT_0
Definition: winbase.h:383
void * arg
Definition: msvc.h:10
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define ERROR_DIRECTORY
Definition: winerror.h:416
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