9

ネイティブ システム 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"));
}

しかし、ネイティブであろうとなかろうと、これらを Win32 パス名に変換する API がなければ、私は非常に驚くでしょう。そのような API は存在しますか?

4

6 に答える 6

8

これは製品コードで行います。私の知る限り、これを処理する API (パブリックまたはプライベート) はありません。いくつかのプレフィックスを使用して文字列の比較を行うだけで、うまくいきます。

どうやら ntdll.dll に RtlNtPathNameToDosPathName() という名前の関数があるようですが (XP で導入されましたか?)、それが何をするのかわかりません。ただし、\Device\Harddisk0 などと関係があると思います。

ただし、そのような機能が本当に必要かどうかはわかりません。Win32 はパス (CreateFile などの意味で) を NT に渡します。NT は Win32 にパスを渡しません。したがって、ntdll.dll は NT パスから Win32 パスに移動する必要はありません。一部の NT クエリ関数がフル パスを返すまれなケースでは、変換関数が Win32 dll の内部にある可能性があります (エクスポートされないなど)。GetModuleFileName() のようなものは、画像をロードするために使用されたパスを返すだけなので、気にするかどうかさえわかりません。これは単なる漏れやすい抽象化だと思います。

于 2010-12-15T02:29:45.037 に答える
5

ここにあなたが試すことができるものがあります。最初にNtCreateFileを使用して、読み取り用のファイル、ボリュームなどを開きます。次に、返された HANDLE を使用して、ここで説明されているようにフル パスを取得します。

于 2010-12-15T16:15:19.740 に答える
2

Win32 で正規のパス名を取得するには、これを確認してください。あなたに役立つかもしれません:

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

于 2010-12-14T22:53:34.207 に答える
2

この質問に対する私の回答を参照してください。

最初にそのパスでファイルへのハンドルを取得し、次にハンドルの Win32 パスを取得する必要があります。

于 2011-06-04T23:03:54.440 に答える
0

さまざまな種類の NT デバイス名 (ファイル名、COM ポート、ネットワーク パスなど) を DOS パスに変換する関数を作成しました。

2 つの機能があります。1 つはハンドルを NT パスに変換し、もう 1 つはこの NT パスを DOS パスに変換します。

こちらをご覧ください: オープンハンドルに関連付けられた名前を取得する方法

// "\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)
于 2015-08-11T03:26:08.950 に答える