Index: /trunk/src/lib/nt/nthlp.h
===================================================================
--- /trunk/src/lib/nt/nthlp.h	(revision 2703)
+++ /trunk/src/lib/nt/nthlp.h	(revision 2704)
@@ -56,5 +56,9 @@
 HANDLE      birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
                          ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs);
+HANDLE      birdOpenParentDir(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
+                              ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
+                              MY_UNICODE_STRING *pNameUniStr);
 void        birdCloseFile(HANDLE hFile);
+void        birdFreeNtPath(MY_UNICODE_STRING *pNtPath);
 
 
Index: /trunk/src/lib/nt/nthlpfs.c
===================================================================
--- /trunk/src/lib/nt/nthlpfs.c	(revision 2703)
+++ /trunk/src/lib/nt/nthlpfs.c	(revision 2704)
@@ -36,4 +36,10 @@
 
 
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+static int g_fHaveOpenReparsePoint = -1;
+
+
 
 static int birdHasTrailingSlash(const char *pszPath)
@@ -71,5 +77,4 @@
 }
 
-#ifndef BIRD_USE_WIN32
 
 static int birdDosToNtPath(const char *pszPath, MY_UNICODE_STRING *pNtPath)
@@ -112,105 +117,51 @@
 
 
-static void birdFreeNtPath(MY_UNICODE_STRING *pNtPath)
+void birdFreeNtPath(MY_UNICODE_STRING *pNtPath)
 {
     HeapFree(GetProcessHeap(), 0, pNtPath->Buffer);
     pNtPath->Buffer = NULL;
-}
-
-#endif /* !BIRD_USE_WIN32 */
-
-
-HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
-                    ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
-{
-    static int          s_fHaveOpenReparsePoint = -1;
-    HANDLE              hFile;
-#ifdef BIRD_USE_WIN32
-    SECURITY_ATTRIBUTES SecAttr;
-    DWORD               dwErr;
-    DWORD               fW32Disp;
-    DWORD               fW32Flags;
-#else
-    MY_UNICODE_STRING   NtPath;
-    MY_NTSTATUS         rcNt;
-#endif
-
-    birdResolveImports();
-
-    if (birdIsPathDirSpec(pszPath))
-        fCreateOptions |= FILE_DIRECTORY_FILE;
+    pNtPath->Length = 0;
+    pNtPath->MaximumLength = 0;
+}
+
+
+static MY_NTSTATUS birdOpenFileInternal(MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
+                                        ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
+                                        HANDLE *phFile)
+{
+    MY_IO_STATUS_BLOCK      Ios;
+    MY_OBJECT_ATTRIBUTES    ObjAttr;
+    MY_NTSTATUS             rcNt;
+
     if (  (fCreateOptions & FILE_OPEN_REPARSE_POINT)
-        && s_fHaveOpenReparsePoint == 0)
+        && g_fHaveOpenReparsePoint == 0)
         fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
 
-#ifdef BIRD_USE_WIN32
-    /* NT -> W32 */
-
-    SecAttr.nLength              = sizeof(SecAttr);
-    SecAttr.lpSecurityDescriptor = NULL;
-    SecAttr.bInheritHandle       = fObjAttribs & OBJ_INHERIT ? TRUE : FALSE;
-
-    fW32Flags = 0;
-    if (!(fObjAttribs & OBJ_CASE_INSENSITIVE))
-        fW32Flags |= FILE_FLAG_POSIX_SEMANTICS;
-    if (fCreateOptions & FILE_OPEN_FOR_BACKUP_INTENT)
-        fW32Flags |= FILE_FLAG_BACKUP_SEMANTICS;
-    if (fCreateOptions & FILE_OPEN_REPARSE_POINT)
-        fW32Flags |= FILE_FLAG_OPEN_REPARSE_POINT;
-    //?? if (fCreateOptions & FILE_DIRECTORY_FILE)
-    //??    fW32Flags |= ;
-
-    switch (fCreateDisposition)
-    {
-        case FILE_OPEN:             fW32Disp = OPEN_EXISTING; break;
-        case FILE_CREATE:           fW32Disp = CREATE_NEW; break;
-        case FILE_OPEN_IF:          fW32Disp = OPEN_ALWAYS; break;
-        case FILE_OVERWRITE_IF:     fW32Disp = CREATE_ALWAYS; break;
-        default:
-# ifndef NDEBUG
-            __debugbreak();
-# endif
-            return INVALID_HANDLE_VALUE;
-    }
-
-    hFile = CreateFileA(pszPath, fDesiredAccess, fShareAccess, &SecAttr, fW32Disp, fW32Flags, NULL /*hTemplateFile*/);
-    if (hFile != INVALID_HANDLE_VALUE)
-        return hFile;
-
-    dwErr = GetLastError();
-
-    /* Deal with FILE_FLAG_OPEN_REPARSE_POINT the first times around. */
-    if (   dwErr == ERROR_INVALID_PARAMETER
-        && s_fHaveOpenReparsePoint < 0
-        && (fCreateOptions & FILE_OPEN_REPARSE_POINT) )
+    Ios.Information = -1;
+    Ios.u.Status = 0;
+    MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
+
+    rcNt = g_pfnNtCreateFile(phFile,
+                             fDesiredAccess,
+                             &ObjAttr,
+                             &Ios,
+                             NULL,   /* cbFileInitialAlloc */
+                             fFileAttribs,
+                             fShareAccess,
+                             fCreateDisposition,
+                             fCreateOptions,
+                             NULL,   /* pEaBuffer */
+                             0);     /* cbEaBuffer*/
+    if (   rcNt == STATUS_INVALID_PARAMETER
+        && g_fHaveOpenReparsePoint < 0
+        && (fCreateOptions & FILE_OPEN_REPARSE_POINT))
     {
         fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
-        fW32Flags      &= ~FILE_FLAG_OPEN_REPARSE_POINT;
-        hFile = CreateFileA(pszPath, fDesiredAccess, fFileAttribs, &SecAttr, fW32Disp, fW32Flags, NULL /*hTemplateFile*/);
-        if (hFile != INVALID_HANDLE_VALUE)
-        {
-            s_fHaveOpenReparsePoint = 0;
-            return hFile;
-        }
-    }
-
-    birdSetErrnoFromWin32(dwErr);
-
-#else  /* !BIRD_USE_WIN32 */
-
-    /*
-     * Call the NT API directly.
-     */
-    if (birdDosToNtPath(pszPath, &NtPath) == 0)
-    {
-        MY_IO_STATUS_BLOCK      Ios;
-        MY_OBJECT_ATTRIBUTES    ObjAttr;
 
         Ios.Information = -1;
         Ios.u.Status = 0;
-
-        MyInitializeObjectAttributes(&ObjAttr, &NtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
-
-        rcNt = g_pfnNtCreateFile(&hFile,
+        MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
+
+        rcNt = g_pfnNtCreateFile(phFile,
                                  fDesiredAccess,
                                  &ObjAttr,
@@ -223,4 +174,33 @@
                                  NULL,   /* pEaBuffer */
                                  0);     /* cbEaBuffer*/
+        if (rcNt != STATUS_INVALID_PARAMETER)
+            g_fHaveOpenReparsePoint = 0;
+    }
+    return rcNt;
+}
+
+
+HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
+                    ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
+{
+    MY_UNICODE_STRING   NtPath;
+    MY_NTSTATUS         rcNt;
+
+    birdResolveImports();
+
+    /*
+     * Adjust inputs.
+     */
+    if (birdIsPathDirSpec(pszPath))
+        fCreateOptions |= FILE_DIRECTORY_FILE;
+
+    /*
+     * Call the NT API directly.
+     */
+    if (birdDosToNtPath(pszPath, &NtPath) == 0)
+    {
+        HANDLE hFile;
+        rcNt = birdOpenFileInternal(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
+                                    fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
         if (MY_NT_SUCCESS(rcNt))
         {
@@ -233,17 +213,94 @@
     }
 
-#endif /* !BIRD_USE_WIN32 */
     return INVALID_HANDLE_VALUE;
 }
 
 
+HANDLE birdOpenParentDir(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
+                         ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
+                         MY_UNICODE_STRING *pNameUniStr)
+{
+    MY_UNICODE_STRING   NtPath;
+    MY_NTSTATUS         rcNt;
+
+    birdResolveImports();
+
+    /*
+     * Adjust inputs.
+     */
+    fCreateOptions |= FILE_DIRECTORY_FILE;
+
+    /*
+     * Convert the path and split off the filename.
+     */
+    if (birdDosToNtPath(pszPath, &NtPath) == 0)
+    {
+        USHORT offName = NtPath.Length / sizeof(WCHAR);
+        USHORT cwcName = offName;
+        WCHAR  wc = 0;
+
+        while (   offName > 0
+               && (wc = NtPath.Buffer[offName - 1]) != '\\'
+               && wc != '/'
+               && wc != ':')
+            offName--;
+        if (offName > 0)
+        {
+            cwcName -= offName;
+
+            /* Make a copy of the file name, if requested. */
+            rcNt = STATUS_SUCCESS;
+            if (pNameUniStr)
+            {
+                pNameUniStr->Length        = cwcName * sizeof(WCHAR);
+                pNameUniStr->MaximumLength = pNameUniStr->Length + sizeof(WCHAR);
+                pNameUniStr->Buffer        = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, pNameUniStr->MaximumLength);
+                if (pNameUniStr->Buffer)
+                {
+                    memcpy(pNameUniStr->Buffer, &NtPath.Buffer[offName],pNameUniStr->Length);
+                    pNameUniStr->Buffer[cwcName] = '\0';
+                }
+                else
+                    rcNt = STATUS_NO_MEMORY;
+            }
+
+            /* Chop, chop. */
+            // Bad idea, breaks \\?\c:\pagefile.sys. //while (   offName > 0
+            // Bad idea, breaks \\?\c:\pagefile.sys. //       && (   (wc = NtPath.Buffer[offName - 1]) == '\\'
+            // Bad idea, breaks \\?\c:\pagefile.sys. //           || wc == '/'))
+            // Bad idea, breaks \\?\c:\pagefile.sys. //    offName--;
+            NtPath.Length = offName * sizeof(WCHAR);
+            NtPath.Buffer[offName] = '\0';
+            if (MY_NT_SUCCESS(rcNt))
+            {
+                /*
+                 * Finally, try open the directory.
+                 */
+                HANDLE hFile;
+                rcNt = birdOpenFileInternal(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
+                                            fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
+                if (MY_NT_SUCCESS(rcNt))
+                {
+                    birdFreeNtPath(&NtPath);
+                    return hFile;
+                }
+            }
+
+            if (pNameUniStr)
+                birdFreeNtPath(pNameUniStr);
+        }
+
+        birdFreeNtPath(&NtPath);
+        birdSetErrnoFromNt(rcNt);
+    }
+
+    return INVALID_HANDLE_VALUE;
+}
+
+
 void birdCloseFile(HANDLE hFile)
 {
-#ifdef BIRD_USE_WIN32
-    CloseHandle(hFile);
-#else
     birdResolveImports();
     g_pfnNtClose(hFile);
-#endif
-}
-
+}
+
Index: /trunk/src/lib/nt/ntstat.c
===================================================================
--- /trunk/src/lib/nt/ntstat.c	(revision 2703)
+++ /trunk/src/lib/nt/ntstat.c	(revision 2704)
@@ -133,5 +133,6 @@
 
     /* File type. */
-    if (fAttribs & FILE_ATTRIBUTE_REPARSE_POINT)
+    if (  (fAttribs & FILE_ATTRIBUTE_REPARSE_POINT)
+        && hFile != INVALID_HANDLE_VALUE)
     {
         MY_FILE_ATTRIBUTE_TAG_INFORMATION   TagInfo;
@@ -357,9 +358,86 @@
         //fprintf(stderr, "stat: %s -> %u\n", pszPath, GetLastError());
 
-        /* On things like pagefile.sys we may get sharing violation. */
-        if (errno == ETXTBSY)
-        {
-            /** @todo Fall back on the parent directory enum if we run into a sharing
-             *        violation. */
+        /*
+         * On things like pagefile.sys we may get sharing violation.  We fall
+         * back on directory enumeration for dealing with that.
+         */
+        if (   errno == ETXTBSY
+            && strchr(pszPath, '*') == NULL /* Serious paranoia... */
+            && strchr(pszPath, '?') == NULL)
+        {
+            MY_UNICODE_STRING NameUniStr;
+            hFile = birdOpenParentDir(pszPath,
+                                      FILE_READ_DATA | SYNCHRONIZE,
+                                      FILE_ATTRIBUTE_NORMAL,
+                                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                                      FILE_OPEN,
+                                      FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
+                                      OBJ_CASE_INSENSITIVE,
+                                      &NameUniStr);
+            if (hFile != INVALID_HANDLE_VALUE)
+            {
+                MY_FILE_ID_FULL_DIR_INFORMATION *pBuf;
+                ULONG               cbBuf = sizeof(*pBuf) + NameUniStr.MaximumLength + 1024;
+                MY_IO_STATUS_BLOCK  Ios;
+                MY_NTSTATUS         rcNt;
+
+                pBuf = (MY_FILE_ID_FULL_DIR_INFORMATION *)alloca(cbBuf);
+                Ios.u.Status    = -1;
+                Ios.Information = -1;
+                rcNt = g_pfnNtQueryDirectoryFile(hFile, NULL, NULL, NULL, &Ios, pBuf, cbBuf,
+                                                 MyFileIdFullDirectoryInformation, FALSE, &NameUniStr, TRUE);
+                if (MY_NT_SUCCESS(rcNt))
+                    rcNt = Ios.u.Status;
+                if (MY_NT_SUCCESS(rcNt))
+                {
+                    /*
+                     * Convert the data.
+                     */
+                    pStat->st_mode          = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,
+                                                                 NULL, &pStat->st_dirsymlink);
+                    pStat->st_padding0[0]   = 0;
+                    pStat->st_padding0[1]   = 0;
+                    pStat->st_size          = pBuf->EndOfFile.QuadPart;
+                    birdNtTimeToTimeSpec(pBuf->CreationTime.QuadPart,   &pStat->st_birthtim);
+                    birdNtTimeToTimeSpec(pBuf->ChangeTime.QuadPart,     &pStat->st_ctim);
+                    birdNtTimeToTimeSpec(pBuf->LastWriteTime.QuadPart,  &pStat->st_mtim);
+                    birdNtTimeToTimeSpec(pBuf->LastAccessTime.QuadPart, &pStat->st_atim);
+                    pStat->st_ino           = pBuf->FileId.QuadPart;
+                    pStat->st_nlink         = 1;
+                    pStat->st_rdev          = 0;
+                    pStat->st_uid           = 0;
+                    pStat->st_gid           = 0;
+                    pStat->st_padding1[0]   = 0;
+                    pStat->st_padding1[1]   = 0;
+                    pStat->st_padding1[2]   = 0;
+                    pStat->st_blksize       = 65536;
+                    pStat->st_blocks        = (pBuf->AllocationSize.QuadPart + BIRD_STAT_BLOCK_SIZE - 1)
+                                            / BIRD_STAT_BLOCK_SIZE;
+
+                    /* Get the serial number, reusing the buffer from above. */
+                    rcNt = g_pfnNtQueryVolumeInformationFile(hFile, &Ios, pBuf, cbBuf, MyFileFsVolumeInformation);
+                    if (MY_NT_SUCCESS(rcNt))
+                        rcNt = Ios.u.Status;
+                    if (MY_NT_SUCCESS(rcNt))
+                    {
+                        MY_FILE_FS_VOLUME_INFORMATION const *pVolInfo = (MY_FILE_FS_VOLUME_INFORMATION const *)pBuf;
+                        pStat->st_dev       = pVolInfo->VolumeSerialNumber
+                                            | (pVolInfo->VolumeCreationTime.QuadPart << 32);
+                        rc = 0;
+                    }
+                    else
+                    {
+                        pStat->st_dev       = 0;
+                        rc = birdSetErrnoFromNt(rcNt);
+                    }
+                }
+
+                birdFreeNtPath(&NameUniStr);
+                birdCloseFile(hFile);
+
+                if (MY_NT_SUCCESS(rcNt))
+                    return 0;
+                birdSetErrnoFromNt(rcNt);
+            }
         }
         rc = -1;
Index: /trunk/src/lib/nt/ntstuff.h
===================================================================
--- /trunk/src/lib/nt/ntstuff.h	(revision 2703)
+++ /trunk/src/lib/nt/ntstuff.h	(revision 2704)
@@ -179,4 +179,22 @@
 /** The sizeof(MY_FILE_NAMES_INFORMATION) without the FileName. */
 #define MIN_SIZEOF_MY_FILE_NAMES_INFORMATION  (4 + 4 + 4)
+
+
+typedef struct MY_FILE_ID_FULL_DIR_INFORMATION
+{
+    ULONG           NextEntryOffset;
+    ULONG           FileIndex;
+    LARGE_INTEGER   CreationTime;
+    LARGE_INTEGER   LastAccessTime;
+    LARGE_INTEGER   LastWriteTime;
+    LARGE_INTEGER   ChangeTime;
+    LARGE_INTEGER   EndOfFile;
+    LARGE_INTEGER   AllocationSize;
+    ULONG           FileAttributes;
+    ULONG           FileNameLength;
+    ULONG           EaSize;
+    LARGE_INTEGER   FileId;
+    WCHAR           FileName[1];
+} MY_FILE_ID_FULL_DIR_INFORMATION;
 
 
