I'm working on reporting some information gleaned from native system APIs. (I know this is bad.... but I'm getting information that I can't get otherwise, and I have little issue with having to update my app if/when that time comes around.)
The native API returns native pathnames, as seen by ob
, i.e. \SystemRoot\System32\Ntoskrnl.exe
, or \??\C:\Program Files\VMWare Workstation\vstor-ws60.sys
.
I can replace common prefixes, i.e.
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"));
}
but I'd be strongly surprised if there's not some API, native or otherwise, which will convert these into Win32 path names. Does such an API exist?
PathCanonicalize
do the trick? msdn.microsoft.com/en-us/library/bb773569%28v=vs.85%29.aspx – AcrylylNtCreateFile
(msdn.microsoft.com/en-us/library/bb432380%28v=vs.85%29.aspx) to open the file, volume etc. for reading. Then use the returnedHANDLE
to get the full path as described here msdn.microsoft.com/en-us/library/aa366789%28v=vs.85%29.aspx – AcrylylFindFirstFile
can easily construct Win32 paths; you have to give it one to start from, unlikeZwQueryDirectoryFile
which takes a HANDLE instead. Of course, your problem would be solved if there were an API to return a Win32 path from a HANDLE. – MerelyQUERY_INFORMATION
access level (and notGENERIC_READ
orGENERIC_WRITE
) then you shouldn't interfere in any way with other programs using the file. – LarvaNtQueryFileInformation
and ask it forFILE_NAMES_INFORMATION
from a handle. – Mink