开放目录的CreateFile(Open Directory Using CreateFil

2019-09-16 14:15发布

我想利用CreateFile函数来访问目录信息。 我recieving的5 Win32错误代码然而,这意味着访问被拒绝。 请指教。

CreateFile(path, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero);

这是正在进行的呼叫,并且在文件中指出正在使用的“FILE_FLAG_BACKUP_SEMANTICS”。 该DLL的进口似乎是工作的罚款,如下所示:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateFile(string filename,
                                    uint desiredAccess,
                                    uint sharedMode,
                                    IntPtr securityAttributes,
                                    uint creationDisposition,
                                    uint flagsAndAttributes,
                                    IntPtr templateFile);

更新:我需要获得句柄到一个目录,所以我可以用GetFileInformationByHandle()和提取的唯一ID。 这种方法目前与文件,它不处理目录的当前。

更新:对于这个问题的X是我需要有一个目录的唯一标识符比其绝对路径以外的东西。 它需要保持不变,即使目录被移动或重命名。 .NET不提供任何唯一标识符刚才提到的,它只能通过使用Win32完成

Answer 1:

首先,你应该在你的应用程序清单,以确保它在管理员权限下运行。 那么你应该能够SE_BACKUP_NAME使用权限AdjustTokenPrivileges API。 然后,我会建议你使用FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE标志作为sharedMode 。 现在,你应该能够使用CreateFile打开目录,手柄,并利用GetFileInformationByHandle得到BY_HANDLE_FILE_INFORMATION

更新 :也许下面简单的演示程序可以帮助你

#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;
}

该程序打开C:\目录下,并显示卷序列号和文件索引,其标识在NTFS目录。 为了让我删除了所有的错误信息程序更短(见__leave语句)。 就像我已经提到之前你应该使用requireAdministrator为“UAC执行级别”(见链接器设置“清单文件”部分)。 上面的代码进行测试,它在我的工作。 您可以复制在C#中相同的代码。



文章来源: Open Directory Using CreateFile