home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
msdn_vcb
/
samples
/
vc98
/
sdk
/
sysmgmt
/
msi
/
instmsi
/
initmsi.cpp
Wrap
C/C++ Source or Header
|
1997-09-17
|
7KB
|
212 lines
// initmsi.cpp: MSI initialisation functions for msispy
#include "initmsi.h"
#include "resource.h"
#include "propshts.h"
#include "stdio.h"
// hard-coded component GUIDs and feature Names
TCHAR g_szEXEComponentCode[MAX_GUID+1] = TEXT("{5CB2D5F1-19DD-11d1-9A9D-006097C4E489}");
TCHAR g_szDLLComponentCode[MAX_GUID+1] = TEXT("{5CB2D5F0-19DD-11d1-9A9D-006097C4E489}");
TCHAR g_szIntlDLLComponentCode[MAX_GUID+1]= TEXT("{B62B2CE0-1A98-11d1-9A9E-006097C4E489}");
TCHAR g_szHelpComponentCode[MAX_GUID+1] = TEXT("{1F7586D0-20B1-11d1-9AB3-006097C4E489}");
TCHAR g_szMyProductCode[MAX_GUID+1] = TEXT(""); // will be obtained at runtime
TCHAR g_szDLLFeatureName[] = TEXT("SystemInterface");
TCHAR g_szEXEFeatureName[] = TEXT("UserInterface");
TCHAR g_szDefaultQualifier[] = TEXT("0");
LCID g_lcidCurrentLocale;
TCHAR g_szHelpFilePath[MAX_PATH+1] = TEXT("");
extern MSISPYSTRUCT vmInfo;
// This message is displayed if the (localised) resource DLL could not be loaded.
// This string will always appear in English regardless of the User/System LCID.
#define ERRORMESSAGE_UNABLETOLOADDLL TEXT("Msispy was unable to load the resource file.\nComponent Code: %s\nError Code: %d")
#define ERRORCAPTION_UNABLETOLOADDLL TEXT("Msispy: Fatal Error")
// -------------------------------------------------------------------------------------------
// FindComponent()
// Locates and provides the required component calling MsiProvideQualifiedComponent,
// using the global LCID (g_lcidCurrentLocale) as the qualifier. If that fails, it
// tries just the primary lang-ID of g_lcidCurrentLocale. If that fails as well,
// it tries the default qualifier (g_szDefaultQualifier). Finally if this fails as
// well it returns the error code of this attempt, else it returns ERROR_SUCCESS
// The path to the component is returned in szPath
UINT FindComponent(
LPCTSTR szComponentCode, // GUID of the component to Provide
LPTSTR szPath, // Buffer for returned path
DWORD *pcchPath // size of buffer
)
{
DWORD cchPathInitial = *pcchPath;
lstrcpy(szPath, TEXT("")); // set [out] variable to known value
TCHAR szQualifier[MAX_PATH+1];
UINT iResult;
for (UINT iCount = 0; 3 > iCount ; iCount++)
{
switch (iCount)
{
case 0:
// Try the full Language ID
wsprintf(szQualifier, TEXT("%4.4x"), LANGIDFROMLCID(g_lcidCurrentLocale));
break;
case 1:
// Full language ID failed, try primary Language ID
wsprintf(szQualifier, TEXT("%2.2x"), PRIMARYLANGID(LANGIDFROMLCID(g_lcidCurrentLocale)));
break;
case 2:
// language IDs failed, try the default qualifier
lstrcpy(szQualifier, g_szDefaultQualifier);
break;
}
*pcchPath = cchPathInitial;
iResult = MsiProvideQualifiedComponent(szComponentCode, szQualifier, 0, szPath, pcchPath);
switch (iResult)
{
case ERROR_SUCCESS:
case ERROR_INSTALL_USEREXIT:
case ERROR_INSTALL_FAILURE:
return iResult;
}
}
// ProvideQualifiedComponent failed
return iResult;
}
// -------------------------------------------------------------------------------------------
// fInitMSI()
// Function to fault in resource DLL and initialise MSI related items
// Returns TRUE if the MSI initialisation succeeded, FALSE if there
// was a fatal error.
// When the function returns, hResourceInstance points to the hInstance
// of the resource DLL if the DLL was loaded successfully
BOOL fInitMSI(HINSTANCE *hResourceInstance)
{
// set [out] variable to known value
*hResourceInstance = 0;
g_lcidCurrentLocale = GetUserDefaultLCID();
// Get the product-code of the product using this component.
// The product-code is not hard-coded in because a component may be
// shared by multiple products.
MsiGetProductCode(g_szEXEComponentCode, g_szMyProductCode);
TCHAR szIntlDLLPath[MAX_PATH+1];
DWORD cchIntlDLLPath = MAX_PATH+1;
UINT iResult;
// Try finding the resource DLL- if unsuccessful, inform user and exit
if (ERROR_SUCCESS != (iResult = FindComponent(g_szIntlDLLComponentCode, szIntlDLLPath, &cchIntlDLLPath)))
{
TCHAR szErrorMessage[MAX_MESSAGE+1];
wsprintf(szErrorMessage, ERRORMESSAGE_UNABLETOLOADDLL, g_szIntlDLLComponentCode, iResult);
TCHAR szErrorCaption[MAX_HEADER+1];
wsprintf(szErrorCaption, ERRORCAPTION_UNABLETOLOADDLL);
MessageBox(NULL, szErrorMessage, szErrorCaption, MB_ICONSTOP|MB_OK);
return FALSE;
}
// Load the international DLL
*hResourceInstance = W32::LoadLibrary(szIntlDLLPath);
// Check if the SystemInterface feature is available for use. If not,
// call SwitchMode to gray out features that depend on it and inform
// user.
if (MsiQueryFeatureState(g_szMyProductCode, g_szDLLFeatureName) == INSTALLSTATE_UNKNOWN)
{
// Switch to Degraded Mode [grays out features that depend on SystemInterface feature]
SwitchMode(MODE_DEGRADED);
TCHAR szRestrMsg[MAX_MESSAGE+1];
LoadString(*hResourceInstance, IDS_STARTUPRESTRICTEDMSG, szRestrMsg, MAX_MESSAGE+1);
TCHAR szRestrCaption[MAX_HEADER+1];
LoadString(*hResourceInstance, IDS_STARTUPRESTRICTEDCPN, szRestrCaption, MAX_HEADER+1);
// Inform user that Msispy is now in "Restricted Mode"
MessageBox(NULL, szRestrMsg, szRestrCaption, MB_OK|MB_ICONEXCLAMATION);
}
else
SwitchMode(MODE_NORMAL);
// Prepare to use the UserInterface feature: check its current state and increase usage count.
INSTALLSTATE iEXEFeatureState = MsiUseFeature(g_szMyProductCode, g_szEXEFeatureName);
// If feature is not currently usable, try fixing it
switch (iEXEFeatureState)
{
case INSTALLSTATE_DEFAULT:
case INSTALLSTATE_LOCAL:
case INSTALLSTATE_SOURCE:
// feature is installed and usable
return TRUE;
case INSTALLSTATE_ABSENT:
// feature isn't installed, try installing it
if (MsiConfigureFeature(g_szMyProductCode, g_szEXEFeatureName, INSTALLSTATE_LOCAL) != ERROR_SUCCESS)
return FALSE; // installation failed
break;
default:
// feature is busted- try fixing it
if (MsiReinstallFeature(g_szMyProductCode, g_szEXEFeatureName,
REINSTALLMODE_REPAIR
+ REINSTALLMODE_FILEEQUALVERSION
+ REINSTALLMODE_MACHINEDATA
+ REINSTALLMODE_USERDATA
+ REINSTALLMODE_SHORTCUT) != ERROR_SUCCESS)
return FALSE; // we couldn't fix it
break;
}
return TRUE;
}
// -------------------------------------------------------------------------------------------
// fHandleHelp()
// Creates a new process to bring up the help
// Uses FindComponent to load the appropriate help file (based on g_lcidCurrentLocale)
BOOL fHandleHelp(HINSTANCE hResourceInstance)
{
DWORD cchHelpFilePath = MAX_PATH+1;
UINT iResult = 0;
if (ERROR_SUCCESS != (iResult = FindComponent(g_szHelpComponentCode, g_szHelpFilePath, &cchHelpFilePath)))
{
// we couldn't find the help file
TCHAR szErrorMsg[MAX_MESSAGE+1];
TCHAR szErrorCpn[MAX_HEADER+1];
LoadString(hResourceInstance, IDS_NOHELPMSG, szErrorMsg, MAX_MESSAGE+1);
LoadString(hResourceInstance, IDS_NOHELPCPN, szErrorCpn, MAX_HEADER+1);
MessageBox(NULL, szErrorMsg, szErrorCpn, MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
// MsiUseFeature(g_szMyProductCode, g_szHelpFeatureName);
// Launch WinHelp to handle help
return WinHelp(vmInfo.hwndParent, g_szHelpFilePath, HELP_FINDER, 0);
}