驱动中通过设备链接名取得磁盘符号的方法

主要思路:
从驱动层设备链接名获取DosName很难做到通用,但DosName->DeviceSymblinkName可以做到通用,这样的话就有一种思路:
查询一个设备链接名对应的磁盘盘符的方法:
获取从A到Z的盘的设备链接名,如果有一个和传入的参数(设备链接名)完全匹配,那么其对应的盘符就是该设备链接名对应的盘符。

GetSymbolicLink(
IN PUNICODE_STRING SymbolicLinkName,
OUT PUNICODE_STRING LinkTarget
)

/*++
Routine Description:
This routine returns the target of the symbolic link name.
Arguments:
SymbolicLinkName - Supplies the symbolic link name.
LinkTarget - Returns the link target.
Return Value:
NTSTATUS
--*/

{
OBJECT_ATTRIBUTES oa;
NTSTATUS status;
HANDLE h;

InitializeObjectAttributes(&oa, SymbolicLinkName, OBJ_CASE_INSENSITIVE,0, 0);

status = ZwOpenSymbolicLinkObject(&h, GENERIC_READ, &oa);

if (!NT_SUCCESS(status))
{
return status;
}

LinkTarget->MaximumLength = 200*sizeof(WCHAR);
LinkTarget->Length = 0;
LinkTarget->Buffer = ExAllocatePool(PagedPool, LinkTarget->MaximumLength);

if (!LinkTarget->Buffer)
{
ZwClose(h);
return STATUS_INSUFFICIENT_RESOURCES;
}

RtlZeroMemory(LinkTarget->Buffer, LinkTarget->MaximumLength);

status = ZwQuerySymbolicLinkObject(h, LinkTarget, NULL);
ZwClose(h);

if (!NT_SUCCESS(status))
{
ExFreePool(LinkTarget->Buffer);
}

return status;
}

NTSTATUS QuerySymbolicLink(
IN PUNICODE_STRING SymbolicLinkName,
OUT PUNICODE_STRING LinkTarget
)                                  
{
OBJECT_ATTRIBUTES oa;
NTSTATUS status;
HANDLE handle;

InitializeObjectAttributes(&oa, SymbolicLinkName,
OBJ_CASE_INSENSITIVE,
0, 0);

status = ZwOpenSymbolicLinkObject(&handle, GENERIC_READ, &oa);
if (!NT_SUCCESS(status))
{
return status;
}

LinkTarget->MaximumLength = 200*sizeof(WCHAR);
LinkTarget->Length = 0;
LinkTarget->Buffer = ExAllocatePool(PagedPool, LinkTarget->MaximumLength);
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;
}

NTSTATUS
RtlVolumeDeviceToDosName(
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;
UNICODE_STRING driveLetterName;
WCHAR          driveLetterNameBuf[128];
WCHAR c;
WCHAR DriLetter[3];
UNICODE_STRING linkTarget;

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 = ExAllocatePool(PagedPool, 3*sizeof(WCHAR));
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;
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值