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

  1. /*++
  2. Copyright (c) 1995-1998 Microsoft Corporation
  3. Module Name:
  4. RCA.h
  5. Abstract:
  6. The module defines the constants, structures and function templates for
  7. the NDIS RCA
  8. Author:
  9. Richard Machin (RMachin)
  10. Revision History:
  11. Who When What
  12. -------- -------- ----------------------------------------------
  13. RMachin 10-3-96 created
  14. JameelH 4-18-98 Cleanup
  15. SPATHER 4-20-99 Cleanup, separated out all NDIS components
  16. --*/
  17. #ifndef _RCA__H
  18. #define _RCA__H
  19. #include "mmsystem.h"
  20. #define NOBITMAP
  21. #include "mmreg.h"
  22. #undef NOBITMAP
  23. #include "ks.h"
  24. #include "ksmedia.h"
  25. #include <pxdebug.h>
  26. #include <ntddk.h>
  27. #include <windef.h>
  28. #define AUDIO_SINK_FLAG 1
  29. //
  30. // Signature used for all pool allocs
  31. //
  32. #define rca_signature ' ACR'
  33. #define MODULE_INIT 0x00010000
  34. #define MODULE_NTINIT 0x00020000
  35. #define MODULE_CO 0x00030000
  36. #define MODULE_CL 0x00040000
  37. #define MODULE_DEBUG 0x00050000
  38. #define MODULE_CM 0x00060000
  39. #define MODULE_UTIL 0x00070000
  40. #define MODULE_CFG 0x00080000
  41. #define MODULE_TAPI 0x00100000
  42. #define MODULE_FLT 0x00200000
  43. #define MODULE_STRM 0x00300000
  44. #define MODULE_COCL 0x00400000
  45. #define MODULE_NDIS 0x00500000
  46. #define MODULE_KSNDIS 0x00600000
  47. #ifndef ULONG_MAX
  48. #define ULONG_MAX 0xffffffffUL
  49. #endif
  50. #if DBG
  51. #ifndef DEBUG
  52. #define DEBUG
  53. #endif
  54. #endif
  55. #if MY_ASSERT
  56. #undef ASSERT
  57. #define ASSERT(exp) \
  58. if (!(exp)) \
  59. {\
  60. DbgPrint( #exp, __FILE__, __LINE__, NULL );\
  61. DbgBreakPoint();\
  62. }
  63. #endif
  64. #if PACKET_POOL_OPTIMIZATION
  65. // SendPPOpt - Start
  66. #define SENDPPOPT_NUM_BUCKETS 10000
  67. extern LONG g_alSendPPOptBuckets[SENDPPOPT_NUM_BUCKETS];
  68. extern LONG g_lSendPPOptOutstanding;
  69. extern NDIS_SPIN_LOCK g_SendPPOptLock;
  70. // SendPPOpt - End
  71. // RecvPPOpt - Start
  72. #define RECVPPOPT_NUM_BUCKETS 10000
  73. extern LONG g_alRecvPPOptBuckets[RECVPPOPT_NUM_BUCKETS];
  74. extern LONG g_lRecvPPOptOutstanding;
  75. extern NDIS_SPIN_LOCK g_RecvPPOptLock;
  76. // RecvPPOpt - End
  77. #endif // PACKET_POOL_OPTIMIZATION
  78. //
  79. // Various constants used all over.
  80. //
  81. #define MAXNUM_PIN_TYPES 2
  82. #define MIN_PACKETS_POOL 40
  83. #define MAX_PACKETS_POOL 10000
  84. #define ID_DEVIO_PIN 1
  85. #define ID_BRIDGE_PIN 0
  86. #define RCA_SAP_REG_TIMEOUT 5000 // MS to block filterdispatchcreate waiting for SAP registration to finish.
  87. //
  88. // Structure and macros used to block / unblock the current thread.
  89. //
  90. typedef struct _RCABlockStruc {
  91. NDIS_EVENT Event;
  92. NDIS_STATUS TheStatus;
  93. } RCABlockStruc, *PRCABlockStruc;
  94. /*++
  95. VOID
  96. RCAInitBlockStruc(
  97. IN RCABlockStruc *pBlock
  98. );
  99. --*/
  100. #define RCAInitBlockStruc(pBlock) NdisInitializeEvent(&(pBlock)->Event)
  101. /*++
  102. VOID
  103. RCABlock(
  104. IN RCABlockStruc *pBlock,
  105. OUT NDIS_STATUS *pStatus
  106. );
  107. --*/
  108. #define RCABlock(pBlock, pStatus) \
  109. { \
  110. NdisWaitEvent(&(pBlock)->Event, 0); \
  111. *(pStatus) = (pBlock)->TheStatus; \
  112. }
  113. /*++
  114. VOID
  115. RCABlockTimeOut(
  116. IN RCABlockStruc *pBlock,
  117. IN UINT MsToWait
  118. OUT NDIS_STATUS *pStatus
  119. );
  120. --*/
  121. #define RCABlockTimeOut(pBlock, MsToWait, pStatus) \
  122. { \
  123. if (NdisWaitEvent(&(pBlock)->Event, MsToWait)) \
  124. *(pStatus) = (pBlock)->TheStatus; \
  125. else \
  126. *(pStatus) = STATUS_TIMEOUT; \
  127. }
  128. /*++
  129. VOID
  130. RCASignal(
  131. IN RCABlockStruc *pBlock,
  132. IN UINT Status
  133. );
  134. --*/
  135. #define RCASignal(pBlock, Status) \
  136. { \
  137. (pBlock)->TheStatus = Status; \
  138. NdisSetEvent(&((pBlock)->Event)); \
  139. }
  140. typedef ULONG_PTR FILTER_TYPE;
  141. #define FilterTypeRender (FILTER_TYPE)0
  142. #define FilterTypeCapture (FILTER_TYPE)1
  143. typedef struct _DEVICE_INSTANCE
  144. {
  145. //
  146. // KS-managed header
  147. //
  148. KSDEVICE_HEADER Header;
  149. KSPIN_CINSTANCES PinInstances[ MAXNUM_PIN_TYPES ];
  150. } DEVICE_INSTANCE, *PDEVICE_INSTANCE;
  151. //
  152. // The RCA Stream Header structure (this incorparates a KS Stream Header)
  153. //
  154. typedef struct _RCA_STREAM_HEADER {
  155. LIST_ENTRY ListEntry;
  156. KSSTREAM_HEADER Header;
  157. PNDIS_PACKET NdisPacket; // CLEANUP: Take this out.
  158. ULONG RefCount; // FIXME: NOT YET IMPLEMENTED
  159. } RCA_STREAM_HEADER, *PRCA_STREAM_HEADER;
  160. //
  161. // The Stream Header Pool structure
  162. //
  163. typedef struct _RCA_SH_POOL {
  164. LONG FailCount;
  165. IO_STATUS_BLOCK IoStatus; // HACK:Common IO Status block for all stream IRPs
  166. NPAGED_LOOKASIDE_LIST LookAsideList;
  167. } RCA_SH_POOL, *PRCA_SH_POOL;
  168. //
  169. // Our global device extension
  170. //
  171. PDEVICE_INSTANCE DeviceExtension;
  172. //
  173. // Globals
  174. //
  175. extern const KSDISPATCH_TABLE FilterDispatchTable;
  176. extern const KSPIN_CINSTANCES PinInstances[MAXNUM_PIN_TYPES];
  177. //
  178. // Here's where we keep info that's common across FDOs (shared
  179. // by capture and render devices)
  180. //
  181. typedef struct RCA_GLOBAL
  182. {
  183. ULONG Status;
  184. LONG QueueSize;
  185. NDIS_SPIN_LOCK SpinLock; // SpinLock for this structure
  186. PDRIVER_OBJECT pDriverObject; // passed in DriverEntry
  187. PDEVICE_OBJECT pFunctionalDeviceObject;// created by IoCreateDevice
  188. KSOBJECT_CREATE_ITEM FilterCreateItems[2];
  189. RCA_SH_POOL SHPool; // Pool of stream headers that Capture devices use
  190. BOOL bProtocolInitialized; // True if RCACoNdisInitialize has been called.
  191. } RCA_GLOBAL, *PRCA_GLOGBAL;
  192. extern RCA_GLOBAL RcaGlobal;
  193. #define RCA_ACQUIRE_GLOBAL_LOCK() RCAAcquireLock(&RcaGlobal.SpinLock);
  194. #define RCA_RELEASE_GLOBAL_LOCK() RCAReleaseLock(&RcaGlobal.SpinLock);
  195. //
  196. // Pin constants
  197. //
  198. // 2 PINs on each type of filter (capture or render): bridge-to-net, and dataio
  199. extern const KSPIN_DESCRIPTOR PinDescriptors[2]; // CLEANUP: This is sketchy, see if it's really needed.
  200. typedef struct _FILTER_CONNECTION
  201. {
  202. LIST_ENTRY ListEntry; // used only for destination lists
  203. PFILE_OBJECT FileObject; // The connected pin file object.
  204. PFILE_OBJECT NextFileObject; // The chained file object
  205. } FILTER_CONNECTION;
  206. typedef struct
  207. {
  208. KSOBJECT_HEADER Header;
  209. ULONG PinId;
  210. } PIN_INSTANCE_HEADER, *PPIN_INSTANCE_HEADER;
  211. typedef struct _FILTER_INSTANCE FILTER_INSTANCE, *PFILTER_INSTANCE;
  212. typedef struct
  213. {
  214. PIN_INSTANCE_HEADER InstanceHdr;
  215. LIST_ENTRY EventQueue;
  216. FAST_MUTEX EventQueueLock;
  217. KSSTATE DeviceState;
  218. PVOID VcContext;
  219. PFILTER_INSTANCE FilterInstance;
  220. BOOL ConnectedAsSink;
  221. LIST_ENTRY ActiveQueue;
  222. KSPIN_LOCK QueueLock;
  223. PVOID AllocatorObject;
  224. } PIN_INSTANCE_DEVIO, *PPIN_INSTANCE_DEVIO;
  225. typedef struct
  226. {
  227. PIN_INSTANCE_HEADER InstanceHdr;
  228. LIST_ENTRY EventQueue;
  229. FAST_MUTEX EventQueueLock;
  230. KSSTATE Unused;
  231. PVOID VcContext;
  232. NDIS_WORK_ITEM WorkItem;
  233. BOOL bWorkItemQueued;
  234. LIST_ENTRY WorkQueue;
  235. PFILTER_INSTANCE FilterInstance;
  236. KSPIN_LOCK SpinLock;
  237. KIRQL OldIrql;
  238. RCABlockStruc Block;
  239. BOOL SignalMe;
  240. PKSDATAFORMAT pDataFormat;
  241. LONGLONG PendingSendsCount;
  242. RCABlockStruc PendingSendsBlock;
  243. BOOL SignalWhenSendsComplete;
  244. } PIN_INSTANCE_BRIDGE, *PPIN_INSTANCE_BRIDGE;
  245. #if DBG
  246. #define RCA_ACQUIRE_BRIDGE_PIN_LOCK(pBridgePin) \
  247. {\
  248. KeAcquireSpinLock(&((pBridgePin)->SpinLock), &((pBridgePin)->OldIrql));\
  249. if (RCADebugLevel == RCA_LOCKS) {\
  250. DbgPrint("BRIDGE PIN LOCK (0x%x) ACQUIRED at module %x, line %d\n",\
  251. &((pBridgePin)->SpinLock), MODULE_NUMBER >> 16, __LINE__);\
  252. }\
  253. }
  254. #define RCA_RELEASE_BRIDGE_PIN_LOCK(pBridgePin) \
  255. {\
  256. KeReleaseSpinLock(&((pBridgePin)->SpinLock), (pBridgePin)->OldIrql);\
  257. if (RCADebugLevel == RCA_LOCKS) { \
  258. DbgPrint("BRIDGE PIN LOCK (0x%x) RELEASED at module %x, line %d\n",\
  259. &((pBridgePin)->SpinLock), MODULE_NUMBER >> 16, __LINE__);\
  260. } \
  261. }
  262. #else
  263. #define RCA_ACQUIRE_BRIDGE_PIN_LOCK(pBridgePin) KeAcquireSpinLock(&((pBridgePin)->SpinLock), &((pBridgePin)->OldIrql));
  264. #define RCA_RELEASE_BRIDGE_PIN_LOCK(pBridgePin) KeReleaseSpinLock(&((pBridgePin)->SpinLock), (pBridgePin)->OldIrql);
  265. #endif
  266. typedef struct _FILTER_INSTANCE
  267. {
  268. KSOBJECT_HEADER Header;
  269. FILTER_TYPE FilterType;
  270. KMUTEX ControlMutex;
  271. PFILE_OBJECT PinFileObjects[SIZEOF_ARRAY(PinDescriptors)];
  272. PPIN_INSTANCE_BRIDGE BridgePin;
  273. PPIN_INSTANCE_DEVIO DevIoPin;
  274. PKSDATAFORMAT_WAVEFORMATEX WaveFormat;
  275. KSDATAFORMAT DataFormat;
  276. PFILE_OBJECT NextFileObject, ConnectedFileObject;
  277. FILTER_CONNECTION Connections[2];
  278. KSPIN_CINSTANCES PinInstances[2];
  279. } FILTER_INSTANCE, *PFILTER_INSTANCE;
  280. NTSTATUS
  281. PnpAddDevice(
  282. IN PDRIVER_OBJECT DriverObject,
  283. IN PDEVICE_OBJECT PhysicalDeviceObject
  284. );
  285. NTSTATUS
  286. PinDispatchCreate(
  287. IN PDEVICE_OBJECT DeviceObject,
  288. IN PIRP Irp
  289. );
  290. #define LinkDoubleAtHead(_pHead, _p, Next, Prev) \
  291. { \
  292. (_p)->Next = (_pHead); \
  293. (_p)->Prev = &(_pHead); \
  294. if ((_pHead) != NULL) \
  295. (_pHead)->Prev = &(_p)->Next; \
  296. (_pHead) = (_p); \
  297. }
  298. #define LinkDoubleAtTail(_pThis, _pLast, Next, Prev) \
  299. { \
  300. (_pLast)->Next = (_pThis); \
  301. (_pThis)->Prev = &(_pLast)->Next; \
  302. (_pThis)->Next = NULL; \
  303. }
  304. #define InsertDoubleBefore(_pThis, _pBefore, Next, Prev) \
  305. { \
  306. (_pThis)->Next = (_pBefore); \
  307. (_pThis)->Prev = (_pBefore)->Prev; \
  308. (_pBefore)->Prev = &(_pThis)->Next; \
  309. *((_pThis)->Prev) = (_pThis); \
  310. }
  311. #define UnlinkDouble(_p, Next, Prev) \
  312. { \
  313. *((_p)->Prev) = (_p)->Next; \
  314. if ((_p)->Next != NULL) \
  315. (_p)->Next->Prev = (_p)->Prev; \
  316. }
  317. //
  318. // Work Queue list entry
  319. //
  320. typedef struct
  321. {
  322. LIST_ENTRY ListEntry;
  323. union {
  324. PVOID PacketContext;
  325. PRCA_STREAM_HEADER StreamHeader;
  326. };
  327. union {
  328. // PRCA_VC pRcaVc; //CLEANUP: Remove this
  329. PMDL Mdl;
  330. };
  331. BOOL bFreeThisPacket;
  332. } WORK_ITEM, PKT_RSVD, *PWORK_ITEM, *PPKT_RSVD;
  333. #define PKT_RSVD_FROM_PKT(_pPkt) ((PPKT_RSVD)((_pPkt)->ProtocolReserved))
  334. #define WORK_ITEM_FROM_PKT(_pPkt) ((PWORK_ITEM)((_pPkt)->ProtocolReserved))
  335. #ifndef STRUCT_OF
  336. #define STRUCT_OF(_Type, _Addr, _Field) CONTAINING_RECORD(_Addr, _Type, _Field)
  337. #endif
  338. #ifndef MAX
  339. #define MAX(Fred, Shred) (((Fred) > (Shred)) ? (Fred) : (Shred))
  340. #endif // MAX
  341. #ifndef MIN
  342. #define MIN(Fred, Shred) (((Fred) < (Shred)) ? (Fred) : (Shred))
  343. #endif // MIN
  344. /*++
  345. VOID
  346. RCAMemSet(
  347. IN POPAQUE Pointer,
  348. IN UCHAR Value,
  349. IN ULONG Length
  350. );
  351. --*/
  352. #define RCAMemSet(Pointer, Value, Length) NdisFillMemory((PUCHAR)(Pointer), (ULONG)(Length), (UCHAR)(Value))
  353. /*++
  354. VOID
  355. RCAMemCopy(
  356. IN POPAQUE Destn,
  357. IN POPAQUE Source,
  358. IN ULONG Length
  359. );
  360. --*/
  361. #define RCAMemCopy(Destn, Source, Length) NdisMoveMemory((Destn), (Source), (Length))
  362. #define RCA_TAG ((ULONG)'FACR')
  363. #if DBG
  364. #undef AUDIT_MEM
  365. #define AUDIT_MEM 1
  366. #endif
  367. /*++
  368. PVOID
  369. RCAAllocMem(
  370. IN ULONG Size
  371. );
  372. --*/
  373. #if AUDIT_MEM
  374. #define RCAAllocMem(Pointer, TYPE, Size) Pointer = (TYPE *)RCAAuditAllocMem((PVOID)(&(Pointer)), Size, _FILENUMBER, __LINE__);
  375. #else // AUDIT_MEM
  376. #define RCAAllocMem(Pointer, TYPE, Size) NdisAllocateMemoryWithTag((PVOID)(&Pointer), (ULONG)Size, RCA_TAG)
  377. #endif // AUDIT_MEM
  378. /*++
  379. VOID
  380. RCAFreeMem(
  381. IN PVOID Pointer
  382. );
  383. --*/
  384. #if AUDIT_MEM
  385. #define RCAFreeMem(Pointer) RCAAuditFreeMem((PVOID)Pointer)
  386. #else
  387. #define RCAFreeMem(Pointer) NdisFreeMemory((PVOID)(Pointer), 0, 0)
  388. #endif // AUDIT_MEM
  389. /*++
  390. VOID
  391. RCAInitLock(
  392. IN PNDIS_SPIN_LOCK pLock
  393. );
  394. --*/
  395. #define RCAInitLock(pLock) NdisAllocateSpinLock(pLock)
  396. /*++
  397. VOID
  398. RCAFreeLock(
  399. IN PNDIS_SPIN_LOCK pLock
  400. );
  401. --*/
  402. #define RCAFreeLock(pLock) NdisFreeSpinLock(pLock)
  403. /*++
  404. VOID
  405. RCAAcquireLock(
  406. IN PNDIS_SPIN_LOCK pLock
  407. );
  408. --*/
  409. #define RCAAcquireLock(pLock) NdisAcquireSpinLock(pLock)
  410. /*++
  411. VOID
  412. RCAReleaseLock(
  413. IN PNDIS_SPIN_LOCK pLock
  414. );
  415. --*/
  416. #define RCAReleaseLock(pLock) NdisReleaseSpinLock(pLock)
  417. extern
  418. VOID
  419. RCASetMemory(
  420. IN PUCHAR pStart,
  421. IN UCHAR Value,
  422. IN ULONG NumberOfBytes
  423. );
  424. extern
  425. BOOLEAN
  426. RCAInit(
  427. VOID
  428. );
  429. extern
  430. VOID
  431. RCAUnload(
  432. IN PDRIVER_OBJECT DriverObject
  433. );
  434. extern
  435. NTSTATUS
  436. FilterTopologyProperty(
  437. IN PIRP Irp,
  438. IN PKSPROPERTY Property,
  439. IN OUT PVOID Data
  440. );
  441. extern
  442. NTSTATUS
  443. FilterPinProperty(
  444. IN PIRP Irp,
  445. IN PKSPROPERTY Property,
  446. IN OUT PVOID Data
  447. );
  448. extern
  449. NTSTATUS
  450. FilterPinInstances(
  451. IN PIRP Irp,
  452. IN PKSP_PIN Pin,
  453. OUT PKSPIN_CINSTANCES Instances
  454. );
  455. extern
  456. NTSTATUS
  457. FilterPinIntersection(
  458. IN PIRP Irp,
  459. IN PKSP_PIN Pin,
  460. OUT PVOID Data
  461. );
  462. extern
  463. NTSTATUS
  464. FilterDispatchClose(
  465. IN PDEVICE_OBJECT DeviceObject,
  466. IN PIRP Irp
  467. );
  468. extern
  469. NTSTATUS
  470. FilterDispatchIoControl(
  471. IN PDEVICE_OBJECT DeviceObject,
  472. IN PIRP Irp
  473. );
  474. extern
  475. NTSTATUS
  476. PinDispatchCreate(
  477. IN PDEVICE_OBJECT DeviceObject,
  478. IN PIRP Irp
  479. );
  480. extern
  481. NTSTATUS
  482. FilterDispatchCreate(
  483. IN PDEVICE_OBJECT DeviceObject,
  484. IN PIRP Irp
  485. );
  486. extern
  487. VOID
  488. RCAReceiveCallback(
  489. IN PVOID RcaVcContext,
  490. IN PVOID ClientReceiveContext,
  491. IN PNDIS_PACKET pPacket
  492. );
  493. extern
  494. VOID
  495. RCASendCompleteCallback(
  496. IN PVOID RcaVcContext,
  497. IN PVOID ClientSendContext,
  498. IN PVOID PacketContext,
  499. IN PMDL pSentMdl,
  500. IN NDIS_STATUS Status
  501. );
  502. extern
  503. VOID
  504. RCAVcCloseCallback(
  505. IN PVOID RcaVcContext,
  506. IN PVOID ClientReceiveContext,
  507. IN PVOID ClientSendContext
  508. );
  509. extern
  510. NTSTATUS
  511. WriteStream(
  512. IN PIRP Irp,
  513. IN PPIN_INSTANCE_DEVIO PinInstance
  514. );
  515. extern
  516. NTSTATUS
  517. ReadStream(
  518. IN PIRP Irp,
  519. IN PPIN_INSTANCE_DEVIO PinInstance
  520. );
  521. extern
  522. NTSTATUS
  523. PinDispatchIoControl(
  524. IN PDEVICE_OBJECT DeviceObject,
  525. IN PIRP Irp
  526. );
  527. extern
  528. NTSTATUS
  529. InitializeDevIoPin(
  530. IN PIRP Irp,
  531. IN BOOLEAN Read,
  532. IN PFILTER_INSTANCE FilterInstance,
  533. IN PKSDATAFORMAT DataFormat
  534. );
  535. extern
  536. NTSTATUS
  537. PinDispatchClose(
  538. IN PDEVICE_OBJECT DeviceObject,
  539. IN PIRP Irp
  540. );
  541. extern
  542. NTSTATUS
  543. GetInterface(
  544. IN PIRP Irp,
  545. IN PKSPROPERTY Property,
  546. OUT PKSPIN_INTERFACE Interface
  547. );
  548. extern VOID
  549. RCAIoWorker(
  550. IN PNDIS_WORK_ITEM pNdisWorkItem,
  551. IN PVOID Context
  552. );
  553. extern
  554. NTSTATUS
  555. RCAIoComplete(
  556. IN PDEVICE_OBJECT DeviceObject,
  557. IN PIRP Irp,
  558. IN PVOID Context
  559. );
  560. extern
  561. VOID
  562. RCASHPoolInit(
  563. VOID
  564. );
  565. extern
  566. PRCA_STREAM_HEADER
  567. RCASHPoolGet(
  568. VOID
  569. );
  570. extern
  571. VOID
  572. RCASHPoolReturn(
  573. IN PRCA_STREAM_HEADER StreamHeader
  574. );
  575. extern
  576. VOID
  577. RCASHPoolFree(
  578. VOID
  579. );
  580. extern
  581. NTSTATUS
  582. PinDeviceState(
  583. IN PIRP Irp,
  584. IN PKSPROPERTY Property,
  585. IN OUT PKSSTATE DeviceState
  586. );
  587. extern
  588. NTSTATUS
  589. RCAGenericIntersection(
  590. IN PIRP Irp,
  591. IN PKSDATARANGE DataRange,
  592. IN ULONG OutputBufferLength,
  593. OUT PVOID Data
  594. );
  595. extern
  596. VOID
  597. RCADumpGUID(
  598. INT DebugLevel,
  599. GUID *Guid
  600. );
  601. extern
  602. NTSTATUS
  603. RCADumpKsPropertyInfo(
  604. INT DebugLevel,
  605. PIRP pIrp
  606. );
  607. #if DBG
  608. #define RCA_GET_ENTRY_IRQL(Irql) Irql = KeGetCurrentIrql()
  609. #define RCA_CHECK_EXIT_IRQL(EntryIrql) \
  610. { \
  611. KIRQL ExitIrql; \
  612. \
  613. ExitIrql = KeGetCurrentIrql(); \
  614. if (ExitIrql != EntryIrql) \
  615. { \
  616. DbgPrint("File %s, Line %d, Exit IRQ %d != Entry IRQ %d\n", \
  617. __FILE__, __LINE__, ExitIrql, EntryIrql); \
  618. DbgBreakPoint(); \
  619. } \
  620. }
  621. #else
  622. #define RCA_GET_ENTRY_IRQL(Irql)
  623. #define RCA_CHECK_EXIT_IRQL(EntryIrql)
  624. #endif // DBG
  625. #endif // _RCA__H