Beispiel #1
0
static VOID UsbChief_EvtIoWrite(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t Length)
{
	UNREFERENCED_PARAMETER(Queue);

	PAGED_CODE();

	UsbChief_DbgPrint(DEBUG_RW, ("EvtIoWrite %d\n", Length));
	WdfRequestCompleteWithInformation(Request, STATUS_INVALID_DEVICE_REQUEST, 0);
}
VOID
ForwardRequestToIoTarget(
    _In_ WDFQUEUE   queue,
    _In_ WDFREQUEST request,
    _In_ size_t     length)
{
    TraceEntry();
    Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! - Queue 0x%p, Request 0x%p Length %Iu", queue, request, length);

    auto device = WdfIoQueueGetDevice(queue);
    auto context = GetDeviceContext(device);

    if (length > context->MaxLengthInBytesForRWTransfers) {
        TraceError("%!FUNC! - Buffer Length to big %Iu, Max is %Iu. Status - %!STATUS!",
            length, context->MaxLengthInBytesForRWTransfers, STATUS_BUFFER_OVERFLOW);

        WdfRequestCompleteWithInformation(request, STATUS_BUFFER_OVERFLOW, NULL);
        return;
    }

    auto targetDevice = WdfDeviceGetIoTarget(device);

    WdfRequestFormatRequestUsingCurrentType(request);

    WDF_REQUEST_SEND_OPTIONS options;

    WDF_REQUEST_SEND_OPTIONS_INIT(
        &options,
        WDF_REQUEST_SEND_OPTION_SYNCHRONOUS | WDF_REQUEST_SEND_OPTION_TIMEOUT);

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&options, WDF_ABS_TIMEOUT_IN_SEC(10));

    auto sendSuccess = WdfRequestSend(request, targetDevice, &options);
    auto status = WdfRequestGetStatus(request);
    if (!sendSuccess || !NT_SUCCESS(status))
    {
        TraceError("%!FUNC! - WdfRequestSend returned %d with status: %!STATUS!", sendSuccess, status);
        WdfRequestCompleteWithInformation(request, status, NULL);
        return;
    }

    WdfRequestComplete(request, status);
}
Beispiel #3
0
VOID
NICFreeQueuedSendPackets(
    IN  PFDO_DATA  FdoData
    )
/*++
Routine Description:

    Free and complete the pended sends on SendQueueHead

    Assumption: This function is called with the Send SPINLOCK held.

Arguments:

    FdoData     Pointer to our FdoData

Return Value:

     None

--*/
{
    WDFREQUEST   request;
    NTSTATUS     status;

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

    do {
        status = WdfIoQueueRetrieveNextRequest(
                     FdoData->PendingWriteQueue,
                     &request
                     );

        if(!NT_SUCCESS(status) ) {
            if(STATUS_NO_MORE_ENTRIES != status){
                TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                    "WdfIoQueueRetrieveNextRequest failed %x\n", status);
            }
            break;
        }

        FdoData->nWaitSend--;

        WdfSpinLockRelease(FdoData->SendLock);

        WdfRequestCompleteWithInformation(request, status, 0);

        WdfSpinLockAcquire(FdoData->SendLock);

    } WHILE (TRUE);

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

}
Beispiel #4
0
VOID
EvtRequestReadCompletionRoutine(
    IN WDFREQUEST                  Request,
    IN WDFIOTARGET                 Target,
    PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
    IN WDFCONTEXT                  Context
    )
/*++

Routine Description:

    This is the completion routine for reads/writes
    If the irp completes with success, we check if we
    need to recirculate this irp for another stage of
    transfer.

Arguments:

    Context - Driver supplied context
    Device - Device handle
    Request - Request handle
    Params - request completion params

Return Value:
    None

--*/
{    
    NTSTATUS    status;
    size_t      bytesRead = 0;
    PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;

    UNREFERENCED_PARAMETER(Target);
    UNREFERENCED_PARAMETER(Context);

    status = CompletionParams->IoStatus.Status;
    
    usbCompletionParams = CompletionParams->Parameters.Usb.Completion;
    
    bytesRead =  usbCompletionParams->Parameters.PipeRead.Length;
    
    if (NT_SUCCESS(status)){
        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_READ,
                    "Number of bytes read: %I64d\n", (INT64)bytesRead);        
    } else {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, 
            "Read failed - request status 0x%x UsbdStatus 0x%x\n", 
                status, usbCompletionParams->UsbdStatus);

    }

    WdfRequestCompleteWithInformation(Request, status, bytesRead);

    return;
}
VOID
ToasterEvtIoRead (
    WDFQUEUE      Queue,
    WDFREQUEST    Request,
    size_t        Length
    )
/*++

Routine Description:

    Performs read from the toaster device. This event is called when the
    framework receives IRP_MJ_READ 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.
                 By default, the queue does not dispatch
                 zero length read & write requests to the driver and instead to
                 complete such requests with status success. So we will never get
                 a zero length request.

Return Value:

  None.

--*/
{
    NTSTATUS    status;
    ULONG_PTR bytesCopied =0;
    WDFMEMORY memory;

    UNREFERENCED_PARAMETER(Queue);
    UNREFERENCED_PARAMETER(Length);

    PAGED_CODE();

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

    //
    // Get the request memory and perform read operation here
    //
    status = WdfRequestRetrieveOutputMemory(Request, &memory);
    if(NT_SUCCESS(status) ) {
        //
        // Copy data into the memory buffer using WdfMemoryCopyFromBuffer
        //
    }

    WdfRequestCompleteWithInformation(Request, status, bytesCopied);
}
Beispiel #6
0
VOID FireShockEvtIoWrite(
    _In_ WDFQUEUE   Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t     Length
)
{
    NTSTATUS            status;
    PDEVICE_CONTEXT     pDeviceContext;
    LPVOID              buffer;
    size_t              bufferLength;
    size_t              transferred = 0;

    pDeviceContext = DeviceGetContext(WdfIoQueueGetDevice(Queue));

    switch (pDeviceContext->DeviceType)
    {
    case DualShock3:

        status = WdfRequestRetrieveInputBuffer(
            Request,
            DS3_HID_OUTPUT_REPORT_SIZE,
            &buffer,
            &bufferLength);

        if (NT_SUCCESS(status) && Length == bufferLength)
        {
            status = SendControlRequest(
                pDeviceContext,
                BmRequestHostToDevice,
                BmRequestClass,
                SetReport,
                USB_SETUP_VALUE(HidReportRequestTypeOutput, HidReportRequestIdOne),
                0,
                buffer,
                (ULONG)bufferLength);

            if (!NT_SUCCESS(status))
            {
                TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE,
                    "SendControlRequest failed with status %!STATUS!",
                    status);
                break;
            }

            transferred = bufferLength;
        }

        break;
    default:
        status = STATUS_NOT_SUPPORTED;
        break;
    }

    WdfRequestCompleteWithInformation(Request, status, transferred);
}
Beispiel #7
0
// 读回调
VOID EvtIoRead( IN WDFQUEUE Queue, 
			   IN WDFREQUEST Request, 
			   IN size_t Length )
{
	NTSTATUS status;
	PVOID outBuf; // 输出缓冲区
	size_t bufLength; // 输出缓冲区大小
	ULONG_PTR bytesRead = 0; // 实际读取的字节数

	// 获取输出缓冲区地址
	status = WdfRequestRetrieveOutputBuffer(Request, 0, &outBuf, &bufLength);
	if( !NT_SUCCESS(status) )
	{
		KdPrint(("[EvtIoRead] WdfRequestRetrieveOutputBuffer failed!"));

		WdfRequestComplete(Request, status);
		return ;
	}

	// 实际读取的字节数与文件指针有关
	bytesRead = ((IO_BUFFER_SIZE - gFilePointer) < Length ) ? 
		IO_BUFFER_SIZE - gFilePointer : Length;

	// 检查参数
	if( bufLength < bytesRead )
	{
		WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
		return;
	}

	// 文件指针已经到末尾
	if( 0 == bytesRead )
	{
		WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, 0);
		return;
	}

	// 拷贝内容到输出缓冲区
	RtlCopyMemory(outBuf, gFileBuffer+gFilePointer, bytesRead);

	WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, bytesRead);
}
Beispiel #8
0
__inline
VOID
MP_FREE_SEND_PACKET(
    IN  PFDO_DATA   FdoData,
    IN  PMP_TCB     pMpTcb,
    IN  NTSTATUS    Status
    )
/*++
Routine Description:

    Recycle a MP_TCB and complete the packet if necessary

    Assumption: This function is called with the Send SPINLOCK held.

Arguments:

    FdoData     Pointer to our FdoData
    pMpTcb      Pointer to MP_TCB

Return Value:

    None

--*/
{

    WDFREQUEST          request;
    WDFDMATRANSACTION   dmaTransaction;
    size_t              length;

    ASSERT(MP_TEST_FLAG(pMpTcb, fMP_TCB_IN_USE));

    dmaTransaction = pMpTcb->DmaTransaction;
    pMpTcb->DmaTransaction = NULL;

    MP_CLEAR_FLAGS(pMpTcb);

    FdoData->CurrSendHead = FdoData->CurrSendHead->Next;
    FdoData->nBusySend--;

    request = WdfDmaTransactionGetRequest(dmaTransaction);
    length  = WdfDmaTransactionGetBytesTransferred(dmaTransaction);

    WdfObjectDelete( dmaTransaction );

    if (request)
    {
        WdfSpinLockRelease(FdoData->SendLock);
        WdfRequestCompleteWithInformation(request, Status, length);
        FdoData->BytesTransmitted += length;

        WdfSpinLockAcquire(FdoData->SendLock);
    }
}
Beispiel #9
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsDequeue -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtaEventsDequeue(
    DtaDeviceData*  pDvcData,
    DtFileObject*  pFile,
    DtaEvents*  pEvents)            // If not NULL, we don't need the file object
{
    WDF_REQUEST_PARAMETERS  Params;
    WDFREQUEST  Request;
    WDFREQUEST  Request2;
    NTSTATUS  NtStatus = STATUS_SUCCESS;
    size_t  BufSize;
    DtaIoctlOutputData*  pOutBuf;
    
    
    // Get all pending requests from queue for this file object
    while (NtStatus == STATUS_SUCCESS)
    {
        WDF_REQUEST_PARAMETERS_INIT(&Params);
        
        NtStatus = WdfIoQueueFindRequest(pDvcData->m_IalData.m_EventQueue, NULL, 
                                               DtFileGetHandle(pFile), &Params, &Request);
        if (NtStatus != STATUS_SUCCESS) // Don't use the NT_SUCCESS macro here
            break;
        
        NtStatus = WdfIoQueueRetrieveFoundRequest(pDvcData->m_IalData.m_EventQueue, 
                                                                      Request, &Request2);
        
        WdfObjectDereference(Request);
        if (!NT_SUCCESS(NtStatus))
            continue;
        
        if (NT_SUCCESS(NtStatus))
        {
            NtStatus = WdfRequestRetrieveOutputBuffer(Request2, 
                                     Params.Parameters.DeviceIoControl.OutputBufferLength,
                                     &pOutBuf, &BufSize);
        }

        if (NT_SUCCESS(NtStatus))
        {   DtStatus  Status;
            BufSize = sizeof(DtaIoctlGetEventOutput);
            Status = DtaEventsGet(pDvcData, pFile, pEvents,
                                                    &pOutBuf->m_GetEvent.m_EventType,
                                                    &pOutBuf->m_GetEvent.m_Value1,
                                                    &pOutBuf->m_GetEvent.m_Value2);
        }

        if (!NT_SUCCESS(NtStatus))
            BufSize = 0;
        
        // Complete request, use DtStatus in the driver-defined information field
        WdfRequestCompleteWithInformation(Request2, NtStatus, (ULONG_PTR)BufSize);
    }
    return DT_STATUS_OK;
}
void AndroidUsbFileObject::OnEvtIoWrite(WDFREQUEST request,
                                        size_t length) {
  ASSERT_IRQL_LOW_OR_DISPATCH();
  ASSERT(WdfRequestGetFileObject(request) == wdf_file());
  // Complete zero writes with success
  if (0 == length) {
    WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
    return;
  }

  WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
}
Beispiel #11
0
VOID
EvtIoRead(
    IN WDFQUEUE         Queue,
    IN WDFREQUEST       Request,
    IN size_t           Length
    )
{
    WDFUSBPIPE                  pipe;
    NTSTATUS                    status;
    WDFMEMORY                   reqMemory;
    PDEVICE_CONTEXT             pDeviceContext;
    BOOLEAN                     ret;

    UNREFERENCED_PARAMETER(Length);

    pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

    pipe = pDeviceContext->BulkReadPipe;

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

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

    WdfRequestSetCompletionRoutine(
                            Request,
                            EvtRequestReadCompletionRoutine,
                            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;
}
void AndroidUsbPipeFileObject::OnCtlBulkRead(WDFREQUEST request,
                                             size_t output_buf_len,
                                             size_t input_buf_len) {
  ASSERT_IRQL_LOW_OR_DISPATCH();

  // Make sure that this is an input pipe
  if (is_output_pipe()) {
    GoogleDbgPrint("\n!!!! Attempt to IOCTL read from output pipe %p", this);
    WdfRequestComplete(request, STATUS_ACCESS_DENIED);
    return;
  }

  // Make sure zero length I/O doesn't go through
  if (0 == output_buf_len) {
    WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
    return;
  }

  // Verify buffers
  ASSERT(input_buf_len >= sizeof(AdbBulkTransfer));
  if (input_buf_len < sizeof(AdbBulkTransfer)) {
    WdfRequestComplete(request, STATUS_INVALID_BUFFER_SIZE);
    return;
  }

  // Get the input buffer
  NTSTATUS status;
  AdbBulkTransfer* transfer_param =
    reinterpret_cast<AdbBulkTransfer*>(InAddress(request, &status));
  ASSERT(NT_SUCCESS(status) && (NULL != transfer_param));
  if (!NT_SUCCESS(status)) {
    WdfRequestComplete(request, status);
    return;
  }

  // Get MDL for this request.
  PMDL request_mdl = NULL;
  status = WdfRequestRetrieveOutputWdmMdl(request, &request_mdl);
  ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
  if (NT_SUCCESS(status)) {
    // Perform the read
    CommonBulkReadWrite(request,
                        request_mdl,
                        static_cast<ULONG>(output_buf_len),
                        true,
                        transfer_param->time_out,
                        true);
  } else {
    WdfRequestComplete(request, status);
  }
}
Beispiel #13
0
VOID
tgwinkEvtIoRead(
    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.Read.DeviceOffset;

    status = WdfRequestRetrieveOutputMemory(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.GetBusData(context->busInterface.Context, PCI_WHICHSPACE_CONFIG, WdfMemoryGetBuffer(mem, NULL), offset, (ULONG)Length);

    WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, (ULONG_PTR)result);
}
void AndroidUsbPipeFileObject::OnCtlGetEndpointInformation(
    WDFREQUEST request,
    size_t output_buf_len) {
  ASSERT_IRQL_LOW_OR_DISPATCH();

  // Verify output buffer
  if (output_buf_len < sizeof(AdbEndpointInformation)) {
    WdfRequestCompleteWithInformation(request,
                                      STATUS_BUFFER_TOO_SMALL,
                                      sizeof(AdbEndpointInformation));
    return;
  }

  // Get the output buffer
  NTSTATUS status;
  AdbEndpointInformation* ret_info =
    reinterpret_cast<AdbEndpointInformation*>(OutAddress(request, &status));
  ASSERT(NT_SUCCESS(status) && (NULL != ret_info));
  if (!NT_SUCCESS(status)) {
    WdfRequestComplete(request, status);
    return;
  }

  // Copy endpoint info to the output
  ret_info->max_packet_size = pipe_information_.MaximumPacketSize;
  ret_info->endpoint_address = pipe_information_.EndpointAddress;
  ret_info->polling_interval = pipe_information_.Interval;
  ret_info->setting_index = pipe_information_.SettingIndex;
  ret_info->endpoint_type =
    static_cast<AdbEndpointType>(pipe_information_.PipeType);
  ret_info->max_transfer_size = pipe_information_.MaximumTransferSize;

  WdfRequestCompleteWithInformation(request,
                                    STATUS_SUCCESS,
                                    sizeof(AdbEndpointInformation));
}
VOID PVPanicEvtQueueDeviceControl(IN WDFQUEUE Queue,
                                  IN WDFREQUEST Request,
                                  IN size_t OutputBufferLength,
                                  IN size_t InputBufferLength,
                                  IN ULONG IoControlCode)
{
    NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
    ULONG    length = 0;
    PVOID    buffer;
    size_t   buffer_length;

    PAGED_CODE();

    UNREFERENCED_PARAMETER(Queue);
    UNREFERENCED_PARAMETER(InputBufferLength);
    UNREFERENCED_PARAMETER(OutputBufferLength);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS, "--> %!FUNC!");

    switch (IoControlCode)
    {
    case IOCTL_GET_CRASH_DUMP_HEADER:
    {
        // Return the full result of KeInitializeCrashDumpHeader.
        status = WdfRequestRetrieveOutputBuffer(Request, 0, &buffer, &buffer_length);
        if (!NT_SUCCESS(status))
        {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTLS,
                "WdfRequestRetrieveInputBuffer failed: %!STATUS!", status);
            break;
        }

        status = KeInitializeCrashDumpHeader(DUMP_TYPE_FULL,
                                             0, // flags, must be 0
                                             buffer,
                                             (ULONG)buffer_length,
                                             &length);
        if (status == STATUS_INVALID_PARAMETER_4)
        {
            status = STATUS_BUFFER_TOO_SMALL;
        }
        break;
    }
    }

    WdfRequestCompleteWithInformation(Request, status, NT_SUCCESS(status) ? length : 0);
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS, "<-- %!FUNC!");
}
Beispiel #16
0
VOID
EvtIoDeviceControl(
    __in WDFQUEUE IoQueue,
    __in WDFREQUEST Request,
    __in size_t OutBufferLength,
    __in size_t InBufferLength,
    __in ULONG IoControlCode
    )
{
    PDEVICE_CONTEXT DeviceContext;
    ULONG_PTR Information;
    NTSTATUS Status;
    
    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS, "--> EvtIoDeviceControl(%x)\n", IoControlCode);

    //
    // Get the pointer to the device's context area.
    // We are using the queue handle to get the device handle.
    //
    
    DeviceContext = GetDeviceContext(WdfIoQueueGetDevice(IoQueue));
    Information = 0;
    
    switch(IoControlCode) {
        case IOCTL_SHOW_DATA:
            //Status = EraseFirstSector(WdfIoQueueGetDevice(IoQueue));
            //ShowFwhRegisters(DeviceContext->Lpc);
            //ShowRcrbRegisters(DeviceContext->Rcrb);
            //ShowSpiRegisters(DeviceContext->Rcrb + SPIBAR_OFFSET);
            Status = STATUS_SUCCESS;
            break;
        
        default:
            Status = STATUS_INVALID_DEVICE_REQUEST;
            break;
    }
    
    //
    // Complete the I/O request
    //
    
    WdfRequestCompleteWithInformation(Request, Status, Information);
    
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS, "<-- EvtIoDeviceControl(%x)\n", IoControlCode);
}
Beispiel #17
0
VOID
EchoEvtRequestCancel(
    IN WDFREQUEST Request
    )
/*++

Routine Description:


    Called when an I/O request is cancelled after the driver has marked
    the request cancellable. This callback is automatically synchronized
    with the I/O callbacks since we have chosen to use frameworks Device
    level locking.

Arguments:

    Request - Request being cancelled.

Return Value:

    VOID

--*/
{
    PQUEUE_CONTEXT queueContext = QueueGetContext(WdfRequestGetIoQueue(Request));

    KdPrint(("EchoEvtRequestCancel called on Request 0x%p\n",  Request));

    //
    // The following is race free by the callside or DPC side
    // synchronizing completion by calling
    // WdfRequestMarkCancelable(Queue, Request, FALSE) before
    // completion and not calling WdfRequestComplete if the
    // return status == STATUS_CANCELLED.
    //
    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);

    //
    // This book keeping is synchronized by the common
    // Queue presentation lock
    //
    ASSERT(queueContext->CurrentRequest == Request);
    queueContext->CurrentRequest = NULL;

    return;
}
// 中断Pipe回调函数。这样一旦设备产生了中断信息,驱动就能够读取到。
//
VOID InterruptRead(WDFUSBPIPE Pipe, WDFMEMORY Buffer, size_t NumBytesTransferred, WDFCONTEXT Context)
{
	NTSTATUS status;
	size_t size = 0;
	PDEVICE_CONTEXT pContext = (PDEVICE_CONTEXT)Context;
	WDFREQUEST Request = NULL;
	CHAR *pchBuf = NULL;

	KDBG(DPFLTR_INFO_LEVEL, "[InterruptRead]");
	UNREFERENCED_PARAMETER(Pipe);

	// Read数据缓冲区。注意到,缓冲区长度总是管道最大包长度的倍数。
	// 我们这里只用缓冲区的第一个有效字节。
	pchBuf = (CHAR*)WdfMemoryGetBuffer(Buffer, &size);
	if(pchBuf == NULL || size == 0)
		return;

	// 第一个字节为确认字节,一定是0xD4
	//if(pchBuf[0] != 0xD4)return;

	// 从队列中提取一个未完成请求
	status = WdfIoQueueRetrieveNextRequest(pContext->InterruptManualQueue, &Request);

	if(NT_SUCCESS(status))
	{
		CHAR* pOutputBuffer = NULL;
		status = WdfRequestRetrieveOutputBuffer(Request, 1, &pOutputBuffer, NULL);

		if(NT_SUCCESS(status))
		{
			// 把结果返回给应用程序
			pOutputBuffer[0] = pchBuf[1];
			WdfRequestCompleteWithInformation(Request, status, 1);
		}
		else
		{
			// 返回错误
			WdfRequestComplete(Request, status);
		}

		KDBG(DPFLTR_INFO_LEVEL, "Get and finish an interrupt read request.");
	}else{
		// 队列空,将放弃从设备获取的数据。
		KDBG(DPFLTR_INFO_LEVEL, "Manual interrupt queue is empty!!!");
	}
}
VOID VIOSerialPortWriteRequestCancel(IN WDFREQUEST Request)
{
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(
        WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)))->port;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> %s Request: 0x%p\n",
        __FUNCTION__, Request);

    // synchronize with VIOSerialReclaimConsumedBuffers because the pending
    // request is not guaranteed to be alive after we return from this callback
    WdfSpinLockAcquire(Port->OutVqLock);
    Port->PendingWriteRequest = NULL;
    WdfSpinLockRelease(Port->OutVqLock);

    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
VOID
VIOSerialPortReadRequestCancel(
    IN WDFREQUEST Request
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)));

    TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "-->%s called on request 0x%p\n", __FUNCTION__, Request);

    // synchronize with VIOSerialQueuesInterruptDpc because the pending
    // request is not guaranteed to be alive after we return from this callback
    WdfSpinLockAcquire(pdoData->port->InBufLock);
    pdoData->port->PendingReadRequest = NULL;
    WdfSpinLockRelease(pdoData->port->InBufLock);

    WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
VOID VIOSerialPortWriteRequestCancel(IN WDFREQUEST Request)
{
    BOOLEAN cancel = FALSE;
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(
        WdfIoQueueGetDevice(WdfRequestGetIoQueue(Request)))->port;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> %s Request: 0x%p\n",
        __FUNCTION__, Request);

    if (Port->PendingWriteRequest)
    {
        Port->PendingWriteRequest = NULL;
        cancel = TRUE;
    }

    if (cancel)
    {
        WdfRequestCompleteWithInformation(Request, STATUS_CANCELLED, 0L);
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__);
}
Beispiel #22
0
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"));
}
Beispiel #23
0
static VOID UsbChief_EvtIoRead(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t Length)
{
	PFILE_CONTEXT           fileContext = NULL;
	WDFUSBPIPE              pipe;
	WDF_USB_PIPE_INFORMATION   pipeInfo;

	UNREFERENCED_PARAMETER(Queue);

	PAGED_CODE();

	UsbChief_DbgPrint(DEBUG_RW, ("EvtIoRead %d\n", Length));

	fileContext = GetFileContext(WdfRequestGetFileObject(Request));
	pipe = fileContext->Pipe;
	if (pipe == NULL) {
		UsbChief_DbgPrint(0, ("pipe handle is NULL\n"));
		WdfRequestCompleteWithInformation(Request, STATUS_INVALID_PARAMETER, 0);
		return;
	}
	WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
	WdfUsbTargetPipeGetInformation(pipe, &pipeInfo);

	UsbChief_ReadEndPoint(Queue, Request, (ULONG) Length);
}
VOID XferCtrlComplete(__in WDFREQUEST Request,
                      __in WDFIOTARGET Target,
                      __in PWDF_REQUEST_COMPLETION_PARAMS Params,
                      __in WDFCONTEXT Context)
{
	NTSTATUS status = Params->IoStatus.Status;
	PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams = Params->Parameters.Usb.Completion;
	ULONG length = usbCompletionParams->Parameters.DeviceControlTransfer.Length;

	UNREFERENCED_PARAMETER(Target);
	UNREFERENCED_PARAMETER(Context);

	if (NT_SUCCESS(status))
	{
		USBMSGN("[Ok] transferred=%u", length);
		WdfRequestCompleteWithInformation(Request, status, length);

	}
	else
	{
		USBERR("status=%Xh\n", status);
		WdfRequestComplete(Request, status);
	}
}
Beispiel #25
0
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;
}
Beispiel #26
0
VOID
EchoEvtIoRead(
    IN WDFQUEUE   Queue,
    IN WDFREQUEST Request,
    IN size_t      Length
    )
/*++

Routine Description:

    This event is called when the framework receives IRP_MJ_READ request.
    It will copy the content from the queue-context buffer to the request buffer.
    If the driver hasn't received any write request earlier, the read returns zero.

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;
    PQUEUE_CONTEXT queueContext = QueueGetContext(Queue);
    WDFMEMORY memory;
    size_t writeMemoryLength;

    _Analysis_assume_(Length > 0);

    KdPrint(("EchoEvtIoRead Called! Queue 0x%p, Request 0x%p Length %d\n",
             Queue,Request,Length));
    //
    // No data to read
    //
    if( (queueContext->WriteMemory == NULL)  ) {
        WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, (ULONG_PTR)0L);
        return;
    }

    //
    // Read what we have
    //
    WdfMemoryGetBuffer(queueContext->WriteMemory, &writeMemoryLength);
    _Analysis_assume_(writeMemoryLength > 0);

    if( writeMemoryLength < Length ) {
        Length = writeMemoryLength;
    }

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

    // Copy the memory out
    Status = WdfMemoryCopyFromBuffer( memory, // destination
                             0,      // offset into the destination memory
                             WdfMemoryGetBuffer(queueContext->WriteMemory, NULL),
                             Length );
    if( !NT_SUCCESS(Status) ) {
        KdPrint(("EchoEvtIoRead: WdfMemoryCopyFromBuffer failed 0x%x\n", Status));
        WdfRequestComplete(Request, Status);
        return;
    }

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

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


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

    return;
}
Beispiel #27
0
VOID
FilterEvtIoDeviceControlFromRawPdo(
    IN WDFQUEUE      Queue,
    IN WDFREQUEST    Request,
    IN size_t        OutputBufferLength,
    IN size_t        InputBufferLength,
    IN ULONG         IoControlCode
    )
/*++

Routine Description:

    This routine is the dispatch routine for internal device control requests.
    
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

--*/
{
    PFILTER_EXTENSION               filterExt;
    NTSTATUS                        status = STATUS_SUCCESS;
	size_t                          bytesReturned = 0;
    WDFDEVICE                       device;
	BYTE*                           pDevInfoLen; // len retrieved from device
	BYTE*                           pDevInfoLenInput; // len input from app
	BYTE*                           pDevInfoData; // data retrieved from device

    UNREFERENCED_PARAMETER(OutputBufferLength);
    UNREFERENCED_PARAMETER(InputBufferLength);

    KdPrint(("--> FilterEvtIoDeviceControlFromRawPdo\n"));

    device = WdfIoQueueGetDevice(Queue);

    filterExt = FilterGetData(device);

    switch (IoControlCode) {

    //
    // Put your cases for handling IOCTLs here
    //
    case IOCTL_OSRUSBFX2_FILTER_GETDEVINFOLEN:
	    KdPrint(("Entered IOCTL_OSRUSBFX2_FILTER_GETDEVINFOLEN\n"));

		//
        // Make sure the caller's output buffer is large enough
        // to hold the state of the bar graph
        //
        status = WdfRequestRetrieveOutputBuffer(Request,
                            sizeof(BYTE),
                            &pDevInfoLen,
                            NULL);

        if (!NT_SUCCESS(status)) {
			KdPrint(("User's output buffer is too small for this IOCTL, expecting an BYTE\n"));
            break;
        }
        //
        // Call our function to get
        //
        status = GetDevInfoLength(filterExt, pDevInfoLen);

		//
        // If we succeeded return the user their data
        //
        if (NT_SUCCESS(status)) {
            bytesReturned = sizeof(BYTE);

        } else {
            bytesReturned = 0;

        }
		
		KdPrint(("Completed IOCTL_OSRUSBFX2_FILTER_GETDEVINFOLEN\n"));		
        break;

    case IOCTL_OSRUSBFX2_FILTER_GETDEVINFODATA:
	    KdPrint(("Entered IOCTL_OSRUSBFX2_FILTER_GETDEVINFODATA\n"));

        status = WdfRequestRetrieveInputBuffer(Request,
                            sizeof(BYTE),
                            &pDevInfoLenInput,
                            NULL);
        if (!NT_SUCCESS(status)) {
            KdPrint(("User's input buffer is too small for this IOCTL, expecting a BYTE\n"));
			bytesReturned = 0;
            break;
        }
		KdPrint(("Input length is %d\n", *pDevInfoLenInput));
		//
        // Make sure the caller's output buffer is large enough
        // to hold the state of the bar graph
        //
        status = WdfRequestRetrieveOutputBuffer(Request,
                            *pDevInfoLenInput,
                            &pDevInfoData,
                            NULL);

        if (!NT_SUCCESS(status)) {
			KdPrint(("User's output buffer is too small for this IOCTL, expecting an BYTE\n"));
			bytesReturned = 0;
            break;
        }
        //
        // Call our function to get
        //
        status = GetDevInfoData(filterExt, *pDevInfoLenInput, pDevInfoData, &bytesReturned );

		//
        // If we succeeded return the user their data
        //
        if (!NT_SUCCESS(status)) {
            bytesReturned = 0;
        }
		
		KdPrint(("Completed IOCTL_OSRUSBFX2_FILTER_GETDEVINFODATA\n"));		
        break;
		
	default:
		status = STATUS_INVALID_DEVICE_REQUEST;
		break;
		
    }
    
    WdfRequestCompleteWithInformation ( Request, status, bytesReturned );

    KdPrint(("<-- FilterEvtIoDeviceControlFromRawPdo\n"));
    
    return;
}
Beispiel #28
0
VOID
SingleCompEvtIoDeviceControl(
    _In_ WDFQUEUE Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t OutputBufferLength,
    _In_ size_t InputBufferLength,
    _In_ ULONG IoControlCode
    )
/*++
Routine Description:

    Callback invoked by WDFQUEUE for a Device Io Control request.

Arguments:

    Queue - Device I/O control queue
              
    Request - Device I/O control request

    OutputBufferLength - Output buffer length for the I/O control

    InputBufferLength - Input buffer length for the I/O control

    IoControlCode - I/O control code
                
--*/
{
    NTSTATUS status;
    PPOWERFX_READ_COMPONENT_OUTPUT outputBuffer = NULL;
    WDFDEVICE device = NULL;
    ULONG componentData;
    ULONG_PTR information = 0;
    FDO_DATA *fdoContext = NULL;
    
    //
    // When we complete the request, make sure we don't get the I/O manager to 
    // copy any more data to the client address space than what we write to the
    // output buffer. The only data that we write to the output buffer is the 
    // component data and the C_ASSERT below ensures that the output buffer does
    // not have room to contain anything other than that.
    //
    C_ASSERT(sizeof(componentData) == sizeof(*outputBuffer));

    UNREFERENCED_PARAMETER(OutputBufferLength);
    UNREFERENCED_PARAMETER(InputBufferLength);

    //
    // This is a power-managed queue. So our queue stop/start logic should have 
    // ensured that we are in the active condition when a request is dispatched
    // from this queue.
    //
    device = WdfIoQueueGetDevice(Queue);
    fdoContext = FdoGetContext(device);
    if (FALSE == fdoContext->IsActive) {
        Trace(TRACE_LEVEL_ERROR, 
              "%!FUNC! - IOCTL %d was dispatched from WDFQUEUE %p when the "
              "component was not in an active condition.",
              IOCTL_POWERFX_READ_COMPONENT,
              Queue);
        WdfVerifierDbgBreakPoint();
    }
    
    //
    // Validate Ioctl code
    //
    if (IOCTL_POWERFX_READ_COMPONENT != IoControlCode) {
        status = STATUS_NOT_SUPPORTED;
        Trace(TRACE_LEVEL_ERROR, 
              "%!FUNC! -Unsupported IoControlCode. Expected: %d. Actual: %d."
              " %!status!.", 
              IOCTL_POWERFX_READ_COMPONENT,
              IoControlCode,
              status);
        goto exit;
    }
    
    //
    // Get the output buffer
    //
    status = WdfRequestRetrieveOutputBuffer(Request,
                                            sizeof(*outputBuffer),
                                            (PVOID*) &outputBuffer,
                                            NULL // Length
                                            );
    if (FALSE == NT_SUCCESS(status)) {
        Trace(TRACE_LEVEL_ERROR, 
              "%!FUNC! - WdfRequestRetrieveOutputBuffer failed with %!status!.",
              status);
        goto exit;
    }
    
    //
    // Read the data from the component
    //
    componentData = HwSimReadComponent(device);
    outputBuffer->ComponentData = componentData;
    information = sizeof(*outputBuffer);
    
    status = STATUS_SUCCESS;
    
exit:
    //
    // Complete the request
    //
    WdfRequestCompleteWithInformation(Request, status, information);
    return;
}
Beispiel #29
0
VOID
Bus_EvtIoDeviceControl(
    IN WDFQUEUE     Queue,
    IN WDFREQUEST   Request,
    IN size_t       OutputBufferLength,
    IN size_t       InputBufferLength,
    IN ULONG        IoControlCode
    )

/*++
Routine Description:

  Handle user mode PlugIn, UnPlug and device Eject requests.

Arguments:

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

    Request - Handle to a framework request object. This one represents
              the IRP_MJ_DEVICE_CONTROL IRP received by the framework.

    OutputBufferLength - Length, in bytes, of the request's output buffer,
                        if an output buffer is available.

    InputBufferLength - Length, in bytes, of the request's input buffer,
                        if an input buffer is available.
    IoControlCode - Driver-defined or system-defined I/O control code (IOCTL)
                    that is associated with the request.

Return Value:

   VOID

--*/
{
    NTSTATUS                 status = STATUS_INVALID_PARAMETER;
    WDFDEVICE                hDevice;
    size_t                   length = 0;
    PBUSENUM_PLUGIN_HARDWARE plugIn = NULL;
    PBUSENUM_UNPLUG_HARDWARE unPlug = NULL;
    PBUSENUM_EJECT_HARDWARE  eject  = NULL;


    UNREFERENCED_PARAMETER(OutputBufferLength);

    PAGED_CODE ();

    hDevice = WdfIoQueueGetDevice(Queue);

    KdPrint(("Bus_EvtIoDeviceControl: 0x%p\n", hDevice));

    switch (IoControlCode) {
    case IOCTL_BUSENUM_PLUGIN_HARDWARE:

        status = WdfRequestRetrieveInputBuffer (Request,
                                    sizeof (BUSENUM_PLUGIN_HARDWARE) +
                                    (sizeof(UNICODE_NULL) * 2), // 2 for double NULL termination (MULTI_SZ)
                                    &plugIn, &length);
        if( !NT_SUCCESS(status) ) {
            KdPrint(("WdfRequestRetrieveInputBuffer failed 0x%x\n", status));
            break;
        }

        ASSERT(length == InputBufferLength);

        if (sizeof (BUSENUM_PLUGIN_HARDWARE) == plugIn->Size)
        {

            length = (InputBufferLength - sizeof (BUSENUM_PLUGIN_HARDWARE))/sizeof(WCHAR);
            //
            // Make sure the IDs is two NULL terminated.
            //
            if ((UNICODE_NULL != plugIn->HardwareIDs[length - 1]) ||
                (UNICODE_NULL != plugIn->HardwareIDs[length - 2])) {

                status = STATUS_INVALID_PARAMETER;
                break;
            }

            status = Bus_PlugInDevice( hDevice,
                                       plugIn->HardwareIDs,
                                       length,
                                       plugIn->SerialNo );
        }

        break;

    case IOCTL_BUSENUM_UNPLUG_HARDWARE:

        status = WdfRequestRetrieveInputBuffer( Request,
                                                sizeof(BUSENUM_UNPLUG_HARDWARE),
                                                &unPlug,
                                                &length );
        if( !NT_SUCCESS(status) ) {
            KdPrint(("WdfRequestRetrieveInputBuffer failed 0x%x\n", status));
            break;
        }

        if (unPlug->Size == InputBufferLength)
        {

            status= Bus_UnPlugDevice(hDevice, unPlug->SerialNo );

        }

        break;

    case IOCTL_BUSENUM_EJECT_HARDWARE:

        status = WdfRequestRetrieveInputBuffer (Request,
                                                sizeof (BUSENUM_EJECT_HARDWARE),
                                                &eject, &length);
        if( !NT_SUCCESS(status) ) {
            KdPrint(("WdfRequestRetrieveInputBuffer failed 0x%x\n", status));
            break;
        }

        if (eject->Size == InputBufferLength)
        {
            status= Bus_EjectDevice(hDevice, eject->SerialNo);

        }

        break;

    default:
        break; // default status is STATUS_INVALID_PARAMETER
    }

    WdfRequestCompleteWithInformation(Request, status, length);
}
Beispiel #30
0
VOID
NdisprotSendComplete(
    IN NDIS_HANDLE                  ProtocolBindingContext,
    IN PNET_BUFFER_LIST             pNetBufferList,
    IN ULONG                        SendCompleteFlags
    )
/*++

Routine Description:

    NDIS entry point called to signify completion of a packet send.
    We pick up and complete the Write IRP corresponding to this packet.

Arguments:

    ProtocolBindingContext - pointer to open context
    pNetBufferList - NetBufferList that completed send
    SendCompleteFlags - Specifies if the caller is at DISPATCH level

Return Value:

    None

--*/
{
    PNDISPROT_OPEN_CONTEXT      pOpenContext;
    PNET_BUFFER_LIST            CurrNetBufferList = NULL;
    PNET_BUFFER_LIST            NextNetBufferList;
    NDIS_STATUS                 CompletionStatus;
    BOOLEAN                     DispatchLevel;
    WDFREQUEST                  request;
    PREQUEST_CONTEXT            reqContext;


    pOpenContext = (PNDISPROT_OPEN_CONTEXT)ProtocolBindingContext;
    NPROT_STRUCT_ASSERT(pOpenContext, oc);
    DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendCompleteFlags);


    for (CurrNetBufferList = pNetBufferList;
            CurrNetBufferList != NULL;
            CurrNetBufferList = NextNetBufferList)
    {
        NextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(CurrNetBufferList);

        request = NPROT_REQUEST_FROM_SEND_NBL(CurrNetBufferList);
        reqContext = GetRequestContext(request);
        CompletionStatus = NET_BUFFER_LIST_STATUS(CurrNetBufferList);

        DEBUGP(DL_INFO, ("SendComplete: NetBufferList %p/IRP %p/Length %d "
                        "completed with status %x\n",
                        CurrNetBufferList, request, reqContext->Length,
                        CompletionStatus));

		//
        //  We are done with the NDIS_PACKET:
        //
        NPROT_DEREF_SEND_NBL(CurrNetBufferList, DispatchLevel);
        CurrNetBufferList = NULL;

        if (CompletionStatus == NDIS_STATUS_SUCCESS)
        {
            WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, reqContext->Length);
         }
        else
        {
            WdfRequestCompleteWithInformation(request, STATUS_UNSUCCESSFUL, 0);
        }

        NPROT_ACQUIRE_LOCK(&pOpenContext->Lock, DispatchLevel);
        pOpenContext->PendedSendCount--;

        if ((NPROT_TEST_FLAGS(pOpenContext->Flags, NPROTO_BIND_FLAGS, NPROTO_BIND_CLOSING))
                && (pOpenContext->PendedSendCount == 0))
        {
            NPROT_ASSERT(pOpenContext->ClosingEvent != NULL);
            NPROT_SIGNAL_EVENT(pOpenContext->ClosingEvent);
            pOpenContext->ClosingEvent = NULL;
        }
        NPROT_RELEASE_LOCK(&pOpenContext->Lock, DispatchLevel);

        NPROT_DEREF_OPEN(pOpenContext); // send complete - dequeued send IRP
    }

}