applied patch #1706624 - GetDLLVersionLocal VXD support on NT
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@5118 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
a4fe984390
commit
96491877f2
1 changed files with 227 additions and 0 deletions
227
Source/util.cpp
227
Source/util.cpp
|
@ -825,6 +825,230 @@ static bool GetDLLVersionUsingAPI(const string& filepath, DWORD& high, DWORD& lo
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
// the following structure must be byte-aligned.
|
||||||
|
#pragma pack( push, pre_vxd_ver, 1 )
|
||||||
|
typedef struct _VXD_VERSION_RESOURCE {
|
||||||
|
char cType;
|
||||||
|
WORD wID;
|
||||||
|
char cName;
|
||||||
|
WORD wOrdinal;
|
||||||
|
WORD wFlags;
|
||||||
|
DWORD dwResSize;
|
||||||
|
BYTE bVerData;
|
||||||
|
} VXD_VERSION_RESOURCE, *PVXD_VERSION_RESOURCE;
|
||||||
|
#pragma pack( pop, pre_vxd_ver )
|
||||||
|
|
||||||
|
static BOOL GetVxdVersion( LPCSTR szFile, LPDWORD lpdwLen, LPVOID lpData )
|
||||||
|
{
|
||||||
|
|
||||||
|
HANDLE hFile = NULL;
|
||||||
|
HANDLE hFileMapping = NULL;
|
||||||
|
void * pView = NULL;
|
||||||
|
DWORD dwSize = 0;
|
||||||
|
DWORD dwError = 0;
|
||||||
|
|
||||||
|
PIMAGE_DOS_HEADER pDosExeHdr = NULL;
|
||||||
|
PIMAGE_NT_HEADERS pNtExeHdr = NULL;
|
||||||
|
PIMAGE_VXD_HEADER pLEHdr = NULL;
|
||||||
|
PVXD_VERSION_RESOURCE pVerRes = NULL;
|
||||||
|
LPVOID pRawRes = NULL;
|
||||||
|
|
||||||
|
// Open the file for shared read access.
|
||||||
|
hFile = CreateFile( szFile, GENERIC_READ, FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL );
|
||||||
|
if ( hFile == INVALID_HANDLE_VALUE )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a read-only file mapping object for the file.
|
||||||
|
hFileMapping = CreateFileMapping( hFile, NULL,
|
||||||
|
PAGE_READONLY, 0, 0, NULL);
|
||||||
|
if ( !hFileMapping )
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
|
||||||
|
if ( hFile != INVALID_HANDLE_VALUE )
|
||||||
|
CloseHandle( hFile );
|
||||||
|
|
||||||
|
SetLastError( dwError );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map a view of the the file.
|
||||||
|
pView = MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0 );
|
||||||
|
if ( !pView )
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
|
||||||
|
if ( hFileMapping )
|
||||||
|
CloseHandle( hFileMapping );
|
||||||
|
|
||||||
|
if ( hFile != INVALID_HANDLE_VALUE )
|
||||||
|
CloseHandle( hFile );
|
||||||
|
|
||||||
|
SetLastError( dwError );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The DOS header begins at byte 0.
|
||||||
|
pDosExeHdr = (PIMAGE_DOS_HEADER) pView;
|
||||||
|
|
||||||
|
// Check to make sure the file has a DOS EXE header.
|
||||||
|
if ( pDosExeHdr->e_magic != IMAGE_DOS_SIGNATURE )
|
||||||
|
{
|
||||||
|
if ( pView )
|
||||||
|
UnmapViewOfFile( pView );
|
||||||
|
|
||||||
|
if ( hFileMapping )
|
||||||
|
CloseHandle( hFileMapping );
|
||||||
|
|
||||||
|
if ( hFile != INVALID_HANDLE_VALUE )
|
||||||
|
CloseHandle( hFile );
|
||||||
|
|
||||||
|
SetLastError( ERROR_BAD_FORMAT );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the beginning of the NT header at offset e_lfanew.
|
||||||
|
pNtExeHdr = (PIMAGE_NT_HEADERS) ( (DWORD) pView
|
||||||
|
+ (DWORD) pDosExeHdr->e_lfanew );
|
||||||
|
|
||||||
|
// Check to make sure the file is a VxD.
|
||||||
|
if ( (DWORD) pNtExeHdr->Signature != IMAGE_VXD_SIGNATURE )
|
||||||
|
{
|
||||||
|
if ( pView )
|
||||||
|
UnmapViewOfFile( pView );
|
||||||
|
|
||||||
|
if ( hFileMapping )
|
||||||
|
CloseHandle( hFileMapping );
|
||||||
|
|
||||||
|
if ( hFile != INVALID_HANDLE_VALUE )
|
||||||
|
CloseHandle( hFile );
|
||||||
|
|
||||||
|
SetLastError( ERROR_BAD_FORMAT );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The LE header begins at the same place as the NT header.
|
||||||
|
pLEHdr = (PIMAGE_VXD_HEADER) pNtExeHdr;
|
||||||
|
|
||||||
|
// e32_winreslen contains the size of the VxD's version resource.
|
||||||
|
if ( pLEHdr->e32_winreslen == 0 ) {
|
||||||
|
*lpdwLen = 0;
|
||||||
|
if ( pView )
|
||||||
|
UnmapViewOfFile( pView );
|
||||||
|
|
||||||
|
if ( hFileMapping )
|
||||||
|
CloseHandle( hFileMapping );
|
||||||
|
|
||||||
|
if ( hFile != INVALID_HANDLE_VALUE )
|
||||||
|
CloseHandle( hFile );
|
||||||
|
|
||||||
|
SetLastError( ERROR_RESOURCE_DATA_NOT_FOUND );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// e32_winresoff contains the offset of the resource in the VxD.
|
||||||
|
pVerRes = (VXD_VERSION_RESOURCE *) ( (DWORD) pView
|
||||||
|
+ (DWORD) pLEHdr->e32_winresoff );
|
||||||
|
dwSize = pVerRes->dwResSize;
|
||||||
|
pRawRes = &(pVerRes->bVerData);
|
||||||
|
|
||||||
|
// Make sure the supplied buffer is large enough for the resource.
|
||||||
|
if ( ( lpData == NULL ) || ( *lpdwLen < dwSize ) ) {
|
||||||
|
*lpdwLen = dwSize;
|
||||||
|
|
||||||
|
if ( pView )
|
||||||
|
UnmapViewOfFile( pView );
|
||||||
|
|
||||||
|
if ( hFileMapping )
|
||||||
|
CloseHandle( hFileMapping );
|
||||||
|
|
||||||
|
if ( hFile != INVALID_HANDLE_VALUE )
|
||||||
|
CloseHandle( hFile );
|
||||||
|
|
||||||
|
SetLastError( ERROR_INSUFFICIENT_BUFFER );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero the passed buffer and copy the resource into it.
|
||||||
|
ZeroMemory( lpData, *lpdwLen );
|
||||||
|
CopyMemory( lpData, pRawRes, dwSize );
|
||||||
|
*lpdwLen = dwSize;
|
||||||
|
|
||||||
|
// Clean up resources.
|
||||||
|
if ( pView )
|
||||||
|
UnmapViewOfFile( pView );
|
||||||
|
|
||||||
|
if ( hFileMapping )
|
||||||
|
CloseHandle( hFileMapping );
|
||||||
|
|
||||||
|
if ( hFile != INVALID_HANDLE_VALUE )
|
||||||
|
CloseHandle( hFile );
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD GetVxdVersionInfoSize( LPCSTR szFile )
|
||||||
|
{
|
||||||
|
DWORD dwResult = 0;
|
||||||
|
|
||||||
|
// Call GetVxdVersion() with NULL for the pointer to the buffer.
|
||||||
|
if ( !GetVxdVersion( szFile, &dwResult, NULL ) )
|
||||||
|
{
|
||||||
|
DWORD dwError = GetLastError();
|
||||||
|
|
||||||
|
// GetVxdVersion() will fail with ERROR_INSUFFICIENT_BUFFER and
|
||||||
|
// the required buffer size will be returned in dwResult.
|
||||||
|
if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
|
||||||
|
{
|
||||||
|
SetLastError( 0 );
|
||||||
|
return dwResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following line is never executed.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL GetVxdVersionInfo( LPCSTR szFile, DWORD dwLen, LPVOID lpData )
|
||||||
|
{
|
||||||
|
return GetVxdVersion( szFile, &dwLen, lpData );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //_WIN32
|
||||||
|
|
||||||
|
static bool GetDLLVersionFromVXD(const string& filepath, DWORD& high, DWORD& low)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
DWORD verSize = GetVxdVersionInfoSize(filepath.c_str());
|
||||||
|
if (verSize)
|
||||||
|
{
|
||||||
|
void *buf = (void *) GlobalAlloc(GPTR, verSize);
|
||||||
|
if (buf)
|
||||||
|
{
|
||||||
|
UINT uLen;
|
||||||
|
VS_FIXEDFILEINFO *pvsf;
|
||||||
|
if (GetVxdVersionInfo(filepath.c_str(), verSize, buf) && VerQueryValue(buf, "\\", (void**) &pvsf, &uLen))
|
||||||
|
{
|
||||||
|
low = pvsf->dwFileVersionLS;
|
||||||
|
high = pvsf->dwFileVersionMS;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
GlobalFree(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
bool GetDLLVersion(const string& filepath, DWORD& high, DWORD& low)
|
bool GetDLLVersion(const string& filepath, DWORD& high, DWORD& low)
|
||||||
{
|
{
|
||||||
if (GetDLLVersionUsingAPI(filepath, high, low))
|
if (GetDLLVersionUsingAPI(filepath, high, low))
|
||||||
|
@ -833,5 +1057,8 @@ bool GetDLLVersion(const string& filepath, DWORD& high, DWORD& low)
|
||||||
if (GetDLLVersionUsingRE(filepath, high, low))
|
if (GetDLLVersionUsingRE(filepath, high, low))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (GetDLLVersionFromVXD(filepath, high, low))
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue