|
|
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Main.cpp
//
// Microsoft CONFIDENTIAL
//
// Copyright (C) 1998, 1999 Microsoft Corporation. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Make sure to enable multi-threading and OLE2
//
#ifndef _MT
#define _MT
#endif
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <assert.h>
#include <string.h>
#include "Global.h"
#include "RunOnce.h"
#include "RegistryKey.h"
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
BOOL ExtractComponent(const DWORD dwIndex, LPCTSTR strPath) { BOOL fSuccess = FALSE; HRSRC hResourceInfo; HGLOBAL hResource; LPVOID lpResourceImage; HANDLE hFileHandle; DWORD dwBytesToWrite, dwBytesWritten; TCHAR strDestinationFilename[MAX_PATH];
//
// Build the destination filename
//
wsprintf(strDestinationFilename, TEXT("%s\\%s"), strPath, g_sComponentInfo[dwIndex].strFilename);
//
// Get the resource that contains the binary image of TestSample.exe
//
hResourceInfo = FindResource(g_hInstance, MAKEINTRESOURCE(g_sComponentInfo[dwIndex].dwResourceId), "BINARY"); if (NULL != hResourceInfo) { hResource = LoadResource(g_hInstance, hResourceInfo); if (NULL != hResource) { dwBytesToWrite = SizeofResource(g_hInstance, hResourceInfo); if (0 < dwBytesToWrite) { lpResourceImage = LockResource(hResource); if (NULL != lpResourceImage) { //
// Make sure to delete the existing file
//
if (FileExists(strDestinationFilename)) { SetFileAttributes(strDestinationFilename, FILE_ATTRIBUTE_NORMAL); DeleteFile(strDestinationFilename); }
//
// Write it to a file
//
hFileHandle = CreateFile(strDestinationFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); if (INVALID_HANDLE_VALUE != hFileHandle) { //
// Write the bits to the file
//
if (WriteFile(hFileHandle, lpResourceImage, dwBytesToWrite, &dwBytesWritten, NULL)) { if (dwBytesToWrite == dwBytesWritten) { fSuccess = TRUE; } }
//
// Close the file
//
CloseHandle(hFileHandle); } } } } }
return fSuccess; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
BOOL GetFileVersion(LPTSTR strFilename, VS_FIXEDFILEINFO * lpFileInfo) { BOOL fSuccess = FALSE; LPVOID lpVersion; LPVOID lpVersionInfo; UINT uSize; DWORD dwSize, dwEmpty;
//
// By default we zero out the lpFileInfo buffer
//
ZeroMemory(lpFileInfo, sizeof(VS_FIXEDFILEINFO));
//
// Go get the version info for that file
//
dwSize = GetFileVersionInfoSize((LPTSTR) strFilename, &dwEmpty); if (0 != dwSize) { lpVersion = new BYTE [dwSize]; ZeroMemory(lpVersion, dwSize); if (NULL != lpVersion) { if (0 != GetFileVersionInfo(strFilename, 0, dwSize, lpVersion)) { if (0 != VerQueryValue(lpVersion, TEXT("\\"), &lpVersionInfo, &uSize)) { if (uSize == sizeof(VS_FIXEDFILEINFO)) { //
// Save the version information
//
CopyMemory(lpFileInfo, lpVersionInfo, sizeof(VS_FIXEDFILEINFO));
//
// delete the memory allocated to lpVersion
//
delete [] lpVersion;
//
// Everything was successful
//
fSuccess = TRUE; } } } } }
return fSuccess; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
DWORD CompareFileVersions(VS_FIXEDFILEINFO * lpFileInfo1, VS_FIXEDFILEINFO * lpFileInfo2) { if (HIWORD(lpFileInfo1->dwFileVersionMS) > HIWORD(lpFileInfo2->dwFileVersionMS)) { return COMPONENT_NEWER_VERSION; }
if (HIWORD(lpFileInfo1->dwFileVersionMS) < HIWORD(lpFileInfo2->dwFileVersionMS)) { return COMPONENT_OLDER_VERSION; }
if (LOWORD(lpFileInfo1->dwFileVersionMS) > LOWORD(lpFileInfo2->dwFileVersionMS)) { return COMPONENT_NEWER_VERSION; }
if (LOWORD(lpFileInfo1->dwFileVersionMS) < LOWORD(lpFileInfo2->dwFileVersionMS)) { return COMPONENT_OLDER_VERSION; }
if (HIWORD(lpFileInfo1->dwFileVersionLS) > HIWORD(lpFileInfo2->dwFileVersionLS)) { return COMPONENT_NEWER_VERSION; }
if (HIWORD(lpFileInfo1->dwFileVersionLS) < HIWORD(lpFileInfo2->dwFileVersionLS)) { return COMPONENT_OLDER_VERSION; }
if (LOWORD(lpFileInfo1->dwFileVersionLS) > LOWORD(lpFileInfo2->dwFileVersionLS)) { return COMPONENT_NEWER_VERSION; } if (LOWORD(lpFileInfo1->dwFileVersionLS) < LOWORD(lpFileInfo2->dwFileVersionLS)) { return COMPONENT_OLDER_VERSION; }
return COMPONENT_SAME_VERSION; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
DWORD CompareFiles(LPCTSTR strFile1, LPCTSTR strFile2) { HANDLE hFileHandle[2]; HANDLE hFileMapping[2]; LPVOID lpFileView[2]; DWORD dwFileSize[2]; DWORD dwReturnCode = 0xffffffff;
//
// Open strFile1
//
hFileHandle[0] = CreateFile(strFile1, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != hFileHandle[0]) { //
// Open strFile2
//
hFileHandle[1] = CreateFile(strFile2, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != hFileHandle[1]) { //
// Get the file size for both files. They should be the same in order for us to continue
//
dwFileSize[0] = GetFileSize(hFileHandle[0], NULL); dwFileSize[1] = GetFileSize(hFileHandle[1], NULL);
if (dwFileSize[0] == dwFileSize[1]) { //
// Create a file mapping for hFileHandle[0]
//
hFileMapping[0] = CreateFileMapping(hFileHandle[0], NULL, PAGE_READONLY, 0, dwFileSize[0], NULL); if (NULL != hFileMapping[0]) { //
// Map a view of hFileMapping[0]
//
lpFileView[0] = MapViewOfFile(hFileMapping[0], FILE_MAP_READ, 0, 0, 0); if (NULL != lpFileView[0]) { //
// Create a file mapping for hFileHandle[1]
//
hFileMapping[1] = CreateFileMapping(hFileHandle[1], NULL, PAGE_READONLY, 0, dwFileSize[1], NULL); if (NULL != hFileMapping[1]) { //
// Map a view of hFileMapping[1]
//
lpFileView[1] = MapViewOfFile(hFileMapping[1], FILE_MAP_READ, 0, 0, 0); if (NULL != lpFileView[1]) { //
// Compare lpFileView[0] and lpFileView[1]
//
if (0 != memcmp(lpFileView[0], lpFileView[1], dwFileSize[0])) { dwReturnCode = COMPONENT_NOT_IDENTICAL; } else { dwReturnCode = 0; }
//
// Make sure to unmap the view of file for lpFileView[1]
//
UnmapViewOfFile(lpFileView[1]); }
//
// Make sure to release the mapping for hFileMapping[1]
//
CloseHandle(hFileMapping[1]); }
//
// Make sure to unmap the view of file for lpFileView[0]
//
UnmapViewOfFile(lpFileView[0]); }
//
// Make sure to release the mapping for hFileMapping[0]
//
CloseHandle(hFileMapping[0]); } } else { //
// Files are not the same size
//
dwReturnCode = COMPONENT_NOT_IDENTICAL; }
//
// Make sure to close hFileHandle2
//
CloseHandle(hFileHandle[1]); }
//
// Make sure to close hFileHandle1
//
CloseHandle(hFileHandle[0]); }
return dwReturnCode; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
BOOL RegisterComponent(LPCTSTR strFilename) { BOOL fSuccess = FALSE; HRESULT hResult; HINSTANCE hInstance; LPFNDLLREGISTERSERVER DllRegisterServer;
hInstance = LoadLibrary(strFilename); if (hInstance) { DllRegisterServer = (LPFNDLLREGISTERSERVER) GetProcAddress(hInstance, "DllRegisterServer"); if ((DllRegisterServer)&&(SUCCEEDED(DllRegisterServer()))) { fSuccess = TRUE; }
//
// Make sure to free the library
//
FreeLibrary(hInstance); }
return fSuccess; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
BOOL UnRegisterComponent(LPCTSTR strFilename) { BOOL fSuccess = FALSE; HRESULT hResult; HINSTANCE hInstance; LPFNDLLUNREGISTERSERVER DllUnregisterServer;
hInstance = LoadLibrary(strFilename); if (hInstance) { DllUnregisterServer = (LPFNDLLREGISTERSERVER) GetProcAddress(hInstance, "DllUnregisterServer"); if ((DllUnregisterServer)&&(SUCCEEDED(DllUnregisterServer()))) { fSuccess = TRUE; }
//
// Make sure to free the library
//
FreeLibrary(hInstance); }
return fSuccess; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
BOOL SetDebugMode(void) { BOOL fSuccess = FALSE; CRegistryKey oRegistryKey; TCHAR strValueName[MAX_PATH]; DWORD dwValue, dwKeyDisposition;
//
// Do we want to run in debug mode ?
//
if (g_fInstallDebug) { //
// Make sure our target registry key exists
//
if (S_OK != oRegistryKey.CheckForExistingKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\AppMan"))) { oRegistryKey.CreateKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\AppMan"), 0, KEY_ALL_ACCESS, &dwKeyDisposition); }
//
// Open the target registry key
//
if (S_OK == oRegistryKey.OpenKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\AppMan"), KEY_ALL_ACCESS)) { wsprintf(strValueName, TEXT("Debug")); dwValue = 0; if (S_OK == oRegistryKey.SetValue(strValueName, REG_DWORD, (LPBYTE) &dwValue, sizeof(dwValue))) { wsprintf(strValueName, TEXT("LoadDebugRuntime")); dwValue = 1; if (S_OK == oRegistryKey.SetValue(strValueName, REG_DWORD, (LPBYTE) &dwValue, sizeof(dwValue))) { fSuccess = TRUE; } }
//
// Make sure to close the registry
//
oRegistryKey.CloseKey(); } } else { //
// We do not want to run in debug mode. Make sure to delete the target registry key
//
if (S_OK == oRegistryKey.CheckForExistingKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\AppMan"))) { if (S_OK == oRegistryKey.DeleteKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\AppMan"))) { fSuccess = TRUE; } } }
return fSuccess; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
LONG SetupAndLaunch(void) { LONG lReturnCode = -2; BOOL fReady = FALSE; STARTUPINFO sStartupInfo; PROCESS_INFORMATION sProcessInfo; DWORD dwIndex, dwReturnValue; TCHAR strTempPath[MAX_PATH]; TCHAR strSystemPath[MAX_PATH]; TCHAR strSourceFilename[MAX_PATH]; TCHAR strDestinationFilename[MAX_PATH]; TCHAR strCmdLine[MAX_PATH]; VS_FIXEDFILEINFO sSourceFileInfo; VS_FIXEDFILEINFO sDestinationFileInfo;
//
// Where should the temporary files go
//
if (GetSystemDirectory(strSystemPath, MAX_PATH)) { if (GetTempPath(MAX_PATH, strTempPath)) { //
// What is the source filename ?
//
if (GetModuleFileName(NULL, strSourceFilename, MAX_PATH)) { //
// Generate the path/filename pair for the destination of the setup bits
//
wsprintf(strDestinationFilename, TEXT("%s\\WAMSetup.exe"), strSystemPath); if (FileExists(strDestinationFilename)) { SetFileAttributes(strDestinationFilename, FILE_ATTRIBUTE_NORMAL); if (DeleteFile(strDestinationFilename)) { if (CopyFile(strSourceFilename, strDestinationFilename, FALSE)) { fReady = TRUE; } } } else { //
// There is no existing destination file. Just copy the source to the destination
//
if (CopyFile(strSourceFilename, strDestinationFilename, FALSE)) { fReady = TRUE; } } }
//
// Did we successfully copy the setup executable to the system directory. Continue if so.
//
if (fReady) { //
// Execute the temporary executable
//
ZeroMemory(&sStartupInfo, sizeof(sStartupInfo)); sStartupInfo.cb = sizeof(sStartupInfo); ZeroMemory(&sProcessInfo, sizeof(PROCESS_INFORMATION)); if (g_fInstallDebug) { wsprintf(strCmdLine, TEXT("""%s"" /DoInstall /Debug"), strDestinationFilename); } else { wsprintf(strCmdLine, TEXT("""%s"" /DoInstall"), strDestinationFilename); }
if (CreateProcess(NULL, strCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &sStartupInfo, &sProcessInfo)) { //
// Wait for the process to end
//
WaitForSingleObject(sProcessInfo.hProcess, INFINITE);
//
// What was the return value ?
//
if (GetExitCodeProcess(sProcessInfo.hProcess, &dwReturnValue)) { switch(dwReturnValue) { case _EXIT_SUCCESS : lReturnCode = 1; break;
case _EXIT_SUCCESS_REBOOT : lReturnCode = 2; break;
default : lReturnCode = -1; break; } }
//
// Close the process and thread handles created by CreateProcess()
//
CloseHandle(sProcessInfo.hThread); CloseHandle(sProcessInfo.hProcess); } } } }
return lReturnCode; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
LONG DoInstall(void) { LONG lReturnCode = -1; BOOL fReady = TRUE; BOOL fRebootNeeded = FALSE; DWORD dwIndex; TCHAR strSystemPath[MAX_PATH]; TCHAR strTempPath[MAX_PATH]; TCHAR strSourceFilename[MAX_PATH]; TCHAR strTargetFilename[MAX_PATH]; TCHAR strAlternateTargetFilename[MAX_PATH];
//
// Get the system and temp path to start with
//
if (GetSystemDirectory(strSystemPath, MAX_PATH)) { if (GetTempPath(MAX_PATH, strTempPath)) { //
// Extract the DLLs to a temporary directory
//
for (dwIndex = 0; dwIndex < COMPONENT_COUNT; dwIndex++) { if (g_dwOSVersion & g_sComponentInfo[dwIndex].dwTargetOS) { if ((FALSE == g_sComponentInfo[dwIndex].fDebugVersion)||(g_fInstallDebug)) { if (!ExtractComponent(dwIndex, strTempPath)) { fReady = FALSE; } } } }
//
// Continue on if the DLLS were properly extracted
//
if (fReady) { //
// First we need to initialize the RunOnce process
//
if (InitializeRunOnce(TRUE)) { //
// Determine the status of the component
//
for (dwIndex = 0; dwIndex < COMPONENT_COUNT; dwIndex++) { if (g_dwOSVersion & g_sComponentInfo[dwIndex].dwTargetOS) { if ((FALSE == g_sComponentInfo[dwIndex].fDebugVersion)||(g_fInstallDebug)) { //
// What would be the target filename for component at dwIndex
//
wsprintf(strSourceFilename, TEXT("%s%s"), strTempPath, g_sComponentInfo[dwIndex].strFilename); wsprintf(strTargetFilename, TEXT("%s\\%s"), strSystemPath, g_sComponentInfo[dwIndex].strFilename); if (FileExists(strTargetFilename)) { //
// Flag the component as being on the system
//
g_sComponentInfo[dwIndex].dwStatus |= COMPONENT_ON_SYSTEM;
//
// Get the version of the component on the system
//
GetFileVersion(strTargetFilename, &g_sComponentInfo[dwIndex].sCurrentVersionInfo); GetFileVersion(strSourceFilename, &g_sComponentInfo[dwIndex].sTargetVersionInfo);
//
// Compare the component on the system and the target component
//
g_sComponentInfo[dwIndex].dwStatus |= CompareFileVersions(&g_sComponentInfo[dwIndex].sCurrentVersionInfo, &g_sComponentInfo[dwIndex].sTargetVersionInfo);
//
// If the two files are the same version, they should be identical. Check that fact
//
g_sComponentInfo[dwIndex].dwStatus |= CompareFiles(strTargetFilename, strSourceFilename); } } } }
//
// At first, we will try to copy each component to the system directory. Otherwise we
// will copy the components to the system directory under temporary names.
//
for (dwIndex = 0; dwIndex < COMPONENT_COUNT; dwIndex++) { if (g_dwOSVersion & g_sComponentInfo[dwIndex].dwTargetOS) { if ((FALSE == g_sComponentInfo[dwIndex].fDebugVersion)||(g_fInstallDebug)) { //
// Determine whether or not the component should be updated before proceeding
//
if ((!(COMPONENT_ON_SYSTEM & g_sComponentInfo[dwIndex].dwStatus))||(COMPONENT_OLDER_VERSION & g_sComponentInfo[dwIndex].dwStatus)||((COMPONENT_NOT_IDENTICAL & g_sComponentInfo[dwIndex].dwStatus)&&(COMPONENT_SAME_VERSION & g_sComponentInfo[dwIndex].dwStatus))) { //
// What will be the target filename
//
wsprintf(strSourceFilename, TEXT("%s%s"), strTempPath, g_sComponentInfo[dwIndex].strFilename); wsprintf(strTargetFilename, TEXT("%s\\%s"), strSystemPath, g_sComponentInfo[dwIndex].strFilename); if (!CopyFile(strSourceFilename, strTargetFilename, FALSE)) { //
// We will need to copy the DLL to a temporary directory
//
if ((GenerateUniqueFilename(strSystemPath, TEXT("dll"), strAlternateTargetFilename))&&(CopyFile(strSourceFilename, strAlternateTargetFilename, FALSE))) { SetRunOnceCleanupFile(strAlternateTargetFilename, strTargetFilename, g_sComponentInfo[dwIndex].fRegister); fRebootNeeded = TRUE; } else { break; } }
//
// Excellent, all we need to do is register the component if required
//
if (g_sComponentInfo[dwIndex].fRegister) { if (!RegisterComponent(strTargetFilename)) { break; } } } } } }
//
// Did everything go as planned
//
if (COMPONENT_COUNT == dwIndex) { //
// Finish off the DoInstall process
//
SetDebugMode(); if (fRebootNeeded) { FinalizeRunOnce(TRUE); lReturnCode = 2; } else { FinalizeRunOnce(FALSE); lReturnCode = 1; } } } }
//
// Did we fail ?
//
if (-1 == lReturnCode) { FinalizeRunOnce(FALSE); }
//
// Delete the temporary DLLs
//
for (dwIndex = 0; dwIndex < COMPONENT_COUNT; dwIndex++) { if (g_dwOSVersion & g_sComponentInfo[dwIndex].dwTargetOS) { if ((FALSE == g_sComponentInfo[dwIndex].fDebugVersion)||(g_fInstallDebug)) { wsprintf(strTargetFilename, TEXT("%s\\%s"), strTempPath, g_sComponentInfo[dwIndex].strFilename); SetFileAttributes(strTargetFilename, FILE_ATTRIBUTE_NORMAL); DeleteFile(strTargetFilename); } } } } }
return lReturnCode; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
LONG DoCleanup(void) { LONG lReturnCode = 1; BOOL fSuccess; TCHAR strSourceFilename[MAX_PATH]; TCHAR strDestinationFilename[MAX_PATH];
//
// First we need to initialize the RunOnce process
//
if (InitializeRunOnce(FALSE)) { //
// Get the components that do need to be registered
//
fSuccess = TRUE; while ((fSuccess)&&(GetRunOnceCleanupFile(strSourceFilename, MAX_PATH, strDestinationFilename, MAX_PATH, TRUE))) { //
// By default we pretend that the operation will fail until proven otherwise
//
fSuccess = FALSE;
//
// Make sure the file attribute is set properly prior to deleting the destination file
//
SetFileAttributes(strDestinationFilename, FILE_ATTRIBUTE_NORMAL); if (UnRegisterComponent(strDestinationFilename)) { if (CopyFile(strSourceFilename, strDestinationFilename, FALSE)) { //
// Redo the registration on the component
//
if (UnRegisterComponent(strSourceFilename)) { SetFileAttributes(strSourceFilename, FILE_ATTRIBUTE_NORMAL); if (DeleteFile(strSourceFilename)) { if (RegisterComponent(strDestinationFilename)) { fSuccess = TRUE; } } } } else { //
// We were unable to overwrite the destination component. Make sure to re-register it
//
RegisterComponent(strDestinationFilename); } } }
//
// If we were not successful, put the RunOnceCleanupFile back into the registry before exiting
//
if (!fSuccess) { SetRunOnceCleanupFile(strSourceFilename, strDestinationFilename, TRUE); FinalizeRunOnce(TRUE); lReturnCode = 2; } else { //
// Get the components that do not need to be registered
//
while ((fSuccess)&&(GetRunOnceCleanupFile(strSourceFilename, MAX_PATH, strDestinationFilename, MAX_PATH, FALSE))) { //
// By default we pretend that the operation will fail until proven otherwise
//
fSuccess = FALSE;
//
// Make sure the file attribute is set properly prior to deleting the destination file
//
SetFileAttributes(strDestinationFilename, FILE_ATTRIBUTE_NORMAL); if (CopyFile(strSourceFilename, strDestinationFilename, FALSE)) { //
// Redo the registration on the component
//
SetFileAttributes(strSourceFilename, FILE_ATTRIBUTE_NORMAL); if (DeleteFile(strSourceFilename)) { fSuccess = TRUE; } } }
if (!fSuccess) { SetRunOnceCleanupFile(strSourceFilename, strDestinationFilename, FALSE); FinalizeRunOnce(TRUE); lReturnCode = 2; } else { FinalizeRunOnce(FALSE); lReturnCode = 1; } } }
return lReturnCode; }
//////////////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////////////
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR lpCommandLine, int nCmdShow) { //
// Initialize some global variables
//
g_hInstance = hInstance; g_dwOSVersion = GetOSVersion(); g_dwSuccessCode = 0;
//
// For now, we do not work in Win95
//
//if (OS_VERSION_WIN95 == g_dwOSVersion)
//{
// return -3;
//}
//
// Cast the command line into uppercase
//
_strupr(lpCommandLine);
//
// Define whether or not we care about the DEBUG files
//
if (NULL != strstr((LPCSTR) lpCommandLine, "/DEBUG")) { g_fInstallDebug = TRUE; } else { g_fInstallDebug = FALSE; }
//
// Is the /DoInstall command line parameter on the command line
//
if (NULL != strstr((LPCSTR) lpCommandLine, "/DOINSTALL")) { //
// Do the installation here
//
g_dwSuccessCode = (DWORD) DoInstall(); } else if (NULL == strstr((LPCSTR) lpCommandLine, "/CLEANUP")) { //
// Copy the executable to a temporary directory and restart it
//
g_dwSuccessCode = (DWORD) SetupAndLaunch(); } else { //
// Do the installation cleanup here. Please note that DoCleanup does not return errors.
//
g_dwSuccessCode = (DWORD) DoCleanup(); }
return (int) g_dwSuccessCode; }
///////////////////////////////////////////////////////////////////////////////////////////////////
|