Windows NT引导过程源代码分析(5)

2019-08-30 13:20

// 获取ntdetect.com文件信息

Status = BlGetFileInformation(DetectFileId, &FileInformation); if (Status != ESUCCESS) { BlClose(DetectFileId); #ifDBG

BlPrint(\, Status);//获取文件信息失败 BlPrint(\); while (!GET_KEY()) { } #endif return(FALSE); }

FileSize = FileInformation.EndingAddress.LowPart; if (FileSize == 0) { BlClose(DetectFileId); #ifDBG

BlPrint(\);//获取文件末尾失败 BlPrint(\); while (!GET_KEY()) { } #endif return(FALSE); }

SeekPosition.QuadPart = 0;

Status = BlSeek(DetectFileId,&SeekPosition,SeekAbsolute); if (Status != ESUCCESS) { BlClose(DetectFileId); #ifDBG

BlPrint(\);//获取文件开头失败 BlPrint(\); while (!GET_KEY()) { } #endif return(FALSE); }

Status = BlRead(DetectFileId,DetectionBuffer,FileSize,&Read ); BlClose(DetectFileId); if (Status != ESUCCESS) { #ifDBG

BlPrint(\);//读取文件失败 BlPrint(\,Read); BlPrint(\); while (!GET_KEY()) { } #endif return(FALSE); }

// 必须传递小于1MB的NTDETECT指针,因此使用堆栈中的本地存储 if (LoadOptions) {

strcpy(Buffer, LoadOptions); Options = Buffer; } else { Options = NULL; }

DETECT_HARDWARE((ULONG)(TEMPORARY_HEAP_START - 0x10) * PAGE_SIZE, (ULONG)0x10000, // 堆大小 (PVOID)&TempFwTree, (PULONG)&TempFwHeapUsed, (PCHAR)Options,

(ULONG)(LoadOptions ? strlen(LoadOptions) : 0) );

FwConfigurationTree = TempFwTree; FwHeapUsed = TempFwHeapUsed; FwDescriptorsValid = FALSE;

return(TRUE); }

VOID

DoGlobalInitialization(

INPBOOT_CONTEXTBootContextRecord ) /*++

Routine Description

This routine calls all of the subsytem initialization routines. Arguments: None Returns: Nothing --*/ {

ARC_STATUSStatus;

Status = InitializeMemorySubsystem(BootContextRecord);//初始化内存子系统 if (Status != ESUCCESS) {

BlPrint(\,Status); while (1) { } }

ExternalServicesTable=BootContextRecord->ExternalServicesTable; MachineType = BootContextRecord->MachineType;

// 此处开启光标支持 HW_CURSOR(0,127);

BlpResourceDirectory = (PUCHAR)(BootContextRecord->ResourceDirectory); BlpResourceFileOffset = (PUCHAR)(BootContextRecord->ResourceOffset);

OsLoaderBase = BootContextRecord->OsLoaderBase; OsLoaderExports = BootContextRecord->OsLoaderExports;

InitializeMemoryDescriptors ();//初始化内存描述符 }

VOID

BlGetActivePartition(

OUTPUCHARBootPartitionName ) /*++

Routine Description:

Determine the ARC name for the partition NTLDR was started from Arguments:

BootPartitionName - Supplies a buffer where the ARC name of thepartition will be returned. Return Value:

Name of the partition is in BootPartitionName. Must always succeed. --*/ {

UCHARSectorBuffer[512]; UCHARNameBuffer[80]; ARC_STATUSStatus; ULONGFileId; ULONGCount; inti;

// 尝试打开所有的分区并将其读为引导扇区,并与之前使用的引导扇区进行对比. // 如果相同,则找到,否则尝试分区1 i=1; do {

sprintf(NameBuffer, \,i); Status = ArcOpen(NameBuffer,ArcOpenReadOnly,&FileId); if (Status != ESUCCESS) {

// 遍历所有分区未找到合适的对象,故设置默认值. i=1; break;

} else {

// 读取前512个字节

Status = ArcRead(FileId, SectorBuffer, 512, &Count); ArcClose(FileId);

if (Status==ESUCCESS) {

// 只需要比较前36个字节 // 跳转标识 3 bytes //Oem位段 8字节 // 参数块 25字节

if (memcmp(SectorBuffer, (PVOID)0x7c00, 36)==0) { // 找到匹配对象. break;

} } } ++i; } while ( TRUE );

sprintf(BootPartitionName, \,i); return; }

#ifdefined(ELTORITO)

接下来,os loader 从系统分区(即引导分区)的根目录下读入boot.ini 文件。注意,os loader 包含了读取当前文件系统的代码,它能够读取NTFS 文件系统的子目录。然后,os loader 清除屏幕,并检查在系统分区的根目录下是否有一个有效的hiberfil.sys 文件,如果存在的话,这一次引导过程转移到休眠系统的恢复过程。因此,os loader 将控制权交给一段能恢复休眠系统的内核代码。

如果当前这次引导不是休眠恢复,那么,os loader 解析boot.ini 文件,如果该文件中有多个引导选项,则os loader 显示一个引导选择菜单;如果boot.ini 文件中只包含一个引导选项,那么,此菜单不显示,而是立即应用该引导选项。

代码摘自\\ntos\\boot\\bldr\\i386\\initx86.c

//负责打开驱动和读boot.ini文件 VOID BlStartup(

INPCHARPartitionName ) /*++

Routine Description:

Does x86-specific initialization, particularly presenting the boot.ini menu and running NTDETECT, then calls to the common osloader. Arguments:

PartitionName - Supplies the ARC name of the partition (or floppy) that setupldr was loaded from. Return Value: Does not return --*/ {

PUCHARArgv[10]; ARC_STATUSStatus; ULONGBootFileId; PCHARBootFile; ULONGRead; PCHARp; ULONGi; ULONGDriveId; ULONGFileSize; ULONGCount;

LARGE_INTEGERSeekPosition; PCHARLoadOptions = NULL; BOOLEANUseTimeOut=TRUE; BOOLEANAlreadyInitialized = FALSE; externBOOLEANFwDescriptorsValid;

// 打开引导分区以便加载引导驱动.

Status = ArcOpen(PartitionName, ArcOpenReadOnly, &DriveId); if (Status != ESUCCESS) {

BlPrint(\,PartitionName); BlPrint(BlFindMessage(BL_DRIVE_ERROR),PartitionName); gotoBootFailed; }

// 初始化双字节内码系统以及显示支持. TextGrInitialize(DriveId); do {

Status = BlOpen( DriveId, \, ArcOpenReadOnly,

&BootFileId );//此处开始打开boot.ini

BootFile = MyBuffer;

RtlZeroMemory(MyBuffer, SECTOR_SIZE+32);

if (Status != ESUCCESS) { BootFile[0]='\\0'; } else {

// 通过从头到尾读取boot.ini文件获取大小

FileSize = 0; do {

Status = BlRead(BootFileId, BootFile, SECTOR_SIZE, &Count); if (Status != ESUCCESS) { BlClose(BootFileId);

BlPrint(BlFindMessage(BL_READ_ERROR),Status); BootFile[0] = '\\0'; //结束符 FileSize = 0; Count = 0; gotoBootFailed; } FileSize += Count;

} while (Count != 0);

if (FileSize>= SECTOR_SIZE) {

// 如果boot.ini文件大于一个扇区的大小,那么就需要重新分配更大的缓冲区 BootFile=FwAllocateHeap(FileSize); }

if (BootFile == NULL) {

BlPrint(BlFindMessage(BL_READ_ERROR),ENOMEM); BootFile = MyBuffer; BootFile[0] = '\\0'; gotoBootFailed; } else {

SeekPosition.QuadPart = 0; Status = BlSeek(BootFileId, &SeekPosition, SeekAbsolute);

if (Status != ESUCCESS) {

BlPrint(BlFindMessage(BL_READ_ERROR),Status); BootFile = MyBuffer; BootFile[0] = '\\0'; gotoBootFailed; } else { Status = BlRead( BootFileId, BootFile, FileSize, &Read );

SeekPosition.QuadPart = 0; Status = BlSeek(BootFileId, &SeekPosition, SeekAbsolute);

if (Status != ESUCCESS) {

BlPrint(BlFindMessage(BL_READ_ERROR),Status); BootFile = MyBuffer; BootFile[0] = '\\0'; gotoBootFailed;

} else { BootFile[Read]='\\0'; } } }


Windows NT引导过程源代码分析(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:重庆一中高2009级(下)09年文科数学2月月考试题 doc

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: