예제 #1
0
파일: lslurn.c 프로젝트: yzx65/ndas4windows
//
//	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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}