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

开发 前端
由于 API 是一个已经对外公开的调用规范,不可轻易修改,否则会破坏兼容性。为此在最新的操作系统上运行那些老程序,只能最大限度地保留现有 API 的外部接口。同时,通过增加新的 API 来支持操作系统上开发出来的新特性。这就说我们经常说的:对扩展开放,对修改关闭。

​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 来支持操作系统上开发出来的新特性。这就说我们经常说的:对扩展开放,对修改关闭。

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

责任编辑:武晓燕 来源: 今日头条
相关推荐

2009-06-29 09:57:05

Unix

2012-12-24 15:00:56

sis塞班

2009-03-11 09:28:18

文件名乱码下载浏览器PHP

2021-03-16 12:42:42

FreeDOS开源

2009-10-24 10:38:34

2010-01-14 10:07:08

VB.NET文件名排序

2009-11-02 11:13:06

VB.NET读写文件

2012-10-09 16:37:20

FastDFS

2012-05-02 10:08:51

桌面Linux微软

2012-03-26 10:26:43

openstackeucalyptus

2012-08-17 10:01:07

云计算

2021-07-09 09:24:06

NanoID UUID软件开发

2020-03-30 15:05:46

Kafka消息数据

2014-03-05 14:58:00

苹果CarPlayiOS

2023-03-22 09:10:18

IT文档语言

2015-12-07 10:49:43

卸载App用户体验

2021-01-25 07:14:53

Cloud DevOps云计算

2022-04-13 20:53:15

Spring事务管理

2022-05-11 08:22:54

IO负载NFSOS

2021-06-28 11:30:39

PythonWindows反斜杠
点赞
收藏

51CTO技术栈公众号