Beispiel #1
0
NTSTATUS registry_get_or_create_ulong(WDFKEY key, PCUNICODE_STRING value_name,
                                      ULONG *value, ULONG initial_value)
{
    NTSTATUS status;

    status = WdfRegistryQueryULong(key, value_name, value);
    if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            "WdfRegistryQueryULong failed %!STATUS!", status);
        return status;
    }

    /* This is the first time loading the driver so initialize the starting port
       number to 0 */
    if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
        status = WdfRegistryAssignULong(key, value_name, initial_value);
        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
                "WdfRegistryAssignULong failed %!STATUS!", status);
            return status;
        }

        status = WdfRegistryQueryULong(key, value_name, value);
        if (!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
                "WdfRegistryQueryULong failed %!STATUS!", status);
            return status;
        }
    }

    return status;
}
Beispiel #2
0
VOID MamakuRegistryInit(IN WDFDRIVER Driver)
{
    NTSTATUS status;
    WDFKEY key;
    DECLARE_CONST_UNICODE_STRING(UseMultitouchName, L"UseMultitouchDebug");
    DECLARE_CONST_UNICODE_STRING(DragThresholdName, L"DragThreshold");

    status = WdfDriverOpenParametersRegistryKey(Driver, STANDARD_RIGHTS_ALL, WDF_NO_OBJECT_ATTRIBUTES, &key);

    if (!NT_SUCCESS(status)) 
    {
        MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT,
            "WdfDriverOpenParametersRegistryKey failed with status 0x%x\n", status);

        return;
    }

    status = WdfRegistryQueryULong(key, &UseMultitouchName, &UseMultitouch);

    if (!NT_SUCCESS(status)) 
    {
        MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT,
            "WdfRegistryQueryULong(UseMultitouch) failed with status 0x%x\n", status);
    }

    MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT,
        "UseMultitouchDebug = %d\n", UseMultitouch);

    status = WdfRegistryQueryULong(key, &DragThresholdName, &DragThreshold);

    if (!NT_SUCCESS(status)) 
    {
        MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT,
            "WdfRegistryQueryULong(DragThreshold) failed with status 0x%x\n", status);
    }

    MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT,
        "DragThreshold = %d\n", DragThreshold);

    WdfRegistryClose(key);
}
Beispiel #3
0
NTSTATUS
QueryDesiredControlResponse(
    __in ULONG_PTR controlCode,
    __in PSERIAL_DEVICE_EXTENSION DevExt
    )
/*++

Routine Description:

    This routine routine reads data from the registry to determine how the
    IRP dispatch routine should respond. It can either simulate success or failure
    based on the value it finds in the registry.


Arguments:

    controlCode - Control code

    DevExt        - Device extension

Return Value:



--*/
{
    NTSTATUS    status = STATUS_SUCCESS;
    ULONG        dwData = 0;
    UNICODE_STRING valueName = {0};

    KdPrint(("Control code:%d\n", controlCode));

    RtlInitUnicodeString(&valueName, CONTROL_RESPONSE);

    status = WdfRegistryQueryULong (DevExt->SimDevKey,
                              &valueName,
                              &dwData);
    if (NT_SUCCESS(status) && dwData == controlCode)
    {
        KdPrint(("Failed request num:%d\n", controlCode));
        status = STATUS_INVALID_PARAMETER;
    }
    else
    {
        status = STATUS_SUCCESS;
        KdPrint(("failed to query key\n"));
    }

    KdPrint(("RegData:%d\n", dwData));

    return status;
}
Beispiel #4
0
NTSTATUS registry_get_ulong(WDFKEY key, PCUNICODE_STRING value_name,
                            ULONG *value)
{
    NTSTATUS status;

    status = WdfRegistryQueryULong(key, value_name, value);
    if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            "WdfRegistryQueryULong failed %!STATUS!", status);
        return status;
    }

    return status;
}
Beispiel #5
0
VOID
DeviceQueryDeviceParameters(
    _In_ WDFDRIVER  _Driver
)
/*++
Routine Description:

    Query driver's registry location for device specific parameter, such as baudrate.

        HLM\system\CCS\Services\serialhcibus\Parameters\
        
            KeyName/Type/value

Arguments:

    _Driver - WDF Driver object

Return Value: 

    None
    
--*/   
{
    WDFKEY Key;
    NTSTATUS Status;
    UNICODE_STRING ValueName;
    ULONG Value = 0;

    PAGED_CODE();    

    Status = WdfDriverOpenParametersRegistryKey(_Driver,
                                                GENERIC_READ,
                                                WDF_NO_OBJECT_ATTRIBUTES,
                                                &Key
                                                );
    if (NT_SUCCESS(Status)) {        

        RtlInitUnicodeString(&ValueName, STR_BAUDRATE);
        Status = WdfRegistryQueryULong(Key, &ValueName, &Value);
        
        if (NT_SUCCESS(Status)) {
            // Vendor: can cache and use this values.
        }
       
        WdfRegistryClose(Key);       
    }
    
}
Beispiel #6
0
/*++
Routine Description:

Can be used to read any REG_DWORD registry value stored
under Device Parameter.

Arguments:

Driver - pointer to the device object
Name - Name of the registry value
Value - Value...
--*/
NTSTATUS ReadFdoRegistryKeyValue(__in  WDFDRIVER Driver, __in LPWSTR Name, __out PULONG Value)
{
    WDFKEY      hKey = NULL;
    NTSTATUS    status;
    UNICODE_STRING  valueName;

    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE();

    *Value = 0;

    status = WdfDriverOpenParametersRegistryKey(WdfGetDriver(), KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &hKey);
    if (NT_SUCCESS(status))
	{
        RtlInitUnicodeString(&valueName,Name);

        status = WdfRegistryQueryULong (hKey, &valueName, Value);

        WdfRegistryClose(hKey);
    }

    return status;
}
Beispiel #7
0
NTSTATUS
Bus_DoStaticEnumeration(
    IN WDFDEVICE Device
    )
/*++
Routine Description:

    The routine enables you to statically enumerate child devices
    during start instead of running the enum.exe/notify.exe to
    enumerate toaster devices.

    In order to statically enumerate, user must specify the number
    of toasters in the Toaster Bus driver's device registry. The
    default value is zero.

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\SYSTEM\0002\
                    Device Parameters
                        NumberOfToasters:REG_DWORD:2

    You can also configure this value in the Toaster Bus Inf file.

--*/

{
    WDFKEY      hKey = NULL;
    NTSTATUS    status;
    ULONG       value, i;
    DECLARE_CONST_UNICODE_STRING(valueName, L"NumberOfToasters");

    //
    // If the registry value doesn't exist, we will use the
    // hardcoded default number.
    //
    value = DEF_STATICALLY_ENUMERATED_TOASTERS;

    //
    // Open the device registry and read the "NumberOfToasters" value.
    //
    status = WdfDeviceOpenRegistryKey(Device,
                                      PLUGPLAY_REGKEY_DEVICE,
                                      STANDARD_RIGHTS_ALL,
                                      NULL, // PWDF_OBJECT_ATTRIBUTES
                                      &hKey);

    if (NT_SUCCESS (status)) {

        status = WdfRegistryQueryULong(hKey,
                                  &valueName,
                                  &value);

        WdfRegistryClose(hKey);
        hKey = NULL; // Set hKey to NULL to catch any accidental subsequent use.

        if (NT_SUCCESS (status)) {
            //
            // Make sure it doesn't exceed the max. This is required to prevent
            // denial of service by enumerating large number of child devices.
            //
            value = min(value, MAX_STATICALLY_ENUMERATED_TOASTERS);
        }else {
            return STATUS_SUCCESS; // This is an optional property.
        }
    }

    KdPrint(("Enumerating %d toaster devices\n", value));

    for(i=1; i<= value; i++) {
        //
        // Value of i is used as serial number.
        //
        status = Bus_PlugInDevice(Device,
                         BUS_HARDWARE_IDS,
                         BUS_HARDWARE_IDS_LENGTH / sizeof(WCHAR),
                         i );
    }

    return status;
}
Beispiel #8
0
NTSTATUS
OnDeviceAdd(
    _In_    WDFDRIVER       FxDriver,
    _Inout_ PWDFDEVICE_INIT FxDeviceInit
    )
/*++
 
  Routine Description:

    This routine creates the device object for an SPB 
    controller and the device's child objects.

  Arguments:

    FxDriver - the WDF driver object handle
    FxDeviceInit - information about the PDO that we are loading on

  Return Value:

    Status

--*/
{
    //FuncEntry(TRACE_FLAG_WDFLOADING);

    PDEVICE_CONTEXT pDevice;
    NTSTATUS status;
    
    UNREFERENCED_PARAMETER(FxDriver);

    //
    // Setup PNP/Power callbacks.
    //

    {
        WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks;
        WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks);

        pnpCallbacks.EvtDevicePrepareHardware = OnPrepareHardware;
        pnpCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware;
        pnpCallbacks.EvtDeviceD0Entry = OnD0Entry;
        pnpCallbacks.EvtDeviceD0Exit = OnD0Exit;

        WdfDeviceInitSetPnpPowerEventCallbacks(FxDeviceInit, &pnpCallbacks);
    }

    //
    // Prepare for file object handling.
    //

    {
        WDF_FILEOBJECT_CONFIG fileObjectConfig;

        WDF_FILEOBJECT_CONFIG_INIT(
            &fileObjectConfig, 
            nullptr, 
            nullptr,
            OnFileCleanup);

        WDF_OBJECT_ATTRIBUTES fileObjectAttributes;
        WDF_OBJECT_ATTRIBUTES_INIT(&fileObjectAttributes);

        WdfDeviceInitSetFileObjectConfig(
            FxDeviceInit, 
            &fileObjectConfig,
            &fileObjectAttributes);
    }

    //
    // Set request attributes.
    //

    {
        WDF_OBJECT_ATTRIBUTES attributes;
        WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
            &attributes,
            REQUEST_CONTEXT);

        WdfDeviceInitSetRequestAttributes(FxDeviceInit, &attributes);
    }

    //
    // Create the device.
    //

    {
        WDFDEVICE fxDevice;
        WDF_OBJECT_ATTRIBUTES deviceAttributes;
        WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);

        status = WdfDeviceCreate(
            &FxDeviceInit, 
            &deviceAttributes,
            &fxDevice);

        if (!NT_SUCCESS(status))
        {
            Trace(
                TRACE_LEVEL_ERROR, 
                TRACE_FLAG_WDFLOADING,
                "Error creating WDFDEVICE - %!STATUS!", 
                status);

            goto exit;
        }

        pDevice = GetDeviceContext(fxDevice);
        NT_ASSERT(pDevice != nullptr);

        pDevice->FxDevice = fxDevice;
    }

    //
    // Ensure device is disable-able
    //
    
    {
        WDF_DEVICE_STATE deviceState;
        WDF_DEVICE_STATE_INIT(&deviceState);
        
        deviceState.NotDisableable = WdfFalse;
        WdfDeviceSetDeviceState(pDevice->FxDevice, &deviceState);
    }

    //
    // Create queues to handle IO
    //

    {
        WDF_IO_QUEUE_CONFIG queueConfig;
        WDFQUEUE queue;

        //
        // Top-level queue
        //

        WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
            &queueConfig, 
            WdfIoQueueDispatchParallel);

        queueConfig.EvtIoDefault = OnTopLevelIoDefault;
        queueConfig.PowerManaged = WdfFalse;

        status = WdfIoQueueCreate(
            pDevice->FxDevice,
            &queueConfig,
            WDF_NO_OBJECT_ATTRIBUTES,
            &queue
            );

        if (!NT_SUCCESS(status))
        {
            Trace(
                TRACE_LEVEL_ERROR, 
                TRACE_FLAG_WDFLOADING,
                "Error creating top-level IO queue - %!STATUS!", 
                status);

            goto exit;
        }

        //
        // Sequential SPB queue
        //

        WDF_IO_QUEUE_CONFIG_INIT(
            &queueConfig, 
            WdfIoQueueDispatchSequential);

        queueConfig.EvtIoRead = OnIoRead;
        queueConfig.EvtIoWrite = OnIoWrite;
        queueConfig.EvtIoDeviceControl = OnIoDeviceControl;
        queueConfig.PowerManaged = WdfFalse;

        status = WdfIoQueueCreate(
            pDevice->FxDevice,
            &queueConfig,
            WDF_NO_OBJECT_ATTRIBUTES,
            &pDevice->SpbQueue
            );

        if (!NT_SUCCESS(status))
        {
            Trace(
                TRACE_LEVEL_ERROR, 
                TRACE_FLAG_WDFLOADING,
                "Error creating SPB IO queue - %!STATUS!", 
                status);

            goto exit;
        }
    }

    //
    // Create a symbolic link.
    //

    {
        DECLARE_UNICODE_STRING_SIZE(symbolicLinkName, 128);

        status = RtlUnicodeStringPrintf(
            &symbolicLinkName, L"%ws",
            sensy_SYMBOLIC_NAME);

        if (!NT_SUCCESS(status))
        {
            Trace(
                TRACE_LEVEL_ERROR, 
                TRACE_FLAG_WDFLOADING,
                "Error creating symbolic link string for device "
                "- %!STATUS!", 
                status);

            goto exit;
        }

        status = WdfDeviceCreateSymbolicLink(
            pDevice->FxDevice, 
            &symbolicLinkName);

        if (!NT_SUCCESS(status))
        {
            Trace(
                TRACE_LEVEL_ERROR, 
                TRACE_FLAG_WDFLOADING,
                "Error creating symbolic link for device "
                "- %!STATUS!", 
                status);

            goto exit;
        }
    }

    //
    // Retrieve registry settings.
    //

    {
        WDFKEY key = NULL;
        WDFKEY subkey = NULL;
        ULONG connectInterrupt = 0;
        NTSTATUS settingStatus;
    
        DECLARE_CONST_UNICODE_STRING(subkeyName, L"Settings");
        DECLARE_CONST_UNICODE_STRING(connectInterruptName, L"ConnectInterrupt");

        settingStatus = WdfDeviceOpenRegistryKey(
            pDevice->FxDevice,
            PLUGPLAY_REGKEY_DEVICE,
            KEY_READ,
            WDF_NO_OBJECT_ATTRIBUTES,
            &key);

        if (!NT_SUCCESS(settingStatus))
        {
            Trace(
                TRACE_LEVEL_WARNING, 
                TRACE_FLAG_WDFLOADING,
                "Error opening device registry key - %!STATUS!",
                settingStatus);
        }

        if (NT_SUCCESS(settingStatus))
        {
            settingStatus = WdfRegistryOpenKey(
                key,
                &subkeyName,
                KEY_READ,
                WDF_NO_OBJECT_ATTRIBUTES,
                &subkey);

            if (!NT_SUCCESS(settingStatus))
            {
                Trace(
                    TRACE_LEVEL_WARNING, 
                    TRACE_FLAG_WDFLOADING,
                    "Error opening registry subkey for 'Settings' - %!STATUS!", 
                    settingStatus);
            }
        }

        if (NT_SUCCESS(settingStatus))
        {

            settingStatus = WdfRegistryQueryULong(
                subkey,
                &connectInterruptName,
                &connectInterrupt);

            if (!NT_SUCCESS(settingStatus))
            {
                Trace(
                    TRACE_LEVEL_WARNING, 
                    TRACE_FLAG_WDFLOADING,
                    "Error querying registry value for 'ConnectInterrupt' - %!STATUS!", 
                    settingStatus);
            }
        }

        if (key != NULL)
        {
            WdfRegistryClose(key);
        }

        if (subkey != NULL)
        {
            WdfRegistryClose(subkey);
        }

        pDevice->ConnectInterrupt = (connectInterrupt == 1);
    }

exit:

    //FuncExit(TRACE_FLAG_WDFLOADING);

    return status;
}
BOOLEAN
SerialGetFdoRegistryKeyValue(
    IN PWDFDEVICE_INIT  DeviceInit,
    _In_ PCWSTR         Name,
    OUT PULONG          Value
    )
/*++

Routine Description:

    Can be used to read any REG_DWORD registry value stored
    under Device Parameter.

Arguments:

    FdoData - pointer to the device extension
    Name - Name of the registry value
    Value -


Return Value:

   TRUE if successful
   FALSE if not present/error in reading registry

--*/
{
    WDFKEY      hKey = NULL;
    NTSTATUS    status;
    BOOLEAN     retValue = FALSE;
    UNICODE_STRING valueName;

    PAGED_CODE();

    SerialDbgPrintEx(TRACE_LEVEL_VERBOSE, DBG_PNP,
                     "-->SerialGetFdoRegistryKeyValue\n");

    *Value = 0;

    status = WdfFdoInitOpenRegistryKey(DeviceInit,
                                  PLUGPLAY_REGKEY_DEVICE,
                                  STANDARD_RIGHTS_ALL,
                                  WDF_NO_OBJECT_ATTRIBUTES,
                                  &hKey);

    if (NT_SUCCESS (status)) {

        RtlInitUnicodeString(&valueName,Name);

        status = WdfRegistryQueryULong (hKey, &valueName, Value);

        if (NT_SUCCESS (status)) {
            retValue = TRUE;
        }

        WdfRegistryClose(hKey);
    }

    SerialDbgPrintEx(TRACE_LEVEL_VERBOSE, DBG_PNP,
                     "<--SerialGetFdoRegistryKeyValue %ws %d \n",
                            Name, *Value);

    return retValue;
}
NTSTATUS
SerialGetConfigDefaults(
    IN PSERIAL_FIRMWARE_DATA    DriverDefaultsPtr,
    IN WDFDRIVER          Driver
    )

/*++

Routine Description:

    This routine reads the default configuration data from the
    registry for the serial driver.

    It also builds fields in the registry for several configuration
    options if they don't exist.

Arguments:

    DriverDefaultsPtr - Pointer to a structure that will contain
                        the default configuration values.

    RegistryPath - points to the entry for this driver in the
                   current control set of the registry.

Return Value:

    STATUS_SUCCESS if we got the defaults, otherwise we failed.
    The only way to fail this call is if the  STATUS_INSUFFICIENT_RESOURCES.

--*/

{

    NTSTATUS status = STATUS_SUCCESS;    // return value
    WDFKEY hKey;
    DECLARE_UNICODE_STRING_SIZE(valueName,PARAMATER_NAME_LEN);

    status = WdfDriverOpenParametersRegistryKey(Driver,
                                  STANDARD_RIGHTS_ALL,
                                  WDF_NO_OBJECT_ATTRIBUTES,
                                  &hKey);
    if (!NT_SUCCESS (status)) {
        return status;
    }

    status = RtlUnicodeStringPrintf(&valueName,L"BreakOnEntry");
    if (!NT_SUCCESS (status)) {
             goto End;

    }

    status = WdfRegistryQueryULong (hKey,
                              &valueName,
                              &DriverDefaultsPtr->ShouldBreakOnEntry);

    if (!NT_SUCCESS (status)) {
        DriverDefaultsPtr->ShouldBreakOnEntry = 0;
    }

    status = RtlUnicodeStringPrintf(&valueName,L"DebugLevel");
    if (!NT_SUCCESS (status)) {
            goto End;
    }

    status = WdfRegistryQueryULong (hKey,
                              &valueName,
                              &DriverDefaultsPtr->DebugLevel);

    if (!NT_SUCCESS (status)) {
        DriverDefaultsPtr->DebugLevel = 0;
    }


    status = RtlUnicodeStringPrintf(&valueName,L"ForceFifoEnable");
    if (!NT_SUCCESS (status)) {
            goto End;
    }

    status = WdfRegistryQueryULong (hKey,
              &valueName,
              &DriverDefaultsPtr->ForceFifoEnableDefault);

    if (!NT_SUCCESS (status)) {

        //
        // If it isn't then write out values so that it could
        // be adjusted later.
        //
        DriverDefaultsPtr->ForceFifoEnableDefault = SERIAL_FORCE_FIFO_DEFAULT;

        status = WdfRegistryAssignULong(hKey,
                            &valueName,
                            DriverDefaultsPtr->ForceFifoEnableDefault
                            );
        if (!NT_SUCCESS (status)) {
            goto End;
        }

    }

    status = RtlUnicodeStringPrintf(&valueName,L"RxFIFO");
    if (!NT_SUCCESS (status)) {
            goto End;
    }

    status = WdfRegistryQueryULong (hKey,
              &valueName,
              &DriverDefaultsPtr->RxFIFODefault);

    if (!NT_SUCCESS (status)) {

        DriverDefaultsPtr->RxFIFODefault = SERIAL_RX_FIFO_DEFAULT;

        status = WdfRegistryAssignULong(hKey,
                            &valueName,
                            DriverDefaultsPtr->RxFIFODefault
                            );
        if (!NT_SUCCESS (status)) {
            goto End;
        }

    }

    status = RtlUnicodeStringPrintf(&valueName,L"TxFIFO");
    if (!NT_SUCCESS (status)) {
            goto End;
    }

    status = WdfRegistryQueryULong (hKey,
              &valueName,
              &DriverDefaultsPtr->TxFIFODefault);

    if (!NT_SUCCESS (status)) {

        DriverDefaultsPtr->TxFIFODefault = SERIAL_TX_FIFO_DEFAULT;

        status = WdfRegistryAssignULong(hKey,
                            &valueName,
                            DriverDefaultsPtr->TxFIFODefault
                            );
        if (!NT_SUCCESS (status)) {
            goto End;
        }

    }

    status = RtlUnicodeStringPrintf(&valueName,L"PermitShare");
    if (!NT_SUCCESS (status)) {
            goto End;
    }

    status = WdfRegistryQueryULong (hKey,
              &valueName,
              &DriverDefaultsPtr->PermitShareDefault);

    if (!NT_SUCCESS (status)) {

        DriverDefaultsPtr->PermitShareDefault = SERIAL_PERMIT_SHARE_DEFAULT;

        status = WdfRegistryAssignULong(hKey,
                            &valueName,
                            DriverDefaultsPtr->PermitShareDefault
                            );
        if (!NT_SUCCESS (status)) {
            goto End;
        }

    }

    status = RtlUnicodeStringPrintf(&valueName,L"LogFifo");
    if (!NT_SUCCESS (status)) {
            goto End;
    }

    status = WdfRegistryQueryULong (hKey,
              &valueName,
              &DriverDefaultsPtr->LogFifoDefault);

    if (!NT_SUCCESS (status)) {

        DriverDefaultsPtr->LogFifoDefault = SERIAL_LOG_FIFO_DEFAULT;

        status = WdfRegistryAssignULong(hKey,
                            &valueName,
                            DriverDefaultsPtr->LogFifoDefault
                            );
        if (!NT_SUCCESS (status)) {
            goto End;
        }

            DriverDefaultsPtr->LogFifoDefault = 1;
    }


    status = RtlUnicodeStringPrintf(&valueName,L"UartRemovalDetect");
    if (!NT_SUCCESS (status)) {
            goto End;
    }

    status = WdfRegistryQueryULong (hKey,
              &valueName,
              &DriverDefaultsPtr->UartRemovalDetect);

    if (!NT_SUCCESS (status)) {
        DriverDefaultsPtr->UartRemovalDetect = 0;
    }


End:
       WdfRegistryClose(hKey);
    return (status);
}
Beispiel #11
0
_Use_decl_annotations_
NTSTATUS OnDeviceAdd (WDFDRIVER /*WdfDriver*/, WDFDEVICE_INIT* DeviceInitPtr)
{
    PAGED_CODE();
    BCM_I2C_ASSERT_MAX_IRQL(PASSIVE_LEVEL);

    NTSTATUS status;

    //
    // Configure DeviceInit structure
    //
    status = SpbDeviceInitConfig(DeviceInitPtr);
    if (!NT_SUCCESS(status)) {
        BSC_LOG_ERROR(
            "SpbDeviceInitConfig() failed. (DeviceInitPtr = %p, status = %!STATUS!)",
            DeviceInitPtr,
            status);
        return status;
    }

    //
    // Setup PNP/Power callbacks.
    //
    {
        WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks;
        WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks);

        pnpCallbacks.EvtDevicePrepareHardware = OnPrepareHardware;
        pnpCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware;
        pnpCallbacks.EvtDeviceD0Entry = OnD0Entry;
        pnpCallbacks.EvtDeviceD0Exit = OnD0Exit;

        WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInitPtr, &pnpCallbacks);
    }

    //
    // Create the device.
    //
    WDFDEVICE wdfDevice;
    BCM_I2C_DEVICE_CONTEXT* devicePtr;
    {
        WDF_OBJECT_ATTRIBUTES deviceAttributes;
        WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
            &deviceAttributes,
            BCM_I2C_DEVICE_CONTEXT);

        status = WdfDeviceCreate(
            &DeviceInitPtr,
            &deviceAttributes,
            &wdfDevice);
        if (!NT_SUCCESS(status)) {
            BSC_LOG_ERROR(
                "Failed to create WDFDEVICE. (DeviceInitPtr = %p, status = %!STATUS!)",
                DeviceInitPtr,
                status);
            return status;
        }

        devicePtr = GetDeviceContext(wdfDevice);
        NT_ASSERT(devicePtr);
        devicePtr->WdfDevice = wdfDevice;
    }

    //
    // Query registry for ClockStretchTimeout
    //
    {
        WDFKEY wdfKey;
        status = WdfDeviceOpenRegistryKey(
                wdfDevice,
                PLUGPLAY_REGKEY_DEVICE,
                KEY_QUERY_VALUE,
                WDF_NO_OBJECT_ATTRIBUTES,
                &wdfKey);
        if (!NT_SUCCESS(status)) {
            BSC_LOG_ERROR(
                "Failed to open device parameters registry key. (status=%!STATUS!)",
                status);
            return status;
        }
        auto closeRegKey = Finally([&] {
            PAGED_CODE();
            WdfRegistryClose(wdfKey);
        });

        DECLARE_CONST_UNICODE_STRING(
            regValString,
            REGSTR_VAL_CLOCK_STRETCH_TIMEOUT);

        ULONG clockStretchTimeout;
        status = WdfRegistryQueryULong(
                wdfKey,
                &regValString,
                &clockStretchTimeout);
        if (NT_SUCCESS(status)) {
            if ((clockStretchTimeout & BCM_I2C_REG_CLKT_TOUT_MASK) !=
                 clockStretchTimeout) {

                BSC_LOG_ERROR(
                    "Clock stretch timeout value from registry is out of range. (clockStretchTimeout=0x%x, BCM_I2C_REG_CLKT_TOUT_MASK=0x%x)",
                    clockStretchTimeout,
                    BCM_I2C_REG_CLKT_TOUT_MASK);
                return STATUS_INVALID_PARAMETER;
            }

            BSC_LOG_INFORMATION(
                "Using ClockStretchTimeout value from registry. (clockStretchTimeout=0x%x)",
                clockStretchTimeout);

        } else {
            switch (status) {
            case STATUS_OBJECT_NAME_NOT_FOUND:
                clockStretchTimeout = BCM_I2C_REG_CLKT_TOUT_DEFAULT;
                status = STATUS_SUCCESS;
                break;
            default:
                BSC_LOG_ERROR(
                    "Failed to query clock stretch timeout from registry. (status=%!STATUS!, REGSTR_VAL_CLOCK_STRETCH_TIMEOUT=%S)",
                    status,
                    REGSTR_VAL_CLOCK_STRETCH_TIMEOUT);
                return status;
            }
        }

        devicePtr->ClockStretchTimeout = clockStretchTimeout;
    }

    //
    // Ensure device is disable-able
    //
    {
        WDF_DEVICE_STATE deviceState;
        WDF_DEVICE_STATE_INIT(&deviceState);
        deviceState.NotDisableable = WdfFalse;
        WdfDeviceSetDeviceState(wdfDevice, &deviceState);
    }

    //
    // Bind a SPB controller object to the device.
    //
    {
        SPB_CONTROLLER_CONFIG spbConfig;
        SPB_CONTROLLER_CONFIG_INIT(&spbConfig);

        //
        // Register for target connect callback.  The driver
        // does not need to respond to target disconnect.
        //

        spbConfig.EvtSpbTargetConnect = OnTargetConnect;

        //
        // Register for IO callbacks.
        //

        spbConfig.ControllerDispatchType = WdfIoQueueDispatchSequential;
        spbConfig.EvtSpbIoRead = OnRead;
        spbConfig.EvtSpbIoWrite = OnWrite;
        spbConfig.EvtSpbIoSequence = OnSequence;

        status = SpbDeviceInitialize(wdfDevice, &spbConfig);
        if (!NT_SUCCESS(status)) {
            BSC_LOG_ERROR(
                "SpbDeviceInitialize failed. (wdfDevice = %p, status = %!STATUS!)",
                wdfDevice,
                status);
            return status;
        }
    }

    //
    // Set target object attributes.
    //
    {
        WDF_OBJECT_ATTRIBUTES targetAttributes;
        WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
            &targetAttributes,
            BCM_I2C_TARGET_CONTEXT);

        SpbControllerSetTargetAttributes(wdfDevice, &targetAttributes);
    }

    //
    // Create an interrupt object
    //
    BCM_I2C_INTERRUPT_CONTEXT* interruptContextPtr;
    {
        WDF_OBJECT_ATTRIBUTES interruptObjectAttributes;
        WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
            &interruptObjectAttributes,
            BCM_I2C_INTERRUPT_CONTEXT);

        WDF_INTERRUPT_CONFIG interruptConfig;
        WDF_INTERRUPT_CONFIG_INIT(
            &interruptConfig,
            OnInterruptIsr,
            OnInterruptDpc);

        status = WdfInterruptCreate(
            wdfDevice,
            &interruptConfig,
            &interruptObjectAttributes,
            &devicePtr->WdfInterrupt);
        if (!NT_SUCCESS(status)) {
            BSC_LOG_ERROR(
                "Failed to create interrupt object. (wdfDevice = %p, status = %!STATUS!)",
                wdfDevice,
                status);
            return status;
        }

        interruptContextPtr = GetInterruptContext(devicePtr->WdfInterrupt);
        interruptContextPtr->WdfInterrupt = devicePtr->WdfInterrupt;
    }
    devicePtr->InterruptContextPtr = interruptContextPtr;

    NT_ASSERT(NT_SUCCESS(status));
    return STATUS_SUCCESS;
}
Beispiel #12
0
NTSTATUS
QueryDesiredReadWriteResponse(
    __in UCHAR IrpMajorFunc,
    __in PSERIAL_DEVICE_EXTENSION DevExt
    )
/*++

Routine Description:

    This routine routine reads data from the registry to determine how the
    IRP dispatch routine should respond. It can either simulate success or failure
    based on the value it finds in the registry.


Arguments:
QueryDesiredReadWriteResponse
    IrpMajorFunc - Major function code

    DevExt        - Device extension

Return Value:
    STATUS_INVALID_PARAMETER
    STATUS_SUCCESS


--*/
{
    NTSTATUS                    status = STATUS_SUCCESS;
    ULONG                       dwData = 0;
    UNICODE_STRING              valueName = {0};
    ULONG                       IrpCount = DevExt->WriteCount;
    LARGE_INTEGER               Timeout = {0};
    

    if(IRP_MJ_READ == IrpMajorFunc)
    {
        KdPrint(("Read request\n"));
        RtlInitUnicodeString(&valueName, READ_RESPONSE);
        IrpCount = DevExt->ReadCount;
    } else {
        KdPrint(("Write request\n"));
        RtlInitUnicodeString(&valueName, WRITE_RESPONSE);
    }

    status = WdfRegistryQueryULong (DevExt->SimDevKey,
                              &valueName,
                              &dwData);
    if(NT_SUCCESS(status) && 
        ((dwData == IrpCount) || (0 == dwData))
        )
    {
        //add time delay for possible timeout testing.
        Timeout.QuadPart = IO_TIMEOUT;
        KeDelayExecutionThread(KernelMode, FALSE, (LARGE_INTEGER *)&Timeout);
        //data in the registry asked us to fail the "IrpCount"th IRP
        KdPrint(("Failed request num:%d\n", IrpCount));
        status = STATUS_INVALID_PARAMETER;			
    }
    else
    {
        status = STATUS_SUCCESS;
        KdPrint(("failed to query key\n"));
    }

    KdPrint(("RegData:%d\n", dwData));

    return status;
}
NTSTATUS
StreamEditLoadConfig(
   const WDFKEY key
   )
{
   NTSTATUS status = STATUS_SUCCESS;
   DECLARE_CONST_UNICODE_STRING(stringToFindKey, L"StringToFind");
   DECLARE_CONST_UNICODE_STRING(stringToReplaceKey, L"StringToReplace");
   DECLARE_CONST_UNICODE_STRING(inspectionPortKey, L"InspectionPort");
   DECLARE_CONST_UNICODE_STRING(editInlineKey, L"EditInline");
   DECLARE_CONST_UNICODE_STRING(inspectOutboundKey, L"InspectOutbound");

   UNICODE_STRING stringValue;
   WCHAR buffer[128];
   USHORT requiredSize;
   ULONG valueSize;
   ULONG ulongValue;

   stringValue.Buffer = buffer;
   stringValue.Length = 0;
   stringValue.MaximumLength = sizeof(buffer) - sizeof(buffer[0]);

   if (NT_SUCCESS(
         WdfRegistryQueryUnicodeString(
            key,
            &stringToFindKey,
            &requiredSize,
            &stringValue
            )))
   {
      stringValue.Buffer[stringValue.Length/sizeof(stringValue.Buffer[0])] = 
         UNICODE_NULL;

      status = RtlUnicodeToMultiByteN(
                  configStringToFind,
                  sizeof(configStringToFind) - 1,
                  &valueSize,
                  stringValue.Buffer,
                  (ULONG)requiredSize
                  );

      if (!NT_SUCCESS(status))
      {
         goto Exit;
      }

      configStringToFind[valueSize] = '\0';
   }

   if (NT_SUCCESS(
         WdfRegistryQueryUnicodeString(
            key,
            &stringToReplaceKey,
            &requiredSize,
            &stringValue
            )))
   {
      status = RtlUnicodeToMultiByteN(
                  configStringToReplace,
                  sizeof(configStringToReplace) - 1,
                  &valueSize,
                  stringValue.Buffer,
                  (ULONG)requiredSize
                  );

      if (!NT_SUCCESS(status))
      {
         goto Exit;
      }

      configStringToReplace[valueSize] = '\0';
   }

   if (NT_SUCCESS(
         WdfRegistryQueryULong(
            key,
            &inspectionPortKey,
            &ulongValue
            )))
   {
      configInspectionPort = (USHORT) ulongValue;
   }

   if (NT_SUCCESS(
         WdfRegistryQueryULong(
            key,
            &editInlineKey,
            &ulongValue
            )))
   {
      configEditInline = (ulongValue != 0);
   }

   if (NT_SUCCESS(
         WdfRegistryQueryULong(
            key,
            &inspectOutboundKey,
            &ulongValue
            )))
   {
      configInspectionOutbound = (ulongValue != 0);
   }

Exit:
   return status;
}