|
|
/*++
Copyright (c) 2000-2002 Microsoft Corporation
Module Name:
AOLFindBundledInstaller_Shim.cpp
Abstract: This shim is to provide a way to verify existance of America Online bundled in OEM machines when user runs older version of AOL/CS program (waol.exe or wcs2000.exe) or setup.
If it exists, it will provide Apphelp dialog to tell user that there is newer America Online installer available. If user chose "Run this program", shim will launch the bundled installer. If user chose "Cancel", then shim will continue with current process.
Apphelp dialog only get displayed if LocateInstaller function says to do so.
History:
04/30/2001 markder Created 05/16/2001 andyseti Implemented LocateInstaller and ApphelpShowDialog. 03/07/2002 robkenny Security changes
--*/
#include "precomp.h"
#include <Softpub.h>
#include <WinCrypt.h>
#include <WinTrust.h>
#include "AOLFindBundledInstaller_AOLCode.h"
IMPLEMENT_SHIM_BEGIN(AOLFindBundledInstaller) #include "ShimHookMacro.h"
#include "shimdb.h"
APIHOOK_ENUM_BEGIN APIHOOK_ENUM_ENTRY(GetCommandLineA) APIHOOK_ENUM_ENTRY(GetStartupInfoA) APIHOOK_ENUM_ENTRY(GetModuleFileNameA) APIHOOK_ENUM_ENTRY(CreateWindowExA) APIHOOK_ENUM_END
#define MAX_PARAM 4
BOOL g_bDoneIt = FALSE; CString g_csHTMLHelpID_BundledFound; CString g_csHTMLHelpID_Incompatible; DWORD g_dwHTMLHelpID_BundledFound = 0; DWORD g_dwHTMLHelpID_Incompatible = 0; CString g_csAppName; CString g_csGUID;
#define APPHELP_DIALOG_FAILED ((DWORD)-1)
// from sdbapi\shimdb.w
/*
typedef struct _APPHELP_INFO {
//
// html help id mode
//
DWORD dwHtmlHelpID; // html help id
DWORD dwSeverity; // must have
LPCTSTR lpszAppName; GUID guidID; // entry guid
//
// Conventional mode
//
TAGID tiExe; // the TAGID of the exe entry within the DB
GUID guidDB; // the guid of the DB that has the EXE entry
BOOL bOfflineContent; BOOL bUseHTMLHelp; LPCTSTR lpszChmFile; LPCTSTR lpszDetailsFile;
} APPHELP_INFO, *PAPPHELP_INFO;
*/
typedef BOOL (*_pfn_ApphelpShowDialog)( IN PAPPHELP_INFO pAHInfo, // the info necessary to find the apphelp data
IN PHANDLE phProcess // [optional] returns the process handle of
// the process displaying the apphelp.
// When the process completes, the return value
// (from GetExitCodeProcess()) will be zero
// if the app should not run, or non-zero
// if it should run.
);
/*++
Parse the command line.
The format of the command line is:
MODE:AOL|CS;APPNAME:xxxxxx;HTMLHELPID:99999;GUID:xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx
--*/
BOOL ParseCommandLine( LPCSTR lpCommandLine ) { int iTotalParam = 0;
CSTRING_TRY { CStringToken csTok(lpCommandLine, L" ;");
CString token;
while (csTok.GetToken(token)) { CStringToken csSingleTok(token, L":");
CString csParam; CString csValue;
csSingleTok.GetToken(csParam); csSingleTok.GetToken(csValue);
if (csParam.CompareNoCase(L"APPNAME") == 0) { g_csAppName = csValue; ++iTotalParam; }
if (csParam.CompareNoCase(L"HTMLHELPID_BUNDLED") == 0) { g_csHTMLHelpID_BundledFound = csValue; g_dwHTMLHelpID_BundledFound = _wtol(csValue.Get()); ++iTotalParam; }
if (csParam.CompareNoCase(L"HTMLHELPID_INCOMPAT") == 0) { g_csHTMLHelpID_Incompatible = csValue; g_dwHTMLHelpID_Incompatible = _wtol(csValue.Get()); ++iTotalParam; }
if (csParam.CompareNoCase(L"GUID") == 0) { g_csGUID = csValue; ++iTotalParam; } } } CSTRING_CATCH { DPF("FindAOL", eDbgLevelInfo, "Error in CString.Exiting\n"); return FALSE; }
if (iTotalParam < MAX_PARAM) { DPF("FindAOL", eDbgLevelInfo, "Total Parameter = %d is less than = %d\n",iTotalParam, MAX_PARAM); return FALSE; }
//
// Dump results of command line parse
//
DPF("FindAOL", eDbgLevelInfo, "===================================\n"); DPF("FindAOL", eDbgLevelInfo, " FindAOL \n"); DPF("FindAOL", eDbgLevelInfo, "===================================\n"); DPF("FindAOL", eDbgLevelInfo, "COMMAND_LINE(%s)", lpCommandLine); DPF("FindAOL", eDbgLevelInfo, "-----------------------------------\n");
DPF("FindAOL", eDbgLevelInfo, "APPNAME = %S\n", g_csAppName); DPF("FindAOL", eDbgLevelInfo, "HTMLHELPID_BUNDLED = %S\n", g_csHTMLHelpID_BundledFound); DPF("FindAOL", eDbgLevelInfo, "HTMLHELPID_INCOMPAT = %S\n", g_csHTMLHelpID_Incompatible); DPF("FindAOL", eDbgLevelInfo, "GUID = %S\n", g_csGUID);
DPF("FindAOL", eDbgLevelInfo, "-----------------------------------\n");
return TRUE; }
BOOL InvokeApphelpShowDialog(DWORD dwHTMLHelpID) { _pfn_ApphelpShowDialog pfnApphelpShowDialog = NULL; APPHELP_INFO AHInfo = { 0 }; HMODULE hAppHelpDLL = NULL;
hAppHelpDLL = LoadLibrary(L"APPHELP.DLL");
DPF("FindAOL", eDbgLevelWarning, "Apphelp:%d\n",hAppHelpDLL );
if (hAppHelpDLL) {
pfnApphelpShowDialog = (_pfn_ApphelpShowDialog) GetProcAddress(hAppHelpDLL, "ApphelpShowDialog");
if (pfnApphelpShowDialog == NULL) { DPF("FindAOL", eDbgLevelInfo, "Unable to get APPHELP!ApphelpShowDialog procedure address.\n"); return FALSE; }
AHInfo.dwHtmlHelpID = dwHTMLHelpID; AHInfo.dwSeverity = APPHELP_NOBLOCK; AHInfo.lpszAppName = g_csAppName.Get(); AHInfo.bPreserveChoice = TRUE;
UNICODE_STRING ustrGuid; NTSTATUS ntstatus;
RtlInitUnicodeString(&ustrGuid, g_csGUID.Get());
ntstatus = RtlGUIDFromString(&ustrGuid, &AHInfo.guidID);
if (NT_SUCCESS(ntstatus)==FALSE) { DPF("FindAOL", eDbgLevelInfo, "RtlGUIDFromString failed!\n"); return FALSE; }
if (pfnApphelpShowDialog(&AHInfo,NULL)) { DPF("FindAOL", eDbgLevelInfo, "!\n"); } else { DPF("FindAOL", eDbgLevelInfo, "RtlGUIDFromString FAILED!\n"); return FALSE; } } else { DPF("FindAOL", eDbgLevelInfo, "LoadLibrary FAILED!\n"); return FALSE; } return TRUE; }
void DoIt() { CHAR lpszInstaller[MAX_PATH]; BOOL bBundledInstallerFound = FALSE; BOOL bDisplayAppHelpDialog = FALSE; BOOL bKillCurrentProcess = FALSE; BOOL bLaunchBundledInstaller = FALSE; BOOL bReturnValue = FALSE; UINT uiWinExecReturned = 0;
if (!g_bDoneIt) { if (!ParseCommandLine(COMMAND_LINE)) { goto eh; } bBundledInstallerFound = LocateInstaller(lpszInstaller, MAX_PATH, &bDisplayAppHelpDialog);
if (bBundledInstallerFound) { DPF("FindAOL", eDbgLevelWarning, "Bundled installer found in %s.\n",lpszInstaller); }
if (bBundledInstallerFound == FALSE && bDisplayAppHelpDialog == FALSE) { DPF("FindAOL", eDbgLevelWarning, "Bundled installer not found. Let client run normally.\n"); goto eh; }
if (bBundledInstallerFound == FALSE && bDisplayAppHelpDialog == TRUE) { bReturnValue = InvokeApphelpShowDialog(g_dwHTMLHelpID_Incompatible);
// if user chose Cancel button, then just kill current process.
if (FALSE == bReturnValue) { bKillCurrentProcess = TRUE; } }
if (bBundledInstallerFound == TRUE && bDisplayAppHelpDialog == TRUE) { bReturnValue = InvokeApphelpShowDialog(g_dwHTMLHelpID_BundledFound);
// if user chose Continue button, then launch bundled installer.
if (TRUE == bReturnValue) { bKillCurrentProcess = TRUE; bLaunchBundledInstaller = TRUE; } }
if (bBundledInstallerFound == TRUE && bDisplayAppHelpDialog == FALSE) {
// Launch bundled installer.
bKillCurrentProcess = TRUE; bLaunchBundledInstaller = TRUE; }
if (bLaunchBundledInstaller) { // launch bundled installer instead
uiWinExecReturned = WinExec(lpszInstaller, SW_SHOW);
if (uiWinExecReturned <= 31) { DPF("FindAOL", eDbgLevelError, "Can not launch program. Error: %d\n",GetLastError()); goto eh; } }
if (bKillCurrentProcess) { ExitProcess(0); } }
eh:
g_bDoneIt = TRUE; }
LPSTR APIHOOK(GetCommandLineA)() { DoIt();
return ORIGINAL_API(GetCommandLineA)(); }
VOID APIHOOK(GetStartupInfoA)( LPSTARTUPINFOA lpStartupInfo) { DoIt();
ORIGINAL_API(GetStartupInfoA)(lpStartupInfo); }
DWORD APIHOOK(GetModuleFileNameA)( HMODULE hModule, // handle to module
LPSTR lpFilename, // file name of module
DWORD nSize // size of buffer
) { DoIt();
return ORIGINAL_API(GetModuleFileNameA)(hModule, lpFilename, nSize); }
HWND APIHOOK(CreateWindowExA)( DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam ) { DoIt();
return ORIGINAL_API(CreateWindowExA)( dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam ); }
/*++
Register hooked functions
--*/
HOOK_BEGIN APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineA) APIHOOK_ENTRY(KERNEL32.DLL, GetStartupInfoA) APIHOOK_ENTRY(KERNEL32.DLL, GetModuleFileNameA) APIHOOK_ENTRY(USER32.DLL, CreateWindowExA) HOOK_END
IMPLEMENT_SHIM_END
|