Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

782 lines
15 KiB

/*++
Copyright (c) 1995-1998 Microsoft Corporation
Module Name:
RCA.h
Abstract:
The module defines the constants, structures and function templates for
the NDIS RCA
Author:
Richard Machin (RMachin)
Revision History:
Who When What
-------- -------- ----------------------------------------------
RMachin 10-3-96 created
JameelH 4-18-98 Cleanup
SPATHER 4-20-99 Cleanup, separated out all NDIS components
--*/
#ifndef _RCA__H
#define _RCA__H
#include "mmsystem.h"
#define NOBITMAP
#include "mmreg.h"
#undef NOBITMAP
#include "ks.h"
#include "ksmedia.h"
#include <pxdebug.h>
#include <ntddk.h>
#include <windef.h>
#define AUDIO_SINK_FLAG 1
//
// Signature used for all pool allocs
//
#define rca_signature ' ACR'
#define MODULE_INIT 0x00010000
#define MODULE_NTINIT 0x00020000
#define MODULE_CO 0x00030000
#define MODULE_CL 0x00040000
#define MODULE_DEBUG 0x00050000
#define MODULE_CM 0x00060000
#define MODULE_UTIL 0x00070000
#define MODULE_CFG 0x00080000
#define MODULE_TAPI 0x00100000
#define MODULE_FLT 0x00200000
#define MODULE_STRM 0x00300000
#define MODULE_COCL 0x00400000
#define MODULE_NDIS 0x00500000
#define MODULE_KSNDIS 0x00600000
#ifndef ULONG_MAX
#define ULONG_MAX 0xffffffffUL
#endif
#if DBG
#ifndef DEBUG
#define DEBUG
#endif
#endif
#if MY_ASSERT
#undef ASSERT
#define ASSERT(exp) \
if (!(exp)) \
{\
DbgPrint( #exp, __FILE__, __LINE__, NULL );\
DbgBreakPoint();\
}
#endif
#if PACKET_POOL_OPTIMIZATION
// SendPPOpt - Start
#define SENDPPOPT_NUM_BUCKETS 10000
extern LONG g_alSendPPOptBuckets[SENDPPOPT_NUM_BUCKETS];
extern LONG g_lSendPPOptOutstanding;
extern NDIS_SPIN_LOCK g_SendPPOptLock;
// SendPPOpt - End
// RecvPPOpt - Start
#define RECVPPOPT_NUM_BUCKETS 10000
extern LONG g_alRecvPPOptBuckets[RECVPPOPT_NUM_BUCKETS];
extern LONG g_lRecvPPOptOutstanding;
extern NDIS_SPIN_LOCK g_RecvPPOptLock;
// RecvPPOpt - End
#endif // PACKET_POOL_OPTIMIZATION
//
// Various constants used all over.
//
#define MAXNUM_PIN_TYPES 2
#define MIN_PACKETS_POOL 40
#define MAX_PACKETS_POOL 10000
#define ID_DEVIO_PIN 1
#define ID_BRIDGE_PIN 0
#define RCA_SAP_REG_TIMEOUT 5000 // MS to block filterdispatchcreate waiting for SAP registration to finish.
//
// Structure and macros used to block / unblock the current thread.
//
typedef struct _RCABlockStruc {
NDIS_EVENT Event;
NDIS_STATUS TheStatus;
} RCABlockStruc, *PRCABlockStruc;
/*++
VOID
RCAInitBlockStruc(
IN RCABlockStruc *pBlock
);
--*/
#define RCAInitBlockStruc(pBlock) NdisInitializeEvent(&(pBlock)->Event)
/*++
VOID
RCABlock(
IN RCABlockStruc *pBlock,
OUT NDIS_STATUS *pStatus
);
--*/
#define RCABlock(pBlock, pStatus) \
{ \
NdisWaitEvent(&(pBlock)->Event, 0); \
*(pStatus) = (pBlock)->TheStatus; \
}
/*++
VOID
RCABlockTimeOut(
IN RCABlockStruc *pBlock,
IN UINT MsToWait
OUT NDIS_STATUS *pStatus
);
--*/
#define RCABlockTimeOut(pBlock, MsToWait, pStatus) \
{ \
if (NdisWaitEvent(&(pBlock)->Event, MsToWait)) \
*(pStatus) = (pBlock)->TheStatus; \
else \
*(pStatus) = STATUS_TIMEOUT; \
}
/*++
VOID
RCASignal(
IN RCABlockStruc *pBlock,
IN UINT Status
);
--*/
#define RCASignal(pBlock, Status) \
{ \
(pBlock)->TheStatus = Status; \
NdisSetEvent(&((pBlock)->Event)); \
}
typedef ULONG_PTR FILTER_TYPE;
#define FilterTypeRender (FILTER_TYPE)0
#define FilterTypeCapture (FILTER_TYPE)1
typedef struct _DEVICE_INSTANCE
{
//
// KS-managed header
//
KSDEVICE_HEADER Header;
KSPIN_CINSTANCES PinInstances[ MAXNUM_PIN_TYPES ];
} DEVICE_INSTANCE, *PDEVICE_INSTANCE;
//
// The RCA Stream Header structure (this incorparates a KS Stream Header)
//
typedef struct _RCA_STREAM_HEADER {
LIST_ENTRY ListEntry;
KSSTREAM_HEADER Header;
PNDIS_PACKET NdisPacket; // CLEANUP: Take this out.
ULONG RefCount; // FIXME: NOT YET IMPLEMENTED
} RCA_STREAM_HEADER, *PRCA_STREAM_HEADER;
//
// The Stream Header Pool structure
//
typedef struct _RCA_SH_POOL {
LONG FailCount;
IO_STATUS_BLOCK IoStatus; // HACK:Common IO Status block for all stream IRPs
NPAGED_LOOKASIDE_LIST LookAsideList;
} RCA_SH_POOL, *PRCA_SH_POOL;
//
// Our global device extension
//
PDEVICE_INSTANCE DeviceExtension;
//
// Globals
//
extern const KSDISPATCH_TABLE FilterDispatchTable;
extern const KSPIN_CINSTANCES PinInstances[MAXNUM_PIN_TYPES];
//
// Here's where we keep info that's common across FDOs (shared
// by capture and render devices)
//
typedef struct RCA_GLOBAL
{
ULONG Status;
LONG QueueSize;
NDIS_SPIN_LOCK SpinLock; // SpinLock for this structure
PDRIVER_OBJECT pDriverObject; // passed in DriverEntry
PDEVICE_OBJECT pFunctionalDeviceObject;// created by IoCreateDevice
KSOBJECT_CREATE_ITEM FilterCreateItems[2];
RCA_SH_POOL SHPool; // Pool of stream headers that Capture devices use
BOOL bProtocolInitialized; // True if RCACoNdisInitialize has been called.
} RCA_GLOBAL, *PRCA_GLOGBAL;
extern RCA_GLOBAL RcaGlobal;
#define RCA_ACQUIRE_GLOBAL_LOCK() RCAAcquireLock(&RcaGlobal.SpinLock);
#define RCA_RELEASE_GLOBAL_LOCK() RCAReleaseLock(&RcaGlobal.SpinLock);
//
// Pin constants
//
// 2 PINs on each type of filter (capture or render): bridge-to-net, and dataio
extern const KSPIN_DESCRIPTOR PinDescriptors[2]; // CLEANUP: This is sketchy, see if it's really needed.
typedef struct _FILTER_CONNECTION
{
LIST_ENTRY ListEntry; // used only for destination lists
PFILE_OBJECT FileObject; // The connected pin file object.
PFILE_OBJECT NextFileObject; // The chained file object
} FILTER_CONNECTION;
typedef struct
{
KSOBJECT_HEADER Header;
ULONG PinId;
} PIN_INSTANCE_HEADER, *PPIN_INSTANCE_HEADER;
typedef struct _FILTER_INSTANCE FILTER_INSTANCE, *PFILTER_INSTANCE;
typedef struct
{
PIN_INSTANCE_HEADER InstanceHdr;
LIST_ENTRY EventQueue;
FAST_MUTEX EventQueueLock;
KSSTATE DeviceState;
PVOID VcContext;
PFILTER_INSTANCE FilterInstance;
BOOL ConnectedAsSink;
LIST_ENTRY ActiveQueue;
KSPIN_LOCK QueueLock;
PVOID AllocatorObject;
} PIN_INSTANCE_DEVIO, *PPIN_INSTANCE_DEVIO;
typedef struct
{
PIN_INSTANCE_HEADER InstanceHdr;
LIST_ENTRY EventQueue;
FAST_MUTEX EventQueueLock;
KSSTATE Unused;
PVOID VcContext;
NDIS_WORK_ITEM WorkItem;
BOOL bWorkItemQueued;
LIST_ENTRY WorkQueue;
PFILTER_INSTANCE FilterInstance;
KSPIN_LOCK SpinLock;
KIRQL OldIrql;
RCABlockStruc Block;
BOOL SignalMe;
PKSDATAFORMAT pDataFormat;
LONGLONG PendingSendsCount;
RCABlockStruc PendingSendsBlock;
BOOL SignalWhenSendsComplete;
} PIN_INSTANCE_BRIDGE, *PPIN_INSTANCE_BRIDGE;
#if DBG
#define RCA_ACQUIRE_BRIDGE_PIN_LOCK(pBridgePin) \
{\
KeAcquireSpinLock(&((pBridgePin)->SpinLock), &((pBridgePin)->OldIrql));\
if (RCADebugLevel == RCA_LOCKS) {\
DbgPrint("BRIDGE PIN LOCK (0x%x) ACQUIRED at module %x, line %d\n",\
&((pBridgePin)->SpinLock), MODULE_NUMBER >> 16, __LINE__);\
}\
}
#define RCA_RELEASE_BRIDGE_PIN_LOCK(pBridgePin) \
{\
KeReleaseSpinLock(&((pBridgePin)->SpinLock), (pBridgePin)->OldIrql);\
if (RCADebugLevel == RCA_LOCKS) { \
DbgPrint("BRIDGE PIN LOCK (0x%x) RELEASED at module %x, line %d\n",\
&((pBridgePin)->SpinLock), MODULE_NUMBER >> 16, __LINE__);\
} \
}
#else
#define RCA_ACQUIRE_BRIDGE_PIN_LOCK(pBridgePin) KeAcquireSpinLock(&((pBridgePin)->SpinLock), &((pBridgePin)->OldIrql));
#define RCA_RELEASE_BRIDGE_PIN_LOCK(pBridgePin) KeReleaseSpinLock(&((pBridgePin)->SpinLock), (pBridgePin)->OldIrql);
#endif
typedef struct _FILTER_INSTANCE
{
KSOBJECT_HEADER Header;
FILTER_TYPE FilterType;
KMUTEX ControlMutex;
PFILE_OBJECT PinFileObjects[SIZEOF_ARRAY(PinDescriptors)];
PPIN_INSTANCE_BRIDGE BridgePin;
PPIN_INSTANCE_DEVIO DevIoPin;
PKSDATAFORMAT_WAVEFORMATEX WaveFormat;
KSDATAFORMAT DataFormat;
PFILE_OBJECT NextFileObject, ConnectedFileObject;
FILTER_CONNECTION Connections[2];
KSPIN_CINSTANCES PinInstances[2];
} FILTER_INSTANCE, *PFILTER_INSTANCE;
NTSTATUS
PnpAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
);
NTSTATUS
PinDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
#define LinkDoubleAtHead(_pHead, _p, Next, Prev) \
{ \
(_p)->Next = (_pHead); \
(_p)->Prev = &(_pHead); \
if ((_pHead) != NULL) \
(_pHead)->Prev = &(_p)->Next; \
(_pHead) = (_p); \
}
#define LinkDoubleAtTail(_pThis, _pLast, Next, Prev) \
{ \
(_pLast)->Next = (_pThis); \
(_pThis)->Prev = &(_pLast)->Next; \
(_pThis)->Next = NULL; \
}
#define InsertDoubleBefore(_pThis, _pBefore, Next, Prev) \
{ \
(_pThis)->Next = (_pBefore); \
(_pThis)->Prev = (_pBefore)->Prev; \
(_pBefore)->Prev = &(_pThis)->Next; \
*((_pThis)->Prev) = (_pThis); \
}
#define UnlinkDouble(_p, Next, Prev) \
{ \
*((_p)->Prev) = (_p)->Next; \
if ((_p)->Next != NULL) \
(_p)->Next->Prev = (_p)->Prev; \
}
//
// Work Queue list entry
//
typedef struct
{
LIST_ENTRY ListEntry;
union {
PVOID PacketContext;
PRCA_STREAM_HEADER StreamHeader;
};
union {
// PRCA_VC pRcaVc; //CLEANUP: Remove this
PMDL Mdl;
};
BOOL bFreeThisPacket;
} WORK_ITEM, PKT_RSVD, *PWORK_ITEM, *PPKT_RSVD;
#define PKT_RSVD_FROM_PKT(_pPkt) ((PPKT_RSVD)((_pPkt)->ProtocolReserved))
#define WORK_ITEM_FROM_PKT(_pPkt) ((PWORK_ITEM)((_pPkt)->ProtocolReserved))
#ifndef STRUCT_OF
#define STRUCT_OF(_Type, _Addr, _Field) CONTAINING_RECORD(_Addr, _Type, _Field)
#endif
#ifndef MAX
#define MAX(Fred, Shred) (((Fred) > (Shred)) ? (Fred) : (Shred))
#endif // MAX
#ifndef MIN
#define MIN(Fred, Shred) (((Fred) < (Shred)) ? (Fred) : (Shred))
#endif // MIN
/*++
VOID
RCAMemSet(
IN POPAQUE Pointer,
IN UCHAR Value,
IN ULONG Length
);
--*/
#define RCAMemSet(Pointer, Value, Length) NdisFillMemory((PUCHAR)(Pointer), (ULONG)(Length), (UCHAR)(Value))
/*++
VOID
RCAMemCopy(
IN POPAQUE Destn,
IN POPAQUE Source,
IN ULONG Length
);
--*/
#define RCAMemCopy(Destn, Source, Length) NdisMoveMemory((Destn), (Source), (Length))
#define RCA_TAG ((ULONG)'FACR')
#if DBG
#undef AUDIT_MEM
#define AUDIT_MEM 1
#endif
/*++
PVOID
RCAAllocMem(
IN ULONG Size
);
--*/
#if AUDIT_MEM
#define RCAAllocMem(Pointer, TYPE, Size) Pointer = (TYPE *)RCAAuditAllocMem((PVOID)(&(Pointer)), Size, _FILENUMBER, __LINE__);
#else // AUDIT_MEM
#define RCAAllocMem(Pointer, TYPE, Size) NdisAllocateMemoryWithTag((PVOID)(&Pointer), (ULONG)Size, RCA_TAG)
#endif // AUDIT_MEM
/*++
VOID
RCAFreeMem(
IN PVOID Pointer
);
--*/
#if AUDIT_MEM
#define RCAFreeMem(Pointer) RCAAuditFreeMem((PVOID)Pointer)
#else
#define RCAFreeMem(Pointer) NdisFreeMemory((PVOID)(Pointer), 0, 0)
#endif // AUDIT_MEM
/*++
VOID
RCAInitLock(
IN PNDIS_SPIN_LOCK pLock
);
--*/
#define RCAInitLock(pLock) NdisAllocateSpinLock(pLock)
/*++
VOID
RCAFreeLock(
IN PNDIS_SPIN_LOCK pLock
);
--*/
#define RCAFreeLock(pLock) NdisFreeSpinLock(pLock)
/*++
VOID
RCAAcquireLock(
IN PNDIS_SPIN_LOCK pLock
);
--*/
#define RCAAcquireLock(pLock) NdisAcquireSpinLock(pLock)
/*++
VOID
RCAReleaseLock(
IN PNDIS_SPIN_LOCK pLock
);
--*/
#define RCAReleaseLock(pLock) NdisReleaseSpinLock(pLock)
extern
VOID
RCASetMemory(
IN PUCHAR pStart,
IN UCHAR Value,
IN ULONG NumberOfBytes
);
extern
BOOLEAN
RCAInit(
VOID
);
extern
VOID
RCAUnload(
IN PDRIVER_OBJECT DriverObject
);
extern
NTSTATUS
FilterTopologyProperty(
IN PIRP Irp,
IN PKSPROPERTY Property,
IN OUT PVOID Data
);
extern
NTSTATUS
FilterPinProperty(
IN PIRP Irp,
IN PKSPROPERTY Property,
IN OUT PVOID Data
);
extern
NTSTATUS
FilterPinInstances(
IN PIRP Irp,
IN PKSP_PIN Pin,
OUT PKSPIN_CINSTANCES Instances
);
extern
NTSTATUS
FilterPinIntersection(
IN PIRP Irp,
IN PKSP_PIN Pin,
OUT PVOID Data
);
extern
NTSTATUS
FilterDispatchClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
extern
NTSTATUS
FilterDispatchIoControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
extern
NTSTATUS
PinDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
extern
NTSTATUS
FilterDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
extern
VOID
RCAReceiveCallback(
IN PVOID RcaVcContext,
IN PVOID ClientReceiveContext,
IN PNDIS_PACKET pPacket
);
extern
VOID
RCASendCompleteCallback(
IN PVOID RcaVcContext,
IN PVOID ClientSendContext,
IN PVOID PacketContext,
IN PMDL pSentMdl,
IN NDIS_STATUS Status
);
extern
VOID
RCAVcCloseCallback(
IN PVOID RcaVcContext,
IN PVOID ClientReceiveContext,
IN PVOID ClientSendContext
);
extern
NTSTATUS
WriteStream(
IN PIRP Irp,
IN PPIN_INSTANCE_DEVIO PinInstance
);
extern
NTSTATUS
ReadStream(
IN PIRP Irp,
IN PPIN_INSTANCE_DEVIO PinInstance
);
extern
NTSTATUS
PinDispatchIoControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
extern
NTSTATUS
InitializeDevIoPin(
IN PIRP Irp,
IN BOOLEAN Read,
IN PFILTER_INSTANCE FilterInstance,
IN PKSDATAFORMAT DataFormat
);
extern
NTSTATUS
PinDispatchClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
extern
NTSTATUS
GetInterface(
IN PIRP Irp,
IN PKSPROPERTY Property,
OUT PKSPIN_INTERFACE Interface
);
extern VOID
RCAIoWorker(
IN PNDIS_WORK_ITEM pNdisWorkItem,
IN PVOID Context
);
extern
NTSTATUS
RCAIoComplete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
extern
VOID
RCASHPoolInit(
VOID
);
extern
PRCA_STREAM_HEADER
RCASHPoolGet(
VOID
);
extern
VOID
RCASHPoolReturn(
IN PRCA_STREAM_HEADER StreamHeader
);
extern
VOID
RCASHPoolFree(
VOID
);
extern
NTSTATUS
PinDeviceState(
IN PIRP Irp,
IN PKSPROPERTY Property,
IN OUT PKSSTATE DeviceState
);
extern
NTSTATUS
RCAGenericIntersection(
IN PIRP Irp,
IN PKSDATARANGE DataRange,
IN ULONG OutputBufferLength,
OUT PVOID Data
);
extern
VOID
RCADumpGUID(
INT DebugLevel,
GUID *Guid
);
extern
NTSTATUS
RCADumpKsPropertyInfo(
INT DebugLevel,
PIRP pIrp
);
#if DBG
#define RCA_GET_ENTRY_IRQL(Irql) Irql = KeGetCurrentIrql()
#define RCA_CHECK_EXIT_IRQL(EntryIrql) \
{ \
KIRQL ExitIrql; \
\
ExitIrql = KeGetCurrentIrql(); \
if (ExitIrql != EntryIrql) \
{ \
DbgPrint("File %s, Line %d, Exit IRQ %d != Entry IRQ %d\n", \
__FILE__, __LINE__, ExitIrql, EntryIrql); \
DbgBreakPoint(); \
} \
}
#else
#define RCA_GET_ENTRY_IRQL(Irql)
#define RCA_CHECK_EXIT_IRQL(EntryIrql)
#endif // DBG
#endif // _RCA__H