阅读:2399回复: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; } |
|
|