设备名与链接名互相转化思路
符号链接转设备名可以调用ZwOpenSymbolicLinkObject,ZwQuerySymbolicLinkObject直接查询到设备名反过来是调用第一种方法,把每个盘符A到Z的符号链接对应的设备名求出来,然后一一比对。一种实现DWORDWINAPIMyQueryDosDeviceW(LPCWSTR ...
·
符号链接转设备名可以调用ZwOpenSymbolicLinkObject,ZwQuerySymbolicLinkObject直接查询到设备名
反过来是调用第一种方法,把每个盘符A到Z的符号链接对应的设备名求出来,然后一一比对。
一种实现
DWORD
WINAPI
MyQueryDosDeviceW(
LPCWSTR lpDeviceName,
LPWSTR lpTargetPath,
DWORD ucchMax
)
{
POBJECT_DIRECTORY_INFORMATION DirInfo;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeString;
HANDLE DirectoryHandle;
HANDLE DeviceHandle;
ULONG ReturnLength;
ULONG NameLength;
ULONG Length;
ULONG Context;
BOOLEAN RestartScan;
NTSTATUS Status;
UCHAR Buffer[512];
PWSTR Ptr;
/* Open the '\??' directory */
RtlInitUnicodeString (&UnicodeString,
L"\\??");
InitializeObjectAttributes (&ObjectAttributes,
&UnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenDirectoryObject (&DirectoryHandle,
DIRECTORY_QUERY,
&ObjectAttributes);
if (!NT_SUCCESS (Status))
{
return 0;
}
Length = 0;
if (lpDeviceName != NULL)
{
/* Open the lpDeviceName link object */
RtlInitUnicodeString (&UnicodeString,
(PWSTR)lpDeviceName);
InitializeObjectAttributes (&ObjectAttributes,
&UnicodeString,
OBJ_CASE_INSENSITIVE,
DirectoryHandle,
NULL);
Status = NtOpenSymbolicLinkObject (&DeviceHandle,
GENERIC_READ,
&ObjectAttributes);
if (!NT_SUCCESS (Status))
{
pfnNtClose (DirectoryHandle);
return 0;
}
/* Query link target */
UnicodeString.Length = 0;
UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR);
UnicodeString.Buffer = lpTargetPath;
ReturnLength = 0;
Status = NtQuerySymbolicLinkObject (DeviceHandle,
&UnicodeString,
&ReturnLength);
pfnNtClose (DeviceHandle);
pfnNtClose (DirectoryHandle);
if (!NT_SUCCESS (Status))
{
return 0;
}
Length = UnicodeString.Length / sizeof(WCHAR);
if (Length < ucchMax)
{
/* Append null-charcter */
lpTargetPath[Length] = UNICODE_NULL;
Length++;
}
else
{
return 0;
}
}
else
{
RestartScan = TRUE;
Context = 0;
Ptr = lpTargetPath;
DirInfo = (POBJECT_DIRECTORY_INFORMATION)Buffer;
while (TRUE)
{
Status = NtQueryDirectoryObject (DirectoryHandle,
Buffer,
sizeof (Buffer),
TRUE,
RestartScan,
&Context,
&ReturnLength);
if (!NT_SUCCESS(Status))
{
if (Status == STATUS_NO_MORE_ENTRIES)
{
/* Terminate the buffer */
*Ptr = UNICODE_NULL;
Length++;
Status = STATUS_SUCCESS;
}
else
{
Length = 0;
}
break;
}
if (!wcscmp (DirInfo->TypeName.Buffer, L"SymbolicLink"))
{
NameLength = DirInfo->Name.Length / sizeof(WCHAR);
if (Length + NameLength + 1 >= ucchMax)
{
Length = 0;
break;
}
memcpy (Ptr,
DirInfo->Name.Buffer,
DirInfo->Name.Length);
Ptr += NameLength;
Length += NameLength;
*Ptr = UNICODE_NULL;
Ptr++;
Length++;
}
RestartScan = FALSE;
}
pfnNtClose (DirectoryHandle);
}
return Length;
}
另一种
#include <ntddk.h>
#include <windef.h>
#include <ntstrsafe.h>
//输入\\??\\c:-->\\device\\\harddiskvolume1
//LinkTarget.Buffer注意要释放
NTSTATUS QuerySymbolicLink(
IN PUNICODE_STRING SymbolicLinkName,
OUT PUNICODE_STRING LinkTarget
)
{
OBJECT_ATTRIBUTES oa = {0};
NTSTATUS status = 0;
HANDLE handle = NULL;
InitializeObjectAttributes(
&oa,
SymbolicLinkName,
OBJ_CASE_INSENSITIVE,
0,
0);
status = ZwOpenSymbolicLinkObject(&handle, GENERIC_READ, &oa);
if (!NT_SUCCESS(status))
{
return status;
}
LinkTarget->MaximumLength = MAX_PATH*sizeof(WCHAR);
LinkTarget->Length = 0;
LinkTarget->Buffer = ExAllocatePoolWithTag(PagedPool, LinkTarget->MaximumLength,'SOD');
if (!LinkTarget->Buffer)
{
ZwClose(handle);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(LinkTarget->Buffer, LinkTarget->MaximumLength);
status = ZwQuerySymbolicLinkObject(handle, LinkTarget, NULL);
ZwClose(handle);
if (!NT_SUCCESS(status))
{
ExFreePool(LinkTarget->Buffer);
}
return status;
}
//输入\\Device\\harddiskvolume1
//输出C:
//DosName.Buffer的内存记得释放
NTSTATUS
MyRtlVolumeDeviceToDosName(
IN PUNICODE_STRING DeviceName,
OUT PUNICODE_STRING DosName
)
/*++
Routine Description:
This routine returns a valid DOS path for the given device object.
This caller of this routine must call ExFreePool on DosName->Buffer
when it is no longer needed.
Arguments:
VolumeDeviceObject - Supplies the volume device object.
DosName - Returns the DOS name for the volume
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = 0;
UNICODE_STRING driveLetterName = {0};
WCHAR driveLetterNameBuf[128] = {0};
WCHAR c = L'\0';
WCHAR DriLetter[3] = {0};
UNICODE_STRING linkTarget = {0};
for (c = L'A'; c <= L'Z'; c++)
{
RtlInitEmptyUnicodeString(&driveLetterName,driveLetterNameBuf,sizeof(driveLetterNameBuf));
RtlAppendUnicodeToString(&driveLetterName, L"\\??\\");
DriLetter[0] = c;
DriLetter[1] = L':';
DriLetter[2] = 0;
RtlAppendUnicodeToString(&driveLetterName,DriLetter);
status = QuerySymbolicLink(&driveLetterName, &linkTarget);
if (!NT_SUCCESS(status))
{
continue;
}
if (RtlEqualUnicodeString(&linkTarget, DeviceName, TRUE))
{
ExFreePool(linkTarget.Buffer);
break;
}
ExFreePool(linkTarget.Buffer);
}
if (c <= L'Z')
{
DosName->Buffer = ExAllocatePoolWithTag(PagedPool, 3*sizeof(WCHAR), 'SOD');
if (!DosName->Buffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
DosName->MaximumLength = 6;
DosName->Length = 4;
*DosName->Buffer = c;
*(DosName->Buffer+ 1) = ':';
*(DosName->Buffer+ 2) = 0;
return STATUS_SUCCESS;
}
return status;
}
//c:\\windows\\hi.txt<--\\device\\harddiskvolume1\\windows\\hi.txt
BOOL NTAPI GetNTLinkName(IN WCHAR * wszNTName, OUT WCHAR * wszFileName)
{
UNICODE_STRING ustrFileName = {0};
UNICODE_STRING ustrDosName = {0};
UNICODE_STRING ustrDeviceName = {0};
WCHAR *pPath = NULL;
ULONG i = 0;
ULONG ulSepNum = 0;
if (wszFileName == NULL ||
wszNTName == NULL ||
_wcsnicmp(wszNTName, L"\\device\\harddiskvolume", wcslen(L"\\device\\harddiskvolume"))!=0)
{
return FALSE;
}
ustrFileName.Buffer = wszFileName;
ustrFileName.Length = 0;
ustrFileName.MaximumLength = sizeof(WCHAR)*MAX_PATH;
while(wszNTName[i]!=L'\0')
{
if (wszNTName[i] == L'\0')
{
break;
}
if (wszNTName[i] == L'\\')
{
ulSepNum++;
}
if (ulSepNum == 3)
{
wszNTName[i] = UNICODE_NULL;
pPath = &wszNTName[i+1];
break;
}
i++;
}
if (pPath == NULL)
{
return FALSE;
}
RtlInitUnicodeString(&ustrDeviceName, wszNTName);
if (!NT_SUCCESS(MyRtlVolumeDeviceToDosName(&ustrDeviceName, &ustrDosName)))
{
return FALSE;
}
RtlCopyUnicodeString(&ustrFileName, &ustrDosName);
RtlAppendUnicodeToString(&ustrFileName, L"\\");
RtlAppendUnicodeToString(&ustrFileName, pPath);
ExFreePool(ustrDosName.Buffer);
return TRUE;
}
BOOL QueryVolumeName(WCHAR ch, WCHAR * name, USHORT size)
{
WCHAR szVolume[7] = L"\\??\\C:";
UNICODE_STRING LinkName;
UNICODE_STRING VolName;
UNICODE_STRING ustrTarget;
NTSTATUS ntStatus = 0;
RtlInitUnicodeString(&LinkName, szVolume);
szVolume[4] = ch;
ustrTarget.Buffer = name;
ustrTarget.Length = 0;
ustrTarget.MaximumLength = size;
ntStatus = QuerySymbolicLink(&LinkName, &VolName);
if (NT_SUCCESS(ntStatus))
{
RtlCopyUnicodeString(&ustrTarget, &VolName);
ExFreePool(VolName.Buffer);
}
return NT_SUCCESS(ntStatus);
}
//\\??\\c:\\windows\\hi.txt-->\\device\\harddiskvolume1\\windows\\hi.txt
BOOL NTAPI GetNtDeviceName(IN WCHAR * filename, OUT WCHAR * ntname)
{
UNICODE_STRING uVolName = {0,0,0};
WCHAR volName[MAX_PATH] = L"";
WCHAR tmpName[MAX_PATH] = L"";
WCHAR chVol = L'\0';
WCHAR * pPath = NULL;
int i = 0;
RtlStringCbCopyW(tmpName, MAX_PATH * sizeof(WCHAR), filename);
for(i = 1; i < MAX_PATH - 1; i++)
{
if(tmpName[i] == L':')
{
pPath = &tmpName[(i + 1) % MAX_PATH];
chVol = tmpName[i - 1];
break;
}
}
if(pPath == NULL)
{
return FALSE;
}
if(chVol == L'?')
{
uVolName.Length = 0;
uVolName.MaximumLength = MAX_PATH * sizeof(WCHAR);
uVolName.Buffer = ntname;
RtlAppendUnicodeToString(&uVolName, L"\\Device\\HarddiskVolume?");
RtlAppendUnicodeToString(&uVolName, pPath);
return TRUE;
}
else if(QueryVolumeName(chVol, volName, MAX_PATH * sizeof(WCHAR)))
{
uVolName.Length = 0;
uVolName.MaximumLength = MAX_PATH * sizeof(WCHAR);
uVolName.Buffer = ntname;
RtlAppendUnicodeToString(&uVolName, volName);
RtlAppendUnicodeToString(&uVolName, pPath);
return TRUE;
}
return FALSE;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
DbgPrint("Goodbye!\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
UNICODE_STRING ustrDeviceName = {0};
UNICODE_STRING ustrLinkName = {0};
WCHAR *wszDeviceName = L"\\Device\\harddiskvolume1";
NTSTATUS ntStatus = 0;
WCHAR DeviceName[MAX_PATH] = L"\\Device\\harddiskvolume1\\windows\\hi.txt";
WCHAR FileName[MAX_PATH] = {0};
WCHAR szDeviceName[MAX_PATH] = {0};
RtlInitUnicodeString(&ustrDeviceName, wszDeviceName);
ntStatus = MyRtlVolumeDeviceToDosName(&ustrDeviceName, &ustrLinkName);
if (NT_SUCCESS(ntStatus))
{
DbgPrint("linkname:%wZ\n", &ustrLinkName);
if (ustrLinkName.Buffer)
{
ExFreePool(ustrLinkName.Buffer);
}
}
if (GetNTLinkName(DeviceName, FileName))
{
DbgPrint("FileName:%ws\n", FileName);
GetNtDeviceName(FileName, szDeviceName);
DbgPrint("szDeviceName:%ws", szDeviceName);
}
pDriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
更多推荐
已为社区贡献3条内容
所有评论(0)