gpt4 book ai didi

c++ - Windows CopyFileA 失败然后成功

转载 作者:行者123 更新时间:2023-12-04 06:02:56 25 4
gpt4 key购买 nike

bounty 4 天后到期。此问题的答案有资格获得 +100 声望奖励。
KiwiJaune正在寻找信誉良好的来源的答案:

I am looking from a solution to copy this 1st file successfully or, if it's not possible, an explanation on Windows internal behaviour that leads to this behaviour. Thanks !








尝试将文件复制到具有特定权限的文件夹时遇到问题。
这是我非常简单的测试程序:
#include <iostream>
#include <windows.h>

int main()
{
if(CopyFileA("D:/SOURCE/File.txt", "D:/LOCKED/dst1.txt", TRUE))
std::cout << "OK\n";
else
std::cout << "Fail\n";

if (CopyFileA("D:/SOURCE/File.txt", "D:/LOCKED/dst2.txt", TRUE))
std::cout << "OK\n";
else
std::cout << "Fail\n";

system("PAUSE");
}
结果如下:
Fail
OK
我可以复制任意数量的文件。对于每次运行,第一次总是失败,后续总是成功。错误是 ERROR_ACCESS_DENIED。
这是重要的细节:我的目标文件夹具有受限的权限,只有当我删除“写入属性”或“写入扩展属性”时才会出现此行为。
enter image description here
我使用了 sysInternals 的进程监视器:没有其他进程正在访问源文件和目标文件。但是,目标文件上的行为并不相似。第一次尝试关闭文件并尝试重新打开它。以下是日志:


行动
地位
细节


失败的尝试(第一次)
——
——

创建文件
成功
所需访问:通用读/写、删除、写 DAC、处置:创建、选项:顺序访问、非目录文件、属性:A、共享模式:无、分配大小:0、OpenResult:已创建

关闭文件
成功

创建文件
拒绝访问
所需访问:通用读/写、删除、写 DAC、处置:OpenIf、选项:顺序访问、同步 IO 非警报、非目录文件、属性:A、共享模式:无、分配大小:0

创建文件
拒绝访问
所需访问:通用读/写、删除、写 DAC、处置:OpenIf、选项:顺序访问、同步 IO 非警报、非目录文件、属性:A、共享模式:读、写、分配大小:0

创建文件
拒绝访问
所需访问:通用读/写、写 DAC、处置:OpenIf、选项:顺序访问、同步 IO 非警报、非目录文件、属性:A、共享模式:读、写、分配大小:0

创建文件
拒绝访问
所需访问:通用读/写,处置:OpenIf,选项:顺序访问,同步 IO 非警报,非目录文件,属性:A,共享模式:无,分配大小:0

创建文件
拒绝访问
所需访问:通用读/写,处置:OpenIf,选项:顺序访问,同步 IO 非警报,非目录文件,属性:A,共享模式:读、写,分配大小:0

成功的尝试(第二次和后续)
——
——

创建文件
成功
所需访问:通用读/写、删除、写 DAC、处置:创建、选项:顺序访问、同步 IO 非警报、非目录文件、属性:A、ShareMode:无、AllocationSize:0、OpenResult:已创建

QueryAttributeInformationVolume
成功
FileSystemAttributes: Case Preserved, Case Sensitive, Unicode, ACLs, Compression, Named Streams, EFS, Object IDs, Reparse Points, Sparse Files, Quotas, Transactions, 0x3c00600, MaximumComponentNameLength: 255, FileSystemName: NTFS

查询基本信息文件
成功
CreationTime:19/08/2021 15:20:32,LastAccessTime:19/08/2021 15:20:32,LastWriteTime:19/08/2021 15:20:32,ChangeTime:19/08/2021 15:20: 32、FileAttributes:A

SetEndOfFileInformationFile
成功
文件结尾:24

写文件
成功
偏移:0,长度:24,优先级:正常

读取文件
成功
偏移量:0,长度:24,I/O 标志:非缓存,分页 I/O,同步分页 I/O,优先级:正常

设置基本信息文件
成功
CreationTime:01/01/1601 02:00:00,LastAccessTime:01/01/1601 02:00:00,LastWriteTime:19/08/2021 14:50:49,ChangeTime:19/08/2021 14:50: 49、FileAttributes:不适用

QueryRemoteProtocolInformation
无效的参数

关闭文件
成功



编辑1:
这是 get-acl D:\LOCKED | fl回复:
Path   : Microsoft.PowerShell.Core\FileSystem::D:\LOCKED
Owner : BUILTIN\Administrators
Group : KJ-WIN10\None
Access : Everyone Allow CreateFiles, AppendData, ReadAndExecute, Synchronize
Audit :
Sddl : O:BAG:S-1-5-21-1983668899-2794625975-2151939504-513D:PAI(A;OICI;0x1200af;;;WD)
您可以在 https://github.com/KiwiJaune/CantMove/blob/master/Program.cs 使用我的 C# 示例程序重现完整行为(文件夹创建和文件复制)。 .
编辑2:
这是 fltmc在几台经过测试的 PC 之一上的结果:


过滤器名称
数量实例
高度
框架


绑定(bind)
1
409800
0

依赖
12
407000
0

过滤器
12
328010
0

暴风雪
0
244000
0

西弗斯
4
189900
0

氟利昂
2
180451
0

自卫队
12
145900
0

文件加密
0
141100
0

路飞
1
135000
0

npsvctrig
1
46000
0

沃夫
8
40700
0

文件信息
12
40500
0


我发现它总是在 D:/或闪存驱动器上失败,但在 C:/上成功,无论 D: 是另一个物理磁盘还是与 C: 相同磁盘上的分区...
我在 4 台经过测试的 PC 上有相同的行为(3 台 Win10 和 1 台 Win7)
是否有 Windows 已知行为?
提前感谢您的想法。

最佳答案

这是正常的,因为它是未定义的行为。
CopyFileA 的文档中你可以找到这一行:

File attributes for the existing file are copied to the new file.


不明显的是 copying attributes在单独的操作中完成。所以 CopyFileA 内部有两个步骤:
  • 复制文件
  • 复制属性

  • 当您删除 Write attributes 时和 Write extended attributes权限第二步不再可能。因此出现 ERROR_ACCESS_DENIED 错误。
    由于缓存,后续文件工作。第一个复制操作被缓存,现在可以重用。
    要修复它,您需要正确使用该功能。 CopyFileA对能够复制文件属性有严格的要求。因此,您必须启用目标文件夹的写入权限:
  • 使用 SetNamedSecurityInfo 启用写权限或 SetSecurityInfo
  • 使用 CopyFileA
  • 复制文件
  • 禁用写权限

  • 一些有用的链接:
  • https://docs.microsoft.com/en-us/windows/win32/fileio/file-security-and-access-rights
  • https://docs.microsoft.com/en-us/windows/win32/secauthz/modifying-the-acls-of-an-object-in-c--
  • 关于c++ - Windows CopyFileA 失败然后成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68849367/

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