0
    DWORD dwHandle;

    DWORD dwSize = GetFileVersionInfoSizeEx( FILE_VER_GET_NEUTRAL , strFilePath.c_str() , &dwHandle );
    if( dwSize == 0 )
        break;
    pVersionInfo = new BYTE[ dwSize ];
    bRetVal = GetFileVersionInfoEx( FILE_VER_GET_NEUTRAL , strFilePath.c_str() ,dwHandle , dwSize , &pVersionInfo );
    if( bRetVal == false )
        break;
    UINT uLen;
    VS_FIXEDFILEINFO *pFileInfo;

    bRetVal = VerQueryValue( &pVersionInfo , L"\\" , (LPVOID *)&pFileInfo , &uLen );

    if( bRetVal == false )
        break;
    DWORD dwFileVersionMS = pFileInfo->dwFileVersionMS;
    DWORD dwFileVersionLS = pFileInfo->dwFileVersionLS;

    DWORD dwLeftMost     = HIWORD(dwFileVersionMS);
    DWORD dwSecondLeft   = LOWORD(dwFileVersionMS);
    DWORD dwSecondRight  = HIWORD(dwFileVersionLS);
    DWORD dwRightMost    = LOWORD(dwFileVersionLS);

    strVersion.sprintf( L"%u.%u.%u.%u", dwLeftMost , dwSecondLeft , dwSecondRight , dwRightMost );
}while(0);
if( pVersionInfo )
    delete []pVersionInfo;
return bRetVal;

While debugging this code i am getting access violation error at delete statement . . can anyone tell what i am doing wrong.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
Anup
  • 61
  • 1
  • 9

3 Answers3

2

The error is that you pass a pointer to the pointer to the allocated data block as the first argument to VerQueryValue, which leads to you passing the wrong address to the function. This leads to undefined behavior as VerQueryValue reads data from, and writes data to, somewhere in memory where it should not be read from/written to.

The solution is to not use the address-of operator here.


Update: you do the same thing with the GetFileVersionInfoEx function call. Don't use the address-of operator for pVersionInfo.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Need to specify which 'address-of' operator for this answer to be helpful... I *think* you mean `pVersionInfo` instead of `&pVersionInfo`. – Roddy Oct 01 '13 at 11:54
  • Looks like call to `GetFileVersionInfoEx` is similarly wrong! – Roddy Oct 01 '13 at 12:08
1

The error is in the line

bRetVal = GetFileVersionInfoEx( FILE_VER_GET_NEUTRAL , strFilePath.c_str() ,dwHandle , dwSize , &pVersionInfo );

The correct call should be

bRetVal = GetFileVersionInfoEx( FILE_VER_GET_NEUTRAL , strFilePath.c_str() ,dwHandle , dwSize , pVersionInfo );

From msdn:

BOOL WINAPI GetFileVersionInfoEx(
  _In_        DWORD dwFlags,
  _In_        LPCTSTR lptstrFilename,
  _Reserved_  DWORD dwHandle,
  _In_        DWORD dwLen,
  _Out_       LPVOID lpData
);

The function GetFileVersionInfoEx() will fill the buffer pointed to by lpData (or, in the corrected above example, pVersionInfo) with the version info. In your code, it would be changing the value of the pointer, making it point to somewhere else in memory.

When you call delete[], it is giving you the exception because the value of your pointer has changed and it is no longer the value set by the new [] operator. In other words you are trying to free memory that was not dynamically allocated.

ajcaruana
  • 505
  • 3
  • 14
0

Here is the solution yo your issue in another thread with a full code example, but as pointed out the issue is that you are passing the pointer to the buffer for the information the wrong way, no need for the address of opearator.

Here is a snipplet with your code fixed to be working:

#include <Windows.h>
#include <cstdio>

#pragma comment(lib, "version.lib")

void main(int argc, char** argv)
{
    const wchar_t* strFilePath = L"C:\\Windows\\System32\\kernel32.dll";
    DWORD dwHandle;
    BOOL bRetVal;
    DWORD dwSize = GetFileVersionInfoSizeEx( FILE_VER_GET_NEUTRAL , strFilePath , &dwHandle );
    if( dwSize == 0 )
        return;
    BYTE* pVersionInfo = new BYTE[dwSize];
    bRetVal = GetFileVersionInfoEx( FILE_VER_GET_NEUTRAL , strFilePath , dwHandle , dwSize , pVersionInfo );
    if( bRetVal == false )
        return;
    UINT uLen;
    VS_FIXEDFILEINFO *pFileInfo = NULL;

    bRetVal = VerQueryValue( pVersionInfo , L"\\" , (LPVOID *)&pFileInfo , &uLen );

    if( bRetVal == false )
        return;
    DWORD dwFileVersionMS = pFileInfo->dwFileVersionMS;
    DWORD dwFileVersionLS = pFileInfo->dwFileVersionLS;

    DWORD dwLeftMost     = HIWORD(dwFileVersionMS);
    DWORD dwSecondLeft   = LOWORD(dwFileVersionMS);
    DWORD dwSecondRight  = HIWORD(dwFileVersionLS);
    DWORD dwRightMost    = LOWORD(dwFileVersionLS);

    char pVersion[1024];
    sprintf(pVersion, "%u.%u.%u.%u", dwLeftMost , dwSecondLeft , dwSecondRight , dwRightMost );
    if( pVersionInfo )
        delete []pVersionInfo;
}
Community
  • 1
  • 1
Rudolfs Bundulis
  • 11,636
  • 6
  • 33
  • 71