|
阅读:2472回复:1
请教下如何把符号连接名转换成盘符?
得到类似\Device\HarddiskVolume2的文件路径,有这样地内核函数可以直接转换成d:吗?如果没有咋转换呢?
|
|
|
沙发#
发布于:2007-06-28 09:20
借花献佛,贴一段ReactOS中QueryDosDeviceW的实现,其实也就是查询“??”中的符号链接。
DWORD
STDCALL
QueryDosDeviceW(
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))
{
DPRINT ("NtOpenDirectoryObject() failed (Status %lx)\n", Status);
SetLastErrorByStatus (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,
SYMBOLIC_LINK_QUERY,
&ObjectAttributes);
if (!NT_SUCCESS (Status))
{
DPRINT ("NtOpenSymbolicLinkObject() failed (Status %lx)\n", Status);
NtClose (DirectoryHandle);
SetLastErrorByStatus (Status);
return 0;
}
/* Query link target */
UnicodeString.Length = 0;
UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR);
UnicodeString.Buffer = lpTargetPath;
ReturnLength = 0;
Status = NtQuerySymbolicLinkObject (DeviceHandle,
&UnicodeString,
&ReturnLength);
NtClose (DeviceHandle);
NtClose (DirectoryHandle);
if (!NT_SUCCESS (Status))
{
DPRINT ("NtQuerySymbolicLinkObject() failed (Status %lx)\n", Status);
SetLastErrorByStatus (Status);
return 0;
}
DPRINT ("ReturnLength: %lu\n", ReturnLength);
DPRINT ("TargetLength: %hu\n", UnicodeString.Length);
DPRINT ("Target: '%wZ'\n", &UnicodeString);
Length = ReturnLength / sizeof(WCHAR);
if (Length < ucchMax)
{
/* Append null-charcter */
lpTargetPath[Length] = UNICODE_NULL;
Length++;
}
else
{
DPRINT ("Buffer is too small\n");
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
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;
}
SetLastErrorByStatus (Status);
break;
}
if (!wcscmp (DirInfo->ObjectTypeName.Buffer, L"SymbolicLink"))
{
DPRINT ("Name: '%wZ'\n", &DirInfo->ObjectName);
NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR);
if (Length + NameLength + 1 >= ucchMax)
{
Length = 0;
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
break;
}
memcpy (Ptr,
DirInfo->ObjectName.Buffer,
DirInfo->ObjectName.Length);
Ptr += NameLength;
Length += NameLength;
*Ptr = UNICODE_NULL;
Ptr++;
Length++;
}
RestartScan = FALSE;
}
NtClose (DirectoryHandle);
}
return Length;
} |
|
|