windows内核 nt路径转化dos路径
NTSTATUS ConvertNtToDosPath(
_In_ PUNICODE_STRING NtPath,
_Out_ PUNICODE_STRING DosPath
)
{
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE linkHandle = NULL;
UNICODE_STRING linkTarget = { 0 };
WCHAR linkBuffer[512];
WCHAR driveLetter;
// 初始化输出
RtlZeroMemory(DosPath, sizeof(UNICODE_STRING));
// 遍历驱动器号 C: 到 Z:
for (driveLetter = L'C'; driveLetter <= L'Z'; driveLetter++) {
WCHAR symlinkPath[16];
UNICODE_STRING symlinkName;
// 构建符号链接路径 "\??\C:"
swprintf(symlinkPath, L"\\??\\%wc:", driveLetter);
RtlInitUnicodeString(&symlinkName, symlinkPath);
InitializeObjectAttributes(
&objectAttributes,
&symlinkName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL
);
status = ZwOpenSymbolicLinkObject(&linkHandle, GENERIC_READ, &objectAttributes);
if (!NT_SUCCESS(status)) {
continue;
}
linkTarget.Buffer = linkBuffer;
linkTarget.MaximumLength = sizeof(linkBuffer);
linkTarget.Length = 0;
status = ZwQuerySymbolicLinkObject(linkHandle, &linkTarget, NULL);
ZwClose(linkHandle);
linkHandle = NULL;
if (NT_SUCCESS(status)) {
// 检查NT路径是否以这个符号链接目标开始
if (RtlPrefixUnicodeString(&linkTarget, NtPath, TRUE)) {
// 找到匹配的驱动器
USHORT remainderLength = NtPath->Length - linkTarget.Length;
USHORT dosPathLength = 2 * sizeof(WCHAR) + remainderLength; // "C:" + 剩余路径
// 先创建原始的DOS路径(和之前一样)
PWCHAR tempBuffer = (PWCHAR)ExAllocatePoolWithTag(
PagedPool,
dosPathLength + sizeof(WCHAR),
'Temp'
);
if (!tempBuffer) {
return STATUS_INSUFFICIENT_RESOURCES;
}
// 构建原始DOS路径: "C:" + 剩余路径
tempBuffer[0] = driveLetter;
tempBuffer[1] = L':';
if (remainderLength > 0) {
RtlCopyMemory(
(PUCHAR)tempBuffer + 2 * sizeof(WCHAR),
(PUCHAR)NtPath->Buffer + linkTarget.Length,
remainderLength
);
}
tempBuffer[dosPathLength / sizeof(WCHAR)] = L'\0';
// 现在在前面加上 "\\??\\" 前缀
USHORT prefixLength = 8; // "\\??\\" 的字符数
USHORT totalLength = (prefixLength + dosPathLength / sizeof(WCHAR)) * sizeof(WCHAR);
DosPath->Buffer = (PWCHAR)ExAllocatePoolWithTag(
PagedPool,
totalLength + sizeof(WCHAR),
'DosP'
);
if (!DosPath->Buffer) {
ExFreePoolWithTag(tempBuffer, 'Temp');
return STATUS_INSUFFICIENT_RESOURCES;
}
// 组合最终路径: "\\??\\" + 原始DOS路径
swprintf(DosPath->Buffer, L"\\??\\%s", tempBuffer);
DosPath->Length = totalLength;
DosPath->MaximumLength = totalLength + sizeof(WCHAR);
// 释放临时缓冲区
ExFreePoolWithTag(tempBuffer, 'Temp');
return STATUS_SUCCESS;
}
}
}
return STATUS_NOT_FOUND;
}
输入
\\Device\\HarddiskVolume3\\test.docx
输出
\??\C:\test.docx
更多推荐
所有评论(0)