From 85e610895c011a6b1fc856d51f515ab0eb7413e2 Mon Sep 17 00:00:00 2001 From: Dmitry Chapyshev Date: Wed, 31 Dec 2008 11:54:30 +0000 Subject: [PATCH] - Fix ReadDirectoryChangesW - FindFirstChangeNotificationW +17 passed winetests svn path=/trunk/; revision=38486 --- reactos/dll/win32/kernel32/file/cnotify.c | 54 ++++++++++++++++++----- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/reactos/dll/win32/kernel32/file/cnotify.c b/reactos/dll/win32/kernel32/file/cnotify.c index 2321eb8cac7..59f61650bfa 100644 --- a/reactos/dll/win32/kernel32/file/cnotify.c +++ b/reactos/dll/win32/kernel32/file/cnotify.c @@ -92,12 +92,7 @@ FindFirstChangeNotificationW ( &ObjectAttributes, &IoStatus, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, - FILE_DIRECTORY_FILE); - - /* - FIXME: I think we should use FILE_OPEN_FOR_BACKUP_INTENT. See M$ Q188321 - -Gunnar - */ + FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT); RtlFreeHeap(RtlGetProcessHeap(), 0, @@ -122,6 +117,7 @@ FindFirstChangeNotificationW ( (BOOLEAN)bWatchSubtree); if (!NT_SUCCESS(Status)) { + NtClose(hDir); SetLastErrorByStatus(Status); return INVALID_HANDLE_VALUE; } @@ -185,24 +181,62 @@ ReadDirectoryChangesW( LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine /* OPTIONAL???????? */ ) { + PVOID CompletionRoutine; NTSTATUS Status; IO_STATUS_BLOCK IoStatus; + HANDLE EventHandle; + PIO_APC_ROUTINE IoApcRoutine; if (lpOverlapped ) + { + if (lpCompletionRoutine) + { + CompletionRoutine = (PVOID) lpCompletionRoutine; + EventHandle = NULL; + IoApcRoutine = ApcRoutine; + } + else + { + if (((ULONG_PTR) lpOverlapped->hEvent & 1) == 0) + CompletionRoutine = (PVOID) lpOverlapped; + else + CompletionRoutine = NULL; + + EventHandle = lpOverlapped->hEvent; + IoApcRoutine = NULL; + } + lpOverlapped->Internal = STATUS_PENDING; + } + else + { + EventHandle = NULL; + IoApcRoutine = NULL; + CompletionRoutine = NULL; + } Status = NtNotifyChangeDirectoryFile( hDirectory, - lpOverlapped ? lpOverlapped->hEvent : NULL, - lpCompletionRoutine ? ApcRoutine : NULL, /* ApcRoutine OPTIONAL???? */ - lpCompletionRoutine, /* ApcContext */ - lpOverlapped ? (PIO_STATUS_BLOCK)lpOverlapped : &IoStatus, + EventHandle, + IoApcRoutine, + CompletionRoutine, /* ApcContext */ + lpOverlapped ? (PIO_STATUS_BLOCK)lpOverlapped->Internal : &IoStatus, lpBuffer, nBufferLength, dwNotifyFilter, (BOOLEAN)bWatchSubtree ); + if ((Status == STATUS_PENDING) && (!lpOverlapped)) + { + Status = NtWaitForSingleObject(hDirectory, FALSE, NULL); + + if (NT_SUCCESS(Status)) + { + Status = IoStatus.Status; + } + } + if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status);