[KERNEL32]
[reactos.git] / reactos / dll / win32 / kernel32 / file / cnotify.c
index ce0b322..37814a1 100644 (file)
@@ -9,15 +9,18 @@
  *                  Created 01/11/98
  */
 
+/* INCLUDES *****************************************************************/
+
 #include <k32.h>
-#include <wine/debug.h>
+#define NDEBUG
+#include <debug.h>
 
-WINE_DEFAULT_DEBUG_CHANNEL(kernel32file);
+/* FUNCTIONS ****************************************************************/
 
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 FindCloseChangeNotification (HANDLE hChangeHandle)
 {
    NTSTATUS Status = NtClose(hChangeHandle);
@@ -35,21 +38,31 @@ FindCloseChangeNotification (HANDLE hChangeHandle)
  * @implemented
  */
 HANDLE
-STDCALL
-FindFirstChangeNotificationA (
-       LPCSTR  lpPathName,
-       BOOL    bWatchSubtree,
-       DWORD   dwNotifyFilter
-       )
+WINAPI
+FindFirstChangeNotificationA(IN LPCSTR lpPathName,
+                             IN BOOL bWatchSubtree,
+                             IN DWORD dwNotifyFilter)
 {
-       PWCHAR PathNameW;
-
-   if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
-      return INVALID_HANDLE_VALUE;
-
-   return FindFirstChangeNotificationW (PathNameW ,
-                                               bWatchSubtree,
-                                               dwNotifyFilter);
+    NTSTATUS Status;
+    ANSI_STRING PathNameString;
+
+    RtlInitAnsiString(&PathNameString, lpPathName);
+    Status = RtlAnsiStringToUnicodeString(&(NtCurrentTeb()->StaticUnicodeString), &PathNameString, FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        if (Status != STATUS_BUFFER_OVERFLOW)
+        {
+            SetLastError(ERROR_FILENAME_EXCED_RANGE);
+        }
+        else
+        {
+            BaseSetLastNTError(Status);
+        }
+        return INVALID_HANDLE_VALUE;
+    }
+
+    return FindFirstChangeNotificationW(NtCurrentTeb()->StaticUnicodeString.Buffer,
+                                        bWatchSubtree, dwNotifyFilter);
 }
 
 
@@ -57,7 +70,7 @@ FindFirstChangeNotificationA (
  * @implemented
  */
 HANDLE
-STDCALL
+WINAPI
 FindFirstChangeNotificationW (
        LPCWSTR lpPathName,
        BOOL    bWatchSubtree,
@@ -92,12 +105,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 +130,7 @@ FindFirstChangeNotificationW (
                                         (BOOLEAN)bWatchSubtree);
    if (!NT_SUCCESS(Status))
    {
+      NtClose(hDir);
       SetLastErrorByStatus(Status);
       return INVALID_HANDLE_VALUE;
    }
@@ -134,7 +143,7 @@ FindFirstChangeNotificationW (
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 FindNextChangeNotification (
        HANDLE  hChangeHandle
        )
@@ -164,7 +173,7 @@ FindNextChangeNotification (
 
 
 extern VOID
-(STDCALL ApcRoutine)(PVOID ApcContext,
+(WINAPI ApcRoutine)(PVOID ApcContext,
       struct _IO_STATUS_BLOCK* IoStatusBlock,
       ULONG Reserved);
 
@@ -173,7 +182,7 @@ extern VOID
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 ReadDirectoryChangesW(
     HANDLE hDirectory,
     LPVOID lpBuffer OPTIONAL,
@@ -185,24 +194,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 : &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);