ScsiClassInitialize函数初始化驱动程序对象,主要是找到合适的端口驱动程序,并设置它来处理磁盘的命令,具体实现代码如下:
#001 ULONG
#002 NTAPI
#003 ScsiClassInitialize(
#004 IN PVOID Argument1,
#005 IN PVOID Argument2,
#006 IN PCLASS_INIT_DATA InitializationData
#007 )
#008
#009 /*++
#010
#011 Routine Description:
#012
#013 This routine is called by a class driver during its
#014 DriverEntry routine to initialize the driver.
#015
#016 Arguments:
#017
#018 Argument1 - Driver Object.
#019 Argument2 - Registry Path.
#020 InitializationData - Device-specific driver's initialization data.
#021
#022 Return Value:
#023
#024 A valid return code for a DriverEntry routine.
#025
#026 --*/
#027
#028 {
#029
#030
驱动程序对象。
#031 PDRIVER_OBJECT DriverObject = Argument1;
#032 ULONG portNumber = 0;
#033 PDEVICE_OBJECT portDeviceObject;
#034 NTSTATUS status;
#035 STRING deviceNameString;
#036 UNICODE_STRING unicodeDeviceName;
#037 PFILE_OBJECT fileObject;
#038 CCHAR deviceNameBuffer[256];
#039 BOOLEAN deviceFound = FALSE;
#040
#041 DebugPrint((3,"/n/nSCSI Class Driver/n"));
#042
#043 //
#044 // Validate the length of this structure. This is effectively a
#045 // version check.
#046 //
#047
判断初始化的数据结构大小是否与函数处理的一样,如果不一样版本就返回出错。
#048 if (InitializationData->InitializationDataSize > sizeof(CLASS_INIT_DATA)) {
#049
#050 DebugPrint((0,"ScsiClassInitialize: Class driver wrong version/n"));
#051 return (ULONG) STATUS_REVISION_MISMATCH;
#052 }
#053
#054 //
#055 // Check that each required entry is not NULL. Note that Shutdown, Flush and Error
#056 // are not required entry points.
#057 //
#058
判断初始化的函数是否正确设置了。
#059 if ((!InitializationData->ClassFindDevices) ||
#060 (!InitializationData->ClassDeviceControl) ||
#061 (!((InitializationData->ClassReadWriteVerification) ||
#062 (InitializationData->ClassStartIo)))) {
#063
#064 DebugPrint((0,
#065 "ScsiClassInitialize: Class device-specific driver missing required entry/n"));
#066
#067 return (ULONG) STATUS_REVISION_MISMATCH;
#068 }
#069
#070 //
#071 // Update driver object with entry points.
#072 //
#073
设置驱动程序功能调用的函数。
#074 DriverObject->MajorFunction[IRP_MJ_CREATE] = ScsiClassCreateClose;
#075 DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScsiClassCreateClose;
#076 DriverObject->MajorFunction[IRP_MJ_READ] = ScsiClassReadWrite;
#077 DriverObject->MajorFunction[IRP_MJ_WRITE] = ScsiClassReadWrite;
#078 DriverObject->MajorFunction[IRP_MJ_SCSI] = ScsiClassInternalIoControl;
#079 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ScsiClassDeviceControlDispatch;
#080 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ScsiClassShutdownFlush;
#081 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ScsiClassShutdownFlush;
#082
如果StartIO函数,就需要设置顺序操作IO函数。
#083 if (InitializationData->ClassStartIo) {
#084 DriverObject->DriverStartIo = InitializationData->ClassStartIo;
#085 }
#086
#087 //
#088 // Open port driver controller device objects by name.
#089 //
#090
通设备名称来打开端口设备驱动对象。
#091 do {
#092
#093 sprintf(deviceNameBuffer, "//Device//ScsiPort%lu", portNumber);
#094
#095 DebugPrint((2, "ScsiClassInitialize: Open Port %s/n", deviceNameBuffer));
#096
#097 RtlInitString(&deviceNameString, deviceNameBuffer);
#098
#099 status = RtlAnsiStringToUnicodeString(&unicodeDeviceName,
#100 &deviceNameString,
#101 TRUE);
#102
#103 if (!NT_SUCCESS(status)){
#104 break;
#105 }
#106
通过设备名称来获取端口驱动程序。
#107 status = IoGetDeviceObjectPointer(&unicodeDeviceName,
#108 FILE_READ_ATTRIBUTES,
#109 &fileObject,
#110 &portDeviceObject);
#111
#112 if (NT_SUCCESS(status)) {
#113
#114 //
#115 // Call the device-specific driver's FindDevice routine.
#116 //
#117
查找这个设备是否匹配。
#118 if (InitializationData->ClassFindDevices(DriverObject, Argument2, InitializationData,
#119 portDeviceObject, portNumber)) {
#120
如果找到设备就设置返回成功标志。
#121 deviceFound = TRUE;
#122 }
#123 }
#124
#125 //
#126 // Check next SCSI adapter.
#127 //
#128
#129 portNumber++;
#130
#131 } while(NT_SUCCESS(status));
#132
#133 return deviceFound ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE;
#134 }