翻译《The Old New Thing》- 为什么 SHFormatDateTime 要接收一个未对齐的 FILETIME?

Why does SHFormatDateTime take an unaligned FILETIME? - The Old New Thing
https://devblogs.microsoft.com/oldnewthing/20251103-00/?p=111753
我之前曾提到,Windows 要求指针必须对齐,除非显式允许未对齐。我举了一个显式允许未对齐指针的函数例子,那就是 SHFormatDateTime:
LWSTDAPI_(int)SHFormatDateTimeA(_In_ const FILETIME UNALIGNED * pft,_Inout_opt_ DWORD * pdwFlags,_Out_writes_(cchBuf) LPSTR pszBuf,UINT cchBuf);
为什么这个函数要大费周章地允许未对齐的 FILETIME 呢?
SHFormatDateTime 最初是为 Explorer 编写的,用于在详细信息视图和属性表中格式化日期和时间。而这些 FILETIME 结构的常见来源是嵌入在 Shell 项 ID 列表中——通常称为 "pidls"(发音类似 "riddles"),因为它的匈牙利命名法是 pidl,即「指向 ID 列表的指针」。
Shell 项 ID 列表只要求字节对齐,因此你嵌入其中的任何结构都将是未对齐的。SHFormatDateTime 为了迎合其主要用户群体,不惜委曲求全,允许传入未对齐的 FILETIME 结构。(它 presumably 只是将其拷贝到一个已对齐的局部变量中。)
我怀疑 SHFormatDateTime 函数最初是为 Windows 95 系列编写的,该系列运行在 x86 架构处理器上,而 x86 处理器对未对齐访问很宽容。当 Windows NT 团队将代码移植到对对齐敏感的 RISC 处理器时,他们厌倦了逐个修复调用点来将未对齐的 FILETIME 拷贝到已对齐的局部变量,于是他们干脆让 SHFormatDateTime 函数本身容忍未对齐,把拷贝未对齐 FILETIME 到局部变量这项工作转移到 SHFormatDateTime 函数内部来完成。
所以实际上,SHFormatDateTime 接受未对齐指针这件事,只是一个历史上的权宜之计,而非其原始设计的一部分。现如今,我们只会要求所有人在调用端对齐 FILETIME,而不是在接收端处理。
- btw,欢迎关注我
- @0x0007 ~ 😃
- Windows|HarmonyOS|AIGC
