Files
DeviceNameResolver/DeviceNameResolver.cpp

117 lines
5.0 KiB
C++

#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;
}