|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: csocm.cpp
//
// Contents: OCM component DLL for running the Certificate
// Server setup.
//
// Functions:
//
// History: 12/13/96 TedM Created Original Version
// 04/07/97 JerryK Rewrite for Cert Server
// 04/??/97 JerryK Stopped updating these comments since
// every other line changes every day.
// 08/98 XTan Major structure change
//
// Notes:
//
// This sample OCM component DLL can be the component DLL
// for multiple components. It assumes that a companion sample INF
// is being used as the per-component INF, with private data in the
// following form.
//
// [<pwszComponent>,<pwszSubComponent>]
// Bitmap = <bitmapresourcename>
// VerifySelect = 0/1
// VerifyDeselect = 0/1
// ;
// ; follow this with install stuff such as CopyFiles= sections, etc.
//
//------------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
#include <common.ver>
#include "msg.h"
#include "certmsg.h"
#include "setuput.h"
#include "setupids.h"
#include "clibres.h"
#include "csresstr.h"
// defines
#define cwcMESSAGETEXT 250
#define cwcINFVALUE 250
#define wszSMALLICON L"_SmallIcon"
#define wszUNINSTALL L"_Uninstall"
#define wszUPGRADE L"_Upgrade"
#define wszINSTALL L"_Install"
#define wszVERIFYSELECT L"_VerifySelect"
#define wszVERIFYDESELECT L"_VerifyDeselect"
#define wszCONFIGTITLE L"Title"
#define wszCONFIGCOMMAND L"ConfigCommand"
#define wszCONFIGARGS L"ConfigArgs"
#define wszCONFIGTITLEVAL L"Certificate Services"
#define wszCONFIGCOMMANDVAL L"sysocmgr.exe"
#define wszCONFIGARGSVAL L"/i:certmast.inf /x"
#define __dwFILE__ __dwFILE_OCMSETUP_CSOCM_CPP__
// globals
PER_COMPONENT_DATA g_Comp; // Top Level component
HINSTANCE g_hInstance; // get rid of it????
// find out if certsrv post setup is finished by checking
// registry entries. ie. finish CYS?
HRESULT CheckPostBaseInstallStatus( OUT BOOL *pfFinished) { HRESULT hr; HKEY hKey = NULL; DWORD dwSize = 0; DWORD dwType = REG_NONE;
//init
*pfFinished = TRUE;
if (ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, wszREGKEYCERTSRVTODOLIST, 0, KEY_READ, &hKey)) { if (ERROR_SUCCESS == RegQueryValueEx( hKey, wszCONFIGCOMMAND, NULL, &dwType, NULL, // only query size
&dwSize) && REG_SZ == dwType) { dwType = REG_NONE; if (ERROR_SUCCESS == RegQueryValueEx( hKey, wszCONFIGARGS, NULL, &dwType, NULL, // only query size
&dwSize) && REG_SZ == dwType) { dwType = REG_NONE; if (ERROR_SUCCESS == RegQueryValueEx( hKey, wszCONFIGTITLE, NULL, &dwType, NULL, // only query size
&dwSize) && REG_SZ == dwType) { //all entries exist
*pfFinished = FALSE; } } } }
hr = S_OK; //error:
if (NULL != hKey) { RegCloseKey(hKey); } return hr; }
HRESULT InitComponentAttributes( IN OUT PER_COMPONENT_DATA *pComp, IN HINSTANCE hDllHandle) { HRESULT hr;
ZeroMemory(pComp, sizeof(PER_COMPONENT_DATA)); pComp->hInstance = hDllHandle; g_hInstance = hDllHandle; //get rid of it????
pComp->hrContinue = S_OK; pComp->pwszCustomMessage = NULL; pComp->fUnattended = FALSE; pComp->pwszUnattendedFile = NULL; pComp->pwszServerName = NULL; pComp->pwszServerNameOld = NULL; pComp->dwInstallStatus = 0x0; pComp->fPostBase = FALSE; (pComp->CA).pServer = NULL; (pComp->CA).pClient = NULL; pComp->hinfCAPolicy = INVALID_HANDLE_VALUE; hr = S_OK;
//error:
return hr; }
//+------------------------------------------------------------------------
//
// Function: DllMain( . . . . )
//
// Synopsis: DLL Entry Point.
//
// Arguments: [DllHandle] DLL module handle.
// [Reason] Reasons for entry into DLL.
// [Reserved] Reserved.
//
// Returns: BOOL
//
// History: 04/07/97 JerryK Created (again)
//
//-------------------------------------------------------------------------
BOOL WINAPI DllMain( IN HMODULE DllHandle, IN DWORD Reason, IN LPVOID Reserved) { BOOL b;
UNREFERENCED_PARAMETER(Reserved);
b = TRUE; switch(Reason) { case DLL_PROCESS_ATTACH: DBGPRINT((DBG_SS_CERTOCMI, "Process Attach\n")); // component initialization
InitComponentAttributes(&g_Comp, DllHandle);
// Fall through to process first thread
case DLL_THREAD_ATTACH: b = TRUE; break;
case DLL_PROCESS_DETACH: DBGPRINT((DBG_SS_CERTOCMI, "Process Detach\n"));
if(INVALID_HANDLE_VALUE != g_Comp.hinfCAPolicy) myInfCloseFile(g_Comp.hinfCAPolicy);
myInfClearError(); myFreeResourceStrings("certocm.dll"); myFreeColumnDisplayNames(); myRegisterMemDump(); csiLogClose(); break;
case DLL_THREAD_DETACH: break; } return b; }
extern UNATTENDPARM aUnattendParmClient[]; extern UNATTENDPARM aUnattendParmServer[];
SUBCOMP g_aSubComp[] = { { L"certsrv", // pwszSubComponent
cscTopLevel, // cscSubComponent
0, // InstallFlags
0, // UninstallFlags
0, // ChangeFlags
0, // UpgradeFlags
0, // EnabledFlags
0, // SetupStatusFlags
FALSE, // fDefaultInstallUnattend
FALSE, // fInstallUnattend
NULL // aUnattendParm
}, { wszSERVERSECTION, // pwszSubComponent
cscServer, // cscSubComponent
IS_SERVER_INSTALL, // InstallFlags
IS_SERVER_REMOVE, // UninstallFlags
IS_SERVER_CHANGE, // ChangeFlags
IS_SERVER_UPGRADE, // UpgradeFlags
IS_SERVER_ENABLED, // EnabledFlags
SETUP_SERVER_FLAG, // SetupStatusFlags
TRUE, // fDefaultInstallUnattend
FALSE, // fInstallUnattend
aUnattendParmServer // aUnattendParm
}, { wszCLIENTSECTION, // pwszSubComponent
cscClient, // cscSubComponent
IS_CLIENT_INSTALL, // InstallFlags
IS_CLIENT_REMOVE, // UninstallFlags
IS_CLIENT_CHANGE, // ChangeFlags
IS_CLIENT_UPGRADE, // UpgradeFlags
IS_CLIENT_ENABLED, // EnabledFlags
SETUP_CLIENT_FLAG, // SetupStatusFlags
TRUE, // fDefaultInstallUnattend
FALSE, // fInstallUnattend
aUnattendParmClient // aUnattendParm
}, { NULL, // pwszSubComponent
} };
SUBCOMP * TranslateSubComponent( IN WCHAR const *pwszComponent, OPTIONAL IN WCHAR const *pwszSubComponent) { SUBCOMP *psc;
if (NULL == pwszSubComponent) { pwszSubComponent = pwszComponent; } for (psc = g_aSubComp; NULL != psc->pwszSubComponent; psc++) { if (0 == mylstrcmpiL(psc->pwszSubComponent, pwszSubComponent)) { break; } } if (NULL == psc->pwszSubComponent) { psc = NULL; } return(psc); }
SUBCOMP const * LookupSubComponent( IN CertSubComponent SubComp) { SUBCOMP const *psc;
for (psc = g_aSubComp; NULL != psc->pwszSubComponent; psc++) { if (psc->cscSubComponent == SubComp) { break; } } CSASSERT(NULL != psc); return(psc); }
BOOL fDebugSupress = TRUE;
HRESULT UpdateSubComponentInstallStatus( IN WCHAR const *pwszComponent, IN WCHAR const *pwszSubComponent, IN OUT PER_COMPONENT_DATA *pComp) { HRESULT hr; BOOL fWasEnabled; BOOL fIsEnabled; DWORD InstallFlags; SUBCOMP const *psc;
psc = TranslateSubComponent(pwszComponent, pwszSubComponent); if (NULL == psc) { hr = E_INVALIDARG; _JumpError(hr, error, "Internal error: unsupported component"); }
fWasEnabled = certocmWasEnabled(pComp, psc->cscSubComponent); fIsEnabled = certocmIsEnabled(pComp, psc->cscSubComponent); CSILOGDWORD(IDS_LOG_WAS_ENABLED, fWasEnabled); CSILOGDWORD(IDS_LOG_IS_ENABLED, fIsEnabled);
InstallFlags = psc->InstallFlags | psc->ChangeFlags | psc->EnabledFlags; if (!fWasEnabled) { if (fIsEnabled) { // install case
pComp->dwInstallStatus |= InstallFlags; } else // !fIsEnabled
{ // this is from check then uncheck, should remove the bit
// turn off both bits
pComp->dwInstallStatus &= ~InstallFlags; } } else // fWasEnabled
{ if (pComp->fPostBase && (pComp->Flags & SETUPOP_STANDALONE) ) { // was installed, invoke from post setup
// this is install case
pComp->dwInstallStatus |= InstallFlags; } else if (pComp->Flags & SETUPOP_NTUPGRADE) { // if was installed and now in upgrade mode, upgrade case
pComp->dwInstallStatus |= psc->UpgradeFlags | psc->EnabledFlags; } else if (!fIsEnabled) { // uninstall case
pComp->dwInstallStatus &= ~psc->EnabledFlags; pComp->dwInstallStatus |= psc->UninstallFlags | psc->ChangeFlags; } else // fIsEnabled
{ pComp->dwInstallStatus |= psc->EnabledFlags; #if DBG_CERTSRV
BOOL fUpgrade = FALSE;
hr = myGetCertRegDWValue( NULL, NULL, NULL, L"EnforceUpgrade", (DWORD *) &fUpgrade); if (S_OK == hr && fUpgrade) { pComp->dwInstallStatus |= psc->UpgradeFlags; } #endif //DBG_CERTSRV
} // end fIsEnabled else
} // end fWasEnabled else
// after all of this, change upgrade->uninstall if not supported
// detect illegal upgrade
if (pComp->dwInstallStatus & IS_SERVER_UPGRADE) { hr = DetermineServerUpgradePath(pComp); _JumpIfError(hr, error, "DetermineServerUpgradePath"); } else if (pComp->dwInstallStatus & IS_CLIENT_UPGRADE) { hr = DetermineClientUpgradePath(pComp); _JumpIfError(hr, error, "LoadAndDetermineClientUpgradeInfo"); } if ((pComp->dwInstallStatus & IS_SERVER_UPGRADE) || (pComp->dwInstallStatus & IS_CLIENT_UPGRADE)) { CSASSERT(pComp->UpgradeFlag != CS_UPGRADE_UNKNOWN); if (CS_UPGRADE_UNSUPPORTED == pComp->UpgradeFlag) { pComp->dwInstallStatus &= ~InstallFlags; pComp->dwInstallStatus |= psc->UninstallFlags | psc->ChangeFlags; } }
CSILOG( S_OK, IDS_LOG_INSTALL_STATE, pwszSubComponent, NULL, &pComp->dwInstallStatus); hr = S_OK;
error: return hr; }
HRESULT certocmOcPreInitialize( IN WCHAR const *DBGPARMREFERENCED(pwszComponent), IN UINT Flags, OUT ULONG_PTR *pulpRet) { HRESULT hr;
*pulpRet = 0;
DBGPRINT((DBG_SS_CERTOCMI, "OC_PREINITIALIZE(%ws, %x)\n", pwszComponent, Flags));
myVerifyResourceStrings(g_hInstance);
// Return value is flag telling OCM which char width we want to run in.
#ifdef UNICODE
*pulpRet = OCFLAG_UNICODE & Flags; #else
*pulpRet = OCFLAG_ANSI & Flags; #endif
hr = S_OK; //error:
return hr; }
// Allocate and initialize a new component.
//
// Return code is Win32 error indicating outcome. ERROR_CANCELLED tells OCM to
// cancel the installation.
HRESULT certocmOcInitComponent( IN HWND hwnd, IN WCHAR const *pwszComponent, IN OUT SETUP_INIT_COMPONENT *pInitComponent, IN OUT PER_COMPONENT_DATA *pComp, OUT ULONG_PTR *pulpRet) { HRESULT hr; BOOL fCoInit = FALSE; HKEY hkey = NULL; WCHAR awc[30]; WCHAR *pwc;
DBGPRINT(( DBG_SS_CERTOCMI, "OC_INIT_COMPONENT(%ws, %p)\n", pwszComponent, pInitComponent));
hr = CoInitialize(NULL); if (S_OK != hr && S_FALSE != hr) { _JumpError(hr, error, "CoInitialize"); } fCoInit = TRUE; *pulpRet = ERROR_CANCELLED;
if (OCMANAGER_VERSION <= pInitComponent->OCManagerVersion) { pInitComponent->OCManagerVersion = OCMANAGER_VERSION; }
// Allocate a new component string.
pComp->pwszComponent = (WCHAR *) LocalAlloc(LPTR, (wcslen(pwszComponent) + 1) * sizeof(WCHAR)); _JumpIfOutOfMemory(hr, error, pComp->pwszComponent);
wcscpy(pComp->pwszComponent, pwszComponent);
// OCM passes in some information that we want to save, like the open
// handle to our per-component INF. As long as we have a per-component INF,
// append-open any layout file that is associated with it, in preparation
// for later inf-based file queueing operations.
//
// We save away certain other stuff that gets passed to us now, since OCM
// doesn't guarantee that the SETUP_INIT_COMPONENT will persist beyond the
// processing of this one interface routine.
if (INVALID_HANDLE_VALUE != pInitComponent->ComponentInfHandle && NULL != pInitComponent->ComponentInfHandle) { pComp->MyInfHandle = pInitComponent->ComponentInfHandle; } else { hr = E_INVALIDARG; _JumpError(hr, error, "invalid inf handle"); }
if (NULL != pComp->MyInfHandle) { if (!SetupOpenAppendInfFile(NULL, pComp->MyInfHandle, NULL)) { // SetupOpenAppendInfFile:
// If Filename (Param1) is NULL, the INF filename is
// retrieved from the LayoutFile value of the Version
// section in the existing INF file.
//
// If FileName was not specified and there was no
// LayoutFile value in the Version section of the
// existing INF File, GetLastError returns ERROR_INVALID_DATA.
hr = myHLastError(); _PrintErrorStr(hr, "SetupOpenAppendInfFile", pwszComponent); } }
pComp->HelperRoutines = pInitComponent->HelperRoutines;
pComp->Flags = pInitComponent->SetupData.OperationFlags;
pwc = awc; pwc += wsprintf(pwc, L"0x"); if (0 != (DWORD) (pComp->Flags >> 32)) { pwc += wsprintf(pwc, L"%x:", (DWORD) (pComp->Flags >> 32)); } wsprintf(pwc, L"%08x", (DWORD) pComp->Flags); CSILOG(S_OK, IDS_LOG_OPERATIONFLAGS, awc, NULL, NULL); CSILOGDWORD(IDS_LOG_POSTBASE, pComp->fPostBase);
hr = RegOpenKey(HKEY_LOCAL_MACHINE, wszREGKEYOCMSUBCOMPONENTS, &hkey); if (S_OK == hr) { DWORD dwType; DWORD dwValue; DWORD cb; DWORD const *pdw; cb = sizeof(dwValue); hr = RegQueryValueEx( hkey, wszSERVERSECTION, 0, &dwType, (BYTE *) &dwValue, &cb); pdw = NULL; if (S_OK == hr && REG_DWORD == dwType && sizeof(dwValue) == cb) { pdw = &dwValue; } CSILOG(hr, IDS_LOG_REGSTATE, wszSERVERSECTION, NULL, pdw); cb = sizeof(dwValue); hr = RegQueryValueEx( hkey, wszCLIENTSECTION, 0, &dwType, (BYTE *) &dwValue, &cb); pdw = NULL; if (S_OK == hr && REG_DWORD == dwType && sizeof(dwValue) == cb) { pdw = &dwValue; } CSILOG(hr, IDS_LOG_REGSTATE, wszCLIENTSECTION, NULL, pdw); cb = sizeof(dwValue); hr = RegQueryValueEx( hkey, wszOLDDOCCOMPONENT, 0, &dwType, (BYTE *) &dwValue, &cb); pdw = NULL; if (S_OK == hr && REG_DWORD == dwType && sizeof(dwValue) == cb) { CSILOG(hr, IDS_LOG_REGSTATE, wszOLDDOCCOMPONENT, NULL, &dwValue); } }
pComp->fUnattended = (pComp->Flags & SETUPOP_BATCH)? TRUE : FALSE; CSILOG( S_OK, IDS_LOG_UNATTENDED, pComp->fUnattended? pInitComponent->SetupData.UnattendFile : NULL, NULL, (DWORD const *) &pComp->fUnattended);
if (pComp->fUnattended) { pComp->pwszUnattendedFile = (WCHAR *) LocalAlloc( LMEM_FIXED, (wcslen(pInitComponent->SetupData.UnattendFile) + 1) * sizeof(WCHAR)); _JumpIfOutOfMemory(hr, error, pComp->pwszUnattendedFile);
wcscpy( pComp->pwszUnattendedFile, pInitComponent->SetupData.UnattendFile); }
// initialize ca setup data
hr = InitCASetup(hwnd, pComp); _JumpIfError(hr, error, "InitCASetup");
hr = S_OK; *pulpRet = NO_ERROR;
error: if (NULL != hkey) { RegCloseKey(hkey); } if (fCoInit) { CoUninitialize(); } return(hr); }
HRESULT certocmReadInfString( IN HINF hInf, IN WCHAR const *pwszSection, IN WCHAR const *pwszName, IN OUT WCHAR **ppwszValue) { INFCONTEXT InfContext; HRESULT hr; WCHAR wszBuffer[cwcINFVALUE]; WCHAR *pwsz;
if (NULL != *ppwszValue) { // free old
LocalFree(*ppwszValue); *ppwszValue = NULL; }
if (!SetupFindFirstLine(hInf, pwszSection, pwszName, &InfContext)) { hr = myHLastError(); _JumpErrorStr(hr, error, "SetupFindFirstLine", pwszSection); } if (!SetupGetStringField( &InfContext, 1, wszBuffer, sizeof(wszBuffer)/sizeof(wszBuffer[0]), NULL)) { hr = myHLastError(); _JumpErrorStr(hr, error, "SetupGetStringField", pwszName); }
pwsz = (WCHAR *) LocalAlloc( LMEM_FIXED, (wcslen(wszBuffer) + 1) * sizeof(WCHAR)); _JumpIfOutOfMemory(hr, error, pwsz);
wcscpy(pwsz, wszBuffer); *ppwszValue = pwsz;
hr = S_OK; error: return(hr); }
HRESULT certocmReadInfInteger( IN HINF hInf, OPTIONAL IN WCHAR const *DBGPARMREFERENCED(pwszFile), IN WCHAR const *pwszSection, IN WCHAR const *pwszName, OUT INT *pValue) { INFCONTEXT InfContext; HRESULT hr = S_OK;
*pValue = 0; if (!SetupFindFirstLine(hInf, pwszSection, pwszName, &InfContext)) { hr = myHLastError(); DBGPRINT(( DBG_SS_CERTOCMI, __FILE__ "(%u): %ws%wsSetupFindFirstLine([%ws] %ws) failed! -> %x\n", __LINE__, NULL != pwszFile? pwszFile : L"", NULL != pwszFile? L": " : L"", pwszSection, pwszName, hr)); goto error; }
if (!SetupGetIntField(&InfContext, 1, pValue)) { hr = myHLastError(); DBGPRINT(( DBG_SS_CERTOCM, __FILE__ "(%u): %ws%wsSetupGetIntField([%ws] %ws) failed! -> %x\n", __LINE__, NULL != pwszFile? pwszFile : L"", NULL != pwszFile? L": " : L"", pwszSection, pwszName, hr)); goto error; } DBGPRINT(( DBG_SS_CERTOCMI, "%ws%ws[%ws] %ws = %u\n", NULL != pwszFile? pwszFile : L"", NULL != pwszFile? L": " : L"", pwszSection, pwszName, *pValue)); error: return(hr); }
// Return the GDI handle of a small bitmap to be used. NULL means an error
// occurred -- OCM will use a default bitmap.
//
// Demonstrates use of private data in a per-component inf. We will look in
// our per-component inf to determine the resource name for the bitmap for this
// component, and then go fetch it from the resources.
//
// Other possibilities would be to simply return the same hbitmap for all
// cases, or to return NULL, in which case OCM uses a default. Note that we
// ignore the requested width and height and our bitmaps are not language
// dependent.
HRESULT certocmOcQueryImage( IN WCHAR const *DBGPARMREFERENCED(pwszComponent), OPTIONAL IN WCHAR const *DBGPARMREFERENCED(pwszSubComponent), IN SubComponentInfo wSubComp, IN UINT DBGPARMREFERENCED(wWidth), IN UINT DBGPARMREFERENCED(wHeight), IN OUT PER_COMPONENT_DATA *pComp, OUT HBITMAP *pulpRet) { HBITMAP hRet = NULL; HRESULT hr;
DBGPRINT(( DBG_SS_CERTOCMI, "OC_QUERY_IMAGE(%ws, %ws, %hx, %x, %x)\n", pwszComponent, pwszSubComponent, wSubComp, wWidth, wHeight));
if (SubCompInfoSmallIcon != wSubComp) { goto done; }
hRet = LoadBitmap(pComp->hInstance, MAKEINTRESOURCE(IDB_APP)); if (NULL == hRet) { hr = myHLastError(); _JumpError(hr, error, "LoadBitmap"); }
done: hr = S_OK;
error: *pulpRet = hRet; return hr; }
// Return the number of wizard pages the current component places in the
// SETUP_REQUEST_PAGES structure.
HRESULT certocmOcRequestPages( IN WCHAR const *DBGPARMREFERENCED(pwszComponent), IN WizardPagesType WizPagesType, IN OUT SETUP_REQUEST_PAGES *pRequestPages, IN PER_COMPONENT_DATA *pComp, OUT ULONG_PTR *pulpRet) { HRESULT hr;
*pulpRet = 0;
DBGPRINT(( DBG_SS_CERTOCMI, "OC_REQUEST_PAGES(%ws, %x, %p)\n", pwszComponent, WizPagesType, pRequestPages));
// don't invoke wiz apge if unattended
// or if running from base setup/upgrade setup
if ((!pComp->fUnattended) && (SETUPOP_STANDALONE & pComp->Flags)) { *pulpRet = myDoPageRequest(pComp, WizPagesType, pRequestPages); } else { DBGPRINT(( DBG_SS_CERTOCMI, "Not adding wizard pages, %ws\n", pComp->fUnattended? L"Unattended" : L"GUI Setup"));
} hr = S_OK; //error:
return hr; }
HRESULT IsIA5DnsMachineName() { WCHAR *pwszDnsName = NULL; CRL_DIST_POINTS_INFO CRLDistInfo; CRL_DIST_POINT DistPoint; CERT_ALT_NAME_ENTRY AltNameEntry; BYTE *pbEncoded = NULL; DWORD cbEncoded; static HRESULT s_hr = S_FALSE;
if (S_FALSE != s_hr) { goto error; } s_hr = myGetMachineDnsName(&pwszDnsName); _JumpIfError(s_hr, error, "myGetMachineDnsName");
CRLDistInfo.cDistPoint = 1; CRLDistInfo.rgDistPoint = &DistPoint;
ZeroMemory(&DistPoint, sizeof(DistPoint)); DistPoint.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; DistPoint.DistPointName.FullName.cAltEntry = 1; DistPoint.DistPointName.FullName.rgAltEntry = &AltNameEntry;
ZeroMemory(&AltNameEntry, sizeof(AltNameEntry)); AltNameEntry.dwAltNameChoice = CERT_ALT_NAME_URL; AltNameEntry.pwszURL = pwszDnsName;
if (!myEncodeObject( X509_ASN_ENCODING, X509_CRL_DIST_POINTS, &CRLDistInfo, 0, CERTLIB_USE_LOCALALLOC, &pbEncoded, &cbEncoded)) { s_hr = myHLastError(); _JumpIfError(s_hr, error, "myEncodeObject"); } CSASSERT(S_OK == s_hr);
error: if (NULL != pwszDnsName) { LocalFree(pwszDnsName); } if (NULL != pbEncoded) { LocalFree(pbEncoded); } return(s_hr); }
// Return boolean to indicate whether to allow selection state change. As
// demonstrated, again we'll go out to our per-component inf to see whether it
// wants us to validate. Note that unattended mode must be respected.
HRESULT certocmOcQueryChangeSelState( HWND hwnd, IN WCHAR const *pwszComponent, OPTIONAL IN WCHAR const *pwszSubComponent, IN BOOL fSelectedNew, IN DWORD Flags, IN OUT PER_COMPONENT_DATA *pComp, OUT ULONG_PTR *pulpRet) { INT fVerify; TCHAR wszText[cwcMESSAGETEXT]; const WCHAR* Args[2]; SUBCOMP const *psc; HRESULT hr; WCHAR awc[cwcDWORDSPRINTF]; WCHAR awc2[cwcDWORDSPRINTF]; DWORD fRet; BOOL fServerWasInstalled; BOOL fWebClientWasInstalled; int iMsg = 0; static BOOL s_fWarned = FALSE;
*pulpRet = FALSE;
DBGPRINT(( DBG_SS_CERTOCMI, "OC_QUERY_CHANGE_SEL_STATE(%ws, %ws, %x, %x)\n", pwszComponent, pwszSubComponent, fSelectedNew, Flags));
// disallow some selection changes
fServerWasInstalled = certocmWasEnabled(pComp, cscServer); fWebClientWasInstalled = certocmWasEnabled(pComp, cscClient);
if (fWebClientWasInstalled && (OCQ_ACTUAL_SELECTION & Flags)) { if (fSelectedNew) { // check
if (!fServerWasInstalled && (0 == LSTRCMPIS(pwszSubComponent, wszSERVERSECTION) || 0 == LSTRCMPIS(pwszSubComponent, wszCERTSRVSECTION)) ) { // case: web client installed and try install server
iMsg = IDS_WRN_UNINSTALL_CLIENT; } if (fServerWasInstalled && 0 == LSTRCMPIS(pwszSubComponent, wszCLIENTSECTION)) { // case: uncheck both then check web client
iMsg = IDS_WRN_UNINSTALL_BOTH; } } else { // uncheck
if (fServerWasInstalled && 0 == LSTRCMPIS(pwszSubComponent, wszSERVERSECTION)) { // case: full certsrv installed and try leave only web client
iMsg = IDS_WRN_UNINSTALL_BOTH; } } }
// not a server sku
if (!FIsServer()) { iMsg = IDS_WRN_SERVER_ONLY; }
if (0 != iMsg) { CertWarningMessageBox( pComp->hInstance, pComp->fUnattended, hwnd, iMsg, 0, NULL); goto done; }
if (fSelectedNew) { hr = IsIA5DnsMachineName(); if (S_OK != hr) { CertMessageBox( pComp->hInstance, pComp->fUnattended, hwnd, IDS_ERR_NONIA5DNSNAME, hr, MB_OK | MB_ICONERROR, NULL); goto done; } if ((OCQ_ACTUAL_SELECTION & Flags) && 0 != LSTRCMPIS(pwszSubComponent, wszCLIENTSECTION)) { if (!s_fWarned) { DWORD dwSetupStatus;
hr = GetSetupStatus(NULL, &dwSetupStatus); if (S_OK == hr) { if ((SETUP_CLIENT_FLAG | SETUP_SERVER_FLAG) & dwSetupStatus) { s_fWarned = TRUE; } CSILOG( hr, IDS_LOG_QUERYCHANGESELSTATE, NULL, NULL, &dwSetupStatus); } } if (!s_fWarned) { if (IDYES != CertMessageBox( pComp->hInstance, pComp->fUnattended, hwnd, IDS_WRN_NONAMECHANGE, S_OK, MB_YESNO | MB_ICONWARNING | CMB_NOERRFROMSYS, NULL)) { goto done; } s_fWarned = TRUE; } } }
*pulpRet = TRUE;
if (pComp->fUnattended) { goto done; }
psc = TranslateSubComponent(pwszComponent, pwszSubComponent); if (NULL == psc) { hr = E_INVALIDARG; _JumpError(hr, error, "Internal error: unsupported component"); }
hr = certocmReadInfInteger( pComp->MyInfHandle, NULL, psc->pwszSubComponent, fSelectedNew? wszVERIFYSELECT : wszVERIFYDESELECT, &fVerify); if (S_OK != hr || !fVerify) { goto done; }
// Don't pass specific lang id to FormatMessage, as it fails if there's no
// msg in that language. Instead, set the thread locale, which will get
// FormatMessage to use a search algorithm to find a message of the
// appropriate language, or use a reasonable fallback msg if there's none.
Args[0] = pwszComponent; Args[1] = pwszSubComponent;
FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY, pComp->hInstance, fSelectedNew? MSG_SURE_SELECT : MSG_SURE_DESELECT, 0, wszText, sizeof(wszText)/sizeof(wszText[0]), (va_list *) Args);
*pulpRet = (IDYES == CertMessageBox( pComp->hInstance, pComp->fUnattended, hwnd, 0, S_OK, MB_YESNO | MB_ICONWARNING | MB_TASKMODAL | CMB_NOERRFROMSYS, wszText));
done: hr = S_OK;
error: wsprintf(awc, L"%u", fSelectedNew); wsprintf(awc2, L"0x%08x", Flags); fRet = (DWORD) *pulpRet; CSILOG(hr, IDS_LOG_QUERYCHANGESELSTATE, awc, awc2, &fRet); return hr; }
// Calculate disk space for the component being added or removed. Return a
// Win32 error code indicating outcome. In our case the private section for
// this component/subcomponent pair is a simple standard inf install section,
// so we can use high-level disk space list API to do what we want.
HRESULT certocmOcCalcDiskSpace( IN WCHAR const *pwszComponent, OPTIONAL IN WCHAR const *pwszSubComponent, IN BOOL fAddComponent, IN HDSKSPC hDiskSpace, IN OUT PER_COMPONENT_DATA *pComp, OUT ULONG_PTR *pulpRet) { HRESULT hr; WCHAR *pwsz = NULL; SUBCOMP const *psc; static fServerFirstCall = TRUE; static fClientFirstCall = TRUE;
DBGPRINT(( DBG_SS_CERTOCMI, "OC_CALC_DISK_SPACE(%ws, %ws, %x, %p)\n", pwszComponent, pwszSubComponent, fAddComponent, hDiskSpace));
psc = TranslateSubComponent(pwszComponent, pwszSubComponent); if (NULL == psc) { hr = E_INVALIDARG; _JumpError(hr, error, "Internal error: unsupported component"); }
// Being installed or uninstalled. Fetch INSTALL section name,
// so we can add or remove the files being INSTALLed from the disk
// space list.
hr = certocmReadInfString( pComp->MyInfHandle, psc->pwszSubComponent, wszINSTALL, &pwsz); _JumpIfError(hr, error, "certocmReadInfString");
if (fAddComponent) // Adding
{ if (!SetupAddInstallSectionToDiskSpaceList( hDiskSpace, pComp->MyInfHandle, NULL, pwsz, 0, 0)) { hr = myHLastError(); _JumpErrorStr(hr, error, "SetupAddInstallSectionToDiskSpaceList", pwsz); } } else // Removing
{ if (!SetupRemoveInstallSectionFromDiskSpaceList( hDiskSpace, pComp->MyInfHandle, NULL, pwsz, 0, 0)) { hr = myHLastError(); _JumpErrorStr(hr, error, "SetupRemoveInstallSectionFromDiskSpaceList", pwsz); } } hr = S_OK;
error: if (NULL != pwsz) { LocalFree(pwsz); } *pulpRet = hr; return(hr); }
// OCM calls this routine when ready for files to be copied to effect the
// changes the user requested. The component DLL must figure out whether it is
// being installed or uninstalled and take appropriate action. For this
// sample, we look in the private data section for this component/subcomponent
// pair, and get the name of an uninstall section for the uninstall case.
//
// Note that OCM calls us once for the *entire* component and then once per
// subcomponent. We ignore the first call.
//
// Return value is Win32 error code indicating outcome.
HRESULT certocmOcQueueFileOps( IN HWND hwnd, IN WCHAR const *pwszComponent, OPTIONAL IN WCHAR const *pwszSubComponent, IN HSPFILEQ hFileQueue, IN OUT PER_COMPONENT_DATA *pComp, OUT ULONG_PTR *pulpRet) { HRESULT hr; SUBCOMP const *psc; BOOL fRemoveFile = FALSE; // TRUE for uninstall; FALSE for install/upgrade
WCHAR *pwszAction; WCHAR *pwsz = NULL; static BOOL s_fPreUninstall = FALSE; // preuninstall once
DBGPRINT(( DBG_SS_CERTOCMI, "OC_QUEUE_FILE_OPS(%ws, %ws, %p)\n", pwszComponent, pwszSubComponent, hFileQueue));
if (NULL == pwszSubComponent) { // Do no work for top level component
goto done; }
psc = TranslateSubComponent(pwszComponent, pwszSubComponent); if (NULL == psc) { hr = E_INVALIDARG; _JumpError(hr, error, "Internal error: unsupported component"); }
// if unattended, not upgrade, & not uninstall, load
if (pComp->fUnattended && !(pComp->Flags & SETUPOP_NTUPGRADE) ) { // retrieve unattended attributes
hr = certocmRetrieveUnattendedText( pwszComponent, pwszSubComponent, pComp); if (S_OK != hr && 0x0 != (pComp->Flags & SETUPOP_STANDALONE)) { // only error out if it is from add/remove or post because
// it could fail regular ntbase in unattended mode without certsrv
_JumpError(hr, error, "certocmRetrieveUnattendedText"); }
// Init install status (must be done after retrieving unattended text)
hr = UpdateSubComponentInstallStatus(pwszComponent, pwszSubComponent, pComp);
_JumpIfError(hr, error, "UpdateSubComponentInstallStatus");
if (psc->fInstallUnattend) // make sure ON
{ if (certocmWasEnabled(pComp, psc->cscSubComponent) && !pComp->fPostBase) { // the case to run install with component ON twice or more
hr = HRESULT_FROM_WIN32(ERROR_INVALID_STATE); _JumpError(hr, error, "You must uninstall before install"); } if (SETUPOP_STANDALONE & pComp->Flags) { // only prepare and validate unattende attr in standalone mode
// in other word, don't call following if NT base
hr = PrepareUnattendedAttributes( hwnd, pwszComponent, pwszSubComponent, pComp); _JumpIfError(hr, error, "PrepareUnattendedAttributes"); } } } else { // Initialize the install status
hr = UpdateSubComponentInstallStatus(pwszComponent, pwszSubComponent, pComp);
_JumpIfError(hr, error, "UpdateSubComponentInstallStatus"); }
// If we're not doing base setup or an upgrade, check to see if we already
// copied files during base setup, by checking to see if base setup
// left an entry in the ToDo List.
if(pComp->fPostBase) {
DBGPRINT(( DBG_SS_CERTOCMI, "File Queueing Skipped, files already installed by GUI setup")); goto done;
}
/*
//--- Talk with OCM guys and put this functionality into a notification routine
//--- This will allow us to pop compatibility error to user before unattended upgrade begins
// detect illegal upgrade
if (pComp->dwInstallStatus & IS_SERVER_UPGRADE) { hr = DetermineServerUpgradePath(pComp); _JumpIfError(hr, error, "DetermineServerUpgradePath"); } else if (pComp->dwInstallStatus & IS_CLIENT_UPGRADE) { hr = DetermineClientUpgradePath(pComp); _JumpIfError(hr, error, "LoadAndDetermineClientUpgradeInfo"); } if ((pComp->dwInstallStatus & IS_SERVER_UPGRADE) || (pComp->dwInstallStatus & IS_CLIENT_UPGRADE)) { // block if attempting upgrade that is not Win2K or Whistler
// lodge a complaint in the log; upgrade all bits and
if ((CS_UPGRADE_NO != pComp->UpgradeFlag) && (CS_UPGRADE_WHISTLER != pComp->UpgradeFlag) && (CS_UPGRADE_WIN2000 != pComp->UpgradeFlag)) { hr = HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION); CertErrorMessageBox( pComp->hInstance, pComp->fUnattended, hwnd, IDS_ERR_UPGRADE_NOT_SUPPORTED, hr, NULL); // _JumpError(hr, error, "Unsupported upgrade");
// continue uninstall/reinstall
} } */
if ((pComp->dwInstallStatus & psc->ChangeFlags) || (pComp->dwInstallStatus & psc->UpgradeFlags) ) {
// for ChangeFlags, either install or uninstall
// all cases, copy file or remove file
if (pComp->dwInstallStatus & psc->UninstallFlags) { fRemoveFile = TRUE; }
// Uninstall the core if:
// this subcomponent is being uninstalled, and
// this is a core subcomponent (client or server), and
// this is the server subcomponent, or the server isn't being removed or
// upgrade
if (((pComp->dwInstallStatus & psc->UninstallFlags) || (pComp->dwInstallStatus & psc->UpgradeFlags) ) && (cscServer == psc->cscSubComponent || !(IS_SERVER_REMOVE & pComp->dwInstallStatus) ) ) { // if fall into here, either need to overwrite or
// delete certsrv files so unreg all related dlls
if (cscServer == psc->cscSubComponent && (pComp->dwInstallStatus & psc->UpgradeFlags) ) { // if this is server upgrade, determine upgrade path
hr = DetermineServerUpgradePath(pComp); _JumpIfError(hr, error, "DetermineServerUpgradePath");
// determine custom policy module
hr = DetermineServerCustomModule( pComp, TRUE); // policy
_JumpIfError(hr, error, "DetermineServerCustomModule");
// determine custom exit module
hr = DetermineServerCustomModule( pComp, FALSE); // exit
_JumpIfError(hr, error, "DetermineServerCustomModule"); }
if (!s_fPreUninstall) { hr = PreUninstallCore(hwnd, pComp); _JumpIfError(hr, error, "PreUninstallCore"); s_fPreUninstall = TRUE; } }
if ((pComp->dwInstallStatus & psc->ChangeFlags) || (pComp->dwInstallStatus & psc->UpgradeFlags) ) { // Being installed or uninstalled.
// Fetch [un]install/upgrade section name.
if (pComp->dwInstallStatus & psc->InstallFlags) { pwszAction = wszINSTALL; } else if (pComp->dwInstallStatus & psc->UninstallFlags) { pwszAction = wszUNINSTALL; } else if (pComp->dwInstallStatus & psc->UpgradeFlags) { pwszAction = wszUPGRADE; } else { hr = E_INVALIDARG; _JumpError(hr, error, "Internal error"); } hr = certocmReadInfString( pComp->MyInfHandle, psc->pwszSubComponent, pwszAction, &pwsz); _JumpIfError(hr, error, "certocmReadInfString");
// If uninstalling, copy files without version checks.
if (!SetupInstallFilesFromInfSection( pComp->MyInfHandle, NULL, hFileQueue, pwsz, NULL, fRemoveFile? 0 : SP_COPY_NEWER)) { hr = myHLastError(); _JumpIfError(hr, error, "SetupInstallFilesFromInfSection"); } } }
done: hr = S_OK; error: if (NULL != pwsz) { LocalFree(pwsz); } if (S_OK != hr) { SetLastError(hr); } *pulpRet = hr; return(hr); }
// OCM calls this routine when it wants to find out how much work the component
// wants to perform for nonfile operations to install/uninstall a component or
// subcomponent. It is called once for the *entire* component and then once
// for each subcomponent in the component. One could get arbitrarily fancy
// here but we simply return 1 step per subcomponent. We ignore the "entire
// component" case.
//
// Return value is an arbitrary 'step' count or -1 if error.
HRESULT certocmOcQueryStepCount( IN WCHAR const *DBGPARMREFERENCED(pwszComponent), OPTIONAL IN WCHAR const *pwszSubComponent, OUT ULONG_PTR *pulpRet) { HRESULT hr;
*pulpRet = 0;
DBGPRINT(( DBG_SS_CERTOCMI, "OC_QUERY_STEP_COUNT(%ws, %ws)\n", pwszComponent, pwszSubComponent));
// Ignore all but "entire component" case.
if (NULL != pwszSubComponent) { goto done; } *pulpRet = SERVERINSTALLTICKS;
done: hr = S_OK; //error:
return hr; }
// OCM calls this routine when it wants the component dll to perform nonfile
// ops to install/uninstall a component/subcomponent. It is called once for
// the *entire* component and then once for each subcomponent in the component.
// Our install and uninstall actions are based on simple standard inf install
// sections. We ignore the "entire component" case. Note how similar this
// code is to the OC_QUEUE_FILE_OPS case.
HRESULT certocmOcCompleteInstallation( IN HWND hwnd, IN WCHAR const *pwszComponent, OPTIONAL IN WCHAR const *pwszSubComponent, IN OUT PER_COMPONENT_DATA *pComp, OUT ULONG_PTR *pulpRet) { HRESULT hr; TCHAR wszBuffer[cwcINFVALUE]; SUBCOMP const *psc; DWORD dwSetupStatusFlags; CASERVERSETUPINFO *pServer = pComp->CA.pServer; WCHAR *pwszActiveCA = NULL; static BOOL fStoppedW3SVC = FALSE;
*pulpRet = 0;
DBGPRINT(( DBG_SS_CERTOCMI, "OC_COMPLETE_INSTALLATION(%ws, %ws)\n", pwszComponent, pwszSubComponent));
// Do no work for top level component
if (NULL == pwszSubComponent) { goto done; }
psc = TranslateSubComponent(pwszComponent, pwszSubComponent); if (NULL == psc) { hr = E_INVALIDARG; _JumpError(hr, error, "Internal error: unsupported component"); }
if (pComp->dwInstallStatus & IS_SERVER_REMOVE) { // for uninstall, check if active ca use DS
hr = myGetCertRegStrValue(NULL, NULL, NULL, wszREGACTIVE, &pwszActiveCA); if (S_OK == hr && NULL != pwszActiveCA) { hr = myGetCertRegDWValue(pwszActiveCA, NULL, NULL, wszREGCAUSEDS, (DWORD*)&pServer->fUseDS); _PrintIfError(hr, "myGetCertRegDWValue"); } }
DBGPRINT(( DBG_SS_CERTOCMI, "certocmOcCompleteInstallation: pComp->dwInstallStatus: %lx, pComp->Flags: %lx\n", pComp->dwInstallStatus, pComp->Flags));
if ((pComp->dwInstallStatus & psc->ChangeFlags) || (pComp->dwInstallStatus & psc->UpgradeFlags) ) { // for unattended, make sure w3svc is stopped before file copy
if (!fStoppedW3SVC && pComp->fUnattended && !(pComp->Flags & SETUPOP_NTUPGRADE) && !(pComp->dwInstallStatus & psc->UninstallFlags) ) { //fStoppedW3SVC makes stop only once
//don't do this in upgrade
// this happens for unattended
// also not during uninstall
hr = StartAndStopService(pComp->hInstance, pComp->fUnattended, hwnd, wszW3SVCNAME, TRUE, FALSE, 0, // doesn't matter since no confirmation
&g_fW3SvcRunning); _PrintIfError(hr, "StartAndStopService"); fStoppedW3SVC = TRUE; }
// certsrv file copy
if (!SetupInstallFromInfSection( NULL, pComp->MyInfHandle, wszBuffer, SPINST_INIFILES | SPINST_REGISTRY, NULL, NULL, 0, NULL, NULL, NULL, NULL)) { hr = myHLastError(); _JumpError(hr, error, "SetupInstallFromInfSection"); }
// Finish uninstalling the core if:
// this subcomponent is being uninstalled, and
// this is a core subcomponent (client or server), and
// this is the server subcomponent, or the server isn't being removed.
if ( (pComp->dwInstallStatus & psc->UninstallFlags) && (cscServer == psc->cscSubComponent || !(IS_SERVER_REMOVE & pComp->dwInstallStatus) ) ) { // Do uninstall work
hr = UninstallCore( hwnd, pComp, 0, 100, certocmPreserving(pComp, cscClient), TRUE, FALSE); _JumpIfError(hr, error, "UninstallCore");
if (certocmPreserving(pComp, cscClient)) { hr = SetSetupStatus(NULL, SETUP_CLIENT_FLAG, TRUE); _JumpIfError(hr, error, "SetSetupStatus"); } else { // unmark all
hr = SetSetupStatus(NULL, 0xFFFFFFFF, FALSE); _JumpIfError(hr, error, "SetSetupStatus"); } }
// Finish installing the core if:
// this subcomponent is being installed, and
// this is a core subcomponent (client or server), and
// this is the server subcomponent, or the server isn't being installed.
// and this is not base setup (we'll do it later if it is)
else if ((pComp->dwInstallStatus & psc->InstallFlags) && (cscServer == psc->cscSubComponent || !(IS_SERVER_INSTALL & pComp->dwInstallStatus)) && (0 != (pComp->Flags & SETUPOP_STANDALONE))) { DBGPRINT(( DBG_SS_CERTOCMI, "Performing standalone server installation\n"));
hr = InstallCore(hwnd, pComp, cscServer == psc->cscSubComponent); _JumpIfError(hr, error, "InstallCore");
// last enough to mark complete
if (pComp->dwInstallStatus & IS_SERVER_INSTALL) { // machine
hr = SetSetupStatus(NULL, SETUP_SERVER_FLAG, TRUE); _JumpIfError(hr, error, "SetSetupStatus");
// ca
hr = SetSetupStatus( pServer->pwszSanitizedName, SETUP_SERVER_FLAG, TRUE); _JumpIfError(hr, error, "SetSetupStatus");
if(IsEnterpriseCA(pServer->CAType)) { hr = SetSetupStatus( pServer->pwszSanitizedName, SETUP_UPDATE_CAOBJECT_SVRTYPE, TRUE); _JumpIfError(hr, error, "SetSetupStatus SETUP_UPDATE_CAOBJECT_SVRTYPE"); }
hr = GetSetupStatus(pServer->pwszSanitizedName, &dwSetupStatusFlags); _JumpIfError(hr, error, "SetSetupStatus");
// Only start the server if:
// 1: we're not waiting for the CA cert to be issued, and
// 2: this is not base setup -- SETUP_STANDALONE means we're
// running from the Control Panel or were manually invoked.
// The server will not start during base setup due to an
// access denied error from JetInit during base setup.
if (0 == (SETUP_SUSPEND_FLAG & dwSetupStatusFlags) && (0 != (SETUPOP_STANDALONE & pComp->Flags))) { hr = StartCertsrvService(FALSE); _PrintIfError(hr, "failed in starting cert server service"); }
// during base setup: f=0 sus=8
DBGPRINT(( DBG_SS_CERTOCMI, "InstallCore: f=%x sus=%x\n", pComp->Flags, dwSetupStatusFlags));
hr = EnableVRootsAndShares(FALSE, FALSE, TRUE, pComp, hwnd);
if(REGDB_E_CLASSNOTREG == hr || HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST) == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) { CertWarningMessageBox( pComp->hInstance, pComp->fUnattended, hwnd, IDS_WRN_IIS_NOT_INSTALLED, 0, NULL); hr = S_OK; } _JumpIfError(hr, error, "failed creating VRoots/shares"); } if (pComp->dwInstallStatus & IS_CLIENT_INSTALL) { hr = SetSetupStatus(NULL, SETUP_CLIENT_FLAG, TRUE); _JumpIfError(hr, error, "SetSetupStatus"); } if ((pComp->dwInstallStatus & IS_SERVER_INSTALL) && (pComp->dwInstallStatus & IS_CLIENT_INSTALL)) { hr = SetSetupStatus( pServer->pwszSanitizedName, SETUP_CLIENT_FLAG, TRUE); _JumpIfError(hr, error, "SetSetupStatus"); }
// in case we're doing a post-base setup,
// we always clear the post-base to-do list
RegDeleteKey(HKEY_LOCAL_MACHINE, wszREGKEYCERTSRVTODOLIST);
} else if ((pComp->dwInstallStatus & psc->InstallFlags) && (cscServer == psc->cscSubComponent || !(IS_SERVER_INSTALL & pComp->dwInstallStatus)) && (0 == (pComp->Flags & (SETUPOP_STANDALONE | SETUPOP_WIN31UPGRADE | SETUPOP_WIN95UPGRADE | SETUPOP_NTUPGRADE) ))) { HKEY hkToDoList = NULL; WCHAR *pwszConfigTitleVal = NULL; WCHAR *pwszArgsValTemp = NULL; WCHAR *pwszArgsVal = wszCONFIGARGSVAL; BOOL fFreeTitle = FALSE; DWORD disp; DWORD err;
DBGPRINT(( DBG_SS_CERTOCMI, "Adding Certificate Services to ToDoList\n"));
// We're installing base, so create
// the ToDoList entry stating that we copied files.
err = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, wszREGKEYCERTSRVTODOLIST, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkToDoList, &disp); hr = HRESULT_FROM_WIN32(err); _JumpIfError(hr, error, "RegCreateKeyEx");
hr = myLoadRCString( g_hInstance, IDS_TODO_TITLE, &pwszConfigTitleVal); if (S_OK == hr) { fFreeTitle = TRUE; } else { // If there was no resource, get something...
pwszConfigTitleVal = wszCONFIGTITLEVAL; }
// config title
err = RegSetValueEx(hkToDoList, wszCONFIGTITLE, 0, REG_SZ, (PBYTE)pwszConfigTitleVal, sizeof(WCHAR)*(wcslen(pwszConfigTitleVal)+1)); hr = HRESULT_FROM_WIN32(err); _PrintIfErrorStr(hr, "RegSetValueEx", wszCONFIGTITLE);
CSILOG(hr, IDS_LOG_TODOLIST, wszCONFIGTITLE, pwszConfigTitleVal, NULL);
// config command
err = RegSetValueEx(hkToDoList, wszCONFIGCOMMAND, 0, REG_SZ, (PBYTE)wszCONFIGCOMMANDVAL, sizeof(WCHAR)*(wcslen(wszCONFIGCOMMANDVAL)+1)); hr = HRESULT_FROM_WIN32(err); _PrintIfErrorStr(hr, "RegSetValueEx", wszCONFIGCOMMAND);
CSILOG(hr, IDS_LOG_TODOLIST, wszCONFIGCOMMAND, wszCONFIGCOMMANDVAL, NULL);
// config args
if (pComp->fUnattended && NULL != pComp->pwszUnattendedFile) { // if nt base is in unattended mode, expand args with
// unattended answer file name
pwszArgsValTemp = (WCHAR*)LocalAlloc(LMEM_FIXED, (wcslen(pwszArgsVal) + wcslen(pComp->pwszUnattendedFile) + 5) * sizeof(WCHAR)); _JumpIfOutOfMemory(hr, error, pwszArgsValTemp);
wcscpy(pwszArgsValTemp, pwszArgsVal); wcscat(pwszArgsValTemp, L" /u:"); wcscat(pwszArgsValTemp, pComp->pwszUnattendedFile); pwszArgsVal = pwszArgsValTemp; } err = RegSetValueEx(hkToDoList, wszCONFIGARGS, 0, REG_SZ, (PBYTE)pwszArgsVal, sizeof(WCHAR)*(wcslen(pwszArgsVal)+1)); hr = HRESULT_FROM_WIN32(err); _PrintIfErrorStr(hr, "RegSetValueEx", wszCONFIGARGS);
CSILOG(hr, IDS_LOG_TODOLIST, wszCONFIGARGS, pwszArgsVal, NULL);
// free stuff
if (NULL != pwszConfigTitleVal && fFreeTitle) { LocalFree(pwszConfigTitleVal); } if (NULL != pwszArgsValTemp) { LocalFree(pwszArgsValTemp); } if (NULL != hkToDoList) { RegCloseKey(hkToDoList); } } else if (pComp->dwInstallStatus & psc->UpgradeFlags) { BOOL fFinishCYS;
hr = CheckPostBaseInstallStatus(&fFinishCYS); _JumpIfError(hr, error, "CheckPostBaseInstallStatus");
// if post mode is true, don't execute setup upgrade path
if (fFinishCYS) { BOOL fServer = FALSE; // upgrade
if (cscServer == psc->cscSubComponent) { hr = UpgradeServer(hwnd, pComp); _JumpIfError(hr, error, "UpgradeServer"); fServer = TRUE; } else if (cscClient == psc->cscSubComponent) { hr = UpgradeClient(hwnd, pComp); _JumpIfError(hr, error, "UpgradeClient"); }
// mark setup status
hr = SetSetupStatus(NULL, psc->SetupStatusFlags, TRUE); _PrintIfError(hr, "SetSetupStatus"); if (fServer) { // ca level
hr = SetSetupStatus( pServer->pwszSanitizedName, psc->SetupStatusFlags, TRUE); _PrintIfError(hr, "SetSetupStatus");
if(IsEnterpriseCA(pServer->CAType)) { hr = SetSetupStatus( pServer->pwszSanitizedName, SETUP_UPDATE_CAOBJECT_SVRTYPE, TRUE); _JumpIfError(hr, error, "SetSetupStatus SETUP_UPDATE_CAOBJECT_SVRTYPE"); } }
if (fServer && pServer->fCertSrvWasRunning) { hr = StartCertsrvService(TRUE); _PrintIfError(hr, "failed in starting cert server service"); } } } }
done: hr = S_OK;
error: if (NULL != pwszActiveCA) { LocalFree(pwszActiveCA); } *pulpRet = hr; return(hr); }
HRESULT certocmOcCommitQueue( IN HWND hwnd, IN WCHAR const *pwszComponent, IN WCHAR const *pwszSubComponent, IN PER_COMPONENT_DATA *pComp) { HRESULT hr; SUBCOMP *pSub; CASERVERSETUPINFO *pServer = pComp->CA.pServer;
DBGPRINT(( DBG_SS_CERTOCMI, "OC_ABOUT_TO_COMMIT_QUEUE(%ws, %ws)\n", pwszComponent, pwszSubComponent));
pSub = TranslateSubComponent(pwszComponent, pwszSubComponent); if (NULL == pSub) { goto done; }
// setup will satrt soon, mark it incomplete
if ((pSub->InstallFlags & pComp->dwInstallStatus) && cscServer == pSub->cscSubComponent) { hr = SetSetupStatus(NULL, pSub->SetupStatusFlags, FALSE); _PrintIfError(hr, "SetSetupStatus"); hr = SetSetupStatus( pServer->pwszSanitizedName, pSub->SetupStatusFlags, FALSE); _PrintIfError(hr, "SetSetupStatus"); }
if ((cscServer == pSub->cscSubComponent) && (pSub->UpgradeFlags & pComp->dwInstallStatus) ) { // upgrade case, no UI, stop existing certsrv
hr = StartAndStopService(pComp->hInstance, pComp->fUnattended, hwnd, wszSERVICE_NAME, TRUE, // stop the service
FALSE, // no confirm
0, //doesn't matter since no confirm
&pServer->fCertSrvWasRunning); _PrintIfError(hr, "ServiceExists"); }
done: hr = S_OK; //error:
return hr; }
// Component dll is being unloaded.
VOID certocmOcCleanup( IN WCHAR const *pwszComponent, IN PER_COMPONENT_DATA *pComp) { DBGPRINT((DBG_SS_CERTOCMI, "OC_CLEANUP(%ws)\n", pwszComponent));
if (NULL != pComp->pwszComponent) { if (0 == mylstrcmpiL(pComp->pwszComponent, pwszComponent)) { FreeCAComponentInfo(pComp); } }
// also free some globals
FreeCAGlobals(); }
/////////////////////////////////////////////////////////////////////////////
//++
//
// certocmOcQueryState
//
// Routine Description:
// This funcion sets the original, current, and final selection states of the
// CertSrv service optional component.
//
// Return Value:
// SubcompOn - indicates that the checkbox should be set
// SubcompOff - indicates that the checkbox should be clear
// SubcompUseOCManagerDefault - OC Manager should set the state of the checkbox
// according to state information that is maintained
// internally by OC Manager itself.
//
// Note:
// By the time this function gets called OnOcInitComponent has already determined
// that Terminal Services is not installed. It is only necessary to determine
// whether Terminal Services is selected for installation.
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT certocmOcQueryState( IN WCHAR const *pwszComponent, OPTIONAL IN WCHAR const *pwszSubComponent, IN DWORD SelectionState, IN PER_COMPONENT_DATA *pComp, OUT ULONG_PTR *pulpRet) { HRESULT hr; SubComponentState stateRet = SubcompUseOcManagerDefault; DWORD status; WCHAR awc[cwcDWORDSPRINTF]; BOOL fFinished;
DBGPRINT(( DBG_SS_CERTOCMI, "OC_QUERY_STATE(%ws, %ws, %x)\n", pwszComponent, pwszSubComponent, SelectionState));
if (NULL == pwszSubComponent) { goto done; }
switch(SelectionState) { case OCSELSTATETYPE_ORIGINAL: { // check to see if the post link exist
hr = CheckPostBaseInstallStatus(&fFinished); _JumpIfError(hr, error, "CheckPostBaseInstallStatus");
if (!pComp->fPostBase && (SETUPOP_STANDALONE & pComp->Flags) ) { // install through Components button
if (!fFinished) { // don't honor local reg SetupStatus
break; } }
// Return the initial installation state of the subcomponent
if (!pComp->fPostBase && ((SETUPOP_STANDALONE & pComp->Flags) || (SETUPOP_NTUPGRADE & pComp->Flags)) ) { //there is chance for user installed certsrv during base setup
//and then upgrade without finishing CYS
if (fFinished) { // If this is an upgrade or a standalone, query the registry to
// get the current installation status
// XTAN, 7/99
// currently certsrv_server has Needs relationship with
// certsrv_client. OCM gathers success for certsrv_client before
// certsrv_server is complete so we don't trust OCM state info
// about certsrv_client and we check our reg SetupStatus here.
// our certsrv_server Needs define is incorrect. If we take it
// out, we probably don't need to reg SetupStatus at
// Configuration level at all and we can trust OCM state info
hr = GetSetupStatus(NULL, &status); if (S_OK == hr) { if ( (0 == LSTRCMPIS(pwszSubComponent, wszSERVERSECTION) && !(SETUP_SERVER_FLAG & status)) || (0 == LSTRCMPIS(pwszSubComponent, wszCLIENTSECTION) && !(SETUP_CLIENT_FLAG & status)) ) { // overwrite OCM default
stateRet = SubcompOff; } } } } break; } case OCSELSTATETYPE_CURRENT: { break; }
case OCSELSTATETYPE_FINAL: { SUBCOMP const *psc; BOOL fWasEnabled;
if (S_OK != pComp->hrContinue && !pComp->fUnattended) { stateRet = SubcompOff; }
//get component install info
psc = TranslateSubComponent(pwszComponent, pwszSubComponent); if (NULL == psc) { hr = E_INVALIDARG; _JumpError(hr, error, "Internal error: unsupported component"); } fWasEnabled = certocmWasEnabled(pComp, psc->cscSubComponent);
// after all of this, change upgrade->uninstall if not supported
if ((SETUPOP_NTUPGRADE & pComp->Flags) && fWasEnabled) { CSASSERT(pComp->UpgradeFlag != CS_UPGRADE_UNKNOWN); if (CS_UPGRADE_UNSUPPORTED == pComp->UpgradeFlag) stateRet = SubcompOff; }
break; } }
done: hr = S_OK; error: wsprintf(awc, L"%u", SelectionState); CSILOG(S_OK, IDS_LOG_SELECTIONSTATE, awc, NULL, (DWORD const *) &stateRet); *pulpRet = stateRet; return(hr); }
//+------------------------------------------------------------------------
//
// Function: CertSrvOCProc( . . . . )
//
// Synopsis: Service procedure for Cert Server OCM Setup.
//
// Arguments: [pwszComponent]
// [pwszSubComponent]
// [Function]
// [Param1]
// [Param2]
//
// Returns: DWORD
//
// History: 04/07/97 JerryK Created
//
//-------------------------------------------------------------------------
ULONG_PTR CertSrvOCProc( IN WCHAR const *pwszComponent, IN WCHAR const *pwszSubComponent, IN UINT Function, IN UINT_PTR Param1, IN OUT VOID *Param2) { ULONG_PTR ulpRet = 0; WCHAR const *pwszFunction = NULL; BOOL fReturnErrCode = TRUE; DWORD ErrorLine;
__try { switch (Function) { // OC_PREINITIALIZE:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = CHAR top level component string
// Param1 = char width flags
// Param2 = unused
//
// Return code is char width allowed flags
case OC_PREINITIALIZE: csiLogOpen("+certocm.log"); CSILOGFILEVERSION(0, L"certocm.dll", szCSVER_STR);
pwszFunction = L"OC_PREINITIALIZE"; fReturnErrCode = FALSE;
// Make sure IDS_LOG_BEGIN & IDS_LOG_END see a Unicode string:
pwszSubComponent = pwszComponent;
CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_PREINITIALIZE");
g_Comp.hrContinue = myInfOpenFile(NULL, &g_Comp.hinfCAPolicy, &ErrorLine); if(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == g_Comp.hrContinue) { g_Comp.hrContinue = S_OK; } _LeaveIfError(g_Comp.hrContinue, "myInfOpenFile");
g_Comp.hrContinue = certocmOcPreInitialize( pwszComponent, (UINT)Param1, //cast to UINT, use as flags
&ulpRet); _PrintIfError(g_Comp.hrContinue, "certocmOcPreInitialize"); break;
// OC_INIT_COMPONENT:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = unused
// Param1 = unused
// Param2 = points to IN OUT SETUP_INIT_COMPONENT structure
//
// Return code is Win32 error indicating outcome.
case OC_INIT_COMPONENT: pwszFunction = L"OC_INIT_COMPONENT"; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_INIT_COMPONENT");
g_Comp.hrContinue = certocmOcInitComponent( NULL, // probably have to pass null hwnd
pwszComponent, (SETUP_INIT_COMPONENT *) Param2, &g_Comp, &ulpRet); _PrintIfError(g_Comp.hrContinue, "certocmOcInitComponent"); break;
case OC_SET_LANGUAGE: pwszFunction = L"OC_SET_LANGUAGE"; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_SET_LANGUAGE"); DBGPRINT(( DBG_SS_CERTOCMI, "OC_SET_LANGUAGE(%ws, %ws, %x, %x)\n", pwszComponent, pwszSubComponent, Param1, Param2)); break;
// OC_QUERY_IMAGE:
//
// obsolete (only called on x86 if IMAGE_EX fails)
// use OC_QUERY_IMAGE_EX instead
//
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = low 16 bits specify image; only small icon supported
// Param2 = low 16 bits = desired width, high 16 bits = desired height
//
// Return value is the GDI handle of a small bitmap to be used.
case OC_QUERY_IMAGE: pwszFunction = L"OC_QUERY_IMAGE"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_QUERY_IMAGE");
g_Comp.hrContinue = certocmOcQueryImage( pwszComponent, pwszSubComponent, (SubComponentInfo) LOWORD(Param1), LOWORD((ULONG_PTR) Param2), HIWORD((ULONG_PTR) Param2), &g_Comp, (HBITMAP*)&ulpRet); _PrintIfError(g_Comp.hrContinue, "certocmOcQueryImage"); break;
// OC_QUERY_IMAGE_EX:
//
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = [in] OC_QUERY_IMAGE_INFO*
// Param2 = [in,out] HBITMAP*
//
// Return value is S_OK or ERROR_CALL_COMPONENT
case OC_QUERY_IMAGE_EX: pwszFunction = L"OC_QUERY_IMAGE_EX"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); { OC_QUERY_IMAGE_INFO *pocQueryImageInfo = (OC_QUERY_IMAGE_INFO *) Param1; g_Comp.hrContinue = certocmOcQueryImage( pwszComponent, pwszSubComponent, pocQueryImageInfo->ComponentInfo, pocQueryImageInfo->DesiredWidth, pocQueryImageInfo->DesiredHeight, &g_Comp, (HBITMAP *) Param2); _PrintIfError(g_Comp.hrContinue, "certocmOcQueryImage"); ulpRet = (S_OK == g_Comp.hrContinue)? TRUE:FALSE; } break;
// OC_REQUEST_PAGES:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = unused
// Param1 = Type of wiz pages being requested (WizardPagesType enum)
// Param2 = points to IN OUT SETUP_REQUEST_PAGES structure
//
// Return value is number of pages the component places in the
// SETUP_REQUEST_PAGES structure.
case OC_REQUEST_PAGES: pwszFunction = L"OC_REQUEST_PAGES"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_REQUEST_PAGES");
g_Comp.hrContinue = certocmOcRequestPages( pwszComponent, (WizardPagesType) Param1, (SETUP_REQUEST_PAGES *) Param2, &g_Comp, &ulpRet); _PrintIfError(g_Comp.hrContinue, "certocmOcRequestPages"); break;
// OC_QUERY_CHANGE_SEL_STATE:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = proposed new sel state; 0 = unselected, non 0 = selected
// Param2 = flags -- OCQ_ACTUAL_SELECTION
//
// Return boolean to indicate whether to allow selection state change
case OC_QUERY_CHANGE_SEL_STATE: pwszFunction = L"OC_QUERY_CHANGE_SEL_STATE"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_QUERY_CHANGE_SEL_STATE");
g_Comp.hrContinue = certocmOcQueryChangeSelState( g_Comp.HelperRoutines.QueryWizardDialogHandle(g_Comp.HelperRoutines.OcManagerContext), pwszComponent, pwszSubComponent, (BOOL) Param1, (DWORD) (ULONG_PTR) Param2, &g_Comp, &ulpRet); _PrintIfError(g_Comp.hrContinue, "certocmOcQueryChangeSelState"); break;
// OC_CALC_DISK_SPACE:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = 0 for removing component or non 0 for adding component
// Param2 = HDSKSPC to operate on
//
// Return value is Win32 error code indicating outcome.
case OC_CALC_DISK_SPACE: pwszFunction = L"OC_CALC_DISK_SPACE"; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_CALC_DISK_SPACE");
g_Comp.hrContinue = certocmOcCalcDiskSpace( pwszComponent, pwszSubComponent, (BOOL) Param1, (HDSKSPC) Param2, &g_Comp, &ulpRet); _PrintIfError(g_Comp.hrContinue, "certocmOcCalcDiskSpace"); break;
// OC_QUEUE_FILE_OPS:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = unused
// Param2 = HSPFILEQ to operate on
//
// Return value is Win32 error code indicating outcome.
case OC_QUEUE_FILE_OPS: pwszFunction = L"OC_QUEUE_FILE_OPS"; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_QUEUE_FILE_OPS");
g_Comp.hrContinue = certocmOcQueueFileOps( g_Comp.HelperRoutines.QueryWizardDialogHandle(g_Comp.HelperRoutines.OcManagerContext), pwszComponent, pwszSubComponent, (HSPFILEQ) Param2, &g_Comp, &ulpRet); _PrintIfError(g_Comp.hrContinue, "certocmOcQueueFileOps"); break;
// Params? xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// OC_NOTIFICATION_FROM_QUEUE:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = unused
// Param1 = unused
// Param2 = unused
//
// Return value is ???
case OC_NOTIFICATION_FROM_QUEUE: pwszFunction = L"OC_NOTIFICATION_FROM_QUEUE"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); DBGPRINT(( DBG_SS_CERTOCMI, "OC_NOTIFICATION_FROM_QUEUE(%ws, %ws, %x, %x)\n", pwszComponent, pwszSubComponent, Param1, Param2)); break;
// OC_QUERY_STEP_COUNT:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = unused
// Param2 = unused
//
// Return value is an arbitrary 'step' count or -1 if error.
case OC_QUERY_STEP_COUNT: pwszFunction = L"OC_QUERY_STEP_COUNT"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_QUERY_STEP_COUNT");
g_Comp.hrContinue = (DWORD) certocmOcQueryStepCount( pwszComponent, pwszSubComponent, &ulpRet); _PrintIfError(g_Comp.hrContinue, "certocmOcQueryStepCount"); break;
// OC_COMPLETE_INSTALLATION:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = reserved for future expansion
// Param2 = unused
//
// Return value is Win32 error code indicating outcome.
case OC_COMPLETE_INSTALLATION: pwszFunction = L"OC_COMPLETE_INSTALLATION"; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_COMPLETE_INSTALLATION");
g_Comp.hrContinue = certocmOcCompleteInstallation( g_Comp.HelperRoutines.QueryWizardDialogHandle(g_Comp.HelperRoutines.OcManagerContext), pwszComponent, pwszSubComponent, &g_Comp, &ulpRet); _PrintIfError(g_Comp.hrContinue, "certocmOcCompleteInstallation"); break;
// OC_CLEANUP:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = unused
// Param1 = unused
// Param2 = unused
//
// Return value is ignored
case OC_CLEANUP: // don't _LeaveIfError(g_Comp.hrContinue, "OC_CLEANUP");
// avoid memory leaks
pwszFunction = L"OC_CLEANUP"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); certocmOcCleanup(pwszComponent, &g_Comp); break;
// Params? xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// OC_QUERY_STATE:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = unused? (but Index Server uses it for current state)!
// Param2 = unused
//
// Return value is from the SubComponentState enumerated type
case OC_QUERY_STATE: pwszFunction = L"OC_QUERY_STATE"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); //don't _LeaveIfError(g_Comp.hrContinue, "OC_QUERY_STATE");
certocmOcQueryState( pwszComponent, pwszSubComponent, (DWORD)Param1, //cast to DWORD, use as flags
&g_Comp, &ulpRet); break;
// Params? xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// OC_NEED_MEDIA:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = unused
// Param2 = unused
//
// Return value is ???
case OC_NEED_MEDIA: pwszFunction = L"OC_NEED_MEDIA"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); DBGPRINT(( DBG_SS_CERTOCMI, "OC_NEED_MEDIA(%ws, %ws, %x, %x)\n", pwszComponent, pwszSubComponent, Param1, Param2)); break;
// OC_ABOUT_TO_COMMIT_QUEUE:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = WCHAR sub-component string
// Param1 = reserved for future expansion
// Param2 = unused
//
// Return value is Win32 error code indicating outcome.
case OC_ABOUT_TO_COMMIT_QUEUE: pwszFunction = L"OC_ABOUT_TO_COMMIT_QUEUE"; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_ABOUT_TO_COMMIT_QUEUE");
g_Comp.hrContinue = certocmOcCommitQueue( g_Comp.HelperRoutines.QueryWizardDialogHandle(g_Comp.HelperRoutines.OcManagerContext), pwszComponent, pwszSubComponent, &g_Comp); _PrintIfError(g_Comp.hrContinue, "certocmOcCommitQueue"); break;
// OC_QUERY_SKIP_PAGE:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = unused
// Param1 = OcManagerPage page indicator
// Param2 = unused
//
// Return value is a boolean -- 0 for display or non 0 for skip
case OC_QUERY_SKIP_PAGE: pwszFunction = L"OC_QUERY_SKIP_PAGE"; fReturnErrCode = FALSE; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); DBGPRINT(( DBG_SS_CERTOCMI, "OC_QUERY_SKIP_PAGE(%ws, %x)\n", pwszComponent, (OcManagerPage) Param1)); _LeaveIfError(g_Comp.hrContinue, "OC_QUERY_SKIP_PAGE");
if (g_Comp.fPostBase && (WizardPagesType) Param1 == WizPagesWelcome) { ulpRet = 1; // non 0 to skip wiz page
} break;
// OC_WIZARD_CREATED:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = ???
// Param1 = ???
// Param2 = ???
//
// Return value is ???
case OC_WIZARD_CREATED: pwszFunction = L"OC_WIZARD_CREATED"; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_WIZARD_CREATED"); break;
// OC_EXTRA_ROUTINES:
// pwszComponent = WCHAR top level component string
// pwszSubComponent = ???
// Param1 = ???
// Param2 = ???
//
// Return value is ???
case OC_EXTRA_ROUTINES: pwszFunction = L"OC_EXTRA_ROUTINES"; CSILOG(g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, NULL); _LeaveIfError(g_Comp.hrContinue, "OC_EXTRA_ROUTINES"); break;
// Some other notification:
default: fReturnErrCode = FALSE; CSILOG( g_Comp.hrContinue, IDS_LOG_BEGIN, pwszFunction, pwszSubComponent, (DWORD const *) &Function); DBGPRINT(( DBG_SS_CERTOCMI, "DEFAULT(0x%x: %ws, %ws, %x, %x)\n", Function, pwszComponent, pwszSubComponent, Param1, Param2)); break; } } __except(ulpRet = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER) { if (S_OK == g_Comp.hrContinue) { g_Comp.hrContinue = (HRESULT)ulpRet; } _PrintError((HRESULT)ulpRet, "Exception"); }
DBGPRINT((DBG_SS_CERTOCMI, "return %p\n", ulpRet));
// make sure to get a pop up in case of fatal error
if (S_OK != g_Comp.hrContinue) { if (!g_Comp.fShownErr) { int iMsgId = g_Comp.iErrMsg; if (0 == iMsgId) { // use generic one
iMsgId = IDS_ERR_CERTSRV_SETUP_FAIL; } CertErrorMessageBox( g_Comp.hInstance, g_Comp.fUnattended, NULL, // null hwnd
iMsgId, g_Comp.hrContinue, g_Comp.pwszCustomMessage); g_Comp.fShownErr = TRUE; } // anything fails, cancel install
HRESULT hr2 = CancelCertsrvInstallation(NULL, &g_Comp); _PrintIfError(hr2, "CancelCertsrvInstallation"); } CSILOG( fReturnErrCode? (HRESULT) ulpRet : S_OK, IDS_LOG_END, pwszFunction, pwszSubComponent, fReturnErrCode? NULL : (DWORD const *) &ulpRet); return(ulpRet); }
ULONG_PTR CertSrvOCPostProc( IN WCHAR const *pwszComponent, IN WCHAR const *pwszSubComponent, IN UINT Function, IN UINT Param1, IN OUT VOID *Param2) { // post setup entry point
// by going through this path, we know it is invoked in post setup
g_Comp.fPostBase = TRUE;
return CertSrvOCProc( pwszComponent, pwszSubComponent, Function, Param1, Param2); }
VOID certocmBumpGasGauge( OPTIONAL IN PER_COMPONENT_DATA *pComp, IN DWORD PerCentComplete DBGPARM(IN WCHAR const *pwszSource)) { static DWORD dwTickCount = 0;
if (NULL != pComp) { DWORD NewCount;
NewCount = (PerCentComplete * SERVERINSTALLTICKS)/100; DBGPRINT(( DBG_SS_CERTOCMI, "certocmBumpGasGauge(%ws, %u%%) %d ticks: %d --> %d\n", pwszSource, PerCentComplete, NewCount - dwTickCount, dwTickCount, NewCount));
if (SERVERINSTALLTICKS < NewCount) { NewCount = SERVERINSTALLTICKS; } while (dwTickCount < NewCount) { (*pComp->HelperRoutines.TickGauge)( pComp->HelperRoutines.OcManagerContext); dwTickCount++; } } }
BOOL certocmEnabledSub( PER_COMPONENT_DATA *pComp, CertSubComponent SubComp, DWORD SelectionStateType) { SUBCOMP const *psc; BOOL bRet = FALSE; psc = LookupSubComponent(SubComp); if (NULL != psc->pwszSubComponent) { if (pComp->fUnattended && OCSELSTATETYPE_CURRENT == SelectionStateType && 0 == (pComp->Flags & SETUPOP_NTUPGRADE) ) { // unattended case, flags from unattended file
// upgrade is automatically in unattended mode and make sure
// to exclude it
bRet = psc->fInstallUnattend; } else { bRet = (*pComp->HelperRoutines.QuerySelectionState)( pComp->HelperRoutines.OcManagerContext, psc->pwszSubComponent, SelectionStateType); } } return(bRet); }
BOOL certocmIsEnabled( PER_COMPONENT_DATA *pComp, CertSubComponent SubComp) { BOOL bRet;
bRet = certocmEnabledSub(pComp, SubComp, OCSELSTATETYPE_CURRENT); if (!fDebugSupress) { DBGPRINT(( DBG_SS_CERTOCMI, "certocmIsEnabled(%ws) Is %ws\n", LookupSubComponent(SubComp)->pwszSubComponent, bRet? L"Enabled" : L"Disabled")); } return(bRet); }
BOOL certocmWasEnabled( PER_COMPONENT_DATA *pComp, CertSubComponent SubComp) { BOOL bRet;
bRet = certocmEnabledSub(pComp, SubComp, OCSELSTATETYPE_ORIGINAL); if (!fDebugSupress) { DBGPRINT(( DBG_SS_CERTOCMI, "certocmWasEnabled(%ws) Was %ws\n", LookupSubComponent(SubComp)->pwszSubComponent, bRet? L"Enabled" : L"Disabled")); } return(bRet); }
BOOL certocmUninstalling( PER_COMPONENT_DATA *pComp, CertSubComponent SubComp) { BOOL bRet;
fDebugSupress++; bRet = certocmWasEnabled(pComp, SubComp) && !certocmIsEnabled(pComp, SubComp); fDebugSupress--; if (!fDebugSupress) { DBGPRINT(( DBG_SS_CERTOCMI, "certocmUninstalling(%ws) %ws\n", LookupSubComponent(SubComp)->pwszSubComponent, bRet? L"TRUE" : L"False")); } return(bRet); }
BOOL certocmInstalling( PER_COMPONENT_DATA *pComp, CertSubComponent SubComp) { BOOL bRet;
fDebugSupress++; bRet = !certocmWasEnabled(pComp, SubComp) && certocmIsEnabled(pComp, SubComp); fDebugSupress--; if (!fDebugSupress) { DBGPRINT(( DBG_SS_CERTOCMI, "certocmInstalling(%ws) %ws\n", LookupSubComponent(SubComp)->pwszSubComponent, bRet? L"TRUE" : L"False")); } return(bRet); }
BOOL certocmPreserving( PER_COMPONENT_DATA *pComp, CertSubComponent SubComp) { BOOL bRet;
fDebugSupress++; bRet = certocmWasEnabled(pComp, SubComp) && certocmIsEnabled(pComp, SubComp); fDebugSupress--; if (!fDebugSupress) { DBGPRINT(( DBG_SS_CERTOCMI, "certocmPreserving(%ws) %ws\n", LookupSubComponent(SubComp)->pwszSubComponent, bRet? L"TRUE" : L"False")); } return(bRet); }
|