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, "//ArcName//%s", LoaderBlock->ArcBootDeviceName);

#032      RtlInitAnsiString(&ArcString, Buffer);

#033      RtlAnsiStringToUnicodeString(&IoArcBootDeviceName, &ArcString, 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, "//ArcName//%s", 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  }

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值