|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
osloader.c
Abstract:
This module contains the code that implements the NT operating system loader.
Author:
David N. Cutler (davec) 10-May-1991
Revision History:
--*/
#include "bldr.h"
#include "haldtect.h"
#include "parseini.h"
#include "setupbat.h"
#include "ctype.h"
#include "stdio.h"
#include "string.h"
#include "msg.h"
#include <netboot.h>
#if defined(REMOTE_BOOT)
extern BOOLEAN NetFS_Cache;
UCHAR szRemoteBootCfgFile[] = "RemoteBoot.cfg"; CHAR KernelFileName[8+1+3+1]="ntoskrnl.exe"; CHAR HalFileName[8+1+3+1]="hal.dll";
VOID BlWarnAboutFormat( IN BOOLEAN SecretValid, IN PUCHAR OsLoader );
ARC_STATUS BlCheckMachineReplacement ( IN PCHAR SystemDevice, IN ULONG SystemDeviceId, IN ULONGLONG NetRebootParameter, IN PUCHAR OsLoader )
/*++
Routine Description:
This routine checks to see if a part of the machine has been replaced. Specifically, it checks if: - Hal is different. - Physical Disk is different.
If it finds either case, then it creates at SETUP_LOADER_BLOCK and sets the flags to pass to the kernel.
Note: NetFS_Cache is a boolean which is used to turn on/off client side caching in the loader. When set to FALSE, the cache is turned off.
Arguments:
SystemDevice - Character string of the ARC name of the system.
SystemDeviceId - Handle to the server share where this machine account exists.
NetRebootParameter - Any parameter that may have been passed during a soft reboot of the PC.
OsLoader - TFTP path to osloader.exe
Return Value:
Success or not. Failure means to quit loading.
--*/
{ ARC_DISK_SIGNATURE Signature; ARC_STATUS Status; BOOLEAN NetBootRequiresFormat = FALSE; BOOLEAN NetBootClientCacheStale = FALSE; BOOLEAN NetBootDisconnected = FALSE; BOOLEAN SkipHalCheck; ULONG FileId; ULONG CacheBootSerialNumber; ULONG CacheDiskSignature; ULONG ServerBootSerialNumber; ULONG ServerDiskSignature; UCHAR NetBootHalName[MAX_HAL_NAME_LENGTH + 1]; PUCHAR NetBootDetectedHalName; UCHAR OutputBuffer[256]; UCHAR DiskName[80]; PUCHAR p; PUCHAR Guid; ULONG GuidLength;
//
// Detect which HAL we want to use.
//
NetBootDetectedHalName = SlDetectHal(); SkipHalCheck = (NetBootDetectedHalName == NULL);
if (!NetworkBootRom) { NetBootDisconnected = TRUE; goto EndTesting; }
strcpy(OutputBuffer, NetBootPath); strcat(OutputBuffer, szRemoteBootCfgFile);
if (BlOpen(SystemDeviceId, OutputBuffer, ArcOpenReadOnly, &FileId) == ESUCCESS) {
Status = BlReadAtOffset(FileId, 0, sizeof(ULONG), &CacheBootSerialNumber);
BlClose(FileId);
if (Status != ESUCCESS) { NetBootClientCacheStale = TRUE; NetBootRequiresFormat = TRUE; NetFS_Cache = FALSE; goto EndTesting; }
NetFS_Cache = FALSE;
if (BlOpen(SystemDeviceId, OutputBuffer, ArcOpenReadOnly, &FileId) == ESUCCESS) {
// Get parameters from each file
Status = BlReadAtOffset(FileId, 0, sizeof(ULONG), &ServerBootSerialNumber); if (Status != ESUCCESS) { NetBootClientCacheStale = TRUE; NetBootRequiresFormat = TRUE; BlClose(FileId); goto EndTesting; } Status = BlReadAtOffset(FileId, sizeof(ULONG), sizeof(ULONG), &ServerDiskSignature); if (Status != ESUCCESS) { NetBootClientCacheStale = TRUE; NetBootRequiresFormat = TRUE; BlClose(FileId); goto EndTesting; }
Signature.ArcName = OutputBuffer;
strcpy(DiskName, NetBootActivePartitionName); p = strstr(DiskName, "partition"); ASSERT( p != NULL ); *p = '\0';
if (!BlGetDiskSignature(DiskName, FALSE, &Signature )) { // Assume diskless PC
BlClose(FileId); goto EndTesting; }
CacheDiskSignature = Signature.Signature; if (CacheBootSerialNumber < ServerBootSerialNumber) { NetBootClientCacheStale = TRUE; }
if (CacheDiskSignature != ServerDiskSignature) { NetBootClientCacheStale = TRUE; NetBootRequiresFormat = TRUE; BlClose(FileId); goto EndTesting; }
Status = BlReadAtOffset(FileId, sizeof(ULONG) + sizeof(ULONG), sizeof(char) * (MAX_HAL_NAME_LENGTH+1), NetBootHalName ); if (Status != ESUCCESS) { NetBootClientCacheStale = TRUE; NetBootRequiresFormat = TRUE; BlClose(FileId); goto EndTesting; }
GetGuid(&Guid, &GuidLength);
if (!SkipHalCheck && strncmp(NetBootHalName, NetBootDetectedHalName, MAX_HAL_NAME_LENGTH)) { if (!NT_SUCCESS(NetCopyHalAndKernel(NetBootDetectedHalName, Guid, GuidLength))) { Status = EMFILE; goto CleanUp; } NetBootClientCacheStale = TRUE; }
BlClose(FileId);
} else { // Running disconnected. Assume everything is ok.
NetBootDisconnected = TRUE; }
if (!NetBootClientCacheStale) { NetFS_Cache = TRUE; }
} else {
NetFS_Cache = FALSE; NetBootClientCacheStale = TRUE; NetBootRequiresFormat = TRUE;
}
EndTesting:
Status = ESUCCESS;
if (NetBootRequiresFormat) { BlWarnAboutFormat((BOOLEAN)(NetRebootParameter == NET_REBOOT_SECRET_VALID), OsLoader); }
BlLoaderBlock->SetupLoaderBlock->Flags |= SETUPBLK_FLAGS_IS_REMOTE_BOOT; if (NetBootClientCacheStale) { NetBootRepin = TRUE; } if ( NetBootDisconnected ) { BlLoaderBlock->SetupLoaderBlock->Flags |= SETUPBLK_FLAGS_DISCONNECTED; } if ( NetBootRequiresFormat ) { BlLoaderBlock->SetupLoaderBlock->Flags |= SETUPBLK_FLAGS_FORMAT_NEEDED; }
memcpy(BlLoaderBlock->SetupLoaderBlock->NetBootHalName, NetBootDetectedHalName, sizeof(BlLoaderBlock->SetupLoaderBlock->NetBootHalName) ); BlLoaderBlock->SetupLoaderBlock->NetBootHalName[MAX_HAL_NAME_LENGTH] = '\0';
CleanUp:
return Status; }
VOID BlWarnAboutFormat( IN BOOLEAN SecretValid, IN PUCHAR OsLoader )
/*++
Routine Description:
This routine provides the user-interface for warning the user that a new harddisk has been detected and will be formatted.
Arguments:
SecretValid - If TRUE, then return because there is no message for the user, otherwise display a message that the user must logon and the disk will be wiped out.
OsLoader - Path for TFTP to the osloader.exe image.
Return Value:
None.
--*/
{ ULONG HeaderLines; ULONG TrailerLines; ULONG Count; UCHAR Key; PCHAR MenuHeader; PCHAR MenuTrailer; PCHAR Temp; ULONG DisplayLines; ULONG CurrentSelection = 0; UCHAR Buffer[16];
if (SecretValid) { // We don't present the user with a screen in this case because we have already forced
// a logon and a rewrite of the secret.
return; } else { MenuHeader = BlFindMessage(BL_FORCELOGON_HEADER); } MenuTrailer = BlFindMessage(BL_WARNFORMAT_TRAILER);
sprintf(Buffer, "%s%s", ASCI_CSI_OUT, ";44;37m"); // White on Blue
ArcWrite(BlConsoleOutDeviceId, Buffer, strlen(Buffer), &Count);
BlClearScreen();
sprintf(Buffer, "%s%s", ASCI_CSI_OUT, ";37;44m"); // Blue on white
ArcWrite(BlConsoleOutDeviceId, Buffer, strlen(Buffer), &Count);
//
// Count the number of lines in the header.
//
HeaderLines=BlCountLines(MenuHeader);
//
// Display the menu header.
//
ArcWrite(BlConsoleOutDeviceId, MenuHeader, strlen(MenuHeader), &Count);
//
// Count the number of lines in the trailer.
//
TrailerLines=BlCountLines(MenuTrailer);
BlPositionCursor(1, ScreenHeight-TrailerLines); ArcWrite(BlConsoleOutDeviceId, MenuTrailer, strlen(MenuTrailer), &Count);
//
// Compute number of selections that can be displayed
//
DisplayLines = ScreenHeight-HeaderLines-TrailerLines-3;
//
// Start menu selection loop.
//
do { Temp = BlFindMessage(BL_WARNFORMAT_CONTINUE); if (Temp != NULL) { BlPositionCursor(5, HeaderLines+3); BlSetInverseMode(TRUE); ArcWrite(BlConsoleOutDeviceId, Temp, strlen(Temp), &Count); BlSetInverseMode(FALSE); }
//
// Loop waiting for keypress or time change.
//
do { if (ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) { BlPositionCursor(1,ScreenHeight); BlClearToEndOfLine(); ArcRead(ARC_CONSOLE_INPUT, &Key, sizeof(Key), &Count); break; }
} while ( TRUE );
switch (Key) { case ASCI_CSI_IN: ArcRead(ARC_CONSOLE_INPUT, &Key, sizeof(Key), &Count); break;
default: break; }
} while ( (Key != ASCII_CR) && (Key != ASCII_LF) );
BlClearScreen();
if (!SecretValid) { while ( TRUE ) { NetSoftReboot( #if defined(_ALPHA_)
#if defined(_AXP64_)
"OSChooser\\axp64\\startrom.com", #else
"OSChooser\\alpha\\startrom.com", #endif
#endif
#if defined(_MIPS_)
"OSChooser\\mips\\startrom.com", #endif
#if defined(_PPC_)
"OSChooser\\ppc\\startrom.com", #endif
#if defined(_IA64_)
"OSChooser\\ia64\\startrom.com", #endif
#if defined(_X86_)
"OSChooser\\i386\\startrom.com", #endif
NET_REBOOT_WRITE_SECRET_ONLY, OsLoader, NULL, // SIF file
NULL, // user
NULL, // domain
NULL // password
); } } }
#endif // defined(REMOTE_BOOT)
//
// NOTE: [bassamt] Stubs for TextMode setup funtions. These
// are needed so that we can call SlDetectHal during regular boot.
//
PVOID InfFile = NULL; PVOID WinntSifHandle = NULL; BOOLEAN DisableACPI = FALSE;
VOID SlNoMemError( IN ULONG Line, IN PCHAR File )
/*++
Routine Description:
This routine does nothing.
Arguments:
Line - Line number of the error.
File - Name of the file with the error.
Return Value:
None.
--*/ { UNREFERENCED_PARAMETER( Line ); UNREFERENCED_PARAMETER( File );
return; }
VOID SlBadInfLineError( IN ULONG Line, IN PCHAR INFFile ) /*++
Routine Description:
This routine does nothing.
Arguments:
Line - Line number of the error.
INFFile - Supplies a pointer to the INF filename.
Return Value:
None.
--*/ { UNREFERENCED_PARAMETER( Line ); UNREFERENCED_PARAMETER( INFFile );
return; }
VOID SlErrorBox( IN ULONG MessageId, IN ULONG Line, IN PCHAR File ) /*++
Routine Description:
This routine does nothing.
Arguments:
MessageId - Id of the text to display.
Line - Line number of the of the warning.
File - Name of the file where warning is coming from.
Return Value:
None.
--*/ { UNREFERENCED_PARAMETER( MessageId ); UNREFERENCED_PARAMETER( Line ); UNREFERENCED_PARAMETER( File );
return; }
VOID SlFriendlyError( IN ULONG uStatus, IN PCHAR pchBadFile, IN ULONG uLine, IN PCHAR pchCodeFile )
/*++
Routine Description:
This routine does nothing.
Arguments:
uStatus - ARC error code
pchBadFile - Name of file causing error (Must be given for handled ARC codes. Optional for unhandled codes.)
uLine - Line # in source code file where error occurred (only used for unhandled codes.)
pchCodeFile - Name of souce code file where error occurred (only used for unhandled codes.)
Return Value:
None.
--*/
{ UNREFERENCED_PARAMETER( uStatus ); UNREFERENCED_PARAMETER( pchBadFile ); UNREFERENCED_PARAMETER( uLine ); UNREFERENCED_PARAMETER( pchCodeFile );
return; }
VOID SlFatalError( IN ULONG MessageId, ... )
/*++
Routine Description:
This routine does nothing. In the context of dynamic HAL detection, we just ignore the error and hope everything is ok.
Arguments:
MessageId - Supplies ID of message box to be presented.
any sprintf-compatible arguments to be inserted in the message box.
Return Value:
None.
--*/
{ UNREFERENCED_PARAMETER( MessageId );
return; }
ULONG SlGetChar( VOID ) { return 0; }
VOID SlPrint( IN PTCHAR FormatString, ... ) { UNREFERENCED_PARAMETER( FormatString );
return; }
|