reactos操作系统实现(121)

来源:互联网 发布:淘宝客是什么 编辑:程序博客网 时间:2024/06/16 20:13

 CreatePartitionDeviceObjects函数是通过分析MBR扇区的数据,然后来创建所有分区对象。具体实现代码如下:

#001  NTSTATUS

#002  NTAPI

#003 CreatePartitionDeviceObjects(

#004      IN PDEVICE_OBJECTPhysicalDeviceObject,

#005      IN PUNICODE_STRINGRegistryPath

#006      )

#007  {

#008      CCHAR          ntNameBuffer[MAXIMUM_FILENAME_LENGTH];

#009      ULONG          partitionNumber = 0;

#010      NTSTATUS       status;

#011      PDEVICE_OBJECTdeviceObject = NULL;

#012      PDISK_GEOMETRYdiskGeometry = NULL;

#013     PDRIVE_LAYOUT_INFORMATION partitionList = NULL;

#014      PDEVICE_EXTENSIONdeviceExtension;

#015      PDEVICE_EXTENSIONphysicalDeviceExtension;

#016      PCLASS_INIT_DATAinitData = 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 devicegeometry 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 sizeis not zero.

#038      //

#039 

 

确保每个扇区的字节数不为0,如果为0的时候,就让它缺省为512个字节。

#040      if (bytesPerSector == 0){

#041 

#042          //

#043          // Default sectorsize for disk is 512.

#044          //

#045 

#046          bytesPerSector =diskGeometry->BytesPerSector = 512;

#047      }

#048 

#049      sectorShift =physicalDeviceExtension->SectorShift;

#050 

#051      //

#052      // Set pointer to diskdata area that follows device extension.

#053      //

#054 

 

设置指向磁盘结构数据指针。

#055      diskData =(PDISK_DATA)(physicalDeviceExtension + 1);

 

设置磁盘分区表格正在初始化。

#056     diskData->PartitionListState = Initializing;

#057 

#058      //

#059      // Determine is DMDriver is loaded on an IDE drive that is

#060      // under control ofAtapi - this could be either a crashdump or

#061      // an Atapi device issharing 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 deviceextension, so that the call to IoReadPartitionTable

#073          // will get thecorrect 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 theinfomation 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 forall 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 readpartition table failed and this is a removable device,

#102      // then fix up thepartition list to make it look like there is one

#103      // zero lengthpartition.

#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 thisdisk is not ready.

#113              //

#114 

#115             diskData->DriveNotReady = TRUE;

#116 

#117          } else {

#118 

#119              //

#120              // Free the partitionlist allocated by IoReadPartitionTable.

#121              //

#122 

#123             ExFreePool(partitionList);

#124          }

#125 

#126          //

#127          // Allocate and zeroa 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 thestatus to success

#139              // so one deviceobject will be created. Set the partition type

#140              // to a bogusvalue.

#141              //

#142 

#143             partitionList->PartitionCount = 1;

#144 

#145              status =STATUS_SUCCESS;

#146          }

#147      }

#148 

#149      if (NT_SUCCESS(status)){

#150 

#151          //

#152          // Record disksignature.

#153          //

#154 

 

保存磁盘的标志。

#155          diskData->Signature= partitionList->Signature;

#156 

#157          //

#158          // If disk signatureis 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 theregistry and determine if the BIOS knew about this drive.  If

#180          // it did then update the geometry withthe 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              gotoCreatePartitionDeviceObjectsExit;

#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 deviceobjects for the device partitions (if any).

#213          // PartitionCountincludes physical device partition 0,

#214          // so only onepartition 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              // Createpartition 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 objectfor %s/n", ntNameBuffer));

#246 

#247                  break;

#248              }

#249 

#250              //

#251              // Set up deviceobject fields.

#252              //

#253 

 

设置设备是直接通过IO访问。

#254              deviceObject->Flags|= DO_DIRECT_IO;

#255 

#256              //

#257              // Check if thisis during initialization. If not indicate that

#258              // systeminitialization already took place and this disk is ready

#259              // to beaccessed.

#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 deviceextension fields.

#270              //

#271 

 

设置设备扩展结构。

#272              deviceExtension= deviceObject->DeviceExtension;

#273 

#274              if (dmActive) {

#275 

#276                  //

#277                  // Restoreany saved DM values.

#278                  //

#279 

#280                 deviceExtension->DMByteSkew = dmByteSkew;

#281                 deviceExtension->DMSkew     =*dmSkew;

#282                 deviceExtension->DMActive   =TRUE;

#283 

#284              }

#285 

#286              //

#287              // Link newdevice extension to previous disk data

#288              // to supportdynamic partitioning.

#289              //

#290 

 

设置设备连接下一个分区。

#291             diskData->NextPartition = deviceExtension;

#292 

#293              //

#294              // Get pointerto new disk data.

#295              //

#296 

#297              diskData =(PDISK_DATA)(deviceExtension + 1);

#298 

#299              //

#300              // Set nextpartition pointer to NULL in case this is the

#301              // lastpartition.

#302              //

#303 

#304             diskData->NextPartition = NULL;

#305 

#306              //

#307              // Allocate spinlock for zoning forsplit-request completion.

#308              //

#309 

#310             KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock);

#311 

#312              //

#313              // Copy portdevice object pointer to device extension.

#314              //

#315 

 

设置设备指向端口驱动程序。

#316             deviceExtension->PortDeviceObject =physicalDeviceExtension->PortDeviceObject;

#317 

#318              //

#319              // Set thealignment requirements for the device based on the

#320              // host adapterrequirements

#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 thelookaside list for srb's for this partition based on

#336              // whether theadapter and disk can do tagged queueing.

#337              //

#338 

 

设置设备扩展的后备缓冲列表。

#339             ScsiClassInitializeSrbLookasideList(deviceExtension,

#340                                                 numberListElements);

#341 

#342             deviceExtension->SrbFlags = srbFlags;

#343 

#344              //

#345              // Set thesense-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 forremovable media support.

#368              //

#369 

 

检查可移动磁盘的支持。

#370              if(PhysicalDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {

#371                  deviceObject->Characteristics|= FILE_REMOVABLE_MEDIA;

#372              }

#373 

#374              //

#375              // Set timeoutvalue 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 bufferallocated 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  } // endCreatePartitionDeviceObjects()

#416  

原创粉丝点击