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

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐