Listing 1: verres.c Version extractor for C
//============================================================== // // VerRes.cpp // // GetDllVersion() - Returns the load path and version // of a given file. // main() - test entry point // // //============================================================== #include <windows.h> //-- Windows Dynamic Data structure; defined for what we know typedef struct _VS_VERSIONINFO { WORD wLength; WORD wValueLength; WORD wType; WCHAR szKey[15]; //-- WCHAR / UNICODE string WORD Padding1[1]; //-- this is actually dynamic }VS_VERSIONINFO; //-------------------------------------------------------------- // GetDllVersion() // Returns the load path and version of the given file. // // filename [in] - root file name to get the version // loadpath [out] - buffer to write the full path // maxloadpath [in] - max size of loadpath[] // maj [out] - version major // min [out] - version minor // rev [out] - version revision // bld [out] - version build number // //-------------------------------------------------------------- int GetDllVersion( char * filename, char * loadpath, int maxloadpath, int *maj, int *min, int *rev, int *bld ) { int bRetval = 0; //-- 0 = failure HRSRC hRes; HGLOBAL hGbl; void * lpRes; char * p; VS_VERSIONINFO * pInf; VS_FIXEDFILEINFO * pInfo ; HINSTANCE hDll = LoadLibrary( filename ); if( hDll ) { //-- get the library's full path GetModuleFileName( hDll, loadpath, maxloadpath ); //-- find the resource hRes = FindResource( hDll, "#1", RT_VERSION); if( hRes ) { hGbl = LoadResource( hDll, hRes ); if( hGbl ) { lpRes = LockResource( hGbl ); if (lpRes ) { //--type cast to a version info pInf = (VS_VERSIONINFO *)lpRes; if( pInf->wValueLength > 0 ) { p = (char *) pInf->Padding1; //-- cast to a VS_FIXEDFILEINFO pInfo = (VS_FIXEDFILEINFO *)p; while( (((long)p)&0x04) != 0 ) { p++; pInfo = (VS_FIXEDFILEINFO *)p; } //-- extract the version! *maj = HIWORD(pInfo->dwFileVersionMS); *min = LOWORD(pInfo->dwFileVersionMS); *rev = HIWORD(pInfo->dwFileVersionLS); *bld = LOWORD(pInfo->dwFileVersionLS); bRetval = 1; //-- 1 = success } } } } FreeLibrary( hDll ); } return bRetval; } //-------------------------------------------------------------- // main() for testing //-------------------------------------------------------------- #include <stdio.h> int main(int argc, char* argv[]) { char * pFilename; int maj, min, rev, bld; char loadpath[MAX_PATH]; if( argc <= 1) { printf( "VerRes requires a filename "); printf( "as a parameter\r\n" ); return -1; } pFilename = (char *)malloc( strlen(argv[1])+1 ); if( pFilename ) { //-- copy the filename argument strcpy( pFilename, argv[1] ); if (GetDllVersion( pFilename, loadpath, MAX_PATH, &maj, &min, &rev, &bld )) printf( "Loaded version %d.%d.%d.%d from %s\r\n", maj, min, rev, bld, loadpath ); else printf( "error loading file %s\r\n", pFilename ); free( pFilename ); } else printf( "error allocating memory for file buffer\r\n" ); return 0; } //End of File