840 lines
20 KiB
C
840 lines
20 KiB
C
/*++
|
||
|
||
Copyright (c) 1992 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
entry.c
|
||
|
||
Abstract:
|
||
|
||
x86-specific startup for setupldr
|
||
|
||
Author:
|
||
|
||
John Vert (jvert) 14-Oct-1993
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
#include "bootx86.h"
|
||
#include "stdio.h"
|
||
#include "flop.h"
|
||
#include <ramdisk.h>
|
||
|
||
#if 0
|
||
#define DBGOUT(x) BlPrint x
|
||
#define DBGPAUSE while(!GET_KEY());
|
||
#else
|
||
#define DBGOUT(x)
|
||
#define DBGPAUSE
|
||
#endif
|
||
|
||
|
||
//
|
||
// Prototypes for Internal Routines
|
||
//
|
||
|
||
VOID
|
||
DoGlobalInitialization(
|
||
PBOOT_CONTEXT
|
||
);
|
||
|
||
#if defined(ELTORITO)
|
||
BOOLEAN ElToritoCDBoot = FALSE;
|
||
#endif
|
||
|
||
extern CHAR NetBootPath[];
|
||
|
||
//
|
||
// Global context pointers. These are passed to us by the SU module or
|
||
// the bootstrap code.
|
||
//
|
||
|
||
PCONFIGURATION_COMPONENT_DATA FwConfigurationTree = NULL;
|
||
PEXTERNAL_SERVICES_TABLE ExternalServicesTable;
|
||
UCHAR BootPartitionName[80];
|
||
ULONG MachineType = 0;
|
||
ULONG OsLoaderBase;
|
||
ULONG OsLoaderExports;
|
||
extern PUCHAR BlpResourceDirectory;
|
||
extern PUCHAR BlpResourceFileOffset;
|
||
ULONG PcrBasePage;
|
||
ULONG TssBasePage;
|
||
|
||
ULONG BootFlags = 0;
|
||
|
||
ULONG NtDetectStart = 0;
|
||
ULONG NtDetectEnd = 0;
|
||
|
||
#ifdef FORCE_CD_BOOT
|
||
|
||
BOOLEAN
|
||
BlGetCdRomDrive(
|
||
PUCHAR DriveId
|
||
)
|
||
{
|
||
BOOLEAN Result = FALSE;
|
||
UCHAR Id = 0;
|
||
|
||
do {
|
||
if (BlIsElToritoCDBoot(Id)) {
|
||
*DriveId = Id;
|
||
Result = TRUE;
|
||
|
||
break;
|
||
}
|
||
|
||
Id++;
|
||
}
|
||
while (Id != 0);
|
||
|
||
return Result;
|
||
}
|
||
|
||
#endif
|
||
|
||
VOID
|
||
NtProcessStartup(
|
||
IN PBOOT_CONTEXT BootContextRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Main entry point for setup loader. Control is transferred here by the
|
||
start-up (SU) module.
|
||
|
||
Arguments:
|
||
|
||
BootContextRecord - Supplies the boot context, particularly the
|
||
ExternalServicesTable.
|
||
|
||
Returns:
|
||
|
||
Does not return. Control eventually passed to the kernel.
|
||
|
||
|
||
--*/
|
||
{
|
||
ARC_STATUS Status;
|
||
|
||
#ifdef FORCE_CD_BOOT
|
||
BOOLEAN CdFound;
|
||
UCHAR CdId;
|
||
#endif
|
||
|
||
ULONG_PTR pFirmwareHeapAddress;
|
||
ULONG TssSize,TssPages;
|
||
|
||
//
|
||
// Initialize the boot loader's video
|
||
//
|
||
|
||
DoGlobalInitialization(BootContextRecord);
|
||
|
||
BlFillInSystemParameters(BootContextRecord);
|
||
|
||
//
|
||
// Set the global bootflags
|
||
//
|
||
BootFlags = BootContextRecord->BootFlags;
|
||
|
||
#ifdef FORCE_CD_BOOT
|
||
CdFound = BlGetCdRomDrive(&CdId);
|
||
|
||
if (CdFound) {
|
||
BlPrint("CD/DVD-Rom drive found with id:%u\n", CdId);
|
||
BootContextRecord->FSContextPointer->BootDrive = CdId;
|
||
} else {
|
||
BlPrint("CD/DVD-Rom drive not found");
|
||
}
|
||
#endif // for FORCE_CD_BOOT
|
||
|
||
if (BootContextRecord->FSContextPointer->BootDrive == 0) {
|
||
|
||
//
|
||
// Boot was from A:
|
||
//
|
||
|
||
strcpy(BootPartitionName,"multi(0)disk(0)fdisk(0)");
|
||
|
||
//
|
||
// To get around an apparent bug on the BIOS of some MCA machines
|
||
// (specifically the NCR 386sx/MC20 w/ BIOS version 1.04.00 (3421),
|
||
// Phoenix BIOS 1.02.07), whereby the first int13 to floppy results
|
||
// in a garbage buffer, reset drive 0 here.
|
||
//
|
||
|
||
GET_SECTOR(0,0,0,0,0,0,NULL);
|
||
|
||
} else if (BootContextRecord->FSContextPointer->BootDrive == 0x40) {
|
||
|
||
//
|
||
// Boot was from the net
|
||
//
|
||
|
||
strcpy(BootPartitionName,"net(0)");
|
||
BlBootingFromNet = TRUE;
|
||
|
||
#if defined(REMOTE_BOOT)
|
||
BlGetActivePartition(NetBootActivePartitionName);
|
||
NetFindCSCPartitionName();
|
||
#endif
|
||
|
||
} else if (BootContextRecord->FSContextPointer->BootDrive == 0x41) {
|
||
|
||
//
|
||
// Boot was from an SDI image
|
||
//
|
||
|
||
strcpy(BootPartitionName,"ramdisk(0)");
|
||
|
||
} else if (BlIsElToritoCDBoot(BootContextRecord->FSContextPointer->BootDrive)) {
|
||
|
||
//
|
||
// Boot was from El Torito CD
|
||
//
|
||
|
||
sprintf(BootPartitionName, "multi(0)disk(0)cdrom(%u)", BootContextRecord->FSContextPointer->BootDrive);
|
||
ElToritoCDBoot = TRUE;
|
||
|
||
} else {
|
||
|
||
//
|
||
// Find the partition we have been booted from. Note that this
|
||
// is *NOT* necessarily the active partition. If the system has
|
||
// Boot Mangler installed, it will be the active partition, and
|
||
// we have to go figure out what partition we are actually on.
|
||
//
|
||
BlGetActivePartition(BootPartitionName);
|
||
|
||
#if defined(REMOTE_BOOT)
|
||
strcpy(NetBootActivePartitionName, BootPartitionName);
|
||
NetFindCSCPartitionName();
|
||
#endif
|
||
|
||
}
|
||
|
||
|
||
//
|
||
// We need to make sure that we've got a signature on disk 80.
|
||
// If not, then write one.
|
||
//
|
||
{
|
||
ULONG DriveId;
|
||
ULONG NewSignature;
|
||
UCHAR SectorBuffer[4096+256];
|
||
PUCHAR Sector;
|
||
LARGE_INTEGER SeekValue;
|
||
ULONG Count;
|
||
|
||
|
||
Status = ArcOpen("multi(0)disk(0)rdisk(0)partition(0)", ArcOpenReadWrite, &DriveId);
|
||
|
||
if (Status == ESUCCESS) {
|
||
|
||
//
|
||
// Get a reasonably unique seed to start with.
|
||
//
|
||
NewSignature = ArcGetRelativeTime();
|
||
NewSignature = (NewSignature & 0xFFFF) << 16;
|
||
NewSignature += ArcGetRelativeTime();
|
||
|
||
//
|
||
// Now we have a valid new signature to put on the disk.
|
||
// Read the sector off disk, put the new signature in,
|
||
// write the sector back, and recompute the checksum.
|
||
//
|
||
Sector = ALIGN_BUFFER(SectorBuffer);
|
||
SeekValue.QuadPart = 0;
|
||
Status = ArcSeek(DriveId, &SeekValue, SeekAbsolute);
|
||
if (Status == ESUCCESS) {
|
||
Status = ArcRead(DriveId,Sector,512,&Count);
|
||
|
||
if( Status == ESUCCESS ) {
|
||
if( ((PULONG)Sector)[PARTITION_TABLE_OFFSET/2-1] == 0 ) {
|
||
//
|
||
// He's 0. Write a real signature in there.
|
||
//
|
||
|
||
((PULONG)Sector)[PARTITION_TABLE_OFFSET/2-1] = NewSignature;
|
||
|
||
Status = ArcSeek(DriveId, &SeekValue, SeekAbsolute);
|
||
if (Status == ESUCCESS) {
|
||
Status = ArcWrite(DriveId,Sector,512,&Count);
|
||
if( Status != ESUCCESS ) {
|
||
#if DBG
|
||
BlPrint( "Falied to write the new signature on the boot partition.\n" );
|
||
#endif
|
||
}
|
||
} else {
|
||
#if DBG
|
||
BlPrint( "Failed second ArcSeek on the boot partition to check for a signature.\n" );
|
||
#endif
|
||
}
|
||
}
|
||
} else {
|
||
#if DBG
|
||
BlPrint( "Failed to ArcRead the boot partition to check for a signature.\n" );
|
||
#endif
|
||
}
|
||
} else {
|
||
#if DBG
|
||
BlPrint( "Failed to ArcSeek the boot partition to check for a signature.\n" );
|
||
#endif
|
||
}
|
||
|
||
ArcClose(DriveId);
|
||
} else {
|
||
#if DBG
|
||
BlPrint( "Couldn't Open the boot partition to check for a signature.\n" );
|
||
#endif
|
||
}
|
||
}
|
||
|
||
//
|
||
// squirrel away some memory for the PCR and TSS so that we get the
|
||
// preferred memory location (<16MB) for this data.
|
||
//
|
||
pFirmwareHeapAddress = (ULONG_PTR)FwAllocateHeapPermanent( 2 );
|
||
if (!pFirmwareHeapAddress) {
|
||
BlPrint("Couldn't allocate memory for PCR\n");
|
||
goto BootFailed;
|
||
}
|
||
PcrBasePage = (ULONG)(pFirmwareHeapAddress>>PAGE_SHIFT);
|
||
|
||
TssSize = (sizeof(KTSS) + PAGE_SIZE) & ~(PAGE_SIZE - 1);
|
||
TssPages = TssSize / PAGE_SIZE;
|
||
pFirmwareHeapAddress = (ULONG_PTR)FwAllocateHeapPermanent( TssPages );
|
||
if (!pFirmwareHeapAddress) {
|
||
BlPrint("Couldn't allocate memory for TSS\n");
|
||
goto BootFailed;
|
||
}
|
||
TssBasePage = (ULONG)(pFirmwareHeapAddress>>PAGE_SHIFT);
|
||
|
||
//
|
||
// Initialize the memory descriptor list, the OS loader heap, and the
|
||
// OS loader parameter block.
|
||
//
|
||
Status = BlMemoryInitialize();
|
||
if (Status != ESUCCESS) {
|
||
BlPrint("Couldn't initialize memory\n");
|
||
goto BootFailed;
|
||
}
|
||
|
||
//
|
||
// Initialize the OS loader I/O system.
|
||
//
|
||
|
||
AEInitializeStall();
|
||
|
||
Status = BlIoInitialize();
|
||
if (Status != ESUCCESS) {
|
||
BlPrint("Couldn't initialize I/O\n");
|
||
goto BootFailed;
|
||
}
|
||
|
||
//
|
||
// Call off to regular startup code
|
||
//
|
||
BlStartup(BootPartitionName);
|
||
|
||
//
|
||
// we should never get here!
|
||
//
|
||
BootFailed:
|
||
if (BootFlags & BOOTFLAG_REBOOT_ON_FAILURE) {
|
||
ULONG StartTime = ArcGetRelativeTime();
|
||
BlPrint(TEXT("\nRebooting in 5 seconds...\n"));
|
||
while ( ArcGetRelativeTime() - StartTime < 5) {}
|
||
ArcRestart();
|
||
}
|
||
|
||
do {
|
||
GET_KEY(); // BOOT FAILED!
|
||
if (BlTerminalHandleLoaderFailure()) {
|
||
ArcRestart();
|
||
}
|
||
} while ( 1 );
|
||
|
||
}
|
||
|
||
BOOLEAN
|
||
BlDetectHardware(
|
||
IN ULONG DriveId,
|
||
IN PCHAR LoadOptions
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Loads and runs NTDETECT.COM to populate the ARC configuration tree.
|
||
|
||
Arguments:
|
||
|
||
DriveId - Supplies drive id where NTDETECT is located.
|
||
|
||
LoadOptions - Supplies Load Options string to ntdetect.
|
||
|
||
Return Value:
|
||
|
||
TRUE - NTDETECT successfully run.
|
||
|
||
FALSE - Error
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
// Current Loader stack size is 8K, so make sure you do not
|
||
// blow that space. Make sure this is not smaller than 140.
|
||
#define LOAD_OPTIONS_BUFFER_SIZE 512
|
||
|
||
ARC_STATUS Status;
|
||
PCONFIGURATION_COMPONENT_DATA TempFwTree;
|
||
ULONG TempFwHeapUsed;
|
||
ULONG FileSize;
|
||
ULONG DetectFileId;
|
||
FILE_INFORMATION FileInformation;
|
||
PUCHAR DetectionBuffer = (PUCHAR)DETECTION_LOADED_ADDRESS;
|
||
PUCHAR Options = NULL;
|
||
UCHAR Buffer[LOAD_OPTIONS_BUFFER_SIZE];
|
||
LARGE_INTEGER SeekPosition;
|
||
ULONG Read;
|
||
BOOLEAN SkipLegacyDetection;
|
||
BOOLEAN Success = FALSE;
|
||
ULONG HeapStart;
|
||
ULONG HeapSize;
|
||
ULONG RequiredLength = 0;
|
||
|
||
//
|
||
// Check if the ntdetect.com was bundled as a data section
|
||
// in the loader executable.
|
||
//
|
||
if (NtDetectStart == 0) {
|
||
|
||
//
|
||
// Now check if we have ntdetect.com in the root directory, if yes,
|
||
// we will load it to predefined location and transfer control to
|
||
// it.
|
||
//
|
||
|
||
#if defined(ELTORITO)
|
||
if (ElToritoCDBoot) {
|
||
// we assume ntdetect.com is in the i386 directory
|
||
Status = BlOpen( DriveId,
|
||
"\\i386\\ntdetect.com",
|
||
ArcOpenReadOnly,
|
||
&DetectFileId );
|
||
} else {
|
||
#endif
|
||
|
||
if (BlBootingFromNet
|
||
#if defined(REMOTE_BOOT)
|
||
&& NetworkBootRom
|
||
#endif // defined(REMOTE_BOOT)
|
||
) {
|
||
|
||
strcpy(Buffer, NetBootPath);
|
||
|
||
#if defined(REMOTE_BOOT)
|
||
//
|
||
// This is the way it was done for remote BOOT, where we were
|
||
// booting out of a client's machine directory.
|
||
//
|
||
strcat(Buffer, "BootDrive\\ntdetect.com");
|
||
#else
|
||
//
|
||
// This is how it is done for remote INSTALL, where we are
|
||
// booting out of the templates directory under a setup directory.
|
||
//
|
||
strcat(Buffer, "ntdetect.com");
|
||
#endif // defined(REMOTE_BOOT)
|
||
|
||
Status = BlOpen( DriveId,
|
||
Buffer,
|
||
ArcOpenReadOnly,
|
||
&DetectFileId );
|
||
} else {
|
||
Status = BlOpen( DriveId,
|
||
"\\ntdetect.com",
|
||
ArcOpenReadOnly,
|
||
&DetectFileId );
|
||
}
|
||
#if defined(ELTORITO)
|
||
}
|
||
#endif
|
||
|
||
if (Status != ESUCCESS) {
|
||
#if DBG
|
||
BlPrint("Error opening NTDETECT.COM, status = %x\n", Status);
|
||
BlPrint("Press any key to continue\n");
|
||
#endif
|
||
goto Exit;
|
||
}
|
||
|
||
//
|
||
// Determine the length of the ntdetect.com file
|
||
//
|
||
|
||
Status = BlGetFileInformation(DetectFileId, &FileInformation);
|
||
if (Status != ESUCCESS) {
|
||
BlClose(DetectFileId);
|
||
#if DBG
|
||
BlPrint("Error getting NTDETECT.COM file information, status = %x\n", Status);
|
||
BlPrint("Press any key to continue\n");
|
||
#endif
|
||
goto Exit;
|
||
}
|
||
|
||
FileSize = FileInformation.EndingAddress.LowPart;
|
||
if (FileSize == 0) {
|
||
BlClose(DetectFileId);
|
||
#if DBG
|
||
BlPrint("Error: size of NTDETECT.COM is zero.\n");
|
||
BlPrint("Press any key to continue\n");
|
||
#endif
|
||
goto Exit;
|
||
}
|
||
|
||
SeekPosition.QuadPart = 0;
|
||
Status = BlSeek(DetectFileId,
|
||
&SeekPosition,
|
||
SeekAbsolute);
|
||
if (Status != ESUCCESS) {
|
||
BlClose(DetectFileId);
|
||
#if DBG
|
||
BlPrint("Error seeking to start of NTDETECT.COM file\n");
|
||
BlPrint("Press any key to continue\n");
|
||
#endif
|
||
goto Exit;
|
||
}
|
||
|
||
Status = BlRead( DetectFileId,
|
||
DetectionBuffer,
|
||
FileSize,
|
||
&Read );
|
||
|
||
BlClose(DetectFileId);
|
||
if (Status != ESUCCESS) {
|
||
#if DBG
|
||
BlPrint("Error reading from NTDETECT.COM\n");
|
||
BlPrint("Read %lx bytes\n",Read);
|
||
BlPrint("Press any key to continue\n");
|
||
#endif
|
||
goto Exit;
|
||
}
|
||
} else {
|
||
|
||
// ntdetect.com was bundled in the loader image
|
||
// as a data section. We will use it contents
|
||
// instead of opening the file.
|
||
RtlCopyMemory( DetectionBuffer, (PVOID)NtDetectStart, NtDetectEnd - NtDetectStart );
|
||
}
|
||
|
||
//
|
||
// Set the heap start and size used by ntdetect
|
||
//
|
||
HeapStart = (TEMPORARY_HEAP_START - 0x10) * PAGE_SIZE;
|
||
HeapSize = 0x10000; // 64K
|
||
|
||
//
|
||
// We need to pass NTDETECT pointers < 1Mb, so
|
||
// use local storage off the stack if possible. (which is
|
||
// always < 1Mb.) If not possible (boot.ini is too big)
|
||
// and we will add it to the heap used by ntdetect.com, thereby
|
||
// reducing the heap space used by ntdetect.com
|
||
//
|
||
if ( LoadOptions ) {
|
||
// count the characters in LoadOptions + null terminator +
|
||
// room for " NOLEGACY" that might be appended later
|
||
RequiredLength = strlen(LoadOptions) + strlen(" NOLEGACY") + 1;
|
||
|
||
// check if the buffer on the stack is big enough
|
||
if ( RequiredLength > LOAD_OPTIONS_BUFFER_SIZE ) {
|
||
//
|
||
// Buffer is too small. let move it to the
|
||
// end of the ntdetect heap
|
||
//
|
||
Options = (PCHAR)( HeapStart + HeapSize - RequiredLength );
|
||
HeapSize -= RequiredLength;
|
||
|
||
strcpy( Options, LoadOptions );
|
||
|
||
} else {
|
||
//
|
||
// Load options will fit on the stack. copy them there
|
||
//
|
||
strcpy( Buffer, LoadOptions );
|
||
Options = Buffer;
|
||
|
||
}
|
||
} else {
|
||
//
|
||
// No load options
|
||
//
|
||
Options = NULL;
|
||
}
|
||
|
||
//
|
||
// Check whether we need to add the NOLEGACY option
|
||
//
|
||
if (BlDetectLegacyFreeBios()) {
|
||
if (Options != NULL) {
|
||
strcat(Options, " NOLEGACY");
|
||
} else {
|
||
strcpy(Buffer, " NOLEGACY");
|
||
Options = Buffer;
|
||
}
|
||
}
|
||
|
||
DETECT_HARDWARE((ULONG)HeapStart,
|
||
(ULONG)HeapSize,
|
||
(PVOID)&TempFwTree,
|
||
(PULONG)&TempFwHeapUsed,
|
||
(PCHAR)Options,
|
||
(Options != NULL) ? strlen(Options) : 0
|
||
);
|
||
|
||
FwConfigurationTree = TempFwTree;
|
||
|
||
Status = BlpMarkExtendedVideoRegionOffLimits();
|
||
|
||
Success = (BOOLEAN)(Status == ESUCCESS);
|
||
|
||
Exit:
|
||
|
||
//
|
||
// Reinitialize the headless port - detect wipes it out.
|
||
//
|
||
BlInitializeHeadlessPort();
|
||
|
||
return(Success);
|
||
}
|
||
|
||
|
||
VOID
|
||
DoGlobalInitialization(
|
||
IN PBOOT_CONTEXT BootContextRecord
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description
|
||
|
||
This routine calls all of the subsytem initialization routines.
|
||
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Returns:
|
||
|
||
Nothing
|
||
|
||
--*/
|
||
|
||
{
|
||
ARC_STATUS Status;
|
||
|
||
//
|
||
// Set base address of OS Loader image for the debugger.
|
||
//
|
||
|
||
OsLoaderBase = BootContextRecord->OsLoaderBase;
|
||
OsLoaderExports = BootContextRecord->OsLoaderExports;
|
||
|
||
//
|
||
// Initialize memory.
|
||
//
|
||
|
||
Status = InitializeMemorySubsystem(BootContextRecord);
|
||
if (Status != ESUCCESS) {
|
||
BlPrint("InitializeMemory failed %lx\n",Status);
|
||
while (1) {
|
||
}
|
||
}
|
||
ExternalServicesTable=BootContextRecord->ExternalServicesTable;
|
||
MachineType = BootContextRecord->MachineType;
|
||
|
||
//
|
||
// Turn the cursor off
|
||
//
|
||
|
||
HW_CURSOR(0,127);
|
||
|
||
BlpResourceDirectory = (PUCHAR)(BootContextRecord->ResourceDirectory);
|
||
BlpResourceFileOffset = (PUCHAR)(BootContextRecord->ResourceOffset);
|
||
|
||
NtDetectStart = BootContextRecord->NtDetectStart;
|
||
NtDetectEnd = BootContextRecord->NtDetectEnd;
|
||
|
||
//
|
||
// If this is an SDI boot, copy the address of the SDI image out of the
|
||
// boot context record. SdiAddress is declared in boot\inc\ramdisk.h and
|
||
// initialized to 0 in boot\lib\ramdisk.c.
|
||
//
|
||
|
||
if (BootContextRecord->FSContextPointer->BootDrive == 0x41) {
|
||
SdiAddress = BootContextRecord->SdiAddress;
|
||
}
|
||
|
||
InitializeMemoryDescriptors ();
|
||
}
|
||
|
||
|
||
VOID
|
||
BlGetActivePartition(
|
||
OUT PUCHAR BootPartitionName
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Determine the ARC name for the partition NTLDR was started from
|
||
|
||
Arguments:
|
||
|
||
BootPartitionName - Supplies a buffer where the ARC name of the
|
||
partition will be returned.
|
||
|
||
Return Value:
|
||
|
||
Name of the partition is in BootPartitionName.
|
||
|
||
Must always succeed.
|
||
--*/
|
||
|
||
{
|
||
UCHAR SectorBuffer[512];
|
||
ARC_STATUS Status;
|
||
ULONG FileId;
|
||
ULONG Count;
|
||
int i;
|
||
|
||
//
|
||
// The boot sector used to boot us is still in memory at 0x7c00.
|
||
// The hidden sectors field in the BPB is pretty much guaranteed
|
||
// to be intact, since all boot codes use that field and thus
|
||
// are unlikely to have overwritten it.
|
||
// We open each partition and compare the in-memory hidden sector count
|
||
// at 0x7c1c to the hidden sector value in the BPB.
|
||
//
|
||
i = 1;
|
||
do {
|
||
|
||
sprintf(BootPartitionName,"multi(0)disk(0)rdisk(0)partition(%u)",i);
|
||
|
||
Status = ArcOpen(BootPartitionName,ArcOpenReadOnly,&FileId);
|
||
if(Status == ESUCCESS) {
|
||
|
||
//
|
||
// Read the first part of the partition.
|
||
//
|
||
Status = ArcRead(FileId,SectorBuffer,512,&Count);
|
||
ArcClose(FileId);
|
||
if((Status == ESUCCESS) && !memcmp(SectorBuffer+0x1c,(PVOID)0x7c1c,4)) {
|
||
//
|
||
// Found it, BootPartitionName is already set for return.
|
||
//
|
||
return;
|
||
}
|
||
|
||
Status = ESUCCESS;
|
||
}
|
||
|
||
i++;
|
||
|
||
} while (Status == ESUCCESS);
|
||
|
||
//
|
||
// Run out of partitions without finding match. Fall back on partition 1.
|
||
//
|
||
strcpy(BootPartitionName,"multi(0)disk(0)rdisk(0)partition(1)");
|
||
}
|
||
|
||
|
||
BOOLEAN
|
||
BlIsElToritoCDBoot(
|
||
UCHAR DriveNum
|
||
)
|
||
{
|
||
|
||
//
|
||
// Note, even though args are short, they are pushed on the stack with
|
||
// 32bit alignment so the effect on the stack seen by the 16bit real
|
||
// mode code is the same as if we were pushing longs here.
|
||
//
|
||
// GET_ELTORITO_STATUS is 0 if we are in emulation mode
|
||
|
||
if (DriveNum > 0x81) {
|
||
if (!GET_ELTORITO_STATUS(FwDiskCache,DriveNum)) {
|
||
return(TRUE);
|
||
} else {
|
||
return(FALSE);
|
||
}
|
||
} else {
|
||
return(FALSE);
|
||
}
|
||
}
|
||
|
||
#if defined(REMOTE_BOOT)
|
||
BOOLEAN
|
||
NetFindCSCPartitionName(
|
||
)
|
||
{
|
||
UCHAR FileName[80];
|
||
UCHAR DiskName[80];
|
||
UCHAR PartitionName[80];
|
||
PUCHAR p;
|
||
ULONG Part;
|
||
ULONG FileId;
|
||
ULONG DeviceId;
|
||
|
||
if (NetBootSearchedForCSC) {
|
||
return((BOOLEAN)strlen(NetBootCSCPartitionName));
|
||
}
|
||
|
||
if (!strlen(NetBootActivePartitionName)) {
|
||
BlGetActivePartition(NetBootActivePartitionName);
|
||
}
|
||
|
||
strcpy(DiskName, NetBootActivePartitionName);
|
||
p = strstr(DiskName, "partition");
|
||
ASSERT( p != NULL );
|
||
*p = '\0';
|
||
|
||
Part = 1;
|
||
while (TRUE) {
|
||
|
||
sprintf(PartitionName, "%spartition(%u)", DiskName, Part);
|
||
if (ArcOpen(PartitionName, ArcOpenReadOnly, &DeviceId) != ESUCCESS) {
|
||
break;
|
||
}
|
||
ArcClose(DeviceId);
|
||
|
||
sprintf(FileName,
|
||
"%s%s",
|
||
PartitionName,
|
||
REMOTE_BOOT_IMIRROR_PATH_A REMOTE_BOOT_CSC_SUBDIR_A);
|
||
|
||
if (ArcOpen(FileName, ArcOpenReadOnly, &FileId) == ESUCCESS) {
|
||
ArcClose(FileId);
|
||
NetBootSearchedForCSC = TRUE;
|
||
strcpy(NetBootCSCPartitionName, PartitionName);
|
||
return TRUE;
|
||
}
|
||
ArcClose(FileId);
|
||
Part++;
|
||
}
|
||
|
||
strcpy(NetBootCSCPartitionName, NetBootActivePartitionName);
|
||
return FALSE;
|
||
}
|
||
#endif // defined(REMOTE_BOOT)
|
||
|