reactos操作系统实现(120)

前端之家收集整理的这篇文章主要介绍了reactos操作系统实现(120)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

CreateDiskDeviceObject函数主要就是为了物理设备创建磁盘对象,并且查找磁盘上每个分区和创建相应的对象。具体实现代码如下:

#001 NTSTATUS

#002 NTAPI

#003 CreateDiskDeviceObject(

#004 IN PDRIVER_OBJECT DriverObject,

#005 IN PUNICODE_STRING RegistryPath,

#006 IN PDEVICE_OBJECT PortDeviceObject,

#007 IN ULONG PortNumber,

#008 IN PULONG DeviceCount,

#009 IN PIO_SCSI_CAPABILITIES PortCapabilities,

#010 IN PSCSI_INQUIRY_DATA LunInfo,

#011 IN PCLASS_INIT_DATA InitData

#012 )

#013

#014 /*++

#015

#016 Routine Description:

#017

#018 This routine creates an object for the physical device and then searches

#019 the device for partitions and creates an object for each partition.

#020

#021 Arguments:

#022

#023 DriverObject - Pointer to driver object created by system.

#024

#025 PortDeviceObject - Miniport device object.

#026

#027 PortNumber - port number. Used in creating disk objects.

#028

#029 DeviceCount - Number of prevIoUsly installed devices.

#030

#031 PortCapabilities - Capabilities of this SCSI port.

#032

#033 LunInfo - LUN specific information.

#034

#035 Return Value:

#036

#037 NTSTATUS

#038

#039 --*/

#040 {

#041 CCHAR ntNameBuffer[MAXIMUM_FILENAME_LENGTH];

#042 STRING ntNameString;

#043 UNICODE_STRING ntUnicodeString;

#044 OBJECT_ATTRIBUTES objectAttributes;

#045 HANDLE handle;

#046 NTSTATUS status;

#047 PDEVICE_OBJECT deviceObject = NULL;

#048 PDEVICE_OBJECT physicalDevice;

#049 PDISK_GEOMETRY diskGeometry = NULL;

#050 PDEVICE_EXTENSION deviceExtension = NULL;

#051 PDEVICE_EXTENSION physicalDeviceExtension;

#052 UCHAR pathId = LunInfo->PathId;

#053 UCHAR targetId = LunInfo->TargetId;

#054 UCHAR lun = LunInfo->Lun;

#055 BOOLEAN writeCache;

#056 PVOID senseData = NULL;

#057 ULONG srbFlags;

#058 ULONG timeOut = 0;

#059 BOOLEAN srbListInitialized = FALSE;

#060

#061

保证运行这些代骊是非分页代码,如果是分页代码就抛出异常。

#062 PAGED_CODE();

#063

#064 //

#065 // Set up an object directory to contain the objects for this

#066 // device and all its partitions.

#067 //

#068

创建一个设备的磁盘目录对象。

#069 sprintf(ntNameBuffer,

#070 "//Device//Harddisk%lu",

#071 *DeviceCount);

#072

#073 RtlInitString(&ntNameString,

#074 ntNameBuffer);

#075

#076 status = RtlAnsiStringToUnicodeString(&ntUnicodeString,

#077 &ntNameString,

#078 TRUE);

#079

#080 if (!NT_SUCCESS(status)) {

#081 return(status);

#082 }

#083

#084 InitializeObjectAttributes(&objectAttributes,

#085 &ntUnicodeString,

#086 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,

#087 NULL,

#088 NULL);

#089

调用函数ZwCreateDirectoryObject在对象管理器里创建设备目录对象。

#090 status = ZwCreateDirectoryObject(&handle,

#091 DIRECTORY_ALL_ACCESS,

#092 &objectAttributes);

#093

#094 RtlFreeUnicodeString(&ntUnicodeString);

#095

#096 if (!NT_SUCCESS(status)) {

#097

#098 DebugPrint((1,

#099 "CreateDiskDeviceObjects: Could not create directory %s/n",

#100 ntNameBuffer));

#101

#102 return(status);

#103 }

#104

#105 //

#106 // Claim the device.

#107 //

#108

从端口驱动程序里申请一个端口驱动程序对象。

#109 status = ScsiClassClaimDevice(PortDeviceObject,

#110 LunInfo,

#111 FALSE,

#112 &PortDeviceObject);

#113

#114 if (!NT_SUCCESS(status)) {

#115 ZwMakeTemporaryObject(handle);

#116 ZwClose(handle);

#117 return status;

#118 }

#119

#120 //

#121 // Create a device object for this device. Each physical disk will

#122 // have at least one device object. The required device object

#123 // describes the entire device. Its directory path is

#124 // /Device/HarddiskN/Partition0,where N = device number.

#125 //

#126

创建每个物理分区磁盘的名称

#127 sprintf(ntNameBuffer,

#128 "//Device//Harddisk%lu//Partition0",

#129 *DeviceCount);

#130

#131

调用函数ScsiClassCreateDeviceObject为每个物理分区创建物理设备对象,并且设备驱动程序扩展的功能处理函数

#132 status = ScsiClassCreateDeviceObject(DriverObject,

#133 ntNameBuffer,

#134 NULL,

#135 &deviceObject,

#136 InitData);

#137

#138 if (!NT_SUCCESS(status)) {

#139

#140 DebugPrint((1,

#141 "CreateDiskDeviceObjects: Can not create device object %s/n",

#142 ntNameBuffer));

#143

#144 goto CreateDiskDeviceObjectsExit;

#145 }

#146

#147 //

#148 // Indicate that IRPs should include MDLs for data transfers.

#149 //

#150

指明这个物理设备对象是直接IO缓冲区的访问方式。

#151 deviceObject->Flags |= DO_DIRECT_IO;

#152

#153 //

#154 // Check if this is during initialization. If not indicate that

#155 // system initialization already took place and this disk is ready

#156 // to be accessed.

#157 //

#158

如果这个物理设备没有在注册表里,说明它是没有被初始化的。

#159 if (!RegistryPath) {

#160 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

#161 }

#162

#163 //

#164 // Check for removable media support.

#165 //

#166

从端口驱动程序里查找到这个物理设备是可移动的设备,那么就设置为可移动的文件媒体。

#167 if (((PINQUIRYDATA)LunInfo->InquiryData)->RemovableMedia) {

#168 deviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;

#169 }

#170

#171 //

#172 // Set up required stack size in device object.

#173 //

#174

设置设备栈的大小。

#175 deviceObject->StackSize = (CCHAR)PortDeviceObject->StackSize + 1;

#176

获取设备驱动对象扩展。

#177 deviceExtension = deviceObject->DeviceExtension;

#178

#179 //

#180 // Allocate spinlock for split request completion.

#181 //

#182

分配共享请求的自旋锁。

#183 KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock);

#184

#185 //

#186 // Initialize lock count to zero. The lock count is used to

#187 // disable the ejection mechanism on devices that support

#188 // removable media. Only the lock count in the physical

#189 // device extension is used.

#190 //

#191

#192 deviceExtension->LockCount = 0;

#193

#194 //

#195 // Save system disk number.

#196 //

#197

保存磁盘编号。

#198 deviceExtension->DeviceNumber = *DeviceCount;

#199

#200 //

#201 // Copy port device object pointer to the device extension.

#202 //

#203

#204 deviceExtension->PortDeviceObject = PortDeviceObject;

#205

#206 //

#207 // Set the alignment requirements for the device based on the

#208 // host adapter requirements

#209 //

#210

设置为主机适配器的对齐方式。

#211 if (PortDeviceObject->AlignmentRequirement > deviceObject->AlignmentRequirement) {

#212 deviceObject->AlignmentRequirement = PortDeviceObject->AlignmentRequirement;

#213 }

#214

#215 //

#216 // This is the physical device object.

#217 //

#218

设置物理设备对象。

#219 physicalDevice = deviceObject;

#220 physicalDeviceExtension = deviceExtension;

#221

#222 //

#223 // Save address of port driver capabilities.

#224 //

#225

#226 deviceExtension->PortCapabilities = PortCapabilities;

#227

#228 //

#229 // Build the lookaside list for srb's for the physical disk. Should only

#230 // need a couple.

#231 //

#232

创建一个磁盘的后备列表,以便快速访问。

#233 ScsiClassInitializeSrbLookasideList(deviceExtension,

#234 PARTITION0_LIST_SIZE);

#235

#236 srbListInitialized = TRUE;

#237

#238 //

#239 // Initialize the srb flags.

#240 //

#241

开始初始化SRB属性

#242 if (((PINQUIRYDATA)LunInfo->InquiryData)->CommandQueue &&

#243 PortCapabilities->TaggedQueuing) {

#244

#245 deviceExtension->SrbFlags = SRB_FLAGS_QUEUE_ACTION_ENABLE;

#246

#247 } else {

#248

#249 deviceExtension->SrbFlags = 0;

#250

#251 }

#252

#253 //

#254 // Allow queued requests if this is not removable media.

#255 //

#256

如果磁盘设备不是可移动设备,那么就创建一个队列来保存请求包。

#257 if (!(deviceObject->Characteristics & FILE_REMOVABLE_MEDIA)) {

#258

#259 deviceExtension->SrbFlags |= SRB_FLAGS_NO_QUEUE_FREEZE;

#260

#261 }

#262

#263 //

#264 // Look for controller that require special flags.

#265 //

#266

扫描设备的特别设置。

#267 ScanForSpecial(deviceObject,

#268 LunInfo,

#269 PortCapabilities);

#270

#271 srbFlags = deviceExtension->SrbFlags;

#272

#273 //

#274 // Allocate buffer for drive geometry.

#275 //

#276

分配磁盘物理组成属性,比如磁头个数,柱面,扇区数量等等。

#277 diskGeometry = ExAllocatePool(NonPagedPool,sizeof(DISK_GEOMETRY));

#278

#279 if (diskGeometry == NULL) {

#280

#281 DebugPrint((1,

#282 "CreateDiskDeviceObjects: Can not allocate disk geometry buffer/n"));

#283 status = STATUS_INSUFFICIENT_RESOURCES;

#284 goto CreateDiskDeviceObjectsExit;

#285 }

#286

#287 deviceExtension->DiskGeometry = diskGeometry;

#288

#289 //

#290 // Allocate request sense buffer.

#291 //

#292

#293 senseData = ExAllocatePool(NonPagedPoolCacheAligned,SENSE_BUFFER_SIZE);

#294

#295 if (senseData == NULL) {

#296

#297 //

#298 // The buffer can not be allocated.

#299 //

#300

#301 DebugPrint((1,

#302 "CreateDiskDeviceObjects: Can not allocate request sense buffer/n"));

#303

#304 status = STATUS_INSUFFICIENT_RESOURCES;

#305 goto CreateDiskDeviceObjectsExit;

#306 }

#307

#308 //

#309 // Set the sense data pointer in the device extension.

#310 //

#311

保存有意义的数据指针。

#312 deviceExtension->SenseData = senseData;

#313

#314 //

#315 // Physical device object will describe the entire

#316 // device,starting at byte offset 0.

#317 //

#318

设置物理设备的偏移位置。

#319 deviceExtension->StartingOffset.QuadPart = (LONGLONG)(0);

#320

#321 //

#322 // TargetId/LUN describes a device location on the SCSI bus.

#323 // This information comes from the inquiry buffer.

#324 //

#325

设置SCSI总线上标识磁盘的内容

#326 deviceExtension->PortNumber = (UCHAR)PortNumber;

#327 deviceExtension->PathId = pathId;

#328 deviceExtension->TargetId = targetId;

#329 deviceExtension->Lun = lun;

#330

#331 //

#332 // Set timeout value in seconds.

#333 //

#334

设置磁盘设备的命令处理的超时时间。

#335 timeOut = ScsiClassQueryTimeOutRegistryValue(RegistryPath);

#336 if (timeOut) {

#337 deviceExtension->TimeOutValue = timeOut;

#338 } else {

#339 deviceExtension->TimeOutValue = SCSI_DISK_TIMEOUT;

#340 }

#341

#342 //

#343 // Back pointer to device object.

#344 //

#345

设备对象的指针。

#346 deviceExtension->DeviceObject = deviceObject;

#347

#348 //

#349 // If this is a removable device,then make sure it is not a floppy.

#350 // Perform a mode sense command to determine the media type. Note

#351 // IsFloppyDevice also checks for write cache enabled.

#352 //

#353

如果设备是软盘设备,并且设备是可移设备,不可以直接访问时就创建失败。

#354 if (IsFloppyDevice(deviceObject) && deviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&

#355 (((PINQUIRYDATA)LunInfo->InquiryData)->DeviceType == DIRECT_ACCESS_DEVICE)) {

#356

#357 status = STATUS_NO_SUCH_DEVICE;

#358 goto CreateDiskDeviceObjectsExit;

#359 }

#360

关闭写缓存。

#361 DisableWriteCache(deviceObject,LunInfo);

#362

#363 writeCache = deviceExtension->DeviceFlags & DEV_WRITE_CACHE;

#364

#365 //

#366 // NOTE: At this point one device object has been successfully created.

#367 // from here on out return success.

#368 //

#369

#370 //

#371 // Do READ CAPACITY. This SCSI command

#372 // returns the number of bytes on a device.

#373 // Device extension is updated with device size.

#374 //

#375

发送命令READ CAPACITY获取设备容量的大小,比如多少G数据可以保存。

#376 status = ScsiClassReadDriveCapacity(deviceObject);

#377

#378 //

#379 // If the read capcity Failed then just return,unless this is a

#380 // removable disk where a device object partition needs to be created.

#381 //

#382

#383 if (!NT_SUCCESS(status) &&

#384 !(deviceObject->Characteristics & FILE_REMOVABLE_MEDIA)) {

#385

#386 DebugPrint((1,

#387 "CreateDiskDeviceObjects: Can't read capacity for device %s/n",

#388 ntNameBuffer));

#389

#390 return(STATUS_SUCCESS);

#391

#392 } else {

#393

#394 //

#395 // Make sure the volume verification bit is off so that

#396 // IoReadPartitionTable will work.

#397 //

#398

设置可以读取分区表格了。

#399 deviceObject->Flags &= ~DO_VERIFY_VOLUME;

#400 }

#401

为磁盘所有分区创建分区设备对象,主要通过MBR的分区表格来分析有几个可以使用的分区。

#402 status = CreatePartitionDeviceObjects(deviceObject,RegistryPath);

#403

#404 if (NT_SUCCESS(status))

#405 return STATUS_SUCCESS;

#406

#407

下面是删除已经分配的内存。

#408 CreateDiskDeviceObjectsExit:

#409

#410 //

#411 // Release the device since an error occurred.

#412 //

#413

#414 ScsiClassClaimDevice(PortDeviceObject,

#415 LunInfo,

#416 TRUE,

#417 NULL);

#418

#419 if (diskGeometry != NULL) {

#420 ExFreePool(diskGeometry);

#421 }

#422

#423 if (senseData != NULL) {

#424 ExFreePool(senseData);

#425 }

#426

#427 if (deviceObject != NULL) {

#428

#429 if (srbListInitialized) {

#430 ExDeleteNPagedLookasideList(&deviceExtension->SrbLookasideListHead);

#431 }

#432

#433 IoDeleteDevice(deviceObject);

#434 }

#435

#436 //

#437 // Delete directory and return.

#438 //

#439

#440 if (!NT_SUCCESS(status)) {

#441 ZwMakeTemporaryObject(handle);

#442 }

#443

#444 ZwClose(handle);

#445

#446 return(status);

#447

#448} // end CreateDiskDeviceObjects()

猜你在找的React相关文章