Exemplo n.º 1
0
WDFCOMMONBUFFER PciDtfCommonBufferFind(IN PDEVICE_DATA DeviceData, IN int ID,
				       IN BOOLEAN Remove)
{
	WDFCOMMONBUFFER CommonBuffer = NULL;
	ULONG Index, Count;

	Count = WdfCollectionGetCount(DeviceData->CommonBuffers);
	for (Index = 0; Index < Count; Index++) {
		CommonBuffer = (WDFCOMMONBUFFER)
		    WdfCollectionGetItem(DeviceData->CommonBuffers, Index);
		if (GetCommonBufferData(CommonBuffer)->ID == ID) {
			if (Remove)
				WdfCollectionRemoveItem
				    (DeviceData->CommonBuffers, Index);
			break;
		}
	}
	return Index < Count ? CommonBuffer : NULL;
}
Exemplo n.º 2
0
NTSTATUS Registry_ReadAllDeviceKeys(__in PDEVICE_CONTEXT deviceContext)
{
	WDFKEY					hKey = NULL;
	NTSTATUS				status = STATUS_INVALID_DEVICE_STATE;
	UNICODE_STRING			valueName;
	WDF_OBJECT_ATTRIBUTES	collectionAttributes;
	WDF_OBJECT_ATTRIBUTES	stringAttributes;
	GUID					guidTest = {0};

	PAGED_CODE();

	if (!deviceContext->WdfDevice)
	{
		USBERR("deviceContext->WdfDevice is NULL.\n");
		return status;
	}

	// The driver sets the PLUGPLAY_REGKEY_DEVICE flag to open the Device
	// Parameters subkey under the device's hardware key, or it sets the
	// PLUGPLAY_REGKEY_DRIVER flag to open the driver's software key. If the
	// PLUGPLAY_REGKEY_CURRENT_HWPROFILE flag is also set,
	// WdfDeviceOpenRegistryKey opens the copy of the hardware or software key
	// that is in the current hardware profile.
	status = WdfDeviceOpenRegistryKey(deviceContext->WdfDevice,
	                                  PLUGPLAY_REGKEY_DEVICE,
	                                  KEY_READ,
	                                  WDF_NO_OBJECT_ATTRIBUTES,
	                                  &hKey);

	if (!NT_SUCCESS (status))
	{
		USBERR("WdfDeviceOpenRegistryKey failed.\n");
		hKey = NULL;
		return status;
	}

	//////////////////////////////////////////////////////////////////////////
	// Read the device interface guids from the registry.
	// These are set in the inf files [Device_AddReg] group.
	//
	WDF_OBJECT_ATTRIBUTES_INIT(&collectionAttributes);
	collectionAttributes.ParentObject = deviceContext->WdfDevice;

	status = WdfCollectionCreate(&collectionAttributes,
	                             &deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs);
	if (!NT_SUCCESS(status))
	{
		USBERR("collection object could not be allocated. status=%Xh", status);
		goto Done;
	}

	WDF_OBJECT_ATTRIBUTES_INIT(&stringAttributes);
	stringAttributes.ParentObject = deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs;
	RtlInitUnicodeString(&valueName, L"DeviceInterfaceGUIDs");

	status = WdfRegistryQueryMultiString(hKey, &valueName, &stringAttributes, deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs);
	if (NT_SUCCESS(status))
	{
		ULONG guidCount = WdfCollectionGetCount(deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs);
		ULONG guidIndex;
		WDFSTRING wdfGuidString;
		BOOLEAN removeGuidFromCollection;

		USBMSG("Found %u DeviceInterfaceGUIDs strings.", guidCount);

		for (guidIndex = 0; guidIndex < guidCount; guidIndex++)
		{
			removeGuidFromCollection = TRUE;

			wdfGuidString = (WDFSTRING)WdfCollectionGetItem(deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs, guidIndex);
			status = GUIDFromWdfString(wdfGuidString, &guidTest);
			if (!NT_SUCCESS(status))
			{
				USBERR("removing invalid DeviceInterfaceGUID string at index %u\n", guidIndex);
			}
			else
			{
				if (IsEqualGUID(&guidTest, &Libusb0DeviceGuid))
				{
					USBWRN("libusb0 device DeviceInterfaceGUID found. skippng..\n");
				}
				else if (IsEqualGUID(&guidTest, &Libusb0FilterGuid))
				{
					USBWRN("libusb0 filter DeviceInterfaceGUID found. skippng..\n");
				}
				else if (IsEqualGUID(&guidTest, &LibusbKDeviceGuid))
				{
					USBWRN("libusbK default device DeviceInterfaceGUID found. skippng..\n");
				}
				else
				{
					removeGuidFromCollection = FALSE;
				}
			}

			if (removeGuidFromCollection)
			{
				WdfCollectionRemoveItem(deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs, guidIndex);
				guidIndex--;
				guidCount--;
			}
		}
	}
	else
	{
		USBWRN("DeviceInterfaceGUIDs registry key does not exist.\n"
		       "    Ensure the DeviceInterfaceGUIDs key has been properly set in the .inf and re-install the device.\n\n");
	}

	if (WdfCollectionGetCount(deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs) == 0)
	{
		status = AddDefaultDeviceInterfaceGUID(deviceContext);
		if (!NT_SUCCESS(status))
		{
			goto Done;
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// Read the device power policy settings (if any).
	// These are set in the inf files [Device_AddReg] group.
	//
	GetDeviceRegSettingKey(DeviceIdleEnabled, FALSE);
	GetDeviceRegSettingKey(DeviceIdleIgnoreWakeEnable, FALSE);
	GetDeviceRegSettingKey(UserSetDeviceIdleEnabled, FALSE);
	GetDeviceRegSettingKey(DefaultIdleState, FALSE);
	GetDeviceRegSettingKey(DefaultIdleTimeout, 5000);
	GetDeviceRegSettingKey(SystemWakeEnabled, FALSE);

	status = STATUS_SUCCESS;

Done:
	if (hKey)
	{
		WdfRegistryClose(hKey);
		hKey = NULL;
	}
	return status;
}
Exemplo n.º 3
0
/**
 * @brief DPC callback.
 * Calls the Xen interface api to process the ringbuffer until the ringbuffer is empty,
 * then completes all requests provided by the Xen api.
 *
 * @todo consider completion within the XenDpc() loop. However this would release the device
 * lock.
 *
 * @param[in] Dpc The WDFDPC handle.
 *  
 */
VOID
FdoEvtDeviceDpcFunc(
    IN VOID *Context)
{
    // --XT-- FDO context passed directly now.
    PUSB_FDO_CONTEXT fdoContext = (PUSB_FDO_CONTEXT)Context;
    //
    // this stuff needs to be done at DPC level in order to complete irps.
    //
    ULONG passes = 0;
    AcquireFdoLock(fdoContext);

    if (fdoContext->InDpc)
    {
        fdoContext->DpcOverLapCount++;
        ReleaseFdoLock(fdoContext);
        return;
    }
    fdoContext->InDpc = TRUE;

    BOOLEAN moreWork;
    do
    {
        moreWork = XenDpc(fdoContext, fdoContext->RequestCollection);
        passes++;
        if (fdoContext->DpcOverLapCount)
        {
            fdoContext->totalDpcOverLapCount += fdoContext->DpcOverLapCount;
            fdoContext->DpcOverLapCount = 0;
            moreWork = TRUE;
        }
        if (moreWork & (passes >= KeQueryActiveProcessorCount(NULL)))
        {
            //
            // reschedule the dpc to prevent starvation.
            //
            // --XT-- WdfDpcEnqueue(fdoContext->WdfDpc);
            //
            // --XT-- Schedule through the Xen interface now.
            //
            XenScheduleDPC(fdoContext->Xen);
            TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DPC,
                __FUNCTION__": enqueue dpc at %d passes\n",
                passes);
            fdoContext->totalDpcReQueueCount++;
            break;
        }

    } while (moreWork);
 
    fdoContext->InDpc = FALSE; // allow another dpc instance to run and add to the collection.
    if (passes > fdoContext->maxDpcPasses)
    {
        fdoContext->maxDpcPasses = passes;
    }
    //
    // complete all queued Irps. Note that this section is re-entrant.
    // Note also that all of these requests have been "uncanceled" and ahve
    // been marked as completed in their request contexts and that the
    // additional reference on the request object has been removed.
    // The collection can be safely completed with no race conditions.
    //
    ULONG responseCount = 0;
    WDFREQUEST Request;
    while ((Request = (WDFREQUEST) WdfCollectionGetFirstItem(fdoContext->RequestCollection)) != NULL)
    {
        WdfCollectionRemoveItem(fdoContext->RequestCollection, 0);

        TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DPC,
            __FUNCTION__": complete Request %p Status %x\n",
            Request,
            WdfRequestWdmGetIrp(Request)->IoStatus.Status);
        
        ReleaseFdoLock(fdoContext);

        WdfRequestCompleteWithPriorityBoost(Request,
            WdfRequestWdmGetIrp(Request)->IoStatus.Status,
            IO_SOUND_INCREMENT);
        
        AcquireFdoLock(fdoContext);

        responseCount++;
    }

    if (responseCount > fdoContext->maxRequestsProcessed)
    {
        fdoContext->maxRequestsProcessed = responseCount;
    }
    //
    // fire up any queued requests
    //    
    DrainRequestQueue(fdoContext, FALSE);

    ReleaseFdoLock(fdoContext);

    // --XT-- this trace was way too noisy, made it verbose.
    TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DPC,
        __FUNCTION__": exit responses processed %d passes %d\n",
        responseCount,
        passes);
}