为什么 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?》
相关文章
- 什么是dtd文件,为什么需要dtd
- @transactional注解在什么情况下会失效,为什么。
- 数据人PK也无人,为什么业务部门的数据需求都是急活?
- scala为什么需要函数
- [FAQ] 为什么部署到 github pages 时自定义域名总失效 (push-dir)
- 为什么使用中间件下载时总是收到警告消息Object is in status Wait
- 为什么CRM Opportunity的删除会触发一个通向BW系统的RFC
- 为什么某些订单的参与者Participant无法被删除
- 为什么选择用Python做数据分析,看这篇就懂了!
- Python是什么?为什么一定要学Python?
- 618技术特辑(三)直播带货王,“OMG买它”的背后,为什么是一连串技术挑战?
- 什么是基因测序,为什么需要云计算
- 为什么软件正在吞噬这个世界?by 网景创始人 Marc Andreessen 马克·安德森
- Java 为什么要使用反射(通俗易懂的举例)
- LabVIEW为什么在存储VI时死机
- 为什么Windows不再自动探测所有网络上的主机?
- 转:为什么领导没时间,下属没事做?
- 为什么逻辑回归是线性分类器?【转载】
- TRIZ发明问题解决理论——本质是分析问题中的矛盾,利用资源(时间空间物质能量功能信息等)来解决矛盾从而解决问题——抽象出来:问题是什么,为什么?