首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VerQueryValue in Windows10

VerQueryValue in Windows10
EN

Stack Overflow用户
提问于 2016-11-28 08:55:15
回答 1查看 954关注 0票数 0

我已经用我的Win8项目从Win10搬到了VS2012 C++。我在Win8中使用Win8函数时没有问题,但现在在调试过程中出现了错误:

代码语言:javascript
复制
Unhandled exception at 0x77C88F11 (ntdll.dll) in MyApp.exe: 0xC0000005: Access violation writing location 0x00AAC2DC.

我使用来自MSDN的示例代码

代码语言:javascript
复制
CString GetVersionInfo(HMODULE hLib, CString csEntry)
{
    CString csRet;

    if (hLib == NULL)
        hLib = AfxGetResourceHandle();

    HRSRC hVersion = FindResource( hLib, 
        MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION );
    if (hVersion != NULL)
    {
        HGLOBAL hGlobal = LoadResource( hLib, hVersion ); 
        if ( hGlobal != NULL)  
        {  

            LPVOID versionInfo  = LockResource(hGlobal);  
            if (versionInfo != NULL)
            {
                DWORD vLen,langD;
                BOOL retVal;    

                LPVOID retbuf=NULL;

                static char fileEntry[256];

                sprintf(fileEntry,"\\VarFileInfo\\Translation");
                retVal = VerQueryValue(versionInfo,fileEntry,&retbuf,(UINT *)&vLen);
                if (retVal && vLen==4) 
                {
                    memcpy(&langD,retbuf,4);            
                    sprintf(fileEntry, "\\StringFileInfo\\%02X%02X%02X%02X\\%s",
                        (langD & 0xff00)>>8,langD & 0xff,(langD & 0xff000000)>>24, 
                        (langD & 0xff0000)>>16, csEntry);            
                }
                else 
                    sprintf(fileEntry, "\\StringFileInfo\\%04X04B0\\%s", 
                    GetUserDefaultLangID(), csEntry);

                if (VerQueryValue(versionInfo,fileEntry,&retbuf,(UINT *)&vLen)) 
                    csRet = (char*)retbuf;
            }
        }

        UnlockResource( hGlobal );  
        FreeResource( hGlobal );  
    }

    return csRet;
}

有什么问题吗?

EN

回答 1

Stack Overflow用户

发布于 2016-11-28 20:36:09

您正在直接访问版本资源数据,而不是使用GetFileVersionInfo()。因此,不能使用VerQueryValue()查询本地化的值,您可以只查询VS_FIXEDFILEINFO结构,而不需要查询其他任何东西。即使如此,您也不能将LockResource()的返回值用于该访问。在访问结构之前,必须将资源数据复制到您自己的读/写内存缓冲区中。

这是因为GetFileVersionInfo()执行VerQueryValue()内部使用的数据查找和内存块分配。雷蒙德·陈在他的博客上解释道:

VerQueryValue的第一个参数实际上必须是从GetFileVersionInfo获得的缓冲区。

文档指出,VerQueryValue的第一个参数必须是GetFileVersionInfo函数出于某种原因返回的缓冲区。 GetFileVersionInfo返回的缓冲区是一个特殊格式化的不透明数据块,以便VerQueryValue能够工作。您不应该查看该缓冲区,当然也不能尝试“以其他方式获取数据”。因为(如果是这样的话),VerQueryValue将在缓冲区中查找不按函数所期望的方式格式化的内容。

这就是为什么您要崩溃的原因-- VerQueryValue()正在尝试访问未正确设置的内存。

如果要直接访问版本资源,则需要手动解析其数据,根本不使用VerQueryValue()。你很幸运你的代码从来没有崩溃过。您是在未定义的行为区域操作的!你的运气已经用完了。你需要重写代码来做正确的事情。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40840337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档