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  

posted @ 2009-10-31 22:10  ajuanabc  阅读(268)  评论(0编辑  收藏  举报