]> sourceware.org Git - newlib-cygwin.git/commitdiff
* path.cc (copy_cwd_str): Move up in file to be accessible from
authorCorinna Vinschen <corinna@vinschen.de>
Thu, 13 Oct 2011 15:32:10 +0000 (15:32 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Thu, 13 Oct 2011 15:32:10 +0000 (15:32 +0000)
class fcwd_access_t.
(class fcwd_access_t): New class to consolidate and hide the details
of the various FAST_CWD implementations.  Add implementation for
Windows 8 Developer Preview.
(fast_cwd_version): Make static private member of fcwd_access_t.
(fast_cwd_ptr): Change base type to fcwd_access_t.
(find_fast_cwd_pointer): Return fcwd_access_t**.
(find_fast_cwd): Ditto.  Rip out all FAST_CWD implementations and use
fcwd_access_t methods instead.
(cwdstuff::override_win32_cwd): Ditto.

winsup/cygwin/ChangeLog
winsup/cygwin/path.cc

index ad1989ae38347442f1221032c957df1cfa896fbb..7d502bcefc1eeb98fd848dfded14877b608920ea 100644 (file)
@@ -1,3 +1,17 @@
+2011-10-13  Corinna Vinschen  <corinna@vinschen.de>
+
+       * path.cc (copy_cwd_str): Move up in file to be accessible from
+       class fcwd_access_t.
+       (class fcwd_access_t): New class to consolidate and hide the details
+       of the various FAST_CWD implementations.  Add implementation for
+       Windows 8 Developer Preview.
+       (fast_cwd_version): Make static private member of fcwd_access_t.
+       (fast_cwd_ptr): Change base type to fcwd_access_t.
+       (find_fast_cwd_pointer): Return fcwd_access_t**.
+       (find_fast_cwd): Ditto.  Rip out all FAST_CWD implementations and use
+       fcwd_access_t methods instead.
+       (cwdstuff::override_win32_cwd): Ditto.
+
 2011-10-12  Corinna Vinschen  <corinna@vinschen.de>
 
        * fhandler_console.cc (fhandler_console::cursor_set): Disable forcing
index 10b0dfcea6b6e08eb620815d895f5dce8ca5b3a8..f9ed0dc06656ebf19e50255a72be9f84f58ee544 100644 (file)
@@ -3386,6 +3386,17 @@ cygwin_split_path (const char *path, char *dir, char *file)
   file[end - last_slash - 1] = 0;
 }
 
+static inline void
+copy_cwd_str (PUNICODE_STRING tgt, PUNICODE_STRING src)
+{
+  RtlCopyUnicodeString (tgt, src);
+  if (tgt->Buffer[tgt->Length / sizeof (WCHAR) - 1] != L'\\')
+    {
+      tgt->Buffer[tgt->Length / sizeof (WCHAR)] = L'\\';
+      tgt->Length += sizeof (WCHAR);
+    }
+}
+
 /*****************************************************************************/
 
 /* The find_fast_cwd_pointer function and parts of the
@@ -3420,50 +3431,204 @@ cygwin_split_path (const char *path, char *dir, char *file)
    USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
    DAMAGE. */
 
-/* This structure is used to store the CWD starting with Windows Vista.
+/* This class is used to store the CWD starting with Windows Vista.
    The CWD storage in the RTL_USER_PROCESS_PARAMETERS block is only
    an afterthought now.  The actual CWD storage is a FAST_CWD structure
    which is allocated on the process heap.  The new method only requires
    minimal locking and it's much more multi-thread friendly.  Presumably
-   it minimizes contention when accessing the CWD. */
-typedef struct _FAST_CWD {
-  UNICODE_STRING Path;                 /* Path's Buffer member always refers
+   it minimizes contention when accessing the CWD. 
+   The class fcwd_access_t is supposed to encapsulate the gory implementation
+   details depending on OS version from the calling functions. */
+class fcwd_access_t {
+  /* This is the layout used in Windows 8 developer preview. */
+  struct FAST_CWD_8 {
+    LONG           ReferenceCount;     /* Only release when this is 0. */
+    HANDLE         DirectoryHandle;
+    ULONG          OldDismountCount;   /* Reflects the system DismountCount
+                                          at the time the CWD has been set. */
+    UNICODE_STRING Path;               /* Path's Buffer member always refers
+                                          to the following Buffer array. */
+    LONG           FSCharacteristics;  /* Taken from FileFsDeviceInformation */
+    WCHAR          Buffer[MAX_PATH];
+  };
+  /* This is the layout used in Windows 7 and Vista. */
+  struct FAST_CWD_7 {
+    UNICODE_STRING Path;               /* Path's Buffer member always refers
                                           to the following Buffer array. */
-  HANDLE         DirectoryHandle;
-  LONG           FSCharacteristics;    /* Taken from FileFsDeviceInformation */
-  LONG           ReferenceCount;       /* Only release when this is 0. */
-  ULONG          OldDismountCount;     /* Reflects the system DismountCount
+    HANDLE         DirectoryHandle;
+    LONG           FSCharacteristics;  /* Taken from FileFsDeviceInformation */
+    LONG           ReferenceCount;     /* Only release when this is 0. */
+    ULONG          OldDismountCount;   /* Reflects the system DismountCount
                                           at the time the CWD has been set. */
-  WCHAR          Buffer[MAX_PATH];
-} FAST_CWD, *PFAST_CWD;
-
-/* This is the old FAST_CWD structure up to the patch from KB 2393802,
-   release in February 2011.  Hopefully it's not used for long anymore,
-   but for quite some time we can't rely on this fact. */
-typedef struct _FAST_CWD_OLD {
-  LONG           ReferenceCount;       /* Only release when this is 0. */
-  HANDLE         DirectoryHandle;
-  ULONG          OldDismountCount;     /* Reflects the system DismountCount
+    WCHAR          Buffer[MAX_PATH];
+  };
+  /* This is the old FAST_CWD structure up to the patch from KB 2393802,
+     release in February 2011. */
+  struct FAST_CWD_OLD {
+    LONG           ReferenceCount;     /* Only release when this is 0. */
+    HANDLE         DirectoryHandle;
+    ULONG          OldDismountCount;   /* Reflects the system DismountCount
                                           at the time the CWD has been set. */
-  UNICODE_STRING Path;                 /* Path's Buffer member always refers
+    UNICODE_STRING Path;               /* Path's Buffer member always refers
                                           to the following Buffer array. */
-  WCHAR          Buffer[MAX_PATH];
-} FAST_CWD_OLD, *PFAST_CWD_OLD;
+    WCHAR          Buffer[MAX_PATH];
+  };
+  union {
+    FAST_CWD_OLD fold;
+    FAST_CWD_7   f7;
+    FAST_CWD_8   f8;
+  };
 
+  /* Type of FAST_CWD used on this system.  Keeping this information available
+     in shared memory avoids to test for the version every time around.
+     Default to new version. */
+  enum fcwd_version_t {
+    FCWD_OLD,
+    FCWD_W7,
+    FCWD_W8
+  };
+  static fcwd_version_t fast_cwd_version;
+
+#define IMPLEMENT(type, name) \
+  type name () { \
+    switch (fast_cwd_version) { \
+      case FCWD_OLD: \
+      default: \
+       return fold.name; \
+      case FCWD_W7: \
+       return f7.name; \
+      case FCWD_W8: \
+       return f8.name; \
+    } \
+  }
+  IMPLEMENT (LONG &, ReferenceCount)
+  IMPLEMENT (HANDLE &, DirectoryHandle)
+  IMPLEMENT (ULONG &, OldDismountCount)
+  IMPLEMENT (UNICODE_STRING &, Path)
+  IMPLEMENT (WCHAR *, Buffer)
+  /* Special case FSCharacteristics.  Didn't exist originally. */
+  void SetFSCharacteristics (LONG val)
+    {
+      switch (fast_cwd_version)
+       {
+       case FCWD_OLD:
+         break;
+       case FCWD_W7:
+         f7.FSCharacteristics = val;
+         break;
+       case FCWD_W8:
+         f8.FSCharacteristics = val;
+         break;
+       }
+    }
+public:
+  void CopyPath (UNICODE_STRING &target)
+    {
+      /* Copy the Path contents over into the UNICODE_STRING referenced by
+        target.  This is used to set the CurrentDirectoryName in the
+        user parameter block. */
+      target = Path ();
+    }
+  void Free (PVOID heap)
+    {
+      /* Decrement the reference count.  If it's down to 0, free
+        structure from heap. */
+      if (this && InterlockedDecrement (&ReferenceCount ()) == 0)
+       {
+         /* In contrast to pre-Vista, the handle on init is always a
+            fresh one and not the handle inherited from the parent
+            process.  So we always have to close it here.  However, the
+            handle could be NULL, if we cd'ed into a virtual dir. */
+         HANDLE h = DirectoryHandle ();
+         if (h)
+           NtClose (h);
+         RtlFreeHeap (heap, 0, this);
+       }
+    }
+  void FillIn (HANDLE dir, PUNICODE_STRING name, ULONG old_dismount_count)
+    {
+      /* Fill in all values into this FAST_CWD structure. */
+      DirectoryHandle () = dir;
+      ReferenceCount () = 1;
+      OldDismountCount () = old_dismount_count;
+      /* The new structure stores the device characteristics of the
+        volume holding the dir.  RtlGetCurrentDirectory_U checks
+        if the FILE_REMOVABLE_MEDIA flag is set and, if so, checks if
+        the volume is still the same as the one used when opening
+        the directory handle.
+        We don't call NtQueryVolumeInformationFile for the \\?\PIPE,
+        though.  It just returns STATUS_INVALID_HANDLE anyway. */
+      if (fast_cwd_version != FCWD_OLD)
+       {
+         SetFSCharacteristics (0);
+         if (name != &ro_u_pipedir)
+           {
+             IO_STATUS_BLOCK io;
+             FILE_FS_DEVICE_INFORMATION ffdi;
+             if (NT_SUCCESS (NtQueryVolumeInformationFile (dir, &io, &ffdi,
+                             sizeof ffdi, FileFsDeviceInformation)))
+               SetFSCharacteristics (ffdi.Characteristics);
+           }
+       }
+      RtlInitEmptyUnicodeString (&Path (), Buffer (),
+                                MAX_PATH * sizeof (WCHAR));
+      copy_cwd_str (&Path (), name);
+    }
+
+  static void SetDirHandleFromBufferPointer (PWCHAR buf_p, HANDLE dir)
+    {
+      /* Input: The buffer pointer as it's stored in the user parameter block
+        and a directory handle.
+        This function computes the address to the FAST_CWD structure based
+        on the version and overwrites the directory handle.  It is only
+        used if we couldn't figure out the address of fast_cwd_ptr. */
+      fcwd_access_t *f_cwd;
+      switch (fast_cwd_version)
+       {
+       case FCWD_OLD:
+       default:
+         f_cwd = (fcwd_access_t *) 
+           ((PBYTE) buf_p - __builtin_offsetof (FAST_CWD_OLD, Buffer));
+       case FCWD_W7:
+         f_cwd = (fcwd_access_t *) 
+           ((PBYTE) buf_p - __builtin_offsetof (FAST_CWD_7, Buffer));
+       case FCWD_W8:
+         f_cwd = (fcwd_access_t *) 
+           ((PBYTE) buf_p - __builtin_offsetof (FAST_CWD_8, Buffer));
+       }
+      f_cwd->DirectoryHandle () = dir;
+    }
+  static void SetVersionFromPointer (PBYTE buf_p, bool is_buffer)
+    {
+      /* Given a pointer to the FAST_CWD structure (is_buffer == false) or a
+         pointer to the Buffer within (is_buffer == true), this function
+        computes the FAST_CWD version by checking that Path.MaximumLength
+        equals MAX_PATH, and that Path.Buffer == Buffer. */
+      if (is_buffer)
+       buf_p -= __builtin_offsetof (FAST_CWD_8, Buffer);
+      fcwd_access_t *f_cwd = (fcwd_access_t *) buf_p;
+      if (f_cwd->f8.Path.MaximumLength == MAX_PATH * sizeof (WCHAR)
+         && f_cwd->f8.Path.Buffer == f_cwd->f8.Buffer)
+       fast_cwd_version = FCWD_W8;
+      else if (f_cwd->f7.Path.MaximumLength == MAX_PATH * sizeof (WCHAR)
+              && f_cwd->f7.Path.Buffer == f_cwd->f7.Buffer)
+       fast_cwd_version = FCWD_W7;
+      else
+       fast_cwd_version = FCWD_OLD;
+    }
+};
+fcwd_access_t::fcwd_version_t fcwd_access_t::fast_cwd_version
+  __attribute__((section (".cygwin_dll_common"), shared))
+  = fcwd_access_t::FCWD_W7;
 /* fast_cwd_ptr is a pointer to the global pointer in ntdll.dll pointing
    to the FAST_CWD structure which constitutes the CWD.
-
    We put the pointer into the common shared DLL segment.  This allows to
    restrict the call to find_fast_cwd_pointer() to once per Cygwin session
    per user session.  This works, because ASLR randomizes the load address
    of DLLs only once at boot time. */
-static PFAST_CWD *fast_cwd_ptr
-  __attribute__((section (".cygwin_dll_common"), shared)) = (PFAST_CWD *) -1;
-/* Type of FAST_CWD used on this system.  Keeping this information available
-   in shared memory avoids to test for the version every time around.
-   Default to new version. */
-static int fast_cwd_version
-  __attribute__((section (".cygwin_dll_common"), shared)) = 1;
+static fcwd_access_t **fast_cwd_ptr
+  __attribute__((section (".cygwin_dll_common"), shared))
+  = (fcwd_access_t **) -1;
 
 #define peek32(x)      (*(uint32_t *)(x))
 
@@ -3475,7 +3640,7 @@ static int fast_cwd_version
    This code has been tested on Vista 32/64 bit, Server 2008 32/64 bit,
    Windows 7 32/64 bit, and Server 2008 R2 (which is only 64 bit anyway).
    There's some hope that this will still work for Windows 8... */
-static PFAST_CWD *
+static fcwd_access_t **
 find_fast_cwd_pointer ()
 {
   /* Fetch entry points of relevant functions in ntdll.dll. */
@@ -3523,58 +3688,30 @@ find_fast_cwd_pointer ()
   const uint8_t *movesi = rcall + 5;
   if (movesi[0] != 0x8b)
     return NULL;
-  return (PFAST_CWD *) peek32 (movesi + 2);
-}
-
-static inline void
-copy_cwd_str (PUNICODE_STRING tgt, PUNICODE_STRING src)
-{
-  RtlCopyUnicodeString (tgt, src);
-  if (tgt->Buffer[tgt->Length / sizeof (WCHAR) - 1] != L'\\')
-    {
-      tgt->Buffer[tgt->Length / sizeof (WCHAR)] = L'\\';
-      tgt->Length += sizeof (WCHAR);
-    }
+  return (fcwd_access_t **) peek32 (movesi + 2);
 }
 
-static PFAST_CWD *
+static fcwd_access_t **
 find_fast_cwd ()
 {
   /* Fetch the pointer but don't set the global fast_cwd_ptr yet.  First
      we have to make sure we know the version of the FAST_CWD structure
      used on the system. */
-  PFAST_CWD *f_cwd_ptr = find_fast_cwd_pointer ();
+  fcwd_access_t **f_cwd_ptr = find_fast_cwd_pointer ();
   if (!f_cwd_ptr)
     system_printf ("WARNING: Couldn't compute FAST_CWD pointer.  "
                   "Please report this problem to\nthe public mailing "
                   "list cygwin@cygwin.com");
   if (f_cwd_ptr && *f_cwd_ptr)
     {
-      /* Fortunately it's simple to check for the new structure.
-        Path.MaximumLength takes the same space as the high word of
-        the old ReferenceCount.  We know that MaximumLength is always
-        MAX_PATH.  For the ref count this would account for a
-        pratically impossible value between 34078720 and 34079240. */
-      fast_cwd_version = ((*f_cwd_ptr)->Path.MaximumLength
-                         == MAX_PATH * sizeof (WCHAR)) ? 1 : 0;
+      /* Just evaluate structure version. */
+      fcwd_access_t::SetVersionFromPointer ((PBYTE) *f_cwd_ptr, false);
     }
   else
     {
-      /* If we couldn't fetch fast_cwd_ptr, or if fast_cwd_ptr is
-        NULL(*) we have to figure out the version from the Buffer
-        pointer in the ProcessParameters.  We must make sure not
-        to access memory outside of the structure.  Therefore we
-        check the Path.Buffer pointer,
-        which would be the ReferenceCount in the old structure.
-
-        (*) This is very unlikely to happen when starting the first
-        Cygwin process, since it only happens when starting the
-        process in a directory which can't be used as CWD by Win32, or
-        if the directory doesn't exist.  But *if* it happens, we have
-        no valid FAST_CWD structure, even though upp_cwd_str.Buffer is
-        not NULL in that case.  So we let the OS create a valid
-        FAST_CWD structure temporarily to have something to work with.
-        We know the pipe FS works. */
+      /* If we couldn't fetch fast_cwd_ptr, or if fast_cwd_ptr is NULL(*) we
+        have to figure out the version from the Buffer pointer in the
+        ProcessParameters. */
       PEB &peb = *NtCurrentTeb ()->Peb;
 
       if (f_cwd_ptr    /* so *f_cwd_ptr == NULL */
@@ -3582,10 +3719,8 @@ find_fast_cwd ()
        api_fatal ("Couldn't set directory to %S temporarily.\n"
                   "Cannot continue.", &ro_u_pipedir);
       RtlEnterCriticalSection (peb.FastPebLock);
-      PFAST_CWD f_cwd = (PFAST_CWD)
-               ((PBYTE) peb.ProcessParameters->CurrentDirectoryName.Buffer
-                - __builtin_offsetof (struct _FAST_CWD, Buffer));
-      fast_cwd_version = (f_cwd->Path.Buffer == f_cwd->Buffer) ? 1 : 0;
+      fcwd_access_t::SetVersionFromPointer
+       ((PBYTE) peb.ProcessParameters->CurrentDirectoryName.Buffer, true);
       RtlLeaveCriticalSection (peb.FastPebLock);
     }
   /* Eventually, after we set the version as well, set fast_cwd_ptr. */
@@ -3595,8 +3730,6 @@ find_fast_cwd ()
 void
 cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
 {
-  NTSTATUS status;
-  IO_STATUS_BLOCK io;
   HANDLE h = NULL;
 
   PEB &peb = *NtCurrentTeb ()->Peb;
@@ -3605,7 +3738,7 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
 
   if (wincap.has_fast_cwd ())
     {
-      if (fast_cwd_ptr == (PFAST_CWD *) -1)
+      if (fast_cwd_ptr == (fcwd_access_t **) -1)
        fast_cwd_ptr = find_fast_cwd ();
       if (fast_cwd_ptr)
        {
@@ -3613,91 +3746,32 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
             fast_cwd_ptr, we can simply replace the RtlSetCurrentDirectory_U
             function entirely, just as on pre-Vista. */
          PVOID heap = peb.ProcessHeap;
-         /* First allocate a new FAST_CWD structure on the heap.
-            The new FAST_CWD structure is 4 byte bigger than the old one,
+         /* First allocate a new fcwd_access_t structure on the heap.
+            The new fcwd_access_t structure is 4 byte bigger than the old one,
             but we simply don't care, so we allocate always room for the
             new one. */
-         PFAST_CWD f_cwd = (PFAST_CWD)
-                           RtlAllocateHeap (heap, 0, sizeof (FAST_CWD));
+         fcwd_access_t *f_cwd = (fcwd_access_t *)
+                           RtlAllocateHeap (heap, 0, sizeof (fcwd_access_t));
          if (!f_cwd)
            {
              debug_printf ("RtlAllocateHeap failed");
              return;
            }
          /* Fill in the values. */
-         if (fast_cwd_version)
-           {
-             /* New FAST_CWD structure. */
-             FILE_FS_DEVICE_INFORMATION ffdi;
-
-             RtlInitEmptyUnicodeString (&f_cwd->Path, f_cwd->Buffer,
-                                        MAX_PATH * sizeof (WCHAR));
-             f_cwd->DirectoryHandle = dir;
-             /* The new structure stores the device characteristics of the
-                volume holding the dir.  RtlGetCurrentDirectory_U checks
-                if the FILE_REMOVABLE_MEDIA flag is set and, if so, checks if
-                the volume is still the same as the one used when opening
-                the directory handle.
-                We don't call NtQueryVolumeInformationFile for the \\?\PIPE,
-                though.  It just returns STATUS_INVALID_HANDLE anyway. */
-             f_cwd->FSCharacteristics =
-               (!error
-                && NT_SUCCESS (NtQueryVolumeInformationFile (dir, &io, &ffdi,
-                                      sizeof ffdi, FileFsDeviceInformation)))
-               ? ffdi.Characteristics : 0;
-             f_cwd->ReferenceCount = 1;
-             f_cwd->OldDismountCount = old_dismount_count;
-             copy_cwd_str (&f_cwd->Path, error ? &ro_u_pipedir : &win32);
-             /* Use PEB lock when switching fast_cwd_ptr to the new FAST_CWD
-                structure and writing the CWD to the user process parameter
-                block.  This is equivalent to calling RtlAcquirePebLock/
-                RtlReleasePebLock, but without having to go through the FS
-                selector again. */
-             RtlEnterCriticalSection (peb.FastPebLock);
-             PFAST_CWD old_cwd = *fast_cwd_ptr;
-             *fast_cwd_ptr = f_cwd;
-             upp_cwd_str = f_cwd->Path;
-             upp_cwd_hdl = dir;
-             RtlLeaveCriticalSection (peb.FastPebLock);
-             /* Decrement the reference count.  If it's down to 0, free
-                structure from heap. */
-             if (old_cwd
-                 && InterlockedDecrement (&old_cwd->ReferenceCount) == 0)
-               {
-                 /* In contrast to pre-Vista, the handle on init is always a
-                    fresh one and not the handle inherited from the parent
-                    process.  So we always have to close it here.  However, the
-                    handle could be NULL, if we cd'ed into a virtual dir. */
-                 if (old_cwd->DirectoryHandle)
-                   NtClose (old_cwd->DirectoryHandle);
-                 RtlFreeHeap (heap, 0, old_cwd);
-               }
-           }
-         else
-           {
-             /* Old FAST_CWD structure.  Same procedure as above, except for
-                the non-existant FSCharacteristics member. */
-             PFAST_CWD_OLD f_cwd_old = (PFAST_CWD_OLD) f_cwd;
-             f_cwd_old->ReferenceCount = 1;
-             f_cwd_old->DirectoryHandle = dir;
-             f_cwd_old->OldDismountCount = old_dismount_count;
-             RtlInitEmptyUnicodeString (&f_cwd_old->Path, f_cwd_old->Buffer,
-                                        MAX_PATH * sizeof (WCHAR));
-             copy_cwd_str (&f_cwd_old->Path, error ? &ro_u_pipedir : &win32);
-             RtlEnterCriticalSection (peb.FastPebLock);
-             PFAST_CWD_OLD old_cwd = (PFAST_CWD_OLD) *fast_cwd_ptr;
-             *fast_cwd_ptr = (PFAST_CWD) f_cwd_old;
-             upp_cwd_str = f_cwd_old->Path;
-             upp_cwd_hdl = dir;
-             RtlLeaveCriticalSection (peb.FastPebLock);
-             if (old_cwd
-                 && InterlockedDecrement (&old_cwd->ReferenceCount) == 0)
-               {
-                 if (old_cwd->DirectoryHandle)
-                   NtClose (old_cwd->DirectoryHandle);
-                 RtlFreeHeap (heap, 0, old_cwd);
-               }
-           }
+         f_cwd->FillIn (dir, error ? &ro_u_pipedir : &win32,
+                        old_dismount_count);
+         /* Use PEB lock when switching fast_cwd_ptr to the new FAST_CWD
+            structure and writing the CWD to the user process parameter
+            block.  This is equivalent to calling RtlAcquirePebLock/
+            RtlReleasePebLock, but without having to go through the FS
+            selector again. */
+         RtlEnterCriticalSection (peb.FastPebLock);
+         fcwd_access_t *old_cwd = *fast_cwd_ptr;
+         *fast_cwd_ptr = f_cwd;
+         f_cwd->CopyPath (upp_cwd_str);
+         upp_cwd_hdl = dir;
+         RtlLeaveCriticalSection (peb.FastPebLock);
+         old_cwd->Free (heap);
        }
       else
        {
@@ -3727,8 +3801,8 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
             Therefore, use this *only* as a fallback. */
          if (!init)
            {
-             status = RtlSetCurrentDirectory_U (error ? &ro_u_pipedir
-                                                      : &win32);
+             NTSTATUS status =
+               RtlSetCurrentDirectory_U (error ? &ro_u_pipedir : &win32);
              if (!NT_SUCCESS (status))
                {
                  debug_printf ("RtlSetCurrentDirectory_U(%S) failed, %p",
@@ -3739,20 +3813,7 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
          else if (upp_cwd_hdl == NULL)
            return;
          RtlEnterCriticalSection (peb.FastPebLock);
-         if (fast_cwd_version)
-           {
-             PFAST_CWD f_cwd = (PFAST_CWD)
-                       ((PBYTE) upp_cwd_str.Buffer
-                        - __builtin_offsetof (struct _FAST_CWD, Buffer));
-             f_cwd->DirectoryHandle = dir;
-           }
-         else
-           {
-             PFAST_CWD_OLD f_cwd_old = (PFAST_CWD_OLD)
-                       ((PBYTE) upp_cwd_str.Buffer
-                        - __builtin_offsetof (struct _FAST_CWD_OLD, Buffer));
-             f_cwd_old->DirectoryHandle = dir;
-           }
+         fcwd_access_t::SetDirHandleFromBufferPointer(upp_cwd_str.Buffer, dir);
          h = upp_cwd_hdl;
          upp_cwd_hdl = dir;
          RtlLeaveCriticalSection (peb.FastPebLock);
This page took 0.050629 seconds and 5 git commands to generate.