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.
 
 
 
 
 
 

5144 lines
193 KiB

#include "stdafx.h"
#include <afxinet.h>
#include <ole2.h>
#include "iadmw.h"
#include "iiscnfg.h"
#include "mdkey.h"
#include "massupdt.h"
#include "log.h"
#include "other.h"
#include "mtxadmin.h"
#include "mdentry.h"
#include "kill.h"
#include "svc.h"
#include "wolfpack.h"
#include "sakit.hxx"
#include "filter.hxx"
#include "compinst.hxx"
#include "lockdown.hxx"
#include "reg.hxx"
#include <htmlhelp.h>
#pragma hdrstop
int g_GlobalTickValue = 1;
int g_GlobalGuiOverRide = 0;
int g_GlobalTotalTickGaugeCount = 0;
int g_GlobalTickTotal_iis_common = 0;
int g_GlobalTickTotal_iis_inetmgr = 0;
int g_GlobalTickTotal_iis_www = 0;
int g_GlobalTickTotal_iis_pwmgr = 0;
int g_GlobalTickTotal_iis_doc = 0;
int g_GlobalTickTotal_iis_htmla = 0;
int g_GlobalTickTotal_iis_ftp = 0;
TCHAR g_szCurrentSubComponent[25];
// OcManage globals
OCMANAGER_ROUTINES gHelperRoutines;
HANDLE g_MyModuleHandle = NULL;
const TCHAR OC_MANAGER_SETUP_KEY[] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents");
const TCHAR OCM_OptionalComponents_Section[] = _T("Optional Components");
const TCHAR STRING_iis[] = _T("iis");
const TCHAR STRING_iis_htmla[] = _T("iis_htmla");
const TCHAR STRING_iis_doc[] = _T("iis_doc");
const TCHAR STRING_iis_pwmgr[] = _T("iis_pwmgr");
const TCHAR STRING_iis_www[] = _T("iis_www");
const TCHAR STRING_iis_inetmgr[] = _T("iis_inetmgr");
const TCHAR STRING_iis_core[] = _T("iis_core");
const TCHAR STRING_iis_common[] = _T("iis_common");
const TCHAR STRING_iis_www_vdir_scripts[] = _T("iis_www_vdir_scripts");
const TCHAR STRING_iis_www_vdir_printers[] = _T("iis_www_vdir_printers");
int g_iOC_WIZARD_CREATED_Called = FALSE;
int g_iOC_FILE_BUSY_Called = FALSE;
int g_iOC_PREINITIALIZE_Called = FALSE;
int g_iOC_INIT_COMPONENT_Called = FALSE;
int g_iOC_SET_LANGUAGE_Called = FALSE;
int g_iOC_QUERY_IMAGE_Called = FALSE;
int g_iOC_REQUEST_PAGES_Called = FALSE;
int g_iOC_QUERY_STATE_Called = FALSE;
int g_iOC_QUERY_CHANGE_SEL_STATE_Called = FALSE;
int g_iOC_QUERY_SKIP_PAGE_Called = FALSE;
int g_iOC_CALC_DISK_SPACE_Called = FALSE;
int g_iOC_QUEUE_FILE_OPS_Called = FALSE;
int g_iOC_NEED_MEDIA_Called = FALSE;
int g_iOC_NOTIFICATION_FROM_QUEUE_Called = FALSE;
int g_iOC_QUERY_STEP_COUNT_Called = FALSE;
int g_iOC_ABOUT_TO_COMMIT_QUEUE_Called = FALSE;
int g_iOC_COMPLETE_INSTALLATION_Called = FALSE;
int g_iOC_CLEANUP_Called = FALSE;
int g_iOC_DEFAULT_Called = FALSE;
int g_Please_Call_Register_iis_inetmgr = FALSE;
HSPFILEQ g_GlobalFileQueueHandle = NULL;
int g_GlobalFileQueueHandle_ReturnError = 0;
CInitApp *g_pTheApp;
CComponentList *g_pComponents = NULL;
BOOL g_bGlobalWriteUnSecuredIfFailed_All = FALSE;
// 0 = log errors only
// 1 = log warnings
// 2 = trace
// 3 = trace win32 stuff
int g_GlobalDebugLevelFlag = 3;
int g_GlobalDebugLevelFlag_WasSetByUnattendFile = FALSE;
int g_GlobalDebugCallValidateHeap = 1;
int g_GlobalDebugCrypto = 0;
int g_GlobalFastLoad = 0;
TCHAR g_szLastSectionToGetCalled[50];
// Logging class
MyLogFile g_MyLogFile;
int CheckInfInstead(int iPrevious)
{
INFCONTEXT Context;
int iTempFlag = 0;
TCHAR szPersonalFlag[20] = _T("");
iTempFlag = iPrevious;
if (SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, _T("SetupInfo"), _T("Personal"), &Context) )
{
SetupGetStringField(&Context, 1, szPersonalFlag, sizeof(szPersonalFlag)/sizeof(szPersonalFlag[0]), NULL);
if (IsValidNumber((LPCTSTR)szPersonalFlag))
{
iTempFlag = _ttoi(szPersonalFlag);
iTempFlag++;
}
}
return (iTempFlag);
}
BOOL IsWhistlerPersonal(void)
{
static int PersonalSKU = 0;
if (0 == PersonalSKU)
{
OSVERSIONINFOEX osvi;
//
// Determine if we are installing Personal SKU
//
ZeroMemory( &osvi, sizeof( OSVERSIONINFOEX ) );
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *) &osvi);
if (osvi.wProductType == VER_NT_WORKSTATION && (osvi.wSuiteMask & VER_SUITE_PERSONAL))
{
PersonalSKU = 2;
}
else
{
PersonalSKU = 1;
}
PersonalSKU = CheckInfInstead(PersonalSKU);
}
return (PersonalSKU - 1);
}
void WINAPI ProcessInfSection(CHAR *pszSectionName)
{
BOOL bPleaseCloseInfHandle = FALSE;
TSTR strFullPath;
TCHAR wszWideString[MAX_PATH];
int MySavedDebugLevel = 0;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("ProcessInfSection:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("ProcessInfSection: Start.\n")));
if (!pszSectionName)
{goto ProcessInfSection_Exit;}
if (!g_pTheApp->m_hInfHandle || g_pTheApp->m_hInfHandle == INVALID_HANDLE_VALUE)
{
g_pTheApp->m_hInfHandle = INVALID_HANDLE_VALUE;
if ( !strFullPath.Resize( MAX_PATH ) )
{
goto ProcessInfSection_Exit;
}
// get the c:\winnt dir
if (0 == GetWindowsDirectory(strFullPath.QueryStr(), MAX_PATH))
{goto ProcessInfSection_Exit;}
// Tack on the inf\iis.inf subdir and filename
if ( !strFullPath.Append( _T("\\inf\\iis.inf") ) )
{
goto ProcessInfSection_Exit;
}
// Check if the file exists
if (TRUE != IsFileExist( strFullPath.QueryStr() ))
{
iisDebugOut((LOG_TYPE_WARN, _T("ProcessInfSection: %s does not exist!\n"),strFullPath.QueryStr()));
goto ProcessInfSection_Exit;
}
// Get a handle to it.
g_pTheApp->m_hInfHandle = SetupOpenInfFile(strFullPath.QueryStr(), NULL, INF_STYLE_WIN4, NULL);
if (!g_pTheApp->m_hInfHandle || g_pTheApp->m_hInfHandle == INVALID_HANDLE_VALUE)
{
iisDebugOut((LOG_TYPE_WARN, _T("ProcessInfSection: SetupOpenInfFile failed on file: %s.\n"),strFullPath.QueryStr()));
goto ProcessInfSection_Exit;
}
bPleaseCloseInfHandle = TRUE;
}
// get the debug level from the iis.inf
GetDebugLevelFromInf(g_pTheApp->m_hInfHandle);
MySavedDebugLevel = g_GlobalDebugLevelFlag;
// reset global debug level only most of the time
if (LOG_TYPE_TRACE_WIN32_API < g_GlobalDebugLevelFlag)
{g_GlobalDebugLevelFlag = LOG_TYPE_ERROR;}
// Read .inf file and set some globals from the information in there.
ReadGlobalsFromInf(g_pTheApp->m_hInfHandle);
g_pTheApp->InitApplication();
SetDIRIDforThisInf(g_pTheApp->m_hInfHandle,TRUE);
//g_pTheApp->DumpAppVars();
g_GlobalDebugLevelFlag = MySavedDebugLevel;
// See if user configured anything
ReadUserConfigurable(g_pTheApp->m_hInfHandle);
// Convert the input to a wide char if ProcessSection() takes wide type.
#if defined(UNICODE) || defined(_UNICODE)
MultiByteToWideChar( CP_ACP, 0, pszSectionName, -1, wszWideString, MAX_PATH);
#else
_tcscpy(wszWideString, pszSectionName);
#endif
ProcessSection(g_pTheApp->m_hInfHandle, wszWideString);
ProcessInfSection_Exit:
if (TRUE == bPleaseCloseInfHandle)
{if(g_pTheApp->m_hInfHandle != INVALID_HANDLE_VALUE) {SetupCloseInfFile(g_pTheApp->m_hInfHandle);g_pTheApp->m_hInfHandle = INVALID_HANDLE_VALUE;}}
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("ProcessInfSection: End.\n")));
return;
}
void WINAPI IIS5Log(int iLogType, TCHAR *pszfmt)
{
iisDebugOut((iLogType, pszfmt));
}
void WINAPI IIS5LogParmString(int iLogType, TCHAR *pszfmt, TCHAR *pszString)
{
if ( _tcsstr(pszfmt, _T("%s")) || _tcsstr(pszfmt, _T("%S")))
{
iisDebugOut((iLogType, pszfmt, pszString));
}
else
{
iisDebugOut((iLogType, pszfmt));
iisDebugOut((iLogType, pszString));
}
}
void WINAPI IIS5LogParmDword(int iLogType, TCHAR *pszfmt, DWORD dwErrorCode)
{
if ( _tcsstr(pszfmt, _T("%x")) || _tcsstr(pszfmt, _T("%X")) || _tcsstr(pszfmt, _T("%d")) || _tcsstr(pszfmt, _T("%D")))
{
iisDebugOut((iLogType, pszfmt, dwErrorCode));
}
else
{
iisDebugOut((iLogType, pszfmt));
iisDebugOut((iLogType, _T("%d"), dwErrorCode));
}
}
void TestAfterInitApp(void)
{
//iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("...... Start\n")));
//iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("...... End\n")));
return;
}
extern "C" void InitializeIISRTL2();
extern "C" void TerminateIISRTL2();
//
// Standard Win32 DLL Entry point
//
BOOL WINAPI DllMain(IN HANDLE DllHandle,IN DWORD Reason,IN LPVOID Reserved)
{
BOOL bReturn = TRUE;
UNREFERENCED_PARAMETER(Reserved);
bReturn = TRUE;
CString csTempPath;
switch(Reason)
{
case DLL_PROCESS_ATTACH:
InitializeIISRTL2();
// Because Heap problems with IISRTL, we must make sure that anything that
// uses stuff from iisrtl, must NOT live beyond the scope of
// InitializeIISRTL2 and TerminateIISRTL2!!!
g_pTheApp = new (CInitApp);
if ( !g_pTheApp )
{
bReturn = FALSE;
}
if (!g_MyModuleHandle)
{
srand(GetTickCount());
g_MyModuleHandle = DllHandle;
// open the log file.
#ifdef IIS60
g_MyLogFile.LogFileCreate(_T("iis6.log"));
#else
g_MyLogFile.LogFileCreate(_T("iis5.log"));
#endif
gHelperRoutines.OcManagerContext = NULL;
}
break;
case DLL_THREAD_ATTACH:
bReturn = TRUE;
break;
case DLL_PROCESS_DETACH:
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T("Final Check:"));
// only do the final check if we are actually run from sysocmgr.exe!
// and the first thing that sysocmgr.exe does is call preinitialize, so let's check for that!
if (g_iOC_PREINITIALIZE_Called)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("=======================\n")));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_PREINITIALIZE Called=%d\n"), g_iOC_PREINITIALIZE_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_INIT_COMPONENT Called=%d\n"), g_iOC_INIT_COMPONENT_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_SET_LANGUAGE Called=%d\n"), g_iOC_SET_LANGUAGE_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_QUERY_IMAGE Called=%d\n"), g_iOC_QUERY_IMAGE_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_REQUEST_PAGES Called=%d\n"), g_iOC_REQUEST_PAGES_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_WIZARD_CREATED Called=%d\n"), g_iOC_WIZARD_CREATED_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_QUERY_STATE Called=%d\n"), g_iOC_QUERY_STATE_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_QUERY_CHANGE_SEL_STATE Called=%d\n"), g_iOC_QUERY_CHANGE_SEL_STATE_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_QUERY_SKIP_PAGE Called=%d\n"), g_iOC_QUERY_SKIP_PAGE_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_CALC_DISK_SPACE Called=%d\n"), g_iOC_CALC_DISK_SPACE_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_QUEUE_FILE_OPS Called=%d\n"), g_iOC_QUEUE_FILE_OPS_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_NEED_MEDIA Called=%d\n"), g_iOC_NEED_MEDIA_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_NOTIFICATION_FROM_QUEUE Called=%d\n"), g_iOC_NOTIFICATION_FROM_QUEUE_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_QUERY_STEP_COUNT Called=%d\n"), g_iOC_QUERY_STEP_COUNT_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_ABOUT_TO_COMMIT_QUEUE Called=%d\n"), g_iOC_ABOUT_TO_COMMIT_QUEUE_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_FILE_BUSY Called=%d\n"), g_iOC_FILE_BUSY_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_COMPLETE_INSTALLATION Called=%d\n"), g_iOC_COMPLETE_INSTALLATION_Called));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("OC_CLEANUP Called=%d\n"), g_iOC_CLEANUP_Called));
iisDebugOut((LOG_TYPE_TRACE, _T("OC_DEFAULT Called=%d\n"), g_iOC_DEFAULT_Called));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T("Final Check:"));
// Check if g_iOC_COMPLETE_INSTALLATION_Called was called!!!!!
if (!g_iOC_COMPLETE_INSTALLATION_Called)
{
if (g_pTheApp->m_fNTGuiMode)
{
iisDebugOut((LOG_TYPE_ERROR, _T("WARNING.FAILURE: OC_COMPLETE_INSTALLATION was not called (by ocmanage.dll) for this component. IIS was not installed or configured!! This will be a problem for other ocm installed components as well.\n")));
}
}
}
// log the heap state
LogHeapState(TRUE, __FILE__, __LINE__);
// free some memory
FreeTaskListMem();
UnInit_Lib_PSAPI();
// Close the log file
g_MyLogFile.LogFileClose();
ASSERT(g_pTheApp);
delete (g_pTheApp);
g_pTheApp = NULL;
if ( g_pComponents )
{
delete g_pComponents;
g_pComponents = NULL;
}
TerminateIISRTL2();
break;
case DLL_THREAD_DETACH:
break;
}
return(bReturn);
}
BOOL g_fFranceHackAttempted = FALSE;
LCID g_TrueThreadLocale;
DWORD WINAPI FranceFixThread(LPVOID lpParameter)
{
g_TrueThreadLocale = GetThreadLocale ();
return 0;
}
BOOL InitializeComponents()
{
// Make sure we don't call this twice
ASSERT( g_pComponents == NULL );
g_pComponents = new CComponentList;
if ( !g_pComponents )
{
// Failed to allocate
return FALSE;
}
if ( !g_pComponents->Initialize() )
{
delete g_pComponents;
g_pComponents = NULL;
return FALSE;
}
return TRUE;
}
// -----------------------------------------------
// OcEntry is the main entry point (After DllMain)
// -----------------------------------------------
DWORD_PTR OcEntry(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD_PTR dwOcEntryReturn = 0;
_tcscpy(g_szCurrentSubComponent, _T(""));
if (SubcomponentId) {_tcscpy(g_szCurrentSubComponent, SubcomponentId);}
if ( g_pComponents == NULL )
{
if ( !InitializeComponents() )
{
// If we can not initialize, we can not do anything
return dwOcEntryReturn;
}
}
if (!g_fFranceHackAttempted)
{
g_fFranceHackAttempted = TRUE;
LCID InitialThreadLocale;
DWORD thid;
InitialThreadLocale = GetThreadLocale ();
iisDebugOut((LOG_TYPE_TRACE, _T("Initial thread locale=%0x\n"),InitialThreadLocale));
HANDLE hHackThread = CreateThread (NULL,0,FranceFixThread,NULL,0,&thid);
if (hHackThread)
{
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("Starting to wait On France fix thread\n")));
// wait for 10 secs only
DWORD res = WaitForSingleObject (hHackThread,10*1000);
if (res==WAIT_TIMEOUT)
{
iisDebugOut((LOG_TYPE_ERROR, _T("ERROR France fix thread never finished...\n")));
}
else
{
iisDebugOut((LOG_TYPE_TRACE, _T("returned from France fix with locale %0x \n"),g_TrueThreadLocale));
CloseHandle (hHackThread);
// do that only if locales are different and another one is France
if (g_TrueThreadLocale !=InitialThreadLocale && g_TrueThreadLocale==0x40c)
{
BOOL ret = SetThreadLocale (g_TrueThreadLocale);
iisDebugOut((LOG_TYPE_TRACE, _T("SetThreadLocale returned %d\n"),ret));
g_TrueThreadLocale = GetThreadLocale ();
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("France fix succeed=%0x\n"),g_TrueThreadLocale));
}
}
}
else
{
iisDebugOut((LOG_TYPE_ERROR, _T("Failed to start France fix thread. error =%0x\n"),GetLastError()));
}
}
switch(Function)
{
case OC_WIZARD_CREATED:
g_iOC_WIZARD_CREATED_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_WIZARD_CREATED:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
DisplayActionsForAllOurComponents(g_pTheApp->m_hInfHandle);
break;
case OC_FILE_BUSY:
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_FILE_BUSY:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
// if the first time this function was
// called then show all running services
LogHeapState(FALSE, __FILE__, __LINE__);
if (g_iOC_FILE_BUSY_Called != TRUE)
{
// display locked dlls by setup
// This seems to thru exceptions on build nt5 build 1980.
// comment this out since it's not crucial.
//LogThisProcessesDLLs();
// display running services
LogEnumServicesStatus();
}
g_iOC_FILE_BUSY_Called = TRUE;
dwOcEntryReturn = OC_FILE_BUSY_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
LogHeapState(FALSE, __FILE__, __LINE__);
break;
case OC_PREINITIALIZE:
g_iOC_PREINITIALIZE_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_PREINITIALIZE:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_PREINITIALIZE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_INIT_COMPONENT:
g_iOC_INIT_COMPONENT_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_INIT_COMPONENT:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_INIT_COMPONENT_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_SET_LANGUAGE:
g_iOC_SET_LANGUAGE_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_SET_LANGUAGE:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_SET_LANGUAGE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
#ifdef _WIN64
case OC_QUERY_IMAGE_EX:
g_iOC_QUERY_IMAGE_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_QUERY_IMAGE_EX:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_QUERY_IMAGE_EX_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
#endif
case OC_QUERY_IMAGE:
g_iOC_QUERY_IMAGE_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_QUERY_IMAGE:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_QUERY_IMAGE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_REQUEST_PAGES:
ASSERT(FALSE);
g_iOC_REQUEST_PAGES_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_REQUEST_PAGES:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
break;
case OC_QUERY_STATE:
g_iOC_QUERY_STATE_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_QUERY_STATE:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_QUERY_STATE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_QUERY_CHANGE_SEL_STATE:
g_iOC_QUERY_CHANGE_SEL_STATE_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_QUERY_CHANGE_SEL_STATE:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_QUERY_CHANGE_SEL_STATE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_QUERY_SKIP_PAGE:
g_iOC_QUERY_SKIP_PAGE_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_QUERY_SKIP_PAGE:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_QUERY_SKIP_PAGE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_CALC_DISK_SPACE:
g_iOC_CALC_DISK_SPACE_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_CALC_DISK_SPACE:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_CALC_DISK_SPACE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_QUEUE_FILE_OPS:
ProgressBarTextStack_Set(IDS_IIS_ALL_FILEOPS);
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_QUEUE_FILE_OPS:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
if (g_iOC_QUEUE_FILE_OPS_Called != TRUE)
{
// turn logging back on if we need to
// get the debug level from the iis.inf
if (g_GlobalFastLoad)
{
GetDebugLevelFromInf(g_pTheApp->m_hInfHandle);
// output stuff that we missed during init
g_pTheApp->DumpAppVars();
}
}
g_iOC_QUEUE_FILE_OPS_Called = TRUE;
dwOcEntryReturn = OC_QUEUE_FILE_OPS_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
ProgressBarTextStack_Pop();
break;
case OC_NEED_MEDIA:
g_iOC_NEED_MEDIA_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_NEED_MEDIA:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_NEED_MEDIA_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_NOTIFICATION_FROM_QUEUE:
g_iOC_NOTIFICATION_FROM_QUEUE_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_NOTIFICATION_FROM_QUEUE:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_NOTIFICATION_FROM_QUEUE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_QUERY_STEP_COUNT:
g_iOC_QUERY_STEP_COUNT_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_QUERY_STEP_COUNT:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = OC_QUERY_STEP_COUNT_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
break;
case OC_ABOUT_TO_COMMIT_QUEUE:
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_ABOUT_TO_COMMIT_QUEUE:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
LogHeapState(FALSE, __FILE__, __LINE__);
if (g_iOC_ABOUT_TO_COMMIT_QUEUE_Called != TRUE)
{
if (g_GlobalDebugLevelFlag >= LOG_TYPE_TRACE)
{
// display running processes
LogCurrentProcessIDs();
// display running services
LogEnumServicesStatus();
// log file versions
LogImportantFiles();
// display locked dlls by setup
//LogThisProcessesDLLs();
// check if temp dir is writeable
LogCheckIfTempDirWriteable();
}
}
g_iOC_ABOUT_TO_COMMIT_QUEUE_Called = TRUE;
dwOcEntryReturn = OC_ABOUT_TO_COMMIT_QUEUE_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
LogHeapState(FALSE, __FILE__, __LINE__);
break;
case OC_COMPLETE_INSTALLATION:
g_iOC_COMPLETE_INSTALLATION_Called = TRUE;
//ProgressBarTextStack_Set(IDS_IIS_ALL_COMPLETE);
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_COMPLETE_INSTALLATION:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
LogHeapState(FALSE, __FILE__, __LINE__);
// no need to do this, just slows things down
//g_MyLogFile.m_bFlushLogToDisk = TRUE;
if (g_iOC_COMPLETE_INSTALLATION_Called != TRUE)
{
// Get the debug level, incase we changed it during setup...
GetDebugLevelFromInf(g_pTheApp->m_hInfHandle);
}
dwOcEntryReturn = OC_COMPLETE_INSTALLATION_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
LogHeapState(FALSE, __FILE__, __LINE__);
g_MyLogFile.m_bFlushLogToDisk = FALSE;
//ProgressBarTextStack_Pop();
break;
case OC_CLEANUP:
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_CLEANUP:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
LogHeapState(FALSE, __FILE__, __LINE__);
if (g_iOC_CLEANUP_Called != TRUE)
{
// turn logging back on if we need to
// get the debug level from the iis.inf
if (g_GlobalFastLoad)
{
GetDebugLevelFromInf(g_pTheApp->m_hInfHandle);
}
}
g_iOC_CLEANUP_Called = TRUE;
dwOcEntryReturn = OC_CLEANUP_Func(ComponentId,SubcomponentId,Function,Param1,Param2);
LogHeapState(FALSE, __FILE__, __LINE__);
break;
default:
g_iOC_DEFAULT_Called = TRUE;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_(DEFAULT):"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
dwOcEntryReturn = 0;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Type=0x%x. Return=%d\n"), ComponentId, SubcomponentId, Function, dwOcEntryReturn));
break;
}
return(dwOcEntryReturn);
}
// -----------------------------------------------------
// Retrive the original state of the subcomponent
// -----------------------------------------------------
STATUS_TYPE GetSubcompInitStatus(LPCTSTR SubcomponentId)
{
STATUS_TYPE nStatus = ST_UNINSTALLED;
BOOL OriginalState;
#ifdef _CHICAGO_
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_FTP].szComponentName ) == 0)
{return nStatus;}
#endif //_CHICAGO_
// Get the original state from the Helper Routines (which get it from the registry)
OriginalState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_ORIGINAL);
if (OriginalState == 1) {nStatus = ST_INSTALLED;}
if (OriginalState == 0) {nStatus = ST_UNINSTALLED;}
return nStatus;
}
void DebugOutAction(LPCTSTR SubcomponentId, ACTION_TYPE nAction)
{
switch (nAction)
{
case AT_DO_NOTHING:
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Action of [%s]\t= AT_DO_NOTHING.\n"), SubcomponentId));
break;
case AT_REMOVE:
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Action of [%s]\t= AT_REMOVE.\n"), SubcomponentId));
break;
case AT_INSTALL_FRESH:
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Action of [%s]\t= AT_INSTALL_FRESH.\n"), SubcomponentId));
break;
case AT_INSTALL_UPGRADE:
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Action of [%s]\t= AT_INSTALL_UPGRADE.\n"), SubcomponentId));
break;
case AT_INSTALL_REINSTALL:
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Action of [%s]\t= AT_INSTALL_REINSTALL.\n"), SubcomponentId));
break;
default:
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Action of [%s]\t= UN_DEFINED.\n"), SubcomponentId));
break;
}
return;
}
// ---------------------------------------------------------
// OriginalState = 1 (means that it was previously installed and exists on the computer)
// OriginalState = 0 (means that it does not exist on the computer)
//
// CurrentState = 1 (means please install the subcomponent)
// CurrentState = 0 (means please remove the subcomponent)
// ---------------------------------------------------------
ACTION_TYPE GetSubcompAction(LPCTSTR SubcomponentId, int iLogResult)
{
ACTION_TYPE nReturn = AT_DO_NOTHING;
BOOL CurrentState,OriginalState;
OriginalState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_ORIGINAL);
CurrentState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_CURRENT);
// if already installed and we want to remove it, then remove it
if (OriginalState == 1 && CurrentState == 0) {nReturn = AT_REMOVE;}
// if not installed and we want to install it, then install it.
if (OriginalState == 0 && CurrentState == 1) {nReturn = AT_INSTALL_FRESH;}
// if already installed and we want to install it, then Gee i dunno.
// it could be a bunch of things
if (OriginalState == 1 && CurrentState == 1)
{
if (g_pTheApp->m_eInstallMode == IM_UPGRADE) {nReturn = AT_INSTALL_UPGRADE;}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_REINSTALL) {nReturn = AT_INSTALL_REINSTALL;}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_ADDREMOVE) {nReturn = AT_DO_NOTHING;}
}
if (iLogResult)
{
TCHAR szTempString[50];
_tcscpy(szTempString, _T("UN_DEFINED"));
switch (nReturn)
{
case AT_DO_NOTHING:
_tcscpy(szTempString, _T("AT_DO_NOTHING"));
break;
case AT_REMOVE:
_tcscpy(szTempString, _T("AT_REMOVE"));
break;
case AT_INSTALL_FRESH:
_tcscpy(szTempString, _T("AT_INSTALL_FRESH"));
break;
case AT_INSTALL_UPGRADE:
_tcscpy(szTempString, _T("AT_INSTALL_UPGRADE"));
break;
case AT_INSTALL_REINSTALL:
_tcscpy(szTempString, _T("AT_INSTALL_REINSTALL"));
break;
default:
_tcscpy(szTempString, _T("UN_DEFINED"));
break;
}
if (_tcsicmp(SubcomponentId, _T("iis")) == 0)
{
// use two tabs
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Action of [%s]\t\t= %s. Original=%d, Current=%d.\n"), SubcomponentId, szTempString, OriginalState, CurrentState));
}
else
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Action of [%s]\t= %s. Original=%d, Current=%d.\n"), SubcomponentId, szTempString, OriginalState, CurrentState));
}
}
return nReturn;
}
BOOL GetDataFromMetabase(LPCTSTR szPath, int nID, LPBYTE Buffer, int BufSize)
{
BOOL bFound = FALSE;
DWORD attr, uType, dType, cbLen;
CMDKey cmdKey;
cmdKey.OpenNode(szPath, TRUE);
if ( (METADATA_HANDLE)cmdKey )
{
bFound = cmdKey.GetData(nID, &attr, &uType, &dType, &cbLen, (PBYTE)Buffer, BufSize);
cmdKey.Close();
}
else
{
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetDataFromMetabase():%s:ID=%d.Could not open node.\n"),szPath,nID));
}
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetDataFromMetabase():%s:ID=%d.ret=%d.\n"),szPath,nID,bFound));
return (bFound);
}
void SetIISSetupMode(DWORD dwSetupMode)
{
if (g_pTheApp->m_fInvokedByNT)
{
g_pTheApp->DefineSetupModeOnNT();
}
else
{
g_pTheApp->m_dwSetupMode = dwSetupMode;
}
if (g_pTheApp->m_dwSetupMode & SETUPMODE_UPGRADE){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_UPGRADE\n")));}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_UPGRADEONLY){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_UPGRADE | SETUPMODE_UPGRADEONLY\n")));}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_ADDEXTRACOMPS){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_UPGRADE | SETUPMODE_ADDEXTRACOMPS\n")));}
if (g_pTheApp->m_dwSetupMode & SETUPMODE_MAINTENANCE){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_MAINTENANCE\n")));}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_ADDREMOVE){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_MAINTENANCE | SETUPMODE_ADDREMOVE\n")));}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_REINSTALL){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_MAINTENANCE | SETUPMODE_REINSTALL\n")));}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_REMOVEALL){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_MAINTENANCE | SETUPMODE_REMOVEALL\n")));}
if (g_pTheApp->m_dwSetupMode & SETUPMODE_FRESH){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_FRESH\n")));}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_MINIMAL){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_FRESH | SETUPMODE_MINIMAL\n")));}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_TYPICAL){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_FRESH | SETUPMODE_TYPICAL\n")));}
if (g_pTheApp->m_dwSetupMode == SETUPMODE_CUSTOM){iisDebugOut((LOG_TYPE_TRACE, _T("SetIISSetupMode() m_dwSetupMode=SETUPMODE_FRESH | SETUPMODE_CUSTOM\n")));}
gHelperRoutines.SetSetupMode(gHelperRoutines.OcManagerContext, g_pTheApp->m_dwSetupMode);
gHelperRoutines.SetPrivateData(gHelperRoutines.OcManagerContext,_T("IISSetupMode"),(PVOID)&(g_pTheApp->m_dwSetupMode),sizeof(DWORD),REG_DWORD);
return;
}
BOOL ToBeInstalled(LPCTSTR ComponentId, LPCTSTR SubcomponentId)
{
BOOL fReturn = FALSE;
if ( SubcomponentId )
{
BOOL CurrentState,OriginalState;
OriginalState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_ORIGINAL);
CurrentState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_CURRENT);
if (OriginalState == 0 && CurrentState == 1)
{fReturn = TRUE;}
}
return fReturn;
}
void CustomFTPRoot(LPCTSTR szFTPRoot)
{
g_pTheApp->m_csPathFTPRoot = szFTPRoot;
SetupSetDirectoryId_Wrapper(g_pTheApp->m_hInfHandle, 32769, g_pTheApp->m_csPathFTPRoot);
gHelperRoutines.SetPrivateData(gHelperRoutines.OcManagerContext,_T("PathFTPRoot"),(PVOID)(LPCTSTR)g_pTheApp->m_csPathFTPRoot,(g_pTheApp->m_csPathFTPRoot.GetLength() + 1) * sizeof(TCHAR),REG_SZ);
return;
}
void CustomWWWRoot(LPCTSTR szWWWRoot)
{
TCHAR szParentDir[_MAX_PATH], szDir[_MAX_PATH];
g_pTheApp->m_csPathWWWRoot = szWWWRoot;
InetGetFilePath(szWWWRoot, szParentDir);
g_pTheApp->m_csPathInetpub = szParentDir;
SetupSetDirectoryId_Wrapper(g_pTheApp->m_hInfHandle, 32773, szParentDir);
AppendDir(szParentDir, _T("iissamples"), szDir);
g_pTheApp->m_csPathIISSamples = szDir;
AppendDir(szParentDir, _T("webpub"), szDir);
g_pTheApp->m_csPathWebPub = szDir;
AppendDir(szParentDir, _T("scripts"), szDir);
g_pTheApp->m_csPathScripts = szDir;
AppendDir(szParentDir, _T("ASPSamp"), szDir);
g_pTheApp->m_csPathASPSamp = szDir;
g_pTheApp->m_csPathAdvWorks = g_pTheApp->m_csPathASPSamp + _T("\\AdvWorks");
CString csPathScripts = g_pTheApp->m_csPathIISSamples + _T("\\Scripts");
gHelperRoutines.SetPrivateData(gHelperRoutines.OcManagerContext,_T("PathScripts"),(PVOID)(LPCTSTR)csPathScripts,(csPathScripts.GetLength() + 1) * sizeof(TCHAR),REG_SZ);
gHelperRoutines.SetPrivateData(gHelperRoutines.OcManagerContext,_T("PathWWWRoot"),(PVOID)(LPCTSTR)g_pTheApp->m_csPathWWWRoot,(g_pTheApp->m_csPathWWWRoot.GetLength() + 1) * sizeof(TCHAR),REG_SZ);
gHelperRoutines.SetPrivateData(gHelperRoutines.OcManagerContext,_T("PathIISSamples"),(PVOID)(LPCTSTR)g_pTheApp->m_csPathIISSamples,(g_pTheApp->m_csPathIISSamples.GetLength() + 1) * sizeof(TCHAR),REG_SZ);
// Set inf file dir id's
SetupSetDirectoryId_Wrapper(g_pTheApp->m_hInfHandle, 32770, g_pTheApp->m_csPathWWWRoot);
SetupSetDirectoryId_Wrapper(g_pTheApp->m_hInfHandle, 32771, g_pTheApp->m_csPathIISSamples);
SetupSetDirectoryId_Wrapper(g_pTheApp->m_hInfHandle, 32772, g_pTheApp->m_csPathScripts);
SetupSetDirectoryId_Wrapper(g_pTheApp->m_hInfHandle, 32779, g_pTheApp->m_csPathWebPub);
return;
}
void StartInstalledServices(void)
{
ACTION_TYPE atWWW = GetSubcompAction(STRING_iis_www, FALSE);
ACTION_TYPE atFTP = GetSubcompAction(g_ComponentList[COMPONENT_IIS_FTP].szComponentName, FALSE);
STATUS_TYPE stFTP = GetSubcompInitStatus(g_ComponentList[COMPONENT_IIS_FTP].szComponentName );
STATUS_TYPE stWWW = GetSubcompInitStatus(STRING_iis_www);
iisDebugOut_Start(_T("StartInstalledServices()"), LOG_TYPE_TRACE);
if (atWWW == AT_INSTALL_FRESH || atWWW == AT_INSTALL_UPGRADE || atWWW == AT_INSTALL_REINSTALL || (stWWW == ST_INSTALLED && atWWW != AT_REMOVE))
{
InetStartService(_T("W3SVC"));
}
#ifndef _CHICAGO_
if (atFTP == AT_INSTALL_FRESH || atFTP == AT_INSTALL_UPGRADE || atFTP == AT_INSTALL_REINSTALL || (stFTP == ST_INSTALLED && atFTP != AT_REMOVE))
{
InetStartService(_T("MSFTPSVC"));
}
#endif // _CHICAGO_
if (g_pTheApp->m_eOS == OS_W95 || g_pTheApp->m_eNTOSType == OT_NTW)
{
ACTION_TYPE atPWMGR = GetSubcompAction(STRING_iis_pwmgr, FALSE);
if (atPWMGR == AT_INSTALL_FRESH ||
atPWMGR == AT_INSTALL_UPGRADE ||
atPWMGR == AT_INSTALL_REINSTALL)
{
CString csProgram;
csProgram = g_pTheApp->m_csSysDir + _T("\\pwstray.exe");
if (IsFileExist(csProgram))
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof( STARTUPINFO );
CreateProcess( csProgram, NULL, NULL, NULL,FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi );
}
}
}
return;
}
void GetShortDesc(LPCTSTR SubcomponentId, LPTSTR szShortDesc)
{
INFCONTEXT Context;
TCHAR szSection[_MAX_PATH] = _T("Strings");
TCHAR szKey[_MAX_PATH] = _T("SDESC_");
TCHAR szString[_MAX_PATH] = _T("");
int nLen=0;
_tcscat(szKey, SubcomponentId);
*szShortDesc = _T('\0');
if (SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, szSection, szKey, &Context))
{
SetupGetStringField(&Context, 1, szString, _MAX_PATH, NULL);
nLen = _tcslen(szString);
if (*szString == _T('"') && *_tcsninc(szString, nLen-1) == _T('"'))
{_tcsncpy(szShortDesc, _tcsinc(szString), nLen-2);}
else
{_tcscpy(szShortDesc, szString);}
}
return;
}
void ParseCmdLine(void)
{
TSTR strCmdLine;
if ( !strCmdLine.Copy( GetCommandLine() ) )
{
// Failed to load string
return;
}
if ( strCmdLine.SubStringExists( _T("sysoc.inf"), FALSE ) )
{
g_pTheApp->m_fInvokedByNT = TRUE;
}
}
// DuplicateSetupStructure
//
// Copy the setup structure, so that we can give it to the COM and DTC guys.
//
BOOL
DuplicateSetupStructure(PSETUP_INIT_COMPONENT pTarget, PSETUP_INIT_COMPONENT pSource)
{
memcpy( pTarget, pSource, sizeof( SETUP_INIT_COMPONENT ) );
return TRUE;
}
// -----------------------------
// handles the OC_INIT_COMPONENT call from ocmanager
//
// 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.
//
//
// Param1 = unused
// Param2 = points to SETUP_INIT_COMPONENT structure
// Return code = is Win32 error indicating outcome.
//
// -----------------------------
DWORD_PTR OC_INIT_COMPONENT_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] Start.\n"), ComponentId, SubcomponentId));
DWORD_PTR dwOcEntryReturn = 0;
// Set the global OCMInfo pointer
if ( !DuplicateSetupStructure( &g_OCMInfo, (PSETUP_INIT_COMPONENT)Param2 ) )
{
// Failed to duplicate
return ERROR_CANCELLED;
}
// set flag if running as admin
BOOL g_fAdministrator = RunningAsAdministrator();
// Parse The Command line and set global Variables.
ParseCmdLine();
// first of all display iis.dll to avoid any confusion!
DisplayVerOnCurrentModule();
g_pTheApp->m_hInfHandle = g_OCMInfo.ComponentInfHandle;
if (g_OCMInfo.ComponentInfHandle == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, _T("Invalid inf handle."), _T("IIS Setup"), MB_OK | MB_SETFOREGROUND);
iisDebugOut((LOG_TYPE_ERROR, _T("g_OCMInfo.ComponentInfHandle FAILED")));
dwOcEntryReturn = ERROR_CANCELLED;
goto OC_INIT_COMPONENT_Func_Exit;
}
g_pTheApp->m_fNTOperationFlags = g_OCMInfo.SetupData.OperationFlags;
g_pTheApp->m_fNtWorkstation = g_OCMInfo.SetupData.ProductType == PRODUCT_WORKSTATION;
if (g_OCMInfo.SetupData.OperationFlags & SETUPOP_STANDALONE)
{
g_pTheApp->m_fNTGuiMode = FALSE;
}
else
{
g_pTheApp->m_fNTGuiMode = TRUE;
}
g_pTheApp->m_csPathSource = g_OCMInfo.SetupData.SourcePath;
gHelperRoutines = g_OCMInfo.HelperRoutines;
g_pTheApp->m_fInvokedByNT = g_pTheApp->m_fNTGuiMode;
// get the handle to the unattended file (the answer file)
// if this is a migration from win95, then there will be
// a section in here called [InternetServer] which will
// point to the win95 migration.dat file.
g_pTheApp->m_hUnattendFile = gHelperRoutines.GetInfHandle(INFINDEX_UNATTENDED, gHelperRoutines.OcManagerContext);
if (_tcsicmp(g_OCMInfo.SetupData.UnattendFile,_T("")) != 0 && g_OCMInfo.SetupData.UnattendFile != NULL)
{
g_pTheApp->m_csUnattendFile = g_OCMInfo.SetupData.UnattendFile;
}
g_pTheApp->m_fUnattended = (((DWORD)g_OCMInfo.SetupData.OperationFlags) & SETUPOP_BATCH);
if (g_pTheApp->m_fUnattended)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Set UnAttendFlag:ON (File='%s')\n"), g_pTheApp->m_csUnattendFile));
if (g_pTheApp->m_hUnattendFile == INVALID_HANDLE_VALUE || g_pTheApp->m_hUnattendFile == NULL)
{iisDebugOut((LOG_TYPE_WARN, _T("WARNING: There should have been an unattended file but there is none.\n")));}
}
else
{iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("Set UnAttendFlag:OFF (File='%s')\n"), g_pTheApp->m_csUnattendFile));}
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("CmdLine=%s"), GetCommandLine()));
// make sure that this is always set -- so that
// you never get the iis welcome, min\typ\custom, dir selection, End pages.
g_pTheApp->m_fInvokedByNT = TRUE;
if (g_pTheApp->m_fInvokedByNT) {g_pTheApp->m_bAllowMessageBoxPopups = FALSE;}
//if (g_SpecialFlagForDebug) {g_pTheApp->m_bAllowMessageBoxPopups = TRUE;}
// get the debug level from the iis.inf
GetDebugLevelFromInf(g_pTheApp->m_hInfHandle);
if (!g_pTheApp->m_fNTGuiMode)
{
if (g_GlobalFastLoad)
{
// change it so that there is no logging during the load process.
// so that the iis.dll loads up faster.
// g_pTheApp->m_fNTGuiMode
g_GlobalDebugLevelFlag = LOG_TYPE_WARN;
}
}
// Read .inf file
// and set some globals from the informatin in there.
ReadGlobalsFromInf(g_pTheApp->m_hInfHandle);
if (g_GlobalGuiOverRide)
{
g_pTheApp->m_fNTGuiMode = TRUE;
SetIISSetupMode(SETUPMODE_UPGRADEONLY);
}
// ----------------------------------
// handle win95 migration
//
// win95 migration is handled this way.
// 1. on the win95 side a file is generated. it is a actually a
// setupapi type .inf fie.
// 2. win95 migration dll creates the file and sticks the path to where
// it is in the answerfile.txt file. should look like this
// [InternetServer]
// Win95MigrateDll=d:\winnt\system32\setup\????\something.dat
//
// 3. so we should, open the answer file,
// find the [InternetServer] section
// have setupapi install it
//
// 4. that will put appropriate registry values into the registry.
//
// ----------------------------------
HandleWin95MigrateDll();
if (!g_fAdministrator)
{
g_pTheApp->MsgBox(NULL, IDS_NOT_ADMINISTRATOR, MB_OK, TRUE);
dwOcEntryReturn = ERROR_CANCELLED;
goto OC_INIT_COMPONENT_Func_Exit;
}
// Call this stuff after setting m_fNTGuiMode and m_fNtWorkstation and m_fInvokedByNT
// since it maybe used in InitApplication().
if ( FALSE == g_pTheApp->InitApplication() )
{
g_pTheApp->DumpAppVars();
iisDebugOut((LOG_TYPE_ERROR, _T("FAILED")));
// setup should be terminated.
dwOcEntryReturn = ERROR_CANCELLED;
goto OC_INIT_COMPONENT_Func_Exit;
}
if ( g_pTheApp->m_eInstallMode == IM_MAINTENANCE )
{g_pTheApp->m_fEULA = TRUE;}
// If NT4 upgrade, enable iisadmin so we can read some data
// from it
if ( g_pTheApp->IsUpgrade() &&
( g_pTheApp->GetUpgradeVersion() <= 4 ) )
{
// Remove iisadmin dependency on ntlmssp, so we can use the old metabase now
if ( !ChangeServiceDependency(SERVICENAME_IISADMIN,
FALSE,
SERVICENAME_NTLMSSP) )
{
// We have seen this error io pending during upgrade if the service
// does not exist, so ignore it
if ( ( GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST ) &&
( GetLastError() != ERROR_IO_PENDING ) )
{
iisDebugOut((LOG_TYPE_WARN, _T("Could not remove IISAdmin dependency on NTLMSSP, GLE=0x%8x\n"), GetLastError() ));
}
}
}
// check if the .inf we are looking at is the right inf for what the machine is running as
//if (FALSE == CheckIfPlatformMatchesInf(g_pTheApp->m_hInfHandle))
//{
// dwOcEntryReturn = ERROR_CANCELLED;
// goto OC_INIT_COMPONENT_Func_Exit;
//}
// something like "this build requires nt build 1899 or something"
CheckSpecificBuildinInf(g_pTheApp->m_hInfHandle);
// Check for old gopher!
if (FALSE == CheckForOldGopher(g_pTheApp->m_hInfHandle))
{
dwOcEntryReturn = ERROR_CANCELLED;
goto OC_INIT_COMPONENT_Func_Exit;
}
// See if user configured anything
// must happen after g_pTheApp->InitApplication
// but before SetDIRIDforThisInf!
ReadUserConfigurable(g_pTheApp->m_hInfHandle);
//
// Set up the DIRIDs for our .inf file
// these are very very important and can get changed throughout the program
//
SetDIRIDforThisInf(g_pTheApp->m_hInfHandle,TRUE);
//
// Set global ocm private data for other components to find out
// (during installation) where our inetpub or inetsrv dir is located..
SetOCGlobalPrivateData();
dwOcEntryReturn = NO_ERROR;
// Check if There are pending reboot operations...
if (LogPendingReBootOperations() != ERROR_SUCCESS)
{dwOcEntryReturn = ERROR_CANCELLED;}
// if we already did some win95 stuff then don't need to do this
// do this only in gui mode
if (g_pTheApp->m_fNTGuiMode)
{
if (!g_pTheApp->m_bWin95Migration){CheckIfWeNeedToMoveMetabaseBin();}
}
// Get the last section to be called.
_tcscpy(g_szLastSectionToGetCalled, _T(""));
GetLastSectionToBeCalled();
ProcessSection(g_pTheApp->m_hInfHandle, _T("OC_INIT_COMPONENT"));
Check_For_DebugServiceFlag();
TestAfterInitApp();
OC_INIT_COMPONENT_Func_Exit:
g_pTheApp->DumpAppVars();
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d \n"), ComponentId, SubcomponentId, dwOcEntryReturn));
return dwOcEntryReturn;
}
// function: IsComponentCheckedbyDefault
//
// Return whether this particular component is suppose to be installed by "default".
// By default here means that if you check all the components, is this one suppose to be
// automatically selected?
//
// Parameters:
// szComponentName
//
// Return
// TRUE - This component should install by default
// FALSE - This component should NOT install by default
BOOL
IsComponentCheckedbyDefault( LPCTSTR szComponentName )
{
BOOL bInstallbyDefault = FALSE;
DWORD dwCurrent;
ASSERT( szComponentName );
for ( dwCurrent = 0;
dwCurrent < COMPONENT_ENDOFLIST;
dwCurrent++ )
{
if ( _tcscmp( szComponentName,
g_ComponentList[ dwCurrent ].szComponentName ) == 0 )
{
bInstallbyDefault = g_ComponentList[ dwCurrent ].bSelectedByDefault;
break;
}
}
return bInstallbyDefault;
}
//
// FUNCTION: FatWndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the Fat warning Window.
//
LRESULT CALLBACK FatWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TSTR_PATH strWinHelpLocation;
switch (message) {
case WM_HELP:
if ( strWinHelpLocation.RetrieveWindowsDir() &&
strWinHelpLocation.PathAppend( PATH_IISHELP ) &&
strWinHelpLocation.Append( _T("::") ) &&
strWinHelpLocation.Append( PATH_IISHELP_FAT_NTFS_WARNING ) )
{
HtmlHelp(GetDesktopWindow(), strWinHelpLocation.QueryStr(), HH_DISPLAY_TOPIC, NULL);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//
// ShowFatWarning
//
// Display the Fat warning
//
// This window is used as a shim, between the OCM window
// and the MessageBox that we are going to pop up. The reason
// we need this is to intercept the WM_HELP message.
//
BOOL ShowFatWarning( LPBOOL pbQuit, LPTSTR szCation, LPTSTR szText )
{
WNDCLASSEX wcex;
HWND hWnd = NULL;
HWND hOCMWnd = NULL;
BOOL bRet = FALSE;
INT iMessageReturn;
TCHAR szWindowClass[] = L"OCM_IIS_WARNING_FAT";
ATOM Atom = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = FatWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = (HINSTANCE) g_MyModuleHandle;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
Atom = RegisterClassEx(&wcex);
if ( Atom == 0 )
{
// Failure
return FALSE;
}
hOCMWnd = GetForegroundWindow();
hWnd = CreateWindow( (LPTSTR) Atom, // Class Name/Atom
NULL, // Window Name
0, // Style
0, // X
0, // Y
0, // Width
0, // Height
hOCMWnd, // Parent
NULL, // Menu
NULL, // hInstance (ignored on .net)
NULL);
if ( hWnd && hOCMWnd )
{
// Disable OCM Window
EnableWindow( hOCMWnd, FALSE);
iMessageReturn = MessageBox ( hWnd, // Parent Handle
szText, // Text
szCation, // Caption
MB_ICONWARNING |
MB_OKCANCEL |
MB_OK |
MB_HELP);
*pbQuit = !( iMessageReturn == IDOK );
bRet = TRUE;
// ReEnable OCM Window and set to Foreground
EnableWindow( hOCMWnd, TRUE);
SetForegroundWindow( hOCMWnd );
}
if ( hWnd )
{
// Destroy window we created, it is no longer needed
DestroyWindow( hWnd );
}
if ( Atom )
{
// Unregister class needed
UnregisterClass( (LPTSTR) Atom, (HINSTANCE) g_MyModuleHandle );
}
return bRet;
}
// CheckandShowFatWarning
//
// If we are being installed on a FAT partition, then show a warning
// telling the user that they are more secure on NTFS, and should choose
// that
//
// Parameters
// bpQuit [out] - Should we quit (ie. user selected 'Cancel')
//
// Return Value
// TRUE - Successfully called
// FALSE - Failure during call
BOOL CheckandShowFatWarning( LPBOOL pbQuit )
{
TSTR strMessage;
TSTR strCaption;
BOOL bPreservesAcls = FALSE;
if ( !DoesTheInstallDrivePreserveAcls( &bPreservesAcls ) )
{
return FALSE;
}
if ( bPreservesAcls )
{
// We can exit, since we preserve acls
*pbQuit = FALSE;
return TRUE;
}
if ( !strMessage.LoadString( IDS_ERROR_INSTALLONFAT ) ||
!strCaption.LoadString( IDS_PRODUCT_IIS ) )
{
return FALSE;
}
return ShowFatWarning( pbQuit,
strCaption.QueryStr(),
strMessage.QueryStr() );
}
// ShouldWeChangeStateonFAT
//
// This function will take the state of the common component
// and determine if we should show a FAT warning.
//
// This is the biggest hack, so let me explain how it works
// The problem: When we show this error, we must show it only once, and
// for all of the calls resulting from that click we must
// return the appropriate return value. For all subsequent
// requests we must return success. Because it is almost
// imposible to know the difference between requests, we have
// all the logic below
//
// Directly clicked:
// You will be queried twice, and it is okay to return failure for only
// one of those, so that is what we do
//
// Dependency click:
// When someone else requiresyou, you can do the same as when you are
// clicked directly
//
// Hireactical click (your parent is selected):
// When you parent is selected you must return the same value for all of
// the queried you receive. Your first and last message will have this
// OCQ_DEPENDENT_SELECTION flag set. So that is why we keep track of that
// and whether we are in the middle of the notification or not
//
// Return Values
// 0 - Deny the change
// 1 - Approve the change
//
DWORD
ShouldWeChangeStateonFAT(DWORD dwFlags)
{
static BOOL bHaveAskedFatQuestion = FALSE;
static BOOL bDontInstall = FALSE;
static BOOL bParentCall = FALSE;
// Have we already queried the user?
if ( bHaveAskedFatQuestion )
{
// Was our parent selected?
if ( bParentCall )
{
if ( dwFlags & OCQ_DEPENDENT_SELECTION )
{
bParentCall = FALSE;
return bDontInstall ? 0 : 1;
}
else
{
return bDontInstall ? 0 : 1;
}
}
return 1;
}
bHaveAskedFatQuestion = TRUE;
if ( !CheckandShowFatWarning( &bDontInstall ) )
{
// Failed to do query, fail on change
return 0;
}
if ( dwFlags & OCQ_DEPENDENT_SELECTION )
{
bParentCall = TRUE;
}
return bDontInstall ? 0 : 1;
}
// ShouldBlockInstall
//
// This checks if we should block the install based on the Group Policy to
// not allow instalation
//
// Return Values:
// TRUE - Block instalation
// FALSE - Do not block instalation
//
BOOL ShouldBlockInstall( BOOL bShowUI )
{
static BOOL bBlockInstall = FALSE;
static BOOL bCheckedRegistry = FALSE;
if ( !bCheckedRegistry )
{
CRegistry Reg;
CRegValue Value;
DWORD dwRegValue;
if ( Reg.OpenRegistry( HKEY_LOCAL_MACHINE,
REG_GROUPPOLICY_BLOCKINSTALL_PATH,
KEY_READ ) )
{
if ( Reg.ReadValue( REG_GROUPPOLICY_BLOCKINSTALL_NAME,
Value ) &&
Value.GetDword( &dwRegValue ) )
{
// If the reg key is one, then block install
bBlockInstall = ( dwRegValue == 1 );
}
}
if ( bBlockInstall )
{
TSTR strText;
TSTR strCaption;
if ( bShowUI &&
strText.LoadString( IDS_ERROR_GROUPPOLICY ) &&
strCaption.LoadString( IDS_PRODUCT_IIS ) )
{
// The first time this happens, spit up an error
// Nothing really to do with an error, so ignore it
MessageBox( NULL,
strText.QueryStr(),
strCaption.QueryStr(),
MB_OK | MB_ICONEXCLAMATION );
}
}
bCheckedRegistry = TRUE;
}
return bBlockInstall;
}
// ShowFATErrorforSaKit
//
// The Server Appliance Kit does not install on FAT, so show
// a warning when it is selected
//
void ShowFATErrorforSaKit()
{
TSTR strError;
TSTR strTitle;
if ( !strError.LoadString( IDS_ERROR_SAKITONFAT ) ||
!strTitle.LoadString( IDS_PRODUCT_IIS ) )
{
return;
}
MessageBox( NULL,
strError.QueryStr(),
strTitle.QueryStr(),
MB_OK | MB_ICONEXCLAMATION );
}
DWORD_PTR OC_QUERY_CHANGE_SEL_STATE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD dwOcEntryReturn = 0;
DWORD dwCurrentState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_CURRENT);
BOOL bOriginalyOn = gHelperRoutines.QuerySelectionState(
gHelperRoutines.OcManagerContext,
SubcomponentId,
OCSELSTATETYPE_ORIGINAL) == 1;
BOOL bDrivePreservesAcls;
if ( SubcomponentId && // Componet is specified
( !bOriginalyOn ) && // It was originally off
( Param1 == 0x1 ) &&
( !g_pTheApp->m_fNTGuiMode ) &&
( !g_pTheApp->m_fUnattended ) &&
DoesTheInstallDrivePreserveAcls( &bDrivePreservesAcls ) &&
!bDrivePreservesAcls )
{
if ( _tcsicmp(SubcomponentId,
g_ComponentList[COMPONENT_IIS_COMMON].szComponentName ) == 0 )
{
return ShouldWeChangeStateonFAT( (UINT) (ULONG_PTR) Param2 );
}
else
if ( _tcsicmp(SubcomponentId,
g_ComponentList[COMPONENT_SAKIT_WEB].szComponentName ) == 0 )
{
ShowFATErrorforSaKit();
return 0;
}
}
if ( SubcomponentId && // Componet is specified
( !bOriginalyOn ) && // It was originally off
( Param1 == 0x1 ) &&
( !g_pTheApp->m_fNTGuiMode ) &&
( !g_pTheApp->m_fUnattended ) &&
( _tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_COMMON].szComponentName ) == 0 ) )
{
if ( ShouldBlockInstall( !g_pTheApp->m_fUnattended ) )
{
return 0;
}
}
dwOcEntryReturn = 1;
if (SubcomponentId)
{
//iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] Param1=%d, Param2=%d, Original=%d, Current=%d\n"), ComponentId, SubcomponentId, Param1, Param2,OriginalState,CurrentState));
if ( bOriginalyOn )
{
if ((BOOL)Param1)
{
dwOcEntryReturn = 1;
if (_tcsicmp(SubcomponentId, STRING_iis_inetmgr) == 0 || _tcsicmp(SubcomponentId, STRING_iis_www) == 0 || _tcsicmp(SubcomponentId, STRING_iis_pwmgr) == 0 )
{
// check if tcpip is installed
g_pTheApp->IsTCPIPInstalled();
if (g_pTheApp->m_fTCPIP == FALSE)
{
g_pTheApp->MsgBox(NULL, IDS_TCPIP_NEEDED_ON_OPTION, MB_OK, TRUE);
dwOcEntryReturn = 0;
}
}
}
else
{
// In upgrade case, we don't allow user to uncheck previously installed components
if (g_pTheApp->m_eInstallMode == IM_UPGRADE)
{dwOcEntryReturn = 0;}
}
}
else
{
if (_tcsicmp(SubcomponentId, STRING_iis_inetmgr) == 0 || _tcsicmp(SubcomponentId, STRING_iis_www) == 0 || _tcsicmp(SubcomponentId, STRING_iis_pwmgr) == 0 )
{
if ((BOOL)Param1)
{
//
// if we are turning ON then we NEED TCPIP
//
// check if tcpip is installed
g_pTheApp->IsTCPIPInstalled();
if (g_pTheApp->m_fTCPIP == FALSE)
{
g_pTheApp->MsgBox(NULL, IDS_TCPIP_NEEDED_ON_OPTION, MB_OK, TRUE);
dwOcEntryReturn = 0;
}
}
}
}
}
// Do not enable some of the components, if they are being selected because their parent is being selected
// Param1 == 0x1 -> This tells us it is being turned on
// Param2 & OCQ_DEPENDENT_SELECTION -> Tells us that it is selected from its parent
// !(Param2 & OCQ_ACTUAL_SELECTION) -> Tells us it was not selected itself
if ( ( (BOOL) Param1 ) &&
( ( (UINT) (ULONG_PTR) Param2 ) & OCQ_DEPENDENT_SELECTION ) &&
!( ( (UINT) (ULONG_PTR) Param2 ) & OCQ_ACTUAL_SELECTION ) &&
!IsComponentCheckedbyDefault( SubcomponentId )
)
{
// Deny request to change state
dwOcEntryReturn = 0;
}
//
// if we are running on Whistler personal, then return denied.
// so that no other component can turn us on! or think that they're going to turn us on.
//
if (IsWhistlerPersonal())
{
dwOcEntryReturn = 0;
}
if (dwOcEntryReturn == 0)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d (denied) \n"), ComponentId, SubcomponentId, dwOcEntryReturn));
}
else
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d (approved)\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
}
return dwOcEntryReturn;
}
//
// gets called right before we show your page!
//
DWORD_PTR OC_QUERY_SKIP_PAGE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] Start.\n"), ComponentId, SubcomponentId));
DWORD_PTR dwOcEntryReturn = 0;
TCHAR szTempString[50];
_tcscpy(szTempString, _T(""));
switch (g_pTheApp->m_dwSetupMode)
{
case SETUPMODE_UPGRADEONLY:
_tcscpy(szTempString, _T("SETUPMODE_UPGRADEONLY"));
dwOcEntryReturn = 1;
break;
case SETUPMODE_REINSTALL:
_tcscpy(szTempString, _T("SETUPMODE_REINSTALL"));
dwOcEntryReturn = 1;
break;
case SETUPMODE_REMOVEALL:
_tcscpy(szTempString, _T("SETUPMODE_REMOVEALL"));
dwOcEntryReturn = 1;
break;
case SETUPMODE_MINIMAL:
_tcscpy(szTempString, _T("SETUPMODE_MINIMAL"));
dwOcEntryReturn = 1;
break;
case SETUPMODE_TYPICAL:
_tcscpy(szTempString, _T("SETUPMODE_TYPICAL"));
dwOcEntryReturn = 1;
break;
case SETUPMODE_ADDEXTRACOMPS:
_tcscpy(szTempString, _T("SETUPMODE_ADDEXTRACOMPS"));
dwOcEntryReturn = 0;
break;
case SETUPMODE_ADDREMOVE:
_tcscpy(szTempString, _T("SETUPMODE_ADDREMOVE"));
dwOcEntryReturn = 0;
break;
case SETUPMODE_CUSTOM:
_tcscpy(szTempString, _T("SETUPMODE_CUSTOM"));
dwOcEntryReturn = 0;
break;
}
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. g_pTheApp->m_dwSetupMode=%x (%s), dwOcEntryReturn=%d\n"), ComponentId, SubcomponentId, g_pTheApp->m_dwSetupMode, szTempString, dwOcEntryReturn));
return dwOcEntryReturn;
}
// ----------------------------------------
// 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.
// Logic is not correct here !!!
// ----------------------------------------
DWORD_PTR OC_CALC_DISK_SPACE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD_PTR dwOcEntryReturn = 0;
BOOL bTempFlag = FALSE;
TCHAR SectionName[128];
dwOcEntryReturn = NO_ERROR;
if (SubcomponentId)
{
bTempFlag = TRUE;
if ( Param1 )
{
// add component
_stprintf(SectionName,TEXT("%s_%s"),SubcomponentId, _T("install"));
bTempFlag = SetupAddInstallSectionToDiskSpaceList(Param2,g_pTheApp->m_hInfHandle,NULL,SectionName,0,0);
}
else
{
// removing component
// Comment this out per PatSt, 3/5/97, and change it to the install list
//_stprintf(SectionName,TEXT("%s_%s"),SubcomponentId, _T("uninstall"));
_stprintf(SectionName,TEXT("%s_%s"),SubcomponentId, _T("install"));
bTempFlag = SetupRemoveInstallSectionFromDiskSpaceList(Param2,g_pTheApp->m_hInfHandle,NULL,SectionName,0,0);
//
// check if it's something we need to warn user about
//
// in add remove case, if the user is removing w3svc or msftpsvc
// then check if clustering is installed. if clustering is installed
// then check if there are any cluster resources which have w3svc or msftpsvc as a
// resouce, if there are any, then warn the user that they must remove these cluster resources!
#ifndef _CHICAGO_
if (g_pTheApp->m_eInstallMode == IM_MAINTENANCE)
{
BOOL CurrentState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_CURRENT);
BOOL OriginalState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_ORIGINAL);
if (OriginalState == 1 && CurrentState == 0)
{
if (TRUE == DoesClusterServiceExist())
{
TCHAR * szClusterName = NULL;
WCHAR szServiceLookingFor[20];
CString MyReturnString;
CLUSTER_SVC_INFO_FILL_STRUCT MyStructOfInfo;
// check if they are trying to
// remove the W3SVC service!
if (_tcsicmp(SubcomponentId, STRING_iis_www) == 0 ||
_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_FTP].szComponentName ) == 0)
{
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_FTP].szComponentName) == 0)
{
wcscpy(szServiceLookingFor,L"MSFTPSVC");
// check for msftpsvc resource
MyStructOfInfo.szTheClusterName = szClusterName;
MyStructOfInfo.pszTheServiceType = szServiceLookingFor;
MyStructOfInfo.csTheReturnServiceResName = &MyReturnString;
MyStructOfInfo.dwReturnStatus = 0;
if (TRUE == DoClusterServiceCheck(&MyStructOfInfo))
{
g_pTheApp->MsgBox2(NULL, IDS_REMOVE_CLUS_MSFTPSVC_FIRST, *MyStructOfInfo.csTheReturnServiceResName, MB_OK | MB_SETFOREGROUND);
}
}
else
{
wcscpy(szServiceLookingFor,L"W3SVC");
// check for w3svc resource
MyStructOfInfo.szTheClusterName = szClusterName;
MyStructOfInfo.pszTheServiceType = szServiceLookingFor;
MyStructOfInfo.csTheReturnServiceResName = &MyReturnString;
MyStructOfInfo.dwReturnStatus = 0;
if (TRUE == DoClusterServiceCheck(&MyStructOfInfo))
{
g_pTheApp->MsgBox2(NULL, IDS_REMOVE_CLUS_W3SVC_FIRST, *MyStructOfInfo.csTheReturnServiceResName, MB_OK | MB_SETFOREGROUND);
}
else
{
// check for smtp resources
wcscpy(szServiceLookingFor,L"SMTPSVC");
if (TRUE == DoClusterServiceCheck(&MyStructOfInfo))
{
g_pTheApp->MsgBox2(NULL, IDS_REMOVE_CLUS_W3SVC_FIRST, *MyStructOfInfo.csTheReturnServiceResName, MB_OK | MB_SETFOREGROUND);
}
else
{
// check for nntp resources
wcscpy(szServiceLookingFor,L"NNTPSVC");
if (TRUE == DoClusterServiceCheck(&MyStructOfInfo))
{
g_pTheApp->MsgBox2(NULL, IDS_REMOVE_CLUS_W3SVC_FIRST, *MyStructOfInfo.csTheReturnServiceResName, MB_OK | MB_SETFOREGROUND);
}
}
}
}
}
}
}
}
#endif
}
dwOcEntryReturn = bTempFlag ? NO_ERROR : GetLastError();
}
// Display the new state of this component
if (SubcomponentId)
{
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_FTP].szComponentName) == 0 ||
_tcsicmp(SubcomponentId, STRING_iis_www) == 0)
{
GetIISCoreAction(TRUE);
}
else
{
GetSubcompAction(SubcomponentId, TRUE);
}
}
if (dwOcEntryReturn == NO_ERROR)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=NO_ERROR\n"), ComponentId, SubcomponentId));
}
else
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return='0x%x'\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
}
return dwOcEntryReturn;
}
DWORD_PTR OC_NEED_MEDIA_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD_PTR dwOcEntryReturn = 0;
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("[%1!s!,%2!s!] Start. Param1=0x%3!x!,Param2=0x%4!x!\n"), ComponentId, SubcomponentId, Param1, Param2));
dwOcEntryReturn = NO_ERROR;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
return dwOcEntryReturn;
}
// -------------------------------
// 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_PTR OC_QUEUE_FILE_OPS_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] Start.\n"), ComponentId, SubcomponentId));
DWORD_PTR dwOcEntryReturn = NO_ERROR;
g_GlobalFileQueueHandle = Param2;
g_GlobalFileQueueHandle_ReturnError = NO_ERROR;
g_GlobalTotalTickGaugeCount = 0;
if ( SubcomponentId )
{
if ( GetSubcompAction(SubcomponentId, FALSE) == AT_REMOVE )
{
// This is before we do our normal uninstall, so notify
// our component of PreUninstall
g_pComponents->PreUnInstall( SubcomponentId );
}
}
// -----------------------
// handle all removes here = the file operations only
// -----------------------
//
// Check to see if the user has chosen to "remove-all"
//
// handle all removes here.
// we need to handle it in or special order
// because we want to make sure that removeal happens in the right order.
// right order means =(considering the 'needs' relationship - since ocmanage does not handle it).
//
if (!SubcomponentId)
{
DisplayActionsForAllOurComponents(g_pTheApp->m_hInfHandle);
}
else
{
if (g_pTheApp->m_eInstallMode != IM_UPGRADE)
{
// make sure they can't mistakenly
// do these remove's during guimode!
if (!g_pTheApp->m_fNTGuiMode)
{
_tcscpy(g_szCurrentSubComponent, SubcomponentId);
if ( _tcsicmp( SubcomponentId,
g_ComponentList[COMPONENT_IIS_COMMON].szComponentName ) == 0 )
{
// If we are removing common, lets also remove core
RemoveComponent( STRING_iis_core ,1);
}
RemoveComponent( SubcomponentId ,1);
}
}
}
// ------------------------
// handle fresh and upgrade
// ------------------------
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
if (!SubcomponentId)
{
ProcessSection(g_pTheApp->m_hInfHandle, _T("OC_QUEUE_FILE_OPS"));
ACTION_TYPE atCORE = GetIISCoreAction(FALSE);
if (atCORE == AT_INSTALL_FRESH || atCORE == AT_INSTALL_UPGRADE || atCORE == AT_INSTALL_REINSTALL)
{
ProcessSection(g_pTheApp->m_hInfHandle, _T("OC_QUEUE_FILE_OPS_install.iis_core"));
dwOcEntryReturn = g_GlobalFileQueueHandle_ReturnError ? NO_ERROR : GetLastError();
}
}
else
{
ACTION_TYPE atComp = GetSubcompAction(SubcomponentId, FALSE);
if (atComp == AT_INSTALL_FRESH ||atComp == AT_INSTALL_UPGRADE || atComp == AT_INSTALL_REINSTALL)
{
TSTR strTheSectionToDo;
if ( strTheSectionToDo.Copy( _T("OC_QUEUE_FILE_OPS_install.") ) &&
strTheSectionToDo.Append(SubcomponentId)
)
{
if (GetSectionNameToDo(g_pTheApp->m_hInfHandle, &strTheSectionToDo))
{
ProcessSection(g_pTheApp->m_hInfHandle, strTheSectionToDo.QueryStr() );
dwOcEntryReturn = g_GlobalFileQueueHandle_ReturnError ? NO_ERROR : GetLastError();
}
else
{
dwOcEntryReturn = NO_ERROR;
}
}
else
{
dwOcEntryReturn = ERROR_NOT_ENOUGH_MEMORY;
}
}
}
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
return dwOcEntryReturn;
}
DWORD_PTR OC_ABOUT_TO_COMMIT_QUEUE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] Start. 0x%x,0x%x\n"), ComponentId, SubcomponentId, Param1, Param2));
DWORD_PTR dwOcEntryReturn = 0;
BOOL bTempFlag = FALSE;
g_GlobalTotalTickGaugeCount = 0;
if ( SubcomponentId )
{
ACTION_TYPE Action = GetSubcompAction(SubcomponentId, FALSE);
if ( Action == AT_REMOVE )
{
TSTR strFriendlyName;
TSTR strText;
BOOL bSet = FALSE;
if ( g_pComponents->GetFriendlyName( SubcomponentId, &strFriendlyName ) )
{
// Create text for UI
if ( strText.LoadString( IDS_COMPONENT_REMOVING ) &&
strText.Append( _T(" ") ) &&
strText.Append( strFriendlyName ) )
{
ProgressBarTextStack_Push( strText.QueryStr() );
bSet = TRUE;
}
}
// This is the main place for uninstall, lets do all the work now
g_pComponents->UnInstall( SubcomponentId );
if ( bSet )
{
ProgressBarTextStack_Pop();
}
}
else if ( ( Action == AT_INSTALL_FRESH ) ||
( Action == AT_INSTALL_UPGRADE ) ||
( Action == AT_INSTALL_REINSTALL ) )
{
// Since we are installing, lets do any PreInstall Work Now
g_pComponents->PreInstall( SubcomponentId );
}
}
// OCM will send this notification to each components by using the order
// of bottom==>top of the dependency tree.
// You should handle un-installation in this notification.
dwOcEntryReturn = NO_ERROR;
SetCurrentDirectory(g_pTheApp->m_csPathInetsrv);
if (!SubcomponentId)
{
DisplayActionsForAllOurComponents(g_pTheApp->m_hInfHandle);
// Re-set ID's which weren't available during oc_init
SetDIRIDforThisInf(g_pTheApp->m_hInfHandle,FALSE);
ProcessSection(g_pTheApp->m_hInfHandle, _T("OC_ABOUT_TO_COMMIT_QUEUE"));
}
else
{
TCHAR szTheSectionToDo[100];
_stprintf(szTheSectionToDo,_T("OC_ABOUT_TO_COMMIT_QUEUE.%s"),SubcomponentId);
ProcessSection(g_pTheApp->m_hInfHandle, szTheSectionToDo);
ACTION_TYPE atCORE = GetIISCoreAction(FALSE);
ACTION_TYPE atComp = GetSubcompAction(SubcomponentId, FALSE);
ProcessSection(g_pTheApp->m_hInfHandle, szTheSectionToDo);
}
// ------------------------------------
// Stop any services that we need to...
// ------------------------------------
if (!SubcomponentId)
{
if (g_pTheApp->m_fNTGuiMode)
{
// In any type of case, either fresh,upgrade, reinstall, whatevers,
// the services must be stopped at this point!!!!
StopAllServicesRegardless(FALSE);
// handle the metabase file appropriately,
// in order to work correctly with NT5 GUI mode setup re-startable
HandleMetabaseBeforeSetupStarts();
//AfterRemoveAll_SaveMetabase();
}
else
{
// add\remove, so only stop services that will be affected
StopAllServicesThatAreRelevant(FALSE);
}
}
// -----------------------
// handle all removes here
// -----------------------
//
// Check to see if the user has chosen to "remove-all"
//
// handle all removes here.
// we need to handle it in or special order
// because we want to make sure that removeal happens in the right order.
// right order means =(considering the 'needs' relationship - since ocmanage does not handle it).
//
if (!SubcomponentId)
{
DisplayActionsForAllOurComponents(g_pTheApp->m_hInfHandle);
}
else
{
if (g_pTheApp->m_eInstallMode != IM_UPGRADE)
{
_tcscpy(g_szCurrentSubComponent, SubcomponentId );
if ( _tcsicmp( SubcomponentId,
g_ComponentList[COMPONENT_IIS_COMMON].szComponentName ) == 0 )
{
// If we are removing common, lets also remove core
RemoveComponent( STRING_iis_core ,2);
}
RemoveComponent( SubcomponentId , 2);
}
}
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoFreeUnusedLibraries().Start.")));
CoFreeUnusedLibraries();
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoFreeUnusedLibraries().End.")));
// ------------------------------------
// Make sure that all possible services are stopped before anytype of copyfiles!
// ------------------------------------
if (g_pTheApp->m_fNTGuiMode)
{
// In any type of case, either fresh,upgrade, reinstall, whatevers,
// the services must be stopped at this point!!!!
StopAllServicesRegardless(TRUE);
}
else
{
// add\remove, so only stop services that will be affected
StopAllServicesThatAreRelevant(TRUE);
}
// -------------------------------------
// Make sure to unload all dll's possible
// -------------------------------------
CoFreeUnusedLibrariesEx(0, 0);
if ( SubcomponentId &&
( _tcscmp(SubcomponentId, STRING_iis_common ) == 0 ) &&
( GetSubcompAction(SubcomponentId, FALSE) == AT_REMOVE )
)
{
// Remove w3ssl dependency on iisadmin
if ( !ChangeServiceDependency(SERVICENAME_HTTP_SSL_PROVIDER,
FALSE,
SERVICENAME_IISADMIN) )
{
iisDebugOut((LOG_TYPE_ERROR, _T("ChangeServiceDependency failed during OC_QUEUE_FILE_OPS_Func\n") ));
}
}
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
return dwOcEntryReturn;
}
// IsIncludedInGroupPolicyDeny
//
// Determine if the component is included in the group policy
// deny
//
// Return Values
// TRUE - Should be denied if group policy is set
// FALSE - Should not be denied if group policy is set
BOOL IsIncludedInGroupPolicyDeny( LPCTSTR szComponentName )
{
if ( !szComponentName )
{
// No component specified
return FALSE;
}
for ( DWORD i = 0;
i < COMPONENT_ENDOFLIST;
i++ )
{
if ( _tcsicmp( szComponentName, g_ComponentList[i].szComponentName ) == 0 )
{
return g_ComponentList[i].bIncludedInGroupPolicyDeny;
}
}
// Not found
return FALSE;
}
DWORD_PTR OC_COMPLETE_INSTALLATION_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] Start. 0x%x,0x%x\n"), ComponentId, SubcomponentId, Param1, Param2));
// OCM will send this notification to each components by using the order
// of top==>bottom of the dependency tree.
// You should handle installation in this notification.
DWORD_PTR dwOcEntryReturn = 0;
BOOL bTempFlag = FALSE;
TCHAR szTheSectionToDo[100];
ACTION_TYPE Action = SubcomponentId ?
GetSubcompAction(SubcomponentId, FALSE) :
AT_DO_NOTHING;
g_GlobalTotalTickGaugeCount = 0;
if ( ( SubcomponentId != NULL ) &&
ShouldBlockInstall( FALSE ) &&
( Action == AT_INSTALL_FRESH ) &&
IsIncludedInGroupPolicyDeny( SubcomponentId ) )
{
iisDebugOut((LOG_TYPE_ERROR, _T("Internet Information Services (IIS)")
_T(" could not be installed because your administrator has enabled")
_T(" a \"Prevent IIS installation\" group policy.\n") ));
return ERROR_ACCESS_DENIED;
}
if ( g_pTheApp->IsUpgrade() &&
( SubcomponentId != NULL ) &&
( _tcsicmp(SubcomponentId, STRING_iis_common ) == 0 )
)
{
// If this is an upgrade in iis_common, the metabase maybe disabled and we may
// want to reenable it, for the time being, until setup is complete
g_pTheApp->m_bIISAdminWasDisabled = IsServiceDisabled( SERVICENAME_IISADMIN );
if ( g_pTheApp->m_bIISAdminWasDisabled )
{
// Enable IISAdmin, so we can edit the metabase
SetServiceStart( SERVICENAME_IISADMIN, SERVICE_AUTO_START );
}
}
if (!SubcomponentId)
{
_stprintf(szTheSectionToDo,_T("OC_COMPLETE_INSTALLATION_install.%s"),ComponentId);
ProcessSection(g_pTheApp->m_hInfHandle, szTheSectionToDo);
}
dwOcEntryReturn = NO_ERROR;
SetCurrentDirectory(g_pTheApp->m_csPathInetsrv);
if (SubcomponentId)
{
// Should get called in this order
// ===============================
// [Optional Components]
// iis
// iis_common
// iis_inetmgr
// iis_www
// iis_doc
// iis_htmla
// iis_www_vdir_scripts
// iis_ftp
// ===============================
//
// iis_common should be the first call....
//
// ===============================
if (_tcsicmp(SubcomponentId, STRING_iis_common) == 0)
{
//
// install the iis_common section
//
if (Action == AT_INSTALL_FRESH || Action == AT_INSTALL_UPGRADE || (Action == AT_INSTALL_REINSTALL))
{
_stprintf(g_MyLogFile.m_szLogPreLineInfo2,_T("%s:"),SubcomponentId);
if (Action == AT_INSTALL_UPGRADE){ProgressBarTextStack_Set(IDS_IIS_ALL_UPGRADE);}
else{ProgressBarTextStack_Set(IDS_IIS_ALL_INSTALL);}
_stprintf(szTheSectionToDo,_T("OC_COMPLETE_INSTALLATION_install.%s"),SubcomponentId);
ProcessSection(g_pTheApp->m_hInfHandle, szTheSectionToDo);
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
ProgressBarTextStack_Pop();
}
//
// If we just processed iis_common,
// but now we should install iis_core
//
if (Action == AT_INSTALL_FRESH || Action == AT_INSTALL_UPGRADE || (Action == AT_INSTALL_REINSTALL) || Action == AT_DO_NOTHING)
{
ACTION_TYPE atCORE = GetIISCoreAction(FALSE);
if (atCORE == AT_INSTALL_FRESH || atCORE == AT_INSTALL_UPGRADE || (atCORE == AT_INSTALL_REINSTALL))
{
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T("iis_core:"));
if (Action != AT_DO_NOTHING)
{
if (atCORE == AT_INSTALL_UPGRADE){ProgressBarTextStack_Set(IDS_IIS_ALL_UPGRADE);}
else{ProgressBarTextStack_Set(IDS_IIS_ALL_INSTALL);}
}
_stprintf(szTheSectionToDo,_T("OC_COMPLETE_INSTALLATION_install.%s"),STRING_iis_core);
ProcessSection(g_pTheApp->m_hInfHandle, szTheSectionToDo);
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
if (Action != AT_DO_NOTHING)
{
ProgressBarTextStack_Pop();
}
}
}
}
else if ( _tcscmp(SubcomponentId, COMPONENTS_SAKIT_WEB ) == 0 )
{
SAKit Kit;
if (Action == AT_INSTALL_FRESH || Action == AT_INSTALL_UPGRADE || (Action == AT_INSTALL_REINSTALL))
{
Kit.InstallKit_Web();
}
else if (Action == AT_REMOVE)
{
Kit.UninstallKit_Web();
}
}
else
{
// ===============================
//
// Handle the Registration of all other components...
//
// ===============================
if (Action == AT_INSTALL_FRESH || Action == AT_INSTALL_UPGRADE || (Action == AT_INSTALL_REINSTALL))
{
_stprintf(g_MyLogFile.m_szLogPreLineInfo2,_T("%s:"),SubcomponentId);
if (Action == AT_INSTALL_UPGRADE){ProgressBarTextStack_Set(IDS_IIS_ALL_UPGRADE);}
else{ProgressBarTextStack_Set(IDS_IIS_ALL_INSTALL);}
// Call the sections registration stuff.
if (_tcsicmp(SubcomponentId, STRING_iis_inetmgr) == 0)
{
// Do this at the end of setup since things that it needs may not happen yet (mmc)
g_Please_Call_Register_iis_inetmgr = TRUE;
// Register_iis_inetmgr();
}
_stprintf(szTheSectionToDo,_T("OC_COMPLETE_INSTALLATION_install.%s"),SubcomponentId);
ProcessSection(g_pTheApp->m_hInfHandle, szTheSectionToDo);
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
ProgressBarTextStack_Pop();
}
}
//
// If we are removing something, then remove the directories
//
if (Action == AT_REMOVE)
{
ProgressBarTextStack_Set(IDS_IIS_ALL_REMOVE);
_stprintf(szTheSectionToDo,_T("OC_COMPLETE_INSTALLATION_remove.%s"),SubcomponentId);
ProcessSection(g_pTheApp->m_hInfHandle, szTheSectionToDo);
ProgressBarTextStack_Pop();
}
}
AdvanceProgressBarTickGauge();
SumUpProgressBarTickGauge(SubcomponentId);
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
if ( SubcomponentId )
{
if ( Action == AT_REMOVE )
{
// Call the appropriate PostUninstall, since everything has already
// been pretty much done
g_pComponents->PostUnInstall( SubcomponentId );
}
else if ( ( Action == AT_INSTALL_FRESH ) ||
( Action == AT_INSTALL_UPGRADE ) ||
( Action == AT_INSTALL_REINSTALL ) )
{
TSTR strFriendlyName;
TSTR strText;
BOOL bSet = FALSE;
if ( g_pComponents->GetFriendlyName( SubcomponentId, &strFriendlyName ) )
{
// Create text for UI
if ( strText.LoadString( IDS_COMPONENT_INSTALLING ) &&
strText.Append( _T(" ") ) &&
strText.Append( strFriendlyName ) )
{
ProgressBarTextStack_Push( strText.QueryStr() );
bSet = TRUE;
}
}
// Call the appropriate Install section for this component
g_pComponents->Install( SubcomponentId );
if ( bSet )
{
ProgressBarTextStack_Pop();
}
}
}
// If this is iis_www, and it is an upgrade, lets make sure that we migrate the
// filters from the registry
if ( SubcomponentId &&
( _tcscmp(SubcomponentId, STRING_iis_www ) == 0 ) &&
( g_pTheApp->IsUpgrade() ) &&
( g_pTheApp->GetUpgradeVersion() < 6 )
)
{
CFilter::MigrateRegistryFilterstoMetabase();
}
if ( SubcomponentId &&
( _tcscmp(SubcomponentId, STRING_iis_www ) == 0 ) &&
( ( Action == AT_INSTALL_FRESH ) ||
( Action == AT_INSTALL_UPGRADE ) ||
( Action == AT_INSTALL_REINSTALL )
)
)
{
if ( !ChangeServiceDependency(SERVICENAME_HTTP_SSL_PROVIDER,
TRUE,
SERVICENAME_IISADMIN) )
{
iisDebugOut((LOG_TYPE_ERROR, _T("ChangeServiceDependency failed during OC_COMPLETE_INSTALLATION_Func\n") ));
}
}
// check if this is the last section to get called!!!
if (SubcomponentId)
{
// Yes this is the last section to get called! So, let's say sooooo....
if (_tcsicmp(SubcomponentId, g_szLastSectionToGetCalled) == 0)
{
// Enforce max connections
if (CheckifServiceExist(_T("IISADMIN")) == 0 )
{
//EnforceMaxConnections();
}
// free some memory
FreeTaskListMem();
UnInit_Lib_PSAPI();
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("....All OC_COMPLETE_INSTALLATION for all 'IIS' sections have been completed.....\n")));
// if there were errors then popup message box.
MesssageBoxErrors_IIS();
}
}
return dwOcEntryReturn;
}
DWORD_PTR OC_CLEANUP_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD dwCurrent;
ACTION_TYPE Action;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] Start. 0x%x,0x%x\n"), ComponentId, SubcomponentId, Param1, Param2));
// OCM send out this notification after the "Finish" button on
// the End Page has been clicked.
//
// remove the files we downloaded from the web in this session
DWORD_PTR dwOcEntryReturn = 0;
// display running services in case our services
// need other services to be running!
ShowStateOfTheseServices(g_pTheApp->m_hInfHandle);
for ( dwCurrent = 0;
dwCurrent < COMPONENT_ENDOFLIST;
dwCurrent++ )
{
Action = GetSubcompAction( g_ComponentList[dwCurrent].szComponentName , FALSE);
if ( ( Action == AT_INSTALL_FRESH ) ||
( Action == AT_INSTALL_UPGRADE ) ||
( Action == AT_INSTALL_REINSTALL ) )
{
// This is our last point on install, so lets notify of
// any PostInstall
g_pComponents->PostInstall( g_ComponentList[dwCurrent].szComponentName );
}
}
// Lets assert that the Enum for this list, and the list length match up
ASSERT( g_ComponentList[dwCurrent].szComponentName == NULL );
// Install inetmgr after gui mode setup is done because
// it may require other things that were setup in guimode.
if (TRUE == g_Please_Call_Register_iis_inetmgr) {Register_iis_inetmgr();}
ProcessSection(g_pTheApp->m_hInfHandle, _T("OC_CLEANUP"));
// restart services that we stopped
ServicesRestartList_RestartServices();
#ifndef _CHICAGO_
// restart cluster resources that we had stopped
if (!g_pTheApp->m_fNTGuiMode)
{
BringALLIISClusterResourcesOnline();
}
#endif
//--------------------------------------------------------------------
// For Migrations we need to scan the entire metabase and look for the old
// system directory (e.g. "C:\\Windows\\System\\") and replace
// with the new system directory (e.g. "C:\\WINNT.1\\System32\\")
//
// Does the iisadmin service exist?
// Does the metabase exist???
if (g_pTheApp->m_eInstallMode == IM_UPGRADE)
{
if (g_pTheApp->m_fMoveInetsrv)
{
// Check if the iisadmin service exists...
if (CheckifServiceExist(_T("IISADMIN")) == 0 )
{
CMDKey cmdKey;
cmdKey.OpenNode(_T("LM"));
if ( (METADATA_HANDLE)cmdKey )
{
HRESULT hr;
cmdKey.Close();
CString cOldWinSysPath;
CString cNewWinSysPath;
// Change all "c:\windows\system\inetsrv" to "c:\windows\system32\inetsrv"
cOldWinSysPath = g_pTheApp->m_csPathOldInetsrv;
cOldWinSysPath += _T("\\"); // add a trailing backslash
cNewWinSysPath = g_pTheApp->m_csPathInetsrv;
cNewWinSysPath += _T("\\"); // add a trailing backslash
iisDebugOut((LOG_TYPE_TRACE, _T("CPhysicalPathFixer: please change %s to %s.\n"),cOldWinSysPath, cNewWinSysPath));
CPhysicalPathFixer cmdKeySpecial(cOldWinSysPath, cNewWinSysPath);
hr = cmdKeySpecial.Update(_T("LM"), TRUE);
if (FAILED(hr)) {iisDebugOut((LOG_TYPE_ERROR, _T("CPhysicalPathFixer failed return HR:%#lx\n"), hr));}
// Change all "%WinDir%\System" to "%windir%\System32"
cOldWinSysPath = _T("%WinDir%\\System");
cNewWinSysPath = _T("%WinDir%\\System32");
CPhysicalPathFixer cmdKeySpecial2(cOldWinSysPath, cNewWinSysPath);
hr = cmdKeySpecial2.Update(_T("LM"), TRUE);
if (FAILED(hr)) {iisDebugOut((LOG_TYPE_ERROR, _T("CPhysicalPathFixer failed return HR:%#lx\n"), hr));}
}
}
}
}
// if iis is installed, then check if Tcp/ip is installed.
// if it is not installed... then output some error message to the log saying
// a big warning that they must install tcp/ip inorder for iis to work.
//IDS_TCPIP_ERROR
if (CheckifServiceExist(_T("TCPIP")) == ERROR_SERVICE_DOES_NOT_EXIST)
{
int IISInstalled = FALSE;
if (CheckifServiceExist(_T("W3SVC")) == 0 )
{IISInstalled=TRUE;}
if (CheckifServiceExist(_T("MSFTPSVC")) == 0 )
{IISInstalled=TRUE;}
if (IISInstalled)
{
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T(""));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T("FAIL:"));
CString csTemp;
MyLoadString(IDS_TCPIP_ERROR, csTemp);
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("================================\n")));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("%s\n"), csTemp));
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("================================\n")));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo, _T("OC_CLEANUP:"));
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
//LogSevInformation 0x00000000
//LogSevWarning 0x00000001
//LogSevError 0x00000002
//LogSevFatalError 0x00000003
//LogSevMaximum 0x00000004
// Write it to the setupapi log file!
SetupLogError(csTemp, LogSevWarning);
}
}
else
{
// The tcpip service exists, but is it running???
}
// Write the uninstall info for this session out to the registry
g_pTheApp->UnInstallList_RegWrite();
CRegKey regINetStp( HKEY_LOCAL_MACHINE, REG_INETSTP);
if ((HKEY) regINetStp){regINetStp.DeleteValue(_T("MetabaseUnSecuredRead"));}
if ( g_pTheApp->m_bIISAdminWasDisabled )
{
// ReDisable the IISAdmin Service
SetServiceStart( SERVICENAME_IISADMIN, SERVICE_DISABLED );
}
dwOcEntryReturn = 0;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
return dwOcEntryReturn;
}
//
// 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_PTR OC_PREINITIALIZE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD_PTR dwOcEntryReturn = 0;
#ifdef UNICODE
dwOcEntryReturn = OCFLAG_UNICODE;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s] End. Return=%d (OCFLAG_UNICODE)\n"), ComponentId, dwOcEntryReturn));
#else
dwOcEntryReturn = OCFLAG_ANSI;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s] End. Return=%d (OCFLAG_ANSI)\n"), ComponentId, dwOcEntryReturn));
#endif
return dwOcEntryReturn;
}
//
// 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_PTR OC_SET_LANGUAGE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD_PTR dwOcEntryReturn = 0;
dwOcEntryReturn = TRUE;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Win32LANGID=0x%x, Return=%d\n"), ComponentId, SubcomponentId, Param1, dwOcEntryReturn));
return dwOcEntryReturn;
}
#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)
{
BOOL bReturn = FALSE;
HBITMAP hBitMap = NULL;
HBITMAP * phBitMapInput = NULL;
OC_QUERY_IMAGE_INFO * MyQueryInfo = NULL;
MyQueryInfo = (OC_QUERY_IMAGE_INFO *) Param1;
phBitMapInput = (HBITMAP *) Param2;
if(MyQueryInfo->ComponentInfo == SubCompInfoSmallIcon)
{
if ( g_pComponents->GetSmallIcon( SubcomponentId, &hBitMap ) )
{
// Nothing need to be done, we have retrieved the value
}
else
{
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_FTP].szComponentName ) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle,MAKEINTRESOURCE(IDB_FTP));}
if (_tcsicmp(SubcomponentId, STRING_iis_www) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_WWW_PARENT].szComponentName) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW));}
if (_tcsicmp(SubcomponentId, STRING_iis_www_vdir_scripts) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW_VDIR));}
if (_tcsicmp(SubcomponentId, STRING_iis_www_vdir_printers) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW_VDIR));}
if (_tcsicmp(SubcomponentId, COMPONENTS_SAKIT_WEB) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW_VDIR));}
if (_tcsicmp(SubcomponentId, STRING_iis_htmla) == 0 || _tcsicmp(SubcomponentId, STRING_iis_doc) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_HTMLA));}
if (_tcsicmp(SubcomponentId, STRING_iis_inetmgr) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WEBAPPSRV_CONSOLE));}
if (_tcsicmp(SubcomponentId, STRING_iis_pwmgr) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_PWS));}
if (_tcsicmp(SubcomponentId, _T("iis")) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_TOPLEVEL_IIS));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_WEBAPPSRV_CONSOLE].szComponentName) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WEBAPPSRV_CONSOLE));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_COMPLUS].szComponentName) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_ICON_COMPLUS));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_DTC].szComponentName) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_ICON_DTC));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_WEBAPPSRV].szComponentName) == 0) {hBitMap = LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_ICON_WEB_APP_SERVER));}
}
if (hBitMap)
{
*phBitMapInput = (HBITMAP) hBitMap;
bReturn = TRUE;
}
}
if (phBitMapInput != NULL)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End.Return=0x%x.\n"), ComponentId, SubcomponentId,phBitMapInput));
}
else
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End.Return=0x%x.\n"), ComponentId, SubcomponentId,phBitMapInput));
}
MyQueryInfo = NULL;
return bReturn;
}
#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 dwOcEntryReturn;
HBITMAP hBitMap = NULL;
dwOcEntryReturn = (DWORD)NULL;
if(LOWORD(Param1) == SubCompInfoSmallIcon)
{
if ( g_pComponents->GetSmallIcon( SubcomponentId, &hBitMap ) )
{
dwOcEntryReturn = (DWORD) (DWORD_PTR) hBitMap;
}
else
{
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_FTP].szComponentName ) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle,MAKEINTRESOURCE(IDB_FTP));}
if (_tcsicmp(SubcomponentId, STRING_iis_www) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_WWW_PARENT].szComponentName) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW));}
if (_tcsicmp(SubcomponentId, STRING_iis_www_vdir_scripts) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW_VDIR));}
if (_tcsicmp(SubcomponentId, STRING_iis_www_vdir_printers) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW_VDIR));}
if (_tcsicmp(SubcomponentId, COMPONENTS_SAKIT_WEB) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WWW_VDIR));}
if (_tcsicmp(SubcomponentId, STRING_iis_htmla) == 0 || _tcsicmp(SubcomponentId, STRING_iis_doc) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_HTMLA));}
if (_tcsicmp(SubcomponentId, STRING_iis_inetmgr) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WEBAPPSRV_CONSOLE));}
if (_tcsicmp(SubcomponentId, STRING_iis_pwmgr) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_PWS));}
if (_tcsicmp(SubcomponentId, _T("iis")) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_TOPLEVEL_IIS));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_WEBAPPSRV_CONSOLE].szComponentName) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_WEBAPPSRV_CONSOLE));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_COMPLUS].szComponentName) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_ICON_COMPLUS));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_DTC].szComponentName) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_ICON_DTC));}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_WEBAPPSRV].szComponentName) == 0) {dwOcEntryReturn = (DWORD_PTR) LoadBitmap((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDB_ICON_WEB_APP_SERVER));}
}
}
if (dwOcEntryReturn != NULL)
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End.Return=0x%x.\n"), ComponentId, SubcomponentId,dwOcEntryReturn));
}
else
{
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End.Return=NULL.\n"), ComponentId, SubcomponentId));
}
return dwOcEntryReturn;
}
int GetTotalTickGaugeFromINF(IN LPCTSTR SubcomponentId, IN int GimmieForInstall)
{
int nReturn = 0;
INFCONTEXT Context;
TCHAR szTempString[20];
TCHAR szTempString2[20];
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("TotalTicks"), &Context) )
{
SetupGetStringField(&Context, 1, szTempString, 20, NULL);
if (!SetupGetStringField(&Context, 2, szTempString2, 20, NULL))
{_tcscpy(szTempString2,szTempString);}
//iisDebugOut((LOG_TYPE_TRACE, _T("GetTotalTickGaugeFromINF:%s,%s\n"),szTempString,szTempString2));
if (GimmieForInstall)
{
nReturn = _ttoi(szTempString);
}
else
{
nReturn = _ttoi(szTempString2);
}
}
return nReturn;
}
//
// 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 2 step
// per subcomponent. We ignore the "entire component" case.
//
DWORD_PTR OC_QUERY_STEP_COUNT_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD_PTR dwOcEntryReturn = 0;
// iis
// iis_common
// iis_inetmgr
// iis_www
// iis_doc
// iis_htmla
// iis_ftp
//AT_DO_NOTHING AT_REMOVE AT_INSTALL_FRESH AT_INSTALL_UPGRADE AT_INSTALL_REINSTALL
if (SubcomponentId)
{
ACTION_TYPE atComp = GetSubcompAction(SubcomponentId, FALSE);
// Set the Tick Total value for iis_common (which includes iis_core)
if (_tcsicmp(SubcomponentId, STRING_iis_common) == 0)
{
// Get the operations for Core instead since this is bigger.
ACTION_TYPE atCORE = GetIISCoreAction(FALSE);
if (atCORE == AT_REMOVE)
{dwOcEntryReturn = GetTotalTickGaugeFromINF(SubcomponentId, FALSE);}
else
{dwOcEntryReturn = GetTotalTickGaugeFromINF(SubcomponentId, TRUE);}
if (atCORE == AT_DO_NOTHING)
{dwOcEntryReturn = 0;}
}
else
{
if (atComp == AT_REMOVE)
{dwOcEntryReturn = GetTotalTickGaugeFromINF(SubcomponentId, FALSE);}
else
{dwOcEntryReturn = GetTotalTickGaugeFromINF(SubcomponentId, TRUE);}
if (atComp == AT_DO_NOTHING)
{dwOcEntryReturn = 0;}
}
}
else
{
//
// "Entire component" case, which we ignore.
//
dwOcEntryReturn = 0;
}
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
return dwOcEntryReturn;
}
//
// This is a fake notification. You'll never receive this notification from OCM.
//
DWORD_PTR OC_NOTIFICATION_FROM_QUEUE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD_PTR dwOcEntryReturn = 0;
dwOcEntryReturn = 0;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
return dwOcEntryReturn;
}
void StopAllServicesThatAreRelevant(int iShowErrorsFlag)
{
int iPleaseStopTheService = FALSE;
#ifndef _CHICAGO_
ACTION_TYPE atTheComponent_core = GetIISCoreAction(FALSE);
ACTION_TYPE atTheComponent_ftp = GetSubcompAction( g_ComponentList[COMPONENT_IIS_FTP].szComponentName, FALSE);
ACTION_TYPE atTheComponent_www = GetSubcompAction(STRING_iis_www, FALSE);
int BringALLIISClusterResourcesOffline_WasCalled = FALSE;
//ACTION_TYPE atTheComponent_common = GetSubcompAction(STRING_iis_common, FALSE);
//ACTION_TYPE atTheComponent_inetmgr = GetSubcompAction(STRING_iis_inetmgr, FALSE);
//ACTION_TYPE atTheComponent_pwmgr = GetSubcompAction(STRING_iis_pwmgr, FALSE);
//ACTION_TYPE atTheComponent_doc = GetSubcompAction(STRING_iis_doc, FALSE);
//ACTION_TYPE atTheComponent_htmla = GetSubcompAction(STRING_iis_htmla, FALSE);
// ----------------------
// Handle the MSFTPSVC service...
// ----------------------
// Check if we are going to remove something...
iPleaseStopTheService = FALSE;
if (atTheComponent_ftp != AT_DO_NOTHING){iPleaseStopTheService = TRUE;}
if (iPleaseStopTheService)
{
// important: you must take iis clusters off line before doing anykind of upgrade\installs...
// but incase the user didn't do this... try to take them off line for the user
if (FALSE == BringALLIISClusterResourcesOffline_WasCalled)
{
DWORD dwResult = ERROR_SUCCESS;
dwResult = BringALLIISClusterResourcesOffline();
BringALLIISClusterResourcesOffline_WasCalled = TRUE;
}
if (StopServiceAndDependencies(_T("MSFTPSVC"), FALSE) == FALSE)
{
if (iShowErrorsFlag)
{
MyMessageBox(NULL, IDS_UNABLE_TO_STOP_SERVICE,_T("MSFTPSVC"), MB_OK | MB_SETFOREGROUND);
}
}
}
// ----------------------
// Handle the W3SVC service...
// ----------------------
iPleaseStopTheService = FALSE;
if (atTheComponent_www != AT_DO_NOTHING){iPleaseStopTheService = TRUE;}
if (iPleaseStopTheService)
{
// important: you must take iis clusters off line before doing anykind of upgrade\installs...
// but incase the user didn't do this... try to take them off line for the user
if (FALSE == BringALLIISClusterResourcesOffline_WasCalled)
{
DWORD dwResult = ERROR_SUCCESS;
dwResult = BringALLIISClusterResourcesOffline();
BringALLIISClusterResourcesOffline_WasCalled = TRUE;
}
if (StopServiceAndDependencies(_T("W3SVC"), FALSE) == FALSE)
{
if (iShowErrorsFlag)
{
MyMessageBox(NULL, IDS_UNABLE_TO_STOP_SERVICE,_T("W3SVC"), MB_OK | MB_SETFOREGROUND);
}
}
}
// ----------------------
// Handle the IISADMIN service...
// ----------------------
iPleaseStopTheService = FALSE;
if (atTheComponent_core != AT_DO_NOTHING){iPleaseStopTheService = TRUE;}
// if they are adding msftpsvc or w3svc, then we'll have to stop this iisadmin service as well!
// why? because the iisadmin serivce (inetinfo.exe) can be locking some files that we want to copy in.
// and if we can't copy them in, things could get hosed -- especially w3svc.
// actually if you think about it all the services (msftp,w3svc,smtp, etc..) area all running in the same process (inetinfo.exe)
// so it kinda makes sense that we have to stop this service when add\removing.
// let's say i removed msftpsvc -- and the services are still running,
// then i go and re-add msftpsvc -- well because we didn't reboot some of those ftp files are still
// locked -- so well have to do the old "slip it in on reboot" trick or something
// which still may have problems. Bottom line here is -- we have to stop iisadmin service when adding\readding
// msftpsvc or w3svc
// when i tested this -- it looks like the wam*.dll's get locked by the inetinfo.exe process
// so i have to stop the iisadmin service to unload those.
// if we they are trying to remove ftp then we don't have to stop the iisadmin service.
// but if we are trying to add, then stop the iisadmin service
if (atTheComponent_ftp != AT_DO_NOTHING && atTheComponent_ftp != AT_REMOVE)
{iPleaseStopTheService = TRUE;}
// if we they are trying to remove w3svc then we don't have to stop the iisadmin service.
// but if we are trying to add, then stop the iisadmin service
if (atTheComponent_www != AT_DO_NOTHING && atTheComponent_www != AT_REMOVE)
{iPleaseStopTheService = TRUE;}
if (iPleaseStopTheService)
{
// important: you must take iis clusters off line before doing anykind of upgrade\installs...
// but incase the user didn't do this... try to take them off line for the user
if (FALSE == BringALLIISClusterResourcesOffline_WasCalled)
{
DWORD dwResult = ERROR_SUCCESS;
dwResult = BringALLIISClusterResourcesOffline();
BringALLIISClusterResourcesOffline_WasCalled = TRUE;
}
if (StopServiceAndDependencies(_T("IISADMIN"), TRUE) == FALSE)
{
if (iShowErrorsFlag)
{
MyMessageBox(NULL, IDS_UNABLE_TO_STOP_SERVICE,_T("IISADMIN"), MB_OK | MB_SETFOREGROUND);
}
}
}
#endif
return;
}
DWORD_PTR OC_FILE_BUSY_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
{
DWORD_PTR dwOcEntryReturn = 0;
//dwOcEntryReturn = TRUE;
PFILEPATHS pTheBusyFile;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] Start.\n"), ComponentId, SubcomponentId));
pTheBusyFile = (PFILEPATHS) Param1;
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("Target=%1!s!, Source=%2!s!\n"), pTheBusyFile->Target, pTheBusyFile->Source));
ProcessSection(g_pTheApp->m_hInfHandle, _T("OC_FILE_BUSY"));
// display the file version information
LogFileVersion(pTheBusyFile->Target, TRUE);
// handle the file busy stuff ourselves.
// either - 1. findout who is locking this file -- which process or services and stop it.
// 2. or try to rename the locked file and copy in the new one.
// will set the reboot flag if we did #2
HandleFileBusyOurSelf(pTheBusyFile);
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. Return=%d\n"), ComponentId, SubcomponentId, dwOcEntryReturn));
return dwOcEntryReturn;
}
#define HandleMetabaseBeforeSetupStarts_log _T("HandleMetabaseBeforeSetupStarts")
void HandleMetabaseBeforeSetupStarts()
/*++
Routine Description:
This function handles the metabase file in various installation scenario before iis setup really starts.
It is developed in order to handle NT5 GUI mode setup re-startable.
This function should be called exactly after we have stopped all running iis services,
such that nobody is locking the metabase file.
Arguments:
None
Return Value:
void
--*/
{
CString csMetabaseFile;
csMetabaseFile = g_pTheApp->m_csPathInetsrv + _T("\\metabase.bin");
switch (g_pTheApp->m_eInstallMode) {
case IM_UPGRADE:
{
if (g_pTheApp->m_bUpgradeTypeHasMetabaseFlag)
{
CString csBackupFile;
csBackupFile = g_pTheApp->m_csPathInetsrv + _T("\\upg45b2.bin");
if (IsFileExist(csBackupFile)) {
//
// restore it back to be the current metabase.bin
//
iisDebugOut((LOG_TYPE_TRACE, _T("%s:IM_UPGRADE:restore upg45b2.bin to metabase.bin\n"),HandleMetabaseBeforeSetupStarts_log));
InetCopyFile(csBackupFile, csMetabaseFile);
} else {
//
// backup the current metabase.bin to upg45b2.bin
//
if (IsFileExist(csMetabaseFile))
{
iisDebugOut((LOG_TYPE_TRACE, _T("%s:IM_UPGRADE:backup metabase.bin to upg45b2.bin\n"),HandleMetabaseBeforeSetupStarts_log));
InetCopyFile(csMetabaseFile, csBackupFile);
}
else
{
iisDebugOut((LOG_TYPE_TRACE, _T("%s:IM_UPGRADE:backup metabase.bin to upg45b2.bin. metabase.bin not found WARNING.\n"),HandleMetabaseBeforeSetupStarts_log));
}
}
//
// delete the backup file on reboot
//
iisDebugOut((LOG_TYPE_TRACE, _T("%s:IM_UPGRADE:mark upg45b2.bin as delete-on-reboot\n"),HandleMetabaseBeforeSetupStarts_log));
MoveFileEx( (LPCTSTR)csBackupFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT );
break;
}
// for all the other upgrades, fall through
// to blow away the existing metabase.bin
}
case IM_FRESH:
{
//
// blow away the existing metabase.bin
//
iisDebugOut((LOG_TYPE_TRACE, _T("%s:IM_FRESH.Delete metabase.bin for NTsetup restartable mode case.\n"),HandleMetabaseBeforeSetupStarts_log));
InetDeleteFile(csMetabaseFile);
break;
}
default:
{
break;
}
}
return;
}
void SetRebootFlag(void)
{
gHelperRoutines.SetReboot(gHelperRoutines.OcManagerContext, TRUE);
}
#define GetStateFromUnattendFile_log _T("GetStateFromUnattendFile")
int GetStateFromUnattendFile(LPCTSTR SubcomponentId)
/*++
Routine Description:
This function determines the current state of SubcomponentId
according to values specified in the unattend text file.
Arguments:
SubcomponentId: the name of the component, e.g., iis_www
Return Value:
SubcompOn/SubcompOff/SubcompUseOcManagerDefault
This function returns SubcompUseOcManagerDefault in case the value of SubcomponentId
is neither specified as ON nor OFF.
--*/
{
int nReturn = SubcompUseOcManagerDefault;
INFCONTEXT Context;
TCHAR szSectionName[_MAX_PATH];
TCHAR szValue[_MAX_PATH] = _T("");
_tcscpy(szSectionName, _T("InternetServer"));
if (g_pTheApp->m_hUnattendFile == INVALID_HANDLE_VALUE || g_pTheApp->m_hUnattendFile == NULL)
{return SubcompUseOcManagerDefault;}
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hUnattendFile, szSectionName, SubcomponentId, &Context) )
{SetupGetStringField(&Context, 1, szValue, _MAX_PATH, NULL);}
if (_tcsicmp(szValue, _T("ON")) == 0)
{nReturn = SubcompOn;}
else if (_tcsicmp(szValue, _T("OFF")) == 0)
{nReturn = SubcompOff;}
else
{nReturn = SubcompUseOcManagerDefault;}
if (SubcompOn)
{iisDebugOut((LOG_TYPE_TRACE, _T("%s() on %s returns SubcompOn\n"), GetStateFromUnattendFile_log, SubcomponentId));}
if (SubcompOff)
{iisDebugOut((LOG_TYPE_TRACE, _T("%s() on %s returns SubcompOff\n"), GetStateFromUnattendFile_log, SubcomponentId));}
if (SubcompUseOcManagerDefault)
{iisDebugOut((LOG_TYPE_TRACE, _T("%s() on %s returns SubcompUseOcManagerDefault\n"), GetStateFromUnattendFile_log, SubcomponentId));}
return nReturn;
}
int GetStateFromModesLine(LPCTSTR SubcomponentId, int nModes)
/*++
Routine Description:
This function determines the current state of SubcomponentId
according to the Modes= line specified in the inf file.
Arguments:
SubcomponentId: the name of the component, e.g., iis_www
Return Value:
SubcompOn/SubcompOff only
--*/
{
int nReturn = SubcompOff;
BOOL bFound = FALSE;
INFCONTEXT Context;
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("Modes"), &Context) )
{
int n, i, nValue;
n = SetupGetFieldCount(&Context);
for(i=0; i<n; i++) {
if(SetupGetIntField(&Context,i+1,&nValue) && ((DWORD)nValue < 32)) {
if (nValue == nModes) {
bFound = TRUE;
break;
}
}
}
}
if (bFound)
nReturn = SubcompOn;
else
nReturn = SubcompOff;
iisDebugOut((LOG_TYPE_TRACE, _T("%s() on %s for mode %d returns %d\n"), GetStateFromUnattendFile_log, SubcomponentId, nModes, nReturn));
return nReturn;
}
int GetStateFromRegistry(LPCTSTR SubcomponentId)
/*++
Routine Description:
This function determines the original state of SubcomponentId
according to the registry value.
Arguments:
SubcomponentId: the name of the component, e.g., iis_www
Return Value:
SubcompOn/SubcompOff only
--*/
{
int nReturn = SubcompOff;
CRegKey regKey(HKEY_LOCAL_MACHINE,OC_MANAGER_SETUP_KEY,KEY_READ);
if ((HKEY)regKey)
{
DWORD dwValue = 0xffffffff;
regKey.m_iDisplayWarnings = TRUE;
if (regKey.QueryValue(SubcomponentId, dwValue) == ERROR_SUCCESS)
{
if (dwValue == 0x0)
nReturn = SubcompOff;
else
nReturn = SubcompOn;
}
}
iisDebugOut((LOG_TYPE_TRACE, _T("GetStateFromRegistry() on %s returns %d\n"), SubcomponentId, nReturn));
return nReturn;
}
int IsThisSubCompNeededByOthers(LPCTSTR SubcomponentId)
{
int iReturn = FALSE;
// search thru our inf to see if another component needs it
return iReturn;
}
int DoesOCManagerKeyExist(LPCTSTR SubcomponentId)
{
int iReturn = FALSE;
CRegKey regKey(HKEY_LOCAL_MACHINE,OC_MANAGER_SETUP_KEY,KEY_READ);
if ((HKEY)regKey)
{
DWORD dwValue = 0xffffffff;
regKey.m_iDisplayWarnings = FALSE;
if (regKey.QueryValue(SubcomponentId, dwValue) == ERROR_SUCCESS)
{iReturn = TRUE;}
}
return iReturn;
}
int GetStateFromUpgRegLines(LPCTSTR SubcomponentId)
/*++
Routine Description:
This function determines the original state of SubcomponentId
according to the UpgReg= line specified in the inf file.
Arguments:
SubcomponentId: the name of the component, e.g., iis_www
Return Value:
SubcompOn/SubcompOff only
--*/
{
int nReturn = SubcompOff;
INFCONTEXT Context;
TCHAR szPath[_MAX_PATH];
TCHAR szUpgradeInfKeyToUse[30];
_tcscpy(szUpgradeInfKeyToUse, _T("None"));
// Check for special NT4 upgrade
if (g_pTheApp->m_eUpgradeType == UT_40)
{
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("UpgReg4"), &Context) )
{
_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg4"));
//iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("GetStateFromUpgRegLines() use: UpgReg4.\n")));
SetupGetStringField(&Context, 1, szPath, _MAX_PATH, NULL);
CRegKey regKey(HKEY_LOCAL_MACHINE, szPath, KEY_READ);
if ((HKEY)regKey)
{
TCHAR szCompId[_MAX_PATH];
int iValue = 0;
DWORD dwValue = 0xffffffff;
SetupGetStringField(&Context, 2, szCompId, _MAX_PATH, NULL);
SetupGetIntField(&Context, 3, &iValue);
regKey.m_iDisplayWarnings = TRUE;
if (regKey.QueryValue(szCompId, dwValue) == ERROR_SUCCESS)
{
if (dwValue == (DWORD)iValue)
nReturn = SubcompOn;
}
}
}
goto GetStateFromUpgRegLines_Exit;
}
// Check for special NT60 upgrade
if (g_pTheApp->m_eUpgradeType == UT_60)
{
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("UpgReg60"), &Context) )
{
_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg60"));
//iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("GetStateFromUpgRegLines() use: UpgReg60.\n")));
SetupGetStringField(&Context, 1, szPath, _MAX_PATH, NULL);
CRegKey regKey(HKEY_LOCAL_MACHINE, szPath, KEY_READ);
if ((HKEY)regKey)
{
TCHAR szCompId[_MAX_PATH];
int iValue = 0;
DWORD dwValue = 0xffffffff;
SetupGetStringField(&Context, 2, szCompId, _MAX_PATH, NULL);
SetupGetIntField(&Context, 3, &iValue);
regKey.m_iDisplayWarnings = TRUE;
if (regKey.QueryValue(szCompId, dwValue) == ERROR_SUCCESS)
{
if (dwValue == (DWORD)iValue)
nReturn = SubcompOn;
}
}
}
goto GetStateFromUpgRegLines_Exit;
}
// Check for special NT5 upgrade
if (g_pTheApp->m_eUpgradeType == UT_51)
{
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("UpgReg51"), &Context) )
{
_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg51"));
//iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("GetStateFromUpgRegLines() use: UpgReg51.\n")));
SetupGetStringField(&Context, 1, szPath, _MAX_PATH, NULL);
CRegKey regKey(HKEY_LOCAL_MACHINE, szPath, KEY_READ);
if ((HKEY)regKey)
{
TCHAR szCompId[_MAX_PATH];
int iValue = 0;
DWORD dwValue = 0xffffffff;
SetupGetStringField(&Context, 2, szCompId, _MAX_PATH, NULL);
SetupGetIntField(&Context, 3, &iValue);
regKey.m_iDisplayWarnings = TRUE;
if (regKey.QueryValue(szCompId, dwValue) == ERROR_SUCCESS)
{
if (dwValue == (DWORD)iValue)
nReturn = SubcompOn;
}
}
}
goto GetStateFromUpgRegLines_Exit;
}
// Check for special NT5 upgrade
if (g_pTheApp->m_eUpgradeType == UT_50)
{
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("UpgReg5"), &Context) )
{
_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg5"));
//iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("GetStateFromUpgRegLines() use: UpgReg5.\n")));
SetupGetStringField(&Context, 1, szPath, _MAX_PATH, NULL);
CRegKey regKey(HKEY_LOCAL_MACHINE, szPath, KEY_READ);
if ((HKEY)regKey)
{
TCHAR szCompId[_MAX_PATH];
int iValue = 0;
DWORD dwValue = 0xffffffff;
SetupGetStringField(&Context, 2, szCompId, _MAX_PATH, NULL);
SetupGetIntField(&Context, 3, &iValue);
regKey.m_iDisplayWarnings = TRUE;
if (regKey.QueryValue(szCompId, dwValue) == ERROR_SUCCESS)
{
if (dwValue == (DWORD)iValue)
nReturn = SubcompOn;
}
}
}
goto GetStateFromUpgRegLines_Exit;
}
// Check if there is a specific one for our special upgrade type.
_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg"));
if (g_pTheApp->m_eUpgradeType == UT_351)
{
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("UpgReg351"), &Context) )
{_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg351"));}
}
if (g_pTheApp->m_eUpgradeType == UT_10)
{
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("UpgReg1"), &Context) )
{_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg1"));}
}
if (g_pTheApp->m_eUpgradeType == UT_20)
{
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("UpgReg2"), &Context) )
{_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg2"));}
}
if (g_pTheApp->m_eUpgradeType == UT_30)
{
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("UpgReg3"), &Context) )
{_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg3"));}
}
if (g_pTheApp->m_eUpgradeType == UT_10_W95)
{
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, _T("UpgReg1_w95"), &Context) )
{_tcscpy(szUpgradeInfKeyToUse, _T("UpgReg1_w95"));}
}
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, SubcomponentId, szUpgradeInfKeyToUse, &Context) )
{
SetupGetStringField(&Context, 1, szPath, _MAX_PATH, NULL);
CRegKey regKey(HKEY_LOCAL_MACHINE, szPath, KEY_READ);
if ((HKEY)regKey)
{
TCHAR szCompId[_MAX_PATH];
int iValue = 0;
DWORD dwValue = 0xffffffff;
// check if there is a parameter specified
if (SetupGetStringField(&Context, 2, szCompId, _MAX_PATH, NULL))
{
if (SetupGetIntField(&Context, 3, &iValue))
{
// check if the dword matches what we specified.
regKey.m_iDisplayWarnings = FALSE;
if (regKey.QueryValue(szCompId, dwValue) == ERROR_SUCCESS)
{
if (dwValue == (DWORD)iValue)
{nReturn = SubcompOn;}
}
}
else
{
// just check for existence.
regKey.m_iDisplayWarnings = FALSE;
if (regKey.QueryValue(szCompId, dwValue) == ERROR_SUCCESS)
{
nReturn = SubcompOn;
}
}
}
else
{
nReturn = SubcompOn;
}
}
}
GetStateFromUpgRegLines_Exit:
iisDebugOut((LOG_TYPE_TRACE, _T("GetStateFromUpgRegLines() %s:%s returns %d\n"), szUpgradeInfKeyToUse, SubcomponentId, nReturn));
return nReturn;
}
void InCaseNoTCPIP(LPCTSTR SubcomponentId, int nNewStateValue, int *pnState)
/*++
Routine Description:
This function overwrites current state with nNewStateValue
in case that TCPIP is not present.
Arguments:
LPCTSTR SubcomponentId: e.g., iis_www, etc.
int nNewStateValue: SubcompOn/SubcompOff/SubcompUseOcManagerDefault
int *pnState: pointer to the state which will be overwritten if condition is met.
Return Value:
void
--*/
{
// check if tcpip is installed
g_pTheApp->IsTCPIPInstalled();
if (g_pTheApp->m_fTCPIP == FALSE)
{
if (_tcsicmp(SubcomponentId, STRING_iis_inetmgr) == 0 ||
_tcsicmp(SubcomponentId, STRING_iis_www) == 0 ||
_tcsicmp(SubcomponentId, STRING_iis_pwmgr) == 0 )
{
*pnState = nNewStateValue;
}
}
return;
}
DWORD_PTR OC_QUERY_STATE_Func(IN LPCTSTR ComponentId,IN LPCTSTR SubcomponentId,IN UINT Function,IN UINT_PTR Param1,IN OUT PVOID Param2)
/*++
Routine Description:
This function handles OC_QUERY_STATE notification.
IIS 4.0 SETUP NOTE (LinanT):
============================
This function returns SubcompOn/SubcompOff explicitly.
It does NOT return SubcompUseOcManagerDefault, because
OCM sometimes behaves strangely when SubcompUseOcManagerDefault is returned.
The above comments were valid for iis4 but in iis5 ocmanage has been fixed so
that SubcompUseOcManagerDefault is valid
IIS 5.0 SETUP NOTE (AaronL):
============================
Well okay. iis5.0 shipped with Win2000, Patst and then AndrewR took over the ocmanager.
They made a bunch of changes to ocmanager to appropriately handle the "needs" relationship stuff in the .inf files.
Anyway, that stuffs all kool, however things had to be changed in order for this oc_query_state stuff to work.
Here is basic description of how this works:
OCSELSTATETYPE_ORIGINAL
-----------------------
During setup ocmanage will ask each of the components for they're original state (OCSELSTATETYPE_ORIGINAL).
In this call each component can return back the state of that certain component -- such as "yes, a previous inetmgr 1.0,2.0,3.0,4.0 or 5.0 is already installed".
If this is a fresh\maintenance installation, the component should return back SubcompUseOcManagerDefault. Meaning, ocmanage will look in the registry for this component
probably at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OC Manager\Subcomponents;SubcomponentId=1 or 0.
if the component value is 0, then ocmanage will figure your component is off. if it's 1 then it's on. however if it's not there, then ocmanage will use whatever
the component has specified for for it's Modes= line in the .inf file.
During an upgrade installation, well, since older installations of inetmgr maybe located at a different registry key than at:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OC Manager\Subcomponents;iis_inetmgr=1 or 0.
we have to let ocmanage know, what the original state is by manually returning on/off/default.
Okay so what's the deal here? Why do we even need to use default? That's because something in ocmanage isn't working quite right and AndrewR doesn't want to destabilize
setup by making such a drastic this late in win2000 ship cycle. Here is the story. If iis_inetmgr returns on during this call -- kool, everything is fine and no problems.
however if i find that iis_inetmgr was not previously installed, then naturally i would want to return "off", but in fact this is wrong and will hose other things. how you say?
well because if i return "off" here, that means other components which need iis_inetmgr will not be able to turn it "on" thru needs (since the ocmanage has a screwy bug with this).
But if i return here "SubcompUseOcManagerDefault", then the other components will be able to turn it on iff they need it. the catch here is that -- ocmanage will use SubcompUseOcManagerDefault
which means that it will lookup in the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OC Manager\Subcomponents;iis_inetmgr=1 or 0.
and determine for itself if it should be on or off, however on the upgrade iis_inetmgr won't be there so it will want to default to the "Modes=" line. however if iis is installed by default -- as
specified in the modes= lines -- then iis_inetmgr would be turned on wrongly!
How to work around this problem? Well, if the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OC Manager\Subcomponents;iis_inetmgr=1 or 0
key was there then ocmanage wouldn't have to consult the Modes= line. so the workaround was for AndrewR, on an upgrade case to crate the
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OC Manager\Subcomponents;iis_inetmgr key if it wasn't already there.
OCSELSTATETYPE_CURRENT
-----------------------
on a fresh just returns SubcompUseOcManagerDefault. in this case ocmanage should open the .inf file and read my Modes= line to determine if this component should be on or off.
on a maintenance mode add\remove (there is no removeall or reinstall in win2000 add\remove ocmanage) just returns SubcompUseOcManagerDefault. in which ocmanage will just read the registry again.
on upgrade the code will return either on or usedefault. we don't ever want to return off here because that would prevent other components which need us from turing us on.
--*/
{
int nReturn = SubcompUseOcManagerDefault;
TCHAR szTempStringInstallMode[40];
_tcscpy(szTempStringInstallMode, _T("NONE"));
BOOL bIsInstalled;
if (!SubcomponentId)
{goto OC_QUERY_STATE_Func_Exit;}
switch (g_pTheApp->m_eInstallMode)
{
case IM_FRESH:
_tcscpy(szTempStringInstallMode, _T("IM_FRESH"));
break;
case IM_MAINTENANCE:
_tcscpy(szTempStringInstallMode, _T("IM_MAINTENANCE"));
break;
case IM_UPGRADE:
_tcscpy(szTempStringInstallMode, _T("IM_UPGRADE"));
break;
}
if (Param1 == OCSELSTATETYPE_ORIGINAL)
{
if ( SubcomponentId )
{
if ( _tcscmp(SubcomponentId, COMPONENTS_SAKIT_WEB ) == 0 )
{
SAKit Kit;
nReturn = Kit.IsInstalled_Web() ? SubcompOn : SubcompOff ;
}
// Check to see if we already know if it is installed
if ( g_pComponents->IsInstalled( SubcomponentId, &bIsInstalled ) )
{
nReturn = bIsInstalled ? SubcompOn : SubcompOff;
}
if ( _tcscmp(SubcomponentId, STRING_iis_www_vdir_scripts ) == 0 )
{
// If they are quering about the scripts vdir, lets check the metabase to
// see if it is really installed, since they could of deleted it by hand.
CMDKey cmdKey;
CMDValue cmdValue;
if ( SUCCEEDED( cmdKey.OpenNode( METABASEPATH_DEFAULTSITE, TRUE ) ) )
{
nReturn = cmdKey.GetData ( cmdValue, MD_KEY_TYPE, METABASEPATH_VDIRSCRIPTS ) ? SubcompOn : SubcompOff;
}
}
}
if ( nReturn == SubcompUseOcManagerDefault )
{
switch (g_pTheApp->m_eInstallMode)
{
case IM_FRESH:
nReturn = SubcompUseOcManagerDefault;
break;
case IM_MAINTENANCE:
nReturn = SubcompUseOcManagerDefault;
break;
case IM_UPGRADE:
nReturn = GetStateFromUpgRegLines(SubcomponentId);
if (SubcompOff == nReturn)
{
if (g_pTheApp->m_eUpgradeType != UT_NONE)
{
// Dont' return back SubCompOff because ocmanage won't be able to turn it on from they're screwy needs logic.
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. OCSELSTATETYPE_ORIGINAL. %s. Return=SubcompUseOcManagerDefault (But really it was SubCompOff)\n"), ComponentId, SubcomponentId, szTempStringInstallMode));
nReturn = SubcompUseOcManagerDefault;
}
}
break;
default:
break;
}
}
goto OC_QUERY_STATE_Func_Exit;
} // OCSELSTATETYPE_ORIGINAL
if (Param1 == OCSELSTATETYPE_CURRENT)
{
// This should overide everything...
if (g_pTheApp->m_bPleaseDoNotInstallByDefault == TRUE)
{
_tcscpy(szTempStringInstallMode, _T("IM_NO_IIS_TO_UPGRADE"));
// change for AndrewR to make sure that during an upgrade, our component is set to default (which will be "off" by default since the modes= line will be set [if not there] at the beginning of guimode setup)
nReturn = SubcompUseOcManagerDefault;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] Start. OCSELSTATETYPE_CURRENT.m_bPleaseDoNotInstallByDefault=TRUE,so setting to SubcompUseOcManagerDefault by default.\n"), ComponentId, SubcomponentId));
goto OC_QUERY_STATE_Func_Exit;
}
if (g_pTheApp->m_eInstallMode == IM_FRESH)
{
nReturn = SubcompUseOcManagerDefault;
goto OC_QUERY_STATE_Func_Exit;
}
if (g_pTheApp->m_eInstallMode == IM_MAINTENANCE)
{
int nOriginal = (gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_ORIGINAL)) ? SubcompOn : SubcompOff;
switch (g_pTheApp->m_dwSetupMode)
{
case SETUPMODE_ADDREMOVE:
nReturn = SubcompUseOcManagerDefault;
break;
case SETUPMODE_REINSTALL:
nReturn = nOriginal;
break;
case SETUPMODE_REMOVEALL:
nReturn = SubcompOff;
break;
}
goto OC_QUERY_STATE_Func_Exit;
}
if (g_pTheApp->m_eInstallMode == IM_UPGRADE)
{
int nOriginal = (gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_ORIGINAL)) ? SubcompOn : SubcompOff;
switch (g_pTheApp->m_dwSetupMode)
{
case SETUPMODE_UPGRADEONLY:
nReturn = nOriginal;
break;
case SETUPMODE_ADDEXTRACOMPS:
nReturn = nOriginal;
break;
}
// ocmanager work around.
// check the ocmanage setup key to see if this entry
// exists -- in an upgrade ocmanage is assuming that it does exist
// when in fact -- it may not (since they ocmanage key could have been introduced in this new OS version
// if the key is in the registry then set this to subcompuseocmanagedefault, otherwise, set it to off
//if (TRUE == DoesOCManagerKeyExist(SubcomponentId))
{
if (SubcompOff == nReturn)
{
nReturn = SubcompUseOcManagerDefault;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. OCSELSTATETYPE_CURRENT. %s. Return=SubcompUseOcManagerDefault (But really it was SubCompOff)\n"), ComponentId, SubcomponentId, szTempStringInstallMode));
}
}
/*
else
{
// however if the key does not exist
// we want to set this to off (since ocmanage will take the default from the modes line -- which is probably on)
// however if this component is needed by another component, then this component won't be able to be turned on
// since it was set to off.
// so before we go and set this component to be off, check to see if it has any needs dependencies (like it's needed by someone else)
// if it's needed by someone else then we set it to be SubcompUseOcManagerDefault
if (TRUE == IsThisSubCompNeededByOthers(SubcomponentId))
{
if (SubcompOff == nReturn)
{
nReturn = SubcompUseOcManagerDefault;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. OCSELSTATETYPE_CURRENT. %s. Return=SubcompUseOcManagerDefault (But really it was SubCompOff)\n"), ComponentId, SubcomponentId, szTempStringInstallMode));
}
}
}
*/
//
// if we are running on Whistler personal, then
// return back OFF! -- so that we will remove ourselves!
//
if (TRUE == IsWhistlerPersonal())
{
nReturn = SubcompOff;
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. OCSELSTATETYPE_CURRENT. %s. Return=SubCompOff (always on personal)\n"), ComponentId, SubcomponentId, szTempStringInstallMode));
}
}
goto OC_QUERY_STATE_Func_Exit;
} // OCSELSTATETYPE_CURRENT
if (Param1 == OCSELSTATETYPE_FINAL)
{
nReturn = SubcompUseOcManagerDefault;
if (!g_iOC_COMPLETE_INSTALLATION_Called)
{
// user could have cancelled setup
// so only do this in guimode fresh or upgrade scenario.
if (g_pTheApp->m_fNTGuiMode)
{
nReturn = SubcompOff;
}
}
goto OC_QUERY_STATE_Func_Exit;
} // OCSELSTATETYPE_FINAL
OC_QUERY_STATE_Func_Exit:
TCHAR szTempStringMode[40];
if (nReturn == SubcompOn)
{_tcscpy(szTempStringMode, _T("SubcompOn"));}
if (nReturn == SubcompOff)
{_tcscpy(szTempStringMode, _T("SubcompOff"));}
if (nReturn == SubcompUseOcManagerDefault)
{_tcscpy(szTempStringMode, _T("SubcompUseOcManagerDefault"));}
if (Param1 == OCSELSTATETYPE_ORIGINAL)
{iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. OCSELSTATETYPE_ORIGINAL. %s. Return=%s\n"), ComponentId, SubcomponentId, szTempStringInstallMode, szTempStringMode));}
if (Param1 == OCSELSTATETYPE_CURRENT)
{iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. OCSELSTATETYPE_CURRENT. %s. Return=%s\n"), ComponentId, SubcomponentId, szTempStringInstallMode, szTempStringMode));}
if (Param1 == OCSELSTATETYPE_FINAL)
{iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("[%s,%s] End. OCSELSTATETYPE_FINAL. %s. Return=%s\n"), ComponentId, SubcomponentId, szTempStringInstallMode, szTempStringMode));}
return nReturn;
}
DWORD TryToSlipInFile(PFILEPATHS pFilePath)
{
DWORD dwReturn = FALSE;
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("TryToSlipInFile:Replacing critical setup file %1!s!.\n"), pFilePath->Target));
BOOL bOK = FALSE;
DWORD dwSourceAttrib = 0;
DWORD dwTargetAttrib = 0;
TCHAR tszTempFileName[MAX_PATH+1];
TCHAR tszTempDir[MAX_PATH+1];
_tcscpy(tszTempDir, pFilePath->Target);
LPTSTR ptszTemp = _tcsrchr(tszTempDir, _T('\\'));
if (ptszTemp)
{
*ptszTemp = _T('\0');
}
GetTempFileName(tszTempDir, _T("IIS"), 0, tszTempFileName);
DeleteFile(tszTempFileName);
//Save file attributes so they can be restored after we are done.
dwSourceAttrib = GetFileAttributes(pFilePath->Source);
dwTargetAttrib = GetFileAttributes(pFilePath->Target);
//Now set the file attributes to normal to ensure file ops succeed.
SetFileAttributes(pFilePath->Source, FILE_ATTRIBUTE_NORMAL);
SetFileAttributes(pFilePath->Target, FILE_ATTRIBUTE_NORMAL);
// Try to rename the filename.dll file!
bOK = MoveFile(pFilePath->Target, tszTempFileName);
if (bOK) {iisDebugOutSafeParams((LOG_TYPE_TRACE, _T("Rename %1!s! to %2!s!. Successfull.\n"), pFilePath->Target, tszTempFileName));}
else{iisDebugOutSafeParams((LOG_TYPE_WARN, _T("Rename %1!s! to %2!s!. Failed.\n"), pFilePath->Target, tszTempFileName));}
bOK = CopyFile(pFilePath->Source, pFilePath->Target, FALSE);
if (bOK) {iisDebugOutSafeParams((LOG_TYPE_TRACE, _T("Copy %1!s! to %2!s!. Successfull.\n"), pFilePath->Source, pFilePath->Target));}
else{iisDebugOutSafeParams((LOG_TYPE_WARN, _T("Copy %1!s! to %2!s!. Failed, Replace on reboot.\n"), pFilePath->Source, pFilePath->Target));}
#ifdef _CHICAGO_
if(!DeleteFile(tszTempFileName))
{
TCHAR tszWinInitFile[MAX_PATH+1];
GetWindowsDirectory(tszWinInitFile, MAX_PATH);
AddPath(tszWinInitFile, _T("WININIT.INI"));
WritePrivateProfileString(_T("Rename"), _T("NUL"), tszTempFileName, tszWinInitFile);
}
#else
MoveFileEx(tszTempFileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
#endif
SetFileAttributes(pFilePath->Source, dwSourceAttrib);
SetFileAttributes(pFilePath->Target, dwTargetAttrib);
SetRebootFlag();
dwReturn = TRUE;
return dwReturn;
}
DWORD HandleFileBusyOurSelf(PFILEPATHS pFilePath)
{
// ----------------------------
// Why would we want to handle the file busy ourself?
//
// When setupapi/ocmanage handles it:
// it will keep the old filename.dll and create a new randomename.tmp for the new file.
//
// The result is that our files will link with the old filename.dll when it does
// all of it's regsvr32 stuff -- this is bad and can produce very confusing results.
//
//
// What We will want to do is:
// 1. try to rename filename.dll to something else. and copy over filename.dll
// 2. if we can't do it then at least log it.
// ----------------------------
DWORD dwRetVal = 0;
TCHAR szDrive_only[_MAX_DRIVE];
TCHAR szPath_only[_MAX_PATH];
TCHAR szDrive_and_Path[_MAX_DRIVE + _MAX_PATH];
TCHAR szFilename_only[_MAX_FNAME];
TCHAR szFilename_ext_only[_MAX_EXT];
TCHAR szFilename_and_ext[_MAX_FNAME + _MAX_EXT];
BOOL bOK = FALSE;
BOOL bFileFound = FALSE;
//Critical Setup files
TCHAR * szFileList[] = {
_T("admexs.dll"),
_T("admwprox.dll"),
_T("admxprox.dll"),
_T("ADROT.dll"),
_T("adsiis.dll"),
_T("adsiis51.dll"),
_T("asp.dll"),
_T("asp51.dll"),
_T("aspperf.dll"),
_T("asptxn.dll"),
_T("authfilt.dll"),
_T("axctrnm.h2"),
_T("axperf.ini"),
_T("browscap.dll"),
_T("browscap.ini"),
_T("CertMap.ocx"),
_T("certobj.dll"),
_T("CertWiz.ocx"),
_T("Cnfgprts.ocx"),
_T("coadmin.dll"),
_T("compfilt.dll"),
_T("ContRot.dll"),
_T("convlog.exe"),
_T("counters.dll"),
_T("davcdata.exe"),
_T("exstrace.dll"),
_T("fortutil.exe"),
_T("ftpctrs.h2"),
_T("ftpctrs.ini"),
_T("ftpctrs2.dll"),
_T("ftpmib.dll"),
_T("ftpsapi2.dll"),
_T("ftpsvc2.dll"),
_T("gzip.dll"),
_T("httpext.dll"),
_T("httpmb51.dll"),
_T("httpmib.dll"),
_T("httpod51.dll"),
_T("httpodbc.dll"),
_T("iis.dll"),
_T("iis.msc"),
_T("iisadmin.dll"),
_T("IIsApp.vbs"),
_T("iisback.vbs"),
_T("iiscfg.dll"),
_T("iische51.dll"),
_T("iisclex4.dll"),
_T("IIsCnfg.vbs"),
_T("iiscrmap.dll"),
_T("iisext.dll"),
_T("iisext51.dll"),
_T("iisfecnv.dll"),
_T("IIsFtp.vbs"),
_T("IIsFtpdr.vbs"),
_T("iislog.dll"),
_T("iislog51.dll"),
_T("iismap.dll"),
_T("iismui.dll"),
_T("iisperf.pmc"),
_T("iisreset.exe"),
_T("iisrstap.dll"),
_T("iisrstas.exe"),
_T("iisRtl.dll"),
_T("IIsScHlp.wsc"),
_T("iissync.exe"),
_T("iisui.dll"),
_T("iisutil.dll"),
_T("iisvdir.vbs"),
_T("iisw3adm.dll"),
_T("iisweb.vbs"),
_T("iiswmi.dll"),
_T("iiswmi.mfl"),
_T("iiswmi.mof"),
_T("inetin51.exe"),
_T("inetinfo.exe"),
_T("inetmgr.dll"),
_T("inetmgr.exe"),
_T("inetsloc.dll"),
_T("infoadmn.dll"),
_T("infocomm.dll"),
_T("infoctrs.dll"),
_T("infoctrs.h2"),
_T("infoctrs.ini"),
_T("ipm.dll"),
_T("isapips.dll"),
_T("isatq.dll"),
_T("iscomlog.dll"),
_T("iwrps.dll"),
_T("logscrpt.dll"),
_T("logtemp.sql"),
_T("logui.ocx"),
_T("lonsint.dll"),
_T("md5filt.dll"),
_T("mdsync.dll"),
_T("metada51.dll"),
_T("metadata.dll"),
_T("NEXTLINK.dll"),
_T("nsepm.dll"),
_T("PageCnt.dll"),
_T("PermChk.dll"),
_T("pwsdata.dll"),
_T("rpcref.dll"),
_T("spud.sys"),
_T("ssinc.dll"),
_T("ssinc51.dll"),
_T("sspifilt.dll"),
_T("status.dll"),
_T("staxmem.dll"),
_T("svcext.dll"),
_T("tools.dll"),
_T("uihelper.dll"),
_T("w3cache.dll"),
_T("w3comlog.dll"),
_T("w3core.dll"),
_T("w3ctrlps.dll"),
_T("w3ctrs.dll"),
_T("w3ctrs.h2"),
_T("w3ctrs.ini"),
_T("w3ctrs51.dll"),
_T("w3ctrs51.h2"),
_T("w3ctrs51.ini"),
_T("w3dt.dll"),
_T("w3ext.dll"),
_T("w3isapi.dll"),
_T("w3svapi.dll"),
_T("w3svc.dll"),
_T("w3tp.dll"),
_T("w3wp.exe"),
_T("wam.dll"),
_T("wam51.dll"),
_T("wamps.dll"),
_T("wamps51.dll"),
_T("wamreg.dll"),
_T("wamreg51.dll"),
_T("wamregps.dll"),
_T("clusiis4.dll"),
_T("iis.msc"),
_T("iissuba.dll"),
_T("regtrace.exe"),
NULL
};
// make sure we didn't get some bogus pointers
if(pFilePath->Target == NULL || pFilePath->Source == NULL) return dwRetVal;
// Check to make sure the file exists!
if(!IsFileExist(pFilePath->Source)) return dwRetVal;
_tsplitpath( pFilePath->Target, szDrive_only, szPath_only, szFilename_only, szFilename_ext_only);
_tcscpy(szFilename_and_ext, szFilename_only);
_tcscat(szFilename_and_ext, szFilename_ext_only);
_tcscpy(szDrive_and_Path, szDrive_only);
_tcscat(szDrive_and_Path, szPath_only);
//
// if this is a removal, then forget it, if it's locked!
//
if((g_pTheApp->m_eInstallMode == IM_MAINTENANCE) && (g_pTheApp->m_dwSetupMode == SETUPMODE_REMOVEALL))
{
return dwRetVal;
}
CString csInetsrvPath = g_pTheApp->m_csPathInetsrv;
// add extra '\' chracter
csInetsrvPath += _T('\\');
BOOL bAbleToCopyFileAfterStopingService = FALSE;
// Check if it's anything in the inetsrv directory.
if (_tcsicmp(csInetsrvPath, szFilename_and_ext) == 0) {bFileFound = TRUE;}
if (_tcsicmp(csInetsrvPath, szDrive_and_Path) == 0)
{
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("Check %1!s! against filename=%2!s!.Match!\n"),csInetsrvPath,szDrive_and_Path));
bFileFound = TRUE;
}
else
{
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("Check %1!s! against filename=%2!s!.no match.\n"),csInetsrvPath,szDrive_and_Path));
}
// loop thru our list of file which
// we care about (since this function will get called for every single
// ocmanage component <-- not just iiS.
if (bFileFound != TRUE)
{
for(int i = 0; !bFileFound && szFileList[i]; i++)
{if(szFilename_and_ext && _tcsicmp(szFileList[i], szFilename_and_ext) == 0) bFileFound = TRUE;}
}
// files on nt5 in the cab are stoed as iis_filename.
// check to see if this file starts with iis_
// if it does then it's a file that we care about..
if (bFileFound != TRUE)
{
}
// ah, do it for everyone.
// bFileFound = TRUE;
// Do we really need to replace this file???
// If the filesize is the same, then lets just save it for reboot!
if (_tcsicmp(_T("iissuba.dll"), szFilename_and_ext) == 0)
{
if (bFileFound)
{
DWORD dwSize1 = ReturnFileSize(pFilePath->Target);
DWORD dwSize2 = ReturnFileSize(pFilePath->Source);
if (dwSize1 == 0xFFFFFFFF || dwSize1 == 0xFFFFFFFF)
{
// unable to retrieve the size of one of those files!
}
else
{
// check if dwSize1 and dwSize2 are the same.
if (dwSize1 == dwSize2)
{
// They are the same, so we don't have to replace it till reboot! yah!
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("Files %1!s! and %2!s! are the same size, not replacing..\n"),pFilePath->Target, pFilePath->Source));
goto HandleFileBusyOurSelf_Exit;
}
}
}
}
// if this is one of the files that we care about, then
// let's try to see who is locking it and try to stop that service or kill the process
// and then try to move the file over!
bAbleToCopyFileAfterStopingService = FALSE;
if(bFileFound)
{
TCHAR szReturnedServiceName[MAX_PATH];
// display which process has it locked, so we can fix it in the future.
CStringList strList;
LogProcessesUsingThisModule(pFilePath->Target, strList);
if (strList.IsEmpty() == FALSE)
{
POSITION pos;
CString csExeName;
int nLen = 0;
pos = strList.GetHeadPosition();
while (pos)
{
csExeName = strList.GetAt(pos);
nLen += csExeName.GetLength() + 1;
if (TRUE == InetIsThisExeAService(csExeName, szReturnedServiceName))
{
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("%1!s! is the %2!s! service and is locking %3!s!. Let's stop that service.\n"),csExeName,szReturnedServiceName, pFilePath->Target));
/*
// Check if it is the netlogon service, We no don't want to stop this service for sure!!!
if (_tcsicmp(szReturnedServiceName, _T("NetLogon")) == 0)
{
// no we do not want to stop this service!!!
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("%1!s! is the %2!s! service and is locking %3!s!. This service should not be stopped.\n"),csExeName,szReturnedServiceName, pFilePath->Target));
bAbleToCopyFileAfterStopingService = FALSE;
break;
}
if (_tcsicmp(szReturnedServiceName, _T("WinLogon")) == 0)
{
// no we do not want to stop this service!!!
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("%1!s! is the %2!s! service and is locking %3!s!. This service should not be stopped.\n"),csExeName,szReturnedServiceName, pFilePath->Target));
bAbleToCopyFileAfterStopingService = FALSE;
break;
}
*/
// check list of services that we definetly do not want to stop!
if (TRUE == IsThisOnNotStopList(g_pTheApp->m_hInfHandle, szReturnedServiceName, TRUE))
{
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("%1!s! is the %2!s! service and is locking %3!s!. This service should not be stopped.\n"),csExeName,szReturnedServiceName, pFilePath->Target));
}
else
{
// add this service to the list of
// services we need to restart after setup is done!!
ServicesRestartList_Add(szReturnedServiceName);
// net stop it
InetStopService(szReturnedServiceName);
// if the service is stopped, then it should be okay if we kill it!
KillProcess_Wrap(csExeName);
// now try to copy over the file!
if (CopyFile(pFilePath->Source, pFilePath->Target, FALSE))
{
bAbleToCopyFileAfterStopingService = TRUE;
break;
}
}
// otherwise go on to the next .exe file
}
else
{
// This .exe file is not a Service....
// Should we kill it???????
// check list of services/processes that we definetly do not want to stop!
if (TRUE == IsThisOnNotStopList(g_pTheApp->m_hInfHandle, csExeName, FALSE))
{
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("%1!s! is locking it. This process should not be killed\n"),csExeName));
}
else
{
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("%1!s! is locking it. Let's kill that process.\n"),csExeName));
if (KillProcess_Wrap(csExeName) == 0)
{
// if we were able to kill the process.
// then let's try to copy over the file.
// now try to copy over the file!
if (CopyFile(pFilePath->Source, pFilePath->Target, FALSE))
{
bAbleToCopyFileAfterStopingService = TRUE;
break;
}
}
}
}
strList.GetNext(pos);
}
}
}
// if this is one of the files that we care about then, let's do the move
if (bAbleToCopyFileAfterStopingService == TRUE)
{
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("HandleFileBusyOurSelf:critical setup file %1!s!, was successfully copied over after stopping services or stopping processes which were locking it.\n"), pFilePath->Target));
}
else
{
if(bFileFound)
{
// make sure the services we know about are stopped.
StopAllServicesRegardless(FALSE);
TryToSlipInFile(pFilePath);
}
else
{
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("HandleFileBusyOurSelf:%1!s! busy, but not one of our files, so ignore.\n"), pFilePath->Target));
}
}
HandleFileBusyOurSelf_Exit:
return dwRetVal;
}
HRESULT GetLastSectionToBeCalled(void)
{
DWORD dwReturn = ERROR_SUCCESS;
// Open up the .inf file and return the last section which will get called...
// [Optional Components]
// iis
// iis_common
// iis_inetmgr
// iis_www
// iis_doc
// iis_htmla
// iis_ftp <-------
//
LPTSTR szLine = NULL;
DWORD dwRequiredSize;
BOOL b = FALSE;
INFCONTEXT Context;
// go to the beginning of the section in the INF file
b = SetupFindFirstLine_Wrapped(g_pTheApp->m_hInfHandle, OCM_OptionalComponents_Section, NULL, &Context);
if (!b)
{
dwReturn = ERROR_PATH_NOT_FOUND;
goto GetLastSectionToBeCalled_Exit;
}
// loop through the items in the section.
while (b)
{
// get the size of the memory we need for this
b = SetupGetLineText(&Context, NULL, NULL, NULL, NULL, 0, &dwRequiredSize);
// prepare the buffer to receive the line
szLine = (LPTSTR)GlobalAlloc( GPTR, dwRequiredSize * sizeof(TCHAR) );
if ( !szLine )
{
goto GetLastSectionToBeCalled_Exit;
}
// get the line from the inf file1
if (SetupGetLineText(&Context, NULL, NULL, NULL, szLine, dwRequiredSize, NULL) == FALSE)
{
goto GetLastSectionToBeCalled_Exit;
}
// overwrite our string
_tcscpy(g_szLastSectionToGetCalled, szLine);
// find the next line in the section. If there is no next line it should return false
b = SetupFindNextLine(&Context, &Context);
// free the temporary buffer
GlobalFree( szLine );
szLine = NULL;
}
if (szLine) {GlobalFree(szLine);szLine=NULL;}
GetLastSectionToBeCalled_Exit:
return dwReturn;
}
// should create a backup of the metabase on remove all....
#define AfterRemoveAll_SaveMetabase_log _T("AfterRemoveAll_SaveMetabase")
int AfterRemoveAll_SaveMetabase(void)
{
iisDebugOut_Start(AfterRemoveAll_SaveMetabase_log);
int iReturn = TRUE;
int iFileExist = FALSE;
CString csMetabaseFile;
csMetabaseFile = g_pTheApp->m_csPathInetsrv + _T("\\metabase.xml");
switch (g_pTheApp->m_eInstallMode)
{
case IM_MAINTENANCE:
{
iisDebugOut((LOG_TYPE_TRACE, _T("%s.End.Maintenance.\n"),AfterRemoveAll_SaveMetabase_log));
if ( g_pTheApp->m_dwSetupMode == SETUPMODE_ADDREMOVE || g_pTheApp->m_dwSetupMode == SETUPMODE_REMOVEALL)
{
iisDebugOut((LOG_TYPE_TRACE, _T("%s.End.Maintenance.addremoveorremoveall\n"),AfterRemoveAll_SaveMetabase_log));
// Check if we removed iis_core!!!
ACTION_TYPE atCORE = GetIISCoreAction(FALSE);
if (atCORE == AT_REMOVE)
{
iisDebugOut((LOG_TYPE_TRACE, _T("%s.End.removing Core.\n"),AfterRemoveAll_SaveMetabase_log));
// Back up the file!
if (IsFileExist(csMetabaseFile))
{
CString csBackupFile;
SYSTEMTIME SystemTime;
GetLocalTime(&SystemTime);
TCHAR szDatedFileName[50];
csBackupFile = g_pTheApp->m_csPathInetsrv + _T("\\MetaBack");
CreateDirectory(csBackupFile, NULL);
_stprintf(szDatedFileName,_T("\\MetaBack\\Metabase.%d%d%d"),SystemTime.wYear,SystemTime.wMonth, SystemTime.wDay);
csBackupFile = g_pTheApp->m_csPathInetsrv + szDatedFileName;
// Get a new filename
csBackupFile = ReturnUniqueFileName(csBackupFile);
if (!IsFileExist(csBackupFile))
{
// backup the current metabase.bin to Metabase.bin.bak#
iisDebugOut((LOG_TYPE_TRACE, _T("backup metabase.bin to %s\n"), csBackupFile));
InetCopyFile(csMetabaseFile, csBackupFile);
}
}
}
}
break;
}
default:
{break;}
}
iisDebugOut_End(AfterRemoveAll_SaveMetabase_log);
return iReturn;
}
int CheckIfWeNeedToMoveMetabaseBin(void)
{
int iReturn = TRUE;
TCHAR szTempDir1[_MAX_PATH];
TCHAR szTempDir2[_MAX_PATH];
BOOL bOK = FALSE;
DWORD dwSourceAttrib = 0;
// check if the old inetsrv dir is different from the new inetsrv directory.
// if it's different then we need to move all the old inetsrv files to the new directory
// no. we just need to move the metabase.bin file.
// all those other files should get deleted in the iis.inf file.
if (!g_pTheApp->m_fMoveInetsrv)
{goto CheckIfWeNeedToMoveMetabaseBin_Exit;}
_tcscpy(szTempDir1, g_pTheApp->m_csPathOldInetsrv);
_tcscpy(szTempDir2, g_pTheApp->m_csPathInetsrv);
AddPath(szTempDir1, _T("Metabase.bin"));
AddPath(szTempDir2, _T("Metabase.bin"));
// Check if the old metabase.bin even exists first...
if (!IsFileExist(szTempDir1))
{goto CheckIfWeNeedToMoveMetabaseBin_Exit;}
// Check if there is a metabase.bin already in the new place
if (IsFileExist(szTempDir2))
{
iisDebugOut((LOG_TYPE_WARN, _T("CheckIfWeNeedToMoveMetabaseBin:Cannot copy %s to %s because already exists. WARNING.\n"), szTempDir1, szTempDir2));
goto CheckIfWeNeedToMoveMetabaseBin_Exit;
}
//
// Try to move over the entire dirs...
//
// Try to rename the system\inetsrv to system32\inetsrv
if (TRUE == MoveFileEx( g_pTheApp->m_csPathOldInetsrv, g_pTheApp->m_csPathInetsrv, MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH ))
{
goto CheckIfWeNeedToMoveMetabaseBin_Exit;
}
// otherwise, we were not able to move the system\inetsrv dir to system32\inetsrv....
// let's see if we can do another type of dirmove.
//Save file attributes so they can be restored after we are done.
dwSourceAttrib = GetFileAttributes(szTempDir1);
//Now set the file attributes to normal to ensure file ops succeed.
SetFileAttributes(szTempDir1, FILE_ATTRIBUTE_NORMAL);
bOK = CopyFile(szTempDir1, szTempDir2, FALSE);
if (bOK) {iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("CheckIfWeNeedToMoveMetabaseBin: Copy %1!s! to %2!s!. Successfull.\n"), szTempDir1, szTempDir2));}
else{iisDebugOutSafeParams((LOG_TYPE_ERROR, _T("CheckIfWeNeedToMoveMetabaseBin: Copy %1!s! to %2!s!. FAILED. Metabase.bin will not be upgraded.\n"), szTempDir1, szTempDir2));}
if (bOK)
{
// remove the old one
DeleteFile(szTempDir1);
// set the file attributes back to what it was.
SetFileAttributes(szTempDir2, dwSourceAttrib);
}
else
{
// set the file attributes back to what it was.
SetFileAttributes(szTempDir1, dwSourceAttrib);
// set return flag to say we failed to move over old files.
// upgrade will not do an upgrade.
iReturn = FALSE;
}
CheckIfWeNeedToMoveMetabaseBin_Exit:
return iReturn;
}
//
// function will copy all the old c:\windows\system\inetsrv files
//
// over to c:\windows\system32\inetsrv
//
// keep a list of the files which we're copied and
// then after the files are copied, delete the files in the old location.
int MigrateAllWin95Files(void)
{
int iReturn = TRUE;
TCHAR szTempSysDir1[_MAX_PATH];
TCHAR szTempSysDir2[_MAX_PATH];
TCHAR szTempSysDir3[_MAX_PATH];
//
// Check if the old metabase.bin even exists first...
//
GimmieOriginalWin95MetabaseBin(szTempSysDir1);
GetSystemDirectory( szTempSysDir2, _MAX_PATH);
AddPath(szTempSysDir2, _T("inetsrv\\Metabase.bin"));
if (!IsFileExist(szTempSysDir1))
{
// Check if there is one in the new location...
if (!IsFileExist(szTempSysDir2))
{
// set return flag to say we failed to move over old files.
// upgrade will not do an upgrade.
iReturn = FALSE;
goto MigrateAllWin95Files_Exit;
}
else
{
iReturn = TRUE;
goto MigrateAllWin95Files_Exit;
}
}
//
// Try to move over the entire dirs...
//
// cut of the filename and just get the path
ReturnFilePathOnly(szTempSysDir1,szTempSysDir3);
GetSystemDirectory( szTempSysDir2, _MAX_PATH);
AddPath(szTempSysDir2, _T("inetsrv"));
// Try to rename the system\inetsrv to system32\inetsrv
RemoveDirectory( szTempSysDir2 ); // Delete the destination directory first, so the move will work.
if (TRUE == MoveFileEx( szTempSysDir3, szTempSysDir2, MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH ))
{goto MigrateAllWin95Files_Exit;}
// otherwise, we were not able to move the system\inetsrv dir to system32\inetsrv....
// let's see if we can do another type of dirmove.
// looks like all the other types of copies failed...
// let's just try to move the metabase.bin file.
GetWindowsDirectory( szTempSysDir1, _MAX_PATH);
AddPath(szTempSysDir1, _T("System\\inetsrv\\Metabase.bin"));
GetSystemDirectory( szTempSysDir2, _MAX_PATH);
AddPath(szTempSysDir2, _T("inetsrv\\Metabase.bin"));
// then let's copy it over, if we don't already have one in system32\inetsrv
if (IsFileExist(szTempSysDir2))
{
iisDebugOut((LOG_TYPE_WARN, _T("Cannot copy %s to %s because already exists. WARNING.\n"), szTempSysDir1, szTempSysDir2));
}
else
{
BOOL bOK = FALSE;
DWORD dwSourceAttrib = 0;
//Save file attributes so they can be restored after we are done.
dwSourceAttrib = GetFileAttributes(szTempSysDir1);
//Now set the file attributes to normal to ensure file ops succeed.
SetFileAttributes(szTempSysDir1, FILE_ATTRIBUTE_NORMAL);
bOK = CopyFile(szTempSysDir1, szTempSysDir2, FALSE);
if (bOK) {iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("Copy %1!s! to %2!s!. Successfull.\n"), szTempSysDir1, szTempSysDir2));}
else{iisDebugOutSafeParams((LOG_TYPE_ERROR, _T("Copy %1!s! to %2!s!. FAILED. Metabase.bin will not be upgraded.\n"), szTempSysDir1, szTempSysDir2));}
if (bOK)
{
// remove the old one
DeleteFile(szTempSysDir1);
// set the file attributes back to what it was.
SetFileAttributes(szTempSysDir2, dwSourceAttrib);
}
else
{
// set the file attributes back to what it was.
SetFileAttributes(szTempSysDir1, dwSourceAttrib);
// set return flag to say we failed to move over old files.
// upgrade will not do an upgrade.
iReturn = FALSE;
}
}
MigrateAllWin95Files_Exit:
return iReturn;
}
int GimmieOriginalWin95MetabaseBin(TCHAR * szReturnedFilePath)
{
int iReturn = FALSE;
INFCONTEXT Context;
int iFindSection = FALSE;
TCHAR szWin95MetabaseFile[_MAX_PATH] = _T("");
iFindSection = SetupFindFirstLine_Wrapped(g_pTheApp->m_hUnattendFile, _T("InternetServer"), _T("Win95MigrateDllMetabaseOrg"), &Context);
if (iFindSection)
{
SetupGetStringField(&Context, 1, szWin95MetabaseFile, _MAX_PATH, NULL);
iisDebugOut((LOG_TYPE_TRACE, _T("[InternetServer].Win95MigrateDllMetabaseOrg=%s.\n"), szWin95MetabaseFile));
// if there is an entry, check if the file exists...
if (IsFileExist(szWin95MetabaseFile))
{
_tcscpy(szReturnedFilePath, szWin95MetabaseFile);
iReturn = TRUE;
}
}
if (FALSE == iReturn)
{
// we were not able to get the metabase.dll from the answer file.
// assume that it's in %windir%\system\inetsrv\metabase.bin
TSTR_PATH strTempSysDir1;
// Check if the old metabase.bin even exists first...
if ( strTempSysDir1.RetrieveWindowsDir() &&
strTempSysDir1.PathAppend( _T("System\\inetsrv\\Metabase.bin") ) )
{
_tcscpy(szReturnedFilePath, strTempSysDir1.QueryStr() );
if (IsFileExist( strTempSysDir1.QueryStr() ))
{
iReturn = TRUE;
}
else
{
iReturn = FALSE;
}
}
}
return iReturn;
}
int HandleWin95MigrateDll(void)
{
int iReturn = TRUE;
int iTempFlag = 0;
int iFindSection = FALSE;
TCHAR szMigrateFileName[_MAX_PATH] = _T("");
INFCONTEXT Context;
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T("Win95Upgrate:"));
if (g_pTheApp->m_hUnattendFile == INVALID_HANDLE_VALUE || g_pTheApp->m_hUnattendFile == NULL)
{
goto HandleWin95MigrateDll_Exit;
}
if (g_pTheApp->m_csUnattendFile)
{
iisDebugOutSafeParams((LOG_TYPE_PROGRAM_FLOW, _T("AnswerFile=%1!s!.\n"), g_pTheApp->m_csUnattendFile));
}
else
{
iisDebugOutSafeParams((LOG_TYPE_TRACE, _T("AnswerFile=(not found).exiting.\n")));
goto HandleWin95MigrateDll_Exit;
}
// Look for our entry
//iisDebugOut((LOG_TYPE_TRACE, _T("HandleWin95MigrateDll:looking for entry [InternetServer]:Win95MigrateDll.\n")));
iFindSection = SetupFindFirstLine_Wrapped(g_pTheApp->m_hUnattendFile, _T("InternetServer"), _T("Win95MigrateDll"), &Context);
if (iFindSection)
{
SetupGetStringField(&Context, 1, szMigrateFileName, _MAX_PATH, NULL);
iisDebugOut((LOG_TYPE_TRACE, _T("[InternetServer].Win95MigrateDll=%s.\n"), szMigrateFileName));
// if there is an entry
// check if the file exists...
if (!IsFileExist(szMigrateFileName))
{
iisDebugOut((LOG_TYPE_ERROR, _T("[InternetServer].Win95MigrateDll=%s. Does not exist!!!!! FAILURE.\n"), szMigrateFileName));
iReturn = FALSE;
goto HandleWin95MigrateDll_Exit;
}
// okay, the file exists.
// lets pass it off to setupapi.
//iisDebugOut((LOG_TYPE_TRACE, _T("%s\n"), szMigrateFileName));
iTempFlag = InstallInfSection(INVALID_HANDLE_VALUE,szMigrateFileName,_T("DefaultInstall"));
if (iTempFlag != TRUE)
{
iisDebugOut((LOG_TYPE_ERROR, _T("FAILED to install DefaultInstall Section.\n"), szMigrateFileName));
goto HandleWin95MigrateDll_Exit;
}
// During the win95 side of migrate.dll
// the metabase.bin file gets a bunch of stuff removed from it.
// then that metabase.bin file gets renamed to another file.
// then the original metabase.bin is put back -- just in case the user cancelled upgrading to win95 (to ensure that they're win95/98 pws still works the metabase.bin has to be kool)
// so what we need to do here is:
// 1.save the old metabase.bin to something in case we mess things up.
// 2.find out what the newlyhacked metabase.bin file is called by looking for the entry in the answerfile
// 3.rename whatever that filename is to metabase.bin
GetTheRightWin95MetabaseFile();
// set the flag to say that we did call win95 migration dll
if (TRUE == MigrateAllWin95Files())
{
// only set this flag if
// we can copy over the existing metabase.bin file!
g_pTheApp->m_bWin95Migration = TRUE;
}
iReturn = iTempFlag;
}
HandleWin95MigrateDll_Exit:
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
return iReturn;
}
int GetTheRightWin95MetabaseFile(void)
{
int iReturn = TRUE;
int iFindSection = FALSE;
INFCONTEXT Context;
TCHAR szOriginalMetabaseBin[_MAX_PATH];
// Get the full path to the original metabase.bin file
GimmieOriginalWin95MetabaseBin(szOriginalMetabaseBin);
iFindSection = FALSE;
iFindSection = SetupFindFirstLine_Wrapped(g_pTheApp->m_hUnattendFile, _T("InternetServer"), _T("Win95MigrateDllMetabaseNew"), &Context);
if (iFindSection)
{
TCHAR szWin95FixedMetabaseFile[_MAX_PATH] = _T("");
SetupGetStringField(&Context, 1, szWin95FixedMetabaseFile, _MAX_PATH, NULL);
iisDebugOut((LOG_TYPE_TRACE, _T("[InternetServer].Win95MigrateDllMetabaseNew=%s.\n"), szWin95FixedMetabaseFile));
// if there is an entry, check if the file exists...
if (IsFileExist(szWin95FixedMetabaseFile))
{
// delete the original metabase.bin file
if (DeleteFile(szOriginalMetabaseBin))
{
// copy in the fixed one.
if (0 == CopyFile(szWin95FixedMetabaseFile, szOriginalMetabaseBin, FALSE))
{
// unable to copy it, try to move it
// Try to rename the system\inetsrv to system32\inetsrv
if (FALSE == MoveFileEx( szWin95FixedMetabaseFile, szOriginalMetabaseBin, MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH ))
{
// do nothing i guess were hosed.
// setup won't upgrade and will only do a clean install
iReturn = FALSE;
}
}
}
}
else
{
iisDebugOut((LOG_TYPE_ERROR, _T("[InternetServer].Win95MigrateDllMetabaseNew=%s. Does not exist!!!!! FAILURE.\n"), szWin95FixedMetabaseFile));
}
}
return iReturn;
}
DWORD RemoveComponent(IN LPCTSTR SubcomponentId, int iThePartToDo)
{
TSTR strTheSectionToDo;
int iWeAreGoingToRemoveSomething = FALSE;
DWORD dwReturn = NO_ERROR;
ACTION_TYPE atTheComponent;
// Make sure there are not MyMessageBox popups!
//int iSaveOld_AllowMessageBoxPopups = g_pTheApp->m_bAllowMessageBoxPopups;
// g_pTheApp->m_bAllowMessageBoxPopups = FALSE;
if (g_pTheApp->m_eInstallMode == IM_UPGRADE) goto RemoveComponent_Exit;
// Check if we are going to remove something...
atTheComponent = GetSubcompAction(SubcomponentId, FALSE);
if (_tcsicmp(SubcomponentId, STRING_iis_core) == 0)
{
atTheComponent = GetIISCoreAction(TRUE);;
}
if (atTheComponent == AT_REMOVE)
{iWeAreGoingToRemoveSomething = TRUE;}
if (iThePartToDo == 1)
{
// Check if we are supposed to do nothing.
if (atTheComponent == AT_DO_NOTHING)
{
// ok, if we're supposed to do nothing
// and the files are not supposed to be there
// then just make sure they are not there by removing them!!!!!
BOOL CurrentState,OriginalState;
OriginalState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_ORIGINAL);
CurrentState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_CURRENT);
// if we think that the original state is uninstalled
// and the current state is not installed, then make sure that the files do not exist by
// removing the files!
if (_tcsicmp(SubcomponentId, STRING_iis_core) == 0)
{
// Since iis_core is not real, check iis_common
if ( gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,
STRING_iis_common,OCSELSTATETYPE_CURRENT) == 1 )
{
iWeAreGoingToRemoveSomething = FALSE;
}
else
{
iWeAreGoingToRemoveSomething = TRUE;
}
}
else
{
if (OriginalState == 0 && CurrentState == 0)
{
// but don't do it for the iis_doc files because there are too many files in that one.
if ((_tcsicmp(SubcomponentId, STRING_iis_common) == 0) ||
(_tcsicmp(SubcomponentId, STRING_iis_www) == 0) ||
(_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_FTP].szComponentName ) == 0))
{
iWeAreGoingToRemoveSomething = TRUE;
}
}
}
}
}
if (iThePartToDo == 2)
{
// Check if we are supposed to do nothing.
if (atTheComponent == AT_DO_NOTHING)
{
if (_tcsicmp(SubcomponentId, _T("iis")) == 0)
{
BOOL CurrentState,OriginalState;
OriginalState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_ORIGINAL);
CurrentState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,SubcomponentId,OCSELSTATETYPE_CURRENT);
// if we think that the original state is uninstalled
// and the current state is not installed, then make sure that the files do not exist by
// removing the files!
if (OriginalState == 0 && CurrentState == 0)
{
// but don't do it for the iis_doc files because there are too many files in that one.
// Special: if this is removing the iis section [all of iis] then, make sure to
// clean everything up.
iWeAreGoingToRemoveSomething = TRUE;
}
else
{
// check if every component is off
if (FALSE == AtLeastOneComponentIsTurnedOn(g_pTheApp->m_hInfHandle))
{
iWeAreGoingToRemoveSomething = TRUE;
}
}
}
}
}
// Do the actual removing
if (iWeAreGoingToRemoveSomething)
{
if (iThePartToDo == 1)
{
//
// Queue the deletion of the files
//
ProgressBarTextStack_Set(IDS_IIS_ALL_REMOVE);
if ( strTheSectionToDo.Copy( _T("OC_QUEUE_FILE_OPS_remove.") ) &&
strTheSectionToDo.Append( SubcomponentId )
)
{
if (GetSectionNameToDo(g_pTheApp->m_hInfHandle, &strTheSectionToDo ))
{
ProcessSection(g_pTheApp->m_hInfHandle, strTheSectionToDo.QueryStr() );
dwReturn = g_GlobalFileQueueHandle_ReturnError ? NO_ERROR : GetLastError();
}
else
{
dwReturn = NO_ERROR;
}
}
else
{
dwReturn = ERROR_NOT_ENOUGH_MEMORY;
}
ProgressBarTextStack_Pop();
}
else
{
ProgressBarTextStack_Set(IDS_IIS_ALL_REMOVE);
_stprintf(g_MyLogFile.m_szLogPreLineInfo2,_T("Unreg %s:"),SubcomponentId);
if ( strTheSectionToDo.Copy( _T("OC_ABOUT_TO_COMMIT_QUEUE_remove.") ) &&
strTheSectionToDo.Append( SubcomponentId ) )
{
ProcessSection(g_pTheApp->m_hInfHandle, strTheSectionToDo.QueryStr() );
}
_tcscpy(g_MyLogFile.m_szLogPreLineInfo2, _T(""));
ProgressBarTextStack_Pop();
}
}
RemoveComponent_Exit:
// Turn popups back on.
//g_pTheApp->m_bAllowMessageBoxPopups = iSaveOld_AllowMessageBoxPopups;
return dwReturn;
}
int AtLeastOneComponentIsTurnedOn(IN HINF hInfFileHandle)
{
int bSomeIsOn = FALSE;
BOOL CurrentState,OriginalState;
CStringList strList;
TSTR strTheSection;
if ( strTheSection.Copy( OCM_OptionalComponents_Section ) &&
GetSectionNameToDo(hInfFileHandle, &strTheSection )
)
{
if ( ERROR_SUCCESS == FillStrListWithListOfSections(hInfFileHandle, strList, strTheSection.QueryStr() ) )
{
// loop thru the list returned back
if (strList.IsEmpty() == FALSE)
{
POSITION pos;
CString csEntry;
pos = strList.GetHeadPosition();
while (pos)
{
csEntry = _T("");
csEntry = strList.GetAt(pos);
// We now have the entry, send it to the function.
OriginalState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,csEntry,OCSELSTATETYPE_ORIGINAL);
CurrentState = gHelperRoutines.QuerySelectionState(gHelperRoutines.OcManagerContext,csEntry,OCSELSTATETYPE_CURRENT);
if (CurrentState == 1) {bSomeIsOn = TRUE;}
// Get the next one.
strList.GetNext(pos);
}
}
}
}
return bSomeIsOn;
}
void AdvanceProgressBarTickGauge(int iTicks)
{
// multiply the amount of ticks by our tick multiple
iTicks = g_GlobalTickValue * iTicks;
for(int i = 0; i < iTicks; i++)
{
gHelperRoutines.TickGauge(gHelperRoutines.OcManagerContext);
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("--- TickGauge ---\n")));
}
g_GlobalTotalTickGaugeCount=g_GlobalTotalTickGaugeCount+iTicks;
if (_tcsicmp(g_szCurrentSubComponent, STRING_iis_common) == 0)
{g_GlobalTickTotal_iis_common = g_GlobalTickTotal_iis_common + g_GlobalTotalTickGaugeCount;}
if (_tcsicmp(g_szCurrentSubComponent, STRING_iis_inetmgr) == 0)
{g_GlobalTickTotal_iis_inetmgr = g_GlobalTickTotal_iis_inetmgr + g_GlobalTotalTickGaugeCount;}
if (_tcsicmp(g_szCurrentSubComponent, STRING_iis_www) == 0)
{g_GlobalTickTotal_iis_www = g_GlobalTickTotal_iis_www + g_GlobalTotalTickGaugeCount;}
if (_tcsicmp(g_szCurrentSubComponent, STRING_iis_pwmgr) == 0)
{g_GlobalTickTotal_iis_pwmgr = g_GlobalTickTotal_iis_pwmgr + g_GlobalTotalTickGaugeCount;}
if (_tcsicmp(g_szCurrentSubComponent, STRING_iis_doc) == 0)
{g_GlobalTickTotal_iis_doc = g_GlobalTickTotal_iis_doc + g_GlobalTotalTickGaugeCount;}
if (_tcsicmp(g_szCurrentSubComponent, STRING_iis_htmla) == 0)
{g_GlobalTickTotal_iis_htmla = g_GlobalTickTotal_iis_htmla + g_GlobalTotalTickGaugeCount;}
if (_tcsicmp(g_szCurrentSubComponent, g_ComponentList[COMPONENT_IIS_FTP].szComponentName ) == 0)
{g_GlobalTickTotal_iis_ftp = g_GlobalTickTotal_iis_ftp + g_GlobalTotalTickGaugeCount;}
}
void SumUpProgressBarTickGauge(IN LPCTSTR SubcomponentId)
{
int iTicksYetToDo = 0;
int iTicksSupposedToDo = 0;
if (SubcomponentId)
{
ACTION_TYPE atComp = GetSubcompAction(SubcomponentId, FALSE);
// Set the Tick Total value for iis_common (which includes iis_core)
if (_tcsicmp(SubcomponentId, STRING_iis_common) == 0)
{
// Get the operations for Core instead since this is bigger.
ACTION_TYPE atCORE = GetIISCoreAction(FALSE);
if (atCORE == AT_REMOVE)
{iTicksSupposedToDo = GetTotalTickGaugeFromINF(SubcomponentId, FALSE);}
else
{iTicksSupposedToDo = GetTotalTickGaugeFromINF(SubcomponentId, TRUE);}
if (atCORE == AT_DO_NOTHING)
{iTicksSupposedToDo = 0;}
}
else
{
if (atComp == AT_REMOVE)
{iTicksSupposedToDo = GetTotalTickGaugeFromINF(SubcomponentId, FALSE);}
else
{iTicksSupposedToDo = GetTotalTickGaugeFromINF(SubcomponentId, TRUE);}
if (atComp == AT_DO_NOTHING)
{iTicksSupposedToDo = 0;}
}
// 1. Take the amount that we're supposed to be finsihed with from the inf.
// 2. take the amount that we are actually done with.
// fill up the difference
if (iTicksSupposedToDo > g_GlobalTotalTickGaugeCount)
{
int iTempVal = 0;
if (_tcsicmp(SubcomponentId, STRING_iis_common) == 0)
{iTempVal = g_GlobalTickTotal_iis_common;}
if (_tcsicmp(SubcomponentId, STRING_iis_inetmgr) == 0)
{iTempVal = g_GlobalTickTotal_iis_inetmgr;}
if (_tcsicmp(SubcomponentId, STRING_iis_www) == 0)
{iTempVal = g_GlobalTickTotal_iis_www;}
if (_tcsicmp(SubcomponentId, STRING_iis_pwmgr) == 0)
{iTempVal = g_GlobalTickTotal_iis_pwmgr;}
if (_tcsicmp(SubcomponentId, STRING_iis_doc) == 0)
{iTempVal = g_GlobalTickTotal_iis_doc;}
if (_tcsicmp(SubcomponentId, STRING_iis_htmla) == 0)
{iTempVal = g_GlobalTickTotal_iis_htmla;}
if (_tcsicmp(SubcomponentId, g_ComponentList[COMPONENT_IIS_FTP].szComponentName ) == 0)
{iTempVal = g_GlobalTickTotal_iis_ftp;}
//iTicksYetToDo = iTicksSupposedToDo - g_GlobalTotalTickGaugeCount;
iTicksYetToDo = iTicksSupposedToDo - iTempVal;
// divide by the tick multiple.
// multiply the amount of ticks by our tick multiple
if (iTicksYetToDo > 0)
{
iTicksYetToDo = iTicksYetToDo / g_GlobalTickValue;
}
AdvanceProgressBarTickGauge(iTicksYetToDo);
}
}
return;
}
// GetIISCoreAction
//
// In the past, IISCore was the metabase, and it was a complicated section,
// that based on the ftp and www services would determine if it was going
// to be installed. Now we are making it and iis_common, exactly the same
//
ACTION_TYPE GetIISCoreAction(int iLogResult)
{
return GetSubcompAction(STRING_iis_common, iLogResult);
}
void DisplayActionsForAllOurComponents(IN HINF hInfFileHandle)
{
CStringList strList;
ACTION_TYPE atTheComponent;
TSTR strTheSection;
if ( strTheSection.Copy( OCM_OptionalComponents_Section ) &&
GetSectionNameToDo(hInfFileHandle, &strTheSection)
)
{
if ( ERROR_SUCCESS == FillStrListWithListOfSections(hInfFileHandle, strList, strTheSection.QueryStr() ) )
{
// loop thru the list returned back
if (strList.IsEmpty() == FALSE)
{
POSITION pos;
CString csEntry;
pos = strList.GetHeadPosition();
while (pos)
{
csEntry = _T("");
csEntry = strList.GetAt(pos);
// We now have the entry, send it to the function.
atTheComponent = GetSubcompAction(csEntry, TRUE);
// Get the next one.
strList.GetNext(pos);
}
}
}
}
return;
}