现在的位置: 首页 > 综合 > 正文

reactos操作系统实现(121)

2013年10月18日 ⁄ 综合 ⁄ 共 15184字 ⁄ 字号 评论关闭

 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  

抱歉!评论已关闭.