1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | NTSTATUS querySymbolicLink(PUNICODE_STRING symbolicLinkName, 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; } WCHAR *rtlVolumeDeviceToDosName(WCHAR *deviceName) { 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 (_wcsnicmp(linkTarget.Buffer, deviceName, linkTarget.Length) == 0) { deviceName += linkTarget.Length - 2; deviceName[0] = c; deviceName[1] = L":"; ExFreePool(linkTarget.Buffer); break; } ExFreePool(linkTarget.Buffer); } return deviceName; } WCHAR *getDosPath(WCHAR *path) { WCHAR device[] = L"\\Device\\"; if (strIsStartWith(path, device)) { path = rtlVolumeDeviceToDosName(path); } return path; } |