-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDeviceNameResolver.cpp
116 lines (110 loc) · 4.97 KB
/
DeviceNameResolver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "DeviceNameResolver.h"
#include "DeviceNameResolverInternal.h"
#include "DynBuf.h"
#include "NativeWinApi.h"
extern "C" __declspec(dllexport) bool DevicePathToPathW(const wchar_t* szDevicePath, wchar_t* szPath, size_t nSizeInChars)
{
DeviceNameResolver deviceNameResolver;
wchar_t targetPath[MAX_PATH] = L"";
if(!deviceNameResolver.resolveDeviceLongNameToShort(szDevicePath, targetPath))
return false;
wcsncpy_s(szPath, nSizeInChars, targetPath, _TRUNCATE);
return true;
}
extern "C" __declspec(dllexport) bool DevicePathToPathA(const char* szDevicePath, char* szPath, size_t nSizeInChars)
{
size_t len = strlen(szDevicePath);
DynBuf newDevicePathBuf((len + 1) * sizeof(wchar_t));
wchar_t* newDevicePath = (wchar_t*)newDevicePathBuf.GetPtr();
*newDevicePath = L'\0';
if(MultiByteToWideChar(CP_ACP, NULL, szDevicePath, -1, newDevicePath, int(len + 1)))
{
DynBuf newPathBuf((nSizeInChars + 1) * sizeof(wchar_t));
wchar_t* newPath = (wchar_t*)newPathBuf.GetPtr();
if(!DevicePathToPathW(newDevicePath, newPath, nSizeInChars))
return false;
if(!WideCharToMultiByte(CP_ACP, NULL, newPath, -1, szPath, int(wcslen(newPath)) + 1, NULL, NULL))
return false;
}
return true;
}
__declspec(dllexport) bool DevicePathFromFileHandleW(HANDLE hFile, wchar_t* szDevicePath, size_t nSizeInChars)
{
NativeWinApi::initialize();
ULONG ReturnLength;
bool bRet = false;
if(NativeWinApi::NtQueryObject(hFile, ObjectNameInformation, 0, 0, &ReturnLength) == STATUS_INFO_LENGTH_MISMATCH)
{
ReturnLength += 0x2000; //on Windows XP SP3 ReturnLength will not be set just add some buffer space to fix this
POBJECT_NAME_INFORMATION NameInformation = POBJECT_NAME_INFORMATION(GlobalAlloc(0, ReturnLength));
if(NativeWinApi::NtQueryObject(hFile, ObjectNameInformation, NameInformation, ReturnLength, 0) == STATUS_SUCCESS)
{
NameInformation->Name.Buffer[NameInformation->Name.Length / 2] = L'\0'; //null-terminate the UNICODE_STRING
wcsncpy_s(szDevicePath, nSizeInChars, NameInformation->Name.Buffer, _TRUNCATE);
bRet = true;
}
GlobalFree(NameInformation);
}
if(!bRet)
return false;
if(_wcsnicmp(szDevicePath, L"\\Device\\LanmanRedirector\\", 25) == 0) // Win XP
{
wcsncpy_s(szDevicePath, nSizeInChars, L"\\\\", _TRUNCATE);
wcsncat_s(szDevicePath, nSizeInChars, &szDevicePath[25], _TRUNCATE);
}
else if(_wcsnicmp(szDevicePath, L"\\Device\\Mup\\", 12) == 0) // Win 7
{
wcsncpy_s(szDevicePath, nSizeInChars, L"\\\\", _TRUNCATE);
wcsncat_s(szDevicePath, nSizeInChars, &szDevicePath[12], _TRUNCATE);
}
return true;
}
__declspec(dllexport) bool DevicePathFromFileHandleA(HANDLE hFile, char* szDevicePath, size_t nSizeInChars)
{
DynBuf newDevicePathBuf((nSizeInChars + 1) * sizeof(wchar_t));
wchar_t* newDevicePath = (wchar_t*)newDevicePathBuf.GetPtr();
if(!DevicePathFromFileHandleW(hFile, newDevicePath, nSizeInChars))
return false;
if(!WideCharToMultiByte(CP_ACP, NULL, newDevicePath, -1, szDevicePath, int(wcslen(newDevicePath)) + 1, NULL, NULL))
return false;
return true;
}
__declspec(dllexport) bool PathFromFileHandleW(HANDLE hFile, wchar_t* szPath, size_t nSizeInChars)
{
typedef DWORD (WINAPI * GETFINALPATHNAMEBYHANDLEW)(
IN HANDLE /*hFile*/,
OUT wchar_t* /*lpszFilePath*/,
IN DWORD /*cchFilePath*/,
IN DWORD /*dwFlags*/
);
static GETFINALPATHNAMEBYHANDLEW GetFPNBHW = GETFINALPATHNAMEBYHANDLEW(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetFinalPathNameByHandleW"));
if(GetFPNBHW && GetFPNBHW(hFile, szPath, DWORD(nSizeInChars), 0))
{
if(_wcsnicmp(szPath, L"\\\\?\\UNC\\", 8) == 0) // Server path
{
wcsncpy_s(szPath, nSizeInChars, L"\\\\", _TRUNCATE);
wcsncat_s(szPath, nSizeInChars, &szPath[8], _TRUNCATE);
}
else if(_wcsnicmp(szPath, L"\\\\?\\", 4) == 0 && szPath[5] == L':') // Drive path
{
wcsncpy_s(szPath, nSizeInChars, &szPath[4], _TRUNCATE);
}
return true;
}
if(!DevicePathFromFileHandleW(hFile, szPath, nSizeInChars))
return false;
std::wstring oldPath(szPath);
if(!DevicePathToPathW(szPath, szPath, nSizeInChars))
wcsncpy_s(szPath, nSizeInChars, oldPath.c_str(), _TRUNCATE);
return true;
}
__declspec(dllexport) bool PathFromFileHandleA(HANDLE hFile, char* szPath, size_t nSizeInChars)
{
DynBuf newDevicePathBuf((nSizeInChars + 1) * sizeof(wchar_t));
wchar_t* newDevicePath = (wchar_t*)newDevicePathBuf.GetPtr();
if(!PathFromFileHandleW(hFile, newDevicePath, nSizeInChars))
return false;
if(!WideCharToMultiByte(CP_ACP, NULL, newDevicePath, -1, szPath, int(wcslen(newDevicePath)) + 1, NULL, NULL))
return false;
return true;
}