Windows 文件系统 API 不同的输出
Windows filesystem API different outputs
在我的工作场所,我们有一个包装在Win32文件系统API上的接口,它允许我们做一堆文件操作。我们有一个操作,它基本上调用GetFileAttributesExW
后跟FindFirstFileExW
。
这是一个简单的独立用例。
#include <Windows.h>
#include <string>
#include <iostream>
#include <errno.h>
#include <memory>
struct file_handle_close
{
void operator()(void *handle) const
{
if (static_cast<HANDLE>(handle) != INVALID_HANDLE_VALUE)
{
CloseHandle(static_cast<HANDLE>(handle));
}
}
};
typedef std::unique_ptr<void, file_handle_close> file_handle_uptr;
void function2(const std::wstring& path)
{
WIN32_FILE_ATTRIBUTE_DATA attr_ctx;
if (GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &attr_ctx) == 0)
{
DWORD error_code(GetLastError());
std::cout << "Error occurred in GetFileAttributesExW : "<< error_code << std::endl;
}
else
{
std::cout << "This is all good in GetFileAttributesExW!!!nn" ;
}
}
void function3(const std::wstring& path)
{
file_handle_uptr handle_uptr;
WIN32_FIND_DATAW file_attr;
DWORD error_code = ERROR_SUCCESS;
handle_uptr.reset(FindFirstFileExW(path.c_str(), FindExInfoBasic, &file_attr, FindExSearchNameMatch, nullptr, 0));
if (static_cast<HANDLE>(handle_uptr.get()) == INVALID_HANDLE_VALUE)
{
DWORD error_code(GetLastError());
std::cout << "Error occurred in FindFirstFileExW : "<< error_code << std::endl;
}
else
{
std::cout << "This is all good in FindFirstFileExW!!!nn" ;
}
}
int main(int argc,char** argv)
{
if(argc < 2)
{
std::cout << "Please enter a path!!!"<<std::endl;
}
else
{
const std::string str = argv[1];
const std::wstring wstr(str.begin(),str.end());
function2(wstr);
function3(wstr);
}
return 0;
}
我有两条具有混合权限的路径。
C:TEMPDir1Dir2 : Dir1 has permissions denied for current user
C:TEMPDIRXDIRYDIRZ : DIRX and DIRY have permissions denied for current user
我使用以下命令拒绝了权限
%icacls directoryname /deny username:(RX)
我使用这些路径作为上述代码创建的.exe文件的输入。我得到以下输出。
B:testfun>.testfun.exe C:TEMP
This is all good in GetFileAttributesExW!!!
This is all good in FindFirstFileExW!!!
B:testfun>.testfun.exe C:TEMPDir1
This is all good in GetFileAttributesExW!!!
This is all good in FindFirstFileExW!!!
B:testfun>.testfun.exe C:TEMPDir1Dir2 <-------- This
This is all good in GetFileAttributesExW!!!
Error occurred in FindFirstFileExW : 5
B:testfun>.testfun.exe C:TEMPDIRX
This is all good in GetFileAttributesExW!!!
This is all good in FindFirstFileExW!!!
B:testfun>.testfun.exe C:TEMPDIRXDIRY
Error occurred in GetFileAttributesExW : 5
Error occurred in FindFirstFileExW : 5
B:testfun>.testfun.exe C:TEMPDIRXDIRYDIRZ <-------- This
This is all good in GetFileAttributesExW!!!
Error occurred in FindFirstFileExW : 5
我想了解的是这些函数行为的差异。
为什么GetFileAttributesExW
给出不同的输出,而不是似乎尊重目录上设置的权限的FindFirstFileExW
?
我正在使用带有VS 10编译器的Windows 16299 Build 2017。
首先让我们看看FindFirstFileExW
如何使用第一个参数lpFileName
- 这不是最终的,确切地说是用于打开的文件的路径。 API 解析并拆分此字符串。 它在此字符串中搜索最后一个尾随反斜杠并将其拆分为 2 个字符串。 然后它是
lpFileName
的第一部分(在最后一个尾随反斜杠之前(,如果用作文件夹的路径,则尝试使用CC_打开系统9 访问。lpFileName
的第二部分(换行到UNICODE_STRING
后(在调用中使用NtQueryDirectoryFile
FileName
参数 -指向调用方分配的 Unicode 字符串的可选指针,其中包含 FileHandle 指定的目录中的文件(如果使用通配符,则为多个文件(的名称。
例如,如果您调用FindFirstFileExW(L"C:\TEMP\Dir1\Dir2", ..)
C:TEMPDir1Dir2
拆分为C:TEMPDir1
和Dir2
. 和系统尝试打开C:TEMPDir1
(并到达此处访问被拒绝(,然后(如果打开确定(将在文件夹中搜索Dir2
(确切(文件 - 一点意义都不大 - 通常我们使用通配符,例如C:TEMPDir1*
.
相反GetFileAttributesEx
使用lpFileName
作为文件的确切名称。
所以当你打电话
FindFirstFileExW(L"C:\TEMP\Dir1\Dir2", ..);
GetFileAttributesEx(L"C:\TEMP\Dir1\Dir2", ..);
您测试 2 个不同的文件夹:
C:TEMPDir1
(1 行(和C:TEMPDir1Dir2
(第二行( - 访问的结果可能不同也就不足为奇了。 第二 - 此 API 对文件夹使用不同的访问权限 - 当GetFileAttributesEx
仅需要FILE_READ_ATTRIBUTES
访问权限时,FindFirstFileExW
需要FILE_READ_DATA
。 因此,这也可能是不同的结果。 另请注意,FILE_READ_ATTRIBUTES
是文件系统的特殊访问权限。 NTFS(例如(授予FILE_READ_ATTRIBUTES
对调用方的访问权限2 种情况 - 如果调用方直接对文件具有FILE_READ_ATTRIBUTES
访问权限,或者如果调用方对父文件夹具有FILE_LIST_DIRECTORY
访问权限(作为旁注 - 与DELETE
访问权限相同 - 如果明确拥有文件或(如果没有(如果我们对父文件夹具有FILE_DELETE_CHILD
访问权限,我们可以获得它(。
如果对C:TEMPDir1
- 的案例调用不会失败,GetFileAttributesEx
,因为您在父文件夹上具有访问权限C:TEMP
FILE_LIST_DIRECTORY
。FindFirstFileExW
不会失败,因为它确实打开了您可以FILE_READ_DATA
访问的C:TEMP
(另请注意FILE_READ_DATA == FILE_LIST_DIRECTORY == 1
(
C:TEMPDIRX
GetFileAttributesExW
和FindFirstFileExW
正常,因为用户FILE_READ_DATA
(与FILE_LIST_DIRECTORY
相同(C:TEMP
C:TEMPDIRXDIRY
GetFileAttributesExW
失败,因为用户尚未FILE_READ_ATTRIBUTES
DirY
,也没有FILE_LIST_DIRECTORY
DirX
。FindFirstFileExW
失败,因为用户尚未FILE_READ_DATA
DirX
C:TEMPDIRXDIRYDIRZ
GetFileAttributesExW
好的 - 用户对DirZ
具有FILE_READ_ATTRIBUTES
访问权限。FindFirstFileExW
失败,因为用户尚未FILE_READ_DATA
DirY
- 文件系统:复制功能的速度秘诀是什么
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 如何传递多个 std::文件系统选项?
- 遍历顺序由 std::文件系统directory_iterator给出
- 有没有办法简单地从 GPU 调用多个 cpp 输出文件?
- libstdc++ 文件系统中未初始化的用法?
- boost::文件系统::recursive_directory_iterator多线程安全
- C++17 文件系统::remove_all 带有通配符路径
- VI工作室代码错误无法打开输出文件主.exe
- 实验性文件系统库不完整C++?
- 使用文件系统时仍然需要链接到带有 C++20 的 stdc++fs?
- 无法链接文件系统库C++
- 无法识别 Mac c++ 文件系统库
- 使用Boost文件系统C++将具有特定扩展名的文件的名称保存在特定文件夹中
- 获取 clang++:错误:在编译文件系统库的代码时
- C++17 文件系统在 Windows 10 上使用 nuwen MinGW
- C++ VS 错误:<实验/文件系统>提供 std::experimental::文件系统的标头已被Microsoft弃用,将被删除
- Windows 文件系统 API 不同的输出
- 使用boost ::文件系统库中的输出中的奇怪字符
- 使用 std::文件系统输出作为 LPCWSTR