pathint-nt.cpp revision 304e26e9a9c1422dbc299ed139eceacca271a9dd
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync/* $Id$ */
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync/** @file
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * IPRT - Native NT, Internal Path stuff.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync */
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync/*
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Copyright (C) 2006-2013 Oracle Corporation
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync *
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * available from http://www.virtualbox.org. This file is free software;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * General Public License (GPL) as published by the Free Software
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync *
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * The contents of this file may alternatively be used under the terms
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * of the Common Development and Distribution License Version 1.0
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * VirtualBox OSE distribution, in which case the provisions of the
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * CDDL are applicable instead of those of the GPL.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync *
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * You may elect to license modified versions of this file under the
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * terms and conditions of either the GPL or the CDDL or both.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync */
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync/*******************************************************************************
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync* Header Files *
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync*******************************************************************************/
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync#define LOG_GROUP RTLOGGROUP_FS
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync#include "internal-r3-nt.h"
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync#include <iprt/path.h>
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync#include <iprt/string.h>
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync#include <iprt/err.h>
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync#include <iprt/assert.h>
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync/**
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Handles the pass thru case.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync *
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * @returns IPRT status code.
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync * @param pNtName Where to return the NT name.
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync * @param phRootDir Where to return the root handle, if applicable.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * @param pszPath The UTF-8 path.
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync */
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsyncstatic int rtNtPathToNativePassThruWin(struct _UNICODE_STRING *pNtName, PHANDLE phRootDir, const char *pszPath)
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync{
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync PRTUTF16 pwszPath = NULL;
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync size_t cwcLen;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync int rc = RTStrToUtf16Ex(pszPath + 1, RTSTR_MAX, &pwszPath, 0, &cwcLen);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync if (RT_SUCCESS(rc))
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync {
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync if (cwcLen < _32K - 1)
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync {
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync pwszPath[0] = '\\';
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync pwszPath[1] = '.';
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync pwszPath[2] = '\\';
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync pNtName->Buffer = pwszPath;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync pNtName->MaximumLength = pNtName->Length = (uint16_t)(cwcLen * 2);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync *phRootDir = NULL;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync return VINF_SUCCESS;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync }
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync RTUtf16Free(pwszPath);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync rc = VERR_FILENAME_TOO_LONG;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync }
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync return rc;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync}
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync/**
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Converts the path to UTF-16 and sets all the return values.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync *
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * @returns IPRT status code.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * @param pNtName Where to return the NT name.
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync * @param phRootDir Where to return the root handle, if applicable.
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync * @param pszPath The UTF-8 path.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync */
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsyncstatic int rtNtPathToNativeToUtf16(struct _UNICODE_STRING *pNtName, PHANDLE phRootDir, const char *pszPath)
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync{
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync PRTUTF16 pwszPath = NULL;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync size_t cwcLen;
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync int rc = RTStrToUtf16Ex(pszPath, RTSTR_MAX, &pwszPath, 0, &cwcLen);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync if (RT_SUCCESS(rc))
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync {
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync if (cwcLen < _32K - 1)
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync {
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync pNtName->Buffer = pwszPath;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync pNtName->MaximumLength = pNtName->Length = (uint16_t)(cwcLen * 2);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync *phRootDir = NULL;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync return VINF_SUCCESS;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync }
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync RTUtf16Free(pwszPath);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync rc = VERR_FILENAME_TOO_LONG;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync }
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync return rc;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync}
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync/**
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Converts a path to NT format and encoding.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync *
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync * @returns IPRT status code.
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync * @param pNtName Where to return the NT name.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * @param phRootDir Where to return the root handle, if applicable.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * @param pszPath The UTF-8 path.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync */
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsyncstatic int rtNtPathToNative(struct _UNICODE_STRING *pNtName, PHANDLE phRootDir, const char *pszPath)
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync{
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync static char const s_szPrefixUnc[] = "\\??\\UNC\\";
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync static char const s_szPrefix[] = "\\??\\";
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync /*
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Very simple conversion of a win32-like path into an NT path.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync */
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync const char *pszPrefix = s_szPrefix;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync size_t cchPrefix = sizeof(s_szPrefix) - 1;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync size_t cchSkip = 0;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync if ( RTPATH_IS_SLASH(pszPath[0])
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync && RTPATH_IS_SLASH(pszPath[1])
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync && !RTPATH_IS_SLASH(pszPath[2])
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync && pszPath[2])
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync {
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync if ( pszPath[2] == '?'
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync && RTPATH_IS_SLASH(pszPath[3]))
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync return rtNtPathToNativePassThruWin(pNtName, phRootDir, pszPath);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync#ifdef IPRT_WITH_NT_PATH_PASSTHRU
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync /* Special hack: The path starts with "\\\\!\\", we will skip past the bang and pass it thru. */
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync if ( pszPath[2] == '!'
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync && RTPATH_IS_SLASH(pszPath[3]))
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync return rtNtPathToNativeToUtf16(pNtName, phRootDir, pszPath + 3);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync#endif
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync if ( pszPath[2] == '.'
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync && RTPATH_IS_SLASH(pszPath[3]))
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync {
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync /*
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Device path.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Note! I suspect \\.\stuff\..\otherstuff may be handled differently by windows.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync */
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync cchSkip = 4;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync }
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync else
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync {
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync /* UNC */
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync pszPrefix = s_szPrefixUnc;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync cchPrefix = sizeof(s_szPrefixUnc) - 1;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync cchSkip = 2;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync }
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync }
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync /*
* Straighten out all .. and uncessary . references and convert slashes.
*/
char szPath[RTPATH_MAX];
int rc = RTPathAbs(pszPath, &szPath[cchPrefix - cchSkip], sizeof(szPath) - (cchPrefix - cchSkip));
if (RT_FAILURE(rc))
return rc;
/*
* Add prefix and convert it to UTF16.
*/
memcpy(szPath, pszPrefix, cchPrefix);
return rtNtPathToNativeToUtf16(pNtName, phRootDir, szPath);
}
/**
* Frees the native path and root handle.
*
* @param pNtName The NT path after a successful rtNtPathToNative
* call.
* @param phRootDir The root handle variable after a
* rtNtPathToNative.
*/
void rtNtPathFreeNative(struct _UNICODE_STRING *pNtName, PHANDLE phRootDir)
{
RTUtf16Free(pNtName->Buffer);
pNtName->Buffer = NULL;
}
/**
* Wrapper around NtCreateFile.
*
* @returns IPRT status code.
* @param pszPath The UTF-8 path.
* @param fDesiredAccess See NtCreateFile.
* @param fFileAttribs See NtCreateFile.
* @param fShareAccess See NtCreateFile.
* @param fCreateDisposition See NtCreateFile.
* @param fCreateOptions See NtCreateFile.
* @param fObjAttribs The OBJECT_ATTRIBUTES::Attributes value, see
* NtCreateFile and InitializeObjectAttributes.
* @param phHandle Where to return the handle.
* @param puAction Where to return the action taken. Optional.
*/
RTDECL(int) RTNtPathOpen(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
PHANDLE phHandle, PULONG_PTR puAction)
{
*phHandle = RTNT_INVALID_HANDLE_VALUE;
HANDLE hRootDir;
UNICODE_STRING NtName;
int rc = rtNtPathToNative(&NtName, &hRootDir, pszPath);
if (RT_SUCCESS(rc))
{
HANDLE hFile = RTNT_INVALID_HANDLE_VALUE;
IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
OBJECT_ATTRIBUTES ObjAttr;
InitializeObjectAttributes(&ObjAttr, &NtName, fObjAttribs, hRootDir, NULL);
NTSTATUS rcNt = NtCreateFile(&hFile,
fDesiredAccess,
&ObjAttr,
&Ios,
NULL /* AllocationSize*/,
fFileAttribs,
fShareAccess,
fCreateDisposition,
fCreateOptions,
NULL /*EaBuffer*/,
0 /*EaLength*/);
if (NT_SUCCESS(rcNt))
{
if (puAction)
*puAction = Ios.Information;
*phHandle = hFile;
rc = VINF_SUCCESS;
}
else
rc = RTErrConvertFromNtStatus(rcNt);
rtNtPathFreeNative(&NtName, &hRootDir);
}
return rc;
}
/**
* Wrapper around NtCreateFile.
*
* @returns IPRT status code.
* @param pszPath The UTF-8 path.
* @param fDesiredAccess See NtCreateFile.
* @param fFileAttribs See NtCreateFile.
* @param fShareAccess See NtCreateFile.
* @param fCreateDisposition See NtCreateFile.
* @param fCreateOptions See NtCreateFile.
* @param fObjAttribs The OBJECT_ATTRIBUTES::Attributes value, see
* NtCreateFile and InitializeObjectAttributes.
* @param phHandle Where to return the handle.
* @param pfObjDir If not NULL, the variable pointed to will be set
* to @c true if we opened an object directory and
* @c false if we opened an directory file (normal
* directory).
*/
RTDECL(int) RTNtPathOpenDir(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fShareAccess, ULONG fCreateOptions,
ULONG fObjAttribs, PHANDLE phHandle, bool *pfObjDir)
{
*phHandle = RTNT_INVALID_HANDLE_VALUE;
HANDLE hRootDir;
UNICODE_STRING NtName;
int rc = rtNtPathToNative(&NtName, &hRootDir, pszPath);
if (RT_SUCCESS(rc))
{
HANDLE hFile = RTNT_INVALID_HANDLE_VALUE;
IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
OBJECT_ATTRIBUTES ObjAttr;
InitializeObjectAttributes(&ObjAttr, &NtName, fObjAttribs, hRootDir, NULL);
NTSTATUS rcNt = NtCreateFile(&hFile,
fDesiredAccess,
&ObjAttr,
&Ios,
NULL /* AllocationSize*/,
FILE_ATTRIBUTE_NORMAL,
fShareAccess,
FILE_OPEN,
fCreateOptions,
NULL /*EaBuffer*/,
0 /*EaLength*/);
if (NT_SUCCESS(rcNt))
{
if (pfObjDir)
*pfObjDir = false;
*phHandle = hFile;
rc = VINF_SUCCESS;
}
#ifdef IPRT_WITH_NT_PATH_PASSTHRU
else if ( pfObjDir
&& (rcNt == STATUS_OBJECT_NAME_INVALID || rcNt == STATUS_OBJECT_TYPE_MISMATCH)
&& RTPATH_IS_SLASH(pszPath[0])
&& RTPATH_IS_SLASH(pszPath[1])
&& pszPath[2] == '!'
&& RTPATH_IS_SLASH(pszPath[3]))
{
/* Strip trailing slash. */
if ( NtName.Length > 2
&& RTPATH_IS_SLASH(NtName.Buffer[(NtName.Length / 2) - 1]))
NtName.Length -= 2;
/* Rought conversion of the access flags. */
ULONG fObjDesiredAccess = 0;
if (fDesiredAccess & (GENERIC_ALL | STANDARD_RIGHTS_ALL))
fObjDesiredAccess = DIRECTORY_ALL_ACCESS;
else
{
if (fDesiredAccess & (FILE_GENERIC_WRITE | GENERIC_WRITE | STANDARD_RIGHTS_WRITE))
fObjDesiredAccess |= DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_OBJECT;
if ( (fDesiredAccess & (FILE_LIST_DIRECTORY | FILE_GENERIC_READ | GENERIC_READ | STANDARD_RIGHTS_READ))
|| !fObjDesiredAccess)
fObjDesiredAccess |= DIRECTORY_QUERY | FILE_LIST_DIRECTORY;
}
rcNt = NtOpenDirectoryObject(&hFile, fObjDesiredAccess, &ObjAttr);
if (NT_SUCCESS(rcNt))
{
*pfObjDir = true;
*phHandle = hFile;
rc = VINF_SUCCESS;
}
else
rc = RTErrConvertFromNtStatus(rcNt);
}
#endif
else
rc = RTErrConvertFromNtStatus(rcNt);
rtNtPathFreeNative(&NtName, &hRootDir);
}
return rc;
}
/**
* Closes an handled open by rtNtPathOpen.
*
* @returns IPRT status code
* @param hHandle The handle value.
*/
RTDECL(int) RTNtPathClose(HANDLE hHandle)
{
NTSTATUS rcNt = NtClose(hHandle);
if (NT_SUCCESS(rcNt))
return VINF_SUCCESS;
return RTErrConvertFromNtStatus(rcNt);
}