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