首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么 FindFirstFile 会查找短文件名?

FindFirstFile 函数会尝试匹配短文件名和长文件名。这可能会产生一些令人惊讶的结果。例如,如果你查找 “*.htm” ,那么它会返回给你文件 “x.html” ,因为它的短文件名是 “X~1.HTM”。 这确实比较令人感到意外。

为什么 FindFirstFile 会匹配短文件名呢?它不应该只匹配长文件名吗?毕竟,只有旧的 16 位程序才会使用短文件名。

但这就是问题所在:16位程序才会使用短文件名。

通过称为通用Thunk 的方法,16 位程序可以加载 32 位 DLL 并调用它。Windows 95和Windows NT中的Windows 16位仿真层严重依赖通用Thunk,因此他们不必编写所有内容的两个版本。相反,16 位版本只是升级到 32 位版本。

但请注意,这意味着 32 位 DLL 将看到文件系统的两个不同视图,具体取决于它们是从 16 位进程还是 32 位进程托管的。

“然后让 FindFirstFile 函数检查其调用方是谁,并相应地更改其行为”,因为你无法信任返回地址,因此这种方法不会起作用。

即使解决了这个问题,你仍然会遇到跨进程边界的 16/32 互操作的问题。

例如,假设一个 16 位程序调用 WinExec(”记事本 X~1.HTM”)。32位记事本程序最好打开文件X~1.HTM,即使它是一个短文件名。此外,获取文件属性(如上次访问时间)的常用方法是使用文件名调用 FindFirstFile,因为 WIN32_FIND_DATA 结构将该信息作为查找数据的一部分返回。(注意:GetFileAttributesEx 是更好的选择,但该功能相对较新。如果 FindFirstFile 函数不适用于短文件名,则上述技巧对于跨 16/32 边界传递的短文件名将失败。

再举一个例子,假设 DLL 将文件名保存在进程外部的位置,例如配置文件、注册表或共享内存块。如果 16 位程序调用此 DLL,它将传递短文件名,而如果 32 位程序调用 DLL,它将传递长文件名。如果文件系统函数仅返回 32 位程序的长文件名,则在 32 位程序中运行的 DLL 副本将无法读取在 16 位程序中运行的 DLL 写入的数据。

总结

由于 API 是一个已经对外公开的调用规范,不可轻易修改,否则会破坏兼容性。

为此在最新的操作系统上运行那些老程序,只能最大限度地保留现有 API 的外部接口。

同时,通过增加新的 API 来支持操作系统上开发出来的新特性。

这就说我们经常说的:对扩展开放,对修改关闭。

所以,”先知性” 是在规划高层设计的一项特殊能力。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。

本文来自:《Why does FindFirstFile find short names?》

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20221201A00PWA00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券