Hello people,
I’m developing a SCSI miniport in order to mount virtual CDs, but it is impossible to initialize it. This is the source in the DriverEntry:
…
CDDALogS(“SCSI Miniport Entry”);
//SCSI Miniport
RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
HwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
HwInitializationData.HwInitialize = CDDAInitialize;
HwInitializationData.HwResetBus = CDDAResetBus;
HwInitializationData.HwStartIo = CDDAStartIo;
HwInitializationData.HwFindAdapter = CDDAFindAdapter;
HwInitializationData.HwAdapterControl = CDDAAdapterControl;
//HwInitializationData.HwInterrupt = NULL;
//HwInitializationData.HwAdapterState = NULL;
HwInitializationData.AdapterInterfaceType = Internal;
HwInitializationData.DeviceExtensionSize = sizeof( DEVICE_EXTENSION );
HwInitializationData.MapBuffers = TRUE;
HwInitializationData.ReceiveEvent = TRUE;
HwInitializationData.AutoRequestSense = TRUE;
status = ScsiPortInitialize( DriverObject, RegistryPath, &HwInitializationData, &HwContext );
if (!NT_SUCCESS(status))
{
return status;
DbgPrint(“It was impossible to initialize SCSI port”);
CDDALogS(“SCSI Miniport Initilizated WRONG”);
}
CDDALogS(“SCSI Miniport Initilizated OK”);
////////////////////
//
// Create extension for the driverobject to store driver specific
// information. Device specific information should be stored in
// Device Extension
status = IoAllocateDriverObjectExtension(DriverObject,
CDDA_DRIVER_EXTENSION_KEY,
sizeof(CDDA_DRIVER_EXTENSION),
&driverExtension);
…
…
I suppose there is something wrong when ScsiPortInitialize is called because after that no other message is logged. The message “SCSI Miniport Entry” is logged at the beginning, but neither “SCSI Miniport Initilizated WRONG” nor “SCSI Miniport Initilizated OK”. It seems to be that after ScsiPortInitialize the execution doesn’t go on any longer or is stopped because there are no logs and some symbolic links are not created.
The following are the miniport routines I use:
BOOLEAN CDDAInitialize( IN PVOID DeviceExtension )
{
CDDALogS(“CDDAInitialize OUT.”);
return TRUE;
}
BOOLEAN CDDAResetBus( IN PVOID DeviceExtension, IN ULONG PathId )
{
CDDALogS(“CDDAResetBus OUT.”);
return TRUE;
}
SCSI_ADAPTER_CONTROL_STATUS CDDAAdapterControl(
IN PVOID DeviceExtension,
IN SCSI_ADAPTER_CONTROL_TYPE ControlType,
IN PVOID Parameters
)
{
DbgPrint(“AdapterControl(%d)\n”, ControlType);
CDDALogS(“CDDAAdapterControl IN.”);
switch (ControlType) {
case ScsiQuerySupportedControlTypes:
{
SCSI_SUPPORTED_CONTROL_TYPE_LIST* ssctl = (SCSI_SUPPORTED_CONTROL_TYPE_LIST*)Parameters;
ZeroMemory(ssctl->SupportedTypeList, ssctl->MaxControlType);
if (ScsiQuerySupportedControlTypes < ssctl->MaxControlType)
ssctl->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
if (ScsiStopAdapter < ssctl->MaxControlType)
ssctl->SupportedTypeList[ScsiStopAdapter] = TRUE;
if (ScsiRestartAdapter < ssctl->MaxControlType)
ssctl->SupportedTypeList[ScsiRestartAdapter] = TRUE;
}
// fall thru
CDDALogS(“CDDAAdapterControl OUT.”);
case ScsiStopAdapter:
case ScsiRestartAdapter:
return ScsiAdapterControlSuccess;
default:
return ScsiAdapterControlUnsuccessful;
}
}
ULONG CDDAFindAdapter(
IN PVOID DeviceExtension,
IN PVOID Context,
IN PVOID BusInformation,
IN PCHAR ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
OUT PBOOLEAN Again)
{
ConfigInfo->AdapterInterfaceType = Internal;
ConfigInfo->InitiatorBusId[0] = 31; // set SCSI ID in the port
ConfigInfo->MaximumTransferLength = 0x30000; // single transfer size
ConfigInfo->NumberOfPhysicalBreaks = 0x30;
ConfigInfo->NumberOfBuses = 1; // set number of served buses
ConfigInfo->MaximumNumberOfTargets = 1;
ConfigInfo->ScatterGather = FALSE; // fuck off scatter/gather
ConfigInfo->Master = FALSE; // NOT bus master
*Again = FALSE; // indicate to SCSI port in have not call this entry once more
CDDALogS(“CDDAFindAdapter OUT.”);
return SP_RETURN_FOUND; // adapter IS here in any way
}
BOOLEAN CDDAStartIo ( IN PVOID ipDeviceExtension, IN PSCSI_REQUEST_BLOCK ipSRB)
{
//PSPECIFIC_DEVICE_EXTENSION deviceExtension = ipDeviceExtension;
//PSPECIFIC_LU_EXTENSION luExtension;
// Determine the logical unit that this request is for.
//deviceExtension->PathId = ipSRB->PathId;
//luExtension = ScsiPortGetLogicalUnit(deviceExtension, deviceExtension->PathId,
// ipSRB->TargetId, ipSRB->Lun);
PINQUIRYDATA Inq;
PREAD_CAPACITY_DATA pCapacityRead;
PDEVICE_EXTENSION deviceExtension;
ULONG FixBlockEnd;
ULONG FixBlockSize;
PFOUR_BYTE pEnd;
PFOUR_BYTE pSize;
PCDROM_TOC pToc;
deviceExtension = (PDEVICE_EXTENSION) ipDeviceExtension;
pEnd = (PFOUR_BYTE)&FixBlockEnd;
pSize = (PFOUR_BYTE)&FixBlockSize;
switch( ipSRB->Function)
{
case SRB_FUNCTION_ABORT_COMMAND:
ipSRB->SrbStatus = SRB_STATUS_SUCCESS;
break;
case SRB_FUNCTION_RESET_BUS:
ipSRB->SrbStatus = SRB_STATUS_SUCCESS;
break;
case SRB_FUNCTION_EXECUTE_SCSI:
/*
luExtension->ActiveLuRequest = ipSRB;
luExtension->LuState = LS_COMPLETE;
luExtension->SavedDataPointer = (ULONG) ipSRB->DataBuffer;
luExtension->SavedDataLength = ipSRB->DataTransferLength;
*/
switch( ipSRB->Cdb[0])
{
//case SCSIOP_READ_CD_MSF:
// Get CD-ROM Inquiry Data
case (SCSIOP_INQUIRY):
// Setup the context for this target/lun.
memset(ipSRB->DataBuffer, 0, ipSRB->DataTransferLength);
Inq =(PINQUIRYDATA)(ipSRB->DataBuffer);
Inq->DeviceType = DIRECT_ACCESS_DEVICE;
Inq->DeviceTypeQualifier = DEVICE_CONNECTED;
memcpy(Inq->VendorId, “Valhalla”, sizeof Inq->VendorId);
memcpy(Inq->ProductId, “CDDA v1.0”, sizeof Inq->ProductId);
ipSRB->SrbStatus = SRB_STATUS_SUCCESS;
break;
// ReadCapacity: Hardwired data
case(SCSIOP_READ_CAPACITY):
memset(ipSRB->DataBuffer, 0, ipSRB->DataTransferLength);
pCapacityRead = (PREAD_CAPACITY_DATA) (ipSRB->DataBuffer);
FixBlockEnd = 270000;
FixBlockSize = 2048;
((PFOUR_BYTE)&(pCapacityRead->LogicalBlockAddress))->Byte3=
pEnd->Byte0;
((PFOUR_BYTE)&(pCapacityRead->LogicalBlockAddress))->Byte2=
pEnd->Byte1;
((PFOUR_BYTE)&(pCapacityRead->LogicalBlockAddress))->Byte1=
pEnd->Byte2;
((PFOUR_BYTE)&(pCapacityRead->LogicalBlockAddress))->Byte0=
pEnd->Byte3;
((PFOUR_BYTE)&(pCapacityRead->BytesPerBlock))->Byte3=
pSize->Byte0;
((PFOUR_BYTE)&(pCapacityRead->BytesPerBlock))->Byte2=
pSize->Byte1;
((PFOUR_BYTE)&(pCapacityRead->BytesPerBlock))->Byte2=
pSize->Byte2;
((PFOUR_BYTE)&(pCapacityRead->BytesPerBlock))->Byte0=
pSize->Byte3;
ipSRB->SrbStatus = SRB_STATUS_SUCCESS;
break;
// Read Cd-ROM
case SCSIOP_READ_CD:
//…
//return BIN file audio data
//if NT_SUCCESS(CDDAReadCDRom(deviceExtension, luExtension))
// ipSRB->SrbStatus = SRB_STATUS_SUCCESS;
//else
// ipSRB->SrbStatus = SRB_STATUS_ERROR;
//break;
case SCSIOP_READ_TOC:
memset(ipSRB->DataBuffer, 0, ipSRB->DataTransferLength);
pToc = (PCDROM_TOC) (ipSRB->DataBuffer);
CDDAFillAudioToc(pToc);
ipSRB->SrbStatus = SRB_STATUS_SUCCESS;
break;
case SCSIOP_READ_HEADER:
//…
case SCSIOP_TEST_UNIT_READY:
ipSRB->SrbStatus = SRB_STATUS_SUCCESS;
break;
// Invalid Scsi Op code
default:
ipSRB->SrbStatus = SRB_STATUS_SUCCESS;
break;
}
CDDALogS(“ipSRB->Cdb[0] OUT.”);
ScsiPortNotification(RequestComplete, (PVOID) ipDeviceExtension, ipSRB);
break;
default:
ipSRB->SrbStatus = SRB_STATUS_INVALID_REQUEST;
ScsiPortNotification(RequestComplete, (PVOID) ipDeviceExtension, ipSRB);
break;
}
// Adapter ready for next request.
CDDALogS(“CDDAStartIo OUT.”);
ScsiPortNotification(NextRequest, ipDeviceExtension, NULL);
return TRUE;
}
The last but not least, the INF file:
;/*++
;
;Module Name:
;
; CDDA.INF
;
;Abstract:
; INF file for installing CDDA Virtual SCSI Port Device Driver
;
;–*/
[Version]
Signature=“$WINDOWS NT$”
Class=ScsiAdapter
ClassGUID={4d36e97b-e325-11ce-bfc1-08002be10318}
Provider=%VLH%
DriverVer=08/07/2007,1.00.2183.1
[DestinationDirs]
DefaultDestDir = 12
[ClassInstall32]
Addreg=SampleClassReg
[SampleClassReg]
HKR,0,%ClassName%
[DiskCopyfiles]
CDDA.sys
[SourceDisksNames]
1=%InstDisk%,
[SourceDisksFiles]
CDDA.sys=1
[Manufacturer]
%VLH% = DiskDevice
[DiskDevice]
%DiskDevDesc% = DiskInstall, CDDA
[DiskInstall.NT]
CopyFiles = DiskCopyfiles
;-------------- Service installation
[DiskInstall.NT.Services]
AddService = CDDA, %SPSVCINST_ASSOCSERVICE%, DiskServiceInst
[DiskServiceInst]
DisplayName = %DiskServiceDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 1 ; SERVICE_SYSTEM_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\CDDA.sys
LoadOrderGroup = SCSI Miniport
AddReg = DiskAddReg
[DiskAddReg]
HKR, Parameters, ConnectInfo, 0x00001
HKR, Parameters, ConnectionsInRegistry, 0x10001, 1
HKR, “Parameters”, “BreakOnEntry”, %REG_DWORD%, 0x00000000
HKR, “Parameters”, “DebugLevel”, %REG_DWORD%, 0x00000000
HKR, “Parameters”, “DebugComp”, %REG_DWORD%, 0xFFFFFFFF
HKR, “Parameters”, “DriveLetter”, %REG_SZ%, “Y:”
[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
VLH = “Valhalla, Inc”
ClassName = “CDDA SCSI Port Driver”
InstDisk = “CDDA Virtual SCSI Port Device Driver Installation Disk #0”
DiskDevDesc = “CDDA SCSI”
DiskServiceDesc = “CDDA Virtual SCSI Port Device Driver”
REG_DWORD = 0x00010001
REG_SZ = 0x00000000
Any idea what’s the problem?
Thanks in advance.
Christian D’Orazio