Index: trunk/src/VBox/Runtime/r3/nt/RTFileSetMode-r3-nt.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/nt/RTFileSetMode-r3-nt.cpp	(revision 69795)
+++ trunk/src/VBox/Runtime/r3/nt/RTFileSetMode-r3-nt.cpp	(revision 69795)
@@ -0,0 +1,84 @@
+/* $Id$ */
+/** @file
+ * IPRT - RTFileSetMode, Native NT.
+ */
+
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_FILE
+#include "internal-r3-nt.h"
+
+#include <iprt/file.h>
+#include <iprt/err.h>
+
+#include "internal/fs.h"
+
+
+/**
+ * Common worker for RTFileSetMode, RTPathSetMode and RTDirRelPathSetMode.
+ *
+ * @returns IPRT status code.
+ * @param   hNativeFile The NT handle to the file system object.
+ * @param   fMode       Valid and normalized file mode mask to set.
+ */
+DECLHIDDEN(int) rtNtFileSetModeWorker(HANDLE hNativeFile, RTFMODE fMode)
+{
+    IO_STATUS_BLOCK         Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+    FILE_BASIC_INFORMATION  BasicInfo;
+    BasicInfo.CreationTime.QuadPart   = 0;
+    BasicInfo.ChangeTime.QuadPart     = 0;
+    BasicInfo.LastAccessTime.QuadPart = 0;
+    BasicInfo.LastWriteTime.QuadPart  = 0;
+    BasicInfo.FileAttributes          = (fMode & ~(  RTFS_DOS_NT_ENCRYPTED
+                                                   | RTFS_DOS_NT_COMPRESSED
+                                                   | RTFS_DOS_NT_REPARSE_POINT
+                                                   | RTFS_DOS_NT_SPARSE_FILE
+                                                   | RTFS_DOS_NT_DEVICE
+                                                   | RTFS_DOS_DIRECTORY)
+                                               & RTFS_DOS_MASK_NT)
+                                      >> RTFS_DOS_SHIFT;
+    Assert(!(BasicInfo.FileAttributes & ~0x31a7U /* FILE_ATTRIBUTE_VALID_SET_FLAGS */));
+    if (!BasicInfo.FileAttributes)
+        BasicInfo.FileAttributes |= FILE_ATTRIBUTE_NORMAL;
+
+    NTSTATUS rcNt = NtSetInformationFile(hNativeFile, &Ios, &BasicInfo, sizeof(BasicInfo), FileBasicInformation);
+    if (NT_SUCCESS(rcNt))
+        return VINF_SUCCESS;
+    return RTErrConvertFromNtStatus(rcNt);
+}
+
+
+RTDECL(int) RTFileSetMode(RTFILE hFile, RTFMODE fMode)
+{
+    HANDLE hNative = (HANDLE)RTFileToNative(hFile);
+    AssertReturn(hNative != RTNT_INVALID_HANDLE_VALUE, VERR_INVALID_HANDLE);
+    fMode = rtFsModeNormalize(fMode, NULL, 0);
+    AssertReturn(rtFsModeIsValidPermissions(fMode), VERR_INVALID_FMODE);
+
+    return rtNtFileSetModeWorker(hNative, fMode);
+}
+
+
Index: trunk/src/VBox/Runtime/r3/nt/RTPathSetMode-r3-nt.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/nt/RTPathSetMode-r3-nt.cpp	(revision 69795)
+++ trunk/src/VBox/Runtime/r3/nt/RTPathSetMode-r3-nt.cpp	(revision 69795)
@@ -0,0 +1,88 @@
+/* $Id$ */
+/** @file
+ * IPRT - RTPathSetMode, Native NT.
+ */
+
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#define LOG_GROUP RTLOGGROUP_FILE
+#include "internal-r3-nt.h"
+
+#include <iprt/path.h>
+#include <iprt/err.h>
+
+#include "internal/fs.h"
+
+
+
+RTDECL(int) RTPathSetMode(const char *pszPath, RTFMODE fMode)
+{
+    fMode = rtFsModeNormalize(fMode, pszPath, 0);
+    AssertReturn(rtFsModeIsValidPermissions(fMode), VERR_INVALID_FMODE);
+
+    /*
+     * Convert and normalize the path.
+     */
+    UNICODE_STRING NtName;
+    HANDLE         hRootDir;
+    int rc = RTNtPathFromWinUtf8(&NtName, &hRootDir, pszPath);
+    if (RT_SUCCESS(rc))
+    {
+        HANDLE              hPath   = RTNT_INVALID_HANDLE_VALUE;
+        IO_STATUS_BLOCK     Ios     = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+        OBJECT_ATTRIBUTES   ObjAttr;
+        InitializeObjectAttributes(&ObjAttr, &NtName, 0 /*fAttrib*/, hRootDir, NULL);
+
+        ULONG fOpenOptions = FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT;
+        //if (fFlags & RTPATH_F_ON_LINK)
+        //    fOpenOptions |= FILE_OPEN_REPARSE_POINT;
+        NTSTATUS rcNt = NtCreateFile(&hPath,
+                                     FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
+                                     &ObjAttr,
+                                     &Ios,
+                                     NULL /*AllocationSize*/,
+                                     FILE_ATTRIBUTE_NORMAL,
+                                     FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                     FILE_OPEN,
+                                     fOpenOptions,
+                                     NULL /*EaBuffer*/,
+                                     0 /*EaLength*/);
+        if (NT_SUCCESS(rcNt))
+        {
+            rc = rtNtFileSetModeWorker(hPath, fMode);
+
+            rcNt = NtClose(hPath);
+            if (!NT_SUCCESS(rcNt) && RT_SUCCESS(rc))
+                rc = RTErrConvertFromNtStatus(rcNt);
+        }
+        else
+            rc = RTErrConvertFromNtStatus(rcNt);
+
+        RTNtPathFree(&NtName, &hRootDir);
+    }
+    return rc;
+}
+
Index: trunk/src/VBox/Runtime/r3/nt/dirrel-r3-nt.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/nt/dirrel-r3-nt.cpp	(revision 69760)
+++ trunk/src/VBox/Runtime/r3/nt/dirrel-r3-nt.cpp	(revision 69795)
@@ -414,17 +414,48 @@
     AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
+    fMode = rtFsModeNormalize(fMode, pszRelPath, 0);
+    AssertReturn(rtFsModeIsValidPermissions(fMode), VERR_INVALID_FMODE);
     AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_FLAGS);
 
-    char szPath[RTPATH_MAX];
-    int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelPath);
-    if (RT_SUCCESS(rc))
-    {
-RTAssertMsg2("DBG: RTDirRelPathSetMode(%s)...\n", szPath);
-#ifndef RT_OS_WINDOWS
-        rc = RTPathSetMode(szPath, fMode); /** @todo fFlags is currently ignored. */
-#else
-        rc = VERR_NOT_IMPLEMENTED; /** @todo implement RTPathSetMode on windows. */
-        RT_NOREF(fMode);
-#endif
+    /*
+     * Convert and normalize the path.
+     */
+    UNICODE_STRING NtName;
+    HANDLE hRoot = pThis->hDir;
+    int rc = RTNtPathRelativeFromUtf8(&NtName, &hRoot, pszRelPath, RTDIRREL_NT_GET_ASCENT(pThis),
+                                      pThis->enmInfoClass == FileMaximumInformation);
+    if (RT_SUCCESS(rc))
+    {
+        HANDLE              hSubDir = RTNT_INVALID_HANDLE_VALUE;
+        IO_STATUS_BLOCK     Ios     = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+        OBJECT_ATTRIBUTES   ObjAttr;
+        InitializeObjectAttributes(&ObjAttr, &NtName, 0 /*fAttrib*/, hRoot, NULL);
+
+        ULONG fOpenOptions = FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT;
+        if (fFlags & RTPATH_F_ON_LINK)
+            fOpenOptions |= FILE_OPEN_REPARSE_POINT;
+        NTSTATUS rcNt = NtCreateFile(&hSubDir,
+                                     FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
+                                     &ObjAttr,
+                                     &Ios,
+                                     NULL /*AllocationSize*/,
+                                     FILE_ATTRIBUTE_NORMAL,
+                                     FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                     FILE_OPEN,
+                                     fOpenOptions,
+                                     NULL /*EaBuffer*/,
+                                     0 /*EaLength*/);
+        if (NT_SUCCESS(rcNt))
+        {
+            rc = rtNtFileSetModeWorker(hSubDir, fMode);
+
+            rcNt = NtClose(hSubDir);
+            if (!NT_SUCCESS(rcNt) && RT_SUCCESS(rc))
+                rc = RTErrConvertFromNtStatus(rcNt);
+        }
+        else
+            rc = RTErrConvertFromNtStatus(rcNt);
+
+        RTNtPathFree(&NtName, NULL);
     }
     return rc;
Index: trunk/src/VBox/Runtime/r3/nt/internal-r3-nt.h
===================================================================
--- trunk/src/VBox/Runtime/r3/nt/internal-r3-nt.h	(revision 69760)
+++ trunk/src/VBox/Runtime/r3/nt/internal-r3-nt.h	(revision 69795)
@@ -69,2 +69,11 @@
 #endif
 
+/**
+ * Common worker for RTFileSetMode, RTPathSetMode and RTDirRelPathSetMode.
+ *
+ * @returns IPRT status code.
+ * @param   hNativeFile The NT handle to the file system object.
+ * @param   fMode       Valid and normalized file mode mask to set.
+ */
+DECLHIDDEN(int) rtNtFileSetModeWorker(HANDLE hNativeFile, RTFMODE fMode);
+
Index: trunk/src/VBox/Runtime/r3/win/fileio-win.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/win/fileio-win.cpp	(revision 69760)
+++ trunk/src/VBox/Runtime/r3/win/fileio-win.cpp	(revision 69795)
@@ -977,4 +977,5 @@
 
 
+#if 0 /* RTFileSetMode is implemented by RTFileSetMode-r3-nt.cpp */
 /* This comes from a source file with a different set of system headers (DDK)
  * so it can't be declared in a common header, like internal/file.h.
@@ -1003,4 +1004,5 @@
     return VINF_SUCCESS;
 }
+#endif
 
 
Index: trunk/src/VBox/Runtime/r3/win/rtFileNativeSetAttributes-win.cpp
===================================================================
--- trunk/src/VBox/Runtime/r3/win/rtFileNativeSetAttributes-win.cpp	(revision 69760)
+++ 	(revision )
@@ -1,59 +1,0 @@
-/* $Id$ */
-/** @file
- * IPRT - NtSetInformationFile wrapper.
- */
-
-/*
- * Copyright (C) 2009-2017 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-
-/*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
-*********************************************************************************************************************************/
-#include <iprt/nt/nt.h>
-#include <iprt/string.h>
-
-
-/** Windows/NT worker.
- * @todo rename to rtFileWinSetAttributes */
-int rtFileNativeSetAttributes(HANDLE hFile, ULONG fAttributes)
-{
-    IO_STATUS_BLOCK IoStatusBlock;
-    RT_ZERO(IoStatusBlock);
-
-    /*
-     * Members that are set 0 will not be modified on the file object.
-     * See http://msdn.microsoft.com/en-us/library/aa491634.aspx (the struct docs)
-     * for details.
-     */
-    FILE_BASIC_INFORMATION Info;
-    RT_ZERO(Info);
-    Info.FileAttributes = fAttributes;
-
-    /** @todo resolve dynamically to avoid dragging in NtDll? */
-    NTSTATUS rcNt = NtSetInformationFile(hFile,
-                                         &IoStatusBlock,
-                                         &Info,
-                                         sizeof(Info),
-                                         FileBasicInformation);
-    return RtlNtStatusToDosError(rcNt);
-}
-
