示例#1
0
VOID
RamDiskEvtIoWrite(
    IN WDFQUEUE Queue,
    IN WDFREQUEST Request,
    IN size_t Length
    )

/*++

Routine Description:

    This event is invoked when the framework receives IRP_MJ_WRITE request.

Arguments:

    Queue -  Handle to the framework queue object that is associated with the
             I/O request.

    Request - Handle to a framework request object.

    Length - Length of the data buffer associated with the request.
             The default property of the queue is to not dispatch
             zero length read & write requests to the driver and
             complete is with status success. So we will never get
             a zero length request.

Return Value:

    VOID

--*/
{
    PDEVICE_EXTENSION      devExt = QueueGetExtension(Queue)->DeviceExtension;
    NTSTATUS               Status = STATUS_INVALID_PARAMETER;
    WDF_REQUEST_PARAMETERS Parameters;
    LARGE_INTEGER          ByteOffset;
    WDFMEMORY              hMemory;

    _Analysis_assume_(Length > 0);

    WDF_REQUEST_PARAMETERS_INIT(&Parameters);
    WdfRequestGetParameters(Request, &Parameters);

    ByteOffset.QuadPart = Parameters.Parameters.Write.DeviceOffset;

    if (RamDiskCheckParameters(devExt, ByteOffset, Length)) {

        Status = WdfRequestRetrieveInputMemory(Request, &hMemory);
        if(NT_SUCCESS(Status)){

            Status = WdfMemoryCopyToBuffer(hMemory, // Source
                                    0,              // offset in Source memory where the copy has to start
                                    devExt->DiskImage + ByteOffset.LowPart, // destination
                                    Length);
        }

    }

    WdfRequestCompleteWithInformation(Request, Status, (ULONG_PTR)Length);
}
NTSTATUS
DeviceContext::CommandNciRead(
    _In_ WDFREQUEST Request
    )
{
    TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
    NTSTATUS status;

    WDFMEMORY nciPacket;
    status = WdfRequestRetrieveInputMemory(Request, &nciPacket);
    if (!NT_SUCCESS(status))
    {
        TRACE_LINE(LEVEL_ERROR, "WdfRequestRetrieveInputMemory failed. %!STATUS!", status);
        return status;
    }

    status = NfcCxNciReadNotification(_Device, nciPacket);
    if (!NT_SUCCESS(status))
    {
        TRACE_LINE(LEVEL_ERROR, "NfcCxNciReadNotification failed. %!STATUS!", status);
        return status;
    }

    WdfRequestComplete(Request, STATUS_SUCCESS);

    TRACE_FUNCTION_SUCCESS(LEVEL_VERBOSE);
    return STATUS_SUCCESS;
}
示例#3
0
// 写操作
VOID RamDiskEvtIoWrite(IN WDFQUEUE Queue,IN WDFREQUEST Request,IN size_t Length)
{
    PDEVICE_EXTENSION      devExt = QueueGetExtension(Queue)->DeviceExtension;
    //从队列对象获得设备扩展
    NTSTATUS               Status = STATUS_INVALID_PARAMETER;
    WDF_REQUEST_PARAMETERS Parameters;
    LARGE_INTEGER          ByteOffset;
    WDFMEMORY              hMemory;

    //__analysis_assume(Length > 0);
    //参数清0
    WDF_REQUEST_PARAMETERS_INIT(&Parameters);
    //从请求中获取信息
    WdfRequestGetParameters(Request, &Parameters);
    //写入偏移
    ByteOffset.QuadPart = Parameters.Parameters.Write.DeviceOffset;
    //检测写入是否合法
    if (RamDiskCheckParameters(devExt, ByteOffset, Length))
    {
        // from output to input
        Status = WdfRequestRetrieveInputMemory(Request, &hMemory);
        //获得内存状态
        if(NT_SUCCESS(Status))
        {
            // Source # offset in Source memory where the copy has to start # destination
            Status = WdfMemoryCopyToBuffer(hMemory, 0,devExt->DiskImage + ByteOffset.LowPart, Length);
            // from "from" to "to"
        }

    }

    WdfRequestCompleteWithInformation(Request, Status, (ULONG_PTR)Length);
}
示例#4
0
NTSTATUS GetTransferMemory(__in WDFREQUEST Request,
                           __in WDF_REQUEST_TYPE RequestType,
                           __out WDFMEMORY* wdfMemory)
{
    return (RequestType == WdfRequestTypeWrite)
           ? WdfRequestRetrieveInputMemory(Request, wdfMemory)
           : WdfRequestRetrieveOutputMemory(Request, wdfMemory);
}
// Bulk管道写操作
//
VOID BulkWrite(IN WDFQUEUE  Queue, IN WDFREQUEST  Request, IN size_t  Length)
{
	NTSTATUS status = STATUS_SUCCESS;
	WDFMEMORY hMem = NULL;
	WDFDEVICE hDevice = NULL;
	WDFUSBPIPE BulkOutputPipe = NULL;
	UCHAR* lpBuf;

	UNREFERENCED_PARAMETER(Length);

	KDBG(DPFLTR_INFO_LEVEL, "[BulkWrite] size: %d", Length);

	// 获取管道句柄
	hDevice = WdfIoQueueGetDevice(Queue);
	BulkOutputPipe = GetBulkPipe(FALSE, hDevice);

	if(NULL == BulkOutputPipe)
	{
		KDBG(DPFLTR_ERROR_LEVEL, "BulkOutputPipe = NULL");
		WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
		return;
	}

	status = WdfRequestRetrieveInputMemory(Request, &hMem);
	if(!NT_SUCCESS(status))
	{
		KDBG(DPFLTR_ERROR_LEVEL, "WdfRequestRetrieveInputMemory failed(status = 0x%0.8x)!!!", status);
		WdfRequestComplete(Request, status);
		return;
	}

	// 打印出offset值。
	// 在写缓冲的前两个字节中存有write offset的值
	lpBuf = (UCHAR*)WdfMemoryGetBuffer(hMem, 0);
	KDBG(DPFLTR_TRACE_LEVEL, "write offset: %hd", *(WORD*)lpBuf);

	// 把当前的Request对象进行重利用,发送给USB总线。
	// 格式化Request对象,设置Pipe句柄、完成函数等。
	status = WdfUsbTargetPipeFormatRequestForWrite(BulkOutputPipe, Request, hMem, NULL);
	if(!NT_SUCCESS(status))
	{
		KDBG(DPFLTR_ERROR_LEVEL, "WdfUsbTargetPipeFormatRequestForWrite(status 0x%0.8x)!!!", status);
		WdfRequestComplete(Request, status);
		return;
	}

	WdfRequestSetCompletionRoutine(Request, BulkWriteComplete, BulkOutputPipe); 
	if(FALSE == WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(BulkOutputPipe), NULL))
	{
		status = WdfRequestGetStatus(Request);
		KDBG(DPFLTR_ERROR_LEVEL, "WdfRequestSend failed with status 0x%0.8x\n", status);		
		WdfRequestComplete(Request, status);
	}
}
示例#6
0
VOID
EvtIoWrite(
    IN WDFQUEUE         Queue,
    IN WDFREQUEST       Request,
    IN size_t           Length
    )
{
    NTSTATUS                    status;
    WDFUSBPIPE                  pipe;
    WDFMEMORY                   reqMemory;
    PDEVICE_CONTEXT             pDeviceContext;
    BOOLEAN                     ret;

    UNREFERENCED_PARAMETER(Length);

    pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

    pipe = pDeviceContext->BulkWritePipe;

    status = WdfRequestRetrieveInputMemory(Request, &reqMemory);
    if(!NT_SUCCESS(status)){
        goto Exit;
    }

    status = WdfUsbTargetPipeFormatRequestForWrite(pipe,
                                              Request,
                                              reqMemory,
                                              NULL); // Offset
    if (!NT_SUCCESS(status)) {
        goto Exit;
    }

    WdfRequestSetCompletionRoutine(
                            Request,
                            EvtRequestWriteCompletionRoutine,
                            pipe);

    ret = WdfRequestSend(Request,
                    WdfUsbTargetPipeGetIoTarget(pipe),
                    WDF_NO_SEND_OPTIONS);
    if (ret == FALSE) {
        status = WdfRequestGetStatus(Request);
        goto Exit;
    } else {
        return;
    }

Exit:
    WdfRequestCompleteWithInformation(Request, status, 0);

    return;
}
示例#7
0
文件: write.c 项目: npalix/rathaxes
VOID
EvtIoWrite(
    IN WDFQUEUE         Queue,
    IN WDFREQUEST       Request,
    IN size_t           Length
    )
{
	WDFMEMORY					memory;
	NTSTATUS					status;
	PMY_SERIAL_DEVICE_EXTENSION	pContext;
	PUCHAR						buffer;
	size_t						buf_size;
	size_t						i = 0;

	KdPrint((DRIVER_NAME "-->EvtIoWrite\n"));
	pContext = MySerialGetDeviceExtension(WdfIoQueueGetDevice(Queue));
	status = WdfRequestRetrieveInputMemory(Request, &memory);
	if(!NT_SUCCESS(status))
	{
        KdPrint((DRIVER_NAME "EvtIoWrite Could not get request memory buffer 0x%x\n",
                 status));
        WdfRequestComplete(Request, status);
		KdPrint((DRIVER_NAME "<-- EvtDeviceIoWrite\n"));
        return;
    }
	buffer = WdfMemoryGetBuffer(memory, &buf_size);
	KdPrint((DRIVER_NAME "Sending a buffer of %d bytes\n", buf_size));
	while (i < buf_size)
	{
		while (UartGetBit(pContext, LSR, LSR_ETHR) == 0 ) {}
		UartWriteByte(pContext, buffer[i]);
		i++;
	}
	WdfRequestCompleteWithInformation(Request, status, i);
	KdPrint((DRIVER_NAME "<--EvtIoWrite\n"));
}
示例#8
0
VOID 
tgwinkEvtIoWrite(
    WDFQUEUE Queue,
    WDFREQUEST Request,
    size_t Length
    )
{
    NTSTATUS status;
    WDFMEMORY mem;
    WDF_REQUEST_PARAMETERS params;
    ULONG offset;
    ULONG result;
    PDEVICE_CONTEXT context;
    WDFDEVICE device;
    
    device = WdfIoQueueGetDevice(Queue);
    context = DeviceGetContext(device);

    WDF_REQUEST_PARAMETERS_INIT(&params);

    WdfRequestGetParameters(Request, &params);

    offset = (ULONG)params.Parameters.Write.DeviceOffset;
    
    status = WdfRequestRetrieveInputMemory(Request, &mem);
    if (!NT_SUCCESS(status)) {
        KdPrint("tgwinkEvtIoRead could not get request memory buffer, status 0x%x\n", status);
        WdfVerifierDbgBreakPoint();
        WdfRequestCompleteWithInformation(Request, status, 0);
        return;
    }

    result = context->busInterface.SetBusData(context->busInterface.Context, PCI_WHICHSPACE_CONFIG, WdfMemoryGetBuffer(mem, NULL), offset, (ULONG)Length);

    WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, (ULONG_PTR)result);
}
示例#9
0
/*++
Routine Description:

This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
requests from the system.

Arguments:

Queue - Handle to the framework queue object that is associated
with the I/O request.
Request - Handle to a framework request object.

OutputBufferLength - length of the request's output buffer,
if an output buffer is available.
InputBufferLength - length of the request's input buffer,
if an input buffer is available.

IoControlCode - the driver-defined or system-defined I/O control code
(IOCTL) that is associated with the request.
Return Value:

VOID
--*/
VOID PSDrv_EvtIoDeviceControl(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode)
{
    WDFDEVICE					 device;
    PVOID						 ioBuffer;
    size_t						 bufLength;
    NTSTATUS					 status;
    PDEVICE_CONTEXT				 pDevContext;
    PFILE_CONTEXT				 pFileContext;
    ULONG						 length = 0;
	PSUSBDRV_PIPE_PROPERTY*		 pPipeProp;
	PSUSBDRV_CONTROL_TRANSFER*	 pControlTransfer;
	PSUSBDRV_DRIVER_VERSION*	 pDriverVersion;
	PSUSBDRV_INTERFACE_PROPERTY* pInterfaceProperty;
	unsigned int*				 pnDeviceSpeed;
	WDFMEMORY					 WdfMem = NULL; 
	PUCHAR                       pControlBuffer;
	WDFMEMORY					 WdfMemOut = NULL;

	
	WDF_USB_INTERFACE_SELECT_SETTING_PARAMS  selectSettingParams;

    UNREFERENCED_PARAMETER(InputBufferLength);

    PSDrv_DbgPrint(3, ("PSDrv_EvtIoDeviceControl - begins\n"));

    PAGED_CODE();

    // initialize variables
    device = WdfIoQueueGetDevice(Queue);
    pDevContext = GetDeviceContext(device);

    switch(IoControlCode)
	{
		case IOCTL_PSDRV_RESET_PIPE:
			PSDrv_DbgPrint(3, ("IOControl: ResetPipe\n"));

			pFileContext = GetFileContext(WdfRequestGetFileObject(Request));

			if (pFileContext->Pipe == NULL)
			{
				PSDrv_DbgPrint(3, ("Invalid pipe!\n"));
				status = STATUS_INVALID_PARAMETER;
			}
			else
			{
				status = ResetPipe(pFileContext->Pipe);
			}

			break;

		case IOCTL_PSDRV_ABORT_PIPE:
			PSDrv_DbgPrint(3, ("IOControl: AbortPipe\n"));

			pFileContext = GetFileContext(WdfRequestGetFileObject(Request));

			if (pFileContext->Pipe == NULL)
			{
				PSDrv_DbgPrint(3, ("Invalid pipe!\n"));
				status = STATUS_INVALID_PARAMETER;
			}
			else
			{
				status = AbortPipe(pFileContext->Pipe);
			}

			break;

		case IOCTL_PSDRV_GET_CONFIG_DESCRIPTOR:
			PSDrv_DbgPrint(3, ("IOControl: GetConfigDescriptor\n"));

			if (pDevContext->UsbConfigurationDescriptor)
			{
				length = pDevContext->UsbConfigurationDescriptor->wTotalLength;

				status = WdfRequestRetrieveOutputBuffer(Request, length, &ioBuffer, &bufLength);
				if(!NT_SUCCESS(status))
				{
					PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status));
					status = STATUS_INVALID_PARAMETER;
					break;
				}

				RtlCopyMemory(ioBuffer, pDevContext->UsbConfigurationDescriptor, length);

				status = STATUS_SUCCESS;
			}
			else
			{
				PSDrv_DbgPrint(3, ("UsbConfigurationDescriptor is NULL!\n"));
				status = STATUS_INVALID_DEVICE_STATE;
			}

			break;

		case IOCTL_PSDRV_RESET_DEVICE:
			PSDrv_DbgPrint(3, ("IOControl: ResetDevice\n"));

			status = ResetDevice(device);

			break;

		case IOCTL_PSDRV_CONTROL_TRANSFER:
			PSDrv_DbgPrint(3, ("IOControl: ControlTransfer\n"));

			//Get a pointer to the input buffer
			status = WdfRequestRetrieveInputMemory(Request, &WdfMem);
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputMemory failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			if (WdfMem == NULL)
			{
				PSDrv_DbgPrint(1, ("WdfMem is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pControlTransfer = WdfMemoryGetBuffer(WdfMem, NULL);
			if (pControlTransfer == NULL)
			{
				PSDrv_DbgPrint(1, ("pControlTransfer is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			//Get a pointer to the output buffer
			if (OutputBufferLength != 0)
			{
				status = WdfRequestRetrieveOutputMemory(Request, &WdfMemOut);
				if(!NT_SUCCESS(status))
				{
					PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputMemory failed! (Status = %x)\n", status));
					status = STATUS_INVALID_PARAMETER;
					break;
				}

				if (WdfMemOut == NULL)
				{
					PSDrv_DbgPrint(1, ("WdfMemOut is NULL!\n"));
					status = STATUS_INVALID_PARAMETER;
					break;
				}

				pControlBuffer = WdfMemoryGetBuffer(WdfMemOut, NULL);
				if (pControlBuffer == NULL)
				{
					PSDrv_DbgPrint(1, ("pControlBuffer is NULL!\n"));
					status = STATUS_INVALID_PARAMETER;
					break;
				}
			}
			else
			{
				PSDrv_DbgPrint(1, ("This control request has no buffer...\n"));
				pControlBuffer = NULL;
			}

			// Call the control transfer function
			status = ControlTransfer(pDevContext, pControlTransfer, pControlBuffer, OutputBufferLength, &length);

			break;

		case IOCTL_PSDRV_SET_PIPE_PROPERTY:
			PSDrv_DbgPrint(3, ("IOControl: SetPipeProperty\n"));

			status = WdfRequestRetrieveInputMemory(Request, &WdfMem); 
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputMemory failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			if (WdfMem == NULL)
			{
				PSDrv_DbgPrint(1, ("WdfMem is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pPipeProp = WdfMemoryGetBuffer(WdfMem, NULL);
			if (pPipeProp == NULL)
			{
				PSDrv_DbgPrint(1, ("pPipeProp is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pFileContext = GetFileContext(WdfRequestGetFileObject(Request));
			if (pFileContext->Pipe == NULL)
			{
				PSDrv_DbgPrint(3, ("Invalid pipe!\n"));
				status = STATUS_INVALID_PARAMETER;
			}
			else
			{
				status = SetPipeProperty(pFileContext, pPipeProp);
			}

			break;

		case IOCTL_PSDRV_SET_INTERFACE:
			PSDrv_DbgPrint(3, ("IOControl: SetInterface\n"));

			status = WdfRequestRetrieveInputMemory(Request, &WdfMem); 
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputMemory failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			if (WdfMem == NULL)
			{
				PSDrv_DbgPrint(1, ("WdfMem is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pInterfaceProperty = WdfMemoryGetBuffer(WdfMem, NULL);
			if (pInterfaceProperty == NULL)
			{
				PSDrv_DbgPrint(1, ("pInterfaceProperty is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			PSDrv_DbgPrint(3, ("SetInterface: Going to change AltIF to %d...\n", pInterfaceProperty->nAltIF));

			WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING(&selectSettingParams, pInterfaceProperty->nAltIF);

			status = WdfUsbInterfaceSelectSetting(pDevContext->UsbInterface, WDF_NO_OBJECT_ATTRIBUTES, &selectSettingParams);

			if (status == STATUS_SUCCESS)
			{
				pDevContext->nCurrIf = 0;
				pDevContext->nCurrAltIf = pInterfaceProperty->nAltIF;

				PSDrv_DbgPrint(3, ("SetInterface: AltIF is now %d...\n", pInterfaceProperty->nAltIF));
			}

			break;

		case IOCTL_PSDRV_GET_INTERFACE:
			PSDrv_DbgPrint(3, ("IOControl: GetInterface\n"));

			length = sizeof(PSUSBDRV_INTERFACE_PROPERTY);

			status = WdfRequestRetrieveOutputBuffer(Request, length, &pInterfaceProperty, &bufLength);
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pInterfaceProperty->nIF = pDevContext->nCurrIf;
			pInterfaceProperty->nAltIF = pDevContext->nCurrAltIf;

			status = STATUS_SUCCESS;

			break;

		case IOCTL_PSDRV_GET_DRIVER_VERSION:
			PSDrv_DbgPrint(3, ("IOControl: GetDriverVersion\n"));

			length = sizeof(PSUSBDRV_DRIVER_VERSION);

			status = WdfRequestRetrieveOutputBuffer(Request, length, &pDriverVersion, &bufLength);
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pDriverVersion->nMajor = PSUSBDRV_MAJOR_VERSION;
			pDriverVersion->nMinor = PSUSBDRV_MINOR_VERSION;
			pDriverVersion->nMaintenance = PSUSBDRV_MAINTENANCE_VERSION;
			pDriverVersion->nBuild = PSUSBDRV_BUILD_VERSION;
			
			status = STATUS_SUCCESS;

			break;

		case IOCTL_PSDRV_GET_DEVICE_SPEED:
			PSDrv_DbgPrint(3, ("IOControl: GetDeviceSpeed\n"));

			length = sizeof(unsigned int);

			status = WdfRequestRetrieveOutputBuffer(Request, length, &pnDeviceSpeed, &bufLength);
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			if (pDevContext->IsDeviceHighSpeed == TRUE)
			{
				*pnDeviceSpeed = PSUSBDRV_DEVICE_HIGH_SPEED;
			}
			else
			{
				*pnDeviceSpeed = PSUSBDRV_DEVICE_FULL_SPEED;
			}

			break;

		default:
			PSDrv_DbgPrint(3, ("Unknown IOControl! (ControlCode = %x)\n", IoControlCode));

			status = STATUS_INVALID_DEVICE_REQUEST;

			break;
    }

    WdfRequestCompleteWithInformation(Request, status, length);

	PSDrv_DbgPrint(3, ("PSDrv_EvtIoDeviceControl - ends\n"));

    return;
}
示例#10
0
VOID 
OsrFxEvtIoWrite(
    _In_ WDFQUEUE         Queue,
    _In_ WDFREQUEST       Request,
    _In_ size_t           Length
    ) 
/*++

Routine Description:

    Called by the framework when it receives Read or Write requests.

Arguments:

    Queue - Default queue handle
    Request - Handle to the read/write request
    Lenght - Length of the data buffer associated with the request.
                 The default property of the queue is to not dispatch
                 zero lenght read & write requests to the driver and
                 complete is with status success. So we will never get
                 a zero length request.

Return Value:


--*/
{
    NTSTATUS                    status;
    WDFUSBPIPE                  pipe;
    WDFMEMORY                   reqMemory;
    PDEVICE_CONTEXT             pDeviceContext;
    GUID                        activity = RequestToActivityId(Request);

    UNREFERENCED_PARAMETER(Queue);


    // 
    // Log write start event, using IRP activity ID if available or request
    // handle otherwise.
    //
    EventWriteWriteStart(&activity, WdfIoQueueGetDevice(Queue), (ULONG)Length);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "-->OsrFxEvtIoWrite\n");

    //
    // First validate input parameters.
    //
    if (Length > TEST_BOARD_TRANSFER_BUFFER_SIZE) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "Transfer exceeds %d\n",
                            TEST_BOARD_TRANSFER_BUFFER_SIZE);
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

    pipe = pDeviceContext->BulkWritePipe;

    status = WdfRequestRetrieveInputMemory(Request, &reqMemory);
    if(!NT_SUCCESS(status)){
        TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfRequestRetrieveInputBuffer failed\n");
        goto Exit;
    }

    status = WdfUsbTargetPipeFormatRequestForWrite(pipe,
                            Request,
                            reqMemory,
                            NULL); // Offset


    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                    "WdfUsbTargetPipeFormatRequest failed 0x%x\n", status);
        goto Exit;
    }

    WdfRequestSetCompletionRoutine(
                            Request,
                            EvtRequestWriteCompletionRoutine,
                            pipe);

    //
    // Send the request asynchronously.
    //
    if (WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS) == FALSE) {
        //
        // Framework couldn't send the request for some reason.
        //
        TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfRequestSend failed\n");
        status = WdfRequestGetStatus(Request);
        goto Exit;
    }

Exit:

    if (!NT_SUCCESS(status)) {
        //
        // log event write failed
        //
        EventWriteWriteFail(&activity, WdfIoQueueGetDevice(Queue), status);

        WdfRequestCompleteWithInformation(Request, status, 0);
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- OsrFxEvtIoWrite\n");

    return;
}
示例#11
0
///////////////////////////////////////////////////////////////////////////////
//
//  BasicUsbEvtDeviceControl
//
//    This routine is called by the framework when there is a
//    device control request for us to process
//
//  INPUTS:
//
//      Queue    - Our default queue
//
//      Request  - A device control request
//
//      OutputBufferLength - The length of the output buffer
//
//      InputBufferLength  - The length of the input buffer
//
//      IoControlCode      - The operation being performed
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//      This routine is called at IRQL == PASSIVE_LEVEL, due to
//      our PASSIVE_LEVEL execution level contraint
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID
BasicUsbEvtDeviceControl(WDFQUEUE Queue,
            WDFREQUEST Request,
            size_t OutputBufferLength,
            size_t InputBufferLength,
            ULONG IoControlCode)
{

    NTSTATUS                     status;
    WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket;
    WDFMEMORY                    inputMemory;
    WDF_MEMORY_DESCRIPTOR        inputMemoryDescriptor;
    PBASICUSB_DEVICE_CONTEXT     devContext;
   
#if DBG
    DbgPrint("BasicUsbEvtDeviceControl\n");
#endif

    devContext = BasicUsbGetContextFromDevice(
                                WdfIoQueueGetDevice(Queue) );

    switch (IoControlCode) {
        case IOCTL_OSR_BASICUSB_SET_BAR_GRAPH: {

            //
            // Validate the buffers for this request:
            //
            // OutputBufferLength - Must be zero
            //
            if (OutputBufferLength != 0) {
#if DBG
                DbgPrint("Invalid parameter - output buffer supplied in "\
                         "SET_BAR_GRAPH IOCTL (%u bytes)\n",
                         (ULONG)OutputBufferLength);
#endif
                WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
                return;
            }

            //
            // InputBufferLength  - Must be at least 1 byte
            //
            if (InputBufferLength == 0) {
#if DBG
                DbgPrint("No input buffer supplied in SET_BAR_GRAPH IOCTL\n");
#endif
                WdfRequestCompleteWithInformation(Request,
                                                  STATUS_BUFFER_TOO_SMALL,
                                                  sizeof(UCHAR));
                return;
            }

            //
            // We need the input memory from the request so that we can pass
            // it to the bus driver.
            //
            status = WdfRequestRetrieveInputMemory(Request,
                                                   &inputMemory);

            if (!NT_SUCCESS(status)) {
#if DBG
                DbgPrint("WdfRequestRetrieveInputMemory failed 0x%0x\n", status);
#endif
                WdfRequestComplete(Request, status);
                return;
            }

            //
            // The routine we want to call takes a memory descriptor, so
            // initialize that now with the handle to the user memory.
            //
            WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&inputMemoryDescriptor,
                                              inputMemory,
                                              NULL);

            //
            // Initialize the vendor command (defined by the device) that
            // allows us to light the bar graph.
            //
            WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(
                                               &controlSetupPacket,
                                               BmRequestHostToDevice,
                                               BmRequestToDevice,
                                               USBFX2LK_SET_BARGRAPH_DISPLAY,
                                               0,
                                               0);


            //
            // And send the vendor command as a control transfer. This
            // shouldn't take very long, so we'll just send it synchronously
            // to the device.
            //

            //
            // We've specified an execution level restraint of
            // PASSIVE_LEVEL, so we're allowed to send this request
            // synchronously.
            //
            ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
            status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                        devContext->BasicUsbUsbDevice,
                                        WDF_NO_HANDLE,
                                        NULL,
                                        &controlSetupPacket,
                                        &inputMemoryDescriptor,
                                        NULL);
            if (NT_SUCCESS(status)) {
                //
                // If the request succeeded, complete the request with success
                // and indicate to the user how much data was transferred (in
                // this case a single byte was sent to the device)
                //
                WdfRequestCompleteWithInformation(Request,
                                                  status,
                                                  sizeof(UCHAR));

            } else {
                //
                // Bad news! Just complete the request with the failure status.
                //
#if DBG
                DbgPrint("WdfUsbTargetDeviceSendControlTransferSynchronously "\
                         "failed 0x%0x\n", status); 
#endif

                WdfRequestComplete(Request, status);
            }
            return;
        }
        case IOCTL_OSR_BASICUSB_GET_SWITCHPACK_STATE: {

            //
            // Validate the buffers for this request:
            //
            // InputBufferLength - Must be zero
            //
            if (InputBufferLength != 0) {
#if DBG
                DbgPrint("Invalid parameter - input buffer supplied in "\
                         "SWITCHPACK_STATE_CHANGE_NOTIFY IOCTL (%u bytes)\n",
                         (ULONG)InputBufferLength);
#endif
                WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
                return;
            }

            //
            // OutputBufferLength  - Must be at least 1 byte
            //
            if (OutputBufferLength == 0) {
#if DBG
                DbgPrint("No input buffer supplied in "\
                         "SWITCHPACK_STATE_CHANGE_NOTIFY IOCTL\n"); 
#endif
                WdfRequestCompleteWithInformation(Request,
                                                  STATUS_BUFFER_TOO_SMALL,
                                                  sizeof(UCHAR));
                return;
            }

            //
            // Forward the request to our switchpack state change requests
            // queue
            //
            status = WdfRequestForwardToIoQueue(
                                        Request, 
                                        devContext->SwitchPackStateChangeQueue);


            if (!NT_SUCCESS(status)) {

                //
                // Bad news! Print out the status and fail the request.
                //
#if DBG
                DbgPrint("WdfRequestForwardToIoQueue failed with Status "\
                         "code 0x%x", status);
#endif
                WdfRequestComplete(Request, status);
                return;
            }
            return;
        }

        default:  {
#if DBG
            DbgPrint("Unknown IOCTL: 0x%x\n", IoControlCode);
#endif
            WdfRequestCompleteWithInformation(Request,
                                              STATUS_INVALID_DEVICE_REQUEST,
                                              0);
            return;
        }
    }

    return;
}
示例#12
0
///////////////////////////////////////////////////////////////////////////////
//
//  BasicUsbEvtWrite
//
//    This routine is called by the framework when there is a
//    write request for us to process
//
//  INPUTS:
//
//      Queue    - Our default queue
//
//      Request  - A write request
//
//      Length   - The length of the write operation
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//      This routine is called at IRQL == PASSIVE_LEVEL, due to
//      our PASSIVE_LEVEL execution level contraint
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID
BasicUsbEvtWrite(WDFQUEUE  Queue, WDFREQUEST  Request, size_t  Length)
{
    PBASICUSB_DEVICE_CONTEXT devContext;
    WDFMEMORY                requestMemory;
    NTSTATUS                 status;
    WDF_REQUEST_PARAMETERS   requestParams;
    WDF_REQUEST_SEND_OPTIONS sendOptions;
    
    UNREFERENCED_PARAMETER(Length);

#if DBG
    DbgPrint("BasicUsbEvtWrite\n");
#endif

    devContext = BasicUsbGetContextFromDevice(
                                WdfIoQueueGetDevice(Queue) );

    //
    // The purpose of this routine will be to convert the write
    // that we received from the user into a USB request and send
    // it to the underlying bus driver.
    //


    //
    // First thing to do is get the input memory associated with the
    // request (only because it's a required parameter to
    // WdfUsbTargetPipeFormatRequestForWrite)
    //
    status = WdfRequestRetrieveInputMemory(Request, 
                                           &requestMemory);
    if(!NT_SUCCESS(status)){
#if DBG
        DbgPrint("WdfRequestRetrieveInputMemory failed 0x%0x\n", status);
#endif
        WdfRequestComplete(Request, status);
        return;
    }

    //
    // Take the user Write request and format it into a Bulk OUT
    // request.
    //
    status = WdfUsbTargetPipeFormatRequestForWrite(devContext->BulkOutPipe,
                                                   Request,
                                                   requestMemory,
                                                   NULL);
    if(!NT_SUCCESS(status)){
#if DBG
        DbgPrint("WdfUsbTargetPipeFormatRequestForWrite failed 0x%0x\n", 
                 status);
#endif
        WdfRequestComplete(Request, status);
        return;
    }


    //
    // We'd like to asynchronously send this newly formatted request
    // to the underlying bus driver. In order to do that, we *must*
    // supply a completion routine that calls WdfRequestComplete.
    // Failure to do so is not architecturally defined, which means
    // it ain't gonna work.
    //
    // Note that because we have modified the request, we are not
    // allowed to use the WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET
    // flag as a cheap shortcut, we MUST supply the completion
    // routine.
    //
    WdfRequestSetCompletionRoutine(Request,
                                   BasicUsbEvtRequestWriteCompletionRoutine,
                                   NULL);

    //
    // Send the request!
    //
    if (!WdfRequestSend(Request,
                        WdfUsbTargetPipeGetIoTarget(devContext->BulkOutPipe),
                        NULL)) {

        //
        // Bad news. The target didn't get the request, so get the
        // failure status and complete the request ourselves..
        //
        status = WdfRequestGetStatus(Request);
#if DBG
        DbgPrint("WdfRequestSend failed 0x%0x\n", status);
#endif
        WdfRequestComplete(Request, status);
        return;
    }

    return;
}
示例#13
0
VOID
MonitorEvtDeviceControl (
    _In_ WDFQUEUE Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t OutputBufferLength,
    _In_ size_t InputBufferLength,
    _In_ ULONG IoControlCode
    )
/*++

   Handles device IO control requests. This callback drives all communication
   between the usermode exe and this driver.

--*/
{
   NTSTATUS status = STATUS_SUCCESS;

   UNREFERENCED_PARAMETER(Queue);
   UNREFERENCED_PARAMETER(OutputBufferLength);

   DoTraceMessage(TRACE_DEVICE_CONTROL, "MonitorSample Dispatch Device Control: 0x%x", IoControlCode);

   switch (IoControlCode)
   {
      case MONITOR_IOCTL_ENABLE_MONITOR:
      {
         WDFMEMORY pMemory;
         void* pBuffer;

         if (InputBufferLength < sizeof(MONITOR_SETTINGS))
         {
            status = STATUS_INVALID_PARAMETER;
         }
         else
         {
            status = WdfRequestRetrieveInputMemory(Request, &pMemory);

            if (NT_SUCCESS(status))
            {
               pBuffer = WdfMemoryGetBuffer(pMemory, NULL);
               status = MonitorCoEnableMonitoring((MONITOR_SETTINGS*) pBuffer);
            }
         }
         break;
      }

      case MONITOR_IOCTL_DISABLE_MONITOR:
      {
         status = STATUS_SUCCESS;
         
         MonitorCoDisableMonitoring();

         break;
      }

      default:
      {
         status = STATUS_INVALID_PARAMETER;
      }
   }

   WdfRequestComplete(Request, status);
}
VOID XferCtrl (
    __in WDFQUEUE Queue,
    __in WDFREQUEST Request,
    __in size_t InputBufferLength,
    __in size_t OutputBufferLength)
{
	NTSTATUS                status;
	PDEVICE_CONTEXT         deviceContext;
	PREQUEST_CONTEXT        requestContext;
	WDFMEMORY				transferMemory;
	PWDF_USB_CONTROL_SETUP_PACKET setupPacket;
	WDF_REQUEST_SEND_OPTIONS sendOptions;
	WDFMEMORY_OFFSET		_transferOffset;
	PWDFMEMORY_OFFSET		transferOffset = &_transferOffset;

	UNREFERENCED_PARAMETER(InputBufferLength);
	UNREFERENCED_PARAMETER(OutputBufferLength);

	deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
	requestContext = GetRequestContext(Request);

	setupPacket = (PWDF_USB_CONTROL_SETUP_PACKET)&requestContext->IoControlRequest.control;
	USBDBG("bmDir=%s bmType=%s bmRecipient=%s bmReserved=%03u bRequest=%u wIndex=%u wValue=%u wLength=%u\n",
	       GetBmRequestDirString(setupPacket->Packet.bm.Request.Dir),
	       GetBmRequestTypeString(setupPacket->Packet.bm.Request.Type),
	       GetBmRequestRecipientString(setupPacket->Packet.bm.Request.Recipient),
	       setupPacket->Packet.bm.Request.Reserved,
	       setupPacket->Packet.bRequest,
	       setupPacket->Packet.wIndex.Value,
	       setupPacket->Packet.wValue.Value,
	       setupPacket->Packet.wLength);

	// If the device and config descriptor requests are not handled they will be the "true"
	// descriptors directly from the device. i.e. if the device has two unassociated interfaces
	// the composite layer will split it into two but each virtual device interface would show
	// both interface deacriptors.
	//
	if (setupPacket->Packet.bm.Request.Dir == BMREQUEST_DEVICE_TO_HOST &&
	        setupPacket->Packet.bm.Request.Type == BMREQUEST_STANDARD &&
	        setupPacket->Packet.bRequest == USB_REQUEST_GET_DESCRIPTOR)
	{
		UCHAR descriptorType = setupPacket->Packet.wValue.Bytes.HiByte;
		// UCHAR descriptorIndex = setupPacket->Packet.wValue.Bytes.LowByte;
		ULONG descriptorSize = 0;
		PVOID descriptorIn = NULL;
		PVOID outputBuffer = NULL;
		size_t outputBufferLength = 0;

		if (requestContext->IoControlCode == LIBUSB_IOCTL_GET_DESCRIPTOR)
		{
			switch(descriptorType)
			{
			case USB_DESCRIPTOR_TYPE_DEVICE:
				descriptorSize = sizeof(deviceContext->UsbDeviceDescriptor);
				descriptorIn = &deviceContext->UsbDeviceDescriptor;
				break;
			case USB_DESCRIPTOR_TYPE_CONFIGURATION:
				if (setupPacket->Packet.wValue.Bytes.LowByte == 0)
				{
					descriptorSize = deviceContext->ConfigurationDescriptorSize;
					descriptorIn = deviceContext->UsbConfigurationDescriptor;
				}
				else
				{
					// we only support the one for now. ;)
					WdfRequestCompleteWithInformation(Request, STATUS_NO_MORE_ENTRIES, 0);
					return;
				}
				break;
			}

			if (descriptorIn && descriptorSize)
			{
				// handle (or fail) this standard request here.
				status = WdfRequestRetrieveOutputBuffer(Request, 2, &outputBuffer, &outputBufferLength);
				if (NT_SUCCESS(status))
				{
					descriptorSize = (ULONG)min(descriptorSize, outputBufferLength);
					RtlCopyMemory(outputBuffer, descriptorIn, descriptorSize);
					WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, descriptorSize);
					return;
				}
				USBERR("WdfRequestRetrieveOutputBuffer failed. status=%Xh\n", status);
				WdfRequestCompleteWithInformation(Request, status, 0);
				return;
			}
		}
	}

	if (METHOD_FROM_CTL_CODE(requestContext->IoControlCode) == METHOD_BUFFERED &&
	        requestContext->RequestType == WdfRequestTypeWrite)
	{
		// support for some of the legacy LIBUSB_IOCTL codes which place the data input
		// buffer at the end of the libusb_request structure.
		status = WdfRequestRetrieveInputMemory(Request, &transferMemory);
		if (!NT_SUCCESS(status))
		{
			USBERR("WdfRequestRetrieveInputMemory failed. status=%Xh\n", status);
			goto Exit;
		}

		if (requestContext->Length < sizeof(libusb_request))
		{
			// this can never happen because the input buffer length is checked for
			// this by the default IoControl event.
			status = STATUS_BUFFER_TOO_SMALL;
			USBERR("input buffer length is less than sizeof(libusb_request) status=%Xh\n", status);
			goto Exit;
		}

		transferOffset->BufferOffset = sizeof(libusb_request);
		transferOffset->BufferLength = requestContext->Length - sizeof(libusb_request);

		if (transferOffset->BufferLength == 0)
		{
			// this is okay but no input data means transferOffset->BufferOffset is pointing
			// to invalid memory; because the length is also zero it is still most likely safe.
			transferOffset = NULL;
			transferMemory = NULL;
		}
	}
	else
	{
		// native control transfers are direct; data comes from/goes to the out buffer whether reading or writing.
		transferOffset = NULL;
		status = WdfRequestRetrieveOutputMemory(Request, &transferMemory);
		if (!NT_SUCCESS(status) && status != STATUS_BUFFER_TOO_SMALL)
		{
			USBERR("WdfRequestRetrieveOutputMemory failed. status=%Xh\n", status);
			goto Exit;
		}

		if (status == STATUS_BUFFER_TOO_SMALL)
		{
			// zero length transfer buffer, this is okay.
			transferMemory = NULL;
			USBMSG("zero-length transfer buffer\n");
		}
	}



	status = WdfUsbTargetDeviceFormatRequestForControlTransfer(
	             deviceContext->WdfUsbTargetDevice,
	             Request,
	             setupPacket,
	             transferMemory,
	             transferOffset);

	if (!NT_SUCCESS(status))
	{
		USBERR("WdfUsbTargetDeviceFormatRequestForControlTransfer failed. status=%Xh\n", status);
		goto Exit;
	}

	WdfRequestSetCompletionRoutine(Request,
	                               XferCtrlComplete,
	                               NULL);

	WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, 0);
	status = SetRequestTimeout(requestContext, Request, &sendOptions);
	if (!NT_SUCCESS(status))
	{
		USBERR("SetRequestTimeout failed. status=%Xh\n", status);
		goto Exit;
	}

	if (!WdfRequestSend(Request,
	                    WdfUsbTargetDeviceGetIoTarget(deviceContext->WdfUsbTargetDevice),
	                    &sendOptions))
	{
		status = WdfRequestGetStatus(Request);
		USBERR("WdfRequestSend failed. status=%Xh\n", status);
	}
	else
	{
		USBMSGN("[Ok] status=%Xh", status);
		return;
	}


Exit:
	if (!NT_SUCCESS(status))
	{
		WdfRequestCompleteWithInformation(Request, status, 0);
	}

	return;
}
示例#15
0
VOID
ToasterEvtIoWrite (
    WDFQUEUE      Queue,
    WDFREQUEST    Request,
    size_t        Length
    )
/*++

Routine Description:

    Performs write to the toaster device. This event is called when the
    framework receives IRP_MJ_WRITE requests.

Arguments:

    Queue -  Handle to the framework queue object that is associated with the
            I/O request.
    Request - Handle to a framework request object.

    Lenght - Length of the data buffer associated with the request.
                 The default property of the queue is to not dispatch
                 zero lenght read & write requests to the driver and
                 complete is with status success. So we will never get
                 a zero length request.

Return Value:

   None
--*/

{
    NTSTATUS    status;
    ULONG_PTR bytesWritten =0;
    WDFMEMORY memory;

    UNREFERENCED_PARAMETER(Queue);
    UNREFERENCED_PARAMETER(Length);

    KdPrint(("ToasterEvtIoWrite. Request: 0x%p, Queue: 0x%p\n",
                                Request, Queue));

    PAGED_CODE();

    //
    // Get the request buffer and perform write operation here
    //
    status = WdfRequestRetrieveInputMemory(Request, &memory);
    if(NT_SUCCESS(status) ) {
        //
        // 1) Use WdfMemoryCopyToBuffer to copy data from the request
        // to driver buffer.
        // 2) Or get the buffer pointer from the request by calling
        // WdfRequestRetrieveInputBuffer
        // 3) Or you can get the buffer pointer from the memory handle
        // by calling WdfMemoryGetBuffer.
        //
        bytesWritten = Length;
    }

    WdfRequestCompleteWithInformation(Request, status, bytesWritten);

}
示例#16
0
文件: queue.c 项目: 340211173/Driver
VOID
EchoEvtIoWrite(
    IN WDFQUEUE   Queue,
    IN WDFREQUEST Request,
    IN size_t     Length
    )
/*++

Routine Description:

    This event is invoked when the framework receives IRP_MJ_WRITE request.
    This routine allocates memory buffer, copies the data from the request to it,
    and stores the buffer pointer in the queue-context with the length variable
    representing the buffers length. The actual completion of the request
    is defered to the periodic timer dpc.

Arguments:

    Queue -  Handle to the framework queue object that is associated with the
             I/O request.

    Request - Handle to a framework request object.

    Length  - number of bytes to be read.
              The default property of the queue is to not dispatch
              zero lenght read & write requests to the driver and
              complete is with status success. So we will never get
              a zero length request.

Return Value:

    VOID

--*/
{
    NTSTATUS Status;
    WDFMEMORY memory;
    PQUEUE_CONTEXT queueContext = QueueGetContext(Queue);
    PVOID writeBuffer = NULL;

    _Analysis_assume_(Length > 0);

    KdPrint(("EchoEvtIoWrite Called! Queue 0x%p, Request 0x%p Length %d\n",
             Queue,Request,Length));

    if( Length > MAX_WRITE_LENGTH ) {
        KdPrint(("EchoEvtIoWrite Buffer Length to big %d, Max is %d\n",
                 Length,MAX_WRITE_LENGTH));
        WdfRequestCompleteWithInformation(Request, STATUS_BUFFER_OVERFLOW, 0L);
        return;
    }

    // Get the memory buffer
    Status = WdfRequestRetrieveInputMemory(Request, &memory);
    if( !NT_SUCCESS(Status) ) {
        KdPrint(("EchoEvtIoWrite Could not get request memory buffer 0x%x\n",
                 Status));
        WdfVerifierDbgBreakPoint();
        WdfRequestComplete(Request, Status);
        return;
    }

    // Release previous buffer if set
    if( queueContext->WriteMemory != NULL ) {
        WdfObjectDelete(queueContext->WriteMemory);
        queueContext->WriteMemory = NULL;
    }

    Status = WdfMemoryCreate(WDF_NO_OBJECT_ATTRIBUTES,
                             NonPagedPool,
                             'sam1',
                             Length,
                             &queueContext->WriteMemory,
                             &writeBuffer
                             );

    if(!NT_SUCCESS(Status)) {
        KdPrint(("EchoEvtIoWrite: Could not allocate %d byte buffer\n", Length));
        WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES);
        return;
    }


    // Copy the memory in
    Status = WdfMemoryCopyToBuffer( memory,
                                    0,  // offset into the source memory
                                    writeBuffer,
                                    Length );
    if( !NT_SUCCESS(Status) ) {
        KdPrint(("EchoEvtIoWrite WdfMemoryCopyToBuffer failed 0x%x\n", Status));
        WdfVerifierDbgBreakPoint();

        WdfObjectDelete(queueContext->WriteMemory);
        queueContext->WriteMemory = NULL;

        WdfRequestComplete(Request, Status);
        return;
    }

    // Set transfer information
    WdfRequestSetInformation(Request, (ULONG_PTR)Length);

    // Specify the request is cancelable
    WdfRequestMarkCancelable(Request, EchoEvtRequestCancel);

    // Defer the completion to another thread from the timer dpc
    queueContext->CurrentRequest = Request;
    queueContext->CurrentStatus  = Status;

    return;
}
示例#17
0
VOID
EvtIoDeviceControl(
    IN WDFQUEUE   Queue,
    IN WDFREQUEST Request,
    IN size_t     OutputBufferLength,
    IN size_t     InputBufferLength,
    IN ULONG      IoControlCode
    )
{
    WDFDEVICE                           device;
    PDEVICE_CONTEXT                     pDevContext;
    size_t                              bytesTransferred = 0;
    NTSTATUS                            status;
    WDF_USB_CONTROL_SETUP_PACKET        controlSetupPacket;
    WDF_MEMORY_DESCRIPTOR               memDesc;
    WDFMEMORY                           memory;
    WDF_REQUEST_SEND_OPTIONS            sendOptions;

    UNREFERENCED_PARAMETER(InputBufferLength);
    UNREFERENCED_PARAMETER(OutputBufferLength);

    device = WdfIoQueueGetDevice(Queue);
    pDevContext = GetDeviceContext(device);

    switch(IoControlCode) {

    case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY:

        if(InputBufferLength < sizeof(UCHAR)) {
            status = STATUS_BUFFER_OVERFLOW;
            bytesTransferred = sizeof(UCHAR);
            break;
        }

        status = WdfRequestRetrieveInputMemory(Request, &memory);
        if (!NT_SUCCESS(status)) {
            KdPrint(("WdfRequestRetrieveMemory failed %!STATUS!", status));
            break;
        }

        WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestHostToDevice,
                                        BmRequestToDevice,
                                        USBFX2LK_SET_BARGRAPH_DISPLAY, // Request
                                        0, // Value
                                        0); // Index

        WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDesc, memory, NULL);

       //
       // Send the I/O with a timeout to avoid hanging the calling 
       // thread indefinitely.
       //
        WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT);

        WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions,
                                         WDF_REL_TIMEOUT_IN_MS(100));

        status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                        pDevContext->UsbDevice,
                                        NULL, // Optional WDFREQUEST
                                        &sendOptions, // PWDF_REQUEST_SEND_OPTIONS
                                        &controlSetupPacket,
                                        &memDesc,
                                        (PULONG)&bytesTransferred);
        if (!NT_SUCCESS(status)) {
            KdPrint(("SendControlTransfer failed %!STATUS!", status));
            break;
        }
        break;

    default:
        status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    WdfRequestCompleteWithInformation(Request, status, bytesTransferred);

    return;
}