chacent
驱动牛犊
驱动牛犊
  • 注册日期2007-01-13
  • 最后登录2012-02-21
  • 粉丝0
  • 关注0
  • 积分53分
  • 威望26点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
阅读:2398回复:1

请教下如何把符号连接名转换成盘符?

楼主#
更多 发布于:2007-06-27 20:39
得到类似\Device\HarddiskVolume2的文件路径,有这样地内核函数可以直接转换成d:吗?如果没有咋转换呢?
titilima
驱动牛犊
驱动牛犊
  • 注册日期2007-02-08
  • 最后登录2009-06-12
  • 粉丝0
  • 关注0
  • 积分90分
  • 威望10点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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; 
}
http://www.titilima.cn
游客

返回顶部