// // Send Stop Ccb to the LURN. // NTSTATUS SendStopCcbToLurn( PLURELATION_NODE Lurn ) { PCCB ccb; NTSTATUS ntStatus; KDPrintM(DBG_LURN_TRACE,("entered.\n")); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); ntStatus = LSCcbAllocate(&ccb); if(!NT_SUCCESS(ntStatus)) { return STATUS_INSUFFICIENT_RESOURCES; } LSCCB_INITIALIZE(ccb, 0); ccb->OperationCode = CCB_OPCODE_STOP; ccb->HwDeviceExtension = NULL; LSCcbSetFlag(ccb, CCB_FLAG_SYNCHRONOUS|CCB_FLAG_ALLOCATED|CCB_FLAG_LOWER_LURN); LSCcbSetCompletionRoutine(ccb, NULL, NULL); // // Send a CCB to the LURN. // ntStatus = LurnRequest( Lurn, ccb ); if(!NT_SUCCESS(ntStatus)) { LSCcbFree(ccb); } return ntStatus; }
NTSTATUS RemoveDeviceFromMiniport( IN PMINIPORT_DEVICE_EXTENSION HwDeviceExtension, IN PMINIPORT_LU_EXTENSION LuExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CurSrbSequence ) { NDSC_WORKITEM_INIT WorkitemCtx; NTSTATUS status; PCCB Ccb; // // initilize Ccb in srb. // KDPrint(1, ("Entered.\n")); status = LSCcbAllocate(&Ccb); if(!NT_SUCCESS(status)) { KDPrint(1, ("failed.\n")); return status; } LSCcbInitialize( Srb, HwDeviceExtension, CurSrbSequence, Ccb ); InterlockedIncrement(&HwDeviceExtension->RequestExecuting); LsuIncrementTdiClientInProgress(); LSCcbSetCompletionRoutine(Ccb, NdscAdapterCompletion, HwDeviceExtension); LSCcbSetNextStackLocation(Ccb); // // Queue a workitem // NDSC_INIT_WORKITEM(&WorkitemCtx, RemoveDeviceFromMiniport_Worker, Ccb, LuExtension, NULL, HwDeviceExtension); status = MiniQueueWorkItem(&_NdscGlobals, HwDeviceExtension->ScsiportFdoObject, &WorkitemCtx); if(NT_SUCCESS(status)) { status = STATUS_PENDING; } return status; }
NTSTATUS MiniSrbControl( IN PMINIPORT_DEVICE_EXTENSION HwDeviceExtension, IN PMINIPORT_LU_EXTENSION LuExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CurSrbSequence ) /*++ Routine Description: This is the SRB_IO_CONTROL handler for this driver. These requests come from the management driver. Arguments: DeviceExtension - Context Srb - The request to process. Return Value: Value from the helper routines, or if handled in-line, SUCCESS or INVALID_REQUEST. --*/ { PSRB_IO_CONTROL srbIoControl; PUCHAR srbIoctlBuffer; LONG srbIoctlBufferLength; ULONG controlCode; ULONG transferPages = 0; NTSTATUS status; UCHAR srbStatus; // // Start off being paranoid. // if (Srb->DataBuffer == NULL) { KDPrint(1,("DataBuffer is NULL\n")); Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST; return STATUS_INVALID_PARAMETER; } status = STATUS_MORE_PROCESSING_REQUIRED; srbStatus = SRB_STATUS_SUCCESS; // // Extract the io_control // srbIoControl = (PSRB_IO_CONTROL)Srb->DataBuffer; // // Ensure the signature is correct. // if (strncmp(srbIoControl->Signature, LANSCSIMINIPORT_IOCTL_SIGNATURE, 8) != 0) { KDPrint(1,("Signature mismatch %8s, %8s\n", srbIoControl->Signature, LANSCSIMINIPORT_IOCTL_SIGNATURE)); Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST; return STATUS_INVALID_PARAMETER; } // // Get the control code. // controlCode = srbIoControl->ControlCode; // // Get the Ioctl buffer. If this is a send message request, it gets // fixed up to be an I2O message later. // srbIoctlBuffer = ((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL); srbIoctlBufferLength = srbIoControl->Length; // // Based on the control code, figure out what to do. // switch (controlCode) { case LANSCSIMINIPORT_IOCTL_GET_DVD_STATUS: { srbStatus = SrbIoctlGetDVDSTatus( HwDeviceExtension, LuExtension, srbIoctlBufferLength, srbIoctlBuffer, &srbIoControl->ReturnCode, CurSrbSequence ); if(srbStatus == SRB_STATUS_SUCCESS) { KDPrint(4,("LANSCSIMINIPORT_IOCTL_QUERYINFO_EX: Successful.\n")); status = STATUS_SUCCESS; } else { status = STATUS_UNSUCCESSFUL; } } break; case LANSCSIMINIPORT_IOCTL_GET_SLOT_NO: KDPrint(2,("Get Slot No. Slot number is %d\n", HwDeviceExtension->SlotNumber)); *(PULONG)srbIoctlBuffer = HwDeviceExtension->SlotNumber; srbIoControl->ReturnCode = 0; srbStatus = SRB_STATUS_SUCCESS; status = STATUS_SUCCESS; break; case LANSCSIMINIPORT_IOCTL_QUERYINFO_EX: { PLSMPIOCTL_QUERYINFO QueryInfo; PUCHAR tmpBuffer; KDPrint(5, ("Query information EX.\n")); QueryInfo = (PLSMPIOCTL_QUERYINFO)srbIoctlBuffer; tmpBuffer = ExAllocatePoolWithTag(NonPagedPool, srbIoctlBufferLength, LSMP_PTAG_IOCTL); if(tmpBuffer == NULL) { ASSERT(FALSE); KDPrint(1,("LANSCSIMINIPORT_IOCTL_QUERYINFO_EX: SRB_STATUS_DATA_OVERRUN. BufferLength:%d\n", srbIoctlBufferLength)); srbStatus = SRB_STATUS_DATA_OVERRUN; break; } srbStatus = SrbIoctlQueryInfo( HwDeviceExtension, LuExtension, QueryInfo, srbIoctlBufferLength, tmpBuffer, &srbIoControl->ReturnCode, CurSrbSequence ); if(srbStatus == SRB_STATUS_SUCCESS) { KDPrint(4,("LANSCSIMINIPORT_IOCTL_QUERYINFO_EX: Successful.\n")); RtlCopyMemory(srbIoctlBuffer, tmpBuffer, srbIoctlBufferLength); status = STATUS_SUCCESS; } else { status = STATUS_UNSUCCESSFUL; } ExFreePoolWithTag(tmpBuffer, LSMP_PTAG_IOCTL); break; } case LANSCSIMINIPORT_IOCTL_UPGRADETOWRITE: { PLURN_UPDATE LurnUpdate; PCCB Ccb; // // Set a CCB // status = LSCcbAllocate(&Ccb); if(!NT_SUCCESS(status)) { srbStatus = SRB_STATUS_INVALID_REQUEST; KDPrint(1,("LANSCSIMINIPORT_IOCTL_UPGRADETOWRITE: LSCcbAllocate() failed.\n")); break; } LurnUpdate = (PLURN_UPDATE)ExAllocatePoolWithTag(NonPagedPool, sizeof(LURN_UPDATE), LSMP_PTAG_IOCTL); if(!LurnUpdate) { srbStatus = SRB_STATUS_INVALID_REQUEST; KDPrint(1,("LANSCSIMINIPORT_IOCTL_UPGRADETOWRITE: ExAllocatePoolWithTag() failed.\n")); status = STATUS_INSUFFICIENT_RESOURCES; break; } LSCCB_INITIALIZE(Ccb, CurSrbSequence); Ccb->OperationCode = CCB_OPCODE_UPDATE; Ccb->DataBuffer = LurnUpdate; Ccb->DataBufferLength = sizeof(LURN_UPDATE); LSCcbSetFlag(Ccb, CCB_FLAG_ALLOCATED|CCB_FLAG_DATABUF_ALLOCATED); // Ioctl Srb will complete asynchronously. Ccb->Srb = Srb; InterlockedIncrement(&HwDeviceExtension->RequestExecuting); LsuIncrementTdiClientInProgress(); LSCcbSetCompletionRoutine(Ccb, NdscAdapterCompletion, HwDeviceExtension); LurnUpdate->UpdateClass = LURN_UPDATECLASS_WRITEACCESS_USERID; KDPrint(3,("LANSCSIMINIPORT_IOCTL_UPGRADETOWRITE: going to default LuExtention 0.\n")); status = LurRequest( HwDeviceExtension->LURs[0], // default: 0. Ccb ); if(!NT_SUCCESS(status)) { KDPrint(1,("LANSCSIMINIPORT_IOCTL_UPGRADETOWRITE: LurnRequest() failed.\n")); NDScsiLogError( HwDeviceExtension, Srb, Srb->PathId, Srb->TargetId, Srb->Lun, NDASSCSI_IO_UPGRADEIOCTL_FAIL, EVTLOG_UNIQUEID(EVTLOG_MODULE_IOCTL, EVTLOG_FAIL_UPGRADEIOCTL, 0) ); LSCcbFree(Ccb); ExFreePoolWithTag(LurnUpdate, LSMP_PTAG_IOCTL); status = STATUS_SUCCESS; srbStatus = SRB_STATUS_INVALID_REQUEST; } else { status = STATUS_PENDING; } break; } case LANSCSIMINIPORT_IOCTL_ADD_TARGET: { PLANSCSI_ADD_TARGET_DATA AddTargetData; PLURELATION_DESC LurDesc; LONG LurDescLength; LONG LurnCnt; AddTargetData = (PLANSCSI_ADD_TARGET_DATA)srbIoctlBuffer; LurnCnt = AddTargetData->ulNumberOfUnitDiskList; LurDescLength = sizeof(LURELATION_DESC) + // LURELATION_DESC (sizeof(LURELATION_NODE_DESC) + sizeof(LONG) * (LurnCnt-1)) * // LURELATION_NODE_DESC (LurnCnt - 1); // // Allocate LUR Descriptor // It will be freed in the worker routine. // LurDesc = (PLURELATION_DESC)ExAllocatePoolWithTag(NonPagedPool, LurDescLength, LSMP_PTAG_IOCTL); if(LurDesc == NULL) { srbStatus = SRB_STATUS_ERROR; status = STATUS_SUCCESS; break; } // Pass Adapter max request block as LUR max request blocks status = LurTranslateAddTargetDataToLURDesc( AddTargetData, HwDeviceExtension->AdapterMaxBlocksPerRequest, LurDescLength, LurDesc ); if(NT_SUCCESS(status)) { ASSERT(LurDescLength>0); status = AddNewDeviceToMiniport(HwDeviceExtension, LuExtension, Srb, CurSrbSequence, LurDesc); } } case LANSCSIMINIPORT_IOCTL_ADD_DEVICE: { PLURELATION_DESC LurDesc; LurDesc = (PLURELATION_DESC)srbIoctlBuffer; status = AddNewDeviceToMiniport(HwDeviceExtension, LuExtension, Srb, CurSrbSequence, LurDesc); break; } case LANSCSIMINIPORT_IOCTL_REMOVE_DEVICE: { status = RemoveDeviceFromMiniport(HwDeviceExtension, LuExtension, Srb, CurSrbSequence); break; } case LANSCSIMINIPORT_IOCTL_REMOVE_TARGET: { PLANSCSI_REMOVE_TARGET_DATA RemoveTargetData; RemoveTargetData = (PLANSCSI_REMOVE_TARGET_DATA)srbIoctlBuffer; status = RemoveDeviceFromMiniport(HwDeviceExtension, NULL, Srb, CurSrbSequence); break; } case LANSCSIMINIPORT_IOCTL_NOOP: { PCCB Ccb; // // Query to the LUR // status = LSCcbAllocate(&Ccb); if(!NT_SUCCESS(status)) { srbStatus = SRB_STATUS_ERROR; status = STATUS_SUCCESS; KDPrint(1,("LSCcbAllocate() failed.\n")); break; } LSCCB_INITIALIZE(Ccb, CurSrbSequence); Ccb->OperationCode = CCB_OPCODE_NOOP; LSCcbSetFlag(Ccb, CCB_FLAG_ALLOCATED); Ccb->Srb = Srb; LSCcbSetCompletionRoutine(Ccb, NdscAdapterCompletion, HwDeviceExtension); KDPrint(3,("going to default LuExtention 0.\n")); InterlockedIncrement(&HwDeviceExtension->RequestExecuting); LsuIncrementTdiClientInProgress(); status = LurRequest( HwDeviceExtension->LURs[0], // default: 0. Ccb ); if(!NT_SUCCESS(status)) { srbStatus = SRB_STATUS_ERROR; status = STATUS_SUCCESS; KDPrint(1,("LurRequest() failed.\n")); break; } srbStatus = SRB_STATUS_SUCCESS; status = STATUS_PENDING; break; } case LANSCSIMINIPORT_IOCTL_GET_VERSION: { PLSMPIOCTL_DRVVER version = (PLSMPIOCTL_DRVVER)srbIoctlBuffer; version->VersionMajor = VER_FILEMAJORVERSION; version->VersionMinor = VER_FILEMINORVERSION; version->VersionBuild = VER_FILEBUILD; version->VersionPrivate = VER_FILEBUILD_QFE; srbStatus = SRB_STATUS_SUCCESS; status = STATUS_SUCCESS; break; } default: KDPrint(2,("Control Code (%x)\n", controlCode)); srbStatus = SRB_STATUS_INVALID_REQUEST; status = STATUS_MORE_PROCESSING_REQUIRED; } Srb->SrbStatus = srbStatus; return status; }