Как я могу преобразовать собственный путь (NT) в путь Win32? - PullRequest
6 голосов
/ 15 декабря 2010

Я работаю над сообщением некоторой информации, полученной из системных системных API. (Я знаю, что это плохо .... но я получаю информацию, которую не могу получить иначе, и у меня мало проблем с необходимостью обновления моего приложения, если / когда это время наступит.)

Собственный API возвращает собственные пути, как видно по ob, т.е. \SystemRoot\System32\Ntoskrnl.exe или \??\C:\Program Files\VMWare Workstation\vstor-ws60.sys.

Я могу заменить общие префиксы, т.е.

std::wstring NtPathToWin32Path( std::wstring ntPath )
{
    if (boost::starts_with(ntPath, L"\\\\?\\"))
    {
        ntPath.erase(ntPath.begin(), ntPath.begin() + 4);
        return ntPath;
    }
    if (boost::starts_with(ntPath, L"\\??\\"))
    {
        ntPath.erase(ntPath.begin(), ntPath.begin() + 4);
    }
    if (boost::starts_with(ntPath, L"\\"))
    {
        ntPath.erase(ntPath.begin(), ntPath.begin() + 1);
    }
    if (boost::istarts_with(ntPath, L"globalroot\\"))
    {
        ntPath.erase(ntPath.begin(), ntPath.begin() + 11);
    }
    if (boost::istarts_with(ntPath, L"systemroot"))
    {
        ntPath.replace(ntPath.begin(), ntPath.begin() + 10, GetWindowsPath());
    }
    if (boost::istarts_with(ntPath, L"windows"))
    {
        ntPath.replace(ntPath.begin(), ntPath.begin() + 7, GetWindowsPath());
    }
    return ntPath;
}

TEST(Win32Path, NtPathDoubleQuestions)
{
    ASSERT_EQ(L"C:\\Example", NtPathToWin32Path(L"\\??\\C:\\Example"));
}

TEST(Win32Path, NtPathUncBegin)
{
    ASSERT_EQ(L"C:\\Example", NtPathToWin32Path(L"\\\\?\\C:\\Example"));
}

TEST(Win32Path, NtPathWindowsStart)
{
    ASSERT_EQ(GetCombinedPath(GetWindowsPath(), L"Hello\\World"), NtPathToWin32Path(L"\\Windows\\Hello\\World"));
}

TEST(Win32Path, NtPathSystemrootStart)
{
    ASSERT_EQ(GetCombinedPath(GetWindowsPath(), L"Hello\\World"), NtPathToWin32Path(L"\\SystemRoot\\Hello\\World"));
}

TEST(Win32Path, NtPathGlobalRootSystemRoot)
{
    ASSERT_EQ(GetCombinedPath(GetWindowsPath(), L"Hello\\World"), NtPathToWin32Path(L"\\globalroot\\SystemRoot\\Hello\\World"));
}

но я бы сильно удивился, если бы не было какого-либо API, нативного или какого-либо другого, который преобразует их в пути Win32. Существует ли такой API?

Ответы [ 5 ]

8 голосов
/ 15 декабря 2010

Мы делаем это в рабочем коде.Насколько я знаю, нет API (публичного или частного), который бы обрабатывал это.Мы просто проводим сравнение строк с несколькими префиксами, и это работает для нас.

Очевидно, в ntdll.dll есть функция с именем RtlNtPathNameToDosPathName (), но я понятия не имею, что она делает;Я думаю, что это больше связано с такими вещами, как \ Device \ Harddisk0, хотя.

Я не уверен, что такая функция действительно нужна.Win32 передает пути (в смысле CreateFile и т. Д.) В NT;NT не передает пути к Win32.Таким образом, ntdll.dll на самом деле не нужно переходить от путей NT к путям Win32.В редком случае, когда какая-либо функция запроса NT возвращает полный путь, любая функция преобразования может быть внутренней для DLL-библиотеки Win32 (например, не экспортироваться).Я даже не знаю, беспокоятся ли они, потому что такие вещи, как GetModuleFileName () будут просто возвращать любой путь, использованный для загрузки изображения.Я предполагаю, что это просто дырявая абстракция.

4 голосов
/ 15 декабря 2010

Вот что вы можете попробовать. Сначала используйте NtCreateFile , чтобы открыть файл, том и т. Д. Для чтения. Затем используйте возвращенную РУЧКУ, чтобы получить полный путь, как описано здесь .

1 голос
/ 05 июня 2011

См. мой ответ на этот вопрос .

Сначала вам нужно получить дескриптор файла по этому пути, а затем получить путь Win32 для дескриптора.*

1 голос
/ 15 декабря 2010

Проверьте это для получения канонического имени пути в Win32.Это может быть полезно для вас:

http://pdh11.blogspot.com/2009/05/pathcanonicalize-versus-what-it-says-on.html

0 голосов
/ 11 августа 2015

Я написал функцию, которая преобразует различные типы имен устройств NT (имена файлов, COM-порты, сетевые пути и т. Д.) В путь DOS.

Есть две функции. Один преобразует дескриптор в путь NT, а другой преобразует этот путь NT в путь DOS.

Посмотрите здесь: Как получить имя, связанное с открытой HANDLE

// "\Device\HarddiskVolume3"                                (Harddisk Drive)
// "\Device\HarddiskVolume3\Temp"                           (Harddisk Directory)
// "\Device\HarddiskVolume3\Temp\transparent.jpeg"          (Harddisk File)
// "\Device\Harddisk1\DP(1)0-0+6\foto.jpg"                  (USB stick)
// "\Device\TrueCryptVolumeP\Data\Passwords.txt"            (Truecrypt Volume)
// "\Device\Floppy0\Autoexec.bat"                           (Floppy disk)
// "\Device\CdRom1\VIDEO_TS\VTS_01_0.VOB"                   (DVD drive)
// "\Device\Serial1"                                        (real COM port)
// "\Device\USBSER000"                                      (virtual COM port)
// "\Device\Mup\ComputerName\C$\Boot.ini"                   (network drive share,  Windows 7)
// "\Device\LanmanRedirector\ComputerName\C$\Boot.ini"      (network drive share,  Windwos XP)
// "\Device\LanmanRedirector\ComputerName\Shares\Dance.m3u" (network folder share, Windwos XP)
// "\Device\Afd"                                            (internet socket)
// "\Device\Console000F"                                    (unique name for any Console handle)
// "\Device\NamedPipe\Pipename"                             (named pipe)
// "\BaseNamedObjects\Objectname"                           (named mutex, named event, named semaphore)
// "\REGISTRY\MACHINE\SOFTWARE\Classes\.txt"                (HKEY_CLASSES_ROOT\.txt)
...