Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1770 lines
58 KiB

#include "stdafx.h"
#include "k2suite.h"
#include <ole2.h>
#include "helper.h"
#include "setupapi.h"
#include "ocmanage.h"
#include "utils.h"
#include "log.h"
#include "wizpages.h"
#pragma hdrstop
void CreateNNTPGroups(void);
/*
SETUPMODE_UNKNOWN
SETUPMODE_MINIMAL
SETUPMODE_TYPICAL
SETUPMODE_LAPTOP
SETUPMODE_CUSTOM
SETUPMODE_STANDARD_MASK
SETUPMODE_PRIVATE_MASK
*/
#ifndef UNICODE
#error UNICODE not defined
#endif
OCMANAGER_ROUTINES gHelperRoutines;
HINF gMyInfHandle;
HANDLE gMyModuleHandle;
HANDLE g_hUnattended = INVALID_HANDLE_VALUE;
// Logging class
MyLogFile g_MyLogFile;
TCHAR szSysDrive[3] = _T("C:");
TCHAR szComponentNames[MC_MAXMC][24] =
{
_T("ims"),
_T("ins")
};
TCHAR szSubcomponentNames[SC_MAXSC][24] =
{
_T("iis_smtp"),
_T("iis_nntp"),
_T("iis_smtp_docs"),
_T("iis_nntp_docs")
};
TCHAR szDocComponentNames[2][24] =
{
_T("iis_smtp_docs"),
_T("iis_nntp_docs")
};
TCHAR szActionTypeNames[AT_MAXAT][24] =
{
_T("AT_DO_NOTHING"),
_T("AT_FRESH_INSTALL"),
_T("AT_REINSTALL"),
_T("AT_UPGRADE"),
_T("AT_REMOVE"),
_T("AT_UPGRADEK2")
};
#define NUM_OC_STATES (OC_QUERY_IMAGE_EX + 1)
TCHAR szOCMStates[NUM_OC_STATES][40] =
{
_T("OC_PREINITIALIZE"),
_T("OC_INIT_COMPONENT"),
_T("OC_SET_LANGUAGE"),
_T("OC_QUERY_IMAGE"),
_T("OC_REQUEST_PAGES"),
_T("OC_QUERY_CHANGE_SEL_STATE"),
_T("OC_CALC_DISK_SPACE"),
_T("OC_QUEUE_FILE_OPS"),
_T("OC_NOTIFICATION_FROM_QUEUE"),
_T("OC_QUERY_STEP_COUNT"),
_T("OC_COMPLETE_INSTALLATION"),
_T("OC_CLEANUP"),
_T("OC_QUERY_STATE"),
_T("OC_NEED_MEDIA"),
_T("OC_ABOUT_TO_COMMIT_QUEUE"),
_T("OC_QUERY_SKIP_PAGE"),
_T("OC_WIZARD_CREATED"),
_T("OC_FILE_BUSY "),
_T("OC_EXTRA_ROUTINES"),
_T("OC_QUERY_IMAGE_EX"),
};
LPCTSTR szInstallModes[] = {
_T("IM_FRESH"),
_T("IM_UPGRADE"),
_T("IM_MAINTENANCE"),
_T("IM_DEGRADE"),
_T("IM_UPGRADEK2"), // Upgrade from K2 RTM to NT5
_T("IM_UPGRADEB2"), // Upgrade from NT5 Beta2
_T("IM_UPGRADEB3"), // Upgrade from NT5 Beta3
_T("IM_UPGRADEWKS"), // Upgrade from NT5 Workstation to NT5 Server
_T("IM_UPGRADE10"), // Upgrade from MCIS 1.0 to NT5
_T("IM_UPGRADE20"), // Upgrade from MCIS 2.0 to NT5
};
unsigned MyStepCount;
CInitApp theApp;
DWORD OC_PREINITIALIZE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_INIT_COMPONENT_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_SET_LANGUAGE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
#ifdef _WIN64
DWORD_PTR OC_QUERY_IMAGE_EX_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
#endif
DWORD_PTR OC_QUERY_IMAGE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_REQUEST_PAGES_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_QUERY_STATE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_QUERY_CHANGE_SEL_STATE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_QUERY_SKIP_PAGE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_CALC_DISK_SPACE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_QUEUE_FILE_OPS_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_NEED_MEDIA_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_NOTIFICATION_FROM_QUEUE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_QUERY_STEP_COUNT_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_ABOUT_TO_COMMIT_QUEUE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_COMPLETE_INSTALLATION_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD OC_CLEANUP_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2);
DWORD BringALLIISClusterResourcesOffline(void);
BOOL
WINAPI
DllMain(
IN HANDLE DllHandle,
IN DWORD Reason,
IN LPVOID Reserved
)
/*++
Routine Description:
This routine is called by CRT when _DllMainCRTStartup is the
DLL entry point.
Arguments:
Standard Win32 DLL Entry point parameters.
Return Value:
Standard Win32 DLL Entry point return code.
--*/
{
BOOL b;
UNREFERENCED_PARAMETER(Reserved);
b = TRUE;
switch(Reason) {
case DLL_PROCESS_ATTACH:
gMyModuleHandle = DllHandle;
//
// Fall through to process first thread
//
g_MyLogFile.LogFileCreate(_T("imsins.log"));
case DLL_THREAD_ATTACH:
b = TRUE;
break;
case DLL_PROCESS_DETACH:
g_MyLogFile.LogFileClose();
break;
case DLL_THREAD_DETACH:
break;
}
return(b);
}
DWORD GetComponentFromId(LPCTSTR ComponentId)
{
DWORD i;
if (!ComponentId)
return(MC_NONE);
for (i = 0; i < (DWORD)MC_MAXMC; i++)
if (!lstrcmpi(ComponentId, szComponentNames[i]))
return(i);
return(MC_NONE);
}
DWORD GetSubcomponentFromId(LPCTSTR SubcomponentId)
{
DWORD i;
if (!SubcomponentId)
return(SC_NONE);
for (i = 0; i < (DWORD)SC_MAXSC; i++)
if (!lstrcmpi(SubcomponentId, szSubcomponentNames[i]))
return(i);
return(SC_NONE);
}
ACTION_TYPE GetSubcompActionFromCheckboxState(DWORD Id)
{
DWORD State = 0;
DWORD OldState = 0;
ACTION_TYPE at = AT_DO_NOTHING;
// Get the check box state
State = gHelperRoutines.QuerySelectionState(
gHelperRoutines.OcManagerContext,
szSubcomponentNames[Id],
OCSELSTATETYPE_CURRENT
);
if (GetLastError() != NO_ERROR)
{
DebugOutput(_T("Failed to get current state for <%s> (%u)"),
szSubcomponentNames[Id], GetLastError());
State = 0;
}
// Check orignal state
OldState = gHelperRoutines.QuerySelectionState(
gHelperRoutines.OcManagerContext,
szSubcomponentNames[Id],
OCSELSTATETYPE_ORIGINAL
);
if (GetLastError() != NO_ERROR)
{
DebugOutput(_T("Failed to get original state for <%s> (%u)"),
szSubcomponentNames[Id], GetLastError());
OldState = 0;
}
DebugOutput(_T("GetSubcompActionFromCheckboxState(%s): Old state=%d, state=%d"),
szSubcomponentNames[Id], OldState, State);
if (State && !OldState)
{
// Change in state from OFF->ON = install docs
at = AT_FRESH_INSTALL;
DebugOutput(_T("Installing subcomponent <%s>"), szSubcomponentNames[Id]);
}
else if (!State && OldState)
{
// Change in state from ON->OFF = uninstall docs
at = AT_REMOVE;
DebugOutput(_T("Removing subcomponent <%s>"), szSubcomponentNames[Id]);
}
else if (State && OldState)
{
// Change in state from ON->ON : couple of cases here...
if (theApp.m_eState[Id] == IM_UPGRADE || theApp.m_eState[Id] == IM_UPGRADEK2 || theApp.m_eState[Id] == IM_UPGRADE10 || theApp.m_eState[Id] == IM_UPGRADE20)
{
// Upgrade if we were upgrading...
at = AT_UPGRADE;
DebugOutput(_T("Upgrading subcomponent <%s>"), szSubcomponentNames[Id]);
}
if (GetIMSSetupMode() == IIS_SETUPMODE_REINSTALL || (theApp.m_fNTGuiMode && ((theApp.m_eState[Id] == IM_MAINTENANCE) || (theApp.m_eState[Id] == IM_UPGRADEB2))))
{
// Reinstall if doing minor NT5 os upgrade, both from NT5 Beta2, or NT5 Beta3
at = AT_REINSTALL;
DebugOutput(_T("Reinstalling subcomponent <%s>, %s, IMS Reinstall=%s"), szSubcomponentNames[Id],
szInstallModes[theApp.m_eState[Id]],
(GetIMSSetupMode() == IIS_SETUPMODE_REINSTALL) ? _T("TRUE") : _T("FALSE"));
}
if (!theApp.m_fValidSetupString[Id]) {
at = AT_REINSTALL;
DebugOutput(_T("Reinstalling subcomponent <%s> (Invalid setup string)"), szSubcomponentNames[Id]);
}
}
return(at);
}
BOOL IsSubcomponentCore(DWORD dwSubcomponentId)
{
if (dwSubcomponentId == SC_SMTP || dwSubcomponentId == SC_NNTP)
return TRUE;
return FALSE;
}
STATUS_TYPE GetSubcompInitStatus(DWORD Id)
{
STATUS_TYPE nStatus = ST_UNINSTALLED;
BOOL OriginalState;
if (Id != SC_NONE)
{
OriginalState = gHelperRoutines.QuerySelectionState(
gHelperRoutines.OcManagerContext,
szSubcomponentNames[Id],
OCSELSTATETYPE_ORIGINAL
);
if (OriginalState == 1)
nStatus = ST_INSTALLED;
if (OriginalState == 0)
nStatus = ST_UNINSTALLED;
}
return(nStatus);
}
/*
The subcomponent action is a table-driven value which
is dependent on 3 things:
1) the master install mode
2) the installed state of the subcomponent in question
3) the state of the subcomponent check box
We use the following matrix to determine the action.
Note that an 'x' indicates invalid combinations and
should have been coerced earlier by
CInitApp::DetectPreviousINstallations().
----------------+-----------------------+-----------------------
Check box | 1 | 0
----------------+-----------------------+-----------------------
\ Component | Fresh Upgrade Maint. | Fresh Upgrade Maint.
Global | |
----------------+-----------------------+-----------------------
Fresh | FRESH x x | NOTHING x x
Upgrade | FRESH UPGRADE x | NOTHING NOTHING x
Maintenance | FRESH UPGRADE NOTHING | NOTHING NOTHING REMOVE
----------------+-----------------------+-----------------------
*/
ACTION_TYPE GetSubcompAction(DWORD Id)
{
ACTION_TYPE atReturn = AT_DO_NOTHING;
ACTION_TYPE atSubcomp = GetSubcompActionFromCheckboxState(Id);
DebugOutput(_T("GetSubcompAction(): %s=%s"), szSubcomponentNames[Id], szActionTypeNames[atSubcomp]);
//
// Let's do it the way I thing we should do and modify it
// if errors found.
//
return atSubcomp;
}
void CreateAllRequiredDirectories(DWORD Id)
{
ACTION_TYPE atComp;
// If SMTP is being installed fresh, we need to create
// the Queue, Pickup, Drop, and Badmail directories
if (Id != SC_NNTP)
{
atComp = GetSubcompAction(Id);
if (atComp == AT_FRESH_INSTALL)
{
if (Id == SC_SMTP)
{
CreateLayerDirectory(theApp.m_csPathMailroot + SZ_SMTP_QUEUEDIR);
CreateLayerDirectory(theApp.m_csPathMailroot + SZ_SMTP_BADMAILDIR);
CreateLayerDirectory(theApp.m_csPathMailroot + SZ_SMTP_DROPDIR);
CreateLayerDirectory(theApp.m_csPathMailroot + SZ_SMTP_PICKUPDIR);
CreateLayerDirectory(theApp.m_csPathMailroot + SZ_SMTP_SORTTEMPDIR);
}
CreateLayerDirectory(theApp.m_csPathMailroot + SZ_SMTP_ROUTINGDIR);
CreateLayerDirectory(theApp.m_csPathMailroot + SZ_SMTP_MAILBOXDIR);
}
}
}
LPTSTR szServiceNames[MC_MAXMC] =
{
SZ_SMTPSERVICENAME,
SZ_NNTPSERVICENAME,
};
BOOL GetInetpubPathFromPrivData(CString &csPathInetpub)
{
TCHAR szPath[_MAX_PATH];
UINT uType, uSize;
// If we are not upgrading, we get the info from the private data
uSize = _MAX_PATH * sizeof(TCHAR);
if ((gHelperRoutines.GetPrivateData(gHelperRoutines.OcManagerContext,
_T("iis"),
_T("PathWWWRoot"),
(LPVOID)szPath,
&uSize,
&uType) == NO_ERROR) &&
(uType == REG_SZ))
{
GetParentDir(szPath, csPathInetpub.GetBuffer(512));
csPathInetpub.ReleaseBuffer();
return TRUE;
}
else
return FALSE;
}
void SetupMailAndNewsRoot( void )
{
if (!theApp.m_fMailPathSet)
theApp.m_csPathMailroot = theApp.m_csPathInetpub + _T("\\mailroot");
if (!theApp.m_fNntpPathSet)
{
theApp.m_csPathNntpFile = theApp.m_csPathInetpub + _T("\\nntpfile");
theApp.m_csPathNntpRoot = theApp.m_csPathNntpFile + _T("\\root");
}
}
/* =================================================================
The sequence of OCM Calls are as follows:
OC_PREINITIALIZE
OC_INIT_COMPONENT
OC_SET_LANGUAGE
OC_QUERY_STATE
OC_CALC_DISK_SPACE
OC_REQUEST_PAGES
UI Appears with Welcome, EULA, and mode page
OC_QUERY_STATE
OC_QUERY_SKIP_PAGE
OC Page "Check boxes" appears
OC_QUERY_IMAGE
Detail pages
Wizard pages ...
OC_QUEUE_FILE_OPS
OC_QUERY_STEP_COUNT
OC_ABOUT_TO_COMMIT_QUEUE
OC_NEED_MEDIA (if required)
OC_COMPLETE_INSTALLATION
OC_CLEANUP
*/
// NT5 - Leave the DummyOcEntry there for safeguard
DWORD
DummyOcEntry(
IN LPCTSTR ComponentId,
IN LPCTSTR SubcomponentId,
IN UINT Function,
IN UINT_PTR Param1,
IN OUT PVOID Param2
);
extern "C"
DWORD_PTR
OcEntry(
IN LPCTSTR ComponentId,
IN LPCTSTR SubcomponentId,
IN UINT Function,
IN UINT_PTR Param1,
IN OUT PVOID Param2
)
{
DWORD_PTR d = 0;
DWORD CompId, Id;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
// Set the current top-level component so other functions can access it!
theApp.m_dwCompId = CompId;
// Output some debug information ...
if (Function == OC_PREINITIALIZE || Function == OC_INIT_COMPONENT) {
DebugOutput(
_T("Entering OCEntry; Component = <%s> (%u)"),
ComponentId?ComponentId:_T(""), CompId);
} else {
DebugOutput(
_T("Entering OCEntry; Component = <%s> (%u), Subcomponent = <%s> (%u)"),
ComponentId?ComponentId:_T(""), CompId,
SubcomponentId?SubcomponentId:_T(""), Id);
}
DebugOutput(
_T("\tFunction = %s (%u), Param1 = %08X (%u), Param2 = %p (%p)"),
(Function < NUM_OC_STATES) ? szOCMStates[Function] : _T("unknown state"),
Function,
(DWORD)Param1, (DWORD)Param1,
(DWORD_PTR)Param2, (DWORD_PTR)Param2);
// NT5 - Leave the DummyOcEntry there for safeguard
// HACK for standalone only!!
// We are forced to handle the IIS section for standalone or we'll face an AV
if (CompId == MC_NONE)
{
// Well, we will ignore all master sections that we do not know about.
// This includes the IIS Master section
DebugOutput(_T("Unknown master section, calling DummyOcEntry ..."));
d = DummyOcEntry(ComponentId,
SubcomponentId,
Function,
Param1,
Param2);
DebugOutput(_T("DummyOcEntry returning %u"), d);
return(d);
}
switch(Function)
{
case OC_PREINITIALIZE:
d = OC_PREINITIALIZE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_INIT_COMPONENT:
d = OC_INIT_COMPONENT_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_SET_LANGUAGE:
d = OC_SET_LANGUAGE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
#ifdef _WIN64
case OC_QUERY_IMAGE_EX:
d = OC_QUERY_IMAGE_EX_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
#endif
case OC_QUERY_IMAGE:
d = OC_QUERY_IMAGE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_REQUEST_PAGES:
d = OC_REQUEST_PAGES_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_QUERY_STATE:
d = OC_QUERY_STATE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_QUERY_CHANGE_SEL_STATE:
d = OC_QUERY_CHANGE_SEL_STATE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_QUERY_SKIP_PAGE:
d = OC_QUERY_SKIP_PAGE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_CALC_DISK_SPACE:
d = OC_CALC_DISK_SPACE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_QUEUE_FILE_OPS:
d = OC_QUEUE_FILE_OPS_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_NEED_MEDIA:
d = OC_NEED_MEDIA_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_NOTIFICATION_FROM_QUEUE:
d = OC_NOTIFICATION_FROM_QUEUE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_QUERY_STEP_COUNT:
d = OC_QUERY_STEP_COUNT_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_ABOUT_TO_COMMIT_QUEUE:
d = OC_ABOUT_TO_COMMIT_QUEUE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_COMPLETE_INSTALLATION:
d = OC_COMPLETE_INSTALLATION_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_CLEANUP:
d = OC_CLEANUP_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
default:
d = 0;
break;
}
DebugOutput(_T("Leaving OCEntry. Return=%d"), d);
return(d);
}
//
// Param1 = char width flags
// Param2 = unused
//
// Return value is a flag indicating to OC Manager
// which char width we want to run in. Run in "native"
// char width.
//
DWORD OC_PREINITIALIZE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = 0;
#ifdef UNICODE
d = OCFLAG_UNICODE;
#else
d = OCFLAG_ANSI;
#endif
return d;
}
//
// Param1 = unused
// Param2 = points to SETUP_INIT_COMPONENT structure
//
// Return code is Win32 error indicating outcome.
//
DWORD OC_INIT_COMPONENT_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d;
BOOL b;
DWORD CompId, Id;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
PSETUP_INIT_COMPONENT InitComponent = (PSETUP_INIT_COMPONENT)Param2;
theApp.m_hDllHandle = (HINSTANCE)gMyModuleHandle;
// Check for workstation or server!
theApp.m_fNTUpgrade_Mode = (InitComponent->SetupData.OperationFlags & SETUPOP_NTUPGRADE) > 0;
theApp.m_fNTGuiMode = (InitComponent->SetupData.OperationFlags & SETUPOP_STANDALONE) == 0;
theApp.m_fNtWorkstation = InitComponent->SetupData.ProductType == PRODUCT_WORKSTATION;
// a superset of m_fNTGuiMode and controlpanel add/remove
theApp.m_fInvokedByNT = theApp.m_fNTGuiMode;
// if ran from sysoc.inf then set m_fInvokedByNT (for control panel add/remove)
TCHAR szCmdLine1[_MAX_PATH+1];
szCmdLine1[_MAX_PATH] = '\0';
_tcsncpy(szCmdLine1, GetCommandLine(), _MAX_PATH);
_tcslwr(szCmdLine1);
if (_tcsstr(szCmdLine1, _T("sysoc.inf"))) {theApp.m_fInvokedByNT = TRUE;}
// Call this stuff after setting m_fNTGuiMode and m_fNtWorkstation
// since it maybe used in InitApplication().
if ( theApp.InitApplication() == FALSE )
{
// setup should be terminated.
d = ERROR_CANCELLED;
goto OC_INIT_COMPONENT_Func_Exit;
}
//
// The OC Manager passes us some information that we want to save,
// such as an 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
// queuing operations.
//
// We save away certain other stuff that gets passed to us now,
// since OC Manager doesn't guarantee that the SETUP_INIT_COMPONENT
// will persist beyond processing of this one interface routine.
//
if (InitComponent->ComponentInfHandle == INVALID_HANDLE_VALUE) {
MyMessageBox(NULL, _T("Invalid inf handle."), _T(""), MB_OK | MB_SETFOREGROUND);
d = ERROR_CANCELLED;
goto OC_INIT_COMPONENT_Func_Exit;
}
theApp.m_hInfHandle[CompId] = InitComponent->ComponentInfHandle;
theApp.m_csPathSource = InitComponent->SetupData.SourcePath;
gHelperRoutines = InitComponent->HelperRoutines;
// See if we are doing an unattended install
theApp.m_fIsUnattended = (((DWORD)InitComponent->SetupData.OperationFlags) & SETUPOP_BATCH);
if (theApp.m_fIsUnattended)
{
// Save the file handle as well ...
DebugOutput(_T("Entering unattended install mode"));
g_hUnattended = gHelperRoutines.GetInfHandle(INFINDEX_UNATTENDED,
gHelperRoutines.OcManagerContext);
}
// We must see if the Exchange IMC is installed. If it is we
// will disable SMTP so we don't hose IMC. Make sure this check is
// AFTER the check to see if we are doing unattended setup.
if (CompId == MC_IMS)
{
theApp.m_fSuppressSmtp = DetectExistingSmtpServers();
}
// Set up the directory ID for Inetpub
b = SetupSetDirectoryId(theApp.m_hInfHandle[CompId], 32768, theApp.m_csPathInetpub);
// Setup strind id for 34000/34001
SetupSetStringId_Wrapper( theApp.m_hInfHandle[CompId] );
d = NO_ERROR;
OC_INIT_COMPONENT_Func_Exit:
return d;
}
//
// Param1 = low 16 bits specify Win32 LANGID
// Param2 = unused
//
// Return code is a boolean indicating whether we think we
// support the requested language. We remember the language id
// and say we support the language. A more exact check might involve
// looking through our resources via EnumResourcesLnguages() for
// example, or checking our inf to see whether there is a matching
// or closely matching [strings] section. We don't bother with
// any of that here.
//
// Locate the component and remember the language id for later use.
//
DWORD OC_SET_LANGUAGE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = TRUE;
return d;
}
#ifdef _WIN64
DWORD_PTR OC_QUERY_IMAGE_EX_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
HBITMAP hBitMap = NULL;
HBITMAP * phBitMapInput = (HBITMAP *) Param2;
OC_QUERY_IMAGE_INFO * MyQueryInfo = (OC_QUERY_IMAGE_INFO *) Param1;
DWORD CompId = GetComponentFromId(ComponentId);
DWORD Id = GetSubcomponentFromId(SubcomponentId);
if(MyQueryInfo->ComponentInfo == SubCompInfoSmallIcon)
{
if (Id != SC_NONE)
{
switch (Id)
{
case SC_SMTP:
hBitMap = LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_SMTP));
break;
case SC_NNTP:
hBitMap = LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_NNTP));
break;
case SC_SMTP_DOCS:
case SC_NNTP_DOCS:
hBitMap = LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_DOCS));
break;
default:
break;
}
}
else
{
switch (CompId)
{
// Load top-level bitmaps for group
case MC_IMS:
hBitMap = LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_SMTP));
break;
case MC_INS:
hBitMap = LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_NNTP));
break;
default:
break;
}
}
if (hBitMap)
*phBitMapInput = (HBITMAP) hBitMap;
}
return (hBitMap != NULL);
}
#endif
DWORD_PTR OC_QUERY_IMAGE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD_PTR d = (DWORD)NULL;
DWORD CompId, Id;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
if (LOWORD(Param1) == SubCompInfoSmallIcon)
{
if (Id != SC_NONE)
{
switch (Id)
{
case SC_SMTP:
d = (DWORD_PTR)LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_SMTP));
break;
case SC_NNTP:
d = (DWORD_PTR)LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_NNTP));
break;
case SC_SMTP_DOCS:
case SC_NNTP_DOCS:
d = (DWORD_PTR)LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_DOCS));
break;
default:
break;
}
}
else
{
switch (CompId)
{
// Load top-level bitmaps for group
case MC_IMS:
d = (DWORD_PTR)LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_SMTP));
break;
case MC_INS:
d = (DWORD_PTR)LoadBitmap(theApp.m_hDllHandle, MAKEINTRESOURCE(IDB_NNTP));
break;
default:
break;
}
}
}
return d;
}
DWORD OC_REQUEST_PAGES_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = 0;
WizardPagesType PageType;
PSETUP_REQUEST_PAGES pSetupRequestPages = NULL;
UINT MaxPages;
HPROPSHEETPAGE pPage;
PageType = (WizardPagesType)Param1;
if ( PageType == WizPagesWelcome ) {
// NT5 - No Welcome page
if (theApp.m_fInvokedByNT)
{
d = 0;
}
goto OC_REQUEST_PAGES_Func_Exit;
}
if ( PageType == WizPagesMode ) {
pSetupRequestPages = (PSETUP_REQUEST_PAGES)Param2;
MaxPages = pSetupRequestPages->MaxPages;
pSetupRequestPages->MaxPages = 0;
switch (theApp.m_eInstallMode)
{
case IM_UPGRADE:
// NT5 - No Welcome page
if (theApp.m_fInvokedByNT)
{
pSetupRequestPages->MaxPages = 0;
}
break;
case IM_MAINTENANCE:
// NT5 - No Welcome page
if (theApp.m_fInvokedByNT)
{
pSetupRequestPages->MaxPages = 0;
}
break;
case IM_FRESH:
// NT5 - No Welcome page
if (theApp.m_fInvokedByNT)
{
pSetupRequestPages->MaxPages = 0;
}
break;
default:
pSetupRequestPages->MaxPages = 0;
}
d = pSetupRequestPages->MaxPages;
goto OC_REQUEST_PAGES_Func_Exit;
}
if (!theApp.m_fWizpagesCreated && (PageType == WizPagesEarly))
{
// Get the pages, if we don't want it, we'll skip it later
pSetupRequestPages = (PSETUP_REQUEST_PAGES)Param2;
if (theApp.m_fInvokedByNT)
{
pSetupRequestPages->MaxPages = 0;
d = 0;
goto OC_REQUEST_PAGES_Func_Exit;
}
d = 0;
// Once we returned the Wizard pages, we will not return for
// subsequent calls
theApp.m_fWizpagesCreated = TRUE;
goto OC_REQUEST_PAGES_Func_Exit;
}
if ( PageType == WizPagesFinal ) {
// Get the pages, if we don't want it, we'll skip it later
pSetupRequestPages = (PSETUP_REQUEST_PAGES)Param2;
MaxPages = pSetupRequestPages->MaxPages;
pSetupRequestPages->MaxPages = 0;
// NT5 - No Final page
if (theApp.m_fInvokedByNT)
{
pSetupRequestPages->MaxPages = 0;
}
d = pSetupRequestPages->MaxPages;
goto OC_REQUEST_PAGES_Func_Exit;
}
d = 0;
OC_REQUEST_PAGES_Func_Exit:
return d;
}
DWORD OC_QUERY_STATE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = SubcompUseOcManagerDefault;
DWORD CompId, Id;
ACTION_TYPE atComp;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
if (Id != SC_NONE)
{
// Merge all subcomponents here including iis_nntp_docs, iis_smtp_docs!
// We track core components such as iis_nntp and iis_smtp here.
// We track whether a component is active here: if it is queried of
// its initial state, we assume that it's active
theApp.m_fActive[CompId][Id] = TRUE;
switch (Param1) {
case OCSELSTATETYPE_ORIGINAL:
switch (GetIMSSetupMode()) {
case IIS_SETUPMODE_UPGRADEONLY:
atComp = GetSubcompAction(Id);
if (atComp == AT_UPGRADE || atComp == AT_REINSTALL)
{
// 3/30/99 - Both cases have original state turn ON!
// IM_REMOVE?
d = SubcompOn;
}
else
{
d = SubcompUseOcManagerDefault;
}
break;
default:
d = SubcompUseOcManagerDefault;
break;
}
DebugOutput(_T("Original state is: %s"),
(d == SubcompUseOcManagerDefault)?_T("DEFAULT"):
(d == SubcompOn)?_T("ON"):_T("OFF"));
break;
case OCSELSTATETYPE_CURRENT:
// If we are doing unattended setup, we will override all
// other modes ...
if (theApp.m_fIsUnattended)
{
d = GetUnattendedModeFromSetupMode(g_hUnattended, CompId, SubcomponentId);
// We force SMTP to be off if we are suppressing it
// Bug 130734: Leave SMTP installed on the box if IMC is there
if (theApp.m_fSuppressSmtp &&
(Id == SC_SMTP || Id == SC_SMTP_DOCS) &&
(GetIMSSetupMode() == IIS_SETUPMODE_CUSTOM))
{
//d = SubcompOff;
//DebugOutput(_T("Suppressed SMTP %s"), (Id == SC_SMTP_DOCS)?_T("Docs"):_T(""));
}
break;
}
switch (GetIMSSetupMode()) {
case IIS_SETUPMODE_REMOVEALL:
d = SubcompOff;
break;
case IIS_SETUPMODE_MINIMUM:
case IIS_SETUPMODE_TYPICAL:
case IIS_SETUPMODE_CUSTOM:
// Here's a new catch: if we are installing SMTP and
// we are asked to suppress it because of existence of
theApp.m_eState[Id] = IM_FRESH;
break;
case IIS_SETUPMODE_UPGRADEONLY:
// NT5 - Same here, for upgradeonly, we compare against our orignal state
// If it's ON, it's ON, if it's OFF, it's OFF
case IIS_SETUPMODE_ADDEXTRACOMPS:
case IIS_SETUPMODE_ADDREMOVE:
case IIS_SETUPMODE_REINSTALL:
d = gHelperRoutines.QuerySelectionState(
gHelperRoutines.OcManagerContext,
SubcomponentId,
OCSELSTATETYPE_ORIGINAL) ? SubcompOn : SubcompOff;
break;
default:
_ASSERT(FALSE);
break;
}
DebugOutput(_T("Current state is: %s"),
(d == SubcompUseOcManagerDefault)?_T("DEFAULT"):
(d == SubcompOn)?_T("ON"):_T("OFF"));
break;
default:
break;
}
}
return d;
}
// Called by OCMANAGE when a selection state is changed
// Param1 - Proposed new selection state 0=unselected, non-0=selected
// return value: 0 rejected, non-0 accepted
DWORD OC_QUERY_CHANGE_SEL_STATE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = 1;
DWORD CompId, Id;
BOOL OriginalState;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
OriginalState = gHelperRoutines.QuerySelectionState(
gHelperRoutines.OcManagerContext,
SubcomponentId,
OCSELSTATETYPE_ORIGINAL
) ;
//
// If this is the parent component, the subcomponent will be SC_NONE. We only
// allow the state change if we were explicitly selected
//
if (Id == SC_NONE) {
// Parent case
if ((BOOL)Param1 &&
(((UINT)(ULONG_PTR)Param2) & OCQ_DEPENDENT_SELECTION) &&
!(((UINT)(ULONG_PTR)Param2) & OCQ_ACTUAL_SELECTION))
{
d = 0;
}
} else {
// Child case
if (OriginalState == 1)
{
if ((BOOL)Param1)
d = 1;
else
{
// In upgrade case, we don't allow user to uncheck previously
// installed components
if ((GetIMSSetupMode() == IIS_SETUPMODE_ADDEXTRACOMPS) ||
(theApp.m_eState[Id] == IM_UPGRADE || theApp.m_eState[Id] == IM_UPGRADE10 || theApp.m_eState[Id] == IM_UPGRADEK2 || theApp.m_eState[Id] == IM_UPGRADE20))
d = 0;
}
}
}
DebugOutput(_T("New state is: %s"),d?_T("Accepted"):_T("Rejected"));
return d;
}
//
// gets called right before we show your page!
//
DWORD OC_QUERY_SKIP_PAGE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = 0;
WizardPagesType PageType = (WizardPagesType)Param1;
theApp.m_dwSetupMode = GetIMSSetupMode();
switch (theApp.m_dwSetupMode) {
case IIS_SETUPMODE_UPGRADEONLY:
case IIS_SETUPMODE_REMOVEALL:
case IIS_SETUPMODE_MINIMUM:
case IIS_SETUPMODE_TYPICAL:
case IIS_SETUPMODE_REINSTALL:
d = 1;
break;
case IIS_SETUPMODE_ADDREMOVE:
case IIS_SETUPMODE_CUSTOM:
// We have to handle Unattended setup here:
// If unattended, we will skip all wizard pages
if (theApp.m_fIsUnattended)
{
d = 1;
break;
}
// Else fall thru ...
case IIS_SETUPMODE_ADDEXTRACOMPS:
break;
}
return d;
}
//
// Param1 = 0 if for removing component or non-0 if for adding component
// Param2 = HDSKSPC to operate on
//
// Return value is 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 the high-level
// disk space list api to do what we want.
// HACK: we need to determine which components are active and which
// are not. This determination must occur after OC_QUERY_STATE and
// before OC_REQUEST_PAGES
DWORD OC_CALC_DISK_SPACE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = NO_ERROR;
DWORD CompId, Id;
BOOL b;
TCHAR SectionName[128];
DWORD dwErr;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
theApp.m_eInstallMode = theApp.DetermineInstallMode(CompId);
// Logic is not correct here !!!
//
if (SubcomponentId) {
b = TRUE;
_stprintf(SectionName,TEXT("%s_%s"),SubcomponentId, _T("install"));
if (Param1 != 0) { // add component
b = SetupAddInstallSectionToDiskSpaceList(
Param2,
theApp.m_hInfHandle[CompId],
NULL,
SectionName,
0,0
);
} else { // removing component
b = SetupRemoveInstallSectionFromDiskSpaceList(
Param2,
theApp.m_hInfHandle[CompId],
NULL,
SectionName,
0,0
);
}
if (!b)
{
dwErr = GetLastError();
}
d = b ? NO_ERROR : GetLastError();
}
return d;
}
//
// Param1 = unused
// Param2 = HSPFILEQ to operate on
//
// Return value is Win32 error code indicating outcome.
//
// OC Manager calls this routine when it is 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 OC Manager calls us once for the *entire* component
// and then once per subcomponent. We ignore the first call.
//
DWORD OC_QUEUE_FILE_OPS_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = NO_ERROR;
BOOL b;
TCHAR SectionName[128];
DWORD CompId, Id;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
// Setup 34000/34001 string id
SetupSetStringId_Wrapper( theApp.m_hInfHandle[CompId] );
if (!SubcomponentId)
{
// We will setup the proper public directory from IIS private data
if (! GetInetpubPathFromPrivData(theApp.m_csPathInetpub))
{
// Fail to get private data from wwwroot to get inetpub path
// Try to get it from metabase
GetInetpubPathFromMD( theApp.m_csPathInetpub );
}
SetupSetDirectoryId(theApp.m_hInfHandle[CompId], 32768, theApp.m_csPathInetpub);
// For unattended setup, we need to change the NntpFile, NntpRoot, and MailRoot
// based on m_csPathInetpub
// NT5 - Not just for unattended, we want to set these path no matter what
SetupMailAndNewsRoot();
// We will remove all shared files if we are doing a K2 uninstall
if (GetIMSSetupMode() == IIS_SETUPMODE_REMOVEALL)
{
_stprintf(SectionName,TEXT("iis_%s_uninstall"),ComponentId);
DebugOutput(_T("Queueing <%s>"), SectionName);
// Remove all shared files
b = SetupInstallFilesFromInfSection(
theApp.m_hInfHandle[CompId],
NULL,
Param2,
SectionName,
//theApp.m_csPathSource, // BUGBUGBUG: Should be NULL!!!
NULL,
SP_COPY_IN_USE_NEEDS_REBOOT
);
d = b ? NO_ERROR : GetLastError();
}
}
else
{
ACTION_TYPE atComp;
if (Id != SC_NONE)
{
// We have a known subcomponent, so process it as such
// Can be iis_nntp, iis_smtp, iis_nntp_docs, iis_smtp_docs...
atComp = GetSubcompAction(Id);
if (atComp == AT_FRESH_INSTALL || atComp == AT_UPGRADE || atComp == AT_REMOVE || atComp == AT_REINSTALL)
b = TRUE;
else
goto OC_QUEUE_FILE_OPS_Func_Exit;
}
else
{
// If this is not a real subcomponent, nor is it documentation, we
// break out of the loop. Otherwise we will queue the documentation
// files
goto OC_QUEUE_FILE_OPS_Func_Exit;
}
_stprintf(SectionName,TEXT("%s_%s"),SubcomponentId, (atComp == AT_REMOVE) ? _T("uninstall") : _T("install"));
DebugOutput(_T("Queueing <%s>"), SectionName);
UINT uiCopyMode = SP_COPY_IN_USE_NEEDS_REBOOT;
// Handles NT5 Beta2-> Beta3 upgrade as well as upgrade between builds in Beta3
// If it's not these cases, we do FORCE_NEWER. Otherwise, we just copy over the new bits.
// 11/28/98 - FORCE_NEWER seems to be causing more trouble in K2 upgrade as well
// since we have 5.5.1774 verion in K2 while 5.0.19xx in NT5. Take it out!
//if (atComp != AT_REINSTALL || theApp.m_eState[Id] != IM_UPGRADEB2)
// uiCopyMode |= SP_COPY_FORCE_NEWER;
b = SetupInstallFilesFromInfSection(
theApp.m_hInfHandle[CompId],
NULL,
Param2,
SectionName,
//theApp.m_csPathSource, // BUGBUGBUG: should be NULL
NULL,
uiCopyMode
);
d = b ? NO_ERROR : GetLastError();
if (atComp != AT_FRESH_INSTALL && atComp != AT_DO_NOTHING) {
//
// See if we can open the directory. If we can't, then we
// don't bother to delete the files
//
HANDLE h = CreateFile(
(LPCTSTR)theApp.m_csPathInetpub,
GENERIC_WRITE,
FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (h != INVALID_HANDLE_VALUE) {
DebugOutput(_T("Removing webadmin"));
b = SetupInstallFilesFromInfSection(
theApp.m_hInfHandle[CompId],
NULL,
Param2,
TEXT("remove_webadmin"),
NULL,
uiCopyMode
);
d = b ? NO_ERROR : GetLastError();
CloseHandle(h);
} else {
DebugOutput(_T("Not removing webadmin, GLE %d"), GetLastError);
}
}
// Handle the MCIS 1.0 upgrade case for mail and news where
// we delete the old files left over from MCIS 1.0
if (IsSubcomponentCore(Id))
{
if (theApp.m_eState[Id] == IM_UPGRADE10)
{
// Establish the section name and queue files for removal
_stprintf(SectionName,
TEXT("%s_mcis10_product_upgrade"),
SubcomponentId);
DebugOutput(_T("Queueing <%s>"), SectionName);
b = SetupInstallFilesFromInfSection(
theApp.m_hInfHandle[CompId],
NULL,
Param2,
SectionName,
//theApp.m_csPathSource, // BUGBUGBUG: should be NULL
NULL,
0
);
}
}
}
OC_QUEUE_FILE_OPS_Func_Exit:
return d;
}
DWORD OC_NEED_MEDIA_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = 0;
return d;
}
DWORD OC_NOTIFICATION_FROM_QUEUE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = 0;
return d;
}
//
// Param1 = unused
// Param2 = unused
//
// Return value is an arbitrary 'step' count or -1 if error.
//
// OC Manager 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/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.
//
DWORD OC_QUERY_STEP_COUNT_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = 2;
return d;
}
DWORD OC_ABOUT_TO_COMMIT_QUEUE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = NO_ERROR;
TCHAR SectionName[128];
DWORD CompId, Id;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
// Setup 34000/34001 string id
SetupSetStringId_Wrapper( theApp.m_hInfHandle[CompId] );
SetCurrentDirectory(theApp.m_csPathInetsrv);
if (Id == SC_NONE)
{
if (!theApp.m_fNTGuiMode)
{
if (GetSubcompAction(Id) != AT_DO_NOTHING) {
BringALLIISClusterResourcesOffline();
StopServiceAndDependencies(SZ_MD_SERVICENAME, TRUE);
}
}
}
else if (IsSubcomponentCore(Id))
{
// for SC_NNTP & SC_SMTP...
ACTION_TYPE atComp = GetSubcompAction(Id);
if (atComp == AT_REMOVE)
{
// For each component that we are removing, we will
// unregister the service.
switch (Id)
{
case SC_SMTP:
Unregister_iis_smtp();
RemoveServiceFromDispatchList(SZ_SMTPSERVICENAME);
break;
case SC_NNTP:
Unregister_iis_nntp();
RemoveServiceFromDispatchList(SZ_NNTPSERVICENAME);
break;
}
_stprintf(SectionName,TEXT("%s_%s"),SubcomponentId, _T("uninstall"));
SetupInstallFromInfSection(
NULL, theApp.m_hInfHandle[CompId], SectionName,
SPINST_REGISTRY, NULL, NULL, //theApp.m_csPathSource,
0, NULL, NULL, NULL, NULL );
}
else if (atComp == AT_FRESH_INSTALL || atComp == AT_UPGRADE || atComp == AT_REINSTALL)
{
// NT5 - We need to unregister mnntpsnp.dll
// when upgrading from NT4 MCIS20 to NT5 Server
// in the K2 to MCIS upgrade for NNTP we need to unregister
// the K2 version of the admin and plug in the MCIS version
// of it.
if (Id == SC_NNTP && theApp.m_eState[Id] == IM_UPGRADE20) {
CString csOcxFile;
csOcxFile = theApp.m_csPathInetsrv + _T("\\mnntpsnp.dll");
RegisterOLEControl(csOcxFile, FALSE);
}
// If upgrade from MCIS2.0, we need to remove "Use Express" from registry
// to disable Active Messaging.
if (Id == SC_SMTP && theApp.m_eState[Id] == IM_UPGRADE20)
{
CRegKey regActiveMsg( REG_ACTIVEMSG, HKEY_LOCAL_MACHINE );
if ((HKEY) regActiveMsg )
{
regActiveMsg.DeleteValue( _T("Use Express"));
}
}
// A new component should be started
theApp.m_fStarted[CompId] = TRUE;
}
}
CoFreeUnusedLibrariesEx(0, 0);
gHelperRoutines.TickGauge(gHelperRoutines.OcManagerContext);
return d;
}
DWORD OC_COMPLETE_INSTALLATION_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = NO_ERROR;
TCHAR SectionName[128];
BOOL b;
DWORD CompId, Id;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
// Setup 34000/34001 string id
SetupSetStringId_Wrapper( theApp.m_hInfHandle[CompId] );
SetCurrentDirectory(theApp.m_csPathInetsrv);
if (Id != SC_NONE)
{
ACTION_TYPE atComp = GetSubcompAction(Id);
// Here we determine if we need to create or remove the doc links
if (!IsSubcomponentCore(Id))
{
// iis_nntp_docs or iis_smtp_docs...
// We are processing docs, see if we are adding or removing
if (atComp == AT_REMOVE || atComp == AT_UPGRADE)
{
//
// For both AT_REMOVE, or AT_UPGRADE, including K2, MCIS10, or MCIS20
// we need to remove these old links.
//
if (CompId == MC_IMS)
{
RemoveInternetShortcut(CompId,
IDS_PROGITEM_MAIL_DOCS,
FALSE); // NT5 - For SMTP, this is always FALSE for Wks & Srv
// 11/30/98 - Don't care what are we upgrading from, just get rid of the link
//if (theApp.m_eNTOSType == OT_NTS)
{
RemoveInternetShortcut(CompId,
IDS_PROGITEM_MCIS_MAIL_DOCS,
TRUE);
}
}
else if (CompId == MC_INS)
{
// remove K2 DOC link anyway regardless of MCIS/K2 remove-all
RemoveInternetShortcut(CompId,
IDS_PROGITEM_NEWS_DOCS,
FALSE);
// 11/30/98 - Don't care what are we upgrading from, just get rid of the link
//if (theApp.m_eNTOSType == OT_NTS)
{
RemoveInternetShortcut(CompId,
IDS_PROGITEM_MCIS_NEWS_DOCS,
TRUE);
}
}
//
// Todo: remove any possible DOC's links created by Setup
// during fresh install.
//
}
}
else // if (!IsSubcomponentCore(Id))
{
// Core components iis_nntp or iis_smtp
if (atComp == AT_FRESH_INSTALL || atComp == AT_UPGRADE || atComp == AT_REINSTALL)
{
b = (atComp == AT_UPGRADE) ? TRUE : FALSE;
BOOL bReinstall = (atComp == AT_REINSTALL);
if (atComp == AT_FRESH_INSTALL || theApp.m_eState[Id] == IM_UPGRADE10)
{
// do this only if we are fresh-install, or upgrade from MCIS 1.0
// add any freshly installed or upgrading services to
// the dispatch list
AddServiceToDispatchList(szServiceNames[Id]);
}
// Next, we want to create all the required directories
// for fresh setup
CreateAllRequiredDirectories(Id);
// Now, we realized that by stopping and restarting the IISADMIN
// service we can rid ourselves of a lot of Metabase problems,
// especially the 80070094 (ERROR_PATH_BUSY) problems
if (!theApp.m_fNTGuiMode)
{
// BUGBUG: don't stop any services???
// We should stop all services only if we are not running GUI Mode setup
// Don't want to do that since Spooler may be needed by other
// components during setup!!!
BringALLIISClusterResourcesOffline();
StopServiceAndDependencies(SZ_MD_SERVICENAME, TRUE);
InetStartService(SZ_MD_SERVICENAME);
Sleep(2000);
}
// Need to decide which functions to call here:
// 1) Fresh install, or upgrade from MCIS 1.0 - Register_iis_xxxx_nt5
// 2) Upgrade from NT4 K2, MCIS 2.0 - Register_iis_xxxx_nt5_fromk2( fFromK2 )
// 3) Upgrade from NT5 Beta2, or Beta3 - Upgrade_iis_xxxx_nt5_fromb2( fBeta2 )
if (atComp == AT_UPGRADE && (theApp.m_eState[Id] == IM_UPGRADEK2 || theApp.m_eState[Id] == IM_UPGRADE20))
{
// 2) Upgrade from NT4 K2, MCIS 2.0 - Register_iis_xxxx_nt5_fromk2( fFromK2 )
BOOL fFromK2 = (theApp.m_eState[Id] == IM_UPGRADEK2) ? TRUE : FALSE;
switch (Id)
{
case SC_SMTP:
Upgrade_iis_smtp_nt5_fromk2( fFromK2 );
break;
case SC_NNTP:
GetNntpFilePathFromMD(theApp.m_csPathNntpFile, theApp.m_csPathNntpRoot);
Upgrade_iis_nntp_nt5_fromk2( fFromK2 );
break;
}
}
else if (atComp == AT_REINSTALL && (theApp.m_eState[Id] == IM_UPGRADEB2 || theApp.m_eState[Id] == IM_MAINTENANCE || !theApp.m_fValidSetupString[Id]))
{
// 3) Upgrade from NT5 Beta2, or Beta3 - Upgrade_iis_xxxx_nt5_fromb2( fBeta2 )
BOOL fFromB2 = (theApp.m_eState[Id] == IM_UPGRADEB2) ? TRUE : FALSE;
switch (Id)
{
case SC_SMTP:
Upgrade_iis_smtp_nt5_fromb2( fFromB2 );
break;
case SC_NNTP:
Upgrade_iis_nntp_nt5_fromb2( fFromB2 );
break;
}
}
else
{
// 1) Fresh install, or upgrade from MCIS 1.0 - Register_iis_xxxx_nt5
switch (Id)
{
case SC_SMTP:
Register_iis_smtp_nt5(b, bReinstall);
break;
case SC_NNTP:
Register_iis_nntp_nt5(b, bReinstall);
break;
}
}
// Update the registry
_stprintf(SectionName,TEXT("%s_%s"),SubcomponentId, _T("install"));
SetupInstallFromInfSection(
NULL, theApp.m_hInfHandle[CompId], SectionName,
SPINST_REGISTRY, NULL, NULL, //theApp.m_csPathSource,
0, NULL, NULL, NULL, NULL );
// BINLIN: For MCIS 1.0 to NT5 upgrade
// Perform AddReg/DelReg operation for this upgrade only.
if (theApp.m_eState[Id] == IM_UPGRADE10)
{
// Establish the section name and queue files for removal
_stprintf(SectionName,
TEXT("%s_mcis10_product_upgrade"),
SubcomponentId);
SetupInstallFromInfSection(
NULL,
theApp.m_hInfHandle[CompId],
SectionName,
SPINST_REGISTRY,
NULL,
//theApp.m_csPathSource,
NULL,
0, NULL, NULL, NULL, NULL );
// also remove the control panel add/remove items..
// ..and program groups
if (Id == SC_SMTP)
{
RemoveUninstallEntries(SZ_MCIS10_MAIL_UNINST);
RemoveMCIS10MailProgramGroup();
}
else
{
RemoveUninstallEntries(SZ_MCIS10_NEWS_UNINST);
RemoveMCIS10NewsProgramGroup();
}
}
}
else if (atComp == AT_REMOVE)
{
// A removed component should not be re-started
theApp.m_fStarted[CompId] = FALSE;
}
//
// start the service if its appropriate
//
if (theApp.m_fStarted[CompId]) {
InetStartService(szServiceNames[CompId]);
if (Id == SC_NNTP && atComp == AT_FRESH_INSTALL) {
// if this is a fresh install than we need to make
// the nntp groups
CreateNNTPGroups();
}
}
} // if (!IsSubcomponentCore(Id))
} // if (Id != SC_NONE)
gHelperRoutines.TickGauge(gHelperRoutines.OcManagerContext);
return d;
}
DWORD OC_CLEANUP_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD d = 0;
DWORD CompId, Id;
CompId = GetComponentFromId(ComponentId);
Id = GetSubcomponentFromId(SubcomponentId);
//if (!SubcomponentId)
{
if (!theApp.m_fNTGuiMode)
{
ServicesRestartList_RestartServices();
}
}
return d;
}