Open Directory Using CreateFile

我的未来我决定 提交于 2019-12-06 03:37:17

First of all you should include manifest in your application to be sure that it runs under Administrator privileges. Then you should enable SE_BACKUP_NAME privilege using AdjustTokenPrivileges API. Then I would recommend you to use FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE flags as the sharedMode. Now you should be able to use CreateFile to open the directory handle and use GetFileInformationByHandle to get BY_HANDLE_FILE_INFORMATION.

UPDATED: Probably the following simple demo program can help you

#include <windows.h>
#include <tchar.h>

int _tmain()
{
    HANDLE hAccessToken = NULL;
    HANDLE hFile = INVALID_HANDLE_VALUE;

    __try {
        LUID luidPrivilege;
        DWORD dwErrorCode;
        BY_HANDLE_FILE_INFORMATION fiFileInfo;

        // -----------------------------------------------------
        // first of all we need anable SE_BACKUP_NAME privilege
        // -----------------------------------------------------
        if (!OpenProcessToken (GetCurrentProcess(),
                               TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                               &hAccessToken))
            __leave;

        if (LookupPrivilegeValue (NULL, SE_BACKUP_NAME, &luidPrivilege)) {
            TOKEN_PRIVILEGES tpPrivileges;
            tpPrivileges.PrivilegeCount = 1;
            tpPrivileges.Privileges[0].Luid = luidPrivilege;
            tpPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            AdjustTokenPrivileges (hAccessToken, FALSE, &tpPrivileges, 
                                   0, NULL, NULL);
            if ((dwErrorCode = GetLastError ()) != ERROR_SUCCESS)
                __leave;
        }
        else
            __leave;

        // -----------------------------------------------------
        // now one can open directory and get 
        // -----------------------------------------------------
        hFile = CreateFile (TEXT("C:\\"),
                            0, //GENERIC_READ, 
                            0, //FILE_SHARE_READ, //FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                            NULL,
                            OPEN_EXISTING, 
                            FILE_FLAG_BACKUP_SEMANTICS,
                            NULL);
        if (hFile == INVALID_HANDLE_VALUE)
            __leave;
        if (!GetFileInformationByHandle (hFile, &fiFileInfo))
            __leave;

        _tprintf(TEXT("VolumeSerialNumber: 0x%08X\n"), fiFileInfo.dwVolumeSerialNumber);
        _tprintf(TEXT("FileIndex: 0x%08X%08X\n"), fiFileInfo.nFileIndexHigh, fiFileInfo.nFileIndexLow);
    }
    __finally {
        if (hFile != INVALID_HANDLE_VALUE)
            CloseHandle (hFile);
        if (hAccessToken != NULL)
            CloseHandle (hAccessToken);
    }

    return 0;
}

The program opens C:\ directory and display Volume Serial Number and File Index which identify the directory on the NTFS. To make program shorter I removed all error messages (see __leave statements). Like I already mention before you should use requireAdministrator as "UAC Execution Level" (see "Manifest File" part of the Linker settings). The above code is tested and it work at me. You can reproduce the same code in C#.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!