429 lines
7.7 KiB
C
429 lines
7.7 KiB
C
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ocm.c
|
|
|
|
Abstract:
|
|
|
|
OC Manager implementation for intergratation with NT base setup
|
|
|
|
Author:
|
|
|
|
Ted Miller (tedm) 20 May 1997
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "setupp.h"
|
|
#pragma hdrstop
|
|
|
|
#include <ocmanage.h>
|
|
#include <ocmgrlib.h>
|
|
|
|
// Returns TRUE if ASR is enabled. Otherwise, FALSE is returned.
|
|
BOOL
|
|
AsrIsEnabled(VOID);
|
|
|
|
VOID
|
|
OcFillInSetupDataW(
|
|
OUT PSETUP_DATAW SetupData
|
|
);
|
|
|
|
VOID
|
|
OcFillInSetupDataA(
|
|
OUT PSETUP_DATAA SetupData
|
|
);
|
|
|
|
VOID
|
|
OcSetReboot(
|
|
VOID
|
|
);
|
|
|
|
INT
|
|
OcLogError(
|
|
IN OcErrorLevel Level,
|
|
IN LPCWSTR FormatString,
|
|
...
|
|
);
|
|
|
|
|
|
|
|
OCM_CLIENT_CALLBACKS OcManagerImplementationCallbackRoutines = {
|
|
OcFillInSetupDataA,
|
|
OcLogError,
|
|
OcSetReboot,
|
|
OcFillInSetupDataW,
|
|
ShowHideWizardPage,
|
|
Billboard_Progress_Callback,
|
|
Billboard_Set_Progress_Text,
|
|
pSetupDebugPrint
|
|
};
|
|
|
|
|
|
|
|
PVOID
|
|
FireUpOcManager(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize OC Manager, generating an OC Manager context.
|
|
The master oc inf is assumed to be %windir%\system32\SYSOC.INF.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
OC Manager context handle.
|
|
|
|
--*/
|
|
|
|
{
|
|
PWSTR MasterOcInf;
|
|
WCHAR SystemDir[MAX_PATH];
|
|
WCHAR DirSave[MAX_PATH];
|
|
BOOL ShowErr;
|
|
PVOID OcManagerContext;
|
|
|
|
|
|
//
|
|
// save the current directory
|
|
//
|
|
|
|
GetCurrentDirectory( sizeof(DirSave)/sizeof(WCHAR), DirSave );
|
|
|
|
//
|
|
// get the system directory
|
|
//
|
|
|
|
GetSystemDirectory( SystemDir, MAX_PATH );
|
|
|
|
//
|
|
// set the current dir to the master oc inf path
|
|
// so that OcInitialize can find the component DLLs
|
|
//
|
|
|
|
SetCurrentDirectory( SystemDir );
|
|
|
|
//
|
|
// create a valid path to the master oc inf
|
|
//
|
|
|
|
if( !MiniSetup ) {
|
|
if (!AsrIsEnabled()) {
|
|
MasterOcInf = L"SYSOC.INF";
|
|
}
|
|
else {
|
|
MasterOcInf = L"ASROC.INF";
|
|
}
|
|
|
|
} else {
|
|
MasterOcInf = L"MINIOC.INF";
|
|
}
|
|
|
|
//
|
|
// initialize the oc manager
|
|
//
|
|
|
|
BEGIN_SECTION(L"Initializing the OC manager");
|
|
OcManagerContext = OcInitialize(
|
|
&OcManagerImplementationCallbackRoutines,
|
|
MasterOcInf,
|
|
OCINIT_FORCENEWINF,
|
|
&ShowErr,
|
|
NULL
|
|
);
|
|
END_SECTION(L"Initializing the OC manager");
|
|
|
|
//
|
|
// restore the current directory
|
|
//
|
|
|
|
SetCurrentDirectory( DirSave );
|
|
|
|
//
|
|
// return the oc manager handle
|
|
//
|
|
|
|
return OcManagerContext;
|
|
}
|
|
|
|
|
|
VOID
|
|
KillOcManager(
|
|
PVOID OcManagerContext
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Terminate OC Manager
|
|
|
|
Arguments:
|
|
|
|
OC Manager context handle.
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
|
|
{
|
|
MYASSERT(OcManagerContext);
|
|
if (OcManagerContext)
|
|
OcTerminate(&OcManagerContext);
|
|
}
|
|
|
|
|
|
VOID
|
|
OcFillInSetupDataW(
|
|
OUT PSETUP_DATAW SetupData
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
"Glue" routine called by the OC Manager to request that the
|
|
implementation fill in setup data to be passed to OC Manager
|
|
component DLLs that expect Unicode data.
|
|
|
|
Arguments:
|
|
|
|
SetupData - recieves setup data expected by OC components.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// It's not possible to be any more specific than this because
|
|
// the mode page hasn't been shown yet.
|
|
//
|
|
SetupData->SetupMode = SETUPMODE_UNKNOWN;
|
|
SetupData->ProductType = ProductType;
|
|
|
|
lstrcpy(SetupData->SourcePath,SourcePath);
|
|
|
|
SetupData->OperationFlags = 0;
|
|
if(Win31Upgrade) {
|
|
SetupData->OperationFlags |= SETUPOP_WIN31UPGRADE;
|
|
}
|
|
|
|
if(Win95Upgrade) {
|
|
SetupData->OperationFlags |= SETUPOP_WIN95UPGRADE;
|
|
}
|
|
|
|
if(Upgrade) {
|
|
SetupData->OperationFlags |= SETUPOP_NTUPGRADE;
|
|
}
|
|
|
|
if(UnattendMode > UAM_PROVIDEDEFAULT) {
|
|
SetupData->OperationFlags |= SETUPOP_BATCH;
|
|
lstrcpy(SetupData->UnattendFile,AnswerFile);
|
|
}
|
|
|
|
|
|
//
|
|
// Which files are available?
|
|
//
|
|
#if defined(_AMD64_)
|
|
SetupData->OperationFlags |= SETUPOP_X86_FILES_AVAIL | SETUPOP_AMD64_FILES_AVAIL;
|
|
#elif defined(_X86_)
|
|
SetupData->OperationFlags |= SETUPOP_X86_FILES_AVAIL;
|
|
#elif defined(_IA64_)
|
|
SetupData->OperationFlags |= SETUPOP_X86_FILES_AVAIL | SETUPOP_IA64_FILES_AVAIL;
|
|
#else
|
|
#pragma message( "*** Warning! No architecture defined!")
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
OcFillInSetupDataA(
|
|
OUT PSETUP_DATAA SetupData
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
"Glue" routine called by the OC Manager to request that the
|
|
implementation fill in setup data to be passed to OC Manager
|
|
component DLLs that expect ANSI data.
|
|
|
|
Arguments:
|
|
|
|
SetupData - recieves setup data expected by OC components.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
SETUP_DATAW setupdata;
|
|
|
|
OcFillInSetupDataW(&setupdata);
|
|
|
|
SetupData->SetupMode = setupdata.SetupMode;
|
|
SetupData->ProductType = setupdata.ProductType;
|
|
SetupData->OperationFlags = setupdata.OperationFlags;
|
|
|
|
WideCharToMultiByte(
|
|
CP_ACP,
|
|
0,
|
|
setupdata.SourcePath,
|
|
-1,
|
|
SetupData->SourcePath,
|
|
sizeof(SetupData->SourcePath),
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
WideCharToMultiByte(
|
|
CP_ACP,
|
|
0,
|
|
setupdata.UnattendFile,
|
|
-1,
|
|
SetupData->UnattendFile,
|
|
sizeof(SetupData->UnattendFile),
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
|
|
VOID
|
|
OcSetReboot(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
"Glue" routine called by the OC Manager when a reboot is deemed
|
|
necessary by an OC Manager component.
|
|
|
|
For this integrated version of OC Manager, this does nothing;
|
|
the system is rebooted at the end of text mode.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
INT
|
|
OcLogError(
|
|
IN OcErrorLevel Level,
|
|
IN LPCWSTR FormatString,
|
|
...
|
|
)
|
|
{
|
|
TCHAR str[4096];
|
|
va_list arglist;
|
|
UINT Icon;
|
|
UINT lev;
|
|
|
|
va_start(arglist,FormatString);
|
|
wvsprintf(str,FormatString,arglist);
|
|
va_end(arglist);
|
|
|
|
if (Level & OcErrLevWarning)
|
|
lev = LogSevWarning;
|
|
else if (Level & OcErrLevError)
|
|
lev = LogSevError;
|
|
else if (Level & OcErrLevFatal)
|
|
lev = LogSevError;
|
|
else
|
|
lev = LogSevInformation;
|
|
|
|
#if DBG
|
|
if (lev != LogSevInformation) {
|
|
SetupDebugPrint(str);
|
|
}
|
|
#endif
|
|
|
|
SetuplogError(lev, str, 0, NULL, NULL);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
HWND
|
|
ShowHideWizardPage(
|
|
IN BOOL bShow
|
|
)
|
|
{
|
|
HWND hwnd = GetBBhwnd();
|
|
if (hwnd)
|
|
{
|
|
SendMessage(WizardHandle, WMX_BBTEXT, (WPARAM)!bShow, 0);
|
|
}
|
|
// If we show the wizard again, return the wizard hwnd
|
|
if (bShow)
|
|
{
|
|
// Should hide the progress bar, the wizard page is showing.
|
|
BB_ShowProgressGaugeWnd(SW_HIDE);
|
|
hwnd = WizardHandle;
|
|
}
|
|
return hwnd;
|
|
}
|
|
|
|
LRESULT
|
|
Billboard_Progress_Callback(
|
|
IN UINT Msg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
{
|
|
LRESULT lResult;
|
|
if ((Msg == PBM_SETRANGE) || (Msg == PBM_SETRANGE32))
|
|
{
|
|
// Also enable the progress bar
|
|
// Note: No hiding of the progress this way.
|
|
BB_ShowProgressGaugeWnd(SW_SHOW);
|
|
lResult = ProgressGaugeMsgWrapper(Msg, wParam, lParam);
|
|
}
|
|
else
|
|
{
|
|
lResult = ProgressGaugeMsgWrapper(Msg, wParam, lParam);
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
VOID Billboard_Set_Progress_Text(LPCTSTR Text)
|
|
{
|
|
BB_SetProgressText(Text);
|
|
}
|
|
|
|
|
|
|