当前位置: 首页 > 科技观察

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

时间:2023-03-13 16:33:19 科技观察

FindFirstFile函数尝试匹配短文件名和长文件名。这可能会产生一些令人惊讶的结果。例如,如果您搜索“*.htm”,那么它会返回文件“x.html”,因为它的短文件名是“X~1.HTM”。这着实令人意外。为什么FindFirstFile匹配短文件名?它不应该只匹配长文件名吗?毕竟,只有旧的16位程序使用短文件名。但问题是:16位程序只使用短文件名。通过一种称为UniversalThunk的方法,16位程序可以加载32位DLL并调用它。Windows95和WindowsNT中的Windows16位仿真层严重依赖通用的Thunk,因此他们不必为所有内容编写两个版本。相反,16位版本只是对32位版本的升级。但是请注意,这意味着32位DLL将看到文件系统的两个不同视图,具体取决于它们是从16位进程还是32位进程托管的。“然后让FindFirstFile函数检查其调用者是谁,并相应地更改其行为”,因为您不能信任返回地址,所以这不会起作用。即使修复了这个问题,您仍然会遇到跨进程边界的16/32互操作性问题。例如,假设一个16位程序调用WinExec("NotepadX~1.HTM")。32位记事本程序最好打开文件X~1.HTM,即使它是一个短文件名。此外,获取文件属性(如上次访问时间)的常用方法是使用文件名调用FindFirstFile,因为WIN32_FIND_DATA结构返回该信息作为查找数据的一部分。(注意:GetFileAttributesEx是更好的选择,但该功能相对较新。如果FindFirstFile函数不适用于短文件名,则上述技巧对于跨越16/32边界的短文件名将失败。再举一个例子,假设DLL将文件名保存在进程之外的位置,例如配置文件、注册表或共享内存块。如果16位程序调用此DLL,它将传递短文件名,如果32位程序调用DLL,它会传递长文件如果文件系统函数只返回长文件名给32位程序,运行在32位程序中的DLL副本将无法读取DLL写入的数据在16位程序中运行。总结由于API是已经公开的调用规范,不能轻易修改,否则会破坏兼容性。要在最新的操作系统上运行那些老程序,只能最大程度地保留现有API的对外接口。同时,通过增加新的API支持在操作系统上开发的新特性。这就是我们常说的:对扩展开放,对修改关闭。因此,“先知先觉”是策划高层设计的一种特殊能力。