前介绍了初始化函数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()