You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows XP下NT设备路径短名扩展为长名的实现方案咨询

兼容Windows XP的可行实现方案

核心逻辑:利用CreateFile可直接识别原生NT路径的特性,通过文件句柄查询长名称,绕开Win32 API路径解析层对NT路径的格式限制。

具体实现步骤

  • 第一步:调用CreateFileW打开目标NT路径,使用最低权限参数避免占用或无法打开文件,同时兼容目录场景:
HANDLE hFile = CreateFileW(
    ntPath, // 从NtQueryObject拿到的原始NT路径,例如\Device\HarddiskVolume1\Users\ADMINI~1\...
    FILE_READ_ATTRIBUTES, // 仅需读取属性,权限要求最低
    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, // 不独占文件
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_BACKUP_SEMANTICS, // 支持打开目录句柄,适配路径为目录的场景
    NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
    // 自定义错误处理,如权限不足、文件已删除时可降级保留原始短名
    return;
}
  • 第二步:动态导入ntdll.dll中的NtQueryInformationFile函数,XP及以上系统均自带该导出,函数原型如下:
// 先定义需要用到的结构体和枚举
typedef enum _FILE_INFORMATION_CLASS {
    FileFullNameInformation = 14
} FILE_INFORMATION_CLASS;

typedef struct _IO_STATUS_BLOCK {
    union {
        NTSTATUS Status;
        PVOID Pointer;
    };
    ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef struct _FILE_FULL_NAME_INFORMATION {
    ULONG FileNameLength;
    WCHAR FileName[1];
} FILE_FULL_NAME_INFORMATION, *PFILE_FULL_NAME_INFORMATION;

// 导入函数
typedef NTSTATUS (WINAPI *PFN_NtQueryInformationFile)(
    HANDLE FileHandle,
    PIO_STATUS_BLOCK IoStatusBlock,
    PVOID FileInformation,
    ULONG Length,
    FILE_INFORMATION_CLASS FileInformationClass
);

PFN_NtQueryInformationFile pNtQueryInformationFile = (PFN_NtQueryInformationFile)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtQueryInformationFile");
  • 第三步:调用函数查询长路径,拼接得到完整NT长路径:
// 分配足够的缓冲区存储路径,最大路径长度设为32767即可覆盖所有合法路径
ULONG bufSize = 32767 * sizeof(WCHAR) + FIELD_OFFSET(FILE_FULL_NAME_INFORMATION, FileName);
PFILE_FULL_NAME_INFORMATION pNameInfo = (PFILE_FULL_NAME_INFORMATION)malloc(bufSize);
IO_STATUS_BLOCK iosb;

NTSTATUS status = pNtQueryInformationFile(
    hFile,
    &iosb,
    pNameInfo,
    bufSize,
    FileFullNameInformation
);

if (NT_SUCCESS(status)) {
    // 拆分原始NT路径,获取卷设备前缀(如\Device\HarddiskVolume1)
    WCHAR* pThirdBackslash = wcsstr(wcsstr(wcsstr(ntPath, L"\\"), L"\\") + 1, L"\\");
    if (pThirdBackslash) {
        WCHAR fullNtPath[32767];
        // 拼接卷前缀 + 查询到的长路径
        size_t prefixLen = pThirdBackslash - ntPath;
        wcsncpy(fullNtPath, ntPath, prefixLen);
        fullNtPath[prefixLen] = 0;
        wcsncat(fullNtPath, pNameInfo->FileName, pNameInfo->FileNameLength / sizeof(WCHAR));
        // fullNtPath即为转换完成的完整长名NT路径
    }
}

// 资源释放
free(pNameInfo);
CloseHandle(hFile);

可选兜底方案

如果目标文件被独占打开无法调用CreateFile,可以逐段解析路径:将路径按\分割,从卷根开始逐段调用NtQueryDirectoryObject枚举目录项,匹配短名得到对应长名后拼接,该方案无需打开目标文件,只是实现复杂度稍高。


内容的提问来源于stack exchange,提问作者DavidZi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:48:03