gpt4 book ai didi

c# - 使用 CreateFile 打开目录

转载 作者:行者123 更新时间:2023-11-30 15:04:30 31 4
gpt4 key购买 nike

我正在尝试利用 CreateFile 函数来访问目录信息。但是,我收到 win32 错误代码 5,这意味着访问被拒绝。请指教。

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来实现

最佳答案

首先,您应该在您的应用程序中包含 list ,以确保它在管理员权限下运行。然后,您应该使用 AdjustTokenPrivileges API 启用 SE_BACKUP_NAME 权限。那么我建议您使用 FILE_SHARE_DELETE |文件分享阅读 | 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 执行级别”(请参阅​​链接器设置的“ list 文件”部分)。上面的代码已经过测试,对我有用。您可以在 C# 中重现相同的代码。

关于c# - 使用 CreateFile 打开目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10198420/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com