/*++

Copyright (c) Microsoft Corporation. All rights reserved.

Module Name:

    ks.h

Abstract:

    Windows Driver Model/Connection and Streaming Architecture (WDM-CSA)
    core definitions.

--*/

#if !defined(_KS_)
#define _KS_

#pragma warning(disable:4201) // nameless struct/union
#pragma warning(disable:4214) // bit field types other than int

#if defined(__TCS__)
#define _KS_NO_ANONYMOUS_STRUCTURES_ 1
#endif

#if !defined(_NTRTL_)
    #ifndef DEFINE_GUIDEX
        #define DEFINE_GUIDEX(name) EXTERN_C const CDECL GUID name
    #endif // !defined(DEFINE_GUIDEX)

    #ifndef STATICGUIDOF
        #define STATICGUIDOF(guid) STATIC_##guid
    #endif // !defined(STATICGUIDOF)
#endif // !defined(_NTRTL_)

#ifndef SIZEOF_ARRAY
    #define SIZEOF_ARRAY(ar)        (sizeof(ar)/sizeof((ar)[0]))
#endif // !defined(SIZEOF_ARRAY)

#if defined(__cplusplus) && _MSC_VER >= 1100
#define DEFINE_GUIDSTRUCT(g, n) struct __declspec(uuid(g)) n
#define DEFINE_GUIDNAMED(n) __uuidof(struct n)
#else // !defined(__cplusplus)
#define DEFINE_GUIDSTRUCT(g, n) DEFINE_GUIDEX(n)
#define DEFINE_GUIDNAMED(n) n
#endif // !defined(__cplusplus)

//===========================================================================

#define STATIC_GUID_NULL \
    0x00000000L, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

DEFINE_GUIDSTRUCT("00000000-0000-0000-0000-000000000000", GUID_NULL);
#define GUID_NULL DEFINE_GUIDNAMED(GUID_NULL)

//===========================================================================

#define IOCTL_KS_PROPERTY              CTL_CODE(FILE_DEVICE_KS, 0x000, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_KS_ENABLE_EVENT          CTL_CODE(FILE_DEVICE_KS, 0x001, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_KS_DISABLE_EVENT         CTL_CODE(FILE_DEVICE_KS, 0x002, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_KS_METHOD                CTL_CODE(FILE_DEVICE_KS, 0x003, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_KS_WRITE_STREAM          CTL_CODE(FILE_DEVICE_KS, 0x004, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_KS_READ_STREAM           CTL_CODE(FILE_DEVICE_KS, 0x005, METHOD_NEITHER, FILE_READ_ACCESS)
#define IOCTL_KS_RESET_STATE           CTL_CODE(FILE_DEVICE_KS, 0x006, METHOD_NEITHER, FILE_ANY_ACCESS)

//===========================================================================

typedef enum {
    KSRESET_BEGIN,
    KSRESET_END
} KSRESET;

typedef enum {
    KSSTATE_STOP,
    KSSTATE_ACQUIRE,
    KSSTATE_PAUSE,
    KSSTATE_RUN
} KSSTATE, *PKSSTATE;

#define KSPRIORITY_LOW        0x00000001
#define KSPRIORITY_NORMAL     0x40000000
#define KSPRIORITY_HIGH       0x80000000
#define KSPRIORITY_EXCLUSIVE  0xFFFFFFFF

typedef struct {
    ULONG   PriorityClass;
    ULONG   PrioritySubClass;
} KSPRIORITY, *PKSPRIORITY;

typedef struct {
    union {
#if defined( _KS_NO_ANONYMOUS_STRUCTURES_ )
        struct _IDENTIFIER {
#else        
        struct {
#endif        
            GUID    Set;
            ULONG   Id;
            ULONG   Flags;
        };
        LONGLONG    Alignment;
    };
} KSIDENTIFIER, *PKSIDENTIFIER;

typedef KSIDENTIFIER KSPROPERTY, *PKSPROPERTY, KSMETHOD, *PKSMETHOD, KSEVENT, *PKSEVENT;

#define KSMETHOD_TYPE_NONE                  0x00000000
#define KSMETHOD_TYPE_READ                  0x00000001
#define KSMETHOD_TYPE_WRITE                 0x00000002
#define KSMETHOD_TYPE_MODIFY                0x00000003
#define KSMETHOD_TYPE_SOURCE                0x00000004

#define KSMETHOD_TYPE_SEND                  0x00000001
#define KSMETHOD_TYPE_SETSUPPORT            0x00000100
#define KSMETHOD_TYPE_BASICSUPPORT          0x00000200

#define KSMETHOD_TYPE_TOPOLOGY 0x10000000

#define KSPROPERTY_TYPE_GET                 0x00000001
#define KSPROPERTY_TYPE_SET                 0x00000002
#define KSPROPERTY_TYPE_SETSUPPORT          0x00000100
#define KSPROPERTY_TYPE_BASICSUPPORT        0x00000200
#define KSPROPERTY_TYPE_RELATIONS           0x00000400
#define KSPROPERTY_TYPE_SERIALIZESET        0x00000800
#define KSPROPERTY_TYPE_UNSERIALIZESET      0x00001000
#define KSPROPERTY_TYPE_SERIALIZERAW        0x00002000
#define KSPROPERTY_TYPE_UNSERIALIZERAW      0x00004000
#define KSPROPERTY_TYPE_SERIALIZESIZE       0x00008000
#define KSPROPERTY_TYPE_DEFAULTVALUES       0x00010000

#define KSPROPERTY_TYPE_TOPOLOGY 0x10000000

typedef struct {
    KSPROPERTY      Property;
    ULONG           NodeId;
    ULONG           Reserved;
} KSP_NODE, *PKSP_NODE;

typedef struct {
    KSMETHOD        Method;
    ULONG           NodeId;
    ULONG           Reserved;
} KSM_NODE, *PKSM_NODE;

typedef struct {
    KSEVENT         Event;
    ULONG           NodeId;
    ULONG           Reserved;
} KSE_NODE, *PKSE_NODE;

#define STATIC_KSPROPTYPESETID_General \
    0x97E99BA0L, 0xBDEA, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("97E99BA0-BDEA-11CF-A5D6-28DB04C10000", KSPROPTYPESETID_General);
#define KSPROPTYPESETID_General DEFINE_GUIDNAMED(KSPROPTYPESETID_General)

#if defined(_NTDDK_) && !defined(__wtypes_h__)
enum VARENUM {
    VT_EMPTY = 0,
    VT_NULL = 1,
    VT_I2 = 2,
    VT_I4 = 3,
    VT_R4 = 4,
    VT_R8 = 5,
    VT_CY = 6,
    VT_DATE = 7,
    VT_BSTR = 8,
    VT_DISPATCH = 9,
    VT_ERROR = 10,
    VT_BOOL = 11,
    VT_VARIANT = 12,
    VT_UNKNOWN = 13,
    VT_DECIMAL = 14,
    VT_I1 = 16,
    VT_UI1 = 17,
    VT_UI2 = 18,
    VT_UI4 = 19,
    VT_I8 = 20,
    VT_UI8 = 21,
    VT_INT = 22,
    VT_UINT = 23,
    VT_VOID = 24,
    VT_HRESULT  = 25,
    VT_PTR = 26,
    VT_SAFEARRAY = 27,
    VT_CARRAY = 28,
    VT_USERDEFINED = 29,
    VT_LPSTR = 30,
    VT_LPWSTR = 31,
    VT_FILETIME = 64,
    VT_BLOB = 65,
    VT_STREAM = 66,
    VT_STORAGE = 67,
    VT_STREAMED_OBJECT = 68,
    VT_STORED_OBJECT = 69,
    VT_BLOB_OBJECT = 70,
    VT_CF = 71,
    VT_CLSID = 72,
    VT_VECTOR = 0x1000,
    VT_ARRAY = 0x2000,
    VT_BYREF = 0x4000,
    VT_RESERVED = 0x8000,
    VT_ILLEGAL = 0xffff,
    VT_ILLEGALMASKED = 0xfff,
    VT_TYPEMASK = 0xfff
};
#endif // _NTDDK_ && !__wtypes_h__

typedef struct {
    ULONG    Size;
    ULONG    Count;
} KSMULTIPLE_ITEM, *PKSMULTIPLE_ITEM;

typedef struct {
    ULONG           AccessFlags;
    ULONG           DescriptionSize;
    KSIDENTIFIER    PropTypeSet;
    ULONG           MembersListCount;
    ULONG           Reserved;
} KSPROPERTY_DESCRIPTION, *PKSPROPERTY_DESCRIPTION;

#define KSPROPERTY_MEMBER_RANGES            0x00000001
#define KSPROPERTY_MEMBER_STEPPEDRANGES     0x00000002
#define KSPROPERTY_MEMBER_VALUES            0x00000003

#define KSPROPERTY_MEMBER_FLAG_DEFAULT                      0x00000001
#if (NTDDI_VERSION >= NTDDI_WINXP)
#define KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL    0x00000002
#define KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM         0x00000004
#endif // (NTDDI_VERSION >= NTDDI_WINXP)

typedef struct {
    ULONG   MembersFlags;
    ULONG   MembersSize;
    ULONG   MembersCount;
    ULONG   Flags;
} KSPROPERTY_MEMBERSHEADER, *PKSPROPERTY_MEMBERSHEADER;

typedef union {
#if defined( _KS_NO_ANONYMOUS_STRUCTURES_ )
    struct _SIGNED {
#else
    struct {
#endif    
        LONG    SignedMinimum;
        LONG    SignedMaximum;
    };
#if defined( _KS_NO_ANONYMOUS_STRUCTURES_ )
    struct _UNSIGNED {
#else
    struct {
#endif    
        ULONG   UnsignedMinimum;
        ULONG   UnsignedMaximum;
    };
} KSPROPERTY_BOUNDS_LONG, *PKSPROPERTY_BOUNDS_LONG;

typedef union {
#if defined( _KS_NO_ANONYMOUS_STRUCTURES_ )
    struct _SIGNED64 {
#else
    struct {
#endif    
        LONGLONG    SignedMinimum;
        LONGLONG    SignedMaximum;
    };
#if defined( _KS_NO_ANONYMOUS_STRUCTURES_ )
    struct _UNSIGNED64 {
#else
    struct {
#endif    
#if defined(_NTDDK_)
        ULONGLONG   UnsignedMinimum;
        ULONGLONG   UnsignedMaximum;
#else // !_NTDDK_
        DWORDLONG   UnsignedMinimum;
        DWORDLONG   UnsignedMaximum;
#endif // !_NTDDK_
    };
} KSPROPERTY_BOUNDS_LONGLONG, *PKSPROPERTY_BOUNDS_LONGLONG;

typedef struct {
    ULONG                       SteppingDelta;
    ULONG                       Reserved;
    KSPROPERTY_BOUNDS_LONG      Bounds;
} KSPROPERTY_STEPPING_LONG, *PKSPROPERTY_STEPPING_LONG;

typedef struct {
#if defined(_NTDDK_)
    ULONGLONG                   SteppingDelta;
#else // !_NTDDK_
    DWORDLONG                   SteppingDelta;
#endif // !_NTDDK_
    KSPROPERTY_BOUNDS_LONGLONG  Bounds;
} KSPROPERTY_STEPPING_LONGLONG, *PKSPROPERTY_STEPPING_LONGLONG;

//===========================================================================
#if (NTDDI_VERSION >= NTDDI_WINXP)

#if defined(_NTDDK_)
//
// Structure forward declarations.
//
typedef struct _KSDEVICE_DESCRIPTOR
KSDEVICE_DESCRIPTOR, *PKSDEVICE_DESCRIPTOR;
typedef struct _KSDEVICE_DISPATCH
KSDEVICE_DISPATCH, *PKSDEVICE_DISPATCH;
typedef struct _KSDEVICE 
KSDEVICE, *PKSDEVICE;
typedef struct _KSFILTERFACTORY 
KSFILTERFACTORY, *PKSFILTERFACTORY;
typedef struct _KSFILTER_DESCRIPTOR
KSFILTER_DESCRIPTOR, *PKSFILTER_DESCRIPTOR;
typedef struct _KSFILTER_DISPATCH
KSFILTER_DISPATCH, *PKSFILTER_DISPATCH;
typedef struct _KSFILTER 
KSFILTER, *PKSFILTER;
typedef struct _KSPIN_DESCRIPTOR_EX
KSPIN_DESCRIPTOR_EX, *PKSPIN_DESCRIPTOR_EX;
typedef struct _KSPIN_DISPATCH
KSPIN_DISPATCH, *PKSPIN_DISPATCH;
typedef struct _KSCLOCK_DISPATCH
KSCLOCK_DISPATCH, *PKSCLOCK_DISPATCH;
typedef struct _KSALLOCATOR_DISPATCH
KSALLOCATOR_DISPATCH, *PKSALLOCATOR_DISPATCH;
typedef struct _KSPIN 
KSPIN, *PKSPIN;
typedef struct _KSNODE_DESCRIPTOR
KSNODE_DESCRIPTOR, *PKSNODE_DESCRIPTOR;
typedef struct _KSSTREAM_POINTER_OFFSET
KSSTREAM_POINTER_OFFSET, *PKSSTREAM_POINTER_OFFSET;
typedef struct _KSSTREAM_POINTER
KSSTREAM_POINTER, *PKSSTREAM_POINTER;
typedef struct _KSMAPPING
KSMAPPING, *PKSMAPPING;
typedef struct _KSPROCESSPIN
KSPROCESSPIN, *PKSPROCESSPIN;
typedef struct _KSPROCESSPIN_INDEXENTRY
KSPROCESSPIN_INDEXENTRY, *PKSPROCESSPIN_INDEXENTRY;
#endif // _NTDDK_

#endif // (NTDDI_VERSION >= NTDDI_WINXP)

typedef PVOID PKSWORKER;

typedef struct {
    ULONG       NotificationType;
    union {
        struct {
            HANDLE              Event;
            ULONG_PTR           Reserved[2];
        } EventHandle;
        struct {
            HANDLE              Semaphore;
            ULONG               Reserved;
            LONG                Adjustment;
        } SemaphoreHandle;
#if defined(_NTDDK_)
        struct {
            PVOID               Event;
            KPRIORITY           Increment;
            ULONG_PTR           Reserved;
        } EventObject;
        struct {
            PVOID               Semaphore;
            KPRIORITY           Increment;
            LONG                Adjustment;
        } SemaphoreObject;
        struct {
            PKDPC               Dpc;
            ULONG               ReferenceCount;
            ULONG_PTR           Reserved;
        } Dpc;
        struct {
            PWORK_QUEUE_ITEM    WorkQueueItem;
            WORK_QUEUE_TYPE     WorkQueueType;
            ULONG_PTR           Reserved;
        } WorkItem;
        struct {
            PWORK_QUEUE_ITEM    WorkQueueItem;
            PKSWORKER           KsWorkerObject;
            ULONG_PTR           Reserved;
        } KsWorkItem;
#endif // defined(_NTDDK_)
        struct {
            PVOID               Unused;
            LONG_PTR            Alignment[2];
        } Alignment;
    };
} KSEVENTDATA, *PKSEVENTDATA;

#define KSEVENTF_EVENT_HANDLE       0x00000001
#define KSEVENTF_SEMAPHORE_HANDLE   0x00000002
#if defined(_NTDDK_)
#define KSEVENTF_EVENT_OBJECT       0x00000004
#define KSEVENTF_SEMAPHORE_OBJECT   0x00000008
#define KSEVENTF_DPC                0x00000010
#define KSEVENTF_WORKITEM           0x00000020
#define KSEVENTF_KSWORKITEM         0x00000080
#endif // defined(_NTDDK_)

#define KSEVENT_TYPE_ENABLE         0x00000001
#define KSEVENT_TYPE_ONESHOT        0x00000002
#define KSEVENT_TYPE_ENABLEBUFFERED 0x00000004
#define KSEVENT_TYPE_SETSUPPORT     0x00000100
#define KSEVENT_TYPE_BASICSUPPORT   0x00000200
#define KSEVENT_TYPE_QUERYBUFFER    0x00000400

#define KSEVENT_TYPE_TOPOLOGY 0x10000000

typedef struct {
    KSEVENT         Event;
    PKSEVENTDATA    EventData;
    PVOID           Reserved;
} KSQUERYBUFFER, *PKSQUERYBUFFER;

typedef struct {
    ULONG Size;
    ULONG Flags;
    union {
        HANDLE ObjectHandle;
        PVOID ObjectPointer;
    };
    PVOID Reserved;
    KSEVENT Event;
    KSEVENTDATA EventData;
} KSRELATIVEEVENT;

#define KSRELATIVEEVENT_FLAG_HANDLE 0x00000001
#define KSRELATIVEEVENT_FLAG_POINTER 0x00000002

//===========================================================================

typedef struct {
    KSEVENTDATA     EventData;
    LONGLONG        MarkTime;
} KSEVENT_TIME_MARK, *PKSEVENT_TIME_MARK;

typedef struct {
    KSEVENTDATA     EventData;
    LONGLONG        TimeBase;
    LONGLONG        Interval;
} KSEVENT_TIME_INTERVAL, *PKSEVENT_TIME_INTERVAL;

typedef struct {
    LONGLONG        TimeBase;
    LONGLONG        Interval;
} KSINTERVAL, *PKSINTERVAL;

//===========================================================================

#define STATIC_KSPROPSETID_General\
    0x1464EDA5L, 0x6A8F, 0x11D1, 0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("1464EDA5-6A8F-11D1-9AA7-00A0C9223196", KSPROPSETID_General);
#define KSPROPSETID_General DEFINE_GUIDNAMED(KSPROPSETID_General)

typedef enum {
    KSPROPERTY_GENERAL_COMPONENTID
} KSPROPERTY_GENERAL;

typedef struct {
    GUID    Manufacturer;
    GUID    Product;
    GUID    Component;
    GUID    Name;
    ULONG   Version;
    ULONG   Revision;
} KSCOMPONENTID, *PKSCOMPONENTID;

#define DEFINE_KSPROPERTY_ITEM_GENERAL_COMPONENTID(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_GENERAL_COMPONENTID,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSCOMPONENTID),\
        NULL, NULL, 0, NULL, NULL, 0)

#define STATIC_KSMETHODSETID_StreamIo\
    0x65D003CAL, 0x1523, 0x11D2, 0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("65D003CA-1523-11D2-B27A-00A0C9223196", KSMETHODSETID_StreamIo);
#define KSMETHODSETID_StreamIo DEFINE_GUIDNAMED(KSMETHODSETID_StreamIo)

typedef enum {
    KSMETHOD_STREAMIO_READ,
    KSMETHOD_STREAMIO_WRITE
} KSMETHOD_STREAMIO;

#define DEFINE_KSMETHOD_ITEM_STREAMIO_READ(Handler)\
    DEFINE_KSMETHOD_ITEM(\
        KSMETHOD_STREAMIO_READ,\
        KSMETHOD_TYPE_WRITE,\
        (Handler),\
        sizeof(KSMETHOD),\
        0,\
        NULL)

#define DEFINE_KSMETHOD_ITEM_STREAMIO_WRITE(Handler)\
    DEFINE_KSMETHOD_ITEM(\
        KSMETHOD_STREAMIO_WRITE,\
        KSMETHOD_TYPE_READ,\
        (Handler),\
        sizeof(KSMETHOD),\
        0,\
        NULL)

#define STATIC_KSPROPSETID_MediaSeeking\
    0xEE904F0CL, 0xD09B, 0x11D0, 0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("EE904F0C-D09B-11D0-ABE9-00A0C9223196", KSPROPSETID_MediaSeeking);
#define KSPROPSETID_MediaSeeking DEFINE_GUIDNAMED(KSPROPSETID_MediaSeeking)

typedef enum {
    KSPROPERTY_MEDIASEEKING_CAPABILITIES,
    KSPROPERTY_MEDIASEEKING_FORMATS,
    KSPROPERTY_MEDIASEEKING_TIMEFORMAT,
    KSPROPERTY_MEDIASEEKING_POSITION,
    KSPROPERTY_MEDIASEEKING_STOPPOSITION,
    KSPROPERTY_MEDIASEEKING_POSITIONS,
    KSPROPERTY_MEDIASEEKING_DURATION,
    KSPROPERTY_MEDIASEEKING_AVAILABLE,
    KSPROPERTY_MEDIASEEKING_PREROLL,
    KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT
} KSPROPERTY_MEDIASEEKING;

typedef enum {
    KS_SEEKING_NoPositioning,
    KS_SEEKING_AbsolutePositioning,
    KS_SEEKING_RelativePositioning,
    KS_SEEKING_IncrementalPositioning,
    KS_SEEKING_PositioningBitsMask = 0x3,
    KS_SEEKING_SeekToKeyFrame,
    KS_SEEKING_ReturnTime = 0x8
} KS_SEEKING_FLAGS;

typedef enum {
    KS_SEEKING_CanSeekAbsolute = 0x1,
    KS_SEEKING_CanSeekForwards = 0x2,
    KS_SEEKING_CanSeekBackwards = 0x4,
    KS_SEEKING_CanGetCurrentPos = 0x8,
    KS_SEEKING_CanGetStopPos = 0x10,
    KS_SEEKING_CanGetDuration = 0x20,
    KS_SEEKING_CanPlayBackwards = 0x40
} KS_SEEKING_CAPABILITIES;

typedef struct {
    LONGLONG            Current;
    LONGLONG            Stop;
    KS_SEEKING_FLAGS    CurrentFlags;
    KS_SEEKING_FLAGS    StopFlags;
} KSPROPERTY_POSITIONS, *PKSPROPERTY_POSITIONS;

typedef struct {
    LONGLONG    Earliest;
    LONGLONG    Latest;
} KSPROPERTY_MEDIAAVAILABLE, *PKSPROPERTY_MEDIAAVAILABLE;

typedef struct {
    KSPROPERTY  Property;
    GUID        SourceFormat;
    GUID        TargetFormat;
    LONGLONG    Time;
} KSP_TIMEFORMAT, *PKSP_TIMEFORMAT;

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_CAPABILITIES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_CAPABILITIES,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KS_SEEKING_CAPABILITIES),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_FORMATS(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_FORMATS,\
        (Handler),\
        sizeof(KSPROPERTY),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_TIMEFORMAT(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_TIMEFORMAT,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(GUID),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_POSITION(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_POSITION,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(LONGLONG),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_STOPPOSITION(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_STOPPOSITION,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(LONGLONG),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_POSITIONS(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_POSITIONS,\
        NULL,\
        sizeof(KSPROPERTY),\
        sizeof(KSPROPERTY_POSITIONS),\
        (Handler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_DURATION(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_DURATION,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(LONGLONG),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_AVAILABLE(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_AVAILABLE,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSPROPERTY_MEDIAAVAILABLE),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_PREROLL(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_PREROLL,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(LONGLONG),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_CONVERTTIMEFORMAT(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT,\
        (Handler),\
        sizeof(KSP_TIMEFORMAT),\
        sizeof(LONGLONG),\
        NULL, NULL, 0, NULL, NULL, 0)

//===========================================================================

#define STATIC_KSPROPSETID_Topology\
    0x720D4AC0L, 0x7533, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("720D4AC0-7533-11D0-A5D6-28DB04C10000", KSPROPSETID_Topology);
#define KSPROPSETID_Topology DEFINE_GUIDNAMED(KSPROPSETID_Topology)

typedef enum {
    KSPROPERTY_TOPOLOGY_CATEGORIES,
    KSPROPERTY_TOPOLOGY_NODES,
    KSPROPERTY_TOPOLOGY_CONNECTIONS,
    KSPROPERTY_TOPOLOGY_NAME
} KSPROPERTY_TOPOLOGY;

#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CATEGORIES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_TOPOLOGY_CATEGORIES,\
        (Handler),\
        sizeof(KSPROPERTY),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NODES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_TOPOLOGY_NODES,\
        (Handler),\
        sizeof(KSPROPERTY),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CONNECTIONS(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_TOPOLOGY_CONNECTIONS,\
        (Handler),\
        sizeof(KSPROPERTY),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NAME(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_TOPOLOGY_NAME,\
        (Handler),\
        sizeof(KSP_NODE),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_TOPOLOGYSET(TopologySet, Handler)\
DEFINE_KSPROPERTY_TABLE(TopologySet) {\
    DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CATEGORIES(Handler),\
    DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NODES(Handler),\
    DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CONNECTIONS(Handler),\
    DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NAME(Handler)\
}

//=============================================================================

//
// properties used by graph manager to talk to particular filters
//
#if defined(_NTDDK_)

#define STATIC_KSPROPSETID_GM \
    0xAF627536L, 0xE719, 0x11D2, 0x8A, 0x1D, 0x00, 0x60, 0x97, 0xD2, 0xDF, 0x5D    
DEFINE_GUIDSTRUCT("AF627536-E719-11D2-8A1D-006097D2DF5D", KSPROPSETID_GM);
#define KSPROPSETID_GM DEFINE_GUIDNAMED(KSPROPSETID_GM)

typedef VOID (*PFNKSGRAPHMANAGER_NOTIFY)(__in PFILE_OBJECT GraphManager,
                                         __in ULONG EventId,
                                         __in PVOID Filter,
                                         __in PVOID Pin,
                                         __in PVOID Frame,
                                         __in ULONG Duration);

typedef struct KSGRAPHMANAGER_FUNCTIONTABLE {
    PFNKSGRAPHMANAGER_NOTIFY NotifyEvent;
} KSGRAPHMANAGER_FUNCTIONTABLE, PKSGRAPHMANAGER_FUNCTIONTABLE;

typedef struct _KSPROPERTY_GRAPHMANAGER_INTERFACE {
    PFILE_OBJECT                 GraphManager;
    KSGRAPHMANAGER_FUNCTIONTABLE FunctionTable;
} KSPROPERTY_GRAPHMANAGER_INTERFACE, *PKSPROPERTY_GRAPHMANAGER_INTERFACE;


//
// Commands
//
typedef enum {
    KSPROPERTY_GM_GRAPHMANAGER,    
    KSPROPERTY_GM_TIMESTAMP_CLOCK, 
    KSPROPERTY_GM_RATEMATCH,       
    KSPROPERTY_GM_RENDER_CLOCK,    
} KSPROPERTY_GM;

#endif

//===========================================================================


#define STATIC_KSCATEGORY_BRIDGE \
    0x085AFF00L, 0x62CE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("085AFF00-62CE-11CF-A5D6-28DB04C10000", KSCATEGORY_BRIDGE);
#define KSCATEGORY_BRIDGE DEFINE_GUIDNAMED(KSCATEGORY_BRIDGE)

#define STATIC_KSCATEGORY_CAPTURE \
    0x65E8773DL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("65E8773D-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_CAPTURE);
#define KSCATEGORY_CAPTURE DEFINE_GUIDNAMED(KSCATEGORY_CAPTURE)

#define STATIC_KSCATEGORY_RENDER \
    0x65E8773EL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("65E8773E-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_RENDER);
#define KSCATEGORY_RENDER DEFINE_GUIDNAMED(KSCATEGORY_RENDER)

#define STATIC_KSCATEGORY_MIXER \
    0xAD809C00L, 0x7B88, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("AD809C00-7B88-11D0-A5D6-28DB04C10000", KSCATEGORY_MIXER);
#define KSCATEGORY_MIXER DEFINE_GUIDNAMED(KSCATEGORY_MIXER)

#define STATIC_KSCATEGORY_SPLITTER \
    0x0A4252A0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("0A4252A0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_SPLITTER);
#define KSCATEGORY_SPLITTER DEFINE_GUIDNAMED(KSCATEGORY_SPLITTER)

#define STATIC_KSCATEGORY_DATACOMPRESSOR \
    0x1E84C900L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("1E84C900-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATACOMPRESSOR);
#define KSCATEGORY_DATACOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATACOMPRESSOR)

#define STATIC_KSCATEGORY_DATADECOMPRESSOR \
    0x2721AE20L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("2721AE20-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATADECOMPRESSOR);
#define KSCATEGORY_DATADECOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATADECOMPRESSOR)

#define STATIC_KSCATEGORY_DATATRANSFORM \
    0x2EB07EA0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("2EB07EA0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATATRANSFORM);
#define KSCATEGORY_DATATRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_DATATRANSFORM)

//
// KSMFT_CATEGORY_XXX are MF Transform category guids redefined in ks.h 
// to facilitate KS Mini drivers to register KS Filters under MF Transform categories. 
//
#define STATIC_KSMFT_CATEGORY_VIDEO_DECODER \
	0xd6c02d4b, 0x6833, 0x45b4, 0x97, 0x1a, 0x05, 0xa4, 0xb0, 0x4b, 0xab, 0x91
DEFINE_GUIDSTRUCT("d6c02d4b-6833-45b4-971a-05a4b04bab91", KSMFT_CATEGORY_VIDEO_DECODER);
#define KSMFT_CATEGORY_VIDEO_DECODER DEFINE_GUIDNAMED(KSMFT_CATEGORY_VIDEO_DECODER)

#define STATIC_KSMFT_CATEGORY_VIDEO_ENCODER \
	0xf79eac7d, 0xe545, 0x4387, 0xbd, 0xee, 0xd6, 0x47, 0xd7, 0xbd, 0xe4, 0x2a
DEFINE_GUIDSTRUCT("f79eac7d-e545-4387-bdee-d647d7bde42a", KSMFT_CATEGORY_VIDEO_ENCODER);
#define KSMFT_CATEGORY_VIDEO_ENCODER DEFINE_GUIDNAMED(KSMFT_CATEGORY_VIDEO_ENCODER)

#define STATIC_KSMFT_CATEGORY_VIDEO_EFFECT \
	0x12e17c21, 0x532c, 0x4a6e, 0x8a, 0x1c, 0x40, 0x82, 0x5a, 0x73, 0x63, 0x97
DEFINE_GUIDSTRUCT("12e17c21-532c-4a6e-8a1c-40825a736397", KSMFT_CATEGORY_VIDEO_EFFECT);
#define KSMFT_CATEGORY_VIDEO_EFFECT DEFINE_GUIDNAMED(KSMFT_CATEGORY_VIDEO_EFFECT)

#define STATIC_KSMFT_CATEGORY_MULTIPLEXER \
	0x059c561e, 0x05ae, 0x4b61, 0xb6, 0x9d, 0x55, 0xb6, 0x1e, 0xe5, 0x4a, 0x7b
DEFINE_GUIDSTRUCT("059c561e-05ae-4b61-b69d-55b61ee54a7b", KSMFT_CATEGORY_MULTIPLEXER);
#define KSMFT_CATEGORY_MULTIPLEXER DEFINE_GUIDNAMED(KSMFT_CATEGORY_MULTIPLEXER)

#define STATIC_KSMFT_CATEGORY_DEMULTIPLEXER \
	0xa8700a7a, 0x939b, 0x44c5, 0x99, 0xd7, 0x76, 0x22, 0x6b, 0x23, 0xb3, 0xf1
DEFINE_GUIDSTRUCT("a8700a7a-939b-44c5-99d7-76226b23b3f1", KSMFT_CATEGORY_DEMULTIPLEXER);
#define KSMFT_CATEGORY_DEMULTIPLEXER DEFINE_GUIDNAMED(KSMFT_CATEGORY_DEMULTIPLEXER)

#define STATIC_KSMFT_CATEGORY_AUDIO_DECODER \
	0x9ea73fb4, 0xef7a, 0x4559, 0x8d, 0x5d, 0x71, 0x9d, 0x8f, 0x04, 0x26, 0xc7
DEFINE_GUIDSTRUCT("9ea73fb4-ef7a-4559-8d5d-719d8f0426c7", KSMFT_CATEGORY_AUDIO_DECODER);
#define KSMFT_CATEGORY_AUDIO_DECODER DEFINE_GUIDNAMED(KSMFT_CATEGORY_AUDIO_DECODER)

#define STATIC_KSMFT_CATEGORY_AUDIO_ENCODER \
	0x91c64bd0, 0xf91e, 0x4d8c, 0x92, 0x76, 0xdb, 0x24, 0x82, 0x79, 0xd9, 0x75
DEFINE_GUIDSTRUCT("91c64bd0-f91e-4d8c-9276-db248279d975", KSMFT_CATEGORY_AUDIO_ENCODER);
#define KSMFT_CATEGORY_AUDIO_ENCODER DEFINE_GUIDNAMED(KSMFT_CATEGORY_AUDIO_ENCODER)

#define STATIC_KSMFT_CATEGORY_AUDIO_EFFECT \
	0x11064c48, 0x3648, 0x4ed0, 0x93, 0x2e, 0x05, 0xce, 0x8a, 0xc8, 0x11, 0xb7
DEFINE_GUIDSTRUCT("11064c48-3648-4ed0-932e-05ce8ac811b7", KSMFT_CATEGORY_AUDIO_EFFECT);
#define KSMFT_CATEGORY_AUDIO_EFFECT DEFINE_GUIDNAMED(KSMFT_CATEGORY_AUDIO_EFFECT)

#define STATIC_KSMFT_CATEGORY_VIDEO_PROCESSOR \
	0x302ea3fc, 0xaa5f, 0x47f9, 0x9f, 0x7a, 0xc2, 0x18, 0x8b, 0xb1, 0x63, 0x2
DEFINE_GUIDSTRUCT("302ea3fc-aa5f-47f9-9f7a-c2188bb16302", KSMFT_CATEGORY_VIDEO_PROCESSOR);
#define KSMFT_CATEGORY_VIDEO_PROCESSOR DEFINE_GUIDNAMED(KSMFT_CATEGORY_VIDEO_PROCESSOR)

#define STATIC_KSMFT_CATEGORY_OTHER \
	0x90175d57, 0xb7ea, 0x4901, 0xae, 0xb3, 0x93, 0x3a, 0x87, 0x47, 0x75, 0x6f
DEFINE_GUIDSTRUCT("90175d57-b7ea-4901-aeb3-933a8747756f", KSMFT_CATEGORY_OTHER);
#define KSMFT_CATEGORY_OTHER DEFINE_GUIDNAMED(KSMFT_CATEGORY_OTHER)

#define STATIC_KSCATEGORY_COMMUNICATIONSTRANSFORM \
    0xCF1DDA2CL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("CF1DDA2C-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_COMMUNICATIONSTRANSFORM);
#define KSCATEGORY_COMMUNICATIONSTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_COMMUNICATIONSTRANSFORM)

#define STATIC_KSCATEGORY_INTERFACETRANSFORM \
    0xCF1DDA2DL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("CF1DDA2D-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_INTERFACETRANSFORM);
#define KSCATEGORY_INTERFACETRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_INTERFACETRANSFORM)

#define STATIC_KSCATEGORY_MEDIUMTRANSFORM \
    0xCF1DDA2EL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("CF1DDA2E-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_MEDIUMTRANSFORM);
#define KSCATEGORY_MEDIUMTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_MEDIUMTRANSFORM)

#define STATIC_KSCATEGORY_FILESYSTEM \
    0x760FED5EL, 0x9357, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("760FED5E-9357-11D0-A3CC-00A0C9223196", KSCATEGORY_FILESYSTEM);
#define KSCATEGORY_FILESYSTEM DEFINE_GUIDNAMED(KSCATEGORY_FILESYSTEM)

// KSNAME_Clock
#define STATIC_KSCATEGORY_CLOCK \
    0x53172480L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("53172480-4791-11D0-A5D6-28DB04C10000", KSCATEGORY_CLOCK);
#define KSCATEGORY_CLOCK DEFINE_GUIDNAMED(KSCATEGORY_CLOCK)

#define STATIC_KSCATEGORY_PROXY \
    0x97EBAACAL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("97EBAACA-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_PROXY);
#define KSCATEGORY_PROXY DEFINE_GUIDNAMED(KSCATEGORY_PROXY)

#define STATIC_KSCATEGORY_QUALITY \
    0x97EBAACBL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("97EBAACB-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_QUALITY);
#define KSCATEGORY_QUALITY DEFINE_GUIDNAMED(KSCATEGORY_QUALITY)

typedef struct {
    ULONG   FromNode;
    ULONG   FromNodePin;
    ULONG   ToNode;
    ULONG   ToNodePin;
} KSTOPOLOGY_CONNECTION, *PKSTOPOLOGY_CONNECTION;

typedef struct {
    ULONG                           CategoriesCount;
    __field_ecount(CategoriesCount)
    const GUID*                     Categories;
    ULONG                           TopologyNodesCount;
    __field_ecount(TopologyNodesCount)
    const GUID*                     TopologyNodes;
    ULONG                           TopologyConnectionsCount;
    __field_ecount(TopologyConnectionsCount)
    const KSTOPOLOGY_CONNECTION*    TopologyConnections;
    __field_ecount(TopologyNodesCount)
    const GUID*                     TopologyNodesNames;
    ULONG                           Reserved;
} KSTOPOLOGY, *PKSTOPOLOGY;

#define KSFILTER_NODE   ((ULONG)-1)
#define KSALL_NODES     ((ULONG)-1)

typedef struct {
    ULONG       CreateFlags;
    ULONG       Node;
} KSNODE_CREATE, *PKSNODE_CREATE;

//===========================================================================

// TIME_FORMAT_NONE
#define STATIC_KSTIME_FORMAT_NONE       STATIC_GUID_NULL
#define KSTIME_FORMAT_NONE              GUID_NULL

// TIME_FORMAT_FRAME
#define STATIC_KSTIME_FORMAT_FRAME\
    0x7b785570L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6
DEFINE_GUIDSTRUCT("7b785570-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_FRAME);
#define KSTIME_FORMAT_FRAME DEFINE_GUIDNAMED(KSTIME_FORMAT_FRAME)

// TIME_FORMAT_BYTE             
#define STATIC_KSTIME_FORMAT_BYTE\
    0x7b785571L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6
DEFINE_GUIDSTRUCT("7b785571-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_BYTE);
#define KSTIME_FORMAT_BYTE DEFINE_GUIDNAMED(KSTIME_FORMAT_BYTE)

// TIME_FORMAT_SAMPLE
#define STATIC_KSTIME_FORMAT_SAMPLE\
    0x7b785572L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6
DEFINE_GUIDSTRUCT("7b785572-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_SAMPLE);
#define KSTIME_FORMAT_SAMPLE DEFINE_GUIDNAMED(KSTIME_FORMAT_SAMPLE)

// TIME_FORMAT_FIELD
#define STATIC_KSTIME_FORMAT_FIELD\
    0x7b785573L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6
DEFINE_GUIDSTRUCT("7b785573-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_FIELD);
#define KSTIME_FORMAT_FIELD DEFINE_GUIDNAMED(KSTIME_FORMAT_FIELD)

// TIME_FORMAT_MEDIA_TIME
#define STATIC_KSTIME_FORMAT_MEDIA_TIME\
    0x7b785574L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6
DEFINE_GUIDSTRUCT("7b785574-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_MEDIA_TIME);
#define KSTIME_FORMAT_MEDIA_TIME DEFINE_GUIDNAMED(KSTIME_FORMAT_MEDIA_TIME)

//===========================================================================

typedef KSIDENTIFIER KSPIN_INTERFACE, *PKSPIN_INTERFACE;

#define STATIC_KSINTERFACESETID_Standard \
    0x1A8766A0L, 0x62CE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("1A8766A0-62CE-11CF-A5D6-28DB04C10000", KSINTERFACESETID_Standard);
#define KSINTERFACESETID_Standard DEFINE_GUIDNAMED(KSINTERFACESETID_Standard)

typedef enum {
    KSINTERFACE_STANDARD_STREAMING,
    KSINTERFACE_STANDARD_LOOPED_STREAMING,
    KSINTERFACE_STANDARD_CONTROL		//Reserved for system use
} KSINTERFACE_STANDARD;

#define STATIC_KSINTERFACESETID_FileIo \
    0x8C6F932CL, 0xE771, 0x11D0, 0xB8, 0xFF, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("8C6F932C-E771-11D0-B8FF-00A0C9223196", KSINTERFACESETID_FileIo);
#define KSINTERFACESETID_FileIo DEFINE_GUIDNAMED(KSINTERFACESETID_FileIo)

typedef enum {
    KSINTERFACE_FILEIO_STREAMING
} KSINTERFACE_FILEIO;

//===========================================================================

#define KSMEDIUM_TYPE_ANYINSTANCE       0

#define STATIC_KSMEDIUMSETID_Standard \
    0x4747B320L, 0x62CE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("4747B320-62CE-11CF-A5D6-28DB04C10000", KSMEDIUMSETID_Standard);
#define KSMEDIUMSETID_Standard DEFINE_GUIDNAMED(KSMEDIUMSETID_Standard)

//For compatibility only
#define KSMEDIUM_STANDARD_DEVIO     KSMEDIUM_TYPE_ANYINSTANCE

//===========================================================================

#define STATIC_KSPROPSETID_Pin\
    0x8C134960L, 0x51AD, 0x11CF, 0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("8C134960-51AD-11CF-878A-94F801C10000", KSPROPSETID_Pin);
#define KSPROPSETID_Pin DEFINE_GUIDNAMED(KSPROPSETID_Pin)

typedef enum {
    KSPROPERTY_PIN_CINSTANCES,
    KSPROPERTY_PIN_CTYPES,
    KSPROPERTY_PIN_DATAFLOW,
    KSPROPERTY_PIN_DATARANGES,
    KSPROPERTY_PIN_DATAINTERSECTION,
    KSPROPERTY_PIN_INTERFACES,
    KSPROPERTY_PIN_MEDIUMS,
    KSPROPERTY_PIN_COMMUNICATION,
    KSPROPERTY_PIN_GLOBALCINSTANCES,
    KSPROPERTY_PIN_NECESSARYINSTANCES,
    KSPROPERTY_PIN_PHYSICALCONNECTION,
    KSPROPERTY_PIN_CATEGORY,
    KSPROPERTY_PIN_NAME,
    KSPROPERTY_PIN_CONSTRAINEDDATARANGES,
    KSPROPERTY_PIN_PROPOSEDATAFORMAT
} KSPROPERTY_PIN;

typedef struct {
    KSPROPERTY      Property;
    ULONG           PinId;
    ULONG           Reserved;
} KSP_PIN, *PKSP_PIN;

typedef struct {
    KSEVENT         Event;
    ULONG           PinId;
    ULONG           Reserved;
} KSE_PIN, *PKSE_PIN;

#define KSINSTANCE_INDETERMINATE    ((ULONG)-1)

typedef struct {
    ULONG  PossibleCount;
    ULONG  CurrentCount;
} KSPIN_CINSTANCES, *PKSPIN_CINSTANCES;

typedef enum {
    KSPIN_DATAFLOW_IN = 1,
    KSPIN_DATAFLOW_OUT
} KSPIN_DATAFLOW, *PKSPIN_DATAFLOW;

#define KSDATAFORMAT_BIT_TEMPORAL_COMPRESSION   0
#define KSDATAFORMAT_TEMPORAL_COMPRESSION       (1 << KSDATAFORMAT_BIT_TEMPORAL_COMPRESSION)
#define KSDATAFORMAT_BIT_ATTRIBUTES 1
#define KSDATAFORMAT_ATTRIBUTES (1 << KSDATAFORMAT_BIT_ATTRIBUTES)

#define KSDATARANGE_BIT_ATTRIBUTES 1
#define KSDATARANGE_ATTRIBUTES (1 << KSDATARANGE_BIT_ATTRIBUTES)
#define KSDATARANGE_BIT_REQUIRED_ATTRIBUTES 2
#define KSDATARANGE_REQUIRED_ATTRIBUTES (1 << KSDATARANGE_BIT_REQUIRED_ATTRIBUTES)

#if !defined( _MSC_VER ) 
typedef struct {
    ULONG   FormatSize;
    ULONG   Flags;
    ULONG   SampleSize;
    ULONG   Reserved;
    GUID    MajorFormat;
    GUID    SubFormat;
    GUID    Specifier;
} KSDATAFORMAT, *PKSDATAFORMAT, KSDATARANGE, *PKSDATARANGE;
#else
typedef union {
    struct {
        ULONG   FormatSize;
        ULONG   Flags;
        ULONG   SampleSize;
        ULONG   Reserved;
        GUID    MajorFormat;
        GUID    SubFormat;
        GUID    Specifier;
    };
    LONGLONG    Alignment;
} KSDATAFORMAT, *PKSDATAFORMAT, KSDATARANGE, *PKSDATARANGE;
#endif

#define KSATTRIBUTE_REQUIRED 0x00000001

typedef struct {
    ULONG Size;
    ULONG Flags;
    GUID Attribute;
} KSATTRIBUTE, *PKSATTRIBUTE;

#if defined(_NTDDK_)
typedef struct {
    ULONG Count;
    __field_ecount(Count) PKSATTRIBUTE* Attributes;
} KSATTRIBUTE_LIST, *PKSATTRIBUTE_LIST;
#endif // _NTDDK_

typedef enum {
    KSPIN_COMMUNICATION_NONE,
    KSPIN_COMMUNICATION_SINK,
    KSPIN_COMMUNICATION_SOURCE,
    KSPIN_COMMUNICATION_BOTH,
    KSPIN_COMMUNICATION_BRIDGE
} KSPIN_COMMUNICATION, *PKSPIN_COMMUNICATION;

typedef KSIDENTIFIER KSPIN_MEDIUM, *PKSPIN_MEDIUM;

typedef struct {
    KSPIN_INTERFACE Interface;
    KSPIN_MEDIUM    Medium;
    ULONG           PinId;
    HANDLE          PinToHandle;
    KSPRIORITY      Priority;
} KSPIN_CONNECT, *PKSPIN_CONNECT;

typedef struct {
    ULONG   Size;
    ULONG   Pin;
    WCHAR   SymbolicLinkName[1];
} KSPIN_PHYSICALCONNECTION, *PKSPIN_PHYSICALCONNECTION;

#if defined(_NTDDK_)
__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSINTERSECTHANDLER)(
    __in PIRP Irp,
    __in PKSP_PIN Pin,
    __in PKSDATARANGE DataRange,
    __out_opt PVOID Data
    );
__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSINTERSECTHANDLEREX)(
    __in PVOID Context,
    __in PIRP Irp,
    __in PKSP_PIN Pin,
    __in PKSDATARANGE DataRange,
    __in PKSDATARANGE MatchingDataRange,
    __in ULONG DataBufferSize,
    __out_bcount_part_opt(DataBufferSize, *DataSize) PVOID Data,
    __out PULONG DataSize
    );
#endif // _NTDDK_

#define DEFINE_KSPIN_INTERFACE_TABLE(tablename)\
    const KSPIN_INTERFACE tablename[] =

#define DEFINE_KSPIN_INTERFACE_ITEM(guid, interface)\
    {\
        STATICGUIDOF(guid),\
        (interface),\
        0\
    }

#define DEFINE_KSPIN_MEDIUM_TABLE( tablename )\
    const KSPIN_MEDIUM tablename[] =

#define DEFINE_KSPIN_MEDIUM_ITEM(guid, medium)\
    DEFINE_KSPIN_INTERFACE_ITEM(guid, medium)

#define DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_CINSTANCES,\
        (Handler),\
        sizeof(KSP_PIN),\
        sizeof(KSPIN_CINSTANCES),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_CTYPES,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(ULONG),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_DATAFLOW,\
        (Handler),\
        sizeof(KSP_PIN),\
        sizeof(KSPIN_DATAFLOW),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_DATARANGES,\
        (Handler),\
        sizeof(KSP_PIN),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_DATAINTERSECTION,\
        (Handler),\
        sizeof(KSP_PIN) + sizeof(KSMULTIPLE_ITEM),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_INTERFACES,\
        (Handler),\
        sizeof(KSP_PIN),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_MEDIUMS,\
        (Handler),\
        sizeof(KSP_PIN),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_COMMUNICATION,\
        (Handler),\
        sizeof(KSP_PIN),\
        sizeof(KSPIN_COMMUNICATION),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_GLOBALCINSTANCES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_GLOBALCINSTANCES,\
        (Handler),\
        sizeof(KSP_PIN),\
        sizeof(KSPIN_CINSTANCES),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_NECESSARYINSTANCES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_NECESSARYINSTANCES,\
        (Handler),\
        sizeof(KSP_PIN),\
        sizeof(ULONG),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_PHYSICALCONNECTION(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_PHYSICALCONNECTION,\
        (Handler),\
        sizeof(KSP_PIN),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_CATEGORY,\
        (Handler),\
        sizeof(KSP_PIN),\
        sizeof(GUID),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_NAME(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_NAME,\
        (Handler),\
        sizeof(KSP_PIN),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_CONSTRAINEDDATARANGES,\
        (Handler),\
        sizeof(KSP_PIN),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_PIN_PROPOSEDATAFORMAT,\
        NULL,\
        sizeof(KSP_PIN),\
        sizeof(KSDATAFORMAT),\
        (Handler), NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_PINSET(PinSet,\
    PropGeneral, PropInstances, PropIntersection)\
DEFINE_KSPROPERTY_TABLE(PinSet) {\
    DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(PropInstances),\
    DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(PropIntersection),\
    DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_NAME(PropGeneral)\
}

#define DEFINE_KSPROPERTY_PINSETCONSTRAINED(PinSet,\
    PropGeneral, PropInstances, PropIntersection)\
DEFINE_KSPROPERTY_TABLE(PinSet) {\
    DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(PropInstances),\
    DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(PropIntersection),\
    DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_NAME(PropGeneral),\
    DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral)\
}

#define STATIC_KSEVENTSETID_PinCapsChange \
    0xDD4F192E, 0x3B78, 0x49AD, 0xA5, 0x34, 0x2C, 0x31, 0x5b, 0x82, 0x20, 0x00
DEFINE_GUIDSTRUCT("DD4F192E-3B78-49AD-A534-2C315B822000", KSEVENTSETID_PinCapsChange);
#define KSEVENTSETID_PinCapsChange DEFINE_GUIDNAMED(KSEVENTSETID_PinCapsChange)

typedef enum {
    KSEVENT_PINCAPS_FORMATCHANGE,
    KSEVENT_PINCAPS_JACKINFOCHANGE
} KSEVENT_PINCAPS_CHANGENOTIFICATIONS;

#define STATIC_KSNAME_Filter\
    0x9b365890L, 0x165f, 0x11d0, 0xa1, 0x95, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4
DEFINE_GUIDSTRUCT("9b365890-165f-11d0-a195-0020afd156e4", KSNAME_Filter);
#define KSNAME_Filter DEFINE_GUIDNAMED(KSNAME_Filter)

#define KSSTRING_Filter L"{9B365890-165F-11D0-A195-0020AFD156E4}"

#define STATIC_KSNAME_Pin\
    0x146F1A80L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("146F1A80-4791-11D0-A5D6-28DB04C10000", KSNAME_Pin);
#define KSNAME_Pin DEFINE_GUIDNAMED(KSNAME_Pin)

#define KSSTRING_Pin L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"

#define STATIC_KSNAME_Clock\
    0x53172480L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("53172480-4791-11D0-A5D6-28DB04C10000", KSNAME_Clock);
#define KSNAME_Clock DEFINE_GUIDNAMED(KSNAME_Clock)

#define KSSTRING_Clock L"{53172480-4791-11D0-A5D6-28DB04C10000}"

#define STATIC_KSNAME_Allocator\
    0x642F5D00L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("642F5D00-4791-11D0-A5D6-28DB04C10000", KSNAME_Allocator);
#define KSNAME_Allocator DEFINE_GUIDNAMED(KSNAME_Allocator)

#define KSSTRING_Allocator L"{642F5D00-4791-11D0-A5D6-28DB04C10000}"

#define KSSTRING_AllocatorEx L"{091BB63B-603F-11D1-B067-00A0C9062802}"

#define STATIC_KSNAME_TopologyNode\
    0x0621061AL, 0xEE75, 0x11D0, 0xB9, 0x15, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("0621061A-EE75-11D0-B915-00A0C9223196", KSNAME_TopologyNode);
#define KSNAME_TopologyNode DEFINE_GUIDNAMED(KSNAME_TopologyNode)

#define KSSTRING_TopologyNode L"{0621061A-EE75-11D0-B915-00A0C9223196}"

#if defined(_NTDDK_)

typedef struct {
    ULONG                   InterfacesCount;
    __field_ecount(InterfacesCount)
    const KSPIN_INTERFACE*  Interfaces;
    ULONG                   MediumsCount;
    __field_ecount(MediumsCount)
    const KSPIN_MEDIUM*     Mediums;
    ULONG                   DataRangesCount;
    __field_ecount(DataRangesCount)
    const PKSDATARANGE*     DataRanges;
    KSPIN_DATAFLOW          DataFlow;
    KSPIN_COMMUNICATION     Communication;
    const GUID*             Category;
    const GUID*             Name;
    union {
        LONGLONG            Reserved;
        struct {
            ULONG           ConstrainedDataRangesCount;
            __field_ecount(ConstrainedDataRangesCount)
            PKSDATARANGE*   ConstrainedDataRanges;
        };
    };
} KSPIN_DESCRIPTOR, *PKSPIN_DESCRIPTOR;
typedef const KSPIN_DESCRIPTOR *PCKSPIN_DESCRIPTOR;

#define DEFINE_KSPIN_DESCRIPTOR_TABLE(tablename)\
    const KSPIN_DESCRIPTOR tablename[] =

#define DEFINE_KSPIN_DESCRIPTOR_ITEM(\
    InterfacesCount, Interfaces,\
    MediumsCount, Mediums,\
    DataRangesCount, DataRanges,\
    DataFlow, Communication)\
{\
    InterfacesCount, Interfaces, MediumsCount, Mediums,\
    DataRangesCount, DataRanges, DataFlow, Communication,\
    NULL, NULL, 0\
}
#define DEFINE_KSPIN_DESCRIPTOR_ITEMEX(\
    InterfacesCount, Interfaces,\
    MediumsCount, Mediums,\
    DataRangesCount, DataRanges,\
    DataFlow, Communication,\
    Category, Name)\
{\
    InterfacesCount, Interfaces, MediumsCount, Mediums,\
    DataRangesCount, DataRanges, DataFlow, Communication,\
    Category, Name, 0\
}

#endif // defined(_NTDDK_)

//===========================================================================

// MEDIATYPE_NULL
#define STATIC_KSDATAFORMAT_TYPE_WILDCARD       STATIC_GUID_NULL
#define KSDATAFORMAT_TYPE_WILDCARD              GUID_NULL

// MEDIASUBTYPE_NULL
#define STATIC_KSDATAFORMAT_SUBTYPE_WILDCARD    STATIC_GUID_NULL
#define KSDATAFORMAT_SUBTYPE_WILDCARD           GUID_NULL

// MEDIATYPE_Stream
#define STATIC_KSDATAFORMAT_TYPE_STREAM\
    0xE436EB83L, 0x524F, 0x11CE, 0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70
DEFINE_GUIDSTRUCT("E436EB83-524F-11CE-9F53-0020AF0BA770", KSDATAFORMAT_TYPE_STREAM);
#define KSDATAFORMAT_TYPE_STREAM DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_STREAM)

// MEDIASUBTYPE_None
#define STATIC_KSDATAFORMAT_SUBTYPE_NONE\
    0xE436EB8EL, 0x524F, 0x11CE, 0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70
DEFINE_GUIDSTRUCT("E436EB8E-524F-11CE-9F53-0020AF0BA770", KSDATAFORMAT_SUBTYPE_NONE);
#define KSDATAFORMAT_SUBTYPE_NONE DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NONE)

#define STATIC_KSDATAFORMAT_SPECIFIER_WILDCARD  STATIC_GUID_NULL
#define KSDATAFORMAT_SPECIFIER_WILDCARD         GUID_NULL

#define STATIC_KSDATAFORMAT_SPECIFIER_FILENAME\
    0xAA797B40L, 0xE974, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("AA797B40-E974-11CF-A5D6-28DB04C10000", KSDATAFORMAT_SPECIFIER_FILENAME);
#define KSDATAFORMAT_SPECIFIER_FILENAME DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_FILENAME)

#define STATIC_KSDATAFORMAT_SPECIFIER_FILEHANDLE\
    0x65E8773CL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("65E8773C-8F56-11D0-A3B9-00A0C9223196", KSDATAFORMAT_SPECIFIER_FILEHANDLE);
#define KSDATAFORMAT_SPECIFIER_FILEHANDLE DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_FILEHANDLE)

// FORMAT_None
#define STATIC_KSDATAFORMAT_SPECIFIER_NONE\
    0x0F6417D6L, 0xC318, 0x11D0, 0xA4, 0x3F, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("0F6417D6-C318-11D0-A43F-00A0C9223196", KSDATAFORMAT_SPECIFIER_NONE);
#define KSDATAFORMAT_SPECIFIER_NONE DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_NONE)

//===========================================================================

#define STATIC_KSPROPSETID_Quality \
    0xD16AD380L, 0xAC1A, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("D16AD380-AC1A-11CF-A5D6-28DB04C10000", KSPROPSETID_Quality);
#define KSPROPSETID_Quality DEFINE_GUIDNAMED(KSPROPSETID_Quality)

typedef enum {
    KSPROPERTY_QUALITY_REPORT,
    KSPROPERTY_QUALITY_ERROR
} KSPROPERTY_QUALITY;

#define DEFINE_KSPROPERTY_ITEM_QUALITY_REPORT(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_QUALITY_REPORT,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(KSQUALITY),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_QUALITY_ERROR(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_QUALITY_ERROR,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(KSERROR),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

//===========================================================================

#define STATIC_KSPROPSETID_Connection \
    0x1D58C920L, 0xAC9B, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("1D58C920-AC9B-11CF-A5D6-28DB04C10000", KSPROPSETID_Connection);
#define KSPROPSETID_Connection DEFINE_GUIDNAMED(KSPROPSETID_Connection)

typedef enum {
    KSPROPERTY_CONNECTION_STATE,
    KSPROPERTY_CONNECTION_PRIORITY,
    KSPROPERTY_CONNECTION_DATAFORMAT,
    KSPROPERTY_CONNECTION_ALLOCATORFRAMING,
    KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT,
    KSPROPERTY_CONNECTION_ACQUIREORDERING,
    KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX,
    KSPROPERTY_CONNECTION_STARTAT
} KSPROPERTY_CONNECTION;

#define DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CONNECTION_STATE,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(KSSTATE),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CONNECTION_PRIORITY(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CONNECTION_PRIORITY,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(KSPRIORITY),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CONNECTION_DATAFORMAT,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        0,\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CONNECTION_ALLOCATORFRAMING,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSALLOCATOR_FRAMING),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING_EX(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX,\
        (Handler),\
        sizeof(KSPROPERTY),\
        0,\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CONNECTION_PROPOSEDATAFORMAT(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT,\
        NULL,\
        sizeof(KSPROPERTY),\
        sizeof(KSDATAFORMAT),\
        (Handler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ACQUIREORDERING(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CONNECTION_ACQUIREORDERING,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(int),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CONNECTION_STARTAT(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CONNECTION_STARTAT,\
        NULL,\
        sizeof(KSPROPERTY),\
        sizeof(KSRELATIVEEVENT),\
        (Handler),\
        NULL, 0, NULL, NULL, 0)

//===========================================================================
//VRAM transport related propset
//===========================================================================

#define STATIC_KSPROPSETID_MemoryTransport \
    0xa3d1c5d, 0x5243, 0x4819, 0x9e, 0xd0, 0xae, 0xe8, 0x4, 0x4c, 0xee, 0x2b
DEFINE_GUIDSTRUCT("0A3D1C5D-5243-4819-9ED0-AEE8044CEE2B", KSPROPSETID_MemoryTransport);
#define KSPROPSETID_MemoryTransport DEFINE_GUIDNAMED(KSPROPSETID_MemoryTransport)
enum {
    // a value of zero is ignored
    KSPROPERTY_MEMORY_TRANSPORT = 1 //Sets pin's memory transport mechanism e.g. VRAM or SYSMEM
};

#define DEFINE_KSPROPERTY_ITEM_MEMORY_TRANSPORT(SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_MEMORY_TRANSPORT,\
        NULL,\
        sizeof(KSPROPERTY),\
        sizeof(BOOL),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

//===========================================================================
//
// pins flags
//
#define KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER   0x00000001
#define KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY      0x00000002
#define KSALLOCATOR_REQUIREMENTF_FRAME_INTEGRITY    0x00000004
#define KSALLOCATOR_REQUIREMENTF_MUST_ALLOCATE      0x00000008
#define KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY   0x80000000

#define KSALLOCATOR_OPTIONF_COMPATIBLE              0x00000001
#define KSALLOCATOR_OPTIONF_SYSTEM_MEMORY           0x00000002
#define KSALLOCATOR_OPTIONF_VALID                   0x00000003
// 
// pins extended framing flags
//
#define KSALLOCATOR_FLAG_PARTIAL_READ_SUPPORT       0x00000010
#define KSALLOCATOR_FLAG_DEVICE_SPECIFIC            0x00000020
#define KSALLOCATOR_FLAG_CAN_ALLOCATE               0x00000040
#define KSALLOCATOR_FLAG_INSIST_ON_FRAMESIZE_RATIO  0x00000080
//
// allocator pipes flags
//
// there is at least one data modification in a pipe
#define KSALLOCATOR_FLAG_NO_FRAME_INTEGRITY         0x00000100
#define KSALLOCATOR_FLAG_MULTIPLE_OUTPUT            0x00000200
#define KSALLOCATOR_FLAG_CYCLE                      0x00000400
#define KSALLOCATOR_FLAG_ALLOCATOR_EXISTS           0x00000800
// there is no framing dependency between neighbouring pipes.
#define KSALLOCATOR_FLAG_INDEPENDENT_RANGES         0x00001000
#define KSALLOCATOR_FLAG_ATTENTION_STEPPING         0x00002000


//
// old Framing structure
//
typedef struct {
    union {
        ULONG       OptionsFlags;       // allocator options (create)
        ULONG       RequirementsFlags;  // allocation requirements (query)
    };
#if defined(_NTDDK_)
    POOL_TYPE   PoolType;
#else // !_NTDDK_
    ULONG       PoolType;
#endif // !_NTDDK_
    ULONG       Frames;     // total number of allowable outstanding frames
    ULONG       FrameSize;  // total size of frame
    ULONG       FileAlignment;
    ULONG       Reserved;
} KSALLOCATOR_FRAMING, *PKSALLOCATOR_FRAMING;

#if defined(_NTDDK_)
typedef
PVOID
(*PFNKSDEFAULTALLOCATE)(
    __in PVOID Context
    );

typedef
VOID
(*PFNKSDEFAULTFREE)(
    __in PVOID Context,
    __in PVOID Buffer
    );

typedef
NTSTATUS
(*PFNKSINITIALIZEALLOCATOR)(
    __in PVOID InitialContext,
    __in PKSALLOCATOR_FRAMING AllocatorFraming,
    __deref_out PVOID* Context
    );

typedef
VOID
(*PFNKSDELETEALLOCATOR)(
    __in PVOID Context
    );
#endif // !_NTDDK_

//
// new Framing structure, eventually will replace KSALLOCATOR_FRAMING.
// 
typedef struct {
    ULONG   MinFrameSize;
    ULONG   MaxFrameSize;
    ULONG   Stepping;
} KS_FRAMING_RANGE, *PKS_FRAMING_RANGE;


typedef struct {
    KS_FRAMING_RANGE  Range;
    ULONG             InPlaceWeight;
    ULONG             NotInPlaceWeight;
} KS_FRAMING_RANGE_WEIGHTED, *PKS_FRAMING_RANGE_WEIGHTED;


typedef struct {
    ULONG   RatioNumerator;      // compression/expansion ratio
    ULONG   RatioDenominator; 
    ULONG   RatioConstantMargin;
} KS_COMPRESSION, *PKS_COMPRESSION;


//
// Memory Types and Buses are repeated in each entry.
// Easiest to use but takes a little more memory than the varsize layout Pin\Memories\Buses\Ranges.
//
typedef struct {
    GUID                        MemoryType;
    GUID                        BusType;
    ULONG                       MemoryFlags;
    ULONG                       BusFlags;   
    ULONG                       Flags;   
    ULONG                       Frames;              // total number of allowable outstanding frames
    ULONG                       FileAlignment;
    ULONG                       MemoryTypeWeight;    // this memory type Weight pin-wide
    KS_FRAMING_RANGE            PhysicalRange;
    KS_FRAMING_RANGE_WEIGHTED   FramingRange; 
} KS_FRAMING_ITEM, *PKS_FRAMING_ITEM;


typedef struct {
    ULONG               CountItems;         // count of FramingItem-s below.
    ULONG               PinFlags;
    KS_COMPRESSION      OutputCompression;
    ULONG               PinWeight;          // this pin framing's Weight graph-wide
    KS_FRAMING_ITEM     FramingItem[1]; 
} KSALLOCATOR_FRAMING_EX, *PKSALLOCATOR_FRAMING_EX;



//
// define memory type GUIDs
//
#define KSMEMORY_TYPE_WILDCARD          GUID_NULL
#define STATIC_KSMEMORY_TYPE_WILDCARD   STATIC_GUID_NULL

#define KSMEMORY_TYPE_DONT_CARE         GUID_NULL
#define STATIC_KSMEMORY_TYPE_DONT_CARE  STATIC_GUID_NULL

#define KS_TYPE_DONT_CARE           GUID_NULL
#define STATIC_KS_TYPE_DONT_CARE    STATIC_GUID_NULL
     
#define STATIC_KSMEMORY_TYPE_SYSTEM \
    0x091bb638L, 0x603f, 0x11d1, 0xb0, 0x67, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02
DEFINE_GUIDSTRUCT("091bb638-603f-11d1-b067-00a0c9062802", KSMEMORY_TYPE_SYSTEM);
#define KSMEMORY_TYPE_SYSTEM  DEFINE_GUIDNAMED(KSMEMORY_TYPE_SYSTEM)

#define STATIC_KSMEMORY_TYPE_USER \
    0x8cb0fc28L, 0x7893, 0x11d1, 0xb0, 0x69, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02
DEFINE_GUIDSTRUCT("8cb0fc28-7893-11d1-b069-00a0c9062802", KSMEMORY_TYPE_USER);
#define KSMEMORY_TYPE_USER  DEFINE_GUIDNAMED(KSMEMORY_TYPE_USER)

#define STATIC_KSMEMORY_TYPE_KERNEL_PAGED \
    0xd833f8f8L, 0x7894, 0x11d1, 0xb0, 0x69, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02
DEFINE_GUIDSTRUCT("d833f8f8-7894-11d1-b069-00a0c9062802", KSMEMORY_TYPE_KERNEL_PAGED);
#define KSMEMORY_TYPE_KERNEL_PAGED  DEFINE_GUIDNAMED(KSMEMORY_TYPE_KERNEL_PAGED)

#define STATIC_KSMEMORY_TYPE_KERNEL_NONPAGED \
    0x4a6d5fc4L, 0x7895, 0x11d1, 0xb0, 0x69, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02
DEFINE_GUIDSTRUCT("4a6d5fc4-7895-11d1-b069-00a0c9062802", KSMEMORY_TYPE_KERNEL_NONPAGED);
#define KSMEMORY_TYPE_KERNEL_NONPAGED  DEFINE_GUIDNAMED(KSMEMORY_TYPE_KERNEL_NONPAGED)

// old KS clients did not specify the device memory type
#define STATIC_KSMEMORY_TYPE_DEVICE_UNKNOWN \
    0x091bb639L, 0x603f, 0x11d1, 0xb0, 0x67, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02
DEFINE_GUIDSTRUCT("091bb639-603f-11d1-b067-00a0c9062802", KSMEMORY_TYPE_DEVICE_UNKNOWN);
#define KSMEMORY_TYPE_DEVICE_UNKNOWN DEFINE_GUIDNAMED(KSMEMORY_TYPE_DEVICE_UNKNOWN)

//
// Helper framing macros.
//
#define DECLARE_SIMPLE_FRAMING_EX(FramingExName, MemoryType, Flags, Frames, Alignment, MinFrameSize, MaxFrameSize) \
    const KSALLOCATOR_FRAMING_EX FramingExName = \
    {\
        1, \
        0, \
        {\
            1, \
            1, \
            0 \
        }, \
        0, \
        {\
            {\
                MemoryType, \
                STATIC_KS_TYPE_DONT_CARE, \
                0, \
                0, \
                Flags, \
                Frames, \
                Alignment, \
                0, \
                {\
                    0, \
                    (ULONG)-1, \
                    1 \
                }, \
                {\
                    {\
                        MinFrameSize, \
                        MaxFrameSize, \
                        1 \
                    }, \
                    0, \
                    0  \
                }\
            }\
        }\
    }

#define SetDefaultKsCompression(KsCompressionPointer) \
{\
    KsCompressionPointer->RatioNumerator = 1;\
    KsCompressionPointer->RatioDenominator = 1;\
    KsCompressionPointer->RatioConstantMargin = 0;\
}

#define SetDontCareKsFramingRange(KsFramingRangePointer) \
{\
    KsFramingRangePointer->MinFrameSize = 0;\
    KsFramingRangePointer->MaxFrameSize = (ULONG) -1;\
    KsFramingRangePointer->Stepping = 1;\
}

#define SetKsFramingRange(KsFramingRangePointer, P_MinFrameSize, P_MaxFrameSize) \
{\
    KsFramingRangePointer->MinFrameSize = P_MinFrameSize;\
    KsFramingRangePointer->MaxFrameSize = P_MaxFrameSize;\
    KsFramingRangePointer->Stepping = 1;\
}

#define SetKsFramingRangeWeighted(KsFramingRangeWeightedPointer, P_MinFrameSize, P_MaxFrameSize) \
{\
    KS_FRAMING_RANGE *KsFramingRange = &KsFramingRangeWeightedPointer->Range;\
    SetKsFramingRange(KsFramingRange, P_MinFrameSize, P_MaxFrameSize);\
    KsFramingRangeWeightedPointer->InPlaceWeight = 0;\
    KsFramingRangeWeightedPointer->NotInPlaceWeight = 0;\
}

#define INITIALIZE_SIMPLE_FRAMING_EX(FramingExPointer, P_MemoryType, P_Flags, P_Frames, P_Alignment, P_MinFrameSize, P_MaxFrameSize) \
{\
    KS_COMPRESSION *KsCompression = &FramingExPointer->OutputCompression;\
    KS_FRAMING_RANGE *KsFramingRange = &FramingExPointer->FramingItem[0].PhysicalRange;\
    KS_FRAMING_RANGE_WEIGHTED *KsFramingRangeWeighted = &FramingExPointer->FramingItem[0].FramingRange;\
    FramingExPointer->CountItems = 1;\
    FramingExPointer->PinFlags = 0;\
    SetDefaultKsCompression(KsCompression);\
    FramingExPointer->PinWeight = 0;\
    FramingExPointer->FramingItem[0].MemoryType = P_MemoryType;\
    FramingExPointer->FramingItem[0].BusType = KS_TYPE_DONT_CARE;\
    FramingExPointer->FramingItem[0].MemoryFlags = 0;\
    FramingExPointer->FramingItem[0].BusFlags = 0;\
    FramingExPointer->FramingItem[0].Flags = P_Flags;\
    FramingExPointer->FramingItem[0].Frames = P_Frames;\
    FramingExPointer->FramingItem[0].FileAlignment = P_Alignment;\
    FramingExPointer->FramingItem[0].MemoryTypeWeight = 0;\
    SetDontCareKsFramingRange(KsFramingRange);\
    SetKsFramingRangeWeighted(KsFramingRangeWeighted, P_MinFrameSize, P_MaxFrameSize);\
}



// KSEVENTSETID_StreamAllocator: {75D95571-073C-11d0-A161-0020AFD156E4}

#define STATIC_KSEVENTSETID_StreamAllocator\
    0x75d95571L, 0x073c, 0x11d0, 0xa1, 0x61, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4
DEFINE_GUIDSTRUCT("75d95571-073c-11d0-a161-0020afd156e4", KSEVENTSETID_StreamAllocator);
#define KSEVENTSETID_StreamAllocator DEFINE_GUIDNAMED(KSEVENTSETID_StreamAllocator)

typedef enum {
    KSEVENT_STREAMALLOCATOR_INTERNAL_FREEFRAME,
    KSEVENT_STREAMALLOCATOR_FREEFRAME
} KSEVENT_STREAMALLOCATOR;

#define STATIC_KSMETHODSETID_StreamAllocator\
    0xcf6e4341L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4
DEFINE_GUIDSTRUCT("cf6e4341-ec87-11cf-a130-0020afd156e4", KSMETHODSETID_StreamAllocator);
#define KSMETHODSETID_StreamAllocator DEFINE_GUIDNAMED(KSMETHODSETID_StreamAllocator)

typedef enum {
    KSMETHOD_STREAMALLOCATOR_ALLOC,
    KSMETHOD_STREAMALLOCATOR_FREE
} KSMETHOD_STREAMALLOCATOR;

#define DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_ALLOC(Handler)\
    DEFINE_KSMETHOD_ITEM(\
        KSMETHOD_STREAMALLOCATOR_ALLOC,\
        KSMETHOD_TYPE_WRITE,\
        (Handler),\
        sizeof(KSMETHOD),\
        sizeof(PVOID),\
        NULL)

#define DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_FREE(Handler)\
    DEFINE_KSMETHOD_ITEM(\
        KSMETHOD_STREAMALLOCATOR_FREE,\
        KSMETHOD_TYPE_READ,\
        (Handler),\
        sizeof(KSMETHOD),\
        sizeof(PVOID),\
        NULL)

#define DEFINE_KSMETHOD_ALLOCATORSET(AllocatorSet, MethodAlloc, MethodFree)\
DEFINE_KSMETHOD_TABLE(AllocatorSet) {\
    DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_ALLOC(MethodAlloc),\
    DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_FREE(MethodFree)\
}

#define STATIC_KSPROPSETID_StreamAllocator\
    0xcf6e4342L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4
DEFINE_GUIDSTRUCT("cf6e4342-ec87-11cf-a130-0020afd156e4", KSPROPSETID_StreamAllocator);
#define KSPROPSETID_StreamAllocator DEFINE_GUIDNAMED(KSPROPSETID_StreamAllocator)

#if defined(_NTDDK_)
typedef enum {
    KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE,
    KSPROPERTY_STREAMALLOCATOR_STATUS
} KSPROPERTY_STREAMALLOCATOR;

#define DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_FUNCTIONTABLE(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE),\
        NULL, NULL, 0, NULL, NULL, 0)
        
#define DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_STATUS(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAMALLOCATOR_STATUS,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSSTREAMALLOCATOR_STATUS),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ALLOCATORSET(AllocatorSet, PropFunctionTable, PropStatus)\
DEFINE_KSPROPERTY_TABLE(AllocatorSet) {\
    DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_STATUS(PropStatus),\
    DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_FUNCTIONTABLE(PropFunctionTable)\
}

typedef
NTSTATUS
(*PFNALLOCATOR_ALLOCATEFRAME)(
    __in PFILE_OBJECT FileObject,
    __deref_out PVOID *Frame
    );

typedef
VOID
(*PFNALLOCATOR_FREEFRAME)(
    __in PFILE_OBJECT FileObject,
    __in PVOID Frame
    );

typedef struct {
    PFNALLOCATOR_ALLOCATEFRAME  AllocateFrame;
    PFNALLOCATOR_FREEFRAME      FreeFrame;
} KSSTREAMALLOCATOR_FUNCTIONTABLE, *PKSSTREAMALLOCATOR_FUNCTIONTABLE;
#endif // defined(_NTDDK_)

typedef struct {
    KSALLOCATOR_FRAMING Framing;
    ULONG               AllocatedFrames;
    ULONG               Reserved;
} KSSTREAMALLOCATOR_STATUS, *PKSSTREAMALLOCATOR_STATUS;

typedef struct {
    KSALLOCATOR_FRAMING_EX Framing;
    ULONG                  AllocatedFrames;
    ULONG                  Reserved;
} KSSTREAMALLOCATOR_STATUS_EX, *PKSSTREAMALLOCATOR_STATUS_EX;


#define KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT        0x00000001
#define KSSTREAM_HEADER_OPTIONSF_PREROLL            0x00000002
#define KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY  0x00000004
#define KSSTREAM_HEADER_OPTIONSF_TYPECHANGED        0x00000008
#define KSSTREAM_HEADER_OPTIONSF_TIMEVALID          0x00000010
#define KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY  0x00000040
#define KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE       0x00000080
#define KSSTREAM_HEADER_OPTIONSF_DURATIONVALID      0x00000100
#define KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM        0x00000200
#define KSSTREAM_HEADER_OPTIONSF_BUFFEREDTRANSFER   0x00000400
#define KSSTREAM_HEADER_OPTIONSF_VRAM_DATA_TRANSFER 0x00000800
#define KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA         0x80000000

typedef struct {
    LONGLONG    Time;
    ULONG       Numerator;
    ULONG       Denominator;
} KSTIME, *PKSTIME;

typedef struct {
    ULONG       Size;
    ULONG       TypeSpecificFlags;
    KSTIME      PresentationTime;
    LONGLONG    Duration;
    ULONG       FrameExtent;
    ULONG       DataUsed;
    __field_bcount(FrameExtent)
    PVOID       Data;
    ULONG       OptionsFlags;
#if _WIN64
    ULONG       Reserved;
#endif
} KSSTREAM_HEADER, *PKSSTREAM_HEADER;

#define STATIC_KSPROPSETID_StreamInterface\
    0x1fdd8ee1L, 0x9cd3, 0x11d0, 0x82, 0xaa, 0x00, 0x00, 0xf8, 0x22, 0xfe, 0x8a
DEFINE_GUIDSTRUCT("1fdd8ee1-9cd3-11d0-82aa-0000f822fe8a", KSPROPSETID_StreamInterface);
#define KSPROPSETID_StreamInterface DEFINE_GUIDNAMED(KSPROPSETID_StreamInterface)

typedef enum {
    KSPROPERTY_STREAMINTERFACE_HEADERSIZE
} KSPROPERTY_STREAMINTERFACE;

#define DEFINE_KSPROPERTY_ITEM_STREAMINTERFACE_HEADERSIZE( GetHandler )\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAMINTERFACE_HEADERSIZE,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(ULONG),\
        NULL, NULL, 0, NULL, NULL, 0)
        
#define DEFINE_KSPROPERTY_STREAMINTERFACESET(StreamInterfaceSet,\
    HeaderSizeHandler)\
DEFINE_KSPROPERTY_TABLE(StreamInterfaceSet) {\
    DEFINE_KSPROPERTY_ITEM_STREAMINTERFACE_HEADERSIZE( HeaderSizeHandler )\
}

#define STATIC_KSPROPSETID_Stream\
    0x65aaba60L, 0x98ae, 0x11cf, 0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4
DEFINE_GUIDSTRUCT("65aaba60-98ae-11cf-a10d-0020afd156e4", KSPROPSETID_Stream);
#define KSPROPSETID_Stream DEFINE_GUIDNAMED(KSPROPSETID_Stream)

typedef enum {
    KSPROPERTY_STREAM_ALLOCATOR,
    KSPROPERTY_STREAM_QUALITY,
    KSPROPERTY_STREAM_DEGRADATION,
    KSPROPERTY_STREAM_MASTERCLOCK,
    KSPROPERTY_STREAM_TIMEFORMAT,
    KSPROPERTY_STREAM_PRESENTATIONTIME,
    KSPROPERTY_STREAM_PRESENTATIONEXTENT,
    KSPROPERTY_STREAM_FRAMETIME,
    KSPROPERTY_STREAM_RATECAPABILITY,
    KSPROPERTY_STREAM_RATE,
    KSPROPERTY_STREAM_PIPE_ID
} KSPROPERTY_STREAM;

#define DEFINE_KSPROPERTY_ITEM_STREAM_ALLOCATOR(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_ALLOCATOR,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(HANDLE),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_QUALITY(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_QUALITY,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSQUALITY_MANAGER),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_DEGRADATION(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_DEGRADATION,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        0,\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_MASTERCLOCK(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_MASTERCLOCK,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(HANDLE),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_TIMEFORMAT(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_TIMEFORMAT,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(GUID),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONTIME(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_PRESENTATIONTIME,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(KSTIME),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONEXTENT(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_PRESENTATIONEXTENT,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(LONGLONG),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_FRAMETIME(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_FRAMETIME,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSFRAMETIME),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_RATECAPABILITY(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_RATECAPABILITY,\
        (Handler),\
        sizeof(KSRATE_CAPABILITY),\
        sizeof(KSRATE),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_RATE(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_RATE,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(KSRATE),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_STREAM_PIPE_ID(GetHandler, SetHandler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_STREAM_PIPE_ID,\
        (GetHandler),\
        sizeof(KSPROPERTY),\
        sizeof(HANDLE),\
        (SetHandler),\
        NULL, 0, NULL, NULL, 0)

typedef struct {
    HANDLE      QualityManager;
    PVOID       Context;
} KSQUALITY_MANAGER, *PKSQUALITY_MANAGER;

typedef struct {
    LONGLONG    Duration;
    ULONG       FrameFlags;
    ULONG       Reserved;
} KSFRAMETIME, *PKSFRAMETIME;

#define KSFRAMETIME_VARIABLESIZE    0x00000001

typedef struct {
    LONGLONG        PresentationStart;
    LONGLONG        Duration;
    KSPIN_INTERFACE Interface;
    LONG            Rate;
    ULONG           Flags;
} KSRATE, *PKSRATE;

#define KSRATE_NOPRESENTATIONSTART      0x00000001
#define KSRATE_NOPRESENTATIONDURATION   0x00000002

typedef struct {
    KSPROPERTY      Property;
    KSRATE          Rate;
} KSRATE_CAPABILITY, *PKSRATE_CAPABILITY;

#define STATIC_KSPROPSETID_Clock \
    0xDF12A4C0L, 0xAC17, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("DF12A4C0-AC17-11CF-A5D6-28DB04C10000", KSPROPSETID_Clock);
#define KSPROPSETID_Clock DEFINE_GUIDNAMED(KSPROPSETID_Clock)

//
// Performs a x*y/z operation on 64 bit quantities by splitting the operation. The equation
// is simplified with respect to adding in the remainder for the upper 32 bits.
//
// (xh * 10000000 / Frequency) * 2^32 + ((((xh * 10000000) % Frequency) * 2^32 + (xl * 10000000)) / Frequency)
//
#define NANOSECONDS 10000000
#define KSCONVERT_PERFORMANCE_TIME(Frequency, PerformanceTime) \
    ((((ULONGLONG)(ULONG)(PerformanceTime).HighPart * NANOSECONDS / (Frequency)) << 32) + \
    ((((((ULONGLONG)(ULONG)(PerformanceTime).HighPart * NANOSECONDS) % (Frequency)) << 32) + \
    ((ULONGLONG)(PerformanceTime).LowPart * NANOSECONDS)) / (Frequency)))

typedef struct {
    ULONG       CreateFlags;
} KSCLOCK_CREATE, *PKSCLOCK_CREATE;

typedef struct {
    LONGLONG    Time;
    LONGLONG    SystemTime;
} KSCORRELATED_TIME, *PKSCORRELATED_TIME;

typedef struct {
    LONGLONG    Granularity;
    LONGLONG    Error;
} KSRESOLUTION, *PKSRESOLUTION;

typedef enum {
    KSPROPERTY_CLOCK_TIME,
    KSPROPERTY_CLOCK_PHYSICALTIME,
    KSPROPERTY_CLOCK_CORRELATEDTIME,
    KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME,
    KSPROPERTY_CLOCK_RESOLUTION,
    KSPROPERTY_CLOCK_STATE,
#if defined(_NTDDK_)
    KSPROPERTY_CLOCK_FUNCTIONTABLE
#endif // defined(_NTDDK_)
} KSPROPERTY_CLOCK;

#if defined(_NTDDK_)

__drv_maxIRQL(PASSIVE_LEVEL)
typedef
LONGLONG
(FASTCALL *PFNKSCLOCK_GETTIME)(
    __in PFILE_OBJECT FileObject
    );

__drv_maxIRQL(PASSIVE_LEVEL)
typedef
LONGLONG
(FASTCALL *PFNKSCLOCK_CORRELATEDTIME)(
    __in PFILE_OBJECT FileObject,
    __out PLONGLONG SystemTime);

typedef struct {
    PFNKSCLOCK_GETTIME GetTime;
    PFNKSCLOCK_GETTIME GetPhysicalTime;
    PFNKSCLOCK_CORRELATEDTIME GetCorrelatedTime;
    PFNKSCLOCK_CORRELATEDTIME GetCorrelatedPhysicalTime;
} KSCLOCK_FUNCTIONTABLE, *PKSCLOCK_FUNCTIONTABLE;

#if (NTDDI_VERSION >= NTDDI_WINXP)

__drv_maxIRQL(DISPATCH_LEVEL)
typedef
BOOLEAN
(*PFNKSSETTIMER)(
    __in PVOID Context,
    __in PKTIMER Timer,
    __in LARGE_INTEGER DueTime,
    __in PKDPC Dpc
    );

__drv_maxIRQL(DISPATCH_LEVEL)
typedef
BOOLEAN
(*PFNKSCANCELTIMER)(
    __in PVOID Context,
    __in PKTIMER Timer
    );

typedef
LONGLONG
(FASTCALL *PFNKSCORRELATEDTIME)(
    __in PVOID Context,
    __out  PLONGLONG SystemTime);

#endif // (NTDDI_VERSION >= NTDDI_WINXP)

typedef PVOID   PKSDEFAULTCLOCK;

#define DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CLOCK_TIME,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(LONGLONG),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CLOCK_PHYSICALTIME,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(LONGLONG),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CLOCK_CORRELATEDTIME,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSCORRELATED_TIME),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSCORRELATED_TIME),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CLOCK_RESOLUTION,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSRESOLUTION),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CLOCK_STATE,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSSTATE),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(Handler)\
    DEFINE_KSPROPERTY_ITEM(\
        KSPROPERTY_CLOCK_FUNCTIONTABLE,\
        (Handler),\
        sizeof(KSPROPERTY),\
        sizeof(KSCLOCK_FUNCTIONTABLE),\
        NULL, NULL, 0, NULL, NULL, 0)

#define DEFINE_KSPROPERTY_CLOCKSET(ClockSet,\
    PropTime, PropPhysicalTime,\
    PropCorrelatedTime, PropCorrelatedPhysicalTime,\
    PropResolution, PropState, PropFunctionTable)\
DEFINE_KSPROPERTY_TABLE(ClockSet) {\
    DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(PropTime),\
    DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(PropPhysicalTime),\
    DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(PropCorrelatedTime),\
    DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(PropCorrelatedPhysicalTime),\
    DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(PropResolution),\
    DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(PropState),\
    DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(PropFunctionTable)\
}

#endif // defined(_NTDDK_)

#define STATIC_KSEVENTSETID_Clock \
    0x364D8E20L, 0x62C7, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("364D8E20-62C7-11CF-A5D6-28DB04C10000", KSEVENTSETID_Clock);
#define KSEVENTSETID_Clock DEFINE_GUIDNAMED(KSEVENTSETID_Clock)

typedef enum {
    KSEVENT_CLOCK_INTERVAL_MARK,
    KSEVENT_CLOCK_POSITION_MARK
} KSEVENT_CLOCK_POSITION;

#define STATIC_KSEVENTSETID_Connection\
    0x7f4bcbe0L, 0x9ea5, 0x11cf, 0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00
DEFINE_GUIDSTRUCT("7f4bcbe0-9ea5-11cf-a5d6-28db04c10000", KSEVENTSETID_Connection);
#define KSEVENTSETID_Connection DEFINE_GUIDNAMED(KSEVENTSETID_Connection)

typedef enum {
    KSEVENT_CONNECTION_POSITIONUPDATE,
    KSEVENT_CONNECTION_DATADISCONTINUITY,
    KSEVENT_CONNECTION_TIMEDISCONTINUITY,
    KSEVENT_CONNECTION_PRIORITY,
    KSEVENT_CONNECTION_ENDOFSTREAM
} KSEVENT_CONNECTION;

typedef struct {
    PVOID       Context;
    ULONG       Proportion;
    LONGLONG    DeltaTime;
} KSQUALITY, *PKSQUALITY;

typedef struct {
    PVOID       Context;
    ULONG       Status;
} KSERROR, *PKSERROR;

typedef KSIDENTIFIER KSDEGRADE, *PKSDEGRADE;

#define STATIC_KSDEGRADESETID_Standard\
    0x9F564180L, 0x704C, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
DEFINE_GUIDSTRUCT("9F564180-704C-11D0-A5D6-28DB04C10000", KSDEGRADESETID_Standard);
#define KSDEGRADESETID_Standard DEFINE_GUIDNAMED(KSDEGRADESETID_Standard)

typedef enum {
    KSDEGRADE_STANDARD_SAMPLE,
    KSDEGRADE_STANDARD_QUALITY,
    KSDEGRADE_STANDARD_COMPUTATION,
    KSDEGRADE_STANDARD_SKIP
} KSDEGRADE_STANDARD;

#if defined(_NTDDK_)

#define KSPROBE_STREAMREAD      0x00000000
#define KSPROBE_STREAMWRITE     0x00000001
#define KSPROBE_ALLOCATEMDL     0x00000010
#define KSPROBE_PROBEANDLOCK    0x00000020
#define KSPROBE_SYSTEMADDRESS   0x00000040
#define KSPROBE_MODIFY          0x00000200
#define KSPROBE_STREAMWRITEMODIFY (KSPROBE_MODIFY | KSPROBE_STREAMWRITE)
#define KSPROBE_ALLOWFORMATCHANGE   0x00000080

#define KSSTREAM_READ           KSPROBE_STREAMREAD
#define KSSTREAM_WRITE          KSPROBE_STREAMWRITE
#define KSSTREAM_PAGED_DATA     0x00000000
#define KSSTREAM_NONPAGED_DATA  0x00000100
#define KSSTREAM_SYNCHRONOUS    0x00001000
#define KSSTREAM_FAILUREEXCEPTION 0x00002000

__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSCONTEXT_DISPATCH)(
    __in PVOID Context,
    __in PIRP Irp
    );

__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSHANDLER)(
    __in PIRP Irp,
    __in PKSIDENTIFIER Request,
    __inout PVOID Data
    );

__drv_maxIRQL(PASSIVE_LEVEL)
typedef
BOOLEAN
(*PFNKSFASTHANDLER)(
    __in PFILE_OBJECT FileObject,
    __in_bcount(RequestLength) PKSIDENTIFIER Request,
    __in ULONG RequestLength,
    __inout_bcount(DataLength) PVOID Data,
    __in ULONG DataLength,
    __out PIO_STATUS_BLOCK IoStatus
    );

__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSALLOCATOR)(
    __in PIRP Irp,
    __in ULONG BufferSize,
    __in BOOLEAN InputOperation
    );

typedef struct {
    KSPROPERTY_MEMBERSHEADER    MembersHeader;
    const VOID*                 Members;
} KSPROPERTY_MEMBERSLIST, *PKSPROPERTY_MEMBERSLIST;

typedef struct {
    KSIDENTIFIER                    PropTypeSet;
    ULONG                           MembersListCount;
    __field_ecount(MembersListCount)
    const KSPROPERTY_MEMBERSLIST*   MembersList;
} KSPROPERTY_VALUES, *PKSPROPERTY_VALUES;

#define DEFINE_KSPROPERTY_TABLE(tablename)\
    const KSPROPERTY_ITEM tablename[] =

#define DEFINE_KSPROPERTY_ITEM(PropertyId, GetHandler,\
                               MinProperty,\
                               MinData,\
                               SetHandler,\
                               Values, RelationsCount, Relations, SupportHandler,\
                               SerializedSize)\
{\
    PropertyId, (PFNKSHANDLER)GetHandler, MinProperty, MinData,\
    (PFNKSHANDLER)SetHandler,\
    (PKSPROPERTY_VALUES)Values, RelationsCount, (PKSPROPERTY)Relations,\
    (PFNKSHANDLER)SupportHandler, (ULONG)SerializedSize\
}

typedef struct {
    ULONG                   PropertyId;
    union {
        PFNKSHANDLER            GetPropertyHandler;
        BOOLEAN                 GetSupported;
    };
    ULONG                   MinProperty;
    ULONG                   MinData;
    union {
        PFNKSHANDLER            SetPropertyHandler;
        BOOLEAN                 SetSupported;
    };
    const KSPROPERTY_VALUES*Values;
    ULONG                   RelationsCount;
    __field_ecount(RelationsCount)
    const KSPROPERTY*       Relations;
    PFNKSHANDLER            SupportHandler;
    ULONG                   SerializedSize;
} KSPROPERTY_ITEM, *PKSPROPERTY_ITEM;

#define DEFINE_KSFASTPROPERTY_ITEM(PropertyId, GetHandler, SetHandler)\
{\
    PropertyId, (PFNKSFASTHANDLER)GetHandler, (PFNKSFASTHANDLER)SetHandler, 0\
}

typedef struct {
    ULONG                       PropertyId;
    union {
        PFNKSFASTHANDLER            GetPropertyHandler;
        BOOLEAN                     GetSupported;
    };
    union {
        PFNKSFASTHANDLER            SetPropertyHandler;
        BOOLEAN                     SetSupported;
    };
    ULONG                       Reserved;
} KSFASTPROPERTY_ITEM, *PKSFASTPROPERTY_ITEM;

#define DEFINE_KSPROPERTY_SET(Set,\
                              PropertiesCount,\
                              PropertyItem,\
                              FastIoCount,\
                              FastIoTable)\
{\
    Set,\
    PropertiesCount,\
    PropertyItem,\
    FastIoCount,\
    FastIoTable\
}

#define DEFINE_KSPROPERTY_SET_TABLE(tablename)\
    const KSPROPERTY_SET tablename[] =

typedef struct {
    const GUID*                 Set;
    ULONG                       PropertiesCount;
    __field_ecount(PropertiesCount)
    const KSPROPERTY_ITEM*      PropertyItem;
    ULONG                       FastIoCount;
    const KSFASTPROPERTY_ITEM*  FastIoTable;
} KSPROPERTY_SET, *PKSPROPERTY_SET;

#define DEFINE_KSMETHOD_TABLE(tablename)\
    const KSMETHOD_ITEM tablename[] =

#define DEFINE_KSMETHOD_ITEM(MethodId, Flags,\
                             MethodHandler,\
                             MinMethod, MinData, SupportHandler)\
{\
    MethodId, (PFNKSHANDLER)MethodHandler, MinMethod, MinData,\
    SupportHandler, Flags\
}

typedef struct {
    ULONG                   MethodId;
    union {
        PFNKSHANDLER            MethodHandler;
        BOOLEAN                 MethodSupported;
    };
    ULONG                   MinMethod;
    ULONG                   MinData;
    PFNKSHANDLER            SupportHandler;
    ULONG                   Flags;
} KSMETHOD_ITEM, *PKSMETHOD_ITEM;

#define DEFINE_KSFASTMETHOD_ITEM(MethodId, MethodHandler)\
{\
    MethodId, (PFNKSFASTHANDLER)MethodHandler\
}

typedef struct {
    ULONG                   MethodId;
    union {
        PFNKSFASTHANDLER        MethodHandler;
        BOOLEAN                 MethodSupported;
    };
} KSFASTMETHOD_ITEM, *PKSFASTMETHOD_ITEM;

#define DEFINE_KSMETHOD_SET(Set,\
                            MethodsCount,\
                            MethodItem,\
                            FastIoCount,\
                            FastIoTable)\
{\
    Set,\
    MethodsCount,\
    MethodItem,\
    FastIoCount,\
    FastIoTable\
}

#define DEFINE_KSMETHOD_SET_TABLE(tablename)\
    const KSMETHOD_SET tablename[] =

typedef struct {
    const GUID*             Set;
    ULONG                   MethodsCount;
    __field_ecount(MethodsCount)
    const KSMETHOD_ITEM*    MethodItem;
    ULONG                   FastIoCount;
    __field_ecount(FastIoCount) const KSFASTMETHOD_ITEM*FastIoTable;
} KSMETHOD_SET, *PKSMETHOD_SET;

typedef struct _KSEVENT_ENTRY
KSEVENT_ENTRY, *PKSEVENT_ENTRY;

typedef
NTSTATUS
(*PFNKSADDEVENT)(
    __in PIRP Irp,
    __in PKSEVENTDATA EventData,
    __in struct _KSEVENT_ENTRY* EventEntry
    );

typedef
VOID
(*PFNKSREMOVEEVENT)(
    __in PFILE_OBJECT FileObject,
    __in struct _KSEVENT_ENTRY* EventEntry
    );
    
#define DEFINE_KSEVENT_TABLE(tablename)\
    const KSEVENT_ITEM tablename[] =

#define DEFINE_KSEVENT_ITEM(EventId, DataInput, ExtraEntryData,\
                            AddHandler, RemoveHandler, SupportHandler)\
{\
    EventId,\
    DataInput,\
    ExtraEntryData,\
    AddHandler,\
    RemoveHandler,\
    SupportHandler\
}

typedef struct {
    ULONG               EventId;
    ULONG               DataInput;
    ULONG               ExtraEntryData;
    PFNKSADDEVENT       AddHandler;
    PFNKSREMOVEEVENT    RemoveHandler;
    PFNKSHANDLER        SupportHandler;
} KSEVENT_ITEM, *PKSEVENT_ITEM;

#define DEFINE_KSEVENT_SET(Set,\
                           EventsCount,\
                           EventItem)\
{\
    Set, EventsCount, EventItem\
}

#define DEFINE_KSEVENT_SET_TABLE(tablename)\
    const KSEVENT_SET tablename[] =

typedef struct {
    const GUID*         Set;
    ULONG               EventsCount;
    __field_ecount(EventsCount) const KSEVENT_ITEM* EventItem;
} KSEVENT_SET, *PKSEVENT_SET;

typedef struct {
    KDPC            Dpc;
    ULONG           ReferenceCount;
    KSPIN_LOCK      AccessLock;
} KSDPC_ITEM, *PKSDPC_ITEM;

typedef struct {
    KSDPC_ITEM          DpcItem;
    LIST_ENTRY          BufferList;
} KSBUFFER_ITEM, *PKSBUFFER_ITEM;

#define KSEVENT_ENTRY_DELETED   1
#define KSEVENT_ENTRY_ONESHOT   2
#define KSEVENT_ENTRY_BUFFERED  4

struct _KSEVENT_ENTRY {
    LIST_ENTRY      ListEntry;
    PVOID           Object;
    union {
        PKSDPC_ITEM         DpcItem;
        PKSBUFFER_ITEM      BufferItem;
    };
    PKSEVENTDATA        EventData;
    ULONG               NotificationType;
    const KSEVENT_SET*  EventSet;
    const KSEVENT_ITEM* EventItem;
    PFILE_OBJECT        FileObject;
    ULONG               SemaphoreAdjustment;
    ULONG               Reserved;
    ULONG               Flags;
};

typedef enum {
    KSEVENTS_NONE,
    KSEVENTS_SPINLOCK,
    KSEVENTS_MUTEX,
    KSEVENTS_FMUTEX,
    KSEVENTS_FMUTEXUNSAFE,
    KSEVENTS_INTERRUPT,
    KSEVENTS_ERESOURCE
} KSEVENTS_LOCKTYPE;

#define KSDISPATCH_FASTIO       0x80000000

typedef struct {
    PDRIVER_DISPATCH        Create;
    PVOID                   Context;
    UNICODE_STRING          ObjectClass;
    PSECURITY_DESCRIPTOR    SecurityDescriptor;
    ULONG                   Flags;
} KSOBJECT_CREATE_ITEM, *PKSOBJECT_CREATE_ITEM;

typedef
VOID
(*PFNKSITEMFREECALLBACK)(
    __in PKSOBJECT_CREATE_ITEM CreateItem
    );

#define KSCREATE_ITEM_SECURITYCHANGED       0x00000001
#define KSCREATE_ITEM_WILDCARD              0x00000002
#define KSCREATE_ITEM_NOPARAMETERS          0x00000004
#define KSCREATE_ITEM_FREEONSTOP            0x00000008

#define DEFINE_KSCREATE_DISPATCH_TABLE( tablename )\
    KSOBJECT_CREATE_ITEM tablename[] =

#define DEFINE_KSCREATE_ITEM(DispatchCreate, TypeName, Context)\
{\
    (DispatchCreate),\
    (PVOID)(Context),\
    {\
        sizeof(TypeName) - sizeof(UNICODE_NULL),\
        sizeof(TypeName),\
        (PWCHAR)(TypeName)\
    },\
    NULL, 0\
}

#define DEFINE_KSCREATE_ITEMEX(DispatchCreate, TypeName, Context, Flags)\
{\
    (DispatchCreate),\
    (PVOID)(Context),\
    {\
        sizeof(TypeName) - sizeof(UNICODE_NULL),\
        sizeof(TypeName),\
        (PWCHAR)(TypeName)\
    },\
    NULL, (Flags)\
}

#define DEFINE_KSCREATE_ITEMNULL( DispatchCreate, Context )\
{\
    DispatchCreate,\
    Context,\
    {\
        0,\
        0,\
        NULL,\
    },\
    NULL, 0\
}

typedef struct {
    ULONG                    CreateItemsCount;
    __field_ecount(CreateItemsCount) PKSOBJECT_CREATE_ITEM    CreateItemsList;
} KSOBJECT_CREATE, *PKSOBJECT_CREATE;

typedef struct {
    PDRIVER_DISPATCH        DeviceIoControl;
    PDRIVER_DISPATCH        Read;
    PDRIVER_DISPATCH        Write;
    PDRIVER_DISPATCH        Flush;
    PDRIVER_DISPATCH        Close;
    PDRIVER_DISPATCH        QuerySecurity;
    PDRIVER_DISPATCH        SetSecurity;
    PFAST_IO_DEVICE_CONTROL FastDeviceIoControl;
    PFAST_IO_READ           FastRead;
    PFAST_IO_WRITE          FastWrite;
} KSDISPATCH_TABLE, *PKSDISPATCH_TABLE;

#define DEFINE_KSDISPATCH_TABLE( tablename, DeviceIoControl, Read, Write,\
                                 Flush, Close, QuerySecurity, SetSecurity,\
                                 FastDeviceIoControl, FastRead, FastWrite  )\
    const KSDISPATCH_TABLE tablename = \
    {\
        DeviceIoControl,        \
        Read,                   \
        Write,                  \
        Flush,                  \
        Close,                  \
        QuerySecurity,          \
        SetSecurity,            \
        FastDeviceIoControl,    \
        FastRead,               \
        FastWrite,              \
    }

#define KSCREATE_ITEM_IRP_STORAGE(Irp)      (*(PKSOBJECT_CREATE_ITEM*)&(Irp)->Tail.Overlay.DriverContext[0])
#define KSEVENT_SET_IRP_STORAGE(Irp)        (*(const KSEVENT_SET**)&(Irp)->Tail.Overlay.DriverContext[0])
#define KSEVENT_ITEM_IRP_STORAGE(Irp)       (*(const KSEVENT_ITEM**)&(Irp)->Tail.Overlay.DriverContext[3])
#define KSEVENT_ENTRY_IRP_STORAGE(Irp)      (*(PKSEVENT_ENTRY*)&(Irp)->Tail.Overlay.DriverContext[0])
#define KSMETHOD_SET_IRP_STORAGE(Irp)       (*(const KSMETHOD_SET**)&(Irp)->Tail.Overlay.DriverContext[0])
#define KSMETHOD_ITEM_IRP_STORAGE(Irp)      (*(const KSMETHOD_ITEM**)&(Irp)->Tail.Overlay.DriverContext[3])
#define KSMETHOD_TYPE_IRP_STORAGE(Irp)      (*(ULONG_PTR*)(&(Irp)->Tail.Overlay.DriverContext[2]))
#define KSQUEUE_SPINLOCK_IRP_STORAGE(Irp)   (*(PKSPIN_LOCK*)&(Irp)->Tail.Overlay.DriverContext[1])
#define KSPROPERTY_SET_IRP_STORAGE(Irp)     (*(const KSPROPERTY_SET**)&(Irp)->Tail.Overlay.DriverContext[0])
#define KSPROPERTY_ITEM_IRP_STORAGE(Irp)    (*(const KSPROPERTY_ITEM**)&(Irp)->Tail.Overlay.DriverContext[3])
#define KSPROPERTY_ATTRIBUTES_IRP_STORAGE(Irp) (*(PKSATTRIBUTE_LIST*)&(Irp)->Tail.Overlay.DriverContext[2])

typedef PVOID   KSDEVICE_HEADER, KSOBJECT_HEADER;

typedef enum {
    KsInvokeOnSuccess = 1,
    KsInvokeOnError = 2,
    KsInvokeOnCancel = 4
} KSCOMPLETION_INVOCATION;

typedef enum {
    KsListEntryTail,
    KsListEntryHead
} KSLIST_ENTRY_LOCATION;

typedef enum {
    KsAcquireOnly,
    KsAcquireAndRemove,
    KsAcquireOnlySingleItem,
    KsAcquireAndRemoveOnlySingleItem
} KSIRP_REMOVAL_OPERATION;

typedef enum {
    KsStackCopyToNewLocation,
    KsStackReuseCurrentLocation,
    KsStackUseNewLocation
} KSSTACK_USE;

typedef enum {
    KSTARGET_STATE_DISABLED,
    KSTARGET_STATE_ENABLED
} KSTARGET_STATE;

__drv_maxIRQL(DISPATCH_LEVEL)
typedef
NTSTATUS
(*PFNKSIRPLISTCALLBACK)(
    __in PIRP Irp,
    __in PVOID Context
    );

__drv_maxIRQL(PASSIVE_LEVEL)
typedef 
VOID 
(*PFNREFERENCEDEVICEOBJECT)( 
    __in PVOID Context
    );
    
__drv_maxIRQL(PASSIVE_LEVEL)
typedef 
VOID 
(*PFNDEREFERENCEDEVICEOBJECT)( 
    __in PVOID Context
    );
    
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNQUERYREFERENCESTRING)( 
    __in PVOID Context,
    __inout PWCHAR *String
    );

#define BUS_INTERFACE_REFERENCE_VERSION    0x100
    
typedef struct {
    //
    // Standard interface header
    //
    
    INTERFACE                   Interface;
    
    //
    // Standard bus interfaces
    //
    
    PFNREFERENCEDEVICEOBJECT    ReferenceDeviceObject;
    PFNDEREFERENCEDEVICEOBJECT  DereferenceDeviceObject;
    PFNQUERYREFERENCESTRING     QueryReferenceString;
    
} BUS_INTERFACE_REFERENCE, *PBUS_INTERFACE_REFERENCE;

#define STATIC_REFERENCE_BUS_INTERFACE STATIC_KSMEDIUMSETID_Standard
#define REFERENCE_BUS_INTERFACE KSMEDIUMSETID_Standard

__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNQUERYMEDIUMSLIST)( 
    __in PVOID Context,
    __out ULONG* MediumsCount,
    __out_ecount(MediumsCount) PKSPIN_MEDIUM* MediumList
    );

typedef struct {
    //
    // Standard interface header
    //
    
    INTERFACE                   Interface;
    
    //
    // Interface definition
    //
    
    PFNQUERYMEDIUMSLIST         QueryMediumsList;
    
} BUS_INTERFACE_MEDIUMS, *PBUS_INTERFACE_MEDIUMS;

#define STATIC_GUID_BUS_INTERFACE_MEDIUMS \
    0x4EC35C3EL, 0x201B, 0x11D2, 0x87, 0x45, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUIDSTRUCT("4EC35C3E-201B-11D2-8745-00A0C9223196", GUID_BUS_INTERFACE_MEDIUMS);
#define GUID_BUS_INTERFACE_MEDIUMS DEFINE_GUIDNAMED(GUID_BUS_INTERFACE_MEDIUMS)

#endif // defined(_NTDDK_)

#if !defined( PACK_PRAGMAS_NOT_SUPPORTED )
#include <pshpack1.h>
#endif

typedef struct {
    GUID            PropertySet;
    ULONG           Count;
} KSPROPERTY_SERIALHDR, *PKSPROPERTY_SERIALHDR;

#if !defined( PACK_PRAGMAS_NOT_SUPPORTED )
#include <poppack.h>
#endif

typedef struct {
    KSIDENTIFIER    PropTypeSet;
    ULONG           Id;
    ULONG           PropertyLength;
} KSPROPERTY_SERIAL, *PKSPROPERTY_SERIAL;

#if (NTDDI_VERSION >= NTDDI_WINXP)

#if defined(_NTDDK_)

#define IOCTL_KS_HANDSHAKE             CTL_CODE(FILE_DEVICE_KS, 0x007, METHOD_NEITHER, FILE_ANY_ACCESS)

typedef struct {
    GUID ProtocolId;
    PVOID Argument1;
    PVOID Argument2;
} KSHANDSHAKE, *PKSHANDSHAKE;

typedef struct _KSGATE
KSGATE, *PKSGATE;

struct _KSGATE {
    LONG Count;
    PKSGATE NextGate;
};

#ifndef _NTOS_

__drv_maxIRQL(HIGH_LEVEL)
void __inline
KsGateTurnInputOn(
    __in_opt PKSGATE Gate
    )
{
    while (Gate && (InterlockedIncrement(&Gate->Count) == 1)) {
        Gate = Gate->NextGate;
    }
}

__drv_maxIRQL(HIGH_LEVEL)
void __inline
KsGateTurnInputOff(
    __in_opt PKSGATE Gate
    )
{
    while (Gate && (InterlockedDecrement(&Gate->Count) == 0)) {
        Gate = Gate->NextGate;
    }
}

__drv_maxIRQL(HIGH_LEVEL)
BOOLEAN __inline
KsGateGetStateUnsafe(
    __in PKSGATE Gate
    )
{
    ASSERT(Gate);
    return((BOOLEAN)(Gate->Count > 0));
}

__drv_maxIRQL(HIGH_LEVEL)
BOOLEAN __inline
KsGateCaptureThreshold(
    __in PKSGATE Gate
    )
{
    BOOLEAN captured;

    ASSERT(Gate);

    captured = (BOOLEAN)(InterlockedCompareExchange(&Gate->Count,0,1) == 1);
    
    //
    // If we made a transition, it must be propagated.
    //
    if (captured) {
        KsGateTurnInputOff(Gate->NextGate);
    }

    //
    // We return whatever the state was prior to the compare/exchange.  If
    // the state was on, the state is now off.
    //
    return captured;
}

__drv_maxIRQL(HIGH_LEVEL)
void __inline
KsGateInitialize(
    __in PKSGATE Gate,
    __in LONG InitialCount,
    __in_opt PKSGATE NextGate,
    __in BOOLEAN StateToPropagate // __in BOOLEAN NextGateIsAnOrGate
    )
{
    ASSERT(Gate);
    Gate->Count = InitialCount;
    Gate->NextGate = NextGate;

    if (NextGate) {
        if (InitialCount > 0) {
            if (StateToPropagate) {
                KsGateTurnInputOn(NextGate);
            }
        } else {
            if (! StateToPropagate) {
                KsGateTurnInputOff(NextGate);
            }
        }
    }
}

__drv_maxIRQL(HIGH_LEVEL)
void __inline
KsGateInitializeAnd(
    __in PKSGATE AndGate,
    __in_opt PKSGATE NextOrGate
    )
{
    KsGateInitialize(AndGate,1,NextOrGate,TRUE);
}

__drv_maxIRQL(HIGH_LEVEL)
void __inline
KsGateInitializeOr(
    __in PKSGATE OrGate,
    __in_opt PKSGATE NextAndGate
    )
{
    KsGateInitialize(OrGate,0,NextAndGate,FALSE);
}

__drv_maxIRQL(HIGH_LEVEL) void __inline KsGateAddOnInputToAnd(__in PKSGATE AndGate) { UNREFERENCED_PARAMETER (AndGate); }
__drv_maxIRQL(HIGH_LEVEL) void __inline KsGateAddOffInputToAnd(__in PKSGATE AndGate) { KsGateTurnInputOff(AndGate); }
__drv_maxIRQL(HIGH_LEVEL) void __inline KsGateRemoveOnInputFromAnd(__in PKSGATE AndGate) { UNREFERENCED_PARAMETER (AndGate); }
__drv_maxIRQL(HIGH_LEVEL) void __inline KsGateRemoveOffInputFromAnd(__in PKSGATE AndGate) { KsGateTurnInputOn(AndGate); }

__drv_maxIRQL(HIGH_LEVEL) void __inline KsGateAddOnInputToOr(__in PKSGATE OrGate) { KsGateTurnInputOn(OrGate); }
__drv_maxIRQL(HIGH_LEVEL) void __inline KsGateAddOffInputToOr(__in PKSGATE OrGate) { UNREFERENCED_PARAMETER (OrGate); }
__drv_maxIRQL(HIGH_LEVEL) void __inline KsGateRemoveOnInputFromOr(__in PKSGATE OrGate) { KsGateTurnInputOff(OrGate); }
__drv_maxIRQL(HIGH_LEVEL) void __inline KsGateRemoveOffInputFromOr(__in PKSGATE OrGate) { UNREFERENCED_PARAMETER (OrGate); }

__drv_maxIRQL(HIGH_LEVEL)
void __inline
KsGateTerminateAnd(
    __in PKSGATE AndGate
    )
{
    ASSERT(AndGate);
    if (KsGateGetStateUnsafe(AndGate)) {
        KsGateRemoveOnInputFromOr(AndGate->NextGate);
    } else {
        KsGateRemoveOffInputFromOr(AndGate->NextGate);
    }
}

__drv_maxIRQL(HIGH_LEVEL)
void __inline
KsGateTerminateOr(
    __in PKSGATE OrGate
    )
{
    ASSERT(OrGate);
    if (KsGateGetStateUnsafe(OrGate)) {
        KsGateRemoveOnInputFromAnd(OrGate->NextGate);
    } else {
        KsGateRemoveOffInputFromAnd(OrGate->NextGate);
    }
}

#endif // !_NTOS_

typedef PVOID KSOBJECT_BAG;

__drv_maxIRQL(DISPATCH_LEVEL)
typedef
BOOLEAN
(*PFNKSGENERATEEVENTCALLBACK)(
    __in PVOID Context,
    __in PKSEVENT_ENTRY EventEntry
    );

__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSDEVICECREATE)(
    __in PKSDEVICE Device
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSDEVICEPNPSTART)(
    __in PKSDEVICE Device,
    __in PIRP Irp,
    __in_opt PCM_RESOURCE_LIST TranslatedResourceList,
    __in_opt PCM_RESOURCE_LIST UntranslatedResourceList
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSDEVICE)(
    __in PKSDEVICE Device
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSDEVICEIRP)(
    __in PKSDEVICE Device,
    __in PIRP Irp
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
void
(*PFNKSDEVICEIRPVOID)(
    __in PKSDEVICE Device,
    __in PIRP Irp
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSDEVICEQUERYCAPABILITIES)(
    __in PKSDEVICE Device,
    __in PIRP Irp,
    __inout PDEVICE_CAPABILITIES Capabilities
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSDEVICEQUERYPOWER)(
    __in PKSDEVICE Device,
    __in PIRP Irp,
    __in DEVICE_POWER_STATE DeviceTo,
    __in DEVICE_POWER_STATE DeviceFrom,
    __in SYSTEM_POWER_STATE SystemTo,
    __in SYSTEM_POWER_STATE SystemFrom,
    __in POWER_ACTION Action
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
void
(*PFNKSDEVICESETPOWER)(
    __in PKSDEVICE Device,
    __in PIRP Irp,
    __in DEVICE_POWER_STATE To,
    __in DEVICE_POWER_STATE From
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSFILTERFACTORYVOID)(
    __in PKSFILTERFACTORY FilterFactory
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
void
(*PFNKSFILTERFACTORYPOWER)(
    __in PKSFILTERFACTORY FilterFactory,
    __in DEVICE_POWER_STATE State
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSFILTERIRP)(
    __in PKSFILTER Filter,
    __in PIRP Irp
    );
typedef
NTSTATUS
(*PFNKSFILTERPROCESS)(
    __in PKSFILTER Filter,
    __in PKSPROCESSPIN_INDEXENTRY Index
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSFILTERVOID)(
    __in PKSFILTER Filter
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
void
(*PFNKSFILTERPOWER)(
    __in PKSFILTER Filter,
    __in DEVICE_POWER_STATE State
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSPINIRP)(
    __in PKSPIN Pin,
    __in PIRP Irp
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSPINSETDEVICESTATE)(
    __in PKSPIN Pin,
    __in KSSTATE ToState,
    __in KSSTATE FromState
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSPINSETDATAFORMAT)(
    __in PKSPIN Pin,
    __in_opt PKSDATAFORMAT OldFormat,
    __in_opt PKSMULTIPLE_ITEM OldAttributeList,
    __in const KSDATARANGE* DataRange,
    __in_opt const KSATTRIBUTE_LIST* AttributeRange
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSPINHANDSHAKE)(
    __in PKSPIN Pin,
    __in PKSHANDSHAKE In,
    __in PKSHANDSHAKE Out
    );
typedef
NTSTATUS
(*PFNKSPIN)(
    __in PKSPIN Pin
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
void
(*PFNKSPINVOID)(
    __in PKSPIN Pin
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
void
(*PFNKSPINPOWER)(
    __in PKSPIN Pin,
    __in DEVICE_POWER_STATE State
    );
__drv_maxIRQL(DISPATCH_LEVEL)
typedef
BOOLEAN
(*PFNKSPINSETTIMER)(
    __in PKSPIN Pin,
    __in PKTIMER Timer,
    __in LARGE_INTEGER DueTime,
    __in PKDPC Dpc
    );
__drv_maxIRQL(DISPATCH_LEVEL)
typedef
BOOLEAN
(*PFNKSPINCANCELTIMER)(
    __in PKSPIN Pin,
    __in PKTIMER Timer
    );
__drv_maxIRQL(DISPATCH_LEVEL)
typedef
LONGLONG
(FASTCALL *PFNKSPINCORRELATEDTIME)(
    __in PKSPIN Pin,
    __out PLONGLONG SystemTime
    );
__drv_maxIRQL(DISPATCH_LEVEL)
typedef
void
(*PFNKSPINRESOLUTION)(
    __in PKSPIN Pin,
    __out PKSRESOLUTION Resolution
    );
__drv_maxIRQL(PASSIVE_LEVEL)
typedef
NTSTATUS
(*PFNKSPININITIALIZEALLOCATOR)(
    __in PKSPIN Pin,
    __in PKSALLOCATOR_FRAMING AllocatorFraming,
    __out PVOID* Context
    );
__drv_maxIRQL(DISPATCH_LEVEL)
typedef
void
(*PFNKSSTREAMPOINTER)(
    __in PKSSTREAM_POINTER StreamPointer
    );

typedef struct KSAUTOMATION_TABLE_ 
KSAUTOMATION_TABLE, *PKSAUTOMATION_TABLE;
struct KSAUTOMATION_TABLE_ {
    ULONG PropertySetsCount;
    ULONG PropertyItemSize;
    __field_bcount(PropertySetsCount * PropertyItemSize) const KSPROPERTY_SET* PropertySets;
    ULONG MethodSetsCount;
    ULONG MethodItemSize;
    __field_bcount(MethodSetsCount * MethodItemSize) const KSMETHOD_SET* MethodSets;
    ULONG EventSetsCount;
    ULONG EventItemSize;
    __field_bcount(EventSetsCount * EventItemSize) const KSEVENT_SET* EventSets;
#if !defined(_WIN64)
    PVOID Alignment;
#endif // !defined(_WIN64)
};

#define DEFINE_KSAUTOMATION_TABLE(table)\
    const KSAUTOMATION_TABLE table =

#define DEFINE_KSAUTOMATION_PROPERTIES(table)\
    SIZEOF_ARRAY(table),\
    sizeof(KSPROPERTY_ITEM),\
    table

#define DEFINE_KSAUTOMATION_METHODS(table)\
    SIZEOF_ARRAY(table),\
    sizeof(KSMETHOD_ITEM),\
    table

#define DEFINE_KSAUTOMATION_EVENTS(table)\
    SIZEOF_ARRAY(table),\
    sizeof(KSEVENT_ITEM),\
    table

#define DEFINE_KSAUTOMATION_PROPERTIES_NULL\
    0,\
    sizeof(KSPROPERTY_ITEM),\
    NULL

#define DEFINE_KSAUTOMATION_METHODS_NULL\
    0,\
    sizeof(KSMETHOD_ITEM),\
    NULL

#define DEFINE_KSAUTOMATION_EVENTS_NULL\
    0,\
    sizeof(KSEVENT_ITEM),\
    NULL

#define MIN_DEV_VER_FOR_QI (0x100)

struct _KSDEVICE_DISPATCH {
    PFNKSDEVICECREATE Add;
    PFNKSDEVICEPNPSTART Start;
    PFNKSDEVICE PostStart;
    PFNKSDEVICEIRP QueryStop;
    PFNKSDEVICEIRPVOID CancelStop;
    PFNKSDEVICEIRPVOID Stop;
    PFNKSDEVICEIRP QueryRemove;
    PFNKSDEVICEIRPVOID CancelRemove;
    PFNKSDEVICEIRPVOID Remove;
    PFNKSDEVICEQUERYCAPABILITIES QueryCapabilities;
    PFNKSDEVICEIRPVOID SurpriseRemoval;
    PFNKSDEVICEQUERYPOWER QueryPower;
    PFNKSDEVICESETPOWER SetPower;
    PFNKSDEVICEIRP QueryInterface;  // added in version 0x100
};

struct _KSFILTER_DISPATCH {
    PFNKSFILTERIRP Create;
    PFNKSFILTERIRP Close;
    PFNKSFILTERPROCESS Process;
    PFNKSFILTERVOID Reset;
};

struct _KSPIN_DISPATCH {
    PFNKSPINIRP Create;
    PFNKSPINIRP Close;
    PFNKSPIN Process;
    PFNKSPINVOID Reset;
    PFNKSPINSETDATAFORMAT SetDataFormat;
    PFNKSPINSETDEVICESTATE SetDeviceState;
    PFNKSPIN Connect;
    PFNKSPINVOID Disconnect;
    const KSCLOCK_DISPATCH* Clock;
    const KSALLOCATOR_DISPATCH* Allocator;
};

struct _KSCLOCK_DISPATCH {
    PFNKSPINSETTIMER SetTimer;
    PFNKSPINCANCELTIMER CancelTimer;
    PFNKSPINCORRELATEDTIME CorrelatedTime;
    PFNKSPINRESOLUTION Resolution;
};

struct _KSALLOCATOR_DISPATCH {
    PFNKSPININITIALIZEALLOCATOR InitializeAllocator;
    PFNKSDELETEALLOCATOR DeleteAllocator;
    PFNKSDEFAULTALLOCATE Allocate;
    PFNKSDEFAULTFREE Free;
};

//
// VERSION indicates support of the following:
//
//     - QueryInterface dispatch of KSDEVICE_DISPATCH
//
#define KSDEVICE_DESCRIPTOR_VERSION (0x100)

#if (NTDDI_VERSION >= NTDDI_VISTA)

//
// VERSION_2 indicates support of the following:
//
//     - Flags field of KSDEVICE_DESCRIPTOR
//           - Loading a VERSION_2 descriptor on earlier versions of AVStream
//             will work; however, all flags will be considered to be zero.
//           - Using an earlier version descriptor on later versions of
//             AVStream causes no flags to be specificed.
//
#define KSDEVICE_DESCRIPTOR_VERSION_2 (0x110)

#define MIN_DEV_VER_FOR_FLAGS (0x110)

#endif // (NTDDI_VERSION >= NTDDI_VISTA)

struct _KSDEVICE_DESCRIPTOR {
    const KSDEVICE_DISPATCH* Dispatch;
    ULONG FilterDescriptorsCount;
    __field_ecount(FilterDescriptorsCount) const KSFILTER_DESCRIPTOR*const* FilterDescriptors;
    ULONG Version; // this is 0 for pre-version 100 driver

#if (NTDDI_VERSION >= NTDDI_VISTA)

    ULONG Flags; 
#define KSDEVICE_FLAG_ENABLE_REMOTE_WAKEUP	0x00000001
#define KSDEVICE_FLAG_LOWPOWER_PASSTHROUGH 	0x00000002

#if !defined(_WIN64)
    PVOID Alignment;
#endif //!defined(_WIN64)

#endif // (NTDDI_VERSION >= NTDDI_VISTA)

};

struct _KSFILTER_DESCRIPTOR {
    const KSFILTER_DISPATCH* Dispatch;
    const KSAUTOMATION_TABLE* AutomationTable;
    ULONG Version;
#define KSFILTER_DESCRIPTOR_VERSION ((ULONG)-1)
    ULONG Flags;
#define KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING 0x00000001
#define KSFILTER_FLAG_CRITICAL_PROCESSING 0x00000002
#define KSFILTER_FLAG_HYPERCRITICAL_PROCESSING 0x00000004
#define KSFILTER_FLAG_RECEIVE_ZERO_LENGTH_SAMPLES 0x00000008
#if (NTDDI_VERSION >= NTDDI_WINXPSP2)
#define KSFILTER_FLAG_DENY_USERMODE_ACCESS 0x80000000
#endif // (NTDDI_VERSION >= NTDDI_WINXPSP2)
    const GUID* ReferenceGuid;
    ULONG PinDescriptorsCount;
    ULONG PinDescriptorSize;
    __field_bcount(PinDescriptorsCount * PinDescriptorSize) const KSPIN_DESCRIPTOR_EX* PinDescriptors;
    ULONG CategoriesCount;
    __field_ecount(CategoriesCount)
    const GUID* Categories;
    ULONG NodeDescriptorsCount;
    ULONG NodeDescriptorSize;
    __field_bcount(NodeDescriptorsCount * NodeDescriptorSize) const KSNODE_DESCRIPTOR* NodeDescriptors;
    ULONG ConnectionsCount;
    __field_ecount(ConnectionsCount) const KSTOPOLOGY_CONNECTION* Connections;
    const KSCOMPONENTID* ComponentId;
};

#define DEFINE_KSFILTER_DESCRIPTOR(descriptor)\
    const KSFILTER_DESCRIPTOR descriptor =

#define DEFINE_KSFILTER_PIN_DESCRIPTORS(table)\
    SIZEOF_ARRAY(table),\
    sizeof(table[0]),\
    table

#define DEFINE_KSFILTER_CATEGORIES(table)\
    SIZEOF_ARRAY(table),\
    table

#define DEFINE_KSFILTER_CATEGORY(category)\
    1,\
    &(category)

#define DEFINE_KSFILTER_CATEGORIES_NULL\
    0,\
    NULL

#define DEFINE_KSFILTER_NODE_DESCRIPTORS(table)\
    SIZEOF_ARRAY(table),\
    sizeof(table[0]),\
    table

#define DEFINE_KSFILTER_NODE_DESCRIPTORS_NULL\
    0,\
    sizeof(KSNODE_DESCRIPTOR),\
    NULL

#define DEFINE_KSFILTER_CONNECTIONS(table)\
    SIZEOF_ARRAY(table),\
    table

#define DEFINE_KSFILTER_DEFAULT_CONNECTIONS\
    0,\
    NULL

#define DEFINE_KSFILTER_DESCRIPTOR_TABLE(table)\
    const KSFILTER_DESCRIPTOR*const table[] =

struct _KSPIN_DESCRIPTOR_EX {
    const KSPIN_DISPATCH* Dispatch;
    const KSAUTOMATION_TABLE* AutomationTable;
    KSPIN_DESCRIPTOR PinDescriptor;
    ULONG Flags;
#define KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING
#define KSPIN_FLAG_CRITICAL_PROCESSING KSFILTER_FLAG_CRITICAL_PROCESSING
#define KSPIN_FLAG_HYPERCRITICAL_PROCESSING KSFILTER_FLAG_HYPERCRITICAL_PROCESSING
#define KSPIN_FLAG_ASYNCHRONOUS_PROCESSING 0x00000008
#define KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING 0x00000010
#define KSPIN_FLAG_INITIATE_PROCESSING_ON_EVERY_ARRIVAL 0x00000020
#define KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING 0x00000040
#define KSPIN_FLAG_ENFORCE_FIFO 0x00000080

#define KSPIN_FLAG_GENERATE_MAPPINGS 0x00000100
#define KSPIN_FLAG_DISTINCT_TRAILING_EDGE 0x00000200

#define KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY 0x00010000
#define KSPIN_FLAG_SPLITTER 0x00020000
#define KSPIN_FLAG_USE_STANDARD_TRANSPORT 0x00040000
#define KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT 0x00080000
#define KSPIN_FLAG_FIXED_FORMAT 0x00100000
#define KSPIN_FLAG_GENERATE_EOS_EVENTS 0x00200000
#define KSPIN_FLAG_RENDERER (KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY|KSPIN_FLAG_GENERATE_EOS_EVENTS)
#define KSPIN_FLAG_IMPLEMENT_CLOCK 0x00400000
#define KSPIN_FLAG_SOME_FRAMES_REQUIRED_FOR_PROCESSING 0x00800000
#define KSPIN_FLAG_PROCESS_IF_ANY_IN_RUN_STATE 0x01000000
#if (NTDDI_VERSION >= NTDDI_WINXPSP2)
#define KSPIN_FLAG_DENY_USERMODE_ACCESS 0x80000000
#endif // (NTDDI_VERSION >= NTDDI_WINXPSP2)
    ULONG InstancesPossible;
    ULONG InstancesNecessary;
    const KSALLOCATOR_FRAMING_EX* AllocatorFraming;
    PFNKSINTERSECTHANDLEREX IntersectHandler;
};

#define DEFINE_KSPIN_DEFAULT_INTERFACES\
    0,\
    NULL

#define DEFINE_KSPIN_DEFAULT_MEDIUMS\
    0,\
    NULL

struct _KSNODE_DESCRIPTOR {
    const KSAUTOMATION_TABLE* AutomationTable;
    const GUID* Type;
    const GUID* Name;
#if !defined(_WIN64)
    PVOID Alignment;
#endif // !defined(_WIN64)
};

#if !defined(_WIN64)
#define DEFINE_NODE_DESCRIPTOR(automation,type,name) \
    { (automation), (type), (name), NULL }
#else // !defined(_WIN64)
#define DEFINE_NODE_DESCRIPTOR(automation,type,name) \
    { (automation), (type), (name) }
#endif // !defined(_WIN64)

struct _KSDEVICE {
    const KSDEVICE_DESCRIPTOR* Descriptor;
    KSOBJECT_BAG Bag;
    PVOID Context;
    PDEVICE_OBJECT FunctionalDeviceObject;
    PDEVICE_OBJECT PhysicalDeviceObject;
    PDEVICE_OBJECT NextDeviceObject;
    BOOLEAN Started;
    SYSTEM_POWER_STATE SystemPowerState;
    DEVICE_POWER_STATE DevicePowerState;
};

struct _KSFILTERFACTORY {
    const KSFILTER_DESCRIPTOR* FilterDescriptor;
    KSOBJECT_BAG Bag;
    PVOID Context;
};

struct _KSFILTER {
    const KSFILTER_DESCRIPTOR* Descriptor;
    KSOBJECT_BAG Bag;
    PVOID Context;
};

struct _KSPIN {
    const KSPIN_DESCRIPTOR_EX* Descriptor;
    KSOBJECT_BAG Bag;
    PVOID Context;
    ULONG Id;
    KSPIN_COMMUNICATION Communication;
    BOOLEAN ConnectionIsExternal;
    KSPIN_INTERFACE ConnectionInterface;
    KSPIN_MEDIUM ConnectionMedium;
    KSPRIORITY ConnectionPriority;
    PKSDATAFORMAT ConnectionFormat;
    PKSMULTIPLE_ITEM AttributeList;
    ULONG StreamHeaderSize;
    KSPIN_DATAFLOW DataFlow;
    KSSTATE DeviceState;
    KSRESET ResetState;
    KSSTATE ClientState;
};

struct _KSMAPPING {
    PHYSICAL_ADDRESS PhysicalAddress;
    ULONG ByteCount;
    ULONG Alignment;
};

struct _KSSTREAM_POINTER_OFFSET
{
#if defined(_NTDDK_)
    union {
        PUCHAR Data;
        PKSMAPPING Mappings;
    };
#else // !defined(_NTDDK_)
    PUCHAR Data;
#endif // !defined(_NTDDK_)
#if !defined(_WIN64)
    PVOID Alignment;
#endif // !defined(_WIN64)
    ULONG Count;
    ULONG Remaining;
};

struct _KSSTREAM_POINTER
{
    PVOID Context;
    PKSPIN Pin;
    PKSSTREAM_HEADER StreamHeader;
    PKSSTREAM_POINTER_OFFSET Offset;
    KSSTREAM_POINTER_OFFSET OffsetIn;
    KSSTREAM_POINTER_OFFSET OffsetOut;
};

struct _KSPROCESSPIN {
    PKSPIN Pin;
    PKSSTREAM_POINTER StreamPointer;
    PKSPROCESSPIN InPlaceCounterpart;
    PKSPROCESSPIN DelegateBranch;
    PKSPROCESSPIN CopySource;
    __field_bcount(BytesAvailable) PVOID Data;
    ULONG BytesAvailable;
    ULONG BytesUsed;
    ULONG Flags;
    BOOLEAN Terminate;
};

struct _KSPROCESSPIN_INDEXENTRY {
    __field_ecount(Count) PKSPROCESSPIN *Pins;
    ULONG Count;
};

typedef enum {
    KsObjectTypeDevice,
    KsObjectTypeFilterFactory,
    KsObjectTypeFilter,
    KsObjectTypePin
} KSOBJECTTYPE;

typedef
void
(*PFNKSFREE)(
    __in PVOID Data
    );

typedef
void
(*PFNKSPINFRAMERETURN)(
    __in PKSPIN Pin,
    __in_bcount_opt(Size) PVOID Data,
    __in ULONG Size OPTIONAL,
    __in_opt PMDL Mdl,
    __in_opt PVOID Context,
    __in NTSTATUS Status
    );

__drv_maxIRQL(DISPATCH_LEVEL)
typedef
void
(*PFNKSPINIRPCOMPLETION)(
    __in PKSPIN Pin,
    __in PIRP Irp
    );

#if defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__)
#if !defined(_IKsControl_)
#define _IKsControl_

typedef interface IKsControl* PIKSCONTROL;

#if !defined(DEFINE_ABSTRACT_UNKNOWN)

#define DEFINE_ABSTRACT_UNKNOWN()                               \
    STDMETHOD_(NTSTATUS, QueryInterface)(THIS_                   \
        __in REFIID InterfaceId,                                     \
        __deref_out PVOID* Interface                                        \
        ) PURE;                                                 \
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;                        \
    STDMETHOD_(ULONG,Release)(THIS) PURE;

#endif //!defined(DEFINE_ABSTRACT_UNKNOWN)

#undef INTERFACE
#define INTERFACE IKsControl
DECLARE_INTERFACE_(IKsControl,IUnknown)
{
    DEFINE_ABSTRACT_UNKNOWN() // For C

    STDMETHOD_(NTSTATUS, KsProperty)(THIS_
        __in_bcount(PropertyLength) PKSPROPERTY Property,
        __in ULONG PropertyLength,
        __inout_bcount(DataLength) PVOID PropertyData,
        __in ULONG DataLength,
        __out ULONG* BytesReturned
        ) PURE;
    STDMETHOD_(NTSTATUS, KsMethod)(THIS_
        __in_bcount(MethodLength) PKSMETHOD Method,
        __in ULONG MethodLength,
        __inout_bcount(DataLength) PVOID MethodData,
        __in ULONG DataLength,
        __out ULONG* BytesReturned
        ) PURE;
    STDMETHOD_(NTSTATUS, KsEvent)(THIS_
        __in_bcount_opt(EventLength) PKSEVENT Event,
        __in ULONG EventLength,
        __inout_bcount(DataLength) PVOID EventData,
        __in ULONG DataLength,
        __out ULONG* BytesReturned
        ) PURE;
};

typedef interface IKsReferenceClock* PIKSREFERENCECLOCK;

#undef INTERFACE
#define INTERFACE IKsReferenceClock
DECLARE_INTERFACE_(IKsReferenceClock,IUnknown)
{
    DEFINE_ABSTRACT_UNKNOWN() // For C

    STDMETHOD_(LONGLONG,GetTime)(THIS
        ) PURE;
    STDMETHOD_(LONGLONG,GetPhysicalTime)(THIS
        ) PURE;
    STDMETHOD_(LONGLONG,GetCorrelatedTime)(THIS_
        __out PLONGLONG SystemTime
        ) PURE;
    STDMETHOD_(LONGLONG,GetCorrelatedPhysicalTime)(THIS_
        __out PLONGLONG SystemTime
        ) PURE;
    STDMETHOD_(NTSTATUS, GetResolution)(THIS_
        __out PKSRESOLUTION Resolution
        ) PURE;
    STDMETHOD_(NTSTATUS, GetState)(THIS_
        __out PKSSTATE State
        ) PURE;
};
#undef INTERFACE

#if (NTDDI_VERSION >= NTDDI_WS03SP1)

#define INTERFACE IKsDeviceFunctions
DECLARE_INTERFACE_(IKsDeviceFunctions, IUnknown)
{
    DEFINE_ABSTRACT_UNKNOWN() // For C
    
    STDMETHOD_(NTSTATUS, RegisterAdapterObjectEx)(THIS_
        __in PADAPTER_OBJECT AdapterObject,
        __in PDEVICE_DESCRIPTION DeviceDescription,
        __in ULONG NumberOfMapRegisters,
        __in ULONG MaxMappingsByteCount,
        __in ULONG MappingTableStride
        ) PURE;
};

#undef INTERFACE

#endif // (NTDDI_VERSION >= NTDDI_WS03SP1)

#define STATIC_IID_IKsControl \
0x28F54685L, 0x06FD, 0x11D2, 0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
DEFINE_GUID(IID_IKsControl,
0x28F54685L, 0x06FD, 0x11D2, 0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96);
#if defined(__cplusplus) && _MSC_VER >= 1100
struct __declspec(uuid("28F54685-06FD-11D2-B27A-00A0C9223196")) IKsControl;
#endif

#define STATIC_IID_IKsFastClock \
0xc9902485, 0xc180, 0x11d2, 0x84, 0x73, 0xd4, 0x23, 0x94, 0x45, 0x9e, 0x5e
DEFINE_GUID(IID_IKsFastClock,
0xc9902485, 0xc180, 0x11d2, 0x84, 0x73, 0xd4, 0x23, 0x94, 0x45, 0x9e, 0x5e);
#if defined(__cplusplus) && _MSC_VER >= 1100
struct __declspec(uuid("C9902485-C180-11d2-8473-D42394459E5E")) IKsFastClock;
#endif

#if (NTDDI_VERSION >= NTDDI_WS03SP1)

#define STATIC_IID_IKsDeviceFunctions \
0xe234f2e2, 0xbd69, 0x4f8c, 0xb3, 0xf2, 0x7c, 0xd7, 0x9e, 0xd4, 0x66, 0xbd
DEFINE_GUID(IID_IKsDeviceFunctions,
0xe234f2e2, 0xbd69, 0x4f8c, 0xb3, 0xf2, 0x7c, 0xd7, 0x9e, 0xd4, 0x66, 0xbd);
#if defined(__cplusplus) && _MSC_VER >= 1100
struct __declspec(uuid("E234F2E2-BD69-4F8C-B3F2-7CD79ED466BD")) IKsDeviceFunctions;
#endif

#endif // (NTDDI_VERSION >= NTDDI_WS03SP1)

#endif // !defined(_IKsControl_)
#endif // defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__)

#endif // defined(_NTDDK_)

#endif // (NTDDI_VERSION >= NTDDI_WINXP)

//===========================================================================

#if defined(__cplusplus)
extern "C" {
#endif // defined(__cplusplus)

//
// exported prototypes
//

#ifdef _KSDDK_
#define KSDDKAPI
#else // !_KSDDK_
#define KSDDKAPI DECLSPEC_IMPORT
#endif // _KSDDK_

#if defined(_NTDDK_)

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsEnableEvent(
    __in PIRP Irp,
    __in ULONG EventSetsCount,
    __in_ecount(EventSetsCount) const KSEVENT_SET* EventSet,
    __inout_opt PLIST_ENTRY EventsList,
    __in_opt KSEVENTS_LOCKTYPE EventsFlags,
    __in_opt PVOID EventsLock
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsEnableEventWithAllocator(
    __in PIRP Irp,
    __in ULONG EventSetsCount,
    __in_ecount(EventSetsCount) const KSEVENT_SET* EventSet,
    __inout_opt PLIST_ENTRY EventsList,
    __in KSEVENTS_LOCKTYPE EventsFlags OPTIONAL,
    __in_opt PVOID EventsLock,
    __in_opt PFNKSALLOCATOR Allocator,
    __in_opt ULONG EventItemSize
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsDisableEvent(
    __in PIRP Irp,
    __inout PLIST_ENTRY EventsList,
    __in KSEVENTS_LOCKTYPE EventsFlags,
    __in PVOID EventsLock
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsDiscardEvent(
    __in PKSEVENT_ENTRY EventEntry
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsFreeEventList(
    __in PFILE_OBJECT FileObject,
    __inout PLIST_ENTRY EventsList,
    __in KSEVENTS_LOCKTYPE EventsFlags,
    __in PVOID EventsLock
    );

KSDDKAPI
NTSTATUS
NTAPI
KsGenerateEvent(
    __in PKSEVENT_ENTRY EventEntry
    );

KSDDKAPI
NTSTATUS
NTAPI
KsGenerateDataEvent(
    __in PKSEVENT_ENTRY EventEntry,
    __in ULONG DataSize,
    __in_bcount(DataSize) PVOID Data
    );

KSDDKAPI
VOID
NTAPI
KsGenerateEventList(
    __in_opt GUID* Set,
    __in ULONG EventId,
    __in PLIST_ENTRY EventsList,
    __in KSEVENTS_LOCKTYPE EventsFlags,
    __in PVOID EventsLock
    );

// property.c:

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPropertyHandler(
    __in PIRP Irp,
    __in ULONG PropertySetsCount,
    __in_ecount(PropertySetsCount) const KSPROPERTY_SET* PropertySet
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPropertyHandlerWithAllocator(
    __in PIRP Irp,
    __in ULONG PropertySetsCount,
    __in_ecount(PropertySetsCount) const KSPROPERTY_SET* PropertySet,
    __in_opt PFNKSALLOCATOR Allocator,
    __in ULONG PropertyItemSize OPTIONAL
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
BOOLEAN
NTAPI
KsFastPropertyHandler(
    __in PFILE_OBJECT FileObject,
    __in_bcount(PropertyLength) PKSPROPERTY Property,
    __in ULONG PropertyLength,
    __in_bcount(DataLength)PVOID Data,
    __in ULONG DataLength,
    __out PIO_STATUS_BLOCK IoStatus,
    __in ULONG PropertySetsCount,
    __in_ecount(PropertySetsCount) const KSPROPERTY_SET* PropertySet
    );

// method.c:

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsMethodHandler(
    __in PIRP Irp,
    __in ULONG MethodSetsCount,
    __in_ecount(MethodSetsCount) const KSMETHOD_SET* MethodSet
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsMethodHandlerWithAllocator(
    __in PIRP Irp,
    __in ULONG MethodSetsCount,
    __in_ecount(MethodSetsCount) const KSMETHOD_SET* MethodSet,
    __in_opt PFNKSALLOCATOR Allocator,
    __in ULONG MethodItemSize OPTIONAL
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
BOOLEAN
NTAPI
KsFastMethodHandler(
    __in PFILE_OBJECT FileObject,
    __in_bcount(MethodLength) PKSMETHOD Method,
    __in ULONG MethodLength,
    __inout_bcount(DataLength) PVOID Data,
    __in ULONG DataLength,
    __out PIO_STATUS_BLOCK IoStatus,
    __in ULONG MethodSetsCount,
    __in_ecount(MethodSetsCount) const KSMETHOD_SET* MethodSet
    );

// alloc.c:

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreateDefaultAllocator(
    __in PIRP Irp
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreateDefaultAllocatorEx(
    __in PIRP Irp,
    __in_opt PVOID InitializeContext,
    __in_opt PFNKSDEFAULTALLOCATE DefaultAllocate,
    __in_opt PFNKSDEFAULTFREE DefaultFree,
    __in_opt PFNKSINITIALIZEALLOCATOR InitializeAllocator,
    __in_opt PFNKSDELETEALLOCATOR DeleteAllocator
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreateAllocator(
    __in HANDLE ConnectionHandle,
    __in PKSALLOCATOR_FRAMING AllocatorFraming,
    __out PHANDLE AllocatorHandle
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsValidateAllocatorCreateRequest(
    __in PIRP Irp,
    __out PKSALLOCATOR_FRAMING* AllocatorFraming
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsValidateAllocatorFramingEx(
    __in PKSALLOCATOR_FRAMING_EX Framing,
    __in ULONG BufferSize,
    __in const KSALLOCATOR_FRAMING_EX *PinFraming
    );

// clock.c:

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAllocateDefaultClock(
    __out PKSDEFAULTCLOCK* DefaultClock
    );

#if (NTDDI_VERSION >= NTDDI_WINXP)

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAllocateDefaultClockEx(
    __out PKSDEFAULTCLOCK* DefaultClock,
    __in_opt PVOID Context,
    __in_opt PFNKSSETTIMER SetTimer,
    __in_opt PFNKSCANCELTIMER CancelTimer,
    __in_opt PFNKSCORRELATEDTIME CorrelatedTime,
    __in_opt const KSRESOLUTION* Resolution,
    __in ULONG Flags
    );

#endif // (NTDDI_VERSION >= NTDDI_WINXP)

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsFreeDefaultClock(
    __in PKSDEFAULTCLOCK DefaultClock
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreateDefaultClock(
    __in PIRP Irp,
    __in PKSDEFAULTCLOCK DefaultClock
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreateClock(
    __in HANDLE ConnectionHandle,
    __in PKSCLOCK_CREATE ClockCreate,
    __out PHANDLE ClockHandle
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsValidateClockCreateRequest(
    __in PIRP Irp,
    __deref_out PKSCLOCK_CREATE* ClockCreate
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
KSSTATE
NTAPI
KsGetDefaultClockState(
    __in PKSDEFAULTCLOCK DefaultClock
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
VOID
NTAPI
KsSetDefaultClockState(
    __in PKSDEFAULTCLOCK DefaultClock,
    __in KSSTATE State
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
LONGLONG
NTAPI
KsGetDefaultClockTime(
    __in PKSDEFAULTCLOCK DefaultClock
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
VOID
NTAPI
KsSetDefaultClockTime(
    __in PKSDEFAULTCLOCK DefaultClock,
    __in LONGLONG Time
    );

// connect.c:

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreatePin(
    __in HANDLE FilterHandle,
    __in PKSPIN_CONNECT Connect,
    __in ACCESS_MASK DesiredAccess,
    __out PHANDLE ConnectionHandle
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsValidateConnectRequest(
    __in PIRP Irp,
    __in ULONG DescriptorsCount,
    __in_ecount(DescriptorsCount) const KSPIN_DESCRIPTOR* Descriptor,
    __out PKSPIN_CONNECT* Connect
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinPropertyHandler(
    __in PIRP Irp,
    __in PKSPROPERTY Property,
    __inout PVOID Data,
    __in ULONG DescriptorsCount,
    __in_ecount(DescriptorsCount) const KSPIN_DESCRIPTOR* Descriptor
    );

__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinDataIntersection(
    __in PIRP Irp,
    __in PKSP_PIN Pin,
    __out_opt PVOID Data,
    __in ULONG DescriptorsCount,
    __in_ecount(DescriptorsCount) const KSPIN_DESCRIPTOR* Descriptor,
    __in PFNKSINTERSECTHANDLER IntersectHandler
    );

__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinDataIntersectionEx(
    __in PIRP Irp,
    __in PKSP_PIN Pin,
    __out PVOID Data,
    __in ULONG DescriptorsCount,
    __in_bcount(DescriptorsCount * DescriptorSize) const KSPIN_DESCRIPTOR* Descriptor,
    __in ULONG DescriptorSize,
    __in_opt PFNKSINTERSECTHANDLEREX IntersectHandler,
    __in_opt PVOID HandlerContext
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsHandleSizedListQuery(
    __in PIRP Irp,
    __in ULONG DataItemsCount,
    __in ULONG DataItemSize,
    __in_bcount(DataItemsCount * DataItemSize) const VOID* DataItems
    );

// image.c:

#if (!defined( MAKEINTRESOURCE )) 
#define MAKEINTRESOURCE( res ) ((ULONG_PTR) (USHORT) res)
#endif

#if (!defined( RT_STRING ))
#define RT_STRING           MAKEINTRESOURCE( 6 )
#define RT_RCDATA           MAKEINTRESOURCE( 10 ) 
#endif

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsLoadResource(
    __in PVOID ImageBase,
    __in POOL_TYPE PoolType,
    __in ULONG_PTR ResourceName,
    __in ULONG ResourceType,
    __deref_out_bcount(ResourceSize) PVOID *Resource,
    __out_opt PULONG ResourceSize            
    );
    
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsGetImageNameAndResourceId(
    __in HANDLE RegKey,
    __out PUNICODE_STRING ImageName,                
    __out PULONG_PTR ResourceId,
    __out PULONG ValueType
);

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsMapModuleName(
    __in PDEVICE_OBJECT PhysicalDeviceObject,
    __in PUNICODE_STRING ModuleName,
    __out PUNICODE_STRING ImageName,                
    __out PULONG_PTR ResourceId,
    __out PULONG ValueType
    );
    
// irp.c:

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsReferenceBusObject(
    __in KSDEVICE_HEADER  Header
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsDereferenceBusObject(
    __in KSDEVICE_HEADER  Header
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsDispatchQuerySecurity(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsDispatchSetSecurity(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsDispatchSpecificProperty(
    __in PIRP Irp,
    __in PFNKSHANDLER Handler
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsDispatchSpecificMethod(
    __in PIRP Irp,
    __in PFNKSHANDLER Handler
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsReadFile(
    __in PFILE_OBJECT FileObject,
    __in_opt PKEVENT Event,
    __in_opt PVOID PortContext,
    __out PIO_STATUS_BLOCK IoStatusBlock,
    __out_bcount(Length) PVOID Buffer,
    __in ULONG Length,
    __in ULONG Key OPTIONAL,
    __in KPROCESSOR_MODE RequestorMode
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsWriteFile(
    __in PFILE_OBJECT FileObject,
    __in_opt PKEVENT Event,
    __in_opt PVOID PortContext,
    __out PIO_STATUS_BLOCK IoStatusBlock,
    __in_bcount(Length) PVOID Buffer,
    __in ULONG Length,
    __in ULONG Key OPTIONAL,
    __in KPROCESSOR_MODE RequestorMode
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsQueryInformationFile(
    __in PFILE_OBJECT FileObject,
    __out_bcount(Length) PVOID FileInformation,
    __in ULONG Length,
    __in FILE_INFORMATION_CLASS FileInformationClass
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsSetInformationFile(
    __in PFILE_OBJECT FileObject,
    __in_bcount(Length) PVOID FileInformation,
    __in ULONG Length,
    __in FILE_INFORMATION_CLASS FileInformationClass
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsStreamIo(
    __in PFILE_OBJECT FileObject,
    __in_opt PKEVENT Event,
    __in_opt PVOID PortContext,
    __in_opt PIO_COMPLETION_ROUTINE CompletionRoutine,
    __in_opt PVOID CompletionContext,
    __in KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL,
    __out PIO_STATUS_BLOCK IoStatusBlock,
    __inout_bcount(Length) PVOID StreamHeaders,
    __in ULONG Length,
    __in ULONG Flags,
    __in KPROCESSOR_MODE RequestorMode
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsProbeStreamIrp(
    __inout PIRP Irp,
    __in ULONG ProbeFlags,
    __in ULONG HeaderSize OPTIONAL
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAllocateExtraData(
    __inout PIRP Irp,
    __in ULONG ExtraSize,
    __out PVOID* ExtraBuffer
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsNullDriverUnload(
    __in PDRIVER_OBJECT DriverObject
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsSetMajorFunctionHandler(
    __in PDRIVER_OBJECT DriverObject,
    __in ULONG MajorFunction
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsDispatchInvalidDeviceRequest(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsDefaultDeviceIoCompletion(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsDispatchIrp(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
BOOLEAN
NTAPI
KsDispatchFastIoDeviceControlFailure(
    __in PFILE_OBJECT FileObject,
    __in BOOLEAN Wait,
    __in_bcount_opt(InputBufferLength) PVOID InputBuffer,
    __in ULONG InputBufferLength,
    __out_bcount_opt(OutputBufferLength) PVOID OutputBuffer,
    __in ULONG OutputBufferLength,
    __in ULONG IoControlCode,
    __out PIO_STATUS_BLOCK IoStatus,
    __in PDEVICE_OBJECT DeviceObject
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
BOOLEAN
NTAPI
KsDispatchFastReadFailure(
    __in PFILE_OBJECT FileObject,
    __in PLARGE_INTEGER FileOffset,
    __in ULONG Length,
    __in BOOLEAN Wait,
    __in ULONG LockKey,
    __out PVOID Buffer,
    __out PIO_STATUS_BLOCK IoStatus,
    __in PDEVICE_OBJECT DeviceObject
    );

#define KsDispatchFastWriteFailure KsDispatchFastReadFailure

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
DRIVER_CANCEL KsCancelRoutine;

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
VOID
NTAPI
KsCancelIo(   
    __inout PLIST_ENTRY  QueueHead,
    __in PKSPIN_LOCK SpinLock
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
VOID
NTAPI
KsReleaseIrpOnCancelableQueue(
    __in PIRP Irp,
    __in_opt PDRIVER_CANCEL DriverCancel
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PIRP
NTAPI
KsRemoveIrpFromCancelableQueue(
    __inout PLIST_ENTRY QueueHead,
    __in PKSPIN_LOCK SpinLock,
    __in KSLIST_ENTRY_LOCATION ListLocation,
    __in KSIRP_REMOVAL_OPERATION RemovalOperation
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsMoveIrpsOnCancelableQueue(
    __inout PLIST_ENTRY SourceList,
    __in PKSPIN_LOCK SourceLock,
    __inout PLIST_ENTRY DestinationList,
    __in_opt PKSPIN_LOCK DestinationLock,
    __in KSLIST_ENTRY_LOCATION ListLocation,
    __in PFNKSIRPLISTCALLBACK ListCallback,
    __in PVOID Context
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
VOID
NTAPI
KsRemoveSpecificIrpFromCancelableQueue(
    __in PIRP Irp
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
VOID
NTAPI
KsAddIrpToCancelableQueue(
    __inout PLIST_ENTRY QueueHead,
    __in PKSPIN_LOCK SpinLock,
    __in PIRP Irp,
    __in KSLIST_ENTRY_LOCATION ListLocation,
    __in_opt PDRIVER_CANCEL DriverCancel
    );

// api.c:

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAcquireResetValue(
    __in PIRP Irp,
    __out KSRESET* ResetValue
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsTopologyPropertyHandler(
    __in PIRP Irp,
    __in PKSPROPERTY Property,
    __inout PVOID Data,
    __in const KSTOPOLOGY* Topology
    );

__drv_maxIRQL(APC_LEVEL)
KSDDKAPI
VOID
NTAPI
KsAcquireDeviceSecurityLock(
    __in KSDEVICE_HEADER Header,
    __in BOOLEAN Exclusive
    );

__drv_maxIRQL(APC_LEVEL)
KSDDKAPI
VOID
NTAPI
KsReleaseDeviceSecurityLock(
    __in KSDEVICE_HEADER Header
    );
    
KSDDKAPI
__drv_dispatchType(IRP_MJ_PNP) DRIVER_DISPATCH KsDefaultDispatchPnp;

KSDDKAPI
__drv_dispatchType(IRP_MJ_POWER) DRIVER_DISPATCH KsDefaultDispatchPower;
    
KSDDKAPI
__drv_dispatchType(IRP_MJ_SYSTEM_CONTROL) 
__drv_dispatchType(IRP_MJ_DEVICE_CONTROL)
DRIVER_DISPATCH KsDefaultForwardIrp;

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsSetDevicePnpAndBaseObject(
    __in KSDEVICE_HEADER Header,
    __in PDEVICE_OBJECT PnpDeviceObject,
    __in PDEVICE_OBJECT BaseObject
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PDEVICE_OBJECT
NTAPI
KsQueryDevicePnpObject(
    __in KSDEVICE_HEADER Header
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
ACCESS_MASK
NTAPI
KsQueryObjectAccessMask(
    __in KSOBJECT_HEADER Header
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsRecalculateStackDepth(
    __in KSDEVICE_HEADER Header,
    __in BOOLEAN ReuseStackLocation
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsSetTargetState(
    __in KSOBJECT_HEADER Header,
    __in KSTARGET_STATE TargetState
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsSetTargetDeviceObject(
    __in KSOBJECT_HEADER Header,
    __in_opt PDEVICE_OBJECT TargetDevice
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsSetPowerDispatch(
    __in KSOBJECT_HEADER Header,
    __in_opt PFNKSCONTEXT_DISPATCH PowerDispatch,
    __in_opt PVOID PowerContext
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PKSOBJECT_CREATE_ITEM
NTAPI
KsQueryObjectCreateItem(
    __in KSOBJECT_HEADER Header
    );

__drv_maxIRQL(APC_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAllocateDeviceHeader(
    __out KSDEVICE_HEADER* Header,
    __in ULONG ItemsCount,
    __in_ecount_opt(ItemsCount) PKSOBJECT_CREATE_ITEM ItemsList
    );

__drv_maxIRQL(APC_LEVEL)
KSDDKAPI
VOID
NTAPI
KsFreeDeviceHeader(
    __in KSDEVICE_HEADER Header
    );

__drv_maxIRQL(APC_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAllocateObjectHeader(
    __out KSOBJECT_HEADER* Header,
    __in ULONG ItemsCount,
    __in_ecount_opt(ItemsCount) PKSOBJECT_CREATE_ITEM ItemsList,
    __in PIRP Irp,
    __in const KSDISPATCH_TABLE* Table
    );

__drv_maxIRQL(APC_LEVEL)
KSDDKAPI
VOID
NTAPI
KsFreeObjectHeader(
    __in KSOBJECT_HEADER Header
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAddObjectCreateItemToDeviceHeader(
    __in KSDEVICE_HEADER Header,
    __in PDRIVER_DISPATCH Create,
    __in PVOID Context,
    __in PWSTR ObjectClass,
    __in_opt PSECURITY_DESCRIPTOR SecurityDescriptor
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAddObjectCreateItemToObjectHeader(
    __in KSOBJECT_HEADER Header,
    __in PDRIVER_DISPATCH Create,
    __in PVOID Context,
    __in PWSTR ObjectClass,
    __in_opt PSECURITY_DESCRIPTOR SecurityDescriptor
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAllocateObjectCreateItem(
    __in KSDEVICE_HEADER Header,
    __in PKSOBJECT_CREATE_ITEM CreateItem,
    __in BOOLEAN AllocateEntry,
    __in_opt PFNKSITEMFREECALLBACK ItemFreeCallback
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsFreeObjectCreateItem(
    __in KSDEVICE_HEADER Header,
    __in PUNICODE_STRING CreateItem
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsFreeObjectCreateItemsByContext(
    __in KSDEVICE_HEADER Header,
    __in PVOID Context
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreateDefaultSecurity(
    __in_opt PSECURITY_DESCRIPTOR ParentSecurity,
    __out PSECURITY_DESCRIPTOR* DefaultSecurity
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsForwardIrp(
    __in PIRP Irp,
    __in PFILE_OBJECT FileObject,
    __in BOOLEAN ReuseStackLocation
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsForwardAndCatchIrp(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp,
    __in PFILE_OBJECT FileObject,
    __in KSSTACK_USE StackUse
    );

__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsSynchronousIoControlDevice(
    __in PFILE_OBJECT FileObject,
    __in KPROCESSOR_MODE RequestorMode,
    __in ULONG IoControl,
    __in_bcount(InSize) PVOID InBuffer,
    __in ULONG InSize,
    __out_bcount_part(OutSize, *BytesReturned) PVOID OutBuffer,
    __in ULONG OutSize,
    __out PULONG BytesReturned
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsUnserializeObjectPropertiesFromRegistry(
    __in PFILE_OBJECT FileObject,
    __in_opt HANDLE ParentKey,
    __in_opt PUNICODE_STRING RegistryPath
    );

#if (NTDDI_VERSION >= NTDDI_WINXP)

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCacheMedium(
    __in PUNICODE_STRING SymbolicLink,
    __in PKSPIN_MEDIUM Medium,
    __in ULONG PinDirection
    );

#endif // (NTDDI_VERSION >= NTDDI_WINXP)

// thread.c:

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsRegisterWorker(
    __in WORK_QUEUE_TYPE WorkQueueType,
    __out PKSWORKER* Worker
    );
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsRegisterCountedWorker(
    __in WORK_QUEUE_TYPE WorkQueueType,
    __in PWORK_QUEUE_ITEM CountedWorkItem,
    __out PKSWORKER* Worker
    );
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
VOID
NTAPI
KsUnregisterWorker(
    __in PKSWORKER Worker
    );
__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsQueueWorkItem(
    __in PKSWORKER Worker,
    __in PWORK_QUEUE_ITEM WorkItem
    );
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
ULONG
NTAPI
KsIncrementCountedWorker(
    __in PKSWORKER Worker
    );
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
ULONG
NTAPI
KsDecrementCountedWorker(
    __in PKSWORKER Worker
    );

// topology.c:

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreateTopologyNode(
    __in HANDLE ParentHandle,
    __in PKSNODE_CREATE NodeCreate,
    __in ACCESS_MASK DesiredAccess,
    __out PHANDLE NodeHandle
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsValidateTopologyNodeCreateRequest(
    __in PIRP Irp,
    __in PKSTOPOLOGY Topology,
    __out PKSNODE_CREATE* NodeCreate
    );

#if (NTDDI_VERSION >= NTDDI_WINXP)

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsMergeAutomationTables(
    __out PKSAUTOMATION_TABLE* AutomationTableAB,
    __in_opt PKSAUTOMATION_TABLE AutomationTableA,
    __in_opt PKSAUTOMATION_TABLE AutomationTableB,
    __in_opt KSOBJECT_BAG Bag
    );

__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsInitializeDriver(
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPathName,
    __in_opt const KSDEVICE_DESCRIPTOR* Descriptor
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAddDevice(
    __in PDRIVER_OBJECT DriverObject,
    __in PDEVICE_OBJECT PhysicalDeviceObject
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreateDevice(
    __in PDRIVER_OBJECT DriverObject,
    __in PDEVICE_OBJECT PhysicalDeviceObject,
    __in_opt const KSDEVICE_DESCRIPTOR* Descriptor,
    __in ULONG ExtensionSize,
    __out_opt PKSDEVICE* Device
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsInitializeDevice(
    __in PDEVICE_OBJECT FunctionalDeviceObject,
    __in PDEVICE_OBJECT PhysicalDeviceObject,
    __in PDEVICE_OBJECT NextDeviceObject,
    __in_opt const KSDEVICE_DESCRIPTOR* Descriptor
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsTerminateDevice(
    __in PDEVICE_OBJECT DeviceObject
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PKSDEVICE
NTAPI
KsGetDeviceForDeviceObject(
    __in PDEVICE_OBJECT FunctionalDeviceObject
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsAcquireDevice(
    __in PKSDEVICE Device
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsReleaseDevice(
    __in PKSDEVICE Device
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsDeviceRegisterAdapterObject(
    __in PKSDEVICE Device,
    __in PADAPTER_OBJECT AdapterObject,
    __in ULONG MaxMappingsByteCount,
    __in ULONG MappingTableStride
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
ULONG
NTAPI
KsDeviceGetBusData(
    __in PKSDEVICE Device,
    __in ULONG DataType,
    __in_bcount(Length) PVOID Buffer,
    __in ULONG Offset,
    __in ULONG Length
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
ULONG
NTAPI
KsDeviceSetBusData(
    __in PKSDEVICE Device,
    __in ULONG DataType,
    __in_bcount(Length) PVOID Buffer,
    __in ULONG Offset,
    __in ULONG Length
    );

__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCreateFilterFactory(
    __in PDEVICE_OBJECT DeviceObject,
    __in const KSFILTER_DESCRIPTOR *Descriptor,
    __in_opt PWSTR RefString,
    __in_opt PSECURITY_DESCRIPTOR SecurityDescriptor,
    __in ULONG CreateItemFlags,
    __in_opt PFNKSFILTERFACTORYPOWER SleepCallback,
    __in_opt PFNKSFILTERFACTORYPOWER WakeCallback,
    __out_opt PKSFILTERFACTORY *FilterFactory
    );

#define KsDeleteFilterFactory(FilterFactory) \
    KsFreeObjectCreateItemsByContext(\
        *(KSDEVICE_HEADER *)(\
            KsFilterFactoryGetParentDevice(FilterFactory)->FunctionalDeviceObject->\
                DeviceExtension),\
        FilterFactory)

__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsFilterFactoryUpdateCacheData(
    __in PKSFILTERFACTORY FilterFactory,
    __in_opt const KSFILTER_DESCRIPTOR *FilterDescriptor
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsFilterFactoryAddCreateItem(
    __in PKSFILTERFACTORY FilterFactory,
    __in PWSTR RefString,
    __in_opt PSECURITY_DESCRIPTOR SecurityDescriptor,
    __in ULONG CreateItemFlags
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsFilterFactorySetDeviceClassesState(
    __in PKSFILTERFACTORY FilterFactory,
    __in BOOLEAN NewState
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PUNICODE_STRING
NTAPI
KsFilterFactoryGetSymbolicLink(
    __in PKSFILTERFACTORY FilterFactory
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsAddEvent(
    __in PVOID Object,
    __in PKSEVENT_ENTRY EventEntry
    );

__drv_maxIRQL(PASSIVE_LEVEL)
void _inline
KsFilterAddEvent(
    __in PKSFILTER Filter,
    __in PKSEVENT_ENTRY EventEntry
    )
{
    KsAddEvent(Filter,EventEntry);
}

__drv_maxIRQL(PASSIVE_LEVEL)
void _inline
KsPinAddEvent(
    __in PKSPIN Pin,
    __in PKSEVENT_ENTRY EventEntry
    )
{
    KsAddEvent(Pin,EventEntry);
}

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS    
NTAPI
KsDefaultAddEventHandler(
    __in PIRP Irp,
    __in PKSEVENTDATA EventData,
    __inout PKSEVENT_ENTRY EventEntry
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsGenerateEvents(
    __in PVOID Object,
    __in_opt const GUID* EventSet,
    __in ULONG EventId,
    __in ULONG DataSize,
    __in_bcount_opt(DataSize) PVOID Data,
    __in_opt PFNKSGENERATEEVENTCALLBACK CallBack,
    __in_opt PVOID CallBackContext
    );

__drv_maxIRQL(DISPATCH_LEVEL)
void _inline
KsFilterGenerateEvents(
    __in PKSFILTER Filter,
    __in_opt const GUID* EventSet,
    __in ULONG EventId,
    __in ULONG DataSize,
    __in_bcount(DataSize) PVOID Data,
    __in_opt PFNKSGENERATEEVENTCALLBACK CallBack,
    __in_opt PVOID CallBackContext
    )
{
    KsGenerateEvents(
        Filter,
        EventSet,
        EventId,
        DataSize,
        Data,
        CallBack,
        CallBackContext);
}

__drv_maxIRQL(DISPATCH_LEVEL)
void _inline
KsPinGenerateEvents(
    __in PKSPIN Pin,
    __in_opt const GUID* EventSet,
    __in ULONG EventId,
    __in ULONG DataSize,
    __in_bcount_opt(DataSize) PVOID Data,
    __in_opt PFNKSGENERATEEVENTCALLBACK CallBack,
    __in_opt PVOID CallBackContext
    )
{
    KsGenerateEvents(
        Pin,
        EventSet,
        EventId,
        DataSize,
        Data,
        CallBack,
        CallBackContext);
}

typedef enum {
    KSSTREAM_POINTER_STATE_UNLOCKED = 0,
    KSSTREAM_POINTER_STATE_LOCKED
} KSSTREAM_POINTER_STATE;

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinGetAvailableByteCount(
    __in PKSPIN Pin,
    __out_opt PLONG InputDataBytes,
    __out_opt PLONG OutputBufferBytes
    );

__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PKSSTREAM_POINTER
NTAPI
KsPinGetLeadingEdgeStreamPointer(
    __in PKSPIN Pin,
    __in KSSTREAM_POINTER_STATE State
    );

__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PKSSTREAM_POINTER
NTAPI
KsPinGetTrailingEdgeStreamPointer(
    __in PKSPIN Pin,
    __in KSSTREAM_POINTER_STATE State
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsStreamPointerSetStatusCode(
    __in PKSSTREAM_POINTER StreamPointer,
    __in NTSTATUS Status
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsStreamPointerLock(
    __in PKSSTREAM_POINTER StreamPointer
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsStreamPointerUnlock(
    __in PKSSTREAM_POINTER StreamPointer,
    __in BOOLEAN Eject
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsStreamPointerAdvanceOffsetsAndUnlock(
    __in PKSSTREAM_POINTER StreamPointer,
    __in ULONG InUsed,
    __in ULONG OutUsed,
    __in BOOLEAN Eject
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsStreamPointerDelete(
    __in PKSSTREAM_POINTER StreamPointer
    );

__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsStreamPointerClone(
    __in PKSSTREAM_POINTER StreamPointer,
    __in_opt PFNKSSTREAMPOINTER CancelCallback,
    __in ULONG ContextSize,
    __out PKSSTREAM_POINTER* CloneStreamPointer
    );

__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsStreamPointerAdvanceOffsets(
    __in PKSSTREAM_POINTER StreamPointer,
    __in ULONG InUsed,
    __in ULONG OutUsed,
    __in BOOLEAN Eject
    );

__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsStreamPointerAdvance(
    __in PKSSTREAM_POINTER StreamPointer
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PMDL
NTAPI
KsStreamPointerGetMdl(
    __in PKSSTREAM_POINTER StreamPointer
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PIRP
NTAPI
KsStreamPointerGetIrp(
    __in PKSSTREAM_POINTER StreamPointer,
    __out_opt PBOOLEAN FirstFrameInIrp,
    __out_opt PBOOLEAN LastFrameInIrp
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsStreamPointerScheduleTimeout(
    __in PKSSTREAM_POINTER StreamPointer,
    __in PFNKSSTREAMPOINTER Callback,
    __in ULONGLONG Interval
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsStreamPointerCancelTimeout(
    __in PKSSTREAM_POINTER StreamPointer
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PKSSTREAM_POINTER
NTAPI
KsPinGetFirstCloneStreamPointer(
    __in PKSPIN Pin
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PKSSTREAM_POINTER
NTAPI
KsStreamPointerGetNextClone(
    __in PKSSTREAM_POINTER StreamPointer
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinHandshake(
    __in PKSPIN Pin,
    __in PKSHANDSHAKE In,
    __out PKSHANDSHAKE Out
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsCompletePendingRequest(
    __in PIRP Irp
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
KSOBJECTTYPE
NTAPI
KsGetObjectTypeFromIrp(
    __in PIRP Irp
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PVOID
NTAPI
KsGetObjectFromFileObject(
    __in PFILE_OBJECT FileObject
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
KSOBJECTTYPE
NTAPI
KsGetObjectTypeFromFileObject(
    __in PFILE_OBJECT FileObject
    );

__drv_maxIRQL(DISPATCH_LEVEL)
PKSFILTER __inline
KsGetFilterFromFileObject(
    __in PFILE_OBJECT FileObject
    )
{
    return (PKSFILTER) KsGetObjectFromFileObject(FileObject);
}

__drv_maxIRQL(DISPATCH_LEVEL)
PKSPIN __inline
KsGetPinFromFileObject(
    __in PFILE_OBJECT FileObject
    )
{
    return (PKSPIN) KsGetObjectFromFileObject(FileObject);
}    

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PKSGATE
NTAPI
KsFilterGetAndGate(
    __in PKSFILTER Filter
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsFilterAcquireProcessingMutex(
    __in PKSFILTER Filter
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsFilterReleaseProcessingMutex(
    __in PKSFILTER Filter
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsFilterAttemptProcessing(
    __in PKSFILTER Filter,
    __in BOOLEAN Asynchronous
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PKSGATE
NTAPI
KsPinGetAndGate(
    __in PKSPIN Pin
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsPinAttachAndGate(
    __in PKSPIN Pin,
    __in_opt PKSGATE AndGate
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsPinAttachOrGate(
    __in PKSPIN Pin,
    __in_opt PKSGATE OrGate
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsPinAcquireProcessingMutex(
    __in PKSPIN Pin
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsPinReleaseProcessingMutex(
    __in PKSPIN Pin
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
BOOLEAN
NTAPI
KsProcessPinUpdate(
    __in PKSPROCESSPIN ProcessPin
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsPinGetCopyRelationships(
    __in PKSPIN Pin,
    __out PKSPIN* CopySource,
    __out PKSPIN* DelegateBranch
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
void
NTAPI
KsPinAttemptProcessing(
    __in PKSPIN Pin,
    __in BOOLEAN Asynchronous
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PVOID
NTAPI
KsGetParent(
    __in PVOID Object
    );

__drv_maxIRQL(PASSIVE_LEVEL)
PKSDEVICE __inline
KsFilterFactoryGetParentDevice(
    __in PKSFILTERFACTORY FilterFactory
    )
{
    return (PKSDEVICE) KsGetParent((PVOID) FilterFactory);
}

__drv_maxIRQL(PASSIVE_LEVEL)
PKSFILTERFACTORY __inline
KsFilterGetParentFilterFactory(
    __in PKSFILTER Filter
    )
{
    return (PKSFILTERFACTORY) KsGetParent((PVOID) Filter);
}

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PKSFILTER 
NTAPI
KsPinGetParentFilter(
    __in PKSPIN Pin
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PVOID
NTAPI
KsGetFirstChild(
    __in PVOID Object
    );

__drv_maxIRQL(PASSIVE_LEVEL)
PKSFILTERFACTORY __inline
KsDeviceGetFirstChildFilterFactory(
    __in PKSDEVICE Device
    )
{
    return (PKSFILTERFACTORY) KsGetFirstChild((PVOID) Device);
}

__drv_maxIRQL(PASSIVE_LEVEL)
PKSFILTER __inline
KsFilterFactoryGetFirstChildFilter(
    __in PKSFILTERFACTORY FilterFactory
    )
{
    return (PKSFILTER) KsGetFirstChild((PVOID) FilterFactory);
}

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
ULONG
NTAPI
KsFilterGetChildPinCount(
    __in PKSFILTER Filter,
    __in ULONG PinId
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PKSPIN
NTAPI
KsFilterGetFirstChildPin(
    __in PKSFILTER Filter,
    __in ULONG PinId
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PVOID
NTAPI
KsGetNextSibling(
    __in PVOID Object
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PKSPIN 
NTAPI
KsPinGetNextSiblingPin(
    __in PKSPIN Pin
    );

__drv_maxIRQL(PASSIVE_LEVEL)
PKSFILTERFACTORY __inline
KsFilterFactoryGetNextSiblingFilterFactory(
    __in PKSFILTERFACTORY FilterFactory
    )
{
    return (PKSFILTERFACTORY) KsGetNextSibling((PVOID) FilterFactory);
}

__drv_maxIRQL(PASSIVE_LEVEL)
PKSFILTER __inline
KsFilterGetNextSiblingFilter(
    __in PKSFILTER Filter
    )
{
    return (PKSFILTER) KsGetNextSibling((PVOID) Filter);
}


__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PKSDEVICE
NTAPI
KsGetDevice(
    __in PVOID Object
    );

__drv_maxIRQL(PASSIVE_LEVEL)
PKSDEVICE __inline
KsFilterFactoryGetDevice(
    __in PKSFILTERFACTORY FilterFactory
    )
{
    return KsGetDevice((PVOID) FilterFactory);
}

__drv_maxIRQL(PASSIVE_LEVEL)
PKSDEVICE __inline
KsFilterGetDevice(
    __in PKSFILTER Filter
    )
{
    return KsGetDevice((PVOID) Filter);
}

__drv_maxIRQL(PASSIVE_LEVEL)
PKSDEVICE __inline
KsPinGetDevice(
    __in PKSPIN Pin
    )
{
    return KsGetDevice((PVOID) Pin);
}

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PKSFILTER
NTAPI
KsGetFilterFromIrp(
    __in PIRP Irp
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
PKSPIN
NTAPI
KsGetPinFromIrp(
    __in PIRP Irp
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
ULONG
NTAPI
KsGetNodeIdFromIrp(
    __in PIRP Irp
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsAcquireControl(
    __in PVOID Object
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsReleaseControl(
    __in PVOID Object
    );

__drv_maxIRQL(PASSIVE_LEVEL) 
void __inline
KsFilterAcquireControl(
    __in PKSFILTER Filter
    )
{
    KsAcquireControl((PVOID) Filter);
}

__drv_maxIRQL(PASSIVE_LEVEL) 
void __inline
KsFilterReleaseControl(
    __in PKSFILTER Filter
    )
{
    KsReleaseControl((PVOID) Filter);
}

__drv_maxIRQL(PASSIVE_LEVEL) 
void __inline
KsPinAcquireControl(
    __in PKSPIN Pin
    )
{
    KsAcquireControl((PVOID) Pin);
}

__drv_maxIRQL(PASSIVE_LEVEL) 
void __inline
KsPinReleaseControl(
    __in PKSPIN Pin
    )
{
    KsReleaseControl((PVOID) Pin);
}

__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAddItemToObjectBag(
    __in KSOBJECT_BAG ObjectBag,
    __in __drv_aliasesMem PVOID Item,
    __in_opt PFNKSFREE Free
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
ULONG
NTAPI
KsRemoveItemFromObjectBag(
    __in KSOBJECT_BAG ObjectBag,
    __in PVOID Item,
    __in BOOLEAN Free
    );

#define KsDiscard(Object,Pointer)\
    KsRemoveItemFromObjectBag(\
        (Object)->Bag,\
        (PVOID)(Pointer),\
        TRUE)

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsAllocateObjectBag(
    __in PKSDEVICE Device,
    __out KSOBJECT_BAG* ObjectBag
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsFreeObjectBag(
    __in KSOBJECT_BAG ObjectBag
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsCopyObjectBagItems(
    __in KSOBJECT_BAG ObjectBagDestination,
    __in KSOBJECT_BAG ObjectBagSource
    );

__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
_KsEdit(
    __in KSOBJECT_BAG ObjectBag,
    __inout PVOID* PointerToPointerToItem,
    __in ULONG NewSize,
    __in ULONG OldSize,
    __in ULONG Tag
    );

#define KsEdit(Object,PointerToPointer,Tag)\
    _KsEdit(\
        (Object)->Bag,\
        (PVOID*)(PointerToPointer),\
        sizeof(**(PointerToPointer)),\
        sizeof(**(PointerToPointer)),\
        (Tag))
#define KsEditSized(Object,PointerToPointer,NewSize,OldSize,Tag)\
    _KsEdit((Object)->Bag,(PVOID*)(PointerToPointer),(NewSize),(OldSize),(Tag))

__checkReturn
__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsRegisterFilterWithNoKSPins(
                                      __in PDEVICE_OBJECT DeviceObject,
                                      __in const GUID * InterfaceClassGUID,
                                      __in ULONG PinCount,
                                      __in_ecount(PinCount) BOOL * PinDirection,
                                      __in_ecount(PinCount) KSPIN_MEDIUM * MediumList,
                                      __in_ecount_opt(PinCount) GUID * CategoryList
);

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsFilterCreatePinFactory (
    __in PKSFILTER Filter,
    __in const KSPIN_DESCRIPTOR_EX *const PinDescriptor,
    __out PULONG PinID
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsFilterCreateNode (
    __in PKSFILTER Filter,
    __in const KSNODE_DESCRIPTOR *const NodeDescriptor,
    __out PULONG NodeID
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsFilterAddTopologyConnections (
    __in PKSFILTER Filter,
    __in ULONG NewConnectionsCount,
    __in_ecount(NewConnectionsCount) const KSTOPOLOGY_CONNECTION *const NewTopologyConnections
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinGetConnectedPinInterface(
    __in PKSPIN Pin,
    __in const GUID* InterfaceId,
    __out PVOID* Interface
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PFILE_OBJECT
NTAPI
KsPinGetConnectedPinFileObject(
    __in PKSPIN Pin
    );

KSDDKAPI
PDEVICE_OBJECT
NTAPI
KsPinGetConnectedPinDeviceObject(
    __in PKSPIN Pin
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinGetConnectedFilterInterface(
    __in PKSPIN Pin,
    __in const GUID* InterfaceId,
    __out PVOID* Interface
    );

#if defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__)

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinGetReferenceClockInterface(
    __in PKSPIN Pin,
    __out PIKSREFERENCECLOCK* Interface
    );

#endif //defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__)

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
VOID
NTAPI
KsPinSetPinClockTime(
    __in PKSPIN Pin,
    __in LONGLONG Time
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinSubmitFrame(
    __in PKSPIN Pin,
    __in_bcount_opt(Size) PVOID Data,
    __in ULONG Size OPTIONAL,
    __in_opt PKSSTREAM_HEADER StreamHeader,
    __in_opt PVOID Context
    );

__drv_maxIRQL(DISPATCH_LEVEL)
KSDDKAPI
NTSTATUS
NTAPI
KsPinSubmitFrameMdl(
    __in PKSPIN Pin,
    __in_opt PMDL Mdl,
    __in_opt PKSSTREAM_HEADER StreamHeader,
    __in_opt PVOID Context
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsPinRegisterFrameReturnCallback(
    __in PKSPIN Pin,
    __in PFNKSPINFRAMERETURN FrameReturn
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsPinRegisterIrpCompletionCallback(
    __in PKSPIN Pin,
    __in PFNKSPINIRPCOMPLETION IrpCompletion
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsPinRegisterHandshakeCallback(
    __in PKSPIN Pin,
    __in PFNKSPINHANDSHAKE Handshake
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsFilterRegisterPowerCallbacks(
    __in PKSFILTER Filter,
    __in_opt PFNKSFILTERPOWER Sleep,
    __in_opt PFNKSFILTERPOWER Wake
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
void
NTAPI
KsPinRegisterPowerCallbacks(
    __in PKSPIN Pin,
    __in_opt PFNKSPINPOWER Sleep,
    __in_opt PFNKSPINPOWER Wake
    );

#if defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__)

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PUNKNOWN
NTAPI
KsRegisterAggregatedClientUnknown(
    __in PVOID Object,
    __in PUNKNOWN ClientUnknown 
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
PUNKNOWN
NTAPI
KsGetOuterUnknown(
    __in PVOID Object
    );

__drv_maxIRQL(PASSIVE_LEVEL)
PUNKNOWN __inline
KsDeviceRegisterAggregatedClientUnknown(
    __in PKSDEVICE Device,
    __in PUNKNOWN ClientUnknown 
    )
{
    return KsRegisterAggregatedClientUnknown((PVOID) Device,ClientUnknown);
}

__drv_maxIRQL(PASSIVE_LEVEL) 
PUNKNOWN __inline
KsDeviceGetOuterUnknown(
    __in PKSDEVICE Device
    )
{
    return KsGetOuterUnknown((PVOID) Device);
}

__drv_maxIRQL(PASSIVE_LEVEL)
PUNKNOWN __inline
KsFilterFactoryRegisterAggregatedClientUnknown(
    __in PKSFILTERFACTORY FilterFactory,
    __in PUNKNOWN ClientUnknown 
    )
{
    return KsRegisterAggregatedClientUnknown((PVOID) FilterFactory,ClientUnknown);
}

__drv_maxIRQL(PASSIVE_LEVEL) 
PUNKNOWN __inline
KsFilterFactoryGetOuterUnknown(
    __in PKSFILTERFACTORY FilterFactory
    )
{
    return KsGetOuterUnknown((PVOID) FilterFactory);
}

__drv_maxIRQL(PASSIVE_LEVEL)
PUNKNOWN __inline
KsFilterRegisterAggregatedClientUnknown(
    __in PKSFILTER Filter,
    __in PUNKNOWN ClientUnknown 
    )
{
    return KsRegisterAggregatedClientUnknown((PVOID) Filter,ClientUnknown);
}

__drv_maxIRQL(PASSIVE_LEVEL) 
PUNKNOWN __inline
KsFilterGetOuterUnknown(
    __in PKSFILTER Filter
    )
{
    return KsGetOuterUnknown((PVOID) Filter);
}

__drv_maxIRQL(PASSIVE_LEVEL)
PUNKNOWN __inline
KsPinRegisterAggregatedClientUnknown(
    __in PKSPIN Pin,
    __in PUNKNOWN ClientUnknown 
    )
{
    return KsRegisterAggregatedClientUnknown((PVOID) Pin,ClientUnknown);
}

__drv_maxIRQL(PASSIVE_LEVEL) 
PUNKNOWN __inline
KsPinGetOuterUnknown(
    __in PKSPIN Pin
    )
{
    return KsGetOuterUnknown((PVOID) Pin);
}

#endif // defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__)

#endif // (NTDDI_VERSION >= NTDDI_WINXP)

#else // !defined(_NTDDK_)

#if !defined( KS_NO_CREATE_FUNCTIONS )

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
DWORD
WINAPI
KsCreateAllocator(
    __in HANDLE ConnectionHandle,
    __in PKSALLOCATOR_FRAMING AllocatorFraming,
    __out PHANDLE AllocatorHandle
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
DWORD
NTAPI
KsCreateClock(
    __in HANDLE ConnectionHandle,
    __in PKSCLOCK_CREATE ClockCreate,
    __out PHANDLE ClockHandle
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
DWORD
WINAPI
KsCreatePin(
    __in HANDLE FilterHandle,
    __in PKSPIN_CONNECT Connect,
    __in ACCESS_MASK DesiredAccess,
    __out PHANDLE ConnectionHandle
    );

__drv_maxIRQL(PASSIVE_LEVEL)
KSDDKAPI
DWORD
WINAPI
KsCreateTopologyNode(
    __in HANDLE ParentHandle,
    __in PKSNODE_CREATE NodeCreate,
    __in ACCESS_MASK DesiredAccess,
    __out PHANDLE NodeHandle
    );
    
#endif

#endif // !defined(_NTDDK_)

#if defined(__cplusplus)
}
#endif // defined(__cplusplus)


#define DENY_USERMODE_ACCESS( pIrp, CompleteRequest ) \
if ( pIrp->RequestorMode != KernelMode ) { \
    pIrp->IoStatus.Information = 0; \
    pIrp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; \
    if ( CompleteRequest ) IoCompleteRequest ( pIrp, IO_NO_INCREMENT ); \
    return STATUS_INVALID_DEVICE_REQUEST; \
}


#endif // !_KS_


