【问题标题】:_stat fails on networked directory_stat 在网络目录上失败
【发布时间】:2018-06-15 07:56:48
【问题描述】:

我的程序通过 LAN 将文件从我的 Windows 笔记本电脑复制到我的 Windows 桌面。我使用资源管理器中的拖放来提供源和目标。

来源为:C:\Paul

目的地是:\\SERVER\Paul

但是,_stat(dst,&dst_statbuf) 失败,-1errno 设置为 ENOENT(找不到文件)。

请注意,从资源管理器拖放提供的路径是正确且存在的,在资源管理器中我可以看到目标目录并可以打开文件,因此权限似乎没问题。

有人知道_stat 失败的原因吗?

【问题讨论】:

  • @PaulOgilvie _stat 不写。尝试进入_stat 函数并查看实际调用的win32 函数,这可能会给您一些提示。当您调用_stat 时,dst 文件是否真的存在?
  • @MichaelWalz,它使用_stat64i32。目标(目录)存在。
  • 进一步进入_stat64i32 函数,直到遇到原始的win32 函数。
  • 你需要什么_stat?您可以改用GetFileInformationByHandleExZwQueryInformationFile

标签: c windows winapi visual-studio-2008 lan


【解决方案1】:

找到问题了。

stat64.c (VC2008) 中有奇怪的评论:

/* root dir. ('C:\') or UNC root dir. ('\\server\share\') */

随后调用未记录的 API 函数(第 145 行):

IsRootUNCName(path)

确实,将反斜杠附加到 服务器路径 可以使 _stat 工作。但请注意,在服务器路径上的常规目录上调用 _stat 也可以。所以它只会在共享的根目录上失败。

我认为这是一个错误(或者至少是 Windows 资源管理器和 _stat 之间的不一致)

【讨论】:

  • 我确认,使用 VS2017 和 UCRT 我没有这个问题,它可以使用或不使用最终反斜杠。
  • 并不那么令人惊讶。 C: 不同于 C:`. The former is the current directory on drive C, the latter is the root of C`。在这里阅读:msdn.microsoft.com/en-us/library/windows/desktop/…
  • @DavidHeffernan,我不确定这是否适用。您的参考资料说“如果文件名不以 ... UNC 名称开头,则它是相对于当前目录的”,并且特定于磁盘字母它说“如果文件名以冒号后只有一个磁盘指示符而不是反斜杠,它被解释为驱动器上当前目录的相对路径"
  • 旧版本的 CRT 调用 FindFirstFile[Ex] 以获取统计信息。此函数对卷和 UNC 根目录失败,因此 CRT 在这种情况下伪造了 stat 条目。 IsRootUNCName 是 stat64.c 中定义的静态函数。它被称为验证路径是否为有效根目录的一部分,它实际上为没有尾部斜杠的 UNC 路径返回 true。但是,随后的GetDriveType 调用返回DRIVE_NO_ROOT_DIR (1)。由于它不是要伪造的根目录,因此 stat 调用失败并显示 ENOENT
  • 新的通用 CRT 不再使用FindFirstFileEx。相反,它调用CreateFile 并通过GetFileTypeGetFileInformationByHandle 获取统计信息。这应该适用于根目录,但如果由于某种原因它无法获得句柄,如果路径是有效的根目录,它仍然默认返回假条目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 2016-12-28
  • 2015-10-22
  • 2015-05-18
  • 1970-01-01
  • 2017-10-19
相关资源
最近更新 更多