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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom