OSDN Git Service

* ntdll.h (NtNotifyChangeDirectoryFile): Declare.
authorcorinna <corinna>
Tue, 21 Aug 2007 12:37:38 +0000 (12:37 +0000)
committercorinna <corinna>
Tue, 21 Aug 2007 12:37:38 +0000 (12:37 +0000)
(NtQueryAttributesFile): Move to maintain alphabetical order of
declarations.  Add comment to note that timestamp information returned
by NtQueryAttributesFile is unreliable.
* path.h (etc::changed_h): Move here.
(etc::fn): Change type to OBJECT_ATTRIBUTES.
(etc::last_modified): Change type to LARGE_INTEGER.
(etc::init): Take PUNICODE_STRING as second argument.
* path.cc: Accomodate above changes.
(etc::test_file_change): Use NT native functions.
(etc::dir_changed): Ditto.
* uinfo.cc (pwdgrp::load): Call etc::init with NT native path.

winsup/cygwin/ChangeLog
winsup/cygwin/ntdll.h
winsup/cygwin/path.cc
winsup/cygwin/path.h
winsup/cygwin/uinfo.cc

index cb80c58..7ed188d 100644 (file)
@@ -1,5 +1,20 @@
 2007-08-21  Corinna Vinschen  <corinna@vinschen.de>
 
+       * ntdll.h (NtNotifyChangeDirectoryFile): Declare.
+       (NtQueryAttributesFile): Move to maintain alphabetical order of
+       declarations.  Add comment to note that timestamp information returned
+       by NtQueryAttributesFile is unreliable.
+       * path.h (etc::changed_h): Move here.
+       (etc::fn): Change type to OBJECT_ATTRIBUTES.
+       (etc::last_modified): Change type to LARGE_INTEGER.
+       (etc::init): Take PUNICODE_STRING as second argument.
+       * path.cc: Accomodate above changes.
+       (etc::test_file_change): Use NT native functions.
+       (etc::dir_changed): Ditto.
+       * uinfo.cc (pwdgrp::load): Call etc::init with NT native path.
+
+2007-08-21  Corinna Vinschen  <corinna@vinschen.de>
+
        * fhandler_disk_file.cc: Change debugging output througout to print
        the NT status consistently.  Use UNICODE path information if available.
 
index ff9f955..f5c0797 100644 (file)
@@ -779,11 +779,19 @@ extern "C"
   NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG, ULONG,
                                     PLARGE_INTEGER, PULONG, SECTION_INHERIT,
                                     ULONG, ULONG);
+  NTSTATUS NTAPI NtNotifyChangeDirectoryFile (HANDLE, HANDLE, PIO_APC_ROUTINE,
+                                              PVOID, PIO_STATUS_BLOCK,
+                                             PFILE_NOTIFY_INFORMATION, ULONG,
+                                             ULONG, BOOLEAN);
   NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK,
                                        POBJECT_ATTRIBUTES);
   NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
                             PIO_STATUS_BLOCK, ULONG, ULONG);
   NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
+  /* WARNING!  Don't rely on the timestamp information returned by
+     NtQueryAttributesFile.  Only the DOS file attribute info is reliable. */
+  NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
+                                       PFILE_BASIC_INFORMATION);
   NTSTATUS NTAPI NtQueryDirectoryFile(HANDLE, HANDLE, PVOID, PVOID,
                                      PIO_STATUS_BLOCK, PVOID, ULONG,
                                      FILE_INFORMATION_CLASS, BOOLEAN,
@@ -792,8 +800,6 @@ extern "C"
                                         BOOLEAN, PULONG, PULONG);
   NTSTATUS NTAPI NtQueryEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
                                BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN);
-  NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
-                                       PFILE_BASIC_INFORMATION);
   NTSTATUS NTAPI NtQueryFullAttributesFile (POBJECT_ATTRIBUTES,
                                            PFILE_NETWORK_OPEN_INFORMATION);
   NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
index e3377a0..8dcccc8 100644 (file)
@@ -4456,11 +4456,11 @@ out:
 int etc::curr_ix = 0;
 /* Note that the first elements of the below arrays are unused */
 bool etc::change_possible[MAX_ETC_FILES + 1];
-const char *etc::fn[MAX_ETC_FILES + 1];
-FILETIME etc::last_modified[MAX_ETC_FILES + 1];
+OBJECT_ATTRIBUTES etc::fn[MAX_ETC_FILES + 1];
+LARGE_INTEGER etc::last_modified[MAX_ETC_FILES + 1];
 
 int
-etc::init (int n, const char *etc_fn)
+etc::init (int n, PUNICODE_STRING etc_fn)
 {
   if (n > 0)
     /* ok */;
@@ -4469,35 +4469,36 @@ etc::init (int n, const char *etc_fn)
   else
     api_fatal ("internal error");
 
-  fn[n] = etc_fn;
+  InitializeObjectAttributes (&fn[n], etc_fn, OBJ_CASE_INSENSITIVE, NULL, NULL);
   change_possible[n] = false;
   test_file_change (n);
-  paranoid_printf ("fn[%d] %s, curr_ix %d", n, fn[n], curr_ix);
+  paranoid_printf ("fn[%d] %S, curr_ix %d", n, fn[n].ObjectName, curr_ix);
   return n;
 }
 
 bool
 etc::test_file_change (int n)
 {
-  HANDLE h;
-  WIN32_FIND_DATA data;
+  NTSTATUS status;
+  FILE_NETWORK_OPEN_INFORMATION fnoi;
   bool res;
 
-  if ((h = FindFirstFile (fn[n], &data)) == INVALID_HANDLE_VALUE)
+  status = NtQueryFullAttributesFile (&fn[n], &fnoi);
+  if (!NT_SUCCESS (status))
     {
       res = true;
       memset (last_modified + n, 0, sizeof (last_modified[n]));
-      debug_printf ("FindFirstFile failed, %E");
+      debug_printf ("NtQueryFullAttributesFile (%S) failed, %p",
+                   fn[n].ObjectName, status);
     }
   else
     {
-      FindClose (h);
-      res = CompareFileTime (&data.ftLastWriteTime, last_modified + n) > 0;
-      last_modified[n] = data.ftLastWriteTime;
-      debug_printf ("FindFirstFile succeeded");
+      res = CompareFileTime ((FILETIME *) &fnoi.LastWriteTime,
+                            (FILETIME *) last_modified + n) > 0;
+      last_modified[n].QuadPart = fnoi.LastWriteTime.QuadPart;
     }
 
-  paranoid_printf ("fn[%d] %s res %d", n, fn[n], res);
+  paranoid_printf ("fn[%d] %S res %d", n, fn[n].ObjectName, res);
   return res;
 }
 
@@ -4507,17 +4508,42 @@ etc::dir_changed (int n)
   if (!change_possible[n])
     {
       static HANDLE changed_h NO_COPY;
+      NTSTATUS status;
+      IO_STATUS_BLOCK io;
 
       if (!changed_h)
        {
-         path_conv pwd ("/etc");
-         changed_h = FindFirstChangeNotification (pwd.get_win32 (), FALSE,
-                                                 FILE_NOTIFY_CHANGE_LAST_WRITE
-                                                 | FILE_NOTIFY_CHANGE_FILE_NAME);
+         OBJECT_ATTRIBUTES attr;
+
+         path_conv dir ("/etc");
+         status = NtOpenFile (&changed_h, SYNCHRONIZE | FILE_LIST_DIRECTORY,
+                              dir.get_object_attr (attr, sec_none_nih), &io,
+                              FILE_SHARE_VALID_FLAGS, FILE_DIRECTORY_FILE);
+         if (!NT_SUCCESS (status))
+           {
+#ifdef DEBUGGING
+             system_printf ("NtOpenFile (%S) failed, %p",
+                            dir.get_nt_native_path (), status);
+#endif
+             changed_h = INVALID_HANDLE_VALUE;
+           }
+         else
+           {
+             status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL,
+                                               NULL, &io, NULL, 0,
+                                               FILE_NOTIFY_CHANGE_LAST_WRITE
+                                               | FILE_NOTIFY_CHANGE_FILE_NAME,
+                                               FALSE);
+             if (!NT_SUCCESS (status))
+               {
 #ifdef DEBUGGING
-         if (changed_h == INVALID_HANDLE_VALUE)
-           system_printf ("Can't open %s for checking, %E", (char *) pwd);
+                 system_printf ("NtNotifyChangeDirectoryFile (1) failed, %p",
+                                status);
 #endif
+                 NtClose (changed_h);
+                 changed_h = INVALID_HANDLE_VALUE;
+               }
+           }
          memset (change_possible, true, sizeof (change_possible));
        }
 
@@ -4525,12 +4551,26 @@ etc::dir_changed (int n)
        change_possible[n] = true;
       else if (WaitForSingleObject (changed_h, 0) == WAIT_OBJECT_0)
        {
-         FindNextChangeNotification (changed_h);
+         status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL,
+                                               NULL, &io, NULL, 0,
+                                               FILE_NOTIFY_CHANGE_LAST_WRITE
+                                               | FILE_NOTIFY_CHANGE_FILE_NAME,
+                                               FALSE);
+         if (!NT_SUCCESS (status))
+           {
+#ifdef DEBUGGING
+             system_printf ("NtNotifyChangeDirectoryFile (2) failed, %p",
+                            status);
+#endif
+             NtClose (changed_h);
+             changed_h = INVALID_HANDLE_VALUE;
+           }
          memset (change_possible, true, sizeof change_possible);
        }
     }
 
-  paranoid_printf ("fn[%d] %s change_possible %d", n, fn[n], change_possible[n]);
+  paranoid_printf ("fn[%d] %S change_possible %d",
+                  n, fn[n].ObjectName, change_possible[n]);
   return change_possible[n];
 }
 
@@ -4541,7 +4581,7 @@ etc::file_changed (int n)
   if (dir_changed (n) && test_file_change (n))
     res = true;
   change_possible[n] = false;  /* Change is no longer possible */
-  paranoid_printf ("fn[%d] %s res %d", n, fn[n], res);
+  paranoid_printf ("fn[%d] %S res %d", n, fn[n].ObjectName, res);
   return res;
 }
 
index b258ac9..5bf9717 100644 (file)
@@ -336,11 +336,12 @@ class etc
 {
   friend class dtable;
   static int curr_ix;
+  static HANDLE changed_h;
   static bool change_possible[MAX_ETC_FILES + 1];
-  static const char *fn[MAX_ETC_FILES + 1];
-  static FILETIME last_modified[MAX_ETC_FILES + 1];
+  static OBJECT_ATTRIBUTES fn[MAX_ETC_FILES + 1];
+  static LARGE_INTEGER last_modified[MAX_ETC_FILES + 1];
   static bool dir_changed (int);
-  static int init (int, const char *);
+  static int init (int, PUNICODE_STRING);
   static bool file_changed (int);
   static bool test_file_change (int);
   friend class pwdgrp;
index 4ebe724..210b1d1 100644 (file)
@@ -518,7 +518,7 @@ pwdgrp::load (const char *posix_fname)
   curr_lines = 0;
 
   pc.check (posix_fname);
-  etc_ix = etc::init (etc_ix, pc.get_win32 ());
+  etc_ix = etc::init (etc_ix, pc.get_nt_native_path ());
 
   paranoid_printf ("%s", posix_fname);