Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

482 lines
11 KiB

/*++
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"
//
// Prototypes for Internal Routines
//
VOID
DoGlobalInitialization(
PBOOT_CONTEXT
);
#if defined(ELTORITO)
BOOLEAN ElToritoCDBoot = FALSE;
#endif
//
// 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 FwHeapUsed = 0;
ULONG MachineType = 0;
ULONG OsLoaderBase;
ULONG OsLoaderExports;
extern PUCHAR BlpResourceDirectory;
extern PUCHAR BlpResourceFileOffset;
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;
//
// Initialize the boot loader's video
//
DoGlobalInitialization(BootContextRecord);
BlFillInSystemParameters(BootContextRecord);
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);
#if defined(ELTORITO)
} 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;
#endif
} 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);
}
//
// 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");
while (1) {
}
}
//
// Initialize the OS loader I/O system.
//
Status = BlIoInitialize();
if (Status != ESUCCESS) {
BlPrint("Couldn't initialize I/O\n");
}
//
// Call off to regular startup code
//
BlStartup(BootPartitionName);
//
// we should never get here!
//
do {
GET_KEY();
} while ( 1 );
}
BOOLEAN
BlDetectHardware(
IN ULONG DriveId,
IN PCHAR LoadOptions
)
/*++
Routine Description:
Loads and runs NTDETECT.COM to populate the ARC configuration tree.
NTDETECT is assumed to reside in the root directory.
Arguments:
DriveId - Supplies drive id where NTDETECT is located.
LoadOptions - Supplies Load Options string to ntdetect.
Return Value:
TRUE - NTDETECT successfully run.
FALSE - Error
--*/
{
ARC_STATUS Status;
PCONFIGURATION_COMPONENT_DATA TempFwTree;
ULONG TempFwHeapUsed;
extern BOOLEAN FwDescriptorsValid;
ULONG FileSize;
ULONG DetectFileId;
FILE_INFORMATION FileInformation;
PUCHAR DetectionBuffer;
PUCHAR Options;
UCHAR Buffer[100];
LARGE_INTEGER SeekPosition;
ULONG Read;
//
// 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
Status = BlOpen( DriveId,
"\\ntdetect.com",
ArcOpenReadOnly,
&DetectFileId );
#if defined(ELTORITO)
}
#endif
DetectionBuffer = (PUCHAR)DETECTION_LOADED_ADDRESS;
if (Status != ESUCCESS) {
#if DBG
BlPrint("Error opening NTDETECT.COM, status = %x\n", Status);
BlPrint("Press any key to continue\n");
while (!GET_KEY()) {
}
#endif
return(FALSE);
}
//
// 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");
while (!GET_KEY()) {
}
#endif
return(FALSE);
}
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");
while (!GET_KEY()) {
}
#endif
return(FALSE);
}
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");
while (!GET_KEY()) {
}
#endif
return(FALSE);
}
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");
while (!GET_KEY()) {
}
#endif
return(FALSE);
}
//
// We need to pass NTDETECT pointers < 1Mb, so
// use local storage off the stack. (which is
// always < 1Mb.
//
if (LoadOptions) {
strcpy(Buffer, LoadOptions);
Options = Buffer;
} else {
Options = NULL;
}
DETECT_HARDWARE((ULONG)(TEMPORARY_HEAP_START - 0x10) * PAGE_SIZE,
(ULONG)0x10000, // Heap Size
(PVOID)&TempFwTree,
(PULONG)&TempFwHeapUsed,
(PCHAR)Options,
(ULONG)(LoadOptions ? strlen(LoadOptions) : 0)
);
FwConfigurationTree = TempFwTree;
FwHeapUsed = TempFwHeapUsed;
FwDescriptorsValid = FALSE;
return(TRUE);
}
VOID
DoGlobalInitialization(
IN PBOOT_CONTEXT BootContextRecord
)
/*++
Routine Description
This routine calls all of the subsytem initialization routines.
Arguments:
None
Returns:
Nothing
--*/
{
ARC_STATUS Status;
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);
OsLoaderBase = BootContextRecord->OsLoaderBase;
OsLoaderExports = BootContextRecord->OsLoaderExports;
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];
UCHAR NameBuffer[80];
ARC_STATUS Status;
ULONG FileId;
ULONG Count;
int i;
//
// The method we use is to open each partition on the first drive
// and read in its boot sector. Then we compare that to the boot
// sector that we used to boot from (at physical address 0x7c00.
// If they are the same, we've found it. If we run out of partitions,
// just try partition 1
//
i=1;
do {
sprintf(NameBuffer, "multi(0)disk(0)rdisk(0)partition(%u)",i);
Status = ArcOpen(NameBuffer,ArcOpenReadOnly,&FileId);
if (Status != ESUCCESS) {
//
// we've run out of partitions, return the default.
//
i=1;
break;
} else {
//
// Read in the first 512 bytes
//
Status = ArcRead(FileId, SectorBuffer, 512, &Count);
ArcClose(FileId);
if (Status==ESUCCESS) {
//
// only need to compare the first 36 bytes
// Jump instr. == 3 bytes
// Oem field == 8 bytes
// BPB == 25 bytes
//
if (memcmp(SectorBuffer, (PVOID)0x7c00, 36)==0) {
//
// we have found a match.
//
break;
}
}
}
++i;
} while ( TRUE );
sprintf(BootPartitionName, "multi(0)disk(0)rdisk(0)partition(%u)",i);
return;
}
#if defined(ELTORITO)
BOOLEAN
BlIsElToritoCDBoot(
ULONG DriveNum
)
{
if (LocalBuffer == NULL) {
LocalBuffer = FwAllocateHeap(SCRATCH_BUFFER_SIZE);
if (LocalBuffer==NULL) {
return(FALSE);
}
}
// 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(LocalBuffer, DriveNum)) {
return(TRUE);
} else {
return(FALSE);
}
} else {
return(FALSE);
}
}
#endif