Beispiel #1
0
VOID
kmdf1394_EvtDeviceSelfManagedIoCleanup (
                                        IN  WDFDEVICE Device)
/*++

Routine Description:

    EvtDeviceSelfManagedIoCleanup is called by the Framework when the device is
    being torn down, either in response to IRP_MN_REMOVE_DEVICE or
    IRP_MN_SURPRISE_REMOVE_DEVICE.  It will be called only once.  Its job is to
    stop all outstanding I/O in the driver that the Framework is not managing.

Arguments:

    Device - Handle to a framework device object.

Return Value:

    None

--*/
{
    PDEVICE_EXTENSION deviceExtension = NULL;
    PLIST_ENTRY listEntry = NULL;


    Enter();

    deviceExtension = GetDeviceContext(Device);

    DoTraceLevelMessage(TRACE_LEVEL_WARNING, 
                        TRACE_FLAG_PNP,
                        "Removing KMDF1394VDEV.SYS.\n");

    //
    // lets free up any crom data structs we've allocated...
    //
    WdfSpinLockAcquire (deviceExtension->CromSpinLock);

    while (!IsListEmpty (&deviceExtension->CromData))
    {
        PCROM_DATA      CromData;

        //
        // get struct off list
        //
        listEntry = RemoveHeadList (&deviceExtension->CromData);
        CromData = CONTAINING_RECORD (listEntry, CROM_DATA, CromList);

        //
        // need to free up everything associated with this allocate...
        //
        if (CromData)
        {
            if (CromData->Buffer)
            {
                ExFreePoolWithTag (CromData->Buffer, POOLTAG_KMDF_VDEV);
            }

            if (CromData->pMdl)
            {
                IoFreeMdl (CromData->pMdl);
            }
            //
            // we already checked CromData
            //
            ExFreePoolWithTag (CromData, POOLTAG_KMDF_VDEV);
        }
    }

    WdfSpinLockRelease (deviceExtension->CromSpinLock);

    //
    // lets free up any allocated addresses and deallocate all
    // memory associated with them...
    //
    WdfSpinLockAcquire (deviceExtension->AsyncSpinLock);

    while (!IsListEmpty (&deviceExtension->AsyncAddressData)) 
    {
        PASYNC_ADDRESS_DATA     AsyncAddressData;

        //
        // get struct off list
        //
        listEntry = RemoveHeadList (&deviceExtension->AsyncAddressData);

        AsyncAddressData = CONTAINING_RECORD (
            listEntry, 
            ASYNC_ADDRESS_DATA,
            AsyncAddressList);

        // 
        // need to free up everything associated with this allocate...
        //
        if (AsyncAddressData->pMdl)
        {
            IoFreeMdl (AsyncAddressData->pMdl);
        }

        if (AsyncAddressData->Buffer)
        {
            ExFreePoolWithTag(AsyncAddressData->Buffer, POOLTAG_KMDF_VDEV);
        }

        if (AsyncAddressData->AddressRange)
        {
            ExFreePoolWithTag(AsyncAddressData->AddressRange, POOLTAG_KMDF_VDEV);
        }

        ExFreePoolWithTag(AsyncAddressData, POOLTAG_KMDF_VDEV);
    }


    WdfSpinLockRelease(deviceExtension->AsyncSpinLock);

    //
    // TODO: Free up any attached isoch buffers when
    // we get the attach / detach code inserted again.
    //

    //
    // Remove any isoch resource data
    //
    WHILE (TRUE) 
    {
        WdfSpinLockAcquire(deviceExtension->IsochResourceSpinLock);

        if (!IsListEmpty(&deviceExtension->IsochResourceData)) 
        {
            PISOCH_RESOURCE_DATA    IsochResourceData = NULL;

            listEntry = RemoveHeadList(&deviceExtension->CromData);

            IsochResourceData = CONTAINING_RECORD (
                listEntry,
                ISOCH_RESOURCE_DATA,
                IsochResourceList);

            WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock);

            DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, 
                                TRACE_FLAG_PNP, 
                                "Surprise Removal: IsochResourceData = 0x%p\n",
                                IsochResourceData);

            if (IsochResourceData) 
            {
                PIRB pIrb;
                WDFREQUEST request;
                NTSTATUS ntStatus;

                DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, 
                                    TRACE_FLAG_PNP, 
                                    "Surprise Removal: Freeing hResource = 0x%p\n",
                                    IsochResourceData->hResource);

                ntStatus = WdfRequestCreate (
                    WDF_NO_OBJECT_ATTRIBUTES,
                    deviceExtension->StackIoTarget,
                    &request);
                if (!NT_SUCCESS (ntStatus)) 
                {
                    DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                                        TRACE_FLAG_PNP, 
                                        "Failed to allocate request %!STATUS!\n", 
                                        ntStatus);
                }
                else 
                {
                    pIrb = ExAllocatePoolWithTag(
                        NonPagedPool, 
                        sizeof(IRB), 
                        POOLTAG_KMDF_VDEV);
                    if (!pIrb) 
                    {
                        WdfObjectDelete(request);
                        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                                            TRACE_FLAG_PNP, 
                                            "Failed to allocate pIrb!\n");
                    }
                    else 
                    {
                        RtlZeroMemory (pIrb, sizeof (IRB));
                        pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
                        pIrb->Flags = 0;
                        pIrb->u.IsochFreeResources.hResource = \
                            IsochResourceData->hResource;

                        ntStatus = kmdf1394_SubmitIrpSynch (
                            deviceExtension->StackIoTarget, 
                            request, 
                            pIrb);
                        if (!NT_SUCCESS (ntStatus)) 
                        {
                            DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                                                TRACE_FLAG_PNP, 
                                                "SubmitIrpSync failed = %!STATUS!\n", 
                                                ntStatus);
                        }

                        ExFreePoolWithTag (pIrb, POOLTAG_KMDF_VDEV);
                        WdfObjectDelete (request);
                    } // else
                } // else
            } // if (IsochResourceData) 
        } //  if (!IsListEmpty(&deviceExtension->IsochResourceData)) 
        else 
        {
            WdfSpinLockRelease (deviceExtension->IsochResourceSpinLock);
            break;
        }
    }

    ExitS(STATUS_SUCCESS);
} // kmdf1394_EvtDeviceSelfManagedIoCleanup
Beispiel #2
0
VOID
OnIoDeviceControl(
_In_  WDFQUEUE    FxQueue,
_In_  WDFREQUEST  FxRequest,
_In_  size_t      OutputBufferLength,
_In_  size_t      InputBufferLength,
_In_  ULONG       IoControlCode
)
/*++
Routine Description:

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

Arguments:

FxQueue - Handle to the framework queue object that is associated
with the I/O request.
FxRequest - 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

--*/
{
	FuncEntry(TRACE_FLAG_SPBAPI);

	WDFDEVICE device;
	PDEVICE_CONTEXT pDevice;
	BOOLEAN fSync = FALSE;
	NTSTATUS status = STATUS_SUCCESS;
	UNREFERENCED_PARAMETER(OutputBufferLength);
	UNREFERENCED_PARAMETER(InputBufferLength);

	device = WdfIoQueueGetDevice(FxQueue);
	pDevice = GetDeviceContext(device);

	ElanPrint(
		DEBUG_LEVEL_INFO, DBG_IOCTL,
		"DeviceIoControl request %p received with IOCTL=%lu",
		FxRequest,
		IoControlCode);
	ElanPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
		"%s, Queue:0x%p, Request:0x%p\n",
		DbgHidInternalIoctlString(IoControlCode),
		FxQueue,
		FxRequest
		);

	//
	// Translate the test IOCTL into the appropriate 
	// SPB API method.  Open and close are completed 
	// synchronously.
	//

	switch (IoControlCode)
	{
	case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
		//
		// Retrieves the device's HID descriptor.
		//
		status = ElanGetHidDescriptor(device, FxRequest);
		fSync = TRUE;
		break;

	case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
		//
		//Retrieves a device's attributes in a HID_DEVICE_ATTRIBUTES structure.
		//
		status = ElanGetDeviceAttributes(FxRequest);
		fSync = TRUE;
		break;

	case IOCTL_HID_GET_REPORT_DESCRIPTOR:
		//
		//Obtains the report descriptor for the HID device.
		//
		status = ElanGetReportDescriptor(device, FxRequest);
		fSync = TRUE;
		break;

	case IOCTL_HID_GET_STRING:
		//
		// Requests that the HID minidriver retrieve a human-readable string
		// for either the manufacturer ID, the product ID, or the serial number
		// from the string descriptor of the device. The minidriver must send
		// a Get String Descriptor request to the device, in order to retrieve
		// the string descriptor, then it must extract the string at the
		// appropriate index from the string descriptor and return it in the
		// output buffer indicated by the IRP. Before sending the Get String
		// Descriptor request, the minidriver must retrieve the appropriate
		// index for the manufacturer ID, the product ID or the serial number
		// from the device extension of a top level collection associated with
		// the device.
		//
		status = ElanGetString(FxRequest);
		fSync = TRUE;
		break;

	case IOCTL_HID_WRITE_REPORT:
	case IOCTL_HID_SET_OUTPUT_REPORT:
		//
		//Transmits a class driver-supplied report to the device.
		//
		status = BOOTTRACKPAD(pDevice);
		if (!NT_SUCCESS(status)){
			ElanPrint(DBG_IOCTL, DEBUG_LEVEL_ERROR, "Error booting Elan device!\n");
		}
		fSync = TRUE;
		break;

	case IOCTL_HID_READ_REPORT:
	case IOCTL_HID_GET_INPUT_REPORT:
		//
		// Returns a report from the device into a class driver-supplied buffer.
		// 
		status = ElanReadReport(pDevice, FxRequest, &fSync);
		break;

	case IOCTL_HID_GET_FEATURE:
		//
		// returns a feature report associated with a top-level collection
		//
		status = ElanGetFeature(pDevice, FxRequest, &fSync);
		break;
	case IOCTL_HID_ACTIVATE_DEVICE:
		//
		// Makes the device ready for I/O operations.
		//
	case IOCTL_HID_DEACTIVATE_DEVICE:
		//
		// Causes the device to cease operations and terminate all outstanding
		// I/O requests.
		//
	default:
		fSync = TRUE;
		status = STATUS_NOT_SUPPORTED;
		ElanPrint(
			DEBUG_LEVEL_INFO, DBG_IOCTL,
			"Request %p received with unexpected IOCTL=%lu",
			FxRequest,
			IoControlCode);
	}

	//
	// Complete the request if necessary.
	//

	if (fSync)
	{
		ElanPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
			"%s completed, Queue:0x%p, Request:0x%p\n",
			DbgHidInternalIoctlString(IoControlCode),
			FxQueue,
			FxRequest
			);

		WdfRequestComplete(FxRequest, status);
	}
	else {
		ElanPrint(DEBUG_LEVEL_INFO, DBG_IOCTL,
			"%s deferred, Queue:0x%p, Request:0x%p\n",
			DbgHidInternalIoctlString(IoControlCode),
			FxQueue,
			FxRequest
			);
	}

	FuncExit(TRACE_FLAG_SPBAPI);
}
Beispiel #3
0
VOID
ReadWriteBulkEndPoints(
    IN WDFQUEUE         Queue,
    IN WDFREQUEST       Request,
    IN ULONG            Length,
    IN WDF_REQUEST_TYPE RequestType
    )
/*++

Routine Description:

    This callback is invoked when the framework received  WdfRequestTypeRead or
    RP_MJ_WRITE request. This read/write is performed in stages of
    MAX_TRANSFER_SIZE. Once a stage of transfer is complete, then the
    request is circulated again, until the requested length of transfer is
    performed.

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 WdfRequestTypeRead/WdfRequestTypeWrite IRP received by the framework.

    Length - Length of the input/output buffer.

Return Value:

   VOID

--*/
{
    size_t                totalLength = Length;
    size_t                stageLength = 0;
    NTSTATUS              status;
    PVOID                 virtualAddress = 0;
    PREQUEST_CONTEXT      rwContext = NULL;
    PFILE_CONTEXT         fileContext = NULL;
    WDFUSBPIPE            pipe;
    WDFMEMORY             reqMemory;
    WDFMEMORY_OFFSET      offset;
    WDF_OBJECT_ATTRIBUTES objectAttribs;
    PDEVICE_CONTEXT       deviceContext;

    kJtag_DbgPrint(3, ("kJtag_DispatchReadWrite - begins\n"));

    //
    // First validate input parameters.
    //
    deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

    if (totalLength > deviceContext->MaximumTransferSize) {
        kJtag_DbgPrint(1, ("Transfer length > circular buffer\n"));
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    if ((RequestType != WdfRequestTypeRead) &&
        (RequestType != WdfRequestTypeWrite)) {
        kJtag_DbgPrint(1, ("RequestType has to be either Read or Write\n"));
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    //
    // Get the pipe associate with this request.
    //
    fileContext = GetFileContext(WdfRequestGetFileObject(Request));
    pipe = fileContext->Pipe;

    rwContext = GetRequestContext(Request);

    if(RequestType == WdfRequestTypeRead) {
        status = WdfRequestRetrieveOutputBuffer(Request, Length, &virtualAddress, &totalLength);
        rwContext->Read = TRUE;

    } else { //Write

        status = WdfRequestRetrieveInputBuffer(Request, Length, &virtualAddress, &totalLength);
        rwContext->Read = FALSE;
    }

    if(!NT_SUCCESS(status)){
        kJtag_DbgPrint(1, ("WdfRequestRetrieveInputBuffer failed\n"));
        goto Exit;
    }

    //
    // If the totalLength exceeds MAX_TRANSFER_SIZE, we will break
    // that into multiple transfer of size no more than MAX_TRANSFER_SIZE
    // in each stage.
    //
    if (totalLength > MAX_TRANSFER_SIZE) {
        stageLength = MAX_TRANSFER_SIZE;
    }
    else {
        stageLength = totalLength;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs);
    objectAttribs.ParentObject = Request;
    status = WdfMemoryCreatePreallocated(&objectAttribs,
                                         virtualAddress,
                                         totalLength,
                                         &reqMemory);
    if(!NT_SUCCESS(status)){
        kJtag_DbgPrint(1, ("WdfMemoryCreatePreallocated failed\n"));
        goto Exit;
    }

    offset.BufferOffset = 0;
    offset.BufferLength = stageLength;

    //
    // The framework format call validates to make sure that you are reading or
    // writing to the right pipe type, sets the appropriate transfer flags,
    // creates an URB and initializes the request.
    //
    if(RequestType == WdfRequestTypeRead) {

        kJtag_DbgPrint(3, ("Read operation\n"));
        status = WdfUsbTargetPipeFormatRequestForRead(pipe,
                                                      Request,
                                                      reqMemory,
                                                      &offset);
    } else {

        kJtag_DbgPrint(3, ("Write operation\n"));
        status = WdfUsbTargetPipeFormatRequestForWrite(pipe,
                                                       Request,
                                                       reqMemory,
                                                       &offset);
    }

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

    WdfRequestSetCompletionRoutine(
                            Request,
                            ReadWriteCompletion,
                            NULL);
    //
    // set REQUEST_CONTEXT parameters.
    //
    rwContext->Length  = totalLength - stageLength;
    rwContext->Numxfer = 0;

    //
    // Send the request asynchronously.
    //
    if (WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS) == FALSE) {
        kJtag_DbgPrint(1, ("WdfRequestSend failed\n"));
        status = WdfRequestGetStatus(Request);
        goto Exit;
    }


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

    kJtag_DbgPrint(3, ("kJtag_DispatchReadWrite - ends\n"));

    return;
}
Beispiel #4
0
// In this callback, the driver does whatever is necessary to make the hardware ready to use.
// In the case of a USB device, this involves reading and selecting descriptors.
NTSTATUS
HidFx2EvtDevicePrepareHardware(
    _In_ WDFDEVICE    hDevice,
    _In_ WDFCMRESLIST hResourceList,
    _In_ WDFCMRESLIST hResourceListTranslated
   )
{
    NTSTATUS                            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION                   pDevContext = NULL;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    WDF_OBJECT_ATTRIBUTES               attributes;
    PUSB_DEVICE_DESCRIPTOR              pUsbDeviceDescriptor = NULL;

    UNREFERENCED_PARAMETER(hResourceList);
    UNREFERENCED_PARAMETER(hResourceListTranslated);

    PAGED_CODE ();

    TraceVerbose(DBG_INIT, "(%!FUNC!) Enter\n");

    pDevContext = GetDeviceContext(hDevice);

    // Create a WDFUSBDEVICE object. WdfUsbTargetDeviceCreate obtains the USB device descriptor and the first USB configuration
    //descriptor from the device and stores them. It also creates a framework USB interface object for each interface in the device's first configuration.
    //
    // The parent of each USB device object is the driver's framework driver object. The driver cannot change this parent, and the ParentObject
    // member or the WDF_OBJECT_ATTRIBUTES structure must be NULL.
    //
    // We only create device the first time PrepareHardware is called. If the device is restarted by pnp manager for resource rebalance, we 
    // will use the same device handle but then select the interfaces again because the USB stack could reconfigure the device on restart.
    if (pDevContext->hUsbDevice == NULL)
    {
        status = WdfUsbTargetDeviceCreate(hDevice, WDF_NO_OBJECT_ATTRIBUTES, &pDevContext->hUsbDevice);
        if (!NT_SUCCESS(status))
        {
            TraceErr(DBG_PNP, "(%!FUNC!) WdfUsbTargetDeviceCreate failed %!STATUS!\n", status);
            return status;
        }
    }

    // Select a device configuration by using a WDF_USB_DEVICE_SELECT_CONFIG_PARAMS
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);
    status = WdfUsbTargetDeviceSelectConfig(pDevContext->hUsbDevice, WDF_NO_OBJECT_ATTRIBUTES, &configParams);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfUsbTargetDeviceSelectConfig failed %!STATUS!\n", status);
        return status;
    }

    pDevContext->hUsbInterface = configParams.Types.SingleInterface.ConfiguredUsbInterface;

    // Get the device descriptor and store it in device context
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = hDevice;
    status = WdfMemoryCreate(&attributes,
                             NonPagedPool,
                             0,
                             sizeof(USB_DEVICE_DESCRIPTOR),
                             &pDevContext->hDeviceDescriptor,
                             &pUsbDeviceDescriptor);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfMemoryCreate for Device Descriptor failed %!STATUS!\n", status);
        return status;
    }

    WdfUsbTargetDeviceGetDeviceDescriptor(pDevContext->hUsbDevice, pUsbDeviceDescriptor);

    // Get the Interrupt pipe. There are other endpoints but we are only interested in interrupt endpoint since our HID data comes from this
    pDevContext->hInterruptPipe = WdfUsbInterfaceGetConfiguredPipe(pDevContext->hUsbInterface, INTERRUPT_ENDPOINT_INDEX, NULL);
    if (NULL == pDevContext->hInterruptPipe)
    {
        TraceErr(DBG_PNP, "(%!FUNC!) Failed to get interrupt pipe info\n");
        status = STATUS_INVALID_DEVICE_STATE;
        return status;
    }

    // Tell the framework that it's okay to read less than MaximumPacketSize
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDevContext->hInterruptPipe);

    //configure continuous reader
    status = HidFx2ConfigContReaderForInterruptEndPoint(pDevContext);

    TraceVerbose(DBG_INIT, "(%!FUNC!) Exit, Status: %!STATUS!\n", status);

    return status;
}
Beispiel #5
0
/******************************************************************************

  WDF_DEVICE_SEFL_MANAGED_IO_CLEANUP
  (Only the CromData cleanup part of it)

 ******************************************************************************/
VOID
t1394_EvtDeviceSelfManagedIoCleanup(
   /*IN*/ WDFDEVICE Device
    )
/*++

Routine Description:

    EvtDeviceSelfManagedIoCleanup is called by the Framework when the device is
    being torn down, either in response to IRP_MN_REMOVE_DEVICE or
    IRP_MN_SURPRISE_REMOVE_DEVICE.  It will be called only once.  Its job is to
    stop all outstanding I/O in the driver that the Framework is not managing.

Arguments:

    Device - Handle to a framework device object.

Return Value:

    None

--*/
{
    PDEVICE_EXTENSION   deviceExtension;
     PLIST_ENTRY         listEntry;

    //ENTER("t1394_PnpRemoveDevice");

    deviceExtension = GetDeviceContext(Device);

    // TRACE(TL_WARNING, ("Removing 1394VDEV.SYS.\n"));

    // lets free up any crom data structs we've allocated...

    WdfSpinLockAcquire(deviceExtension->CromSpinLock);

    while (!IsListEmpty(&deviceExtension->CromData)) {

        PCROM_DATA      CromData;

        // get struct off list

        listEntry = RemoveHeadList(&deviceExtension->CromData);
        CromData = CONTAINING_RECORD(listEntry, CROM_DATA, CromList);

        // need to free up everything associated with this allocate...
        if (CromData)
        {
	  if (CromData->Buffer) {
                ExFreePool(CromData->Buffer);
	  }
	  if (CromData->pMdl) {
	    IoFreeMdl(CromData->pMdl);
	  }
	  // we already checked CromData
	  ExFreePool(CromData);
        }
    }


    WdfSpinLockRelease(deviceExtension->CromSpinLock);

/*     // lets free up any allocated addresses and deallocate all */
/*     // memory associated with them... */

/*     WdfSpinLockAcquire(deviceExtension->AsyncSpinLock); */

/*     while (!IsListEmpty(&deviceExtension->AsyncAddressData)) { */

/*         PASYNC_ADDRESS_DATA     AsyncAddressData; */

/*         // get struct off list */
/*         listEntry = RemoveHeadList(&deviceExtension->AsyncAddressData); */

/*         AsyncAddressData = CONTAINING_RECORD(listEntry, ASYNC_ADDRESS_DATA, */
/*                                                                             AsyncAddressList); */

/*         // need to free up everything associated with this allocate... */
/*         if (AsyncAddressData->pMdl) */
/*             IoFreeMdl(AsyncAddressData->pMdl); */

/*         if (AsyncAddressData->Buffer) */
/*             ExFreePool(AsyncAddressData->Buffer); */

/*         if (AsyncAddressData->AddressRange) */
/*             ExFreePool(AsyncAddressData->AddressRange); */

/*         if (AsyncAddressData) */
/*             ExFreePool(AsyncAddressData); */
/*     } */


/*     WdfSpinLockRelease(deviceExtension->AsyncSpinLock); */

/*     // */
/*     // Free up any attached isoch buffers */
/*     // Note: There are known bugs in this code path */
/*     // */
/*     WHILE (TRUE) { */

/*         WdfSpinLockAcquire(deviceExtension->IsochSpinLock); */

/*         if (!IsListEmpty(&deviceExtension->IsochDetachData)) { */

/*             PISOCH_DETACH_DATA  IsochDetachData; */

/*             IsochDetachData = (PISOCH_DETACH_DATA) */
/*                 RemoveHeadList(&deviceExtension->IsochDetachData); */

/*             // TRACE(TL_TRACE, ("Surprise Removal: IsochDetachData = 0x%x\n", */
/*                              IsochDetachData)); */

/*             KeCancelTimer(&IsochDetachData->Timer); */

/*             WdfSpinLockRelease(deviceExtension->IsochSpinLock); */

/*             // TRACE(TL_TRACE, ("Surprise Removal: IsochDetachData->Irp = 0x%x\n", */
/*                              IsochDetachData->Request)); */

/*             // need to save the status of the attach */
/*             // we'll clean up in the same spot for success's and timeout's */
/*             IsochDetachData->AttachStatus = STATUS_SUCCESS; */

/*             // detach no matter what... */
/*             IsochDetachData->bDetach = TRUE; */

/*             t1394_IsochCleanup(IsochDetachData); */
/*         } */
/*         else { */

/*             WdfSpinLockRelease(deviceExtension->IsochSpinLock); */
/*             break; */
/*         } */
/*     } */

/*     // */
/*     // Remove any isoch resource data */
/*     // */
/*     WHILE (TRUE) { */

/*         WdfSpinLockAcquire(deviceExtension->IsochResourceSpinLock); */

/*         if (!IsListEmpty(&deviceExtension->IsochResourceData)) { */

/*             PISOCH_RESOURCE_DATA    IsochResourceData = NULL; */

/*             listEntry = RemoveHeadList(&deviceExtension->CromData); */

/*             IsochResourceData = CONTAINING_RECORD(listEntry, */
/*                                                   ISOCH_RESOURCE_DATA, */
/*                                                   IsochResourceList); */

/*             WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock); */

/*             // TRACE(TL_TRACE, ("Surprise Removal: IsochResourceData = 0x%x\n", */
/*                              IsochResourceData)); */

/*             if (IsochResourceData) { */

/*                 PIRB          pIrb; */
/*                 WDFREQUEST    request; */
/* 	         NTSTATUS status; */

/*                 // TRACE(TL_TRACE, ("Surprise Removal: Freeing hResource = 0x%x\n", */
/*                                  IsochResourceData->hResource)); */

/*                 status = WdfRequestCreate( */
/*                     WDF_NO_OBJECT_ATTRIBUTES, */
/*                     deviceExtension->StackIoTarget, */
/*                     &request); */

/*                 if (!NT_SUCCESS(status)) { */
/*                     // TRACE(TL_ERROR, ("Failed to allocate request %x\n", status)); */
/*                 } */
/*                 else { */

/*                     pIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), POOLTAG_1394); */

/*                     if (!pIrb) { */

/*                         WdfObjectDelete(request); */

/*                         // TRACE(TL_ERROR, ("Failed to allocate pIrb!\n")); */
/*                     } */
/*                     else { */

/*                         RtlZeroMemory (pIrb, sizeof (IRB)); */
/*                         pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES; */
/*                         pIrb->Flags = 0; */
/*                         pIrb->u.IsochFreeResources.hResource = IsochResourceData->hResource; */

/*                         status = t1394_SubmitIrpSynch(deviceExtension->StackIoTarget, request, pIrb); */

/*                         if (!NT_SUCCESS(status)) { */

/*                             // TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", status)); */
/*                         } */

/*                         ExFreePool(pIrb); */
/*                         WdfObjectDelete(request); */
/*                     } */
/*                 } */
/*             } */
/*         } */
/*         else { */


/*             WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock); */
/*             break; */
/*         } */
/*     } */

    //EXIT("t1394_PnpRemoveDevice", STATUS_SUCCESS);

} // t1394_PnpRemoveDevice
Beispiel #6
0
//HidFx2EvtDeviceAdd is called by the framework in response to AddDevicecall from the PnP manager. 
//We create and initialize a WDF device object to represent a new instance of  device.
//
NTSTATUS HidFx2EvtDeviceAdd(_In_ WDFDRIVER hDriver, _Inout_ PWDFDEVICE_INIT pDeviceInit)
{
    NTSTATUS                      status = STATUS_SUCCESS;
    WDF_IO_QUEUE_CONFIG           queueConfig;
    WDF_OBJECT_ATTRIBUTES         attributes;
    WDFDEVICE                     hDevice;
    PDEVICE_EXTENSION             pDevContext = NULL;
    WDFQUEUE                      hQueue;
    WDF_PNPPOWER_EVENT_CALLBACKS  pnpPowerCallbacks;
    WDF_TIMER_CONFIG              timerConfig;
    WDFTIMER                      hTimer;

    UNREFERENCED_PARAMETER(hDriver);

    PAGED_CODE();

    TraceVerbose(DBG_PNP, "(%!FUNC!) Enter\n");

    // Tell framework this is a filter driver.
    WdfFdoInitSetFilter(pDeviceInit);

    // Initialize pnp-power callbacks, attributes and a context area for the device object.
    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);

    // For usb devices, PrepareHardware callback is the to place select the interface and configure the device.
    pnpPowerCallbacks.EvtDevicePrepareHardware = HidFx2EvtDevicePrepareHardware;

    // These two callbacks start and stop the wdfusb pipe continuous reader as we go in and out of the D0-working state.
    pnpPowerCallbacks.EvtDeviceD0Entry = HidFx2EvtDeviceD0Entry;
    pnpPowerCallbacks.EvtDeviceD0Exit  = HidFx2EvtDeviceD0Exit;

    WdfDeviceInitSetPnpPowerEventCallbacks(pDeviceInit, &pnpPowerCallbacks);

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_EXTENSION);

    // Create a framework device object.This call will in turn create a WDM device object, attach to the lower stack.
    status = WdfDeviceCreate(&pDeviceInit, &attributes, &hDevice);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfDeviceCreate failed with status code %!STATUS!\n", status);
        return status;
    }

    pDevContext = GetDeviceContext(hDevice);
    
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel);
    queueConfig.EvtIoInternalDeviceControl = HidFx2EvtInternalDeviceControl;

    status = WdfIoQueueCreate(hDevice, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &hQueue);
    if (!NT_SUCCESS (status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfIoQueueCreate failed 0x%x\n", status);
        return status;
    }

    // Register a manual I/O queue for handling Interrupt Message Read Requests.
    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);

    // This queue is used for requests that dont directly access the device.
    // The requests in this queue are serviced only when the device is in a fully powered state and sends an interrupt.
    queueConfig.PowerManaged = WdfFalse;

    status = WdfIoQueueCreate(hDevice, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &pDevContext->hInterruptMsgQueue);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfIoQueueCreate failed %!STATUS!\n", status);
        return status;
    }

    // Create a timer to handle debouncing of switchpack 
    WDF_TIMER_CONFIG_INIT(&timerConfig, HidFx2EvtTimerFunction);
    timerConfig.AutomaticSerialization = FALSE;

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = hDevice;
    status = WdfTimerCreate(&timerConfig, &attributes, &hTimer);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_PNP, "(%!FUNC!) WdfTimerCreate failed status:%!STATUS!\n", status);
        return status;
    }

    pDevContext->hDebounceTimer = hTimer;

    TraceVerbose(DBG_PNP, "(%!FUNC!) Exit\n");
    return status;
}
NTSTATUS
HidFx2EvtDevicePrepareHardware(
    IN WDFDEVICE    Device,
    IN WDFCMRESLIST ResourceList,
    IN WDFCMRESLIST ResourceListTranslated
    )
/*++

Routine Description:

    In this callback, the driver does whatever is necessary to make the
    hardware ready to use.  In the case of a USB device, this involves
    reading and selecting descriptors.

Arguments:

    Device - handle to a device

    ResourceList - A handle to a framework resource-list object that
    identifies the raw hardware resourcest

    ResourceListTranslated - A handle to a framework resource-list object
    that identifies the translated hardware resources

Return Value:

    NT status value

--*/
{
    NTSTATUS                            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION                   devContext = NULL;
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    WDF_OBJECT_ATTRIBUTES               attributes;
    PUSB_DEVICE_DESCRIPTOR              usbDeviceDescriptor = NULL;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);

    PAGED_CODE ();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,
        "HidFx2EvtDevicePrepareHardware Enter\n");

    devContext = GetDeviceContext(Device);

    //
    // Create a WDFUSBDEVICE object. WdfUsbTargetDeviceCreate obtains the
    // USB device descriptor and the first USB configuration descriptor from
    // the device and stores them. It also creates a framework USB interface
    // object for each interface in the device's first configuration.
    //
    // The parent of each USB device object is the driver's framework driver
    // object. The driver cannot change this parent, and the ParentObject
    // member or the WDF_OBJECT_ATTRIBUTES structure must be NULL.
    //
    // We only create device the first time PrepareHardware is called. If
    // the device is restarted by pnp manager for resource rebalance, we
    // will use the same device handle but then select the interfaces again
    // because the USB stack could reconfigure the device on restart.
    //
    if (devContext->UsbDevice == NULL) {
        status = WdfUsbTargetDeviceCreate(Device,
                                          WDF_NO_OBJECT_ATTRIBUTES,
                                          &devContext->UsbDevice);

        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                "WdfUsbTargetDeviceCreate failed 0x%x\n", status);
            return status;
        }

        //
        // TODO: If you are fetching configuration descriptor from device for
        // selecting a configuration or to parse other descriptors, call
        // HidFx2ValidateConfigurationDescriptor
        // to do basic validation on the descriptors before you access them.
        //

    }

    //
    // Select a device configuration by using a
    // WDF_USB_DEVICE_SELECT_CONFIG_PARAMS structure to specify USB
    // descriptors, a URB, or handles to framework USB interface objects.
    //
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

    status = WdfUsbTargetDeviceSelectConfig(devContext->UsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &configParams);
    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfUsbTargetDeviceSelectConfig failed %!STATUS!\n",
            status);
        return status;
    }

    devContext->UsbInterface =
                configParams.Types.SingleInterface.ConfiguredUsbInterface;

    //
    // Get the device descriptor and store it in device context
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = Device;
    status = WdfMemoryCreate(
                             &attributes,
                             NonPagedPoolNx,
                             0,
                             sizeof(USB_DEVICE_DESCRIPTOR),
                             &devContext->DeviceDescriptor,
                             &usbDeviceDescriptor
                             );

    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfMemoryCreate for Device Descriptor failed %!STATUS!\n",
            status);
        return status;
    }

    WdfUsbTargetDeviceGetDeviceDescriptor(
          devContext->UsbDevice,
          usbDeviceDescriptor
          );

    //
    // Get the Interrupt pipe. There are other endpoints but we are only
    // interested in interrupt endpoint since our HID data comes from that
    // endpoint. Another way to get the interrupt endpoint is by enumerating
    // through all the pipes in a loop and looking for pipe of Interrupt type.
    //
    devContext->InterruptPipe = WdfUsbInterfaceGetConfiguredPipe(
                                                  devContext->UsbInterface,
                                                  INTERRUPT_ENDPOINT_INDEX,
                                                  NULL);// pipeInfo

    if (NULL == devContext->InterruptPipe) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                    "Failed to get interrupt pipe info\n");
        status = STATUS_INVALID_DEVICE_STATE;
        return status;
    }

    //
    // Tell the framework that it's okay to read less than
    // MaximumPacketSize
    //
    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(devContext->InterruptPipe);

    //
    //configure continuous reader
    //
    status = HidFx2ConfigContReaderForInterruptEndPoint(devContext);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,
        "HidFx2EvtDevicePrepareHardware Exit, Status:0x%x\n", status);

    return status;
}
Beispiel #8
0
NTSTATUS
t1394_SetLocalHostProperties(
    /*IN*/ WDFDEVICE   Device,
    /*IN*/ WDFREQUEST             Request,
    /*IN*/ ULONG            nLevel,
    /*IN*/ PVOID            Information
    )
{
    NTSTATUS                ntStatus                = STATUS_SUCCESS;
    PDEVICE_EXTENSION       deviceExtension         = GetDeviceContext(Device);
    PIRB                    pIrb                    = NULL;
    PSET_LOCAL_HOST_PROPS3  R0_SetLocalHostProps3   = NULL;
    PCROM_DATA              CromData                = NULL;
    PLIST_ENTRY listHead, thisEntry;

    //ENTER("t1394_SetLocalHostProperties");

    // allocate irb
    pIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), POOLTAG_1394);
    if (!pIrb) {

        // TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit_SetLocalHostProperties;
    } // if



    RtlZeroMemory (pIrb, sizeof (IRB));
    pIrb->FunctionNumber = REQUEST_SET_LOCAL_HOST_PROPERTIES;
    pIrb->Flags = 0;

    // SI: writes to union broken
    // pIrb->u.SetLocalHostProperties.nLevel = nLevel;

    // TRACE(TL_TRACE, ("nLevel = 0x%x\n", nLevel));
    // TRACE(TL_TRACE, ("Information = 0x%x\n", Information));

    if (nLevel == SET_LOCAL_HOST_PROPERTIES_GAP_COUNT) {

        PSET_LOCAL_HOST_PROPS2  SetLocalHostProps2;

        SetLocalHostProps2 = (PSET_LOCAL_HOST_PROPS2)Information;

        // TRACE(TL_TRACE, ("GapCountLowerBound = 0x%x\n", SetLocalHostProps2->GapCountLowerBound));
        // SI: writes to union broken
        // pIrb->u.SetLocalHostProperties.Information = Information;
    }
    else if (nLevel == SET_LOCAL_HOST_PROPERTIES_MODIFY_CROM) {

        PSET_LOCAL_HOST_PROPS3  SetLocalHostProps3;

        SetLocalHostProps3 = (PSET_LOCAL_HOST_PROPS3)Information;

        // TRACE(TL_TRACE, ("fulFlags = 0x%x\n", SetLocalHostProps3->fulFlags));
        // TRACE(TL_TRACE, ("hCromData = 0x%x\n", SetLocalHostProps3->hCromData));
        // TRACE(TL_TRACE, ("nLength = 0x%x\n", SetLocalHostProps3->nLength));

        // since we need to create a mdl, we'll create another setlocalhostprops3
        // and pass that down to the bus driver
        R0_SetLocalHostProps3 = ExAllocatePoolWithTag(NonPagedPool,
                                                      sizeof(SET_LOCAL_HOST_PROPS3),
                                                      POOLTAG_1394);

        if (!R0_SetLocalHostProps3) {

            // TRACE(TL_ERROR, ("Failed to allocate R0_SetLocalHostProps3!\n"));
            if (pIrb)
                ExFreePool(pIrb);

            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
            goto Exit_SetLocalHostProperties;
        } // if

        // TRACE(TL_TRACE, ("R0_SetLocalHostProps3 = 0x%x\n", R0_SetLocalHostProps3));

        // copy over the contents...
        RtlCopyMemory( R0_SetLocalHostProps3,
                       SetLocalHostProps3,
                       sizeof(SET_LOCAL_HOST_PROPS3)
                       );

        // branch, depending if we are adding or removing
        if (R0_SetLocalHostProps3->fulFlags == SLHP_FLAG_ADD_CROM_DATA) {

            // we are adding an entry. let's get our crom data struct...
            CromData = ExAllocatePoolWithTag(NonPagedPool,
                                             sizeof(CROM_DATA),
                                             POOLTAG_1394);

            if (!CromData) {

                // TRACE(TL_ERROR, ("Failed to allocate CromData!\n"));
                if (pIrb)
                    ExFreePool(pIrb);

                if (R0_SetLocalHostProps3)
                    ExFreePool(R0_SetLocalHostProps3);

                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                goto Exit_SetLocalHostProperties;
            }

            // let's allocate our buffer...
            CromData->Buffer = ExAllocatePoolWithTag(NonPagedPool,
                                                     R0_SetLocalHostProps3->nLength,
                                                     POOLTAG_1394);

            // TRACE(TL_TRACE, ("CromData->Buffer = 0x%x\n", CromData->Buffer));

            if (!CromData->Buffer) {

                // TRACE(TL_ERROR, ("Failed to allocate CromData->Buffer!\n"));
                if (pIrb)
                    ExFreePool(pIrb);

                if (R0_SetLocalHostProps3)
                    ExFreePool(R0_SetLocalHostProps3);

                if (CromData)
                    ExFreePool(CromData);

                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                goto Exit_SetLocalHostProperties;
            }

            // copy over contents (mdl == ring 3 buffer)
            RtlCopyMemory(CromData->Buffer,
                          &SetLocalHostProps3->Mdl,
                          SetLocalHostProps3->nLength);

            R0_SetLocalHostProps3->Mdl = IoAllocateMdl (CromData->Buffer,
                                                        R0_SetLocalHostProps3->nLength,
                                                        FALSE,
                                                        FALSE,
                                                        NULL);
            if(R0_SetLocalHostProps3->Mdl == NULL) {

                // TRACE(TL_ERROR, ("Failed to allocate mdl for CromData->Buffer!\n"));
                if (pIrb)
                    ExFreePool(pIrb);

                if (R0_SetLocalHostProps3)
                    ExFreePool(R0_SetLocalHostProps3);

                if (CromData)
                    ExFreePool(CromData);

                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                goto Exit_SetLocalHostProperties;

            }
            MmBuildMdlForNonPagedPool(R0_SetLocalHostProps3->Mdl);

            // TRACE(TL_TRACE, ("Mdl = 0x%x\n", R0_SetLocalHostProps3->Mdl));
        }
        else if (SetLocalHostProps3->fulFlags == SLHP_FLAG_REMOVE_CROM_DATA) {

            // TRACE(TL_TRACE, ("hCromData = 0x%x\n", R0_SetLocalHostProps3->hCromData));
        }

        // SI: writes to union broken
        // pIrb->u.SetLocalHostProperties.Information = (PVOID)R0_SetLocalHostProps3;
    }

    ntStatus = t1394_SubmitIrpSynch(deviceExtension->StackIoTarget, Request, pIrb);

    if (!NT_SUCCESS(ntStatus)) {

        if (nLevel == SET_LOCAL_HOST_PROPERTIES_MODIFY_CROM) {

            if (R0_SetLocalHostProps3 &&
                R0_SetLocalHostProps3->fulFlags == SLHP_FLAG_ADD_CROM_DATA) {

                if (R0_SetLocalHostProps3->Mdl)
                    IoFreeMdl(R0_SetLocalHostProps3->Mdl);

                if (CromData) {
                    if (CromData->Buffer) {
                        ExFreePool(CromData->Buffer);
                    }
                    ExFreePool(CromData);
                }
            }

            if (R0_SetLocalHostProps3)
                ExFreePool(R0_SetLocalHostProps3);
        }

        // TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
    }
    else {

        if (nLevel == SET_LOCAL_HOST_PROPERTIES_MODIFY_CROM) {
            //
            // branch, depending if we are adding or removing
            //
            if (R0_SetLocalHostProps3 &&
                R0_SetLocalHostProps3->fulFlags == SLHP_FLAG_ADD_CROM_DATA) {

                PSET_LOCAL_HOST_PROPS3  SetLocalHostProps3;

                SetLocalHostProps3 = Information;
                SetLocalHostProps3->hCromData = R0_SetLocalHostProps3->hCromData;

                // TRACE(TL_TRACE, ("hCromData = 0x%x\n", SetLocalHostProps3->hCromData));

                if (CromData) {

                    CromData->hCromData = SetLocalHostProps3->hCromData;
                    CromData->pMdl = R0_SetLocalHostProps3->Mdl;

                    // need to add to our list...

                    WdfSpinLockAcquire(deviceExtension->CromSpinLock);
                    InsertHeadList(&deviceExtension->CromData, &CromData->CromList);

                    WdfSpinLockRelease(deviceExtension->CromSpinLock);
                }
            }
            else if (R0_SetLocalHostProps3 &&
                     R0_SetLocalHostProps3->fulFlags == SLHP_FLAG_REMOVE_CROM_DATA) {

                // have to find our struct...

                WdfSpinLockAcquire(deviceExtension->CromSpinLock);

                listHead = &deviceExtension->CromData;

                for(thisEntry = listHead->Flink;
                                thisEntry != listHead;
                                CromData = NULL, thisEntry = thisEntry->Flink)
                {
                    CromData = CONTAINING_RECORD(thisEntry, CROM_DATA, CromList);
                    if (CromData->hCromData == R0_SetLocalHostProps3->hCromData) {
                        RemoveEntryList(&CromData->CromList);
                        break;
                    }
                }

                WdfSpinLockRelease(deviceExtension->CromSpinLock);

                if (CromData) {

                    if (CromData->Buffer)
                        ExFreePool(CromData->Buffer);

                    if (CromData->pMdl)
                        IoFreeMdl(CromData->pMdl);

                    ExFreePool(CromData);
                }
            }

            if (R0_SetLocalHostProps3)
                ExFreePool(R0_SetLocalHostProps3);
        }
    }


Exit_SetLocalHostProperties:

    if (pIrb)
    {
        ExFreePool(pIrb);
    }


    //EXIT("t1394_SetLocalHostProperties", ntStatus);
    return(ntStatus);
} // t1394_SetLocalHostProperties
Beispiel #9
0
/*++
Routine Description:

This callback is invoked when the framework received  WdfRequestTypeRead or
WdfRequestTypeWrite request. This read/write is performed in stages of
MAX_TRANSFER_SIZE. Once a stage of transfer is complete, then the
request is circulated again, until the requested length of transfer is
performed.

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 WdfRequestTypeRead/WdfRequestTypeWrite IRP received by the framework.

Length - Length of the input/output buffer.

Return Value:

VOID
--*/
VOID ReadWriteBulkEndPoints(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG Length, IN WDF_REQUEST_TYPE RequestType)
{
    PMDL						newMdl = NULL;
	PMDL						requestMdl = NULL;
    PURB						urb = NULL;
    WDFMEMORY					urbMemory;
    ULONG						totalLength = Length;
    ULONG						stageLength = 0;
    ULONG						urbFlags = 0;
    NTSTATUS					status;
    ULONG_PTR					virtualAddress = 0;
    PREQUEST_CONTEXT			rwContext = NULL;
    PFILE_CONTEXT				fileContext = NULL;
    WDFUSBPIPE					pipe;
    WDF_USB_PIPE_INFORMATION	pipeInfo;
    WDF_OBJECT_ATTRIBUTES		objectAttribs;
    USBD_PIPE_HANDLE			usbdPipeHandle;
    PDEVICE_CONTEXT				deviceContext;
	WDF_REQUEST_SEND_OPTIONS	sendOptions;

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

    // First validate input parameters.
    deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

    if (totalLength > deviceContext->MaximumTransferSize)
	{
        PSDrv_DbgPrint(1, ("Transfer length (%d) is bigger then MaximumTransferSize (%d)!\n", totalLength, deviceContext->MaximumTransferSize));
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    if ((RequestType != WdfRequestTypeRead) && (RequestType != WdfRequestTypeWrite))
	{
        PSDrv_DbgPrint(1, ("RequestType has to be either Read or Write! (RequestType = %d)\n", RequestType));
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    // Get the pipe associate with this request.
    fileContext = GetFileContext(WdfRequestGetFileObject(Request));
    pipe = fileContext->Pipe;
    WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
    WdfUsbTargetPipeGetInformation(pipe, &pipeInfo);

    if((WdfUsbPipeTypeBulk != pipeInfo.PipeType) && (WdfUsbPipeTypeInterrupt != pipeInfo.PipeType))
	{
        PSDrv_DbgPrint(1, ("Usbd pipe type is not bulk or interrupt! (PipeType = %d)\n", pipeInfo.PipeType));
        status = STATUS_INVALID_DEVICE_REQUEST;
        goto Exit;
    }

    rwContext = GetRequestContext(Request);

    if(RequestType == WdfRequestTypeRead)
	{
        status = WdfRequestRetrieveOutputWdmMdl(Request, &requestMdl);
        if(!NT_SUCCESS(status))
		{
            PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputWdmMdl failed! (Status = %x)\n", status));
            goto Exit;
        }

        urbFlags |= USBD_TRANSFER_DIRECTION_IN;
        rwContext->Read = TRUE;
        PSDrv_DbgPrint(3, ("This is a read operation...\n"));
    }
	else
	{
        status = WdfRequestRetrieveInputWdmMdl(Request, &requestMdl);
        if(!NT_SUCCESS(status))
		{
			PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputWdmMdl failed! (Status = %x)\n", status));
            goto Exit;
        }

        urbFlags |= USBD_TRANSFER_DIRECTION_OUT;
        rwContext->Read = FALSE;
        PSDrv_DbgPrint(3, ("This is a write operation...\n"));
    }


    urbFlags |= USBD_SHORT_TRANSFER_OK;

    virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(requestMdl);

    // The transfer request is for totalLength. We can perform a max of MAX_TRANSFER_SIZE in each stage.
    if (totalLength > MAX_TRANSFER_SIZE)
	{
        stageLength = MAX_TRANSFER_SIZE;
    }
    else
	{
        stageLength = totalLength;
    }

    newMdl = IoAllocateMdl((PVOID)virtualAddress, totalLength, FALSE, FALSE, NULL);
    if (newMdl == NULL)
	{
        PSDrv_DbgPrint(1, ("IoAllocateMdl failed! (newMdl is NULL)\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    // Map the portion of user-buffer described by an mdl to another mdl
    IoBuildPartialMdl(requestMdl, newMdl, (PVOID)virtualAddress, stageLength);

    WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs);
    objectAttribs.ParentObject = Request;

    status = WdfMemoryCreate(&objectAttribs, NonPagedPool, POOL_TAG, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), &urbMemory, (PVOID*)&urb);
    if (!NT_SUCCESS(status))
	{
        PSDrv_DbgPrint(1, ("WdfMemoryCreate for urbMemory failed! (Status = %x)\n", status));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    usbdPipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(pipe);

    UsbBuildInterruptOrBulkTransferRequest(urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), usbdPipeHandle, NULL, newMdl, stageLength, urbFlags, NULL);

    status = WdfUsbTargetPipeFormatRequestForUrb(pipe, Request, urbMemory, NULL);
    if (!NT_SUCCESS(status))
	{
        PSDrv_DbgPrint(1, ("WdfUsbTargetPipeFormatRequestForUrb failed! (Status = %x)\n", status));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);

    // Set REQUEST_CONTEXT parameters.
    rwContext->UrbMemory       = urbMemory;
    rwContext->Mdl             = newMdl;
    rwContext->Length          = totalLength - stageLength;
    rwContext->Numxfer         = 0;
    rwContext->VirtualAddress  = virtualAddress + stageLength;

	// Set the timeout
	if (fileContext->nTimeOut != 0)
	{
		WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT);
		WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(fileContext->nTimeOut));

		PSDrv_DbgPrint(3, ("Pipe timeout is set to: %d\n", fileContext->nTimeOut));

		if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), &sendOptions))
		{
			status = WdfRequestGetStatus(Request);
			ASSERT(!NT_SUCCESS(status));
		}
	}
	else
	{
		if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS))
		{
			status = WdfRequestGetStatus(Request);
			ASSERT(!NT_SUCCESS(status));
		}
	}

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

        if (newMdl != NULL)
		{
            IoFreeMdl(newMdl);
        }
    }

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

    return;
}
Beispiel #10
0
VOID
HidFx2CompleteReadReport(
    WDFDEVICE Device
    )
/*++

Routine Description

    This method handles the completion of the pended request for the
    IOCTL_HID_READ_REPORT

Arguments:

    Device - Handle to a framework device.

Return Value:

    None.

--*/
{
    NTSTATUS             status = STATUS_SUCCESS;
    WDFREQUEST           request;
    PDEVICE_EXTENSION    pDevContext = NULL;
    size_t               bytesReturned = 0;
#ifndef USE_ALTERNATE_HID_REPORT_DESCRIPTOR
    UCHAR                toggledSwitch = 0;
#endif // USE_ALTERNATE_HID_REPORT_DESCRIPTOR
    ULONG                bytesToCopy = 0;
    PHIDFX2_INPUT_REPORT inputReport = NULL;

    pDevContext = GetDeviceContext(Device);

    //
    // Check if there are any pending requests in the Interrupt Message Queue.
    // If a request is found then complete the pending request.
    //
    status = WdfIoQueueRetrieveNextRequest(pDevContext->InterruptMsgQueue, &request);

    if (NT_SUCCESS(status)) {
        //
        // IOCTL_HID_READ_REPORT is METHOD_NEITHER so WdfRequestRetrieveOutputBuffer
        // will correctly retrieve buffer from Irp->UserBuffer. Remember that
        // HIDCLASS provides the buffer in the Irp->UserBuffer field
        // irrespective of the ioctl buffer type. However, framework is very
        // strict about type checking. You cannot get Irp->UserBuffer by using
        // WdfRequestRetrieveOutputMemory if the ioctl is not a METHOD_NEITHER
        // internal ioctl.
        //
        bytesToCopy = sizeof(HIDFX2_INPUT_REPORT);
        status = WdfRequestRetrieveOutputBuffer(request,
                                                bytesToCopy,
                                                &inputReport,
                                                &bytesReturned);// BufferLength

        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                "WdfRequestRetrieveOutputBuffer failed with status: 0x%x\n", status);
        } else {

#ifndef USE_ALTERNATE_HID_REPORT_DESCRIPTOR
            //
            // Map switch pack state. The lower 7 bits of switch pack
            // state are mapped to usages in consumer control collection
            // while the highest one bit is mapped to sleep usage in system
            // control collection
            //
            toggledSwitch = pDevContext->LatestToggledSwitch;

			if (toggledSwitch & CONSUMER_CONTROL_BUTTONS_BIT_MASK) {
                //
                //these are consumer control buttons
                //
                TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "Consumer control SwitchState: 0x%x\n", toggledSwitch);

                inputReport->ReportId = CONSUMER_CONTROL_REPORT_ID;
                inputReport->SwitchStateAsByte = toggledSwitch;
                bytesReturned = bytesToCopy;
            }
            else if (toggledSwitch & SYSTEM_CONTROL_BUTTONS_BIT_MASK) {
                //
                // these are system control buttons
                //
                TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "System Control SwitchState: 0x%x\n", toggledSwitch);

                inputReport->ReportId = SYSTEM_CONTROL_REPORT_ID;
                inputReport->SwitchStateAsByte = toggledSwitch;
                bytesReturned = bytesToCopy;
            }
            else {
                //
                // We can't be here since we already rejected the switch
                // state with no swicthes turned on
                //
                ASSERT(FALSE);
            }
#else
            //
            // Using vendor collection reports instead of HID collections that integrate
            // into consumer and system control
            //
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                "Vendor SwitchState: 0x%x\n", pDevContext->CurrentSwitchState);

            inputReport->ReportId = DIP_SWITCHES_REPORT_ID;
            inputReport->SwitchStateAsByte = pDevContext->CurrentSwitchState;
            bytesReturned = bytesToCopy;

#endif // USE_ALTERNATE_HID_REPORT_DESCRIPTOR

        }

        WdfRequestCompleteWithInformation(request, status, bytesReturned);

    } else if (status != STATUS_NO_MORE_ENTRIES) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
            "WdfIoQueueRetrieveNextRequest status %08x\n", status);
    }

    return;
}
Beispiel #11
0
VOID
OsrFxEvtIoRead(
    __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:


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

    UNREFERENCED_PARAMETER(Queue);

    // 
    // Log read start event, using request as activity id.
    //

    EventWriteReadStart(&activity, WdfIoQueueGetDevice(Queue), (ULONG)Length);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "-->OsrFxEvtIoRead\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->BulkReadPipe;

    status = WdfRequestRetrieveOutputMemory(Request, &reqMemory);
    if(!NT_SUCCESS(status)){
        TraceEvents(TRACE_LEVEL_ERROR, DBG_READ,
               "WdfRequestRetrieveOutputMemory failed %!STATUS!\n", status);
        goto Exit;
    }

    //
    // The format call validates to make sure that you are reading or
    // writing to the right pipe type, sets the appropriate transfer flags,
    // creates an URB and initializes the request.
    //
    status = WdfUsbTargetPipeFormatRequestForRead(pipe,
                            Request,
                            reqMemory,
                            NULL // Offsets
                            );
    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_READ,
                    "WdfUsbTargetPipeFormatRequestForRead failed 0x%x\n", status);
        goto Exit;
    }

    WdfRequestSetCompletionRoutine(
                            Request,
                            EvtRequestReadCompletionRoutine,
                            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_READ, "WdfRequestSend failed\n");
        status = WdfRequestGetStatus(Request);
        goto Exit;
    }


Exit:
    if (!NT_SUCCESS(status)) {
        //
        // log event read failed
        //
        EventWriteReadFail(&activity, WdfIoQueueGetDevice(Queue), status);
        WdfRequestCompleteWithInformation(Request, status, 0);
    }

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_READ, "<-- OsrFxEvtIoRead\n");

    return;
}
Beispiel #12
0
static VOID UsbChief_ReadEndPoint(IN WDFQUEUE Queue, IN WDFREQUEST Request,
			   IN ULONG totalLength)
{
	PMDL                    newMdl=NULL, requestMdl = NULL;
	PURB                    urb = NULL;
	WDFMEMORY               urbMemory;
	ULONG                   stageLength = 0;
	NTSTATUS                status;
	ULONG_PTR               virtualAddress = 0;
	PREQUEST_CONTEXT        rwContext = NULL;
	PFILE_CONTEXT           fileContext = NULL;
	WDFUSBPIPE              pipe;
	WDF_USB_PIPE_INFORMATION   pipeInfo;
	WDF_OBJECT_ATTRIBUTES   objectAttribs;
	USBD_PIPE_HANDLE        usbdPipeHandle;
	PDEVICE_CONTEXT         deviceContext;

	UsbChief_DbgPrint(DEBUG_RW, ("UsbChief_DispatchReadWrite - begins\n"));

	deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
	fileContext = GetFileContext(WdfRequestGetFileObject(Request));
	pipe = fileContext->Pipe;

	WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
	WdfUsbTargetPipeGetInformation(pipe, &pipeInfo);

	rwContext = GetRequestContext(Request);

	status = WdfRequestRetrieveOutputWdmMdl(Request, &requestMdl);
	if(!NT_SUCCESS(status)){
		UsbChief_DbgPrint(0, ("WdfRequestRetrieveOutputWdmMdl failed %x\n", status));
		goto Exit;
	}
	virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(requestMdl);

	if (totalLength > MAX_TRANSFER_SIZE)
		stageLength = MAX_TRANSFER_SIZE;
	else
		stageLength = totalLength;

	newMdl = IoAllocateMdl((PVOID) virtualAddress, totalLength,
			       FALSE, FALSE, NULL);

	if (!newMdl) {
		UsbChief_DbgPrint(0, ("Failed to alloc mem for mdl\n"));
		status = STATUS_INSUFFICIENT_RESOURCES;
		goto Exit;
	}

	IoBuildPartialMdl(requestMdl, newMdl, (PVOID)virtualAddress,
			  stageLength);

	WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs);
	objectAttribs.ParentObject = Request;

	status = WdfMemoryCreate(&objectAttribs,
				 NonPagedPool,
				 POOL_TAG,
				 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
				 &urbMemory,
				 (PVOID*) &urb);

	if (!NT_SUCCESS(status)) {
		UsbChief_DbgPrint(0, ("Failed to alloc mem for urb\n"));
		status = STATUS_INSUFFICIENT_RESOURCES;
		goto Exit;
	}

	usbdPipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(pipe);

	UsbBuildInterruptOrBulkTransferRequest(urb,
					       sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
					       usbdPipeHandle,
					       NULL,
					       newMdl,
					       stageLength,
					       USBD_TRANSFER_DIRECTION_IN |
					       USBD_SHORT_TRANSFER_OK,
					       NULL);

	status = WdfUsbTargetPipeFormatRequestForUrb(pipe, Request, urbMemory, NULL  );
	if (!NT_SUCCESS(status)) {
		UsbChief_DbgPrint(0, ("Failed to format requset for urb\n"));
		status = STATUS_INSUFFICIENT_RESOURCES;
		goto Exit;
	}
	WdfRequestSetCompletionRoutine(Request, UsbChief_ReadCompletion, NULL);

	rwContext->UrbMemory       = urbMemory;
	rwContext->Mdl             = newMdl;
	rwContext->Length          = totalLength - stageLength;
	rwContext->Numxfer         = 0;
	rwContext->VirtualAddress  = virtualAddress + stageLength;

	if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS)) {
		status = WdfRequestGetStatus(Request);
		ASSERT(!NT_SUCCESS(status));
	}

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

		if (newMdl != NULL) {
			IoFreeMdl(newMdl);
		}
	}
}
Beispiel #13
0
static VOID UsbChief_EvtIoDeviceControl(IN WDFQUEUE Queue, IN WDFREQUEST Request,
				 IN size_t OutputBufferLength, IN size_t InputBufferLength,
				 IN ULONG IoControlCode)
{
	NTSTATUS Status;
	size_t Length = 0;
	PIOCTL_DATA data;
	PDEVICE_CONTEXT pDeviceContext;
	UCHAR test[4096];
	UCHAR *config;
	WORD *version;
	URB Urb;
	WDF_USB_INTERFACE_SELECT_SETTING_PARAMS interfaceParams;
	ULONG i;
	UNREFERENCED_PARAMETER(OutputBufferLength);
	UNREFERENCED_PARAMETER(InputBufferLength);
	UNREFERENCED_PARAMETER(Queue);

	PAGED_CODE();

	pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

	Length = 0;
	switch(IoControlCode) {
	case IOCTL_VENDOR_WRITE:

		if (InputBufferLength != sizeof(*data)) {
			UsbChief_DbgPrint(0, ("Invalid InputBuffer Size: %d/%d\n", InputBufferLength, sizeof(*data)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		Status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &data, &Length);
		if (!NT_SUCCESS(Status))
			goto out;

		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtIoDeviceControl: IOCTL_VENDOR_WRITE %x, Index %x, Value %x, Max Length %d, Buf %p\n",
				      data->Request, data->Index, data->Value, data->Length, data->Buffer));

		if (Length != sizeof(*data)) {
			UsbChief_DbgPrint(0, ("Failed to retrieve buffer: %d/%d\n", Length, sizeof(*data)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		memset(&Urb, 0, sizeof(Urb));
		Urb.UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;
		Urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
		Urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0x40;
		Urb.UrbControlVendorClassRequest.TransferBufferLength = data->Length;
		Urb.UrbControlVendorClassRequest.TransferBuffer = (PVOID)data->Buffer;
		Urb.UrbControlVendorClassRequest.Request = data->Request;
		Urb.UrbControlVendorClassRequest.Value = data->Value;
		Urb.UrbControlVendorClassRequest.Index = data->Index;

		if (DebugLevel & DEBUG_IOCTL) {
			for(i = 0; i < data->Length; i++)
				DbgPrint("%02X ", ((PUCHAR)data->Buffer)[i]);
			DbgPrint("\n");
		}
		Status = WdfUsbTargetDeviceSendUrbSynchronously(pDeviceContext->WdfUsbTargetDevice, NULL, NULL, &Urb);

		if (!NT_SUCCESS(Status)) {
			UsbChief_DbgPrint(0, ("WdfUsbTargetDeviceSendControlTransferSynchronously failed\n"));
		}
		break;

	case IOCTL_VENDOR_READ:
		if (InputBufferLength != sizeof(*data)) {
			UsbChief_DbgPrint(0, ("Invalid InputBuffer Size: %d/%d\n", InputBufferLength, sizeof(*data)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		Status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &data, &Length);
		if (!NT_SUCCESS(Status))
			goto out;

		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtIoDeviceControl: IOCTL_VENDOR_READ %x, Index %x, Value %x, Max Length %d, Buf %p\n",
				      data->Request, data->Index, data->Value, data->Length, data->Buffer));

		if (Length != sizeof(*data)) {
			UsbChief_DbgPrint(0, ("Failed to retrieve buffer: %d/%d\n", Length, sizeof(*data)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		if (data->Length > sizeof(test)) {
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		memset(&Urb, 0, sizeof(Urb));
		Urb.UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;
		Urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
		Urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0xc0;
		Urb.UrbControlVendorClassRequest.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
		Urb.UrbControlVendorClassRequest.TransferBufferLength = data->Length;
		Urb.UrbControlVendorClassRequest.TransferBuffer = test;
		Urb.UrbControlVendorClassRequest.Request = data->Request;
		Urb.UrbControlVendorClassRequest.Value = data->Value;
		Urb.UrbControlVendorClassRequest.Index = data->Index;

		Status = WdfUsbTargetDeviceSendUrbSynchronously(pDeviceContext->WdfUsbTargetDevice, NULL, NULL, &Urb);

		if (DebugLevel & DEBUG_IOCTL && NT_SUCCESS(Status)) {
			for(i = 0; i < Urb.UrbControlVendorClassRequest.TransferBufferLength; i++)
				DbgPrint("%02X ", ((PUCHAR)test)[i]);
			DbgPrint("\n");
		}

		if (Urb.UrbControlVendorClassRequest.TransferBufferLength)
			memcpy((PVOID)data->Buffer, test, Urb.UrbControlVendorClassRequest.TransferBufferLength);
		Length = Urb.UrbControlVendorClassRequest.TransferBufferLength;
		break;

	case IOCTL_SELECT_CONFIGURATION:

		if (InputBufferLength != sizeof(*config)) {
			UsbChief_DbgPrint(0, ("Invalid InputBuffer Size: %d/%d\n", InputBufferLength, sizeof(*config)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		config = 0;
		Status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, (PVOID)&config, &Length);
		if (!NT_SUCCESS(Status))
			goto out;

		if (Length != sizeof(*config)) {
			UsbChief_DbgPrint(0, ("Invalid Length: %d/%d\n", Length, sizeof(*config)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl: IOCTL_SELECT_CONFIGURATION %x\n", *config));

		if (!pDeviceContext->UsbInterface) {
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING (&interfaceParams, *config);

		Status = WdfUsbInterfaceSelectSetting(pDeviceContext->UsbInterface, WDF_NO_OBJECT_ATTRIBUTES,
						      &interfaceParams);
		break;

	case IOCTL_GET_FIRMWARE_VERSION:
		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl: GET_FIRMWARE_VERSION\n"));

		Status = WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &version, &Length);
		if (!NT_SUCCESS(Status))
			goto out;

		if (Length != sizeof(*version)) {
			UsbChief_DbgPrint(0, ("Invalid Length: %d/%d\n", Length, sizeof(*version)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		*version = pDeviceContext->UsbDeviceDescriptor.bcdDevice;
		break;

	default:
		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl %08x (Device %x, Method %x) unknown\n",
				      IoControlCode, DEVICE_TYPE_FROM_CTL_CODE(IoControlCode),
				      METHOD_FROM_CTL_CODE(IoControlCode)));
		Status = STATUS_INVALID_DEVICE_REQUEST;
		break;
	}
out:
	UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl: Status %08x, Length %d\n", Status, Length));
	WdfRequestCompleteWithInformation(Request, Status, Length);
}
Beispiel #14
0
NTSTATUS EvtDeviceAdd(
                      IN WDFDRIVER  Driver,
                      IN PWDFDEVICE_INIT  DeviceInit
                      )
{
  NTSTATUS status;
  WDFDEVICE device;									// Device object
  PDEVICE_CONTEXT devCtx = NULL;					// Pointer to a device context
  WDF_OBJECT_ATTRIBUTES attributes;					// Object attribute
  WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;	// PNP Power event callback
  WDF_DEVICE_PNP_CAPABILITIES pnpCapabilities;		//

  UNREFERENCED_PARAMETER(Driver);

  /*Set the callback functions that will be executed on PNP and Power events*/
  WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);	// Init pnpPowerCallbacks
  pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;
  pnpPowerCallbacks.EvtDeviceD0Entry = EvtDeviceD0Entry;
  pnpPowerCallbacks.EvtDeviceD0Exit = EvtDeviceD0Exit;
  WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);	// Setup pnpPowerCallbacks

  WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);	// Buffered IO type

  /*Initialize storage for the device context*/
  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);

  /*Create a device instance.*/
  status = WdfDeviceCreate(&DeviceInit, &attributes, &device);  
  if(!NT_SUCCESS(status))
  {
    KdPrint((__DRIVER_NAME
      "WdfDeviceCreate failed with status 0x%08x\n", status));
    return status;
  }

  /*Set the PNP capabilities of our device. we don't want an annoying
    popup if the device is pulled out of the USB slot.*/
  WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCapabilities);
  pnpCapabilities.Removable = WdfTrue;				// Can hot-unplug
  pnpCapabilities.SurpriseRemovalOK = WdfTrue;		//
  WdfDeviceSetPnpCapabilities(device, &pnpCapabilities);
  
  devCtx = GetDeviceContext(device);

  /*Create a WDF memory object for the memory that is occupied by the
    WdfMemLEDArrayState variable in the device context.
    this way we have the value itself handy for debugging purposes, and
    we have a WDF memory handle that can be used for passing to the low
    level USB functions.
    this alleviates the need to getting the buffer at run time.*/
  status = WdfMemoryCreatePreallocated(WDF_NO_OBJECT_ATTRIBUTES,
                           &devCtx->D0LEDArrayState,
                           sizeof(devCtx->D0LEDArrayState),
                           &devCtx->WdfMemLEDArrayState);	// for Debbug 
  if(!NT_SUCCESS(status))
  {
    KdPrint((__DRIVER_NAME
      "WdfMemoryCreatePreallocated failed with status 0x%08x\n", status));
    return status;
  }

  // Create Queues for handling IO request
  status = CreateQueues(device, devCtx);
  if(!NT_SUCCESS(status))
    return status;

  // Create Device Interface
  status = WdfDeviceCreateDeviceInterface(device, &GUID_DEV_IF_LEDSCTRL, NULL);
  if(!NT_SUCCESS(status))
  {
    KdPrint((__DRIVER_NAME
      "WdfDeviceCreateDeviceInterface failed with status 0x%08x\n", status));
    return status;
  }

  return status;
  
}
Beispiel #15
0
NTSTATUS
HidFx2EvtDeviceD0Entry(
    IN  WDFDEVICE Device,
    IN  WDF_POWER_DEVICE_STATE PreviousState
    )
/*++

Routine Description:

    EvtDeviceD0Entry event callback must perform any operations that are
    necessary before the specified device is used.  It will be called every
    time the hardware needs to be (re-)initialized.

    This function is not marked pageable because this function is in the
    device power up path. When a function is marked pagable and the code
    section is paged out, it will generate a page fault which could impact
    the fast resume behavior because the client driver will have to wait
    until the system drivers can service this page fault.

    This function runs at PASSIVE_LEVEL, even though it is not paged.  A
    driver can optionally make this function pageable if DO_POWER_PAGABLE
    is set.  Even if DO_POWER_PAGABLE isn't set, this function still runs
    at PASSIVE_LEVEL.  In this case, though, the function absolutely must
    not do anything that will cause a page fault.

Arguments:

    Device - Handle to a framework device object.

    PreviousState - Device power state which the device was in most recently.
        If the device is being newly started, this will be
        PowerDeviceUnspecified.

Return Value:

    NTSTATUS

--*/
{
    PDEVICE_EXTENSION   devContext = NULL;
    NTSTATUS            status = STATUS_SUCCESS;
    UCHAR               switchState = 0;

    devContext = GetDeviceContext(Device);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
        "HidFx2EvtDeviceD0Entry Enter - coming from %s\n",
                DbgDevicePowerString(PreviousState));

    //
    // Retrieve the current switch state and store it in device context
    //
    status = HidFx2GetSwitchState(Device, &switchState);
    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "Failed to get current swicth state, status: 0x%x\n", status);
        return status;
    }

    devContext->CurrentSwitchState = switchState;

    //
    // Start the target. This will start the continuous reader
    //
    status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(devContext->InterruptPipe));
    if (NT_SUCCESS(status)) {
        devContext->IsPowerUpSwitchState = TRUE;
    }

    TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
        "HidFx2EvtDeviceD0Entry Exit, status: 0x%x\n", status);

    return status;
}
NTSTATUS VioCryptDeviceAdd(IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit)
{
    NTSTATUS status;
    WDFDEVICE device;
    WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
    WDF_OBJECT_ATTRIBUTES attributes;
    WDFQUEUE queue;
    WDF_IO_QUEUE_CONFIG queueConfig;
    WDF_INTERRUPT_CONFIG interruptConfig;
    PDEVICE_CONTEXT context;

    UNREFERENCED_PARAMETER(Driver);

    Trace(TRACE_LEVEL_VERBOSE, "[%s] -->", __FUNCTION__);

    PAGED_CODE();

    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);

    pnpPowerCallbacks.EvtDevicePrepareHardware = VioCryptDevicePrepareHardware;
    pnpPowerCallbacks.EvtDeviceReleaseHardware = VioCryptDeviceReleaseHardware;
    pnpPowerCallbacks.EvtDeviceD0Entry = VioCryptDeviceD0Entry;
    pnpPowerCallbacks.EvtDeviceD0Exit = VioCryptDeviceD0Exit;

    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
    WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
    attributes.EvtCleanupCallback = VioCryptDeviceContextCleanup;

    status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
    if (!NT_SUCCESS(status))
    {
        Trace(TRACE_LEVEL_ERROR, "[%s] WdfDeviceCreate failed: status %X", __FUNCTION__, status);
        return status;
    }

    context = GetDeviceContext(device);

    RtlZeroMemory(context, sizeof(*context));
    InitializeListHead(&context->PendingBuffers);

    WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, VioCryptInterruptIsr, VioCryptInterruptDpc);

    interruptConfig.EvtInterruptEnable = VioCryptInterruptEnable;
    interruptConfig.EvtInterruptDisable = VioCryptInterruptDisable;

    status = WdfInterruptCreate(device, &interruptConfig,
        WDF_NO_OBJECT_ATTRIBUTES, &context->WdfInterrupt);

    if (!NT_SUCCESS(status))
    {
        Trace(TRACE_LEVEL_ERROR, "[%s] WdfInterruptCreate failed: status %X", __FUNCTION__, status);
        return status;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = device;
    status = WdfSpinLockCreate(&attributes,
        &context->VirtQueueLock);

    if (!NT_SUCCESS(status))
    {
        Trace(TRACE_LEVEL_ERROR, "[%s] WdfSpinLockCreate failed: status %X", __FUNCTION__, status);
        return status;
    }

    status = WdfDeviceCreateDeviceInterface(device,
        &GUID_DEVINTERFACE_VIOCRYPT, NULL);

    if (!NT_SUCCESS(status))
    {
        Trace(TRACE_LEVEL_ERROR, "[%s] WdfDeviceCreateDeviceInterface failed: status %X", __FUNCTION__, status);
        return status;
    }

    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchSequential);
    queueConfig.EvtIoDeviceControl = VioCryptIoControl;
    queueConfig.EvtIoStop = VioCryptIoStop;
    queueConfig.AllowZeroLengthRequests = FALSE;

    status = WdfIoQueueCreate(device, &queueConfig,
        WDF_NO_OBJECT_ATTRIBUTES, &queue);

    if (!NT_SUCCESS(status))
    {
        Trace(TRACE_LEVEL_ERROR, "[%s] WdfIoQueueCreate failed: status %X", __FUNCTION__, status);
        return status;
    }

    status = WdfDeviceConfigureRequestDispatching(device, queue, WdfRequestTypeDeviceControl);

    if (!NT_SUCCESS(status))
    {
        Trace(TRACE_LEVEL_ERROR, "[%s] WdfDeviceConfigureRequestDispatching failed: status %X", __FUNCTION__, status);
        return status;
    }

    Trace(TRACE_LEVEL_VERBOSE, "[%s] <--", __FUNCTION__);

    return status;
}
Beispiel #17
0
NTSTATUS
HidFx2EvtDeviceD0Exit(
    IN  WDFDEVICE Device,
    IN  WDF_POWER_DEVICE_STATE TargetState
    )
/*++

Routine Description:

    This routine undoes anything done in EvtDeviceD0Entry.  It is called
    whenever the device leaves the D0 state, which happens when the device is
    stopped, when it is removed, and when it is powered off.

    The device is still in D0 when this callback is invoked, which means that
    the driver can still touch hardware in this routine.


    EvtDeviceD0Exit event callback must perform any operations that are
    necessary before the specified device is moved out of the D0 state.  If the
    driver needs to save hardware state before the device is powered down, then
    that should be done here.

    This function runs at PASSIVE_LEVEL, though it is generally not paged.  A
    driver can optionally make this function pageable if DO_POWER_PAGABLE is set.

    Even if DO_POWER_PAGABLE isn't set, this function still runs at
    PASSIVE_LEVEL.  In this case, though, the function absolutely must not do
    anything that will cause a page fault.

Arguments:

    Device - Handle to a framework device object.

    TargetState - Device power state which the device will be put in once this
        callback is complete.

Return Value:

    Success implies that the device can be used.  Failure will result in the
    device stack being torn down.

--*/
{
    PDEVICE_EXTENSION         devContext;

    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,
        "HidFx2EvtDeviceD0Exit Enter- moving to %s\n",
          DbgDevicePowerString(TargetState));

    devContext = GetDeviceContext(Device);

    WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(
        devContext->InterruptPipe), WdfIoTargetCancelSentIo);

    TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
        "HidFx2EvtDeviceD0Exit Exit\n");

    return STATUS_SUCCESS;
}
Beispiel #18
0
/******************************************************************************

  WDF_IO_QUEUE_IO_DEVICE_CONTROL

  The IOCTL_SET_LOCAL_HOST_INFORMATION part of EvtIoDeviceControl.
  Tranform the Request into a SetLocalHostInformation, and pass it down to
  the local t1394_SetLocalHostProperties procedure.

 ******************************************************************************/
VOID
t1394_EvtIoDeviceControl(
   /*IN*/WDFQUEUE     Queue,
   /*IN*/WDFREQUEST Request,
   /*IN*/size_t      OutputBufferLength,
   /*IN*/size_t      InputBufferLength,
   /*IN*/ULONG      IoControlCode
    )
{
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION   deviceExtension;
    PVOID               ioBuffer = NULL;
    WDFDEVICE           device;
    size_t              bufLength;

    //ENTER("t1394_EvtIoDeviceControl");
    // TRACE(TL_TRACE, ("Request = 0x%p\n", Request));

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

    //
    // Since all the IOCTLs handled here are buffered, WdfRequestRetrieveOutputBuffer &
    // WdfRequestRetrieveInputBuffer return the same buffer pointer.
    // So make sure you read all the information you need from
    // the buffer before you write to it. Also requiredLength of the buffer vary from
    // ioctl to ioctl, so we will pretend that we need zero length buffer and do the lenght
    // check later in the specific ioct case.
    //
    ntStatus = WdfRequestRetrieveInputBuffer(Request, 0, &ioBuffer, &bufLength);
    if( !NT_SUCCESS(ntStatus) || ioBuffer == NULL) {
        // TRACE(TL_ERROR, ("WdfRequestRetrieveInputBuffer failed 0x%x\n", ntStatus));
        WdfRequestComplete(Request, ntStatus);
        return;
    }


    switch (IoControlCode) {

        case IOCTL_SET_LOCAL_HOST_INFORMATION:
            {
                PSET_LOCAL_HOST_INFORMATION     SetLocalHostInformation;

                // TRACE(TL_TRACE, ("IOCTL_SET_LOCAL_HOST_INFORMATION\n"));

                if (InputBufferLength < sizeof(SET_LOCAL_HOST_INFORMATION)) {

                    ntStatus = STATUS_BUFFER_TOO_SMALL;
                }
                else {

                    SetLocalHostInformation = (PSET_LOCAL_HOST_INFORMATION)ioBuffer;

                    if (InputBufferLength < (sizeof(SET_LOCAL_HOST_INFORMATION) +
                                             SetLocalHostInformation->ulBufferSize)) {

                        ntStatus = STATUS_BUFFER_TOO_SMALL;
                    }
                    else {

                        ntStatus = t1394_SetLocalHostProperties( device,
                                                                     Request,
                                                                     SetLocalHostInformation->nLevel,
                                                                     (PVOID)&SetLocalHostInformation->Information
                                                                     );

                        if (NT_SUCCESS(ntStatus))
                            WdfRequestSetInformation(Request,  OutputBufferLength);
                    }
                }
            }
            break; // IOCTL_SET_LOCAL_HOST_INFORMATION

        default:
            // TRACE(TL_ERROR, ("Invalid ioControlCode = 0x%x\n", IoControlCode));
            ntStatus = STATUS_INVALID_PARAMETER;
            break; // default

    } // switch


    // only complete if the device is there
    if (ntStatus != STATUS_PENDING) {

        WdfRequestComplete(Request, ntStatus);
    }

    //EXIT("t1394_IoControl", ntStatus);
    return ;
} // t1394_EvtIoDeviceControl
Beispiel #19
0
NTSTATUS
HidFx2GetSwitchState(
    IN WDFDEVICE Device,
    OUT PUCHAR SwitchState
    )
/*++

Routine Description:

    This function gets the swicth state of teh USB device

Arguments:

    Device - Handle to a framework device object.

    SwitchState - Pointer to a variable that receives the switch state

Return Value:

    Success implies that the device can be used.  Failure will result in the
    device stack being torn down.

--*/
{
    PDEVICE_EXTENSION            devContext = NULL;
    NTSTATUS                     status = STATUS_SUCCESS;
    WDF_MEMORY_DESCRIPTOR        memDesc;
    WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket;
    ULONG                        bytesTransferred = 0;

    devContext = GetDeviceContext(Device);

    //
    // set the segment state on the USB device
    //
    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestDeviceToHost,
                                        BmRequestToDevice,
                                        HIDFX2_READ_SWITCH_STATE, // Request
                                        0, // Value
                                        0); // Index

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc,
                                    SwitchState,
                                    sizeof(UCHAR));

    status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                                devContext->UsbDevice,
                                                NULL, // Optional WDFREQUEST
                                                NULL, // PWDF_REQUEST_SEND_OPTIONS
                                                &controlSetupPacket,
                                                &memDesc,
                                                &bytesTransferred
                                                );

    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
            "GetSwitchState: Failed to read switch state - 0x%x \n", status);

    } else {
        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,
            "GetSwitchState: Switch state is 0x%x\n", *SwitchState);
    }

    return status;
}
Beispiel #20
0
NTSTATUS
t1394_EvtDeviceAdd(
   /*IN*/WDFDRIVER        Driver,
   /*IN*/PWDFDEVICE_INIT  DeviceInit
    )
/*++
Routine Description:

    EvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS                        status = STATUS_SUCCESS;
    PDEVICE_EXTENSION               deviceExtension;
    PNODE_DEVICE_EXTENSION          pNodeExt;
    WDF_PNPPOWER_EVENT_CALLBACKS    pnpPowerCallbacks;
    WDF_OBJECT_ATTRIBUTES           fdoAttributes,lockAttributes;
    WDFDEVICE                       device;
    WDF_DEVICE_PNP_CAPABILITIES     pnpCaps;
    WDF_IO_QUEUE_CONFIG             ioQueueConfig;
    WDF_IO_TARGET_OPEN_PARAMS       openParams;

    //UNREFERENCED_PARAMETER(Driver);

    //ENTER("t1394_PnpAddDevice");

    //
    // Zero out the PnpPowerCallbacks structure.
    //
    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);

    //
    // Set Callbacks for any of the functions we are interested in.
    // If no callback is set, Framework will take the default action
    // by itself.

    //
    // These two callbacks set up and tear down hardware state,
    // specifically that which only has to be done once.
    //

    pnpPowerCallbacks.EvtDevicePrepareHardware = t1394_EvtPrepareHardware;
    pnpPowerCallbacks.EvtDeviceReleaseHardware = t1394_EvtReleaseHardware;

    pnpPowerCallbacks.EvtDeviceSelfManagedIoCleanup =
        t1394_EvtDeviceSelfManagedIoCleanup;

    pnpPowerCallbacks.EvtDeviceD0Entry = t1394_EvtDeviceD0Entry;
    pnpPowerCallbacks.EvtDeviceD0Exit  = t1394_EvtDeviceD0Exit;

    //
    // Register the PnP and power callbacks. Power policy related callbacks
    // will be registered// later in SotwareInit.
    //
    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
    if ( !NT_SUCCESS(status)) {
        //TRACE(TL_ERROR, ("WdfDeviceInitSetPnpPowerEventCallbacks failed %x\n",
        //                 status));
        return status;
    }

    WdfDeviceInitSetExclusive(DeviceInit, FALSE);

    //
    // Specify the size and type of device context.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, DEVICE_EXTENSION);

    status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device);

    if ( !NT_SUCCESS(status)) {
        //TRACE(TL_ERROR, ("WdfDeviceInitialize failed %x\n", status));
        return status;
    }


    deviceExtension = GetDeviceContext (device);
    deviceExtension->WdfDevice = device;

    //TRACE(TL_TRACE, ("PDO(0x%p) FDO(0x%p), Lower(0x%p) DevExt (0x%p)\n",
    //                 WdfDeviceWdmGetPhysicalDevice (device),
    //                 WdfDeviceWdmGetDeviceObject (device),
    //                 WdfDeviceWdmGetAttachedDevice(device),
    //                 deviceExtension));

    //
    // Tell the Framework that this device will need an interface so that
    // application can interact with it.
    //

    status = WdfDeviceCreateDeviceInterface(
                 device,
#if defined(_1394VDEV_DRIVER_)
                 (LPGUID) &GUID_1394VDEV,
#else
                 (LPGUID) &GUID_1394DIAG,
#endif
                 NULL
             );

    if (!NT_SUCCESS (status)) {
        //TRACE(TL_ERROR, ("WdfDeviceCreateDeviceInterface failed %x\n", status));
        return status;
    }

    //
    // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so
    // that you don't get the popup in usermode (on Win2K) when you surprise
    // remove the device.
    //
    WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);
    pnpCaps.SurpriseRemovalOK = WdfTrue;

    WdfDeviceSetPnpCapabilities(device, &pnpCaps);

    // save the device object we created as our physical device object
    deviceExtension->PhysicalDeviceObject =
        WdfDeviceWdmGetPhysicalDevice (device);

    if (deviceExtension->PhysicalDeviceObject == NULL) {
        //TRACE(TL_ERROR, ("WdfDeviceWdmGetPhysicalDevice: NULL DeviceObject\n"));
        return STATUS_UNSUCCESSFUL;
    }

    //
    // This is our default IoTarget representing the deviceobject
    // we are attached to.
    //
    deviceExtension->StackIoTarget = WdfDeviceGetIoTarget(device);
    deviceExtension->StackDeviceObject = WdfDeviceWdmGetAttachedDevice(device);

    if (deviceExtension->StackDeviceObject == NULL) {
        //TRACE(TL_ERROR, ("WdfDeviceWdmGetAttachedDevice: NULL DeviceObject\n"));
        return STATUS_UNSUCCESSFUL;
    }

    // Patch: this code is not in DDK 7600.16385.1  {
    //
    // Get the port device object from the passed in PhysicalDeviceObject
    // created by the 1394 stack for us.
    // Note: we can't use the top of the stack and get its device extension
    // in case there is a filter driver between us and our PDO.
    //
    //pNodeExt = WdfDeviceWdmGetPhysicalDevice(device)->DeviceExtension;
    //deviceExtension->PortDeviceObject = pNodeExt->PortDeviceObject;
    // Patch: this code is not in DDK 7600.16385.1 }

    //TRACE(TL_TRACE, ("PortDeviceObject = 0x%x\n",
    //                 deviceExtension->PortDeviceObject));

    //
    // Create a automanaged queue for dispatching ioctl requests.
    // All other requests are automatically failed by the framework.
    // By creating an automanaged queue we don't have to worry about
    // PNP/Power synchronization.
    // A default queue gets all the requests that are not
    // configure-fowarded using WdfDeviceConfigureRequestDispatching.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
        &ioQueueConfig,
        WdfIoQueueDispatchParallel
    );

    ioQueueConfig.EvtIoDeviceControl = t1394_EvtIoDeviceControl;

    status = WdfIoQueueCreate(
                 deviceExtension->WdfDevice,
                 &ioQueueConfig,
                 WDF_NO_OBJECT_ATTRIBUTES,
                 &deviceExtension->IoctlQueue // queue handle
             );

    if (!NT_SUCCESS (status)) {
         //TRACE(TL_ERROR, ("WdfIoQueueCreate failed 0x%x\n", status));
        return status;
    }

    //
    // Create an additional queue to hold bus reset requests.
    //
    WDF_IO_QUEUE_CONFIG_INIT(
        &ioQueueConfig,
        WdfIoQueueDispatchManual
        );

    status = WdfIoQueueCreate (
                   deviceExtension->WdfDevice,
                   &ioQueueConfig,
                   WDF_NO_OBJECT_ATTRIBUTES,
                   &deviceExtension->BusResetRequestsQueue
                   );

    if(!NT_SUCCESS (status)){
        //TRACE(TL_ERROR, ("Error Creating Reset Request Queue 0x%x\n",
        //                 status));
        return status;
    }

    //
    // Create another IoTarget representing PortDeviceObject so that
    // we can send async requests in rawmode directly to the port device.
    //
    WDF_IO_TARGET_OPEN_PARAMS_INIT_EXISTING_DEVICE(&openParams,
                                                pNodeExt->PortDeviceObject);
    status = WdfIoTargetCreate(device,
                                WDF_NO_OBJECT_ATTRIBUTES,
                                &deviceExtension->PortDeviceIoTarget);
    if (!NT_SUCCESS (status)) {
        //TRACE(TL_ERROR, ("WdfIoTargetCreate failed 0x%x\n", status));
        return status;
    }

    status = WdfIoTargetOpen(deviceExtension->PortDeviceIoTarget, &openParams);
    if (!NT_SUCCESS (status)) {
        //TRACE(TL_ERROR, ("WdfIoTargetCreate failed 0x%x\n", status));
        return status;
    }


    WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes);
    lockAttributes.ParentObject = device;
    // initialize the spinlock/list to store the bus reset irps...

    status = WdfSpinLockCreate(&lockAttributes,&deviceExtension->CromSpinLock );
    if(!NT_SUCCESS(status)){
         //TRACE(TL_ERROR, ("WdfSpinLockCreate CromSpinLock "
         //                 "failed 0x%x\n", status));
        return status;
    }


    WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes);
    lockAttributes.ParentObject = device;

    status = WdfSpinLockCreate(&lockAttributes,
                               &deviceExtension->AsyncSpinLock );
    if(!NT_SUCCESS(status)){
         //TRACE(TL_ERROR, ("WdfSpinLockCreate AsyncSpinLock "
         //                 "failed 0x%x\n", status));
        return status;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes);
    lockAttributes.ParentObject = device;

    status = WdfSpinLockCreate(&lockAttributes,
                               &deviceExtension->IsochSpinLock );
    if(!NT_SUCCESS(status)){
         //TRACE(TL_ERROR, ("WdfSpinLockCreate IsochSpinLock "
         //                 "failed 0x%x\n", status));
        return status;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes);
    lockAttributes.ParentObject = device;

    status = WdfSpinLockCreate(&lockAttributes,
                               &deviceExtension->IsochResourceSpinLock );
    if(!NT_SUCCESS(status)){
         //TRACE(TL_ERROR, ("WdfSpinLockCreate IsochResourceSpinLock "
         //                 "failed 0x%x\n", status));
        return status;
    }
    InitializeListHead(&deviceExtension->CromData);
    InitializeListHead(&deviceExtension->AsyncAddressData);
    InitializeListHead(&deviceExtension->IsochDetachData);
    InitializeListHead(&deviceExtension->IsochResourceData);

    //EXIT("t1394_PnpAddDevice", status);

    return(status);
} // t1394_PnpAddDevice
Beispiel #21
0
NTSTATUS
OsrFxEvtDevicePrepareHardware(
    WDFDEVICE Device,
    WDFCMRESLIST ResourceList,
    WDFCMRESLIST ResourceListTranslated
    )
/*++

Routine Description:

    In this callback, the driver does whatever is necessary to make the
    hardware ready to use.  In the case of a USB device, this involves
    reading and selecting descriptors.

Arguments:

    Device - handle to a device

Return Value:

    NT status value

--*/
{
    NTSTATUS                            status;
    PDEVICE_CONTEXT                     pDeviceContext;
    WDF_USB_DEVICE_INFORMATION          deviceInfo;
    ULONG                               waitWakeEnable;

    UNREFERENCED_PARAMETER(ResourceList);
    UNREFERENCED_PARAMETER(ResourceListTranslated);
    waitWakeEnable = FALSE;
    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> EvtDevicePrepareHardware\n");

    pDeviceContext = GetDeviceContext(Device);

    //
    // Create a USB device handle so that we can communicate with the
    // underlying USB stack. The WDFUSBDEVICE handle is used to query,
    // configure, and manage all aspects of the USB device.
    // These aspects include device properties, bus properties,
    // and I/O creation and synchronization. We only create device the first
    // the PrepareHardware is called. If the device is restarted by pnp manager
    // for resource rebalance, we will use the same device handle but then select
    // the interfaces again because the USB stack could reconfigure the device on
    // restart.
    //
    if (pDeviceContext->UsbDevice == NULL) {
        status = WdfUsbTargetDeviceCreate(Device,
                                    WDF_NO_OBJECT_ATTRIBUTES,
                                    &pDeviceContext->UsbDevice);
        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                 "WdfUsbTargetDeviceCreate failed with Status code %!STATUS!\n", status);
            return status;
        }
    }    

    //
    // Retrieve USBD version information, port driver capabilites and device
    // capabilites such as speed, power, etc.
    //
    WDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo);

    status = WdfUsbTargetDeviceRetrieveInformation(
                                pDeviceContext->UsbDevice,
                                &deviceInfo);
    if (NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "IsDeviceHighSpeed: %s\n",
            (deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) ? "TRUE" : "FALSE");
        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
                    "IsDeviceSelfPowered: %s\n",
            (deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_SELF_POWERED) ? "TRUE" : "FALSE");

        waitWakeEnable = deviceInfo.Traits &
                            WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE;

        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
                            "IsDeviceRemoteWakeable: %s\n",
                            waitWakeEnable ? "TRUE" : "FALSE");
        //
        // Save these for use later. 
        //
        pDeviceContext->UsbDeviceTraits = deviceInfo.Traits;
    }
    
    status = SelectInterfaces(Device);
    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                    "SelectInterfaces failed 0x%x\n", status);
        return status;
    }
    
    //
    // Enable wait-wake and idle timeout if the device supports it
    //
    if (waitWakeEnable) {
        status = OsrFxSetPowerPolicy(Device);
        if (!NT_SUCCESS (status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                                "OsrFxSetPowerPolicy failed  %!STATUS!\n", status);
            return status;
        }
    }

    status = OsrFxConfigContReaderForInterruptEndPoint(pDeviceContext);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- EvtDevicePrepareHardware\n");

    return status;
}
Beispiel #22
0
VOID
ReadWriteBulkEndPoints(
    IN WDFQUEUE         Queue,
    IN WDFREQUEST       Request,
    IN ULONG            Length,
    IN WDF_REQUEST_TYPE RequestType
    )
/*++

Routine Description:

    This callback is invoked when the framework received  WdfRequestTypeRead or
    WdfRequestTypeWrite request. This read/write is performed in stages of
    MAX_TRANSFER_SIZE. Once a stage of transfer is complete, then the
    request is circulated again, until the requested length of transfer is
    performed.

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 WdfRequestTypeRead/WdfRequestTypeWrite IRP received by the framework.

    Length - Length of the input/output buffer.

Return Value:

   VOID

--*/
{
    PMDL                    newMdl=NULL, requestMdl = NULL;
    PURB                    urb = NULL;
    WDFMEMORY               urbMemory;
    ULONG                   totalLength = Length;
    ULONG                   stageLength = 0;
    ULONG                   urbFlags = 0;
    NTSTATUS                status;
    ULONG_PTR               virtualAddress = 0;
    PREQUEST_CONTEXT        rwContext = NULL;
    PFILE_CONTEXT           fileContext = NULL;
    WDFUSBPIPE              pipe;
    WDF_USB_PIPE_INFORMATION   pipeInfo;
    WDF_OBJECT_ATTRIBUTES   objectAttribs;
    USBD_PIPE_HANDLE        usbdPipeHandle;
    PDEVICE_CONTEXT         deviceContext;

    kJtag_DbgPrint(3, ("kJtag_DispatchReadWrite - begins\n"));

    //
    // First validate input parameters.
    //
    deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

    if (totalLength > deviceContext->MaximumTransferSize) {
        kJtag_DbgPrint(1, ("Transfer length > circular buffer\n"));
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    if ((RequestType != WdfRequestTypeRead) &&
        (RequestType != WdfRequestTypeWrite)) {
        kJtag_DbgPrint(1, ("RequestType has to be either Read or Write\n"));
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    //
    // Get the pipe associate with this request.
    //
    fileContext = GetFileContext(WdfRequestGetFileObject(Request));
    pipe = fileContext->Pipe;
    WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
    WdfUsbTargetPipeGetInformation(pipe, &pipeInfo);

    if((WdfUsbPipeTypeBulk != pipeInfo.PipeType) &&
            (WdfUsbPipeTypeInterrupt != pipeInfo.PipeType)) {
        kJtag_DbgPrint(1, ("Usbd pipe type is not bulk or interrupt\n"));
        status = STATUS_INVALID_DEVICE_REQUEST;
        goto Exit;

    }

    rwContext = GetRequestContext(Request);

    if(RequestType == WdfRequestTypeRead) {

        status = WdfRequestRetrieveOutputWdmMdl(Request, &requestMdl);
        if(!NT_SUCCESS(status)){
            kJtag_DbgPrint(1, ("WdfRequestRetrieveOutputWdmMdl failed %x\n", status));
            goto Exit;
        }

        urbFlags |= USBD_TRANSFER_DIRECTION_IN;
        rwContext->Read = TRUE;
        kJtag_DbgPrint(3, ("Read operation\n"));

    } else {
        status = WdfRequestRetrieveInputWdmMdl(Request, &requestMdl);
        if(!NT_SUCCESS(status)){
            kJtag_DbgPrint(1, ("WdfRequestRetrieveInputWdmMdl failed %x\n", status));
            goto Exit;
        }

        urbFlags |= USBD_TRANSFER_DIRECTION_OUT;
        rwContext->Read = FALSE;
        kJtag_DbgPrint(3, ("Write operation\n"));
    }

    urbFlags |= USBD_SHORT_TRANSFER_OK;
    virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(requestMdl);

    //
    // the transfer request is for totalLength.
    // we can perform a max of MAX_TRANSFER_SIZE
    // in each stage.
    //
    if (totalLength > MAX_TRANSFER_SIZE) {
        stageLength = MAX_TRANSFER_SIZE;
    }
    else {
        stageLength = totalLength;
    }

    newMdl = IoAllocateMdl((PVOID) virtualAddress,
                           totalLength,
                           FALSE,
                           FALSE,
                           NULL);

    if (newMdl == NULL) {
        kJtag_DbgPrint(1, ("Failed to alloc mem for mdl\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    //
    // map the portion of user-buffer described by an mdl to another mdl
    //
    IoBuildPartialMdl(requestMdl,
                      newMdl,
                      (PVOID) virtualAddress,
                      stageLength);

    WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs);
    objectAttribs.ParentObject = Request;

    status = WdfMemoryCreate(&objectAttribs,
                             NonPagedPool,
                             POOL_TAG,
                             sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
                             &urbMemory,
                             (PVOID*) &urb);

    if (!NT_SUCCESS(status)) {
        kJtag_DbgPrint(1, ("Failed to alloc mem for urb\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    usbdPipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(pipe);

    UsbBuildInterruptOrBulkTransferRequest(urb,
                                           sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
                                           usbdPipeHandle,
                                           NULL,
                                           newMdl,
                                           stageLength,
                                           urbFlags,
                                           NULL);

    status = WdfUsbTargetPipeFormatRequestForUrb(pipe, Request, urbMemory, NULL  );
    if (!NT_SUCCESS(status)) {
        kJtag_DbgPrint(1, ("Failed to format requset for urb\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);

    //
    // set REQUEST_CONTEXT  parameters.
    //
    rwContext->UrbMemory       = urbMemory;
    rwContext->Mdl             = newMdl;
    rwContext->Length          = totalLength - stageLength;
    rwContext->Numxfer         = 0;
    rwContext->VirtualAddress  = virtualAddress + stageLength;

    if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS)) {
        status = WdfRequestGetStatus(Request);
        ASSERT(!NT_SUCCESS(status));
    }

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

        if (newMdl != NULL) {
            IoFreeMdl(newMdl);
        }
    }

    kJtag_DbgPrint(3, ("kJtag_DispatchReadWrite - ends\n"));

    return;
}
Beispiel #23
0
NTSTATUS
OsrFxEvtDeviceAdd(
    WDFDRIVER Driver,
    PWDFDEVICE_INIT DeviceInit
    )
/*++
Routine Description:

    EvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager. We create and initialize a device object to
    represent a new instance of the device. All the software resources
    should be allocated in this callback.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    WDF_PNPPOWER_EVENT_CALLBACKS        pnpPowerCallbacks;
    WDF_OBJECT_ATTRIBUTES               attributes;
    NTSTATUS                            status;
    WDFDEVICE                           device;
    WDF_DEVICE_PNP_CAPABILITIES         pnpCaps;
    WDF_IO_QUEUE_CONFIG                 ioQueueConfig;
    PDEVICE_CONTEXT                     pDevContext;
    WDFQUEUE                            queue;
    GUID                                activity;

    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"--> OsrFxEvtDeviceAdd routine\n");

    //
    // Initialize the pnpPowerCallbacks structure.  Callback events for PNP
    // and Power are specified here.  If you don't supply any callbacks,
    // the Framework will take appropriate default actions based on whether
    // DeviceInit is initialized to be an FDO, a PDO or a filter device
    // object.
    //

    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
    //
    // For usb devices, PrepareHardware callback is the to place select the
    // interface and configure the device.
    //
    pnpPowerCallbacks.EvtDevicePrepareHardware = OsrFxEvtDevicePrepareHardware;

    //
    // These two callbacks start and stop the wdfusb pipe continuous reader
    // as we go in and out of the D0-working state.
    //

    pnpPowerCallbacks.EvtDeviceD0Entry = OsrFxEvtDeviceD0Entry;
    pnpPowerCallbacks.EvtDeviceD0Exit  = OsrFxEvtDeviceD0Exit;

    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);

    WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);

    //
    // Now specify the size of device extension where we track per device
    // context.DeviceInit is completely initialized. So call the framework
    // to create the device and attach it to the lower stack.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);

    status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfDeviceCreate failed with Status code %!STATUS!\n", status);
        return status;
    }

    //
    // Setup the activity ID so that we can log events using it.
    //

    activity = DeviceToActivityId(device);

    //
    // Get the DeviceObject context by using accessor function specified in
    // the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro for DEVICE_CONTEXT.
    //
    pDevContext = GetDeviceContext(device);

    //
    // Get the device's friendly name and location so that we can use it in 
    // error logging.  If this fails then it will setup dummy strings.
    //

    GetDeviceEventLoggingNames(device);

    //
    // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so
    // that you don't get the popup in usermode (on Win2K) when you surprise
    // remove the device.
    //
    WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);
    pnpCaps.SurpriseRemovalOK = WdfTrue;

    WdfDeviceSetPnpCapabilities(device, &pnpCaps);

    //
    // Create a parallel default queue and register an event callback to
    // receive ioctl requests. We will create separate queues for
    // handling read and write requests. All other requests will be
    // completed with error status automatically by the framework.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,
                             WdfIoQueueDispatchParallel);

    ioQueueConfig.EvtIoDeviceControl    = OsrFxEvtIoDeviceControl;

    status = WdfIoQueueCreate(device,
                             &ioQueueConfig,
                             WDF_NO_OBJECT_ATTRIBUTES,
                             &queue);// pointer to default queue
    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                            "WdfIoQueueCreate failed  %!STATUS!\n", status);
        goto Error;
    }

    //
    // We will create a separate sequential queue and configure it
    // to receive read requests.  We also need to register a EvtIoStop
    // handler so that we can acknowledge requests that are pending
    // at the target driver.
    //
    WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchSequential);

    ioQueueConfig.EvtIoRead = OsrFxEvtIoRead;
    ioQueueConfig.EvtIoStop = OsrFxEvtIoStop;

    status = WdfIoQueueCreate(
                 device,
                 &ioQueueConfig,
                 WDF_NO_OBJECT_ATTRIBUTES,
                 &queue // queue handle
             );

    if (!NT_SUCCESS (status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfIoQueueCreate failed 0x%x\n", status);
        goto Error;
    }

    status = WdfDeviceConfigureRequestDispatching(
                    device,
                    queue,
                    WdfRequestTypeRead);

    if(!NT_SUCCESS (status)){
        ASSERT(NT_SUCCESS(status));
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                    "WdfDeviceConfigureRequestDispatching failed 0x%x\n", status);
        goto Error;
    }


    //
    // We will create another sequential queue and configure it
    // to receive write requests.
    //
    WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchSequential);

    ioQueueConfig.EvtIoWrite = OsrFxEvtIoWrite;
    ioQueueConfig.EvtIoStop  = OsrFxEvtIoStop;

    status = WdfIoQueueCreate(
                 device,
                 &ioQueueConfig,
                 WDF_NO_OBJECT_ATTRIBUTES,
                 &queue // queue handle
             );

    if (!NT_SUCCESS (status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfIoQueueCreate failed 0x%x\n", status);
        goto Error;
    }

     status = WdfDeviceConfigureRequestDispatching(
                    device,
                    queue,
                    WdfRequestTypeWrite);

    if(!NT_SUCCESS (status)){
        ASSERT(NT_SUCCESS(status));
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                    "WdfDeviceConfigureRequestDispatching failed 0x%x\n", status);
        goto Error;
    }

    //
    // Register a manual I/O queue for handling Interrupt Message Read Requests.
    // This queue will be used for storing Requests that need to wait for an
    // interrupt to occur before they can be completed.
    //
    WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchManual);

    //
    // This queue is used for requests that dont directly access the device. The
    // requests in this queue are serviced only when the device is in a fully
    // powered state and sends an interrupt. So we can use a non-power managed
    // queue to park the requests since we dont care whether the device is idle
    // or fully powered up.
    //
    ioQueueConfig.PowerManaged = WdfFalse;

    status = WdfIoQueueCreate(device,
                              &ioQueueConfig,
                              WDF_NO_OBJECT_ATTRIBUTES,
                              &pDevContext->InterruptMsgQueue
                              );

    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
            "WdfIoQueueCreate failed 0x%x\n", status);
        goto Error;
    }

    //
    // Register a device interface so that app can find our device and talk to it.
    //
    status = WdfDeviceCreateDeviceInterface(device,
                        (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2,
                        NULL);// Reference String
    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                 "WdfDeviceCreateDeviceInterface failed  %!STATUS!\n", status);
        goto Error;
    }

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- OsrFxEvtDeviceAdd\n");

    return status;
    
Error:

    //
    // Log fail to add device to the event log
    //
    EventWriteFailAddDevice(&activity, 
                            pDevContext->DeviceName, 
                            pDevContext->Location,
                            status);

    return status;
}
//	this will Initialize DirectX graphics and its window
void TSRD3D11GraphicsSubSystem::InitGraphics( TSRScreenMode& _mode )
{
    DXGI_SWAP_CHAIN_DESC SwapChainDesc;

    ZeroMemory( &SwapChainDesc, sizeof( SwapChainDesc ) );

	unsigned int uiNumSamples = _mode.m_uiSamplesCountForMSAA;
    if ( uiNumSamples == 0 )
    {
        uiNumSamples = 1;
    }

    D3D_RTV_DIMENSION  RenderTargetViewDimension = D3D_RTV_DIMENSION_TEXTURE2D;
    D3D_DSV_DIMENSION  DepthStencilViewDimension = D3D_DSV_DIMENSION_TEXTURE2D;

    if ( uiNumSamples > 1 )
    {
        RenderTargetViewDimension = D3D_RTV_DIMENSION_TEXTURE2DMS;
        DepthStencilViewDimension = D3D_DSV_DIMENSION_TEXTURE2DMS;
    }


	if ( _mode.m_bBackBufferUsesDesktopResolution )
	{
		m_uiBackBufferWidth  = GetSystemMetrics( SM_CXFULLSCREEN );
		m_uiBackBufferHeight = GetSystemMetrics( SM_CYFULLSCREEN );
	}
	else
	{
		m_uiBackBufferWidth  = TSRSystem()->m_DisplayMode.m_uiWidth;
		m_uiBackBufferHeight = TSRSystem()->m_DisplayMode.m_uiHeight;
	}
       
    SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    SwapChainDesc.BufferDesc.Width = m_uiBackBufferWidth;
    SwapChainDesc.BufferDesc.Height = m_uiBackBufferHeight;
    SwapChainDesc.BufferDesc.RefreshRate.Denominator = 60;
    SwapChainDesc.BufferDesc.RefreshRate.Numerator   = 1;
   // SwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
   // SwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;

    SwapChainDesc.SampleDesc.Count = uiNumSamples;
    SwapChainDesc.SampleDesc.Quality = 0;

    SwapChainDesc.BufferUsage  = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
    SwapChainDesc.BufferCount  = 1;
    SwapChainDesc.OutputWindow = SystemWin32()->GetMainHWND();
    SwapChainDesc.Windowed     = TSRSystem()->m_DisplayMode.m_bIsWindowed ? TRUE : FALSE;
    SwapChainDesc.SwapEffect   = DXGI_SWAP_EFFECT_DISCARD;
    SwapChainDesc.Flags        = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

    /*UINT uiNumAdapters = 0; 
    IDXGIAdapter* pAdapter; 
    std::vector <IDXGIAdapter*> vAdapters;
    std::vector <DXGI_ADAPTER_DESC> vAdapterDescriptors;
    DXGI_ADAPTER_DESC adapterDesc;
    
    IDXGIFactory * pFactory;
    HRESULT hrr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory) );

    while(pFactory->EnumAdapters(uiNumAdapters, &pAdapter) != DXGI_ERROR_NOT_FOUND) 
    { 
	    vAdapters.push_back(pAdapter); 
        pAdapter->GetDesc( &adapterDesc );
        vAdapterDescriptors.push_back( adapterDesc );
	    ++uiNumAdapters; 
    } */


	unsigned int uiDeviceCreationFlags = 0;

#ifdef _DEBUG

	/// onwindows 10, deubg flag results in crash, so disabling it for now
	uiDeviceCreationFlags = 0;//D3D_CREATE_DEVICE_DEBUG;

#endif 


#ifdef D3D10_RENDERER

    HRESULT hr = D3D10CreateDeviceAndSwapChain( NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, uiDeviceCreationFlags, D3D10_SDK_VERSION, &SwapChainDesc, &m_pSwapChain, &m_pD3DDevice );

#endif 

#ifdef D3D11_RENDERER

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
		D3D_FEATURE_LEVEL_9_3,
		D3D_FEATURE_LEVEL_9_2,
		D3D_FEATURE_LEVEL_9_1
    };
    UINT numFeatureLevels = ARRAYSIZE( featureLevels );
    HRESULT hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, uiDeviceCreationFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &SwapChainDesc, &m_pSwapChain, &m_pD3DDevice, &m_FeatureLevel, &m_pD3DDeviceContext );

#endif 

    // Create a render target view
    ID3DTexture2D* pBuffer;
    hr = m_pSwapChain->GetBuffer( 0, __uuidof( ID3DTexture2D ), ( LPVOID* ) &pBuffer );
    if( FAILED( hr ) )
    {
        assert( 0 && "Failed to get the back buffer from the swap chain" );
    }

    D3D_RENDER_TARGET_VIEW_DESC DescRT;
    DescRT.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    DescRT.ViewDimension = RenderTargetViewDimension;
    DescRT.Texture2D.MipSlice = 0;
    hr = m_pD3DDevice->CreateRenderTargetView( pBuffer, &DescRT, &m_pColorBufferView );
    pBuffer->Release();
    if( FAILED( hr ) )
    {
        assert( 0 && "Failed to create render target view" );
    }

    // Create depth stencil texture
    D3D_TEXTURE2D_DESC descDepth;
    descDepth.Width = m_uiBackBufferWidth;
    descDepth.Height = m_uiBackBufferHeight;
    descDepth.MipLevels = 1;
    descDepth.ArraySize = 1;
    descDepth.Format = DXGI_FORMAT_D32_FLOAT;
    descDepth.SampleDesc.Count = uiNumSamples;
    descDepth.SampleDesc.Quality = 0;
    descDepth.Usage = D3D_USAGE_DEFAULT;
    descDepth.BindFlags = D3D_BIND_DEPTH_STENCIL;
    descDepth.CPUAccessFlags = 0;
    descDepth.MiscFlags = 0;
    hr = m_pD3DDevice->CreateTexture2D( &descDepth, NULL, &m_pDepthStencil );
    if ( FAILED( hr ) )
    {
        assert( 0 && "Failed to create the depth stencil target" );
    }

    // Create the depth stencil view
    D3D_DEPTH_STENCIL_VIEW_DESC descDSV;
    ZeroMemory( &descDSV, sizeof( D3D_DEPTH_STENCIL_VIEW_DESC ) );
    descDSV.Format = descDepth.Format;
    descDSV.ViewDimension = DepthStencilViewDimension;
    descDSV.Texture2D.MipSlice = 0;
    hr = m_pD3DDevice->CreateDepthStencilView( m_pDepthStencil, &descDSV, &m_pDepthStencilView );
    if ( FAILED( hr ) )
    {
        assert( 0 && "Failed to create the depth stencil view" );
    }

    m_pActiveColorBufferViews[ 0 ] = m_pColorBufferView;
    m_pActiveColorBufferViews[ 1 ] = NULL;
    m_pActiveColorBufferViews[ 2 ] = NULL;
    m_pActiveColorBufferViews[ 3 ] = NULL;
    m_pActiveDepthStencilView = m_pDepthStencilView;

    GetDeviceContext()->OMSetRenderTargets( 1, m_pActiveColorBufferViews, m_pActiveDepthStencilView );

    // set the projection matrix accordingly
    Resize( _mode.m_uiWidth, _mode.m_uiHeight );

    m_pColorBufferTexture = pBuffer;


    /// Create staging selection buffer texture
    D3D_TEXTURE2D_DESC descSelectionBuffer;
    descSelectionBuffer.Width = m_uiBackBufferWidth;
    descSelectionBuffer.Height = m_uiBackBufferHeight;
    descSelectionBuffer.MipLevels = 1;
    descSelectionBuffer.ArraySize = 1;
    descSelectionBuffer.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    descSelectionBuffer.SampleDesc.Count = 1;//uiNumSamples;
    descSelectionBuffer.SampleDesc.Quality = 0;
    descSelectionBuffer.Usage = D3D_USAGE_STAGING;
    descSelectionBuffer.BindFlags = 0;
    descSelectionBuffer.CPUAccessFlags = D3D_CPU_ACCESS_READ ;
    descSelectionBuffer.MiscFlags = 0;
    hr = m_pD3DDevice->CreateTexture2D( &descSelectionBuffer, NULL, &m_pCpuBackBufferCopy );
    if ( FAILED( hr ) )
    {
        assert( 0 && "Failed to create the selection buffer" );
    }

	m_pQueryIdleGPU = NULL;


	D3D_QUERY_DESC queryDesc;
	queryDesc.MiscFlags = 0;
	queryDesc.Query = D3D_QUERY_EVENT;
    m_pD3DDevice->CreateQuery( &queryDesc, &m_pQueryIdleGPU );


#ifdef D3D10_RENDERER
    TSRPrintln( "D3D10 initialized successfully" );
#endif 

    
#ifdef D3D11_RENDERER
    TSRPrintln( "D3D11 initialized successfully" );
#endif

#ifdef D3D10_RENDERER
    TSRPrintln( "D3D10 initialized successfully" );
#endif 
}
Beispiel #25
0
NTSTATUS
SelectInterfaces(
    __in WDFDEVICE Device
    )
/*++

Routine Description:

    This helper routine selects the configuration, interface and
    creates a context for every pipe (end point) in that interface.

Arguments:

    Device - Handle to a framework device

Return Value:

    NT status value

--*/
{
    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
    NTSTATUS                            status;
    PDEVICE_CONTEXT                     pDeviceContext;
    WDFUSBPIPE                          pipe;
    WDF_USB_PIPE_INFORMATION            pipeInfo;
    UCHAR                               index;
    UCHAR                               numberConfiguredPipes;

    PAGED_CODE();

    pDeviceContext = GetDeviceContext(Device);

    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

    status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
                                        WDF_NO_OBJECT_ATTRIBUTES,
                                        &configParams);
    if(!NT_SUCCESS(status)) {

        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                        "WdfUsbTargetDeviceSelectConfig failed %!STATUS! \n",
                        status);

        //
        // Since the Osr USB fx2 device is capable of working at high speed, the only reason 
        // the device would not be working at high speed is if the port doesn't 
        // support it. If the port doesn't support high speed it is a 1.1 port
        //
        if ((pDeviceContext->UsbDeviceTraits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) == 0) {
            GUID activity = DeviceToActivityId(Device);

            TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                            " On a 1.1 USB port on Windows Vista" 
                            " this is expected as the OSR USB Fx2 board's Interrupt EndPoint descriptor" 
                            " doesn't conform to the USB specification. Windows Vista detects this and"
                            " returns an error. \n"
                            );
            EventWriteSelectConfigFailure(
                &activity,
                pDeviceContext->DeviceName,
                pDeviceContext->Location,
                status
                );
        }
        
        return status;
    }


    pDeviceContext->UsbInterface =
                configParams.Types.SingleInterface.ConfiguredUsbInterface;

    numberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes;

    //
    // Get pipe handles
    //
    for(index=0; index < numberConfiguredPipes; index++) {

        WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);

        pipe = WdfUsbInterfaceGetConfiguredPipe(
            pDeviceContext->UsbInterface,
            index, //PipeIndex,
            &pipeInfo
            );
        //
        // Tell the framework that it's okay to read less than
        // MaximumPacketSize
        //
        WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

        if(WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "Interrupt Pipe is 0x%p\n", pipe);
            pDeviceContext->InterruptPipe = pipe;
        }

        if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
                WdfUsbTargetPipeIsInEndpoint(pipe)) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "BulkInput Pipe is 0x%p\n", pipe);
            pDeviceContext->BulkReadPipe = pipe;
        }

        if(WdfUsbPipeTypeBulk == pipeInfo.PipeType &&
                WdfUsbTargetPipeIsOutEndpoint(pipe)) {
            TraceEvents(TRACE_LEVEL_INFORMATION, DBG_IOCTL,
                    "BulkOutput Pipe is 0x%p\n", pipe);
            pDeviceContext->BulkWritePipe = pipe;
        }

    }

    //
    // If we didn't find all the 3 pipes, fail the start.
    //
    if(!(pDeviceContext->BulkWritePipe
            && pDeviceContext->BulkReadPipe && pDeviceContext->InterruptPipe)) {
        status = STATUS_INVALID_DEVICE_STATE;
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                            "Device is not configured properly %!STATUS!\n",
                            status);

        return status;
    }

    return status;
}
Beispiel #26
0
NTSTATUS
kmdf1394_EvtDeviceAdd (
                       IN WDFDRIVER        Driver,
                       IN PWDFDEVICE_INIT  DeviceInit)
/*++
Routine Description:

    EvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION deviceExtension;
    WDF_PNPPOWER_EVENT_CALLBACKS  pnpPowerCallbacks;
    WDF_OBJECT_ATTRIBUTES fdoAttributes,lockAttributes;
    WDFDEVICE device;
    WDF_DEVICE_PNP_CAPABILITIES pnpCaps;
    WDF_IO_QUEUE_CONFIG ioQueueConfig;

    UNREFERENCED_PARAMETER (Driver);

    PAGED_CODE();

    Enter();

    //
    // Zero out the PnpPowerCallbacks structure.
    //
    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);

    //
    // Set Callbacks for any of the functions we are interested in.
    // If no callback is set, Framework will take the default action
    // by itself.

    //
    // These two callbacks set up and tear down hardware state,
    // specifically that which only has to be done once.
    //

    pnpPowerCallbacks.EvtDevicePrepareHardware = kmdf1394_EvtPrepareHardware;
    pnpPowerCallbacks.EvtDeviceReleaseHardware = kmdf1394_EvtReleaseHardware;

    pnpPowerCallbacks.EvtDeviceSelfManagedIoCleanup = \
        kmdf1394_EvtDeviceSelfManagedIoCleanup;

    pnpPowerCallbacks.EvtDeviceD0Entry = kmdf1394_EvtDeviceD0Entry;
    pnpPowerCallbacks.EvtDeviceD0Exit  = kmdf1394_EvtDeviceD0Exit;

    //
    // Register the PnP and power callbacks. Power policy related callbacks
    // will be registered// later in SotwareInit.
    //
    WdfDeviceInitSetPnpPowerEventCallbacks (DeviceInit, &pnpPowerCallbacks);
    if (!NT_SUCCESS (ntStatus))
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfDeviceInitSetPnpPowerEventCallbacks failed %!STATUS!\n",
                            ntStatus);
        return ntStatus;
    }

    //
    // We'll allow multiple handles to be opened to this device driver
    // so we'll set exclusivity to FALSE.
    //
    WdfDeviceInitSetExclusive (DeviceInit, FALSE);

    //
    // Specify the size and type of device context.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE (&fdoAttributes, DEVICE_EXTENSION);

    ntStatus = WdfDeviceCreate (&DeviceInit, &fdoAttributes, &device);

    if (!NT_SUCCESS (ntStatus)) 
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfDeviceInitialize failed %!STATUS!\n", 
                            ntStatus);
        return ntStatus;
    }


    deviceExtension = GetDeviceContext (device);
    deviceExtension->WdfDevice = device;

    DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, 
                        TRACE_FLAG_PNP,
                        "PDO(0x%p) FDO(0x%p), Lower(0x%p) DevExt (0x%p)\n",
                        WdfDeviceWdmGetPhysicalDevice (device),
                        WdfDeviceWdmGetDeviceObject (device),
                        WdfDeviceWdmGetAttachedDevice(device),
                        deviceExtension);

    //
    // Tell the Framework that this device will need an interface so that
    // application can interact with it.
    //

    ntStatus = WdfDeviceCreateDeviceInterface (
        device,
        (LPGUID) &GUID_KMDF_VDEV,
        NULL);
    if (!NT_SUCCESS (ntStatus)) 
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfDeviceCreateDeviceInterface failed %!STATUS!\n", 
                            ntStatus);
        return ntStatus;
    }

    //
    // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so
    // that you don't get the popup in usermode (on Win2K) when you surprise
    // remove the device.
    //
    WDF_DEVICE_PNP_CAPABILITIES_INIT (&pnpCaps);
    pnpCaps.SurpriseRemovalOK = WdfTrue;

    WdfDeviceSetPnpCapabilities (device, &pnpCaps);

    //
    // save the device object we created as our physical device object
    //
    deviceExtension->PhysicalDeviceObject = \
        WdfDeviceWdmGetPhysicalDevice (device);

    if (NULL == deviceExtension->PhysicalDeviceObject) 
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfDeviceWdmGetPhysicalDevice: NULL DeviceObject\n");
        return STATUS_UNSUCCESSFUL;
    }

    //
    // This is our default IoTarget representing the deviceobject
    // we are attached to.
    //
    deviceExtension->StackIoTarget = WdfDeviceGetIoTarget(device);
    deviceExtension->StackDeviceObject = WdfDeviceWdmGetAttachedDevice(device);

    if (NULL == deviceExtension->StackDeviceObject) 
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfDeviceWdmGetAttachedDevice: NULL DeviceObject\n");
        return STATUS_UNSUCCESSFUL;
    }


    //
    // Create a automanaged queue for dispatching ioctl requests.
    // All other requests are automatically failed by the framework.
    // By creating an automanaged queue we don't have to worry about
    // PNP/Power synchronization.
    // A default queue gets all the requests that are not
    // configure-fowarded using WdfDeviceConfigureRequestDispatching.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE (
        &ioQueueConfig,
        WdfIoQueueDispatchParallel);

    ioQueueConfig.EvtIoDeviceControl = kmdf1394_EvtIoDeviceControl;
    
    __analysis_assume(ioQueueConfig.EvtIoStop != 0);
    ntStatus = WdfIoQueueCreate (
        deviceExtension->WdfDevice,
        &ioQueueConfig,
        WDF_NO_OBJECT_ATTRIBUTES,
        &deviceExtension->IoctlQueue);
    __analysis_assume(ioQueueConfig.EvtIoStop == 0);
    if (!NT_SUCCESS (ntStatus)) 
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfIoQueueCreate failed %!STATUS!\n", 
                            ntStatus);
        return ntStatus;
    }

    //
    // Create an additional queue to hold bus reset requests.
    //
    WDF_IO_QUEUE_CONFIG_INIT (&ioQueueConfig, WdfIoQueueDispatchManual);

    __analysis_assume(ioQueueConfig.EvtIoStop != 0);
    ntStatus = WdfIoQueueCreate (
        deviceExtension->WdfDevice,
        &ioQueueConfig,
        WDF_NO_OBJECT_ATTRIBUTES,
        &deviceExtension->BusResetRequestsQueue);
    __analysis_assume(ioQueueConfig.EvtIoStop == 0);
    if(!NT_SUCCESS (ntStatus))
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "Error Creating Reset Request Queue %!STATUS!\n",
                            ntStatus);
        return ntStatus;
    }
    WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes);
    lockAttributes.ParentObject = device;

    ntStatus = WdfSpinLockCreate (&lockAttributes,&deviceExtension->CromSpinLock);
    if(!NT_SUCCESS (ntStatus))
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfSpinLockCreate CromSpinLock failed %!STATUS!\n", 
                            ntStatus);
        return ntStatus;
    }


    WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes);
    lockAttributes.ParentObject = device;

    ntStatus = WdfSpinLockCreate (
        &lockAttributes,
        &deviceExtension->AsyncSpinLock);
    if(!NT_SUCCESS (ntStatus))
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfSpinLockCreate AsyncSpinLock failed %!STATUS!\n", 
                            ntStatus);
        return ntStatus;
    }

    WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes);
    lockAttributes.ParentObject = device;

    ntStatus = WdfSpinLockCreate (
        &lockAttributes,
        &deviceExtension->IsochSpinLock );
    if(!NT_SUCCESS (ntStatus))
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfSpinLockCreate IsochSpinLock failed %!STATUS!\n", 
                            ntStatus);
        return ntStatus;
    }

    WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes);
    lockAttributes.ParentObject = device;

    ntStatus = WdfSpinLockCreate (
        &lockAttributes,
        &deviceExtension->IsochResourceSpinLock);
    if(!NT_SUCCESS (ntStatus))
    {
        DoTraceLevelMessage(TRACE_LEVEL_ERROR, 
                            TRACE_FLAG_PNP, 
                            "WdfSpinLockCreate IsochResourceSpinLock failed %!STATUS!\n", 
                            ntStatus);
        return ntStatus;
    }

    InitializeListHead (&deviceExtension->CromData);
    InitializeListHead (&deviceExtension->AsyncAddressData);
    InitializeListHead (&deviceExtension->IsochDetachData);
    InitializeListHead (&deviceExtension->IsochResourceData);

    ExitS(ntStatus);
    return(ntStatus);
} // kmdf1394_PnpAddDevice
Beispiel #27
0
VOID
GetDeviceEventLoggingNames(
    __in WDFDEVICE Device
    )
/*++

Routine Description:

    Retrieve the friendly name and the location string into WDFMEMORY objects
    and store them in the device context.

Arguments:

Return Value:

    NT status

--*/
{
    PDEVICE_CONTEXT pDevContext = GetDeviceContext(Device);

    WDF_OBJECT_ATTRIBUTES objectAttributes;

    WDFMEMORY deviceNameMemory = NULL;
    WDFMEMORY locationMemory = NULL;

    NTSTATUS status;

    PAGED_CODE();

    //
    // We want both memory objects to be children of the device so they will 
    // be deleted automatically when the device is removed.
    //

    WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes);
    objectAttributes.ParentObject = Device;

    //
    // First get the length of the string. If the FriendlyName
    // is not there then get the lenght of device description.
    //

    status = WdfDeviceAllocAndQueryProperty(Device,
                                            DevicePropertyFriendlyName,
                                            NonPagedPool,
                                            &objectAttributes,
                                            &deviceNameMemory);

    if (!NT_SUCCESS(status))
    {
        status = WdfDeviceAllocAndQueryProperty(Device,
                                                DevicePropertyDeviceDescription,
                                                NonPagedPool,
                                                &objectAttributes,
                                                &deviceNameMemory);
    }

    if (NT_SUCCESS(status))
    {
        pDevContext->DeviceNameMemory = deviceNameMemory;
        pDevContext->DeviceName = WdfMemoryGetBuffer(deviceNameMemory, NULL);
    }
    else
    {
        pDevContext->DeviceNameMemory = NULL;
        pDevContext->DeviceName = L"(error retrieving name)";
    }

    //
    // Retrieve the device location string.
    //

    status = WdfDeviceAllocAndQueryProperty(Device, 
                                            DevicePropertyLocationInformation,
                                            NonPagedPool,
                                            WDF_NO_OBJECT_ATTRIBUTES,
                                            &locationMemory);

    if (NT_SUCCESS(status))
    {
        pDevContext->LocationMemory = locationMemory;
        pDevContext->Location = WdfMemoryGetBuffer(locationMemory, NULL);
    }
    else
    {
        pDevContext->LocationMemory = NULL;
        pDevContext->Location = L"(error retrieving location)";
    }

    return;
}
Beispiel #28
0
NTSTATUS
kmdf1394_GetLocalHostInformation(
                                 IN WDFDEVICE  Device,
                                 IN WDFREQUEST Request,
                                 IN OUT PGET_LOCAL_HOST_INFORMATION GetLocalHostInfo)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION  deviceExtension = GetDeviceContext(Device);
    PIRB pIrb = NULL;

    GET_LOCAL_HOST_INFO7    LocalHostInfo7  = {0};
    GET_LOCAL_HOST_INFO6    LocalHostInfo6  = {0};
    GET_LOCAL_HOST_INFO5    LocalHostInfo5  = {0};

    ENTER("kmdf1394_GetLocalHostInformation");

    TRACE(TL_TRACE, ("nLevel = 0x%x\n", GetLocalHostInfo->nLevel));
    TRACE(TL_TRACE, ("Information = 0x%x\n", GetLocalHostInfo->Information));

    pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV);
    if (!pIrb) 
    {
        TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
        return STATUS_INSUFFICIENT_RESOURCES;   
    }

    RtlZeroMemory (pIrb, sizeof (IRB));
    pIrb->FunctionNumber = REQUEST_GET_LOCAL_HOST_INFO;
    pIrb->Flags = 0;
    pIrb->u.GetLocalHostInformation.nLevel = GetLocalHostInfo->nLevel;

    switch (GetLocalHostInfo->nLevel)
    {
    case GET_HOST_DMA_CAPABILITIES:
        {

            //
            // need to ensure that no one passed us an GET_LOCAL_HOST_INFO7 
            // structure that just piggy backed on the 
            // GET_LOCAL_HOST_INFORMATION struct, if they did this will cause
            // data misalignment errors in 64 bit because 1394bus will be expecting that structure to
            // be aligned correctly
            //
            RtlCopyMemory (&LocalHostInfo7, GetLocalHostInfo->Information, 
                                    sizeof (GET_LOCAL_HOST_INFO7));

            pIrb->u.GetLocalHostInformation.Information = &LocalHostInfo7;

            TRACE(
                TL_TRACE, 
                ("HostDmaCapabilities = 0x%p\n", 
                LocalHostInfo7.HostDmaCapabilities));

            TRACE(TL_TRACE, ("MaxDmaBufferSize High = 0x%x\n", 
                                    LocalHostInfo7.MaxDmaBufferSize.HighPart));
            TRACE(TL_TRACE, ("MaxDmaBufferSize Low = 0x%x\n", 
                                    LocalHostInfo7.MaxDmaBufferSize.LowPart));

        }
        break;

    case GET_HOST_CSR_CONTENTS:
        {

            LocalHostInfo6.CsrBaseAddress.Off_High = \
                ((PGET_LOCAL_HOST_INFO6)GetLocalHostInfo->Information)->CsrBaseAddress.Off_High;

            LocalHostInfo6.CsrBaseAddress.Off_Low = \
                ((PGET_LOCAL_HOST_INFO6)GetLocalHostInfo->Information)->CsrBaseAddress.Off_Low;

            LocalHostInfo6.CsrDataLength = \
                ((PGET_LOCAL_HOST_INFO6)GetLocalHostInfo->Information)->CsrDataLength;

            //
            // Pointer math needed to correct size differential between 
            // data structures on WIN64 only LocalHostInfo6.CsrDataBuffer 
            // is UCHAR @ 4 bytes, Information->CsrDataBuffer is a PVIOD 
            // @ 8 bytes
            //
            LocalHostInfo6.CsrDataBuffer = \
                ((PCHAR)&(((PGET_LOCAL_HOST_INFO6)GetLocalHostInfo->Information)->CsrDataLength)) \
                + sizeof (ULONG);

            pIrb->u.GetLocalHostInformation.Information = &LocalHostInfo6;

            TRACE(TL_TRACE, ("CsrBaseAddress.Off_High = 0x%x\n", 
                                    LocalHostInfo6.CsrBaseAddress.Off_High));
            TRACE(TL_TRACE, ("CsrBaseAddress.Off_Low = 0x%x\n", 
                                    LocalHostInfo6.CsrBaseAddress.Off_Low));
            TRACE(TL_TRACE, ("CsrDataLength = 0x%x\n", LocalHostInfo6.CsrDataLength));
            TRACE(TL_TRACE, ("CsrDataBuffer = 0x%p\n", LocalHostInfo6.CsrDataBuffer));
        }
        break;

    case GET_HOST_CONFIG_ROM:
        {
            //
            // need to ensure that no one passed us an GET_LOCAL_HOST_INFO5 
            // structure that just piggy backed on the 
            // GET_LOCAL_HOST_INFORMATION struct, if they did this will cause
            // data misalignment errors in 64 bit because 1394bus will be expecting that structure to
            // be aligned correctly
            //
            RtlCopyMemory (&LocalHostInfo5, GetLocalHostInfo->Information, 
                                    sizeof (GET_LOCAL_HOST_INFO5));

            pIrb->u.GetLocalHostInformation.Information = &LocalHostInfo5;

            TRACE(TL_TRACE, ("ConfigRom = 0x%p\n", LocalHostInfo5.ConfigRom));
            TRACE(
                TL_TRACE, 
                ("ConfigRomLength = 0x%x\n", 
                LocalHostInfo5.ConfigRomLength));
        }
    break;

    default:
        {
            pIrb->u.GetLocalHostInformation.Information = \
                GetLocalHostInfo->Information;
        }

        break;
    }// switch

    ntStatus = kmdf1394_SubmitIrpSynch(
        deviceExtension->StackIoTarget, 
        Request, 
        pIrb);
    if (!NT_SUCCESS (ntStatus)) 
    {
        if (STATUS_INVALID_BUFFER_SIZE == ntStatus) 
        {
            //
            // we have to set status=success, otherwise, we don't get
            // the size value passed up to ring 3.
            //
            ntStatus = STATUS_SUCCESS;
            GetLocalHostInfo->Status = 122;

            TRACE(
                TL_WARNING, 
                ("Invalid Buffer Size. nLevel = 0x%x\n", 
                GetLocalHostInfo->nLevel));

            //
            // see if it's a config rom request or a csr request
            //
            if (GET_HOST_CONFIG_ROM == GetLocalHostInfo->nLevel) 
            {
                //
                // it is, lets print out the size
                //
                TRACE(
                    TL_TRACE, 
                    ("ConfigRomLength = 0x%x\n", 
                    LocalHostInfo5.ConfigRomLength));

                //
                // need to set this in the information struct we were passed down
                //
                RtlCopyMemory(
                    GetLocalHostInfo->Information, 
                    &LocalHostInfo5,
                    sizeof (GET_LOCAL_HOST_INFO5));
            }
            else if (GET_HOST_CSR_CONTENTS == GetLocalHostInfo->nLevel) 
            {
                //
                // csr, print out size
                //
                TRACE(
                    TL_TRACE, 
                    ("CsrDataLength needed = 0x%x\n", 
                    LocalHostInfo6.CsrDataLength));

                //
                // need to set this in the information struct we were passed down
                //
                ((PGET_LOCAL_HOST_INFO6)GetLocalHostInfo->Information)->CsrDataLength = \
                    LocalHostInfo6.CsrDataLength;
            }
            else if (GET_HOST_DMA_CAPABILITIES == GetLocalHostInfo->nLevel) 
            {
                //
                // copy the results of the struct passed down
                //
                RtlCopyMemory(
                    GetLocalHostInfo->Information, 
                    &LocalHostInfo7, 
                    sizeof (GET_LOCAL_HOST_INFO7));
            }
        } // if (STATUS_INVALID_BUFFER_SIZE == ntStatus)
        else 
        {
            TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
        }
    } // if (!NT_SUCCESS (ntStatus))
    else 
    {
        GetLocalHostInfo->Status = 0;

        if (GET_HOST_UNIQUE_ID == GetLocalHostInfo->nLevel) 
        {
            PGET_LOCAL_HOST_INFO1   LocalHostInfo1;

            LocalHostInfo1 = (PGET_LOCAL_HOST_INFO1)GetLocalHostInfo->Information;

            TRACE(TL_TRACE, ("UniqueId.LowPart = 0x%x\n",
                             LocalHostInfo1->UniqueId.LowPart));
            TRACE(TL_TRACE, ("UniqueId.HighPart = 0x%x\n",
                             LocalHostInfo1->UniqueId.HighPart));
        }
        else if (GET_HOST_CAPABILITIES == GetLocalHostInfo->nLevel) 
        {
            PGET_LOCAL_HOST_INFO2   LocalHostInfo2;

            LocalHostInfo2 = (PGET_LOCAL_HOST_INFO2)GetLocalHostInfo->Information;

            TRACE(TL_TRACE, ("HostCapabilities = 0x%x\n",
                             LocalHostInfo2->HostCapabilities));
            TRACE(TL_TRACE, ("MaxAsyncReadRequest = 0x%x\n",
                             LocalHostInfo2->MaxAsyncReadRequest));
            TRACE(TL_TRACE, ("MaxAsyncWriteRequest = 0x%x\n",
                             LocalHostInfo2->MaxAsyncWriteRequest));
        }
        else if (GET_POWER_SUPPLIED == GetLocalHostInfo->nLevel) 
        {
            PGET_LOCAL_HOST_INFO3   LocalHostInfo3;

            LocalHostInfo3 = (PGET_LOCAL_HOST_INFO3)GetLocalHostInfo->Information;

            TRACE(TL_TRACE, ("deciWattsSupplied = 0x%x\n",
                             LocalHostInfo3->deciWattsSupplied));
            TRACE(TL_TRACE, ("Voltage = 0x%x\n", LocalHostInfo3->Voltage));
        }
        else if (GET_PHYS_ADDR_ROUTINE == GetLocalHostInfo->nLevel)
        {
            PGET_LOCAL_HOST_INFO4   LocalHostInfo4;

            LocalHostInfo4 = (PGET_LOCAL_HOST_INFO4)GetLocalHostInfo->Information;

            TRACE(TL_TRACE, ("Context = 0x%x\n", LocalHostInfo4->Context));
        }
        else if (GET_HOST_CONFIG_ROM == GetLocalHostInfo->nLevel) 
        {
            PGET_LOCAL_HOST_INFO5   pLocalHostInfo5;

            pLocalHostInfo5 = \
                (PGET_LOCAL_HOST_INFO5)GetLocalHostInfo->Information;

            TRACE(
                TL_TRACE, 
                ("ConfigRomLength = 0x%x\n", 
                pLocalHostInfo5->ConfigRomLength));
        }
        else if (GET_HOST_DMA_CAPABILITIES == GetLocalHostInfo->nLevel) 
        {
            //
            // need to copy the results back into the original address space passed in
            //
            TRACE(TL_TRACE, ("HostDmaCapabilities = 0x%x\n",
                             LocalHostInfo7.HostDmaCapabilities));
            TRACE(TL_TRACE, ("MaxDmaBufferSize Low = 0x%x\n",
                             LocalHostInfo7.MaxDmaBufferSize.LowPart));
            TRACE(TL_TRACE, ("MaxDmaBufferSize High = 0x%x\n",
                             LocalHostInfo7.MaxDmaBufferSize.HighPart));

            RtlCopyMemory(GetLocalHostInfo->Information, &LocalHostInfo7, 
                                    sizeof (GET_LOCAL_HOST_INFO7));
        }
        else 
        {
            TRACE(
                TL_WARNING, 
                ("Returned success on invalid nLevel = 0x%x\n", 
                GetLocalHostInfo->nLevel));
        }
    }
    
    ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV);
    
    EXIT("kmdf1394_GetLocalHostInformation", ntStatus);
    return ntStatus;
} // kmdf1394_GetLocalHostInformation
Beispiel #29
0
NTSTATUS
OnPrepareHardware(
_In_  WDFDEVICE     FxDevice,
_In_  WDFCMRESLIST  FxResourcesRaw,
_In_  WDFCMRESLIST  FxResourcesTranslated
)
/*++

Routine Description:

This routine caches the SPB resource connection ID.

Arguments:

FxDevice - a handle to the framework device object
FxResourcesRaw - list of translated hardware resources that
the PnP manager has assigned to the device
FxResourcesTranslated - list of raw hardware resources that
the PnP manager has assigned to the device

Return Value:

Status

--*/
{
	FuncEntry(TRACE_FLAG_WDFLOADING);

	PDEVICE_CONTEXT pDevice = GetDeviceContext(FxDevice);
	BOOLEAN fSpbResourceFound = FALSE;
	NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;

	UNREFERENCED_PARAMETER(FxResourcesRaw);

	//
	// Parse the peripheral's resources.
	//

	ULONG resourceCount = WdfCmResourceListGetCount(FxResourcesTranslated);

	for (ULONG i = 0; i < resourceCount; i++)
	{
		PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
		UCHAR Class;
		UCHAR Type;

		pDescriptor = WdfCmResourceListGetDescriptor(
			FxResourcesTranslated, i);

		switch (pDescriptor->Type)
		{
		case CmResourceTypeConnection:
			//
			// Look for I2C or SPI resource and save connection ID.
			//
			Class = pDescriptor->u.Connection.Class;
			Type = pDescriptor->u.Connection.Type;
			if (Class == CM_RESOURCE_CONNECTION_CLASS_SERIAL &&
				Type == CM_RESOURCE_CONNECTION_TYPE_SERIAL_I2C)
			{
				if (fSpbResourceFound == FALSE)
				{
					status = STATUS_SUCCESS;
					pDevice->I2CContext.I2cResHubId.LowPart = pDescriptor->u.Connection.IdLowPart;
					pDevice->I2CContext.I2cResHubId.HighPart = pDescriptor->u.Connection.IdHighPart;
					fSpbResourceFound = TRUE;
					Trace(
						TRACE_LEVEL_INFORMATION,
						TRACE_FLAG_WDFLOADING,
						"SPB resource found with ID=0x%llx",
						pDevice->I2CContext.I2cResHubId.QuadPart);
				}
				else
				{
					Trace(
						TRACE_LEVEL_WARNING,
						TRACE_FLAG_WDFLOADING,
						"Duplicate SPB resource found with ID=0x%llx",
						pDevice->I2CContext.I2cResHubId.QuadPart);
				}
			}
			break;
		default:
			//
			// Ignoring all other resource types.
			//
			break;
		}
	}

	//
	// An SPB resource is required.
	//

	if (fSpbResourceFound == FALSE)
	{
		status = STATUS_NOT_FOUND;
		Trace(
			TRACE_LEVEL_ERROR,
			TRACE_FLAG_WDFLOADING,
			"SPB resource not found - %!STATUS!",
			status);
	}

	status = SpbTargetInitialize(FxDevice, &pDevice->I2CContext);
	if (!NT_SUCCESS(status))
	{
		Trace(
			TRACE_LEVEL_ERROR,
			TRACE_FLAG_WDFLOADING,
			"Error in Spb initialization - %!STATUS!",
			status);

		return status;
	}

	FuncExit(TRACE_FLAG_WDFLOADING);

	return status;
}