reactos操作系统实现(78)
ARC命名是Windows NT系统用来定位其引导分区所在的路径,也就是利用它指明引导分区在哪一个磁盘控制器,哪一个硬盘,哪一个分区内。ARC命名可分为两大类,以scsi为首或以multi为首,现分别说明如下: scsi(x)disk(y)rdisk(0)partition(z): 以scsi为首,表明该磁盘控制器为SCSI卡,并且该卡上的BIOS被设置为禁用(disable) scsi(x):表示第几个控制卡,x以0为起始数字。 disk(y):表示该控制卡下的第几块物理磁盘,y以0为起始数字。 partition(z):表示该物理磁盘上第几个分区,z以1为起始数字。 注意:以scsi为首的ARC命名的rdisk项总是rdisk(0)。 multi(x)disk(0)rdisk(y)partition(z): 以multi为首,表明该磁盘控制器是IDE,ESDI,或是BIOS允许使用(enable)的SCSI卡。 multi(x):表示第几个控制卡,x以0为起始数字。 rdisk(y):表示该控制卡下的第几块物理磁盘,y以0为起始数字。 partition(z):表示该物理磁盘上第几个分区,z以1为起始数字。 注意:以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):表示第几个控制卡,x以0为起始数字。 disk(y):表示该控制卡下的第几块物理磁盘,y以0为起始数字。 partition(z):表示该物理磁盘上第几个分区,z以1为起始数字。 注意:以scsi为首的ARC命名的rdisk项总是rdisk(0)。 multi(x)disk(0)rdisk(y)partition(z): 以multi为首,表明该磁盘控制器是IDE,ESDI,或是BIOS允许使用(enable)的SCSI卡。 multi(x):表示第几个控制卡,x以0为起始数字。 rdisk(y):表示该控制卡下的第几块物理磁盘,y以0为起始数字。 partition(z):表示该物理磁盘上第几个分区,z以1为起始数字。 注意:以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-ROM的MBR内存。 #190 /* Allocate a buffer for the CD-ROM MBR */ #191 PartitionBuffer = ExAllocatePoolWithTag(NonPagedPool,2048,TAG_IO); #192 if (!PartitionBuffer) return STATUS_INSUFFICIENT_RESOURCES; #193
创建CDROM的ARC设备名称。 #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} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |