GetFileVersionInfo 获取文件版本信息错误原因分析

概述

这两天遇到一个奇怪的问题:在一个进程中,通过GetFileVersionInfo去获取一个绝对路径文件的版本号时, 实际路径对应文件根本不存在,却获取到了版本号信息。在仔细分析GetFileVersionInfo内部实现后,真相终于大白,为了以后能更好的使用这个API,故把分析过程记录下来。

问题背景

一进程在判断是否需要打补丁时,需要去读取文件的版本号,读取路径是从一个库中配置的。在测试的库中,配置的条件是判断C:\Windows\system32\gdiplus.dll的版本号小于某个补丁,就说明用户机器上面需要安装该补丁。 

该进程运行后,分析到库的条件时,就会通过GetFileVersionIno获取C:\Windows\system32\gdiplus.dll模块的版本号来进行判断, 实际上在C:\Windows\system32\目录下面是不存在gdiplus.dll文件,但是GetFileVersionInfo这个函数却返回了成功,而且可以通过VerQueryValue能够查询出版本号, 从而导致扫描出的结果不符合预期。

为什么GetFileVersionInfo获取不存在路径的版本号信息会出错呢?

查找原因

查看msdn,GetFileVersionInfo:

GetFileVersionInfo function

Retrieves version information for the specified file.

Syntax

BOOL WINAPI GetFileVersionInfo(

  _In_        LPCTSTR lptstrFilename,

  _Reserved_  DWORD dwHandle,

  _In_        DWORD dwLen,

  _Out_       LPVOID lpData

);

Parameters

lptstrFilename [in]

Type: LPCTSTR

The name of the file. If a full path is not specified, the function uses the search sequence specified by the LoadLibrary function.

msdn 来看,如果输入不是全路径,则会通过LoadLibrary去搜索标识的文件名。

进一步查看GetFileVersionInfo内部实现:

BOOL
APIENTRY
GetFileVersionInfoA(
        LPSTR lpstrFilename,
        DWORD dwHandle,
        DWORD dwLen,
        LPVOID lpData
        )
{
    UNICODE_STRING FileName;
    ANSI_STRING AnsiString;
    NTSTATUS Status;
    BOOL bStatus;

    RtlInitAnsiString(&AnsiString, lpstrFilename);
    Status = RtlAnsiStringToUnicodeString(&FileName, &AnsiString, TRUE);
    if (!NT_SUCCESS(Status)) {
        SetLastError(Status);
        return FALSE;
    }

   <span style
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值