您的位置:首页 > Web前端 > React

reactos操作系统实现(121)

2009-10-31 22:10 127 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: