BlDetectHardware函数的作用是加载和运行NTDETECT.COM
第一部分:位置:base/boot/lib/i386/entry.c
第二部分:代码分析
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;
PCHAR Options = NULL;
CHAR Buffer[LOAD_OPTIONS_BUFFER_SIZE];
LARGE_INTEGER SeekPosition;
ULONG Read;
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 ); //打开文件ntdetect.com
} 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, therby
// 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
); //运行NTDETECT.COM
FwConfigurationTree = TempFwTree;
Status = BlpMarkExtendedVideoRegionOffLimits();
Success = (BOOLEAN)(Status == ESUCCESS);
Exit:
//
// Reinitialize the headless port - detect wipes it out.
//
BlInitializeHeadlessPort();
return(Success);
}