reactos操作系统实现(121)
CreatePartitionDeviceObjects函数是通过分析MBR扇区的数据,然后来创建所有分区对象。具体实现代码如下: #001 NTSTATUS #002 NTAPI #003 CreatePartitionDeviceObjects( #004 IN PDEVICE_OBJECT PhysicalDeviceObject, #005 IN PUNICODE_STRING RegistryPath #006 ) #007 { #008 CCHAR ntNameBuffer[MAXIMUM_FILENAME_LENGTH]; #009 ULONG partitionNumber = 0; #010 NTSTATUS status; #011 PDEVICE_OBJECT deviceObject = NULL; #012 PDISK_GEOMETRY diskGeometry = NULL; #013 PDRIVE_LAYOUT_INFORMATION partitionList = NULL; #014 PDEVICE_EXTENSION deviceExtension; #015 PDEVICE_EXTENSION physicalDeviceExtension; #016 PCLASS_INIT_DATA initData = NULL; #017 PDISK_DATA diskData; #018 PDISK_DATA physicalDiskData; #019 ULONG bytesPerSector; #020 UCHAR sectorShift; #021 ULONG srbFlags; #022 ULONG dmByteSkew = 0; #023 PULONG dmSkew; #024 BOOLEAN dmActive = FALSE; #025 ULONG numberListElements = 0; #026 #027 #028 // #029 // Get physical device geometry information for partition table reads. #030 // #031
通过磁盘描述信息来获取磁盘组成结构,比如每扇区多少个字节。 #032 physicalDeviceExtension = PhysicalDeviceObject->DeviceExtension; #033 diskGeometry = physicalDeviceExtension->DiskGeometry; #034 bytesPerSector = diskGeometry->BytesPerSector; #035 #036 // #037 // Make sure sector size is not zero. #038 // #039
确保每个扇区的字节数不为0,如果为0的时候,就让它缺省为512个字节。 #040 if (bytesPerSector == 0) { #041 #042 // #043 // Default sector size for disk is 512. #044 // #045 #046 bytesPerSector = diskGeometry->BytesPerSector = 512; #047 } #048 #049 sectorShift = physicalDeviceExtension->SectorShift; #050 #051 // #052 // Set pointer to disk data area that follows device extension. #053 // #054
设置指向磁盘结构数据指针。 #055 diskData = (PDISK_DATA)(physicalDeviceExtension + 1);
设置磁盘分区表格正在初始化。 #056 diskData->PartitionListState = Initializing; #057 #058 // #059 // Determine is DM Driver is loaded on an IDE drive that is #060 // under control of Atapi - this could be either a crashdump or #061 // an Atapi device is sharing the controller with an IDE disk. #062 // #063
调用函数HalExamineMBR来读取指定类型的MBR扇区数据。其实这个函数调用IO管理器后,生成一个IRP调用ATAPI驱动程序去读取磁盘0扇区数据。 #064 HalExamineMBR(PhysicalDeviceObject, #065 physicalDeviceExtension->DiskGeometry->BytesPerSector, #066 (ULONG)0x54, #067 (PVOID)&dmSkew); #068
判断是否有DM驱动程序,如果有就需要调整相关的磁盘信息。 #069 if (dmSkew) { #070 #071 // #072 // Update the device extension,so that the call to IoReadPartitionTable #073 // will get the correct information. Any I/O to this disk will have #074 // to be skewed by *dmSkew sectors aka DMByteSkew. #075 // #076 #077 physicalDeviceExtension->DMSkew = *dmSkew; #078 physicalDeviceExtension->DMActive = TRUE; #079 physicalDeviceExtension->DMByteSkew = physicalDeviceExtension->DMSkew * bytesPerSector; #080 #081 // #082 // Save away the infomation that we need,since this deviceExtension will soon be #083 // blown away. #084 // #085 #086 dmActive = TRUE; #087 dmByteSkew = physicalDeviceExtension->DMByteSkew; #088 #089 } #090 #091 // #092 // Create objects for all the partitions on the device. #093 // #094
为这个磁盘设备的所有分区创建分区对象。 #095 status = IoReadPartitionTable(PhysicalDeviceObject, #096 physicalDeviceExtension->DiskGeometry->BytesPerSector, #097 TRUE, #098 (PVOID)&partitionList); #099 #100 // #101 // If the I/O read partition table failed and this is a removable device, #102 // then fix up the partition list to make it look like there is one #103 // zero length partition. #104 // #105 DPRINT("IoReadPartitionTable() status: 0x%08X/n",status); #106 if ((!NT_SUCCESS(status) || partitionList->PartitionCount == 0) && #107 PhysicalDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) { #108
如果读分区表出错,就设置磁盘没有准备好。 #109 if (!NT_SUCCESS(status)) { #110 #111 // #112 // Remember this disk is not ready. #113 // #114 #115 diskData->DriveNotReady = TRUE; #116 #117 } else { #118 #119 // #120 // Free the partition list allocated by IoReadPartitionTable. #121 // #122 #123 ExFreePool(partitionList); #124 } #125 #126 // #127 // Allocate and zero a partition list. #128 // #129
分配分区列表。 #130 partitionList = ExAllocatePool(NonPagedPool,sizeof(*partitionList )); #131 #132 #133 if (partitionList != NULL) { #134 #135 RtlZeroMemory( partitionList,sizeof( *partitionList )); #136 #137 // #138 // Set the partition count to one and the status to success #139 // so one device object will be created. Set the partition type #140 // to a bogus value. #141 // #142 #143 partitionList->PartitionCount = 1; #144 #145 status = STATUS_SUCCESS; #146 } #147 } #148 #149 if (NT_SUCCESS(status)) { #150 #151 // #152 // Record disk signature. #153 // #154
保存磁盘的标志。 #155 diskData->Signature = partitionList->Signature; #156 #157 // #158 // If disk signature is zero,then calculate the MBR checksum. #159 // #160
如果磁盘的标志为0,那么就计算MBR的校验码是否正确。 #161 if (!diskData->Signature) { #162 #163 if (!CalculateMbrCheckSum(physicalDeviceExtension, #164 &diskData->MbrCheckSum)) { #165 #166 DebugPrint((1, #167 "SCSIDISK: Can't calculate MBR checksum for disk %x/n", #168 physicalDeviceExtension->DeviceNumber)); #169 } else { #170 #171 DebugPrint((2, #172 "SCSIDISK: MBR checksum for disk %x is %x/n", #173 physicalDeviceExtension->DeviceNumber, #174 diskData->MbrCheckSum)); #175 } #176 } #177 #178 // #179 // Check the registry and determine if the BIOS knew about this drive. If #180 // it did then update the geometry with the BIOS information. #181 // #182
查询注册表,这个磁盘是否在BIOS里可以读取的。 #183 UpdateGeometry(physicalDeviceExtension); #184 #185 srbFlags = physicalDeviceExtension->SrbFlags; #186
创建磁盘的操作函数。 #187 initData = ExAllocatePool(NonPagedPool,sizeof(CLASS_INIT_DATA)); #188 if (!initData) #189 { #190 DebugPrint((1, #191 "Disk.CreatePartionDeviceObjects - Allocation of initData failed/n")); #192 #193 status = STATUS_INSUFFICIENT_RESOURCES; #194 goto CreatePartitionDeviceObjectsExit; #195 } #196 #197 RtlZeroMemory(initData,sizeof(CLASS_INIT_DATA)); #198 #199 initData->InitializationDataSize = sizeof(CLASS_INIT_DATA); #200 initData->DeviceExtensionSize = DEVICE_EXTENSION_SIZE; #201 initData->DeviceType = FILE_DEVICE_DISK; #202 initData->DeviceCharacteristics = PhysicalDeviceObject->Characteristics; #203 initData->ClassError = physicalDeviceExtension->ClassError; #204 initData->ClassReadWriteVerification = physicalDeviceExtension->ClassReadWriteVerification; #205 initData->ClassFindDevices = physicalDeviceExtension->ClassFindDevices; #206 initData->ClassDeviceControl = physicalDeviceExtension->ClassDeviceControl; #207 initData->ClassShutdownFlush = physicalDeviceExtension->ClassShutdownFlush; #208 initData->ClassCreateClose = physicalDeviceExtension->ClassCreateClose; #209 initData->ClassStartIo = physicalDeviceExtension->ClassStartIo; #210 #211 // #212 // Create device objects for the device partitions (if any). #213 // PartitionCount includes physical device partition 0, #214 // so only one partition means no objects to create. #215 // #216 #217 DebugPrint((2, #218 "CreateDiskDeviceObjects: Number of partitions is %d/n", #219 partitionList->PartitionCount)); #220
为所有磁盘分区创建分区对象。 #221 for (partitionNumber = 0; partitionNumber < #222 partitionList->PartitionCount; partitionNumber++) { #223 #224 // #225 // Create partition object and set up partition parameters. #226 // #227 #228 sprintf(ntNameBuffer, #229 "//Device//Harddisk%lu//Partition%lu", #230 physicalDeviceExtension->DeviceNumber, #231 partitionNumber + 1); #232 #233 DebugPrint((2, #234 "CreateDiskDeviceObjects: Create device object %s/n", #235 ntNameBuffer)); #236 #237 status = ScsiClassCreateDeviceObject(PhysicalDeviceObject->DriverObject, #238 ntNameBuffer, #239 PhysicalDeviceObject, #240 &deviceObject, #241 initData); #242 #243 if (!NT_SUCCESS(status)) { #244 #245 DebugPrint((1,"CreateDiskDeviceObjects: Can't create device object for %s/n",ntNameBuffer)); #246 #247 break; #248 } #249 #250 // #251 // Set up device object fields. #252 // #253
设置设备是直接通过IO访问。 #254 deviceObject->Flags |= DO_DIRECT_IO; #255 #256 // #257 // Check if this is during initialization. If not indicate that #258 // system initialization already took place and this disk is ready #259 // to be accessed. #260 // #261 #262 if (!RegistryPath) { #263 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; #264 } #265
设置设备栈。 #266 deviceObject->StackSize = (CCHAR)physicalDeviceExtension->PortDeviceObject->StackSize + 1; #267 #268 // #269 // Set up device extension fields. #270 // #271
设置设备扩展结构。 #272 deviceExtension = deviceObject->DeviceExtension; #273 #274 if (dmActive) { #275 #276 // #277 // Restore any saved DM values. #278 // #279 #280 deviceExtension->DMByteSkew = dmByteSkew; #281 deviceExtension->DMSkew = *dmSkew; #282 deviceExtension->DMActive = TRUE; #283 #284 } #285 #286 // #287 // Link new device extension to previous disk data #288 // to support dynamic partitioning. #289 // #290
设置设备连接下一个分区。 #291 diskData->NextPartition = deviceExtension; #292 #293 // #294 // Get pointer to new disk data. #295 // #296 #297 diskData = (PDISK_DATA)(deviceExtension + 1); #298 #299 // #300 // Set next partition pointer to NULL in case this is the #301 // last partition. #302 // #303 #304 diskData->NextPartition = NULL; #305 #306 // #307 // Allocate spinlock for zoning for split-request completion. #308 // #309 #310 KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock); #311 #312 // #313 // Copy port device object pointer to device extension. #314 // #315
设置设备指向端口驱动程序。 #316 deviceExtension->PortDeviceObject = physicalDeviceExtension->PortDeviceObject; #317 #318 // #319 // Set the alignment requirements for the device based on the #320 // host adapter requirements #321 // #322 #323 if (physicalDeviceExtension->PortDeviceObject->AlignmentRequirement > deviceObject->AlignmentRequirement) { #324 deviceObject->AlignmentRequirement = physicalDeviceExtension->PortDeviceObject->AlignmentRequirement; #325 } #326 #327 #328 if (srbFlags & SRB_FLAGS_QUEUE_ACTION_ENABLE) { #329 numberListElements = 30; #330 } else { #331 numberListElements = 8; #332 } #333 #334 // #335 // Build the lookaside list for srb's for this partition based on #336 // whether the adapter and disk can do tagged queueing. #337 // #338
设置设备扩展的后备缓冲列表。 #339 ScsiClassInitializeSrbLookasideList(deviceExtension, #340 numberListElements); #341 #342 deviceExtension->SrbFlags = srbFlags; #343 #344 // #345 // Set the sense-data pointer in the device extension. #346 // #347 #348 deviceExtension->SenseData = physicalDeviceExtension->SenseData; #349 deviceExtension->PortCapabilities = physicalDeviceExtension->PortCapabilities; #350 deviceExtension->DiskGeometry = diskGeometry; #351 diskData->PartitionOrdinal = diskData->PartitionNumber = partitionNumber + 1; #352 diskData->PartitionType = partitionList->PartitionEntry[partitionNumber].PartitionType; #353 diskData->BootIndicator = partitionList->PartitionEntry[partitionNumber].BootIndicator; #354 #355 DebugPrint((2,"CreateDiskDeviceObjects: Partition type is %x/n", #356 diskData->PartitionType)); #357 #358 deviceExtension->StartingOffset = partitionList->PartitionEntry[partitionNumber].StartingOffset; #359 deviceExtension->PartitionLength = partitionList->PartitionEntry[partitionNumber].PartitionLength; #360 diskData->HiddenSectors = partitionList->PartitionEntry[partitionNumber].HiddenSectors; #361 deviceExtension->PortNumber = physicalDeviceExtension->PortNumber; #362 deviceExtension->PathId = physicalDeviceExtension->PathId; #363 deviceExtension->TargetId = physicalDeviceExtension->TargetId; #364 deviceExtension->Lun = physicalDeviceExtension->Lun; #365 #366 // #367 // Check for removable media support. #368 // #369
检查可移动磁盘的支持。 #370 if (PhysicalDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) { #371 deviceObject->Characteristics |= FILE_REMOVABLE_MEDIA; #372 } #373 #374 // #375 // Set timeout value in seconds. #376 // #377
设置设备超时时间。 #378 deviceExtension->TimeOutValue = physicalDeviceExtension->TimeOutValue; #379 deviceExtension->DiskGeometry->BytesPerSector = bytesPerSector; #380 deviceExtension->SectorShift = sectorShift; #381 deviceExtension->DeviceObject = deviceObject; #382 deviceExtension->DeviceFlags |= physicalDeviceExtension->DeviceFlags; #383 #384 } // end for (partitionNumber) ... #385 #386 // #387 // Free the buffer allocated by reading the #388 // partition table. #389 // #390 #391 ExFreePool(partitionList); #392 #393 } else { #394 #395 CreatePartitionDeviceObjectsExit: #396 #397 if (partitionList) { #398 ExFreePool(partitionList); #399 } #400 if (initData) { #401 ExFreePool(initData); #402 } #403 #404 return status; #405 #406 } // end if...else #407 #408 #409 physicalDiskData = (PDISK_DATA)(physicalDeviceExtension + 1); #410 physicalDiskData->PartitionListState = Initialized; #411 #412 return(STATUS_SUCCESS); #413 #414 #415 } // end CreatePartitionDeviceObjects() #416 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |