|
|
//-----------------------------------------------------------------------------
// America Online for Windows
//-----------------------------------------------------------------------------
// Copyright (c) 1987-2001 America Online, Inc. All rights reserved. This
// software contains valuable confidential and proprietary information of
// America Online and is subject to applicable licensing agreements.
// Unauthorized reproduction, transmission, or distribution of this file and
// its contents is a violation of applicable laws.
//-----------------------------------------------------------------------------
// $Workfile: AOLInstall.cpp $ $Author: RobrtLarson $
// $Date: 05/02/01 $
//-----------------------------------------------------------------------------
#include "precomp.h"
#include <Softpub.h>
#include <WinCrypt.h>
#include <WinTrust.h>
#include <ImageHlp.h>
#include "LegalStr.h"
#include "AOLFindBundledInstaller_AOLCode.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
#define SWAPWORDS(x) (((x) << 16) | ((x) >> 16))
// define encoding method
#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
#define INSTALLER 0x0001
#define CLIENT 0x0002
#define COUNTRY_PICKER 0x0004
#define SERVICE_AOL 0x0010
#define SERVICE_CS 0x0020
// Local function prototypes
BOOL GetExeType(LPSTR lpszExePath, WORD &wExeType); BOOL ExtractCertificateInfo(LPSTR lpszFileName, HCERTSTORE *hCertStore); PCCERT_CONTEXT WINAPI CryptGetSignerCertificateCallback(void *pvGetArg, DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hCertStore); BOOL CheckCertificateName(HCERTSTORE hCertStore); LPSTR GetCommonName(CERT_NAME_BLOB pCertNameBlob); BOOL VerifyFileInfo(WORD &ExeType, LPSTR lpszInstaller, PBOOL pbOldClient); BOOL VerifyCertificate(LPSTR lpszInstaller);
_pfn_CertCloseStore g_pfn_CertCloseStore = NULL; _pfn_CryptVerifyMessageSignature g_pfn_CryptVerifyMessageSignature = NULL; _pfn_ImageGetCertificateData g_pfn_ImageGetCertificateData = NULL; _pfn_ImageGetCertificateHeader g_pfn_ImageGetCertificateHeader = NULL; _pfn_CertGetSubjectCertificateFromStore g_pfn_CertGetSubjectCertificateFromStore = NULL; _pfn_CertDuplicateStore g_pfn_CertDuplicateStore = NULL; _pfn_CertEnumCertificatesInStore g_pfn_CertEnumCertificatesInStore = NULL; _pfn_CertRDNValueToStrA g_pfn_CertRDNValueToStrA = NULL; _pfn_CertFindRDNAttr g_pfn_CertFindRDNAttr = NULL; _pfn_CryptDecodeObject g_pfn_CryptDecodeObject = NULL; _pfn_VerQueryValueA g_pfn_VerQueryValueA = NULL; _pfn_GetFileVersionInfoA g_pfn_GetFileVersionInfoA = NULL; _pfn_GetFileVersionInfoSizeA g_pfn_GetFileVersionInfoSizeA = NULL; _pfn_WinVerifyTrust g_pfn_WinVerifyTrust = NULL;
HMODULE g_hCRYPT32 = NULL; HMODULE g_hWINTRUST = NULL; HMODULE g_hVERSION = NULL; HMODULE g_hIMAGEHLP = NULL;
void UnloadDependencies() { g_pfn_CertCloseStore = NULL; g_pfn_CryptVerifyMessageSignature = NULL; g_pfn_ImageGetCertificateData = NULL; g_pfn_ImageGetCertificateHeader = NULL; g_pfn_CertGetSubjectCertificateFromStore = NULL; g_pfn_CertDuplicateStore = NULL; g_pfn_CertEnumCertificatesInStore = NULL; g_pfn_CertRDNValueToStrA = NULL; g_pfn_CertFindRDNAttr = NULL; g_pfn_CryptDecodeObject = NULL; g_pfn_VerQueryValueA = NULL; g_pfn_GetFileVersionInfoA = NULL; g_pfn_GetFileVersionInfoSizeA = NULL; g_pfn_WinVerifyTrust = NULL;
if (g_hCRYPT32) { FreeLibrary(g_hCRYPT32); g_hCRYPT32 = NULL; }
if (g_hWINTRUST) { FreeLibrary(g_hWINTRUST); g_hWINTRUST = NULL; }
if (g_hVERSION) { FreeLibrary(g_hVERSION); g_hVERSION = NULL; }
if (g_hIMAGEHLP) { FreeLibrary(g_hIMAGEHLP); g_hIMAGEHLP = NULL; } }
BOOL LoadDependencies() { BOOL bSuccess = FALSE;
if (!(g_hCRYPT32 = LoadLibraryA("CRYPT32.DLL"))) { goto eh; }
if (!(g_hWINTRUST = LoadLibraryA("WINTRUST.DLL"))) { goto eh; }
if (!(g_hVERSION = LoadLibraryA("VERSION.DLL"))) { goto eh; }
if (!(g_hIMAGEHLP = LoadLibraryA("IMAGEHLP.DLL"))) { goto eh; }
if (!(g_pfn_CertCloseStore = (_pfn_CertCloseStore) GetProcAddress(g_hCRYPT32, "CertCloseStore"))) { goto eh; } if (!(g_pfn_CryptVerifyMessageSignature = (_pfn_CryptVerifyMessageSignature) GetProcAddress(g_hCRYPT32, "CryptVerifyMessageSignature"))) { goto eh; } if (!(g_pfn_ImageGetCertificateData = (_pfn_ImageGetCertificateData) GetProcAddress(g_hIMAGEHLP, "ImageGetCertificateData"))) { goto eh; } if (!(g_pfn_ImageGetCertificateHeader = (_pfn_ImageGetCertificateHeader) GetProcAddress(g_hIMAGEHLP, "ImageGetCertificateHeader"))) { goto eh; } if (!(g_pfn_CertGetSubjectCertificateFromStore = (_pfn_CertGetSubjectCertificateFromStore) GetProcAddress(g_hCRYPT32, "CertGetSubjectCertificateFromStore"))) { goto eh; } if (!(g_pfn_CertDuplicateStore = (_pfn_CertDuplicateStore) GetProcAddress(g_hCRYPT32, "CertDuplicateStore"))) { goto eh; } if (!(g_pfn_CertEnumCertificatesInStore = (_pfn_CertEnumCertificatesInStore) GetProcAddress(g_hCRYPT32, "CertEnumCertificatesInStore"))) { goto eh; } if (!(g_pfn_CertRDNValueToStrA = (_pfn_CertRDNValueToStrA) GetProcAddress(g_hCRYPT32, "CertRDNValueToStrA"))) { goto eh; } if (!(g_pfn_CertFindRDNAttr = (_pfn_CertFindRDNAttr) GetProcAddress(g_hCRYPT32, "CertFindRDNAttr"))) { goto eh; } if (!(g_pfn_CryptDecodeObject = (_pfn_CryptDecodeObject) GetProcAddress(g_hCRYPT32, "CryptDecodeObject"))) { goto eh; } if (!(g_pfn_VerQueryValueA = (_pfn_VerQueryValueA) GetProcAddress(g_hVERSION, "VerQueryValueA"))) { goto eh; } if (!(g_pfn_GetFileVersionInfoA = (_pfn_GetFileVersionInfoA) GetProcAddress(g_hVERSION, "GetFileVersionInfoA"))) { goto eh; } if (!(g_pfn_GetFileVersionInfoSizeA = (_pfn_GetFileVersionInfoSizeA) GetProcAddress(g_hVERSION, "GetFileVersionInfoSizeA"))) { goto eh; } if (!(g_pfn_WinVerifyTrust = (_pfn_WinVerifyTrust) GetProcAddress(g_hWINTRUST, "WinVerifyTrust"))) { goto eh; }
bSuccess = TRUE;
eh: if (!bSuccess) { UnloadDependencies(); }
return bSuccess; }
//-----------------------------------------------------------------------------
// LocateInstaller
// This functions searches for a valid AOL or CompuServe install program
// based on the default value found in a registry key. This install program
// is then validated by checking the Certificates and verifying that the
// program file has not been modified since being signed by America Online.
//
// AOL Registry Key:
// HKLM\Software\America Online\Installers
//
// CompuServe Registry Key:
// HKLM\Software\CompuServe\Installers
//-----------------------------------------------------------------------------
// Function parameters:
// LPSTR lpszInstaller Returned installer command line,
// NULL if no valid installer located
// Note: allowance should be made in the
// length of this string for an optional
// parameter on the command line of MAX_PATH
// length.
// UINT uiPathSize Length of lpszInstaller parameter
// BOOL *pbMessage TRUE - display App Compat message
// FALSE - do not display App Compat message
//-----------------------------------------------------------------------------
BOOL LocateInstaller_Internal(LPSTR lpszInstaller, UINT uiPathSize, BOOL *pbMessage) { BOOL bResult = FALSE, bCheckCert = TRUE, bOldClient = FALSE; HKEY hKey; LONG lRet; CHAR szModuleName[MAX_PATH]; WORD wExeType = 0;
// Default to no App Compat message
*pbMessage = FALSE;
// Get the name of the file that is executing
DWORD dwLen = GetModuleFileNameA(NULL, szModuleName, sizeof(szModuleName)); if (0 == dwLen) { return FALSE; }
// Determine the type of exe this is
bResult = GetExeType(szModuleName, wExeType); if (bResult) { // Check if this is the uninstaller calling the client
if ((CLIENT & wExeType) && (NULL != strstr(_strlwr(GetCommandLineA()), "regall"))) { return FALSE; }
// If the program we are running is valid, then let it run
if (VerifyFileInfo(wExeType, szModuleName, &bOldClient)) { return FALSE; }
// If this is an client <= 4.0 then display message if not bundled installer found
if (bOldClient) { *pbMessage = TRUE; }
// Open registry key
if (SERVICE_AOL & wExeType) { lRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\America Online\\Installers", &hKey); } else if (SERVICE_CS & wExeType) { lRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\CompuServe\\Installers", &hKey); } else { return FALSE; } // Don't know what this is
if (ERROR_SUCCESS != lRet) { return FALSE; } // No bundled version of AOL/CS located in registry
// Get size of registry key data
ULONG cbSize; DWORD dwType; lRet = RegQueryValueExA(hKey, NULL, NULL, &dwType, NULL, &cbSize); if ((ERROR_SUCCESS != lRet) || (cbSize > uiPathSize) || (REG_SZ != dwType)) { return FALSE; }
// See if we need to check the certificate for the installer
lRet = RegQueryValueExA(hKey, "CC", NULL, &dwType, NULL, &cbSize); if ((ERROR_SUCCESS == lRet) && (cbSize > 0)) { bCheckCert = FALSE; }
lpszInstaller[0] = '\"'; // Get registry key data
cbSize = uiPathSize - 1; lRet = RegQueryValueExA(hKey, NULL, NULL, NULL, (UCHAR *)&lpszInstaller[1], &cbSize);
RegCloseKey(hKey); if (ERROR_SUCCESS == lRet) { // Check for correct installer version
bResult = VerifyFileInfo(wExeType, &lpszInstaller[1], NULL); if (bResult && bCheckCert) { // Get certificate store
HCERTSTORE hCertStore = NULL; bResult = ExtractCertificateInfo(&lpszInstaller[1], &hCertStore); if (bResult) { // Check certificates for AOL/CS signature
bResult = CheckCertificateName(hCertStore); if (bResult) { // Check that file has not been modified
bResult = VerifyCertificate(&lpszInstaller[1]); } }
// Close the certificate store
if (NULL != hCertStore) { (*g_pfn_CertCloseStore)(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); } } } }
if (bResult) { strcat(lpszInstaller, "\"") ; // Check if Message should be displayed to user
if (CLIENT & wExeType) { *pbMessage = TRUE; } else { // Add command line parameter
if (COUNTRY_PICKER & wExeType) { if ((strlen(lpszInstaller) + strlen(szModuleName) + 6) <= uiPathSize) { sprintf(lpszInstaller, "%s -p \"%s\"", lpszInstaller, szModuleName); } } } } else { lpszInstaller[0] = '\0'; }
return bResult; }
BOOL LocateInstaller(LPSTR lpszInstaller, UINT uiPathSize, BOOL *pbMessage) { BOOL bSuccess = FALSE; if (!LoadDependencies()) { goto eh; }
if (!LocateInstaller_Internal(lpszInstaller, uiPathSize, pbMessage)) { goto eh; }
bSuccess = TRUE; eh: UnloadDependencies();
return bSuccess; }
//-----------------------------------------------------------------------------
// GetExeType
// This functions determines whether the executible is an AOL/CS client or
// and AOL/CS installer.
//-----------------------------------------------------------------------------
// Function parameters:
// LPSTR lpszExePath Fully qualified path to executible
// WORD &wExeType Returned executible type
// AOL or CS
// Client or Installer
//-----------------------------------------------------------------------------
BOOL GetExeType(LPSTR lpszExePath, WORD &wExeType) { // Set string to lower case for comparisons
_strlwr(lpszExePath);
LPSTR pszTemp = strrchr(lpszExePath, '\\'); if (NULL == pszTemp) { return FALSE; }
pszTemp++; // Get to beginning of exe name
// Determine if this is an AOL/CS client
if (0 == _stricmp(pszTemp, "waol.exe")) { wExeType = SERVICE_AOL | CLIENT; return TRUE; } else if ((0 == _stricmp(pszTemp, "wcs2000.exe")) || (0 == _stricmp(pszTemp, "cs3.exe"))) { wExeType = SERVICE_CS | CLIENT; return TRUE; } else if ((NULL != strstr(pszTemp, "cs2000")) || (NULL != strstr(pszTemp, "setupcs2k")) || (NULL != strstr(pszTemp, "setupcs2000")) || (0 == _stricmp(pszTemp, "d41000b.exe")) || (0 == _stricmp(pszTemp, "d41510b.exe")) || (0 == _stricmp(pszTemp, "d41540b.exe"))) { // These are CS installers w/ "America Online, Inc." in version info.
wExeType = SERVICE_CS | INSTALLER; return TRUE; } else if (0 == _stricmp(pszTemp, "wgw.exe")) { return FALSE; } // There is no bundled installer for Gateway
else if (0 == _stricmp(pszTemp, "wwm.exe")) { return FALSE; } // There is no bundled installer for Wal-Mart
// Determine AOL/CS installer
// Get size of version info in file
DWORD dwHandle = 0; DWORD dwVerInfoSize = (*g_pfn_GetFileVersionInfoSizeA)(lpszExePath, &dwHandle);
// Allocate memory for version info
BYTE *lpVerInfo = NULL; __try { lpVerInfo = (BYTE *)HeapAlloc(GetProcessHeap(), 0, dwVerInfoSize); if (NULL == lpVerInfo) { __leave; }
// Get version info from file
BOOL bResult = (*g_pfn_GetFileVersionInfoA)(lpszExePath, NULL, dwVerInfoSize, lpVerInfo); if (!bResult) { __leave; }
// Get Language code page
DWORD *pdwTrans; UINT uiBytes; DWORD dwLangCodepage = 0;
bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, "\\VarFileInfo\\Translation", (VOID **)&pdwTrans, &uiBytes); if (bResult) { dwLangCodepage = SWAPWORDS(*pdwTrans); } // Translate language code page to something we can use
else { dwLangCodepage = 0x040904e4; } // Try English multilanguage code page
// Obtain the "CompanyName" from the version info
CHAR szQuery[MAX_PATH]; PCHAR pszVerInfo; sprintf(szQuery, "\\StringFileInfo\\%08X\\CompanyName", dwLangCodepage); bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, szQuery, (VOID **)&pszVerInfo, &uiBytes); if (!bResult) { __leave; }
// Check "CompanyName"
if ((NULL != strstr(pszVerInfo, "America Online")) || (NULL != strstr(pszVerInfo, "AOL"))) { wExeType = SERVICE_AOL | INSTALLER; return TRUE; } if (0 == strcmp("CompuServe Interactive Services, Inc.", pszVerInfo)) { wExeType = SERVICE_CS | INSTALLER; return TRUE; } } __finally { if (NULL != lpVerInfo) { HeapFree(GetProcessHeap(), 0, lpVerInfo); } }
return FALSE; }
//-----------------------------------------------------------------------------
// ExtractCertificateInfo
// This functions obtains and verifies the certificate store for the
// installer.
//-----------------------------------------------------------------------------
// Function parameters:
// LPSTR lpszFileName Fully qualified path to installer
// HCERTSTORE *hCertStore Handle to the certificate store
//-----------------------------------------------------------------------------
BOOL ExtractCertificateInfo(LPSTR lpszFileName, HCERTSTORE *hCertStore) { WIN_CERTIFICATE CertificateHeader; LPWIN_CERTIFICATE pbCertificate = NULL; BOOL bResult = FALSE; HANDLE hFile = NULL; DWORD dwSize; CRYPT_VERIFY_MESSAGE_PARA CryptVerifyMessagePara;
__try { // Open file
hFile = CreateFileA(lpszFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return FALSE; }
// Get Certificate Header
bResult = (*g_pfn_ImageGetCertificateHeader)(hFile, 0, &CertificateHeader); if (!bResult) { __leave; }
// Allocate Memory for Certificate Blob
pbCertificate = (LPWIN_CERTIFICATE)HeapAlloc(GetProcessHeap(), 0, CertificateHeader.dwLength); if (NULL == pbCertificate) { bResult = FALSE; __leave; }
// Get Certificate Blob
dwSize = CertificateHeader.dwLength; bResult = (*g_pfn_ImageGetCertificateData)(hFile, 0, pbCertificate, &dwSize); if (!bResult) { __leave; }
// Zero out CRYPT_VERIFY_MESSAGE_PARA structure
ZeroMemory(&CryptVerifyMessagePara, sizeof(CryptVerifyMessagePara));
CryptVerifyMessagePara.cbSize = sizeof(CryptVerifyMessagePara); CryptVerifyMessagePara.dwMsgAndCertEncodingType = ENCODING; CryptVerifyMessagePara.pfnGetSignerCertificate = CryptGetSignerCertificateCallback;
// Pass Address of certificate store to callback
CryptVerifyMessagePara.pvGetArg = (LPVOID)hCertStore;
// Verify the message and call callback
bResult = (*g_pfn_CryptVerifyMessageSignature)(&CryptVerifyMessagePara, 0, pbCertificate->bCertificate, dwSize, NULL, NULL, NULL); } __finally { if (NULL != pbCertificate) { HeapFree(GetProcessHeap(), 0, pbCertificate); }
if (NULL != hFile) { CloseHandle(hFile); } }
return bResult; }
//-----------------------------------------------------------------------------
// CryptGetSignerCertificateCallback
// This functions is the callback function for CryptVerifyMessageSignature.
//-----------------------------------------------------------------------------
// Function parameters:
// See MicroSoft documentation for details.
//-----------------------------------------------------------------------------
PCCERT_CONTEXT WINAPI CryptGetSignerCertificateCallback(void *pvGetArg, DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hCertStore) { if (NULL == hCertStore) { return FALSE; }
*((HCERTSTORE *)pvGetArg) = (*g_pfn_CertDuplicateStore)(hCertStore);
return (*g_pfn_CertGetSubjectCertificateFromStore)(hCertStore, dwCertEncodingType, pSignerId); }
//-----------------------------------------------------------------------------
// CheckCertificateName
// This functions checks the certificate name to verify that it is signed by
// America Online.
//-----------------------------------------------------------------------------
// Function parameters:
// HCERTSTORE hCertStore Handle to the certificate store
//-----------------------------------------------------------------------------
BOOL CheckCertificateName(HCERTSTORE hCertStore) { BOOL bReturn = FALSE; PCCERT_CONTEXT pCertContext = NULL; PCCERT_CONTEXT pPrevContext = NULL; LPSTR szSubject = NULL;
if (NULL != hCertStore) { do { pCertContext = (*g_pfn_CertEnumCertificatesInStore)(hCertStore, pPrevContext);
if (NULL != pCertContext) { // Get Subject common name, if not then get organization name
szSubject = GetCommonName(pCertContext->pCertInfo->Subject); if (NULL != szSubject) { // Check name of certificate signer
if (0 == strcmp(szSubject, "America Online, Inc.")) { bReturn = TRUE; }
HeapFree(GetProcessHeap(), 0, szSubject); }
pPrevContext = pCertContext; } } while (pCertContext); }
return bReturn; }
//-----------------------------------------------------------------------------
// GetCommonName
// This functions obtains the common name from the certificate store
//-----------------------------------------------------------------------------
// Function parameters:
// CERT_NAME_BLOB pCertNameBlob Pointer to the blob that contains the name
//-----------------------------------------------------------------------------
LPSTR GetCommonName(CERT_NAME_BLOB pCertNameBlob) { BOOL bReturn = FALSE; BOOL bResult; PCERT_NAME_INFO pCertName = NULL; PCERT_RDN_ATTR pCertAttr; LPSTR szName = NULL; DWORD dwSize;
__try { // Find out size of decrypted blob
(*g_pfn_CryptDecodeObject)(ENCODING, X509_NAME, pCertNameBlob.pbData, pCertNameBlob.cbData, 0, NULL, &dwSize);
// Allocate memory for decrypted blob
pCertName = (PCERT_NAME_INFO)HeapAlloc(GetProcessHeap(), 0, dwSize); if (NULL == pCertName) { __leave; }
// Decode the certificate blob
bResult = (*g_pfn_CryptDecodeObject)(ENCODING, X509_NAME, pCertNameBlob.pbData, pCertNameBlob.cbData, 0, pCertName, &dwSize); if (!bResult) { __leave; }
// Get common name
pCertAttr = (*g_pfn_CertFindRDNAttr)(szOID_COMMON_NAME, pCertName); if (NULL == pCertAttr) { // Get organization name if no common name found
pCertAttr = (*g_pfn_CertFindRDNAttr)(szOID_ORGANIZATION_NAME, pCertName); if (NULL == pCertAttr) { __leave; } }
// Find out size of name
dwSize = (*g_pfn_CertRDNValueToStrA)(pCertAttr->dwValueType, &pCertAttr->Value, NULL, 0);
// Allocate memory for name
szName = (LPSTR)HeapAlloc(GetProcessHeap(), 0, dwSize); if (NULL == szName) { __leave; }
// Obtain name from decrypted blob
(*g_pfn_CertRDNValueToStrA)(pCertAttr->dwValueType, &pCertAttr->Value, szName, dwSize); bReturn = TRUE; } __finally { if (NULL != pCertName) { HeapFree(GetProcessHeap(), 0, pCertName); }
if (!bReturn) { if (NULL != szName) { HeapFree(GetProcessHeap(), 0, szName); } } }
if (bReturn) { return szName; } else { return NULL; } }
//-----------------------------------------------------------------------------
// VerifyFileInfo
// This functions verifies that the installer is valid based on the version
// information stored in the file.
//-----------------------------------------------------------------------------
// Function parameters:
// INSTALLER_TYPE InstallerType Specifies whether to look for AOL or CS
// LPSTR lpszInstaller Fully qualified path to installer
// PBOOL pbOldClient Is is a client older then 5.0
//-----------------------------------------------------------------------------
BOOL VerifyFileInfo(WORD &wExeType, LPSTR lpszInstaller, PBOOL pbOldClient) { BOOL bReturn = FALSE; BOOL bResult; BYTE *lpVerInfo = NULL;
__try { // Get size of version info in file
DWORD dwHandle = 0; DWORD dwVerInfoSize = (*g_pfn_GetFileVersionInfoSizeA)(lpszInstaller, &dwHandle);
// Allocate memory for version info
lpVerInfo = (BYTE *)HeapAlloc(GetProcessHeap(), 0, dwVerInfoSize); if (NULL == lpVerInfo) { __leave; }
// Get version info from file
bResult = (*g_pfn_GetFileVersionInfoA)(lpszInstaller, NULL, dwVerInfoSize, lpVerInfo); if (!bResult) { __leave; }
// Get Language code page
DWORD *pdwTrans; UINT uiBytes; DWORD dwLangCodepage = 0;
bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, "\\VarFileInfo\\Translation", (VOID **)&pdwTrans, &uiBytes); if (bResult) { dwLangCodepage = SWAPWORDS(*pdwTrans); } // Translate language code page to something we can use
else { dwLangCodepage = 0x040904e4; } // Try English multilanguage code page
// Obtain the "CompanyName" from the version info
CHAR szQuery[MAX_PATH]; PCHAR pszVerInfo; sprintf(szQuery, "\\StringFileInfo\\%08X\\CompanyName", dwLangCodepage); bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, szQuery, (VOID **)&pszVerInfo, &uiBytes); if (!bResult) { __leave; }
// Check "CompanyName"
if (SERVICE_AOL & wExeType) { if ((NULL == strstr(pszVerInfo, "America Online")) && (NULL == strstr(pszVerInfo, "AOL"))) { __leave; } } else if (SERVICE_CS & wExeType) { if (0 != strcmp("CompuServe Interactive Services, Inc.", pszVerInfo)) { __leave; } } else { __leave; }
// Get fixed file info
VS_FIXEDFILEINFO* pVS_FFI; bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, "\\", (VOID **)&pVS_FFI, &uiBytes); if (!bResult) { __leave; }
// Check if this is the Country Picker
sprintf(szQuery, "\\StringFileInfo\\%08X\\ProductName", dwLangCodepage); bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, szQuery, (VOID **)&pszVerInfo, &uiBytes); if ((bResult) && (NULL != strstr(pszVerInfo, "Country Picker"))) { wExeType |= COUNTRY_PICKER; if (0x00010005 > pVS_FFI->dwProductVersionMS) { __leave; } } else { if ((0x00060000 > pVS_FFI->dwProductVersionMS) || ((0x00060000 >= pVS_FFI->dwProductVersionMS) && (0x00020000 > pVS_FFI->dwProductVersionLS))) { if ((NULL != pbOldClient) && (CLIENT & wExeType) && (0x00050000 > pVS_FFI->dwProductVersionMS)) { *pbOldClient = TRUE; }
__leave; } }
bReturn = TRUE; } __finally { if (NULL != lpVerInfo) { HeapFree(GetProcessHeap(), 0, lpVerInfo); } }
return bReturn; }
//-----------------------------------------------------------------------------
// VerifyCertificate
// This functions verifies that the install has not been modified since
// being signed by America Online.
//-----------------------------------------------------------------------------
// Function parameters:
// LPSTR lpszInstaller Fully qualified path to installer
//-----------------------------------------------------------------------------
BOOL VerifyCertificate(LPSTR lpszInstaller) { GUID ActionGUID = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE; GUID SubjectPeImage = WIN_TRUST_SUBJTYPE_PE_IMAGE;
WIN_TRUST_SUBJECT_FILE Subject;
// Subject.lpPath is a WCHAR string, must convert
LPWSTR lpwszInstaller = NULL; int cchUnicodeSize = 0; cchUnicodeSize = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, lpszInstaller, -1, NULL, 0);
lpwszInstaller = (LPWSTR)malloc(cchUnicodeSize * sizeof(WCHAR));
if (0 == MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, lpszInstaller, -1, lpwszInstaller, cchUnicodeSize)) { if (lpwszInstaller) { free(lpwszInstaller); }
return FALSE; }
Subject.lpPath = lpwszInstaller; Subject.hFile = INVALID_HANDLE_VALUE; // Open the using the lpPath field
WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT ActionData;
ActionData.Subject = &Subject; ActionData.hClientToken = NULL; ActionData.SubjectType = &SubjectPeImage;
// Verify the file has not be changed since being signed
HRESULT hr = (*g_pfn_WinVerifyTrust)((HWND)INVALID_HANDLE_VALUE, &ActionGUID, (WINTRUST_DATA *) &ActionData);
if (lpwszInstaller) { free(lpwszInstaller); }
if (S_OK == hr) { return TRUE; } else { return FALSE; } }
|