reactos操作系统实现(119)

 前介绍了初始化函数ScsiClassInitialize,那么在这个函数里使用下面的语句来查找SCSI的磁盘,如下:

if (InitializationData->ClassFindDevices(DriverObject, Argument2, InitializationData,portDeviceObject, portNumber))

其实这里的函数InitializationData->ClassFindDevices就是函数FindScsiDisks的调用,要了解这个函数的作用,一定要仔细地分析它的代码,才可以理解它,看看它是怎么样实现查找SCSI硬盘的,实现代码如下:

#001  BOOLEAN

#002  NTAPI

#003  FindScsiDisks(

#004      IN PDRIVER_OBJECT DriverObject,

#005      IN PUNICODE_STRING RegistryPath,

#006      IN PCLASS_INIT_DATA InitializationData,

#007      IN PDEVICE_OBJECT PortDeviceObject,

#008      IN ULONG PortNumber

#009      )

#010 

#011  /*++

#012 

#013  Routine Description:

#014 

#015      This routine gets a port drivers capabilities, obtains the

#016      inquiry data, searches the SCSI bus for the port driver and creates

#017      the device objects for the disks found.

#018 

#019  Arguments:

#020 

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

#022 

#023      PortDeviceObject - Device object use to send requests to port driver.

#024 

#025      PortNumber - Number for port driver.  Used to pass on to

#026                   CreateDiskDeviceObjects() and create device objects.

#027 

#028  Return Value:

#029 

#030      True is returned if one disk was found and successfully created.

#031 

#032  --*/

#033 

#034  {

#035      PIO_SCSI_CAPABILITIES portCapabilities;

#036      PULONG diskCount;

#037      PCONFIGURATION_INFORMATION configurationInformation;

#038      PCHAR buffer;

#039      PSCSI_INQUIRY_DATA lunInfo;

#040      PSCSI_ADAPTER_BUS_INFO  adapterInfo;

#041      PINQUIRYDATA inquiryData;

#042      ULONG scsiBus;

#043      ULONG adapterDisk;

#044      NTSTATUS status;

#045      BOOLEAN foundOne = FALSE;

#046 

#047      PAGED_CODE();

#048 

#049      //

#050      // Call port driver to get adapter capabilities.

#051      //

#052 

 

获取底层端口驱动程序的属性。

#053      status = ScsiClassGetCapabilities(PortDeviceObject, &portCapabilities);

#054 

#055      if (!NT_SUCCESS(status)) {

#056          DebugPrint((1,"FindScsiDevices: ScsiClassGetCapabilities failed/n"));

#057          return(FALSE);

#058      }

#059 

#060      //

#061      // Call port driver to get inquiry information to find disks.

#062      //

#063 

 

获取端口驱动程序的配置信息。

#064      status = ScsiClassGetInquiryData(PortDeviceObject, (PSCSI_ADAPTER_BUS_INFO *) &buffer);

#065 

#066      if (!NT_SUCCESS(status)) {

#067          DebugPrint((1,"FindScsiDevices: ScsiClassGetInquiryData failed/n"));

#068          return(FALSE);

#069      }

#070 

#071      //

#072      // Do a quick scan of the devices on this adapter to determine how many

#073      // disks are on this adapter.  This is used to determine the number of

#074      // SRB zone elements to allocate.

#075      //

#076 

#077      adapterDisk = 0;

#078      adapterInfo = (PVOID) buffer;

#079 

 

从端口驱动程序里返回的信息分析有几个磁盘。

#080      adapterDisk = ScsiClassFindUnclaimedDevices(InitializationData, adapterInfo);

#081 

#082      //

#083      // Allocate a zone of SRB for disks on this adapter.

#084      //

#085 

 

如果没有找到磁盘就返回。

#086      if (adapterDisk == 0) {

#087 

#088          //

#089          // No free disks were found.

#090          //

#091 

#092          return(FALSE);

#093      }

#094 

#095      //

#096      // Get the number of disks already initialized.

#097      //

#098 

 

获取配置信息。

#099      configurationInformation = IoGetConfigurationInformation();

 

配置信息里的磁盘个数。

#100      diskCount = &configurationInformation->DiskCount;

#101 

#102      //

#103      // For each SCSI bus this adapter supports ...

#104      //

#105 

 

找适配器里所有总线磁盘。

#106      for (scsiBus=0; scsiBus < (ULONG)adapterInfo->NumberOfBuses; scsiBus++) {

#107 

#108          //

#109          // Get the SCSI bus scan data for this bus.

#110          //

#111 

#112          lunInfo = (PVOID) (buffer + adapterInfo->BusData[scsiBus].InquiryDataOffset);

#113 

#114          //

#115          // Search list for unclaimed disk devices.

#116          //

#117 

 

搜索一个磁盘总线上所有设备。

#118          while (adapterInfo->BusData[scsiBus].InquiryDataOffset) {

#119 

#120              inquiryData = (PVOID)lunInfo->InquiryData;

#121 

#122              if (((inquiryData->DeviceType == DIRECT_ACCESS_DEVICE) ||

#123                  (inquiryData->DeviceType == OPTICAL_DEVICE)) &&

#124                  inquiryData->DeviceTypeQualifier == 0 &&

#125                  (!lunInfo->DeviceClaimed)) {

#126 

#127                  DebugPrint((1,

#128                              "FindScsiDevices: Vendor string is %.24s/n",

#129                              inquiryData->VendorId));

#130 

#131                  //

#132                  // Create device objects for disk

#133                  //

#134 

 

每找到一个磁盘设备,就创建一个磁盘对象。

#135                  status = CreateDiskDeviceObject(DriverObject,

#136                                                  RegistryPath,

#137                                                  PortDeviceObject,

#138                                                  PortNumber,

#139                                                  diskCount,

#140                                                  portCapabilities,

#141                                                  lunInfo,

#142                                                  InitializationData);

#143 

#144                  if (NT_SUCCESS(status)) {

#145 

#146                      //

#147                      // Increment system disk device count.

#148                      //

#149 

 

增加系统磁盘设备个数。

#150                      (*diskCount)++;

#151                      foundOne = TRUE;

#152 

#153                  }

#154              }

#155 

#156              //

#157              // Get next LunInfo.

#158              //

#159 

 

获取一下磁盘设备。

#160              if (lunInfo->NextInquiryDataOffset == 0) {

#161                  break;

#162              }

#163 

#164              lunInfo = (PVOID) (buffer + lunInfo->NextInquiryDataOffset);

#165 

#166          }

#167      }

#168 

#169      //

#170      // Buffer is allocated by ScsiClassGetInquiryData and must be free returning.

#171      //

#172 

#173      ExFreePool(buffer);

#174 

#175      return(foundOne);

#176 

#177  } // end FindScsiDisks()

posted @ 2009-10-29 22:33  ajuanabc  阅读(147)  评论(0编辑  收藏  举报