|
|
/****************************************************************************
Copyright (c) Microsoft Corporation 1997-1999 All rights reserved
***************************************************************************/
#include "pch.h"
#include "dialogs.h"
#include "check.h"
#include "setup.h"
#include "automate.h"
DEFINE_MODULE("Main");
// Globals
HINSTANCE g_hinstance = NULL; OPTIONS g_Options;
// Command line flags
#define OPTION_UNKNOWN 0x00
#define OPTION_VERSIONINGOVERRIDE 0x01
#define OPTION_DEBUG 0x02
#define OPTION_FUNC 0x03
#define OPTION_CHECK 0x04
#define OPTION_ADD 0x05
#define OPTION_UPGRADE 0x06
#define OPTION_AUTOMATED 0x08
// Constants
#define NUMBER_OF_PAGES 15
//
// Adds a page to the dialog.
//
void AddPage( LPPROPSHEETHEADER ppsh, UINT id, DLGPROC pfn, UINT idTitle, UINT idSubtitle ) { PROPSHEETPAGE psp; TCHAR szTitle[ SMALL_BUFFER_SIZE ]; TCHAR szSubTitle[ SMALL_BUFFER_SIZE ];
ZeroMemory( &psp, sizeof(psp) ); psp.dwSize = sizeof(psp); psp.dwFlags = PSP_DEFAULT | PSP_USETITLE; if ( id == IDD_WELCOME || id == IDD_WELCOME_ADD || id == IDD_WELCOME_CHECK ) { psp.dwFlags |= PSP_HIDEHEADER; } else { psp.dwFlags |= PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
if ( idTitle ) { DWORD dw;
dw = LoadString( g_hinstance, idTitle, szTitle, ARRAYSIZE(szTitle) ); Assert( dw ); psp.pszHeaderTitle = szTitle; } else { psp.pszHeaderTitle = NULL; }
if ( idSubtitle ) { DWORD dw;
dw = LoadString( g_hinstance, idSubtitle , szSubTitle, ARRAYSIZE(szSubTitle) ); Assert( dw ); psp.pszHeaderSubTitle = szSubTitle; } else { psp.pszHeaderSubTitle = NULL; } } psp.pszTitle = g_Options.fCheckServer ? MAKEINTRESOURCE( IDS_CHECK_SERVER_TITLE) : MAKEINTRESOURCE( IDS_APPNAME ); psp.hInstance = ppsh->hInstance; psp.pszTemplate = MAKEINTRESOURCE(id); psp.pfnDlgProc = pfn;
ppsh->phpage[ ppsh->nPages ] = CreatePropertySheetPage( &psp ); if ( ppsh->phpage[ ppsh->nPages ] ) ppsh->nPages++; }
//
// Creates the UI pages and kicks off the property sheet.
//
HRESULT WizardPages( ) { TraceFunc( "WizardPages( )\n" );
HRESULT hr = S_OK; HPROPSHEETPAGE rPages[ NUMBER_OF_PAGES ]; PROPSHEETHEADER pshead;
ZeroMemory( &pshead, sizeof(pshead) ); pshead.dwSize = sizeof(pshead); pshead.dwFlags = PSH_WIZARD97 | PSH_PROPTITLE | PSH_USEHICON | PSH_WATERMARK | PSH_HEADER; pshead.hInstance = g_hinstance; pshead.pszCaption = g_Options.fCheckServer ? MAKEINTRESOURCE( IDS_CHECK_SERVER_TITLE) : MAKEINTRESOURCE( IDS_APPNAME ); pshead.phpage = rPages; pshead.pszbmWatermark = MAKEINTRESOURCE( IDB_TITLEPAGE ); pshead.pszbmHeader = MAKEINTRESOURCE( IDB_HEADER );
AddPage( &pshead, IDD_WELCOME, WelcomeDlgProc, 0, 0 ); AddPage( &pshead, IDD_WELCOME_ADD, AddWelcomeDlgProc, 0, 0 ); AddPage( &pshead, IDD_WELCOME_CHECK, CheckWelcomeDlgProc, 0, 0 ); AddPage( &pshead, IDD_EXAMINING_SERVER, ExamineServerDlgProc, IDS_EXAMINING_TITLE, IDS_EXAMINING_SUBTITLE ); AddPage( &pshead, IDD_INTELLIMIRRORROOT, IntelliMirrorRootDlgProc, IDS_INTELLIMIRRORROOT_TITLE, IDS_INTELLIMIRRORROOT_SUBTITLE ); AddPage( &pshead, IDD_SCP, SCPDlgProc, IDS_SCP_TITLE, IDS_SCP_SUBTITLE ); AddPage( &pshead, IDD_OPTIONS, OptionsDlgProc, IDS_OPTIONS_TITLE, IDS_OPTIONS_SUBTITLE ); AddPage( &pshead, IDD_IMAGESOURCE, ImageSourceDlgProc, IDS_IMAGESOURCE_TITLE, IDS_IMAGESOURCE_SUBTITLE ); AddPage( &pshead, IDD_LANGUAGE, LanguageDlgProc, IDS_LANGUAGE_TITLE, IDS_LANGUAGE_SUBTITLE ); AddPage( &pshead, IDD_OSDIRECTORY, OSDirectoryDlgProc, IDS_OSDIRECTORY_TITLE, IDS_OSDIRECTORY_SUBTITLE ); AddPage( &pshead, IDD_DEFAULTSIF, DefaultSIFDlgProc, IDS_DEFAULTSIF_TITLE, IDS_DEFAULTSIF_SUBTITLE ); AddPage( &pshead, IDD_SCREENS, ScreensDlgProc, IDS_SCREENS_TITLE, IDS_SCREENS_SUBTITLE ); AddPage( &pshead, IDD_SUMMARY, SummaryDlgProc, IDS_SUMMARY_TITLE, IDS_SUMMARY_SUBTITLE ); AddPage( &pshead, IDD_WARNING, WarningDlgProc, IDS_WARNING_TITLE, IDS_WARNING_SUBTITLE ); AddPage( &pshead, IDD_SERVEROK, ServerOKDlgProc, IDS_SERVEROK_TITLE, IDS_SERVEROK_SUBTITLE );
PropertySheet( &pshead );
if ( g_Options.fAbort ) { hr = S_FALSE; goto Error; }
if ( g_Options.fError ) { hr = E_FAIL; goto Error; }
Error: RETURN(hr); }
//
// Initializes g_Options.
//
HRESULT InitializeOptions( void ) { DWORD dw; LRESULT lResult; HKEY hkeySetup;
TraceFunc( "InitializeOptions( )\n" );
//
// Initialize all variable to NULL strings or FALSE
//
memset( &g_Options, 0, sizeof(OPTIONS) );
//
// Load default strings
//
dw = LoadString( g_hinstance, IDS_DEFAULTSETUP, g_Options.szInstallationName, ARRAYSIZE(g_Options.szInstallationName) ); Assert( dw );
dw = LoadString( g_hinstance, IDS_UNKNOWN, g_Options.szLanguage, ARRAYSIZE(g_Options.szLanguage) ); Assert( dw );
wcscpy( g_Options.szSourcePath, L"C:\\" ); for( ; g_Options.szSourcePath[0] <= L'Z'; g_Options.szSourcePath[0]++ ) { UINT uDriveType;
uDriveType = GetDriveType( g_Options.szSourcePath );
if ( DRIVE_CDROM == uDriveType ) break; }
if ( g_Options.szSourcePath[0] > L'Z' ) { g_Options.szSourcePath[0] = L'\0'; }
g_Options.hinf = INVALID_HANDLE_VALUE;
g_Options.fFirstTime = TRUE; lResult = RegOpenKey( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Setup", &hkeySetup ); if ( lResult == ERROR_SUCCESS ) { DWORD dwValue; DWORD cbValue; // Find out if we should authorize DCHP
cbValue = sizeof(dwValue); lResult = RegQueryValueEx( hkeySetup, L"RemInst_DontAuthorizeDHCP", NULL, NULL, (LPBYTE)&dwValue, &cbValue ); if ( lResult == ERROR_SUCCESS ) { g_Options.fDontAuthorizeDhcp = dwValue; }
RegCloseKey( hkeySetup ); }
if (SUCCEEDED(GetSetRanFlag(TRUE, FALSE))) { g_Options.fFirstTime = FALSE; } else { g_Options.fFirstTime = TRUE; }
HRETURN(S_OK); }
//
// IsWhiteSpace()
//
BOOL IsWhiteSpace( wchar_t ch ) { if ( ch <=32 ) return TRUE;
return FALSE; }
//
// CheckWhichOption()
DWORD CheckWhichOption( LPWSTR pszOption ) { DWORD dw; WCHAR szOptionTag[ 64 ];
if ( StrCmpNI( pszOption, L"xyzzy", 6 ) == 0 ) return OPTION_VERSIONINGOVERRIDE;
if ( StrCmpNI( pszOption, L"debug", 5 ) == 0 ) return OPTION_DEBUG;
if ( StrCmpNI( pszOption, L"func", 4 ) == 0 ) return OPTION_FUNC;
if ( StrCmpNI( pszOption, L"add", 3 ) == 0 ) return OPTION_ADD;
if ( StrCmpNI( pszOption, L"check", 5 ) == 0 ) return OPTION_CHECK;
if ( StrCmpNI( pszOption, L"upgrade", 7 ) == 0 ) return OPTION_UPGRADE;
if ( StrCmpNI( pszOption, L"auto", 4 ) == 0 ) return OPTION_AUTOMATED;
// Internationalized words
dw = LoadString( g_hinstance, IDS_ADD, szOptionTag, ARRAYSIZE(szOptionTag) ); Assert( dw ); if ( StrCmpNIW( pszOption, szOptionTag, lstrlen(szOptionTag) == 0 ) ) return OPTION_ADD;
dw = LoadString( g_hinstance, IDS_CHECK, szOptionTag, ARRAYSIZE(szOptionTag) ); Assert( dw ); if ( StrCmpNI( pszOption, szOptionTag, lstrlen(szOptionTag) == 0 ) ) return OPTION_CHECK;
return OPTION_UNKNOWN; }
//
// ParseCommandLine()
// Returns false if the call required useage to be printed else true
//
BOOL ParseCommandLine( LPWSTR lpCmdLine ) { LPWSTR psz = lpCmdLine;
while (*psz) { if ( *psz == L'/' || *psz == L'-' ) { LPWSTR pszStartOption = ++psz;
while (*psz && !IsWhiteSpace( *psz ) ) psz++;
*psz = L'\0'; // terminate
switch ( CheckWhichOption( pszStartOption ) ) { #ifdef DEBUG
case OPTION_VERSIONINGOVERRIDE: g_Options.fServerCompatible = TRUE; break; case OPTION_DEBUG: g_dwTraceFlags |= TF_HRESULTS; break;
case OPTION_FUNC: g_dwTraceFlags |= TF_FUNC; break; #endif
case OPTION_ADD: g_Options.fAddOption = TRUE; break;
case OPTION_AUTOMATED: { LPWSTR pszScriptFilename; UINT ErrLine; g_Options.fAutomated = TRUE; WCHAR UnattendedFile[MAX_PATH]; LPWSTR p;
//
// get the script name
//
//
// first eat all the whitespace
//
psz++; while(*psz && IsWhiteSpace( *psz )) { psz++; }
//
// now get the filename, which may or may not be quoted
//
if (*psz == L'\"') { pszScriptFilename = ++psz; while (*psz && ( L'\"' != *psz ) ) { psz++; } } else { pszScriptFilename = psz; while (*psz && !IsWhiteSpace( *psz ) ) { psz++; } } //
// NULL terminate the filename and try to open the file as
// an INF file
//
*psz = L'\0';
g_Options.hinfAutomated = INVALID_HANDLE_VALUE; if( GetFullPathName( pszScriptFilename, MAX_PATH, UnattendedFile, &p ) ) {
g_Options.hinfAutomated = SetupOpenInfFileW( UnattendedFile, NULL, INF_STYLE_WIN4, &ErrLine ); }
if ( g_Options.hinfAutomated == INVALID_HANDLE_VALUE ) { ErrorBox( NULL, L"RISETUP" ); g_Options.fError = TRUE; return(FALSE); } } break;
case OPTION_CHECK: g_Options.fCheckServer = TRUE; break;
case OPTION_UPGRADE: g_Options.fUpgrade = TRUE; break;
case OPTION_UNKNOWN : default : WCHAR szCaption[ SMALL_BUFFER_SIZE ]; WCHAR szUsage[ SMALL_BUFFER_SIZE * 2 ]; DWORD dw; dw = LoadStringW( g_hinstance, IDS_APPNAME, szCaption, ARRAYSIZE( szCaption ) ); Assert( dw ); dw = LoadStringW( g_hinstance, IDS_USAGE, szUsage, ARRAYSIZE( szUsage )); Assert( dw ); MessageBoxW( NULL, szUsage, szCaption, MB_OK ); return FALSE; } }
psz++; } return TRUE; }
//
// DoSetup( )
//
HRESULT DoSetup( ) { HRESULT hr = S_OK; INT iReturn;
//
// Setup dialog
//
iReturn = (INT)DialogBox( g_hinstance, MAKEINTRESOURCE(IDD_TASKS), NULL, SetupDlgProc );
return hr; }
//
// CheckForReboot( )
//
void CheckForReboot( ) { if ( !g_Options.fSISServiceInstalled ) { MessageBoxFromStrings( NULL, IDS_MUST_REBOOT_TITLE, IDS_MUST_REBOOT_MESSAGE, MB_OK | MB_ICONEXCLAMATION );
SetupPromptReboot( NULL, NULL, FALSE ); } }
//
// RunningOnNTServer( )
//
BOOL RunningOnNTServer(void) { TraceFunc( "RunningOnNtServer()\n" );
HKEY hkey; LONG lResult; WCHAR szProductType[50] = { 0 }; DWORD dwType; DWORD dwSize = ARRAYSIZE(szProductType); BOOL fReturn = FALSE; // assume that we are not on NTServer.
// Query the registry for the product type.
lResult = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_READ, &hkey); Assert( lResult == ERROR_SUCCESS ); if ( lResult != ERROR_SUCCESS ) goto Error;
lResult = RegQueryValueEx ( hkey, L"ProductType", NULL, &dwType, (LPBYTE) szProductType, &dwSize); Assert( lResult == ERROR_SUCCESS ); RegCloseKey (hkey); if (lResult != ERROR_SUCCESS) goto Error;
if ( _wcsicmp( szProductType, L"ServerNT" ) == 0 ) { fReturn = TRUE; // yep. NT Server alright.
}
if ( _wcsicmp( szProductType, L"LanmanNT" ) == 0 ) { fReturn = TRUE; // yep. NT Server alright.
}
Error: RETURN(fReturn); }
//
// WinMain()
//
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { TraceFunc( "WinMain( ... )\n" );
HANDLE hMutex; HRESULT hr = E_FAIL; WSADATA wsdata; LPWSTR pszCommandLine = GetCommandLine( );
UNREFERENCED_PARAMETER(nCmdShow); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(hPrevInstance);
TraceFunc( "WinMain( ... )\n" );
g_hinstance = hInstance;
INITIALIZE_TRACE_MEMORY_PROCESS;
// allow only one instance running at a time
hMutex = CreateMutex( NULL, TRUE, L"RemoteBootSetup.Mutext"); if (GetLastError() == ERROR_ALREADY_EXISTS) { MessageBoxFromStrings( NULL, IDS_ALREADY_RUNNING_TITLE, IDS_ALREADY_RUNNING_MESSAGE, MB_OK | MB_ICONSTOP ); goto Cleanup; }
CoInitialize(NULL); WSAStartup( 0x02, &wsdata );
if( !pSetupIsUserAdmin() || !pSetupDoesUserHavePrivilege(SE_SHUTDOWN_NAME) || !pSetupDoesUserHavePrivilege(SE_BACKUP_NAME) || !pSetupDoesUserHavePrivilege(SE_RESTORE_NAME) || !pSetupDoesUserHavePrivilege(SE_SYSTEM_ENVIRONMENT_NAME)) {
MessageBoxFromStrings( NULL, IDS_MUST_BE_ADMINISTRATOR_CAPTION, IDS_MUST_BE_ADMINISTRATOR_TEXT, MB_OK ); goto Cleanup; }
if ( !RunningOnNTServer( ) ) { MessageBoxFromStrings( NULL, IDS_NOT_RUNNING_ON_NT_SERVER_CAPTION, IDS_NOT_RUNNING_ON_NT_SERVER_TEXT, MB_OK ); goto Cleanup; }
hr = InitializeOptions( ); if ( FAILED(hr) ) goto Cleanup;
if( !ParseCommandLine( pszCommandLine )) { goto Cleanup; }
// Change SetupAPI to Non-backup mode.
// also set a flag that makes it fail all signature checks.
// since we're subject to non-driver signing policy and that
// is set to ignore by default, this means that every copy
// operation will generate a signature warning in setupapi.log
// ...but the memory footprint and speed of risetup process
// will both go down significantly since we won't drag the
// crypto libraries into the process.
//
pSetupSetGlobalFlags( pSetupGetGlobalFlags( ) | PSPGF_NO_BACKUP | PSPGF_AUTOFAIL_VERIFIES );
//
// Go figure out a default for what processor we're
// building an image for.
//
GetProcessorType();
if ( !g_Options.fUpgrade && !g_Options.fAutomated ) { hr = WizardPages( ); if ( hr != S_OK ) { goto Cleanup; }
hr = DoSetup( ); if ( hr != S_OK ) { goto Cleanup; } //
// We need to add in the entries so that ntlmv2 gets
// enabled.
//
EnumAndOperate( g_Options.szOSChooserPath, L"login.osc", FixLoginOSC );
CheckForReboot( ); } else if ( g_Options.fAutomated ) { if ( g_Options.fError ) { goto Cleanup; }
hr = GetAutomatedOptions( ); if ( hr != S_OK ) { goto Cleanup; }
hr = FindImageSource( NULL ); if ( hr != S_OK ) { MessageBoxFromStrings( NULL, IDS_FILE_NOT_FOUND_TITLE, IDS_FILE_NOT_FOUND_TEXT, MB_OK ); goto Cleanup; }
hr = CheckImageSource( NULL ); if ( hr != S_OK ) { goto Cleanup; }
hr = CheckInstallation( ); if ( FAILED(hr) ) { goto Cleanup; }
hr = DoSetup( ); if ( hr != S_OK ) { goto Cleanup; }
//
// We need to add in the entries so that ntlmv2 gets
// enabled.
//
EnumAndOperate( g_Options.szOSChooserPath, L"login.osc", FixLoginOSC ); } else if ( g_Options.fUpgrade ) { hr = UpdateRemoteInstallTree( );
//
// We need to add in the entries so that ntlmv2 gets
// enabled.
//
EnumAndOperate( g_Options.szOSChooserPath, L"login.osc", FixLoginOSC );
//
// Generate the name of the SIS path and the set the proper
// security for it
//
if (SUCCEEDED(hr)) { WCHAR sisPathName[MAX_PATH+1]; hr = GetRemoteInstallShareInfo(); if (SUCCEEDED(hr)) {
hr = GetSisVolumePath(sisPathName,(sizeof(sisPathName)/sizeof(WCHAR))); if (SUCCEEDED(hr)) {
hr = SetSISCommonStoreSecurity( sisPathName ); } } } } else { AssertMsg( 0, "How did I get here?" ); }
Cleanup: CoUninitialize(); if ( hMutex ) { CloseHandle( hMutex ); } if ( g_Options.hinf != INVALID_HANDLE_VALUE ) { SetupCloseInfFile( g_Options.hinf ); }
UNINITIALIZE_TRACE_MEMORY;
RETURN(hr); }
// stolen from the CRT, used to shrink our code
int _stdcall ModuleEntry(void) { int i; STARTUPINFO si; LPSTR pszCmdLine = GetCommandLineA();
if ( *pszCmdLine == '\"' ) { /*
* Scan, and skip over, subsequent characters until * another double-quote or a null is encountered. */ while ( *++pszCmdLine && (*pszCmdLine != '\"') ); /*
* If we stopped on a double-quote (usual case), skip * over it. */ if ( *pszCmdLine == '\"' ) pszCmdLine++; } else { while (*pszCmdLine > ' ') pszCmdLine++; }
/*
* Skip past any white space preceeding the second token. */ while (*pszCmdLine && (*pszCmdLine <= ' ')) { pszCmdLine++; }
GetStartupInfo(&si);
i = WinMain(GetModuleHandle(NULL), NULL, pszCmdLine, si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT); ExitProcess(i); }
|