VOID
FxPowerIdleMachine::CheckAssumptions(
    VOID
    )
/*++

Routine Description:
    This routine is never actually called by running code, it just has
    WDFCASSERTs who upon failure, would not allow this file to be compiled.

    DO NOT REMOVE THIS FUNCTION just because it is not called by any running
    code.

Arguments:
    None

Return Value:
    None

  --*/
{
    WDFCASSERT((sizeof(m_StateTable)/sizeof(m_StateTable[0]))
               ==
               (FxIdleMax - FxIdleStopped));
}
_Must_inspect_result_
NTSTATUS
FxDriver::Initialize(
    __in PCUNICODE_STRING ArgRegistryPath,
    __in PWDF_DRIVER_CONFIG Config,
    __in_opt PWDF_OBJECT_ATTRIBUTES DriverAttributes
    )
{
    PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
    NTSTATUS status;

    // WDFDRIVER can not be deleted by the device driver
    MarkNoDeleteDDI();

    MarkDisposeOverride(ObjectDoNotLock);

    //
    // Configure Constraints
    //
    ConfigureConstraints(DriverAttributes);

    if (m_DriverObject.GetObject() == NULL) {
        return STATUS_UNSUCCESSFUL;
    }

    // Allocate FxDisposeList
    status = FxDisposeList::_Create(FxDriverGlobals, m_DriverObject.GetObject(), &m_DisposeList);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Store FxDriver in Driver object extension
    //
    status = AllocateDriverObjectExtensionAndStoreFxDriver();
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Store away the callback functions.
    //
    if ((Config->DriverInitFlags & WdfDriverInitNoDispatchOverride) == 0) {
        //
        // Caller doesn't want to override the dispatch table.  That
        // means that they want to create everything and still be in
        // control (or at least the port driver will take over)
        //
        m_DriverDeviceAdd.Method  = Config->EvtDriverDeviceAdd;
        m_DriverUnload.Method     = Config->EvtDriverUnload;
    }

    if (ArgRegistryPath != NULL) {
        USHORT length;

        length = ArgRegistryPath->Length + sizeof(UNICODE_NULL);

        m_RegistryPath.Length = ArgRegistryPath->Length;
        m_RegistryPath.MaximumLength = length;
        m_RegistryPath.Buffer = (PWSTR) FxPoolAllocate(
            GetDriverGlobals(), PagedPool, length);

        if (m_RegistryPath.Buffer != NULL) {
            RtlCopyMemory(m_RegistryPath.Buffer,
                          ArgRegistryPath->Buffer,
                          ArgRegistryPath->Length);

            //
            // other parts of WDF assumes m_RegistryPath.Buffer is
            // a null terminated string.  make sure it is.
            //
            m_RegistryPath.Buffer[length/sizeof(WCHAR)- 1] = UNICODE_NULL;
        }
        else {
            //
            // We failed to allocate space for the registry path
            // so set the length to 0.
            //
            m_RegistryPath.Length = 0;
            m_RegistryPath.MaximumLength = 0;

            status = STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    if (NT_SUCCESS(status)) {
        if ((Config->DriverInitFlags & WdfDriverInitNoDispatchOverride) == 0) {
            UCHAR i;

            //
            // Set up dispatch routines.
            //
            if (Config->DriverInitFlags & WdfDriverInitNonPnpDriver) {
                //
                // NT4 style drivers must clear the AddDevice field in the
                // driver object so that they can be unloaded while still
                // having device objects around.
                //
                // If AddDevice is set, NT considers the driver a pnp driver
                // and will not allow net stop to unload the driver.
                //
                m_DriverObject.SetDriverExtensionAddDevice(NULL);

                //
                // Unload for an NT4 driver is still optional if the driver
                // does not want to be stopped (through net stop for
                // instance).
                //
                if (Config->EvtDriverUnload != NULL) {
                    m_DriverObject.SetDriverUnload(Unload);
                }
                else {
                    m_DriverObject.SetDriverUnload(NULL);
                }

            }
            else {
                //
                // PnP driver, set our routines up
                //
                m_DriverObject.SetDriverExtensionAddDevice(AddDevice);
                m_DriverObject.SetDriverUnload(Unload);
            }

            //
            // For any major control code that we use a remove lock, the
            // following locations must be updated:
            //
            // 1)  FxDevice::_RequiresRemLock() which decides if the remlock
            //          is required
            // 2)  FxDefaultIrpHandler::Dispatch might need to be changed if
            //          there is catchall generic post processing that must be done
            // 3)  Whereever the major code irp handler completes the irp or
            //          sends it down the stack.  A good design would have all
            //          spots in the irp handler where this is done to call a
            //          common function.
            //
            WDFCASSERT(IRP_MN_REMOVE_DEVICE != 0x0);
            
#if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
            for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
                if (FxDevice::_RequiresRemLock(i, 0x0) == FxDeviceRemLockNotRequired) {
                    m_DriverObject.SetMajorFunction(i, FxDevice::Dispatch);
                }
                else {
                    m_DriverObject.SetMajorFunction(i, FxDevice::DispatchWithLock);
                }
            }
#else // USER_MODE
            for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
                if (FxDevice::_RequiresRemLock(i, 0x0) == FxDeviceRemLockNotRequired) {
                    m_DriverObject.SetMajorFunction(i, FxDevice::DispatchUm);
                }
                else {
                    m_DriverObject.SetMajorFunction(i, FxDevice::DispatchWithLockUm);
                }
            }
#endif
        }

        //
        // Determine if the debugger is connected.
        //
#if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
        if (KD_DEBUGGER_ENABLED == TRUE && KD_DEBUGGER_NOT_PRESENT == FALSE) {
            m_DebuggerConnected = TRUE;
        }
#endif

        //
        // Log this notable event after tracing has been initialized.
        //






        if ((Config->DriverInitFlags & WdfDriverInitNonPnpDriver) &&
            Config->EvtDriverUnload == NULL) {

            DoTraceLevelMessage(
                FxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGDRIVER,
                "Driver Object %p, reg path %wZ cannot be "
                "unloaded, no DriverUnload routine specified",
                m_DriverObject.GetObject(), &m_RegistryPath);
        }

#if FX_IS_USER_MODE
        //
        // Open a R/W handle to the driver's service parameters key
        //
        status = OpenParametersKey();
        if (!NT_SUCCESS(status)) {
            DoTraceLevelMessage(
                FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDRIVER,
                "Cannot open Driver Parameters key %!STATUS!",
                status);
        }
#endif
    }

    return status;
}