如何以编程方式调用fsutil 8dot3name api?

问题描述 投票:0回答:1

我想使用一些 winapi 函数以编程方式调用 fsutil 8dot3name,但我未能通过谷歌搜索找到任何等效的 winapi 。

有人知道这样的winapi函数是否存在吗?

fsutil.exe 8dot3name set O:\ 1
fsutil.exe 8dot3name strip /s /f O:\
c++ winapi fsutil
1个回答
0
投票
fsutil.exe 8dot3name set O:\ 1

对于设置启用/禁用卷上的短名称创建,我们可以使用

FSCTL_QUERY_PERSISTENT_VOLUME_STATE
控制代码

NtFsControlFile
DeviceIoControl

ULONG SetPersistentVolumeState(PCWSTR pszVolumePath, ULONG VolumeFlags)
{
    if (HANDLE hFile = fixH(CreateFileW(pszVolumePath, FILE_WRITE_ATTRIBUTES, 
        FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)))
    {
        FILE_FS_PERSISTENT_VOLUME_INFORMATION PersistVolInfo = { 
            VolumeFlags, 
            PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED,
            1
        };

        ULONG dwError = NOERROR;
        OVERLAPPED ov = {};
        if (!DeviceIoControl(hFile, FSCTL_SET_PERSISTENT_VOLUME_STATE, &PersistVolInfo, sizeof(PersistVolInfo), 0, 0, 0, &ov))
        {
            dwError = GetLastError();
        }
        CloseHandle(hFile);

        return dwError;
    }

    return GetLastError();
}

inline HANDLE fixH(HANDLE hFile)
{
    return hFile == INVALID_HANDLE_VALUE ? 0 : hFile;
}

如果我们想对系统上的所有卷执行此操作,请将

NtfsDisable8dot3NameCreation
中的
REG_DWORD
HKLM\System\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation
设置为 所述

如果我们想要查询文件短名,请使用

FileAlternateNameInformation
。 该信息类用于 查询文件的备用名称信息。替代名称为 文件是其 8.3 格式名称(出现在文件之前的八个字符) “。”以及之后出现的三个字符)。一个文件可能有一个 备用名称以实现与 8.3 命名的兼容性 遗留应用程序的要求。<101>

服务器返回包含 8.3 文件名(第 2.1.5.2.1 节)的 FILE_NAME_INFORMATION(第 2.1.7 节)数据元素。 如果文件没有短名称,我们会得到

STATUS_OBJECT_NAME_NOT_FOUND

对于设置/删除短名称,我们需要使用

FileShortNameInformation

该信息类用于更改文件的短名称。如果提供的名称长度为零,则为文件的现有短名称,如果 任何,应该被删除。否则,提供的名称必须是 2.1.5.2.1 节中指定的有效短名称,并且在其中是唯一的 与该文件位于同一目录中的所有文件名和短名称 进行了手术。更改文件短名称的调用者必须具有 SeRestorePrivilege,如 [MS-LSAD] 第 3.1.1.2.1 节中指定。一个 FILE_NAME_INFORMATION(第 2.1.7 节)包含 8.3 的数据元素 文件名(第2.1.5.2.1节)由客户提供。<144>

NTSTATUS Strip(PCWSTR pszFileName) { HANDLE hFile; IO_STATUS_BLOCK iosb; UNICODE_STRING ObjectName; OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE }; NTSTATUS status; RtlInitUnicodeString(&ObjectName, pszFileName); if (0 <= (status = NtOpenFile(&hFile, DELETE, &oa, &iosb, FILE_SHARE_VALID_FLAGS, FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT))) { union { FILE_NAME_INFORMATION fni; UCHAR buf[offsetof(FILE_NAME_INFORMATION, FileName) + (8+1+3)*sizeof(WCHAR)]; }; if (0 <= (status = NtQueryInformationFile(hFile, &iosb, &fni, sizeof(buf), FileAlternateNameInformation))) { DbgPrint("%.*ws\n", fni.FileNameLength, fni.FileName); fni.FileNameLength = 0; NtSetInformationFile(hFile, &iosb, &fni, sizeof(fni), FileShortNameInformation); } NtClose(hFile); } return status; }
请注意,在执行此操作之前,我们必须启用 SeRestorePrivilege(以及更好的 SeBackupPrivilege)。并且打开文件

必须DELETE

访问权限打开。

FileShortNameInformation 更改当前短文件名,该文件名在 FILE_NAME_INFORMATION 结构中提供。该文件必须位于 NTFS 卷,并且调用者必须使用以下命令打开文件 DesiredAccess 参数中设置的 DesiredAccess DELETE 标志。

如果我们想对每个文件夹执行此操作(必需) - 我们需要枚举文件夹中的所有文件并对每个文件执行此操作

© www.soinside.com 2019 - 2024. All rights reserved.