微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

reactos操作系统实现(78)

ARC命名是Windows NT系统用来定位其引导分区所在的路径,也就是利用它指明引导分区在哪一个磁盘控制器,哪一个硬盘,哪一个分区内。ARC命名可分为两大类,以scsi为首或以multi为首,现分别说明如下: scsi(x)disk(y)rdisk(0)partition(z): scsi为首,表明该磁盘控制器为SCSI卡,并且该卡上的BIOS被设置为禁用(disable scsi(x):表示第几个控制卡,x0为起始数字。 disk(y):表示该控制卡下的第几块物理磁盘,y0为起始数字。 partition(z):表示该物理磁盘上第几个分区,z1为起始数字。 注意:以scsi为首的ARC命名的rdisk项总是rdisk(0) multi(x)disk(0)rdisk(y)partition(z): multi为首,表明该磁盘控制器是IDEESDI,或是BIOS允许使用(enable)的SCSI卡。 multi(x):表示第几个控制卡,x0为起始数字。 rdisk(y):表示该控制卡下的第几块物理磁盘,y0为起始数字。 partition(z):表示该物理磁盘上第几个分区,z1为起始数字。 注意:以multi为首的ARC命名的disk项总是disk(0) 还有一点必须注意的是,系统给NT分区编号时,主分区的编号永远排在扩展分区前。例题 windows2000安装在D盘下,D盘为扩展分区的一个逻辑驱动器,系统可以正常启动。后来,又添加一个分区。重启时发现系统无法引导了,是何原因,如何解决 分析:一个磁盘上最多只能有一个扩展分区,则新添加的分区为主分区,而主分区的编号排在扩展分区前,所以D盘的实际ARC路径的partition增加1,而boot.ini文件内容没变,这样再利用原来的ARC路径就找不到D盘的系统目录了。解决方法就是修改boot.ini文件 ARC命名是Windows NT系统用来定位其引导分区所在的路径,也就是利用它指明引导分区在哪一个磁盘控制器,哪一个硬盘,哪一个分区内。   ARC命名可分为两大类,以scsi为首或以multi为首,现分别说明如下:   scsi(x)disk(y)rdisk(0)partition(z):   以scsi为首,表明该磁盘控制器为SCSI卡,并且该卡上的BIOS被设置为禁用(disable   scsi(x):表示第几个控制卡,x0为起始数字。   disk(y):表示该控制卡下的第几块物理磁盘,y0为起始数字。   partition(z):表示该物理磁盘上第几个分区,z1为起始数字。   注意:以scsi为首的ARC命名的rdisk项总是rdisk(0)   multi(x)disk(0)rdisk(y)partition(z):   以multi为首,表明该磁盘控制器是IDEESDI,或是BIOS允许使用(enable)的SCSI卡。   multi(x):表示第几个控制卡,x0为起始数字。   rdisk(y):表示该控制卡下的第几块物理磁盘,y0为起始数字。   partition(z):表示该物理磁盘上第几个分区,z1为起始数字。   注意:以multi为首的ARC命名的disk项总是disk(0)   还有一点必须注意的是,系统给NT分区编号时,主分区的编号永远排在扩展分区前,故当引导分区处于原硬盘的剩余磁盘空间时,必须将此磁盘空间设为主分区(已存在扩展分区),该分区虽然后编号,但其编号反而在原来扩展分区中的逻辑分区编号之前。

下面来分析创建引导的ARC名称代码如下:

#001 NTSTATUS

#002 INIT_FUNCTION

#003 NTAPI

#004 IopCreateArcNames(IN PLOADER_ParaMETER_BLOCK LoaderBlock)

#005 {

获取配置信息。

#006 PCONfigURATION_informatION ConfigInfo = IoGetConfigurationinformation();

获取Freeloader的参数。

#007 PARC_disK_informatION ArcdiskInfo = LoaderBlock->Arcdiskinformation;

#008 CHAR Buffer[128];

#009 ANSI_STRING ArcBootString,ArcSystemString,ArcString;

#010 UNICODE_STRING ArcName,BootPath,DeviceName;

#011 BOOLEAN Singledisk;

#012 ULONG i,j,Length;

#013 PDEVICE_OBJECT DeviceObject;

#014 ULONG Signature,Checksum,PartitionCount;

#015 PLIST_ENTRY NextEntry;

#016 PARC_disK_SIGNATURE ArcdiskEntry;

#017 NTSTATUS Status;

#018 BOOLEAN FoundBoot = FALSE;

#019 PULONG PartitionBuffer;

#020

检查这台电脑是否只有一个磁盘。

#021 /* Check if we only have one disk on the machine */

#022 Singledisk = ArcdiskInfo->diskSignatureListHead.Flink->Flink ==

#023 (&ArcdiskInfo->diskSignatureListHead);

#024

创建硬件抽像层的分区名称

#025 /* Create the global HAL partition name */

#026 sprintf(Buffer,"//ArcName//%s",LoaderBlock->ArcHalDeviceName);

#027 RtlInitAnsiString(&ArcString,Buffer);

#028 RtlAnsiStringToUnicodeString(&IoArcHalDeviceName,&ArcString,TRUE);

#029

创建系统分区的名称

#030 /* Create the global system partition name */

#031 sprintf(Buffer,LoaderBlock->ArcBootDeviceName);

#032 RtlInitAnsiString(&ArcString,Buffer);

#033 RtlAnsiStringToUnicodeString(&IoArcBootDeviceName,TRUE);

#034

为字符串分配内存大小。

#035 /* Allocate memory for the string */

#036 Length = strlen(LoaderBlock->ArcBootDeviceName) + sizeof(ANSI_NULL);

#037 IoLoaderArcBootDeviceName = ExAllocatePoolWithTag(PagedPool,

#038 Length,

#039 TAG_IO);

#040 if (IoLoaderArcBootDeviceName)

#041 {

#042 /* copy the name */

#043 RtlcopyMemory(IoLoaderArcBootDeviceName,

#044 LoaderBlock->ArcBootDeviceName,

#045 Length);

#046 }

#047

检查是否有一个磁盘,但系统是从CD-ROM引导的。

#048 /* Check if we only found a disk,but we're booting from CD-ROM */

#049 if ((Singledisk) && strstr(LoaderBlock->ArcBootDeviceName,"cdrom"))

#050 {

#051 /* Then disable single-disk mode,since there's a CD drive out there */

#052 Singledisk = FALSE;

#053 }

#054

创建引导的字符串。

#055 /* Build the boot strings */

#056 RtlInitAnsiString(&ArcBootString,LoaderBlock->ArcBootDeviceName);

#057 RtlInitAnsiString(&ArcSystemString,LoaderBlock->ArcHalDeviceName);

#058

循环地创建每个磁盘的ARC名称

#059 /* Loop every detected disk */

#060 for (i = 0; i < ConfigInfo->diskCount; i++)

#061 {

#062 /* Get information about the disk */

#063 if (!IopGetdiskinformation(i,

#064 &Checksum,

#065 &Signature,

#066 &PartitionCount,

#067 &DeviceObject))

#068 {

#069 /* Skip this disk */

#070 continue;

#071 }

#072

#073 /* Loop ARC disks */

#074 for (NextEntry = ArcdiskInfo->diskSignatureListHead.Flink;

#075 NextEntry != &ArcdiskInfo->diskSignatureListHead;

#076 NextEntry = NextEntry->Flink)

#077 {

#078 /* Get the current ARC disk signature entry */

#079 ArcdiskEntry = CONTAINING_RECORD(NextEntry,

#080 ARC_disK_SIGNATURE,

#081 ListEntry);

#082

#083 /*

#084 * Now check if the signature and checksum match,unless this is

#085 * the only disk that was in the ARC list,and also in the device

#086 * tree,in which case the check is bypassed and we accept the disk

#087 */

#088 if (((Singledisk) && (ConfigInfo->diskCount == 1)) ||

#089 ((Checksum == ArcdiskEntry->CheckSum) &&

#090 (Signature == ArcdiskEntry->Signature)))

#091 {

创建NT设备名称

#092 /* Build the NT Device Name */

#093 sprintf(Buffer,"//Device//Harddisk%lu//Partition0",i);

#094

转换UNICODE表示。

#095 /* Convert it to Unicode */

#096 RtlInitAnsiString(&ArcString,Buffer);

#097 Status = RtlAnsiStringToUnicodeString(&DeviceName,

#098 &ArcString,

#099 TRUE);

#100 if (!NT_SUCCESS(Status)) continue;

#101

创建ARC设备名称

#102 /* Build the ARC Device Name */

#103 sprintf(Buffer,ArcdiskEntry->ArcName);

#104

#105 /* Convert it to Unicode */

#106 RtlInitAnsiString(&ArcString,Buffer);

#107 Status = RtlAnsiStringToUnicodeString(&ArcName,

#108 &ArcString,

#109 TRUE);

#110 if (!NT_SUCCESS(Status)) continue;

#111

为设备创建符号连接。

#112 /* Create the symbolic link and free the strings */

#113 IoAssignArcName(&ArcName,&DeviceName);

#114 RtlFreeUnicodeString(&ArcName);

#115 RtlFreeUnicodeString(&DeviceName);

#116

创建所有分区ARC名称

#117 /* Loop all the partitions */

#118 for (j = 0; j < PartitionCount; j++)

#119 {

#120 /* Build the partition device name */

#121 sprintf(Buffer,

#122 "//Device//Harddisk%lu//Partition%lu",

#123 i,

#124 j + 1);

#125

#126 /* Convert it to Unicode */

#127 RtlInitAnsiString(&ArcString,Buffer);

#128 Status = RtlAnsiStringToUnicodeString(&DeviceName,

#129 &ArcString,

#130 TRUE);

#131 if (!NT_SUCCESS(Status)) continue;

#132

#133 /* Build the partial ARC name for this partition */

#134 sprintf(Buffer,

#135 "%spartition(%lu)",

#136 ArcdiskEntry->ArcName,

#137 j + 1);

#138 RtlInitAnsiString(&ArcString,Buffer);

#139

#140 /* Check if this is the boot device */

#141 if (RtlEqualString(&ArcString,&ArcBootString,TRUE))

#142 {

#143 /* Remember that we found a Hard disk Boot Device */

#144 FoundBoot = TRUE;

#145 }

#146

#147 /* Check if it's the system boot partition */

#148 if (RtlEqualString(&ArcString,&ArcSystemString,TRUE))

#149 {

#150 /* It is,create a Unicode string for it */

#151 RtlInitAnsiString(&ArcString,

#152 LoaderBlock->NtHalPathName);

#153 Status = RtlAnsiStringToUnicodeString(&BootPath,

#154 &ArcString,

#155 TRUE);

#156 if (NT_SUCCESS(Status))

#157 {

#158 /* FIXME: Save in registry */

#159

#160 /* Free the string Now */

#161 RtlFreeUnicodeString(&BootPath);

#162 }

#163 }

#164

#165 /* Build the full ARC name */

#166 sprintf(Buffer,

#167 "//ArcName//%spartition(%lu)",

#168 ArcdiskEntry->ArcName,

#169 j + 1);

#170

#171 /* Convert it to Unicode */

#172 RtlInitAnsiString(&ArcString,Buffer);

#173 Status = RtlAnsiStringToUnicodeString(&ArcName,

#174 &ArcString,

#175 TRUE);

#176 if (!NT_SUCCESS(Status)) continue;

#177

#178 /* Create the symbolic link and free the strings */

#179 IoAssignArcName(&ArcName,&DeviceName);

#180 RtlFreeUnicodeString(&ArcName);

#181 RtlFreeUnicodeString(&DeviceName);

#182 }

#183 }

#184 }

#185 }

#186

检查是否找到引导磁盘。

#187 /* Check if we didn't find the boot disk */

#188 if (!FoundBoot)

#189 {

如果没有找到引导磁盘,就分配CD-ROMMBR内存。

#190 /* Allocate a buffer for the CD-ROM MBR */

#191 PartitionBuffer = ExAllocatePoolWithTag(NonPagedPool,2048,TAG_IO);

#192 if (!PartitionBuffer) return STATUS_INSUFFICIENT_RESOURCES;

#193

创建CDROMARC设备名称

#194 /* Loop every CD-ROM */

#195 for (i = 0; i < ConfigInfo->CdRomCount; i++)

#196 {

#197 /* Give it an ARC name */

#198 if (IopAssignArcNamesToCdrom(PartitionBuffer,i)) break;

#199 }

#200

#201 /* Free the buffer */

#202 ExFreePoolWithTag(PartitionBuffer,TAG_IO);

#203 }

#204

#205 /* Return success */

#206 return STATUS_SUCCESS;

#207}

原文地址:https://www.jb51.cc/react/308452.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐