Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1018 lines
27 KiB

//////////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
///////////////////////////////////////////////////////////////////////////////////////////////////