/*++

Copyright (c) Microsoft Corporation

Module Name:

    FxDeviceInit.hpp

Abstract:


Author:


Environment:

    kernel mode only

Revision History:

--*/

#ifndef __FXDEVICEINIT_HPP__
#define __FXDEVICEINIT_HPP__

enum FxDeviceInitType {
    FxDeviceInitTypeFdo = 0,
    FxDeviceInitTypePdo,
    FxDeviceInitTypeControlDevice
};

struct FileObjectInit {
    WDF_FILEOBJECT_CLASS Class;

    WDF_OBJECT_ATTRIBUTES Attributes;

    WDF_FILEOBJECT_CONFIG Callbacks;

    WDF_TRI_STATE AutoForwardCleanupClose;

    BOOLEAN Set;
};

struct SecurityInit {
    FxString* Sddl;

    GUID DeviceClass;

    BOOLEAN DeviceClassSet;
};

struct PnpPowerInit {
    WDF_PNPPOWER_EVENT_CALLBACKS PnpPowerEventCallbacks;

    WDF_POWER_POLICY_EVENT_CALLBACKS PolicyEventCallbacks;

    FxPnpStateCallback* PnpStateCallbacks;

    FxPowerStateCallback* PowerStateCallbacks;

    FxPowerPolicyStateCallback* PowerPolicyStateCallbacks;

    WDF_TRI_STATE PowerPolicyOwner;
};

struct FdoInit {
    WDF_FDO_EVENT_CALLBACKS EventCallbacks;

    WDF_CHILD_LIST_CONFIG ListConfig;

    WDF_OBJECT_ATTRIBUTES ListConfigAttributes;

    BOOLEAN Filter;

    MdDeviceObject PhysicalDevice;
};




#include "fxdeviceinitshared.hpp"

struct ControlInit {
    ControlInit(
        VOID
        )
    {
        ShutdownNotification = NULL;
        Flags = 0;
    }

    PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION ShutdownNotification;

    UCHAR Flags;
};

//
// The typedef for a pointer to this structure is exposed in wdfdevice.h
//
struct WDFDEVICE_INIT : public FxStump {
public:
    WDFDEVICE_INIT(
        __in FxDriver* Driver
        );

    ~WDFDEVICE_INIT();

    VOID
    SetPdo(
        __in FxDevice* Parent
        );

    BOOLEAN
    IsFdoInit(
        VOID
        )
    {
        return InitType == FxDeviceInitTypeFdo;
    }

    BOOLEAN
    IsNotFdoInit(
        VOID
        )
    {
        return InitType != FxDeviceInitTypeFdo;
    }

    BOOLEAN
    IsPdoInit(
        VOID
        )
    {
        return InitType == FxDeviceInitTypePdo;
    }

    BOOLEAN
    IsNotPdoInit(
        VOID
        )
    {
        return InitType != FxDeviceInitTypePdo;
    }
    BOOLEAN
    IsNotControlDeviceInit(
        VOID
        )
    {
        return InitType != FxDeviceInitTypeControlDevice;
    }

    BOOLEAN
    IsControlDeviceInit(
        VOID
        )
    {
        return InitType == FxDeviceInitTypeControlDevice;
    }

    BOOLEAN
    HasName(
        VOID
        )
    {
        if (DeviceName != NULL ||
            (Characteristics & FILE_AUTOGENERATED_DEVICE_NAME)) {
            return TRUE;
        }
        else {
            return FALSE;
        }
    }

    BOOLEAN
    ShouldCreateSecure(
        VOID
        );

    BOOLEAN
    IsPwrPolOwner(
        VOID
        )
    {
        if (PnpPower.PowerPolicyOwner == WdfTrue) {
            return TRUE;
        }
        else if (PnpPower.PowerPolicyOwner == WdfFalse) {
            return FALSE;
        }
        else if (IsPdoInit()) {
            //
            // This is a PDO. If we are a raw PDO, we own pwr policy.
            //
            return Pdo.Raw;
        }
        else {
            ASSERT(IsFdoInit());

            //
            // This is an FDO. If we are not a filter, we own pwr policy.
            //
            return (Fdo.Filter == FALSE ? TRUE : FALSE);
        }
    }

    _Must_inspect_result_
    NTSTATUS
    AssignName(
        __in PFX_DRIVER_GLOBALS FxDriverGlobals,
        __in const UNICODE_STRING* Name
        );

    static
    _Must_inspect_result_
    PWDFDEVICE_INIT
    _AllocateControlDeviceInit(
        __in FxDriver* Driver,
        __in const UNICODE_STRING* SDDLString
        );

    VOID
    AddCxDeviceInit(
        __in PWDFCXDEVICE_INIT CxDeviceInit
        );

    VOID
    AssignIoType(
        _In_ PWDF_IO_TYPE_CONFIG IoTypeConfig
        );

public:
    PFX_DRIVER_GLOBALS DriverGlobals;

    FxDriver* Driver;

    FxDevice* CreatedDevice;

    BOOLEAN CreatedOnStack;

    BOOLEAN Exclusive;

    BOOLEAN PowerPageable;

    BOOLEAN Inrush;

    //
    // If set, the Cx/Client intends to leverage Self IO Target
    //
    BOOLEAN RequiresSelfIoTarget;

    ULONG RemoveLockOptionFlags;

    FxDeviceInitType InitType;

    WDF_DEVICE_IO_TYPE ReadWriteIoType;

    DEVICE_TYPE DeviceType;

    FxString* DeviceName;

    ULONG Characteristics;

    FileObjectInit FileObject;

    SecurityInit Security;

    WDF_OBJECT_ATTRIBUTES RequestAttributes;

    FxIrpPreprocessInfo* PreprocessInfo;

    PFN_WDF_IO_IN_CALLER_CONTEXT IoInCallerContextCallback;

    WDF_RELEASE_HARDWARE_ORDER_ON_FAILURE ReleaseHardwareOrderOnFailure;

    PnpPowerInit    PnpPower;
    FdoInit         Fdo;
    PdoInit         Pdo;
    ControlInit     Control;

    //
    // Class extension's device init.
    //
    LIST_ENTRY      CxDeviceInitListHead;

#if (FX_CORE_MODE == FX_CORE_USER_MODE)
    //
    // IoType preference for IOCTL
    //
    WDF_DEVICE_IO_TYPE DeviceControlIoType;

    //
    // Direct I/O threshold
    //
    ULONG DirectTransferThreshold;

    //
    // Weak reference to host side device stack
    //
    IWudfDeviceStack * DevStack;

    //
    // Kernel redirector's side object name.
    //
    PWSTR KernelDeviceName;

    //
    // PnP devinode hw key handle
    //
    HKEY PdoKey;

    //
    // Registry sub-path name containing driver configuration information.
    // The registry path name is relative to the "device key".
    //
    PWSTR ConfigRegistryPath;

    //
    // PDO Instance ID
    //
    PWSTR DevInstanceID;

    //
    // This ID is used by Host to associated host device and its driver info.
    //
    ULONG DriverID;
#endif

};

#endif // __FXDEVICEINIT_HPP__