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.

523 lines
21 KiB

  1. /*++
  2. Copyright (c) 2000-2000 Microsoft Corporation
  3. Module Name:
  4. Macroes.h
  5. Abstract:
  6. This module contains definitions of commonly used macroes
  7. Author:
  8. Mohammad Shabbir Alam (MAlam) 3-30-2000
  9. Revision History:
  10. --*/
  11. #ifndef _MACROES_H_
  12. #define _MACROES_H_
  13. #define MAX_DEBUG_MESSAGE_LENGTH 300
  14. //
  15. // Debug Flags
  16. //
  17. #define DBG_ENABLE_DBGPRINT 0x00000001
  18. #define DBG_DRIVER_ENTRY 0x00000002
  19. #define DBG_INIT_PGM 0x00000004
  20. #define DBG_DEBUG_REF 0x00000008
  21. #define DBG_PNP 0x00000010
  22. #define DBG_TDI 0x00000020
  23. #define DBG_ADDRESS 0x00000040
  24. #define DBG_CONNECT 0x00000080
  25. #define DBG_QUERY 0x00000100
  26. #define DBG_SEND 0x00000200
  27. #define DBG_RECEIVE 0x00000400
  28. #define DBG_FILEIO 0x00000800
  29. #define DBG_FEC 0x00001000
  30. //
  31. // DbgPrint macroes
  32. //
  33. enum eSEVERITY_LEVEL
  34. {
  35. PGM_LOG_DISABLED, // No logging!
  36. PGM_LOG_CRITICAL_ERROR, // Major errors which can seriously affect functionality
  37. PGM_LOG_ERROR, // Common errors which do not affect the system as a whole
  38. PGM_LOG_INFORM_STATUS, // Mostly to verify major functionality was executed
  39. PGM_LOG_INFORM_ALL_FUNCS, // 1 per function to allow path tracking (not req if printing all code paths)
  40. PGM_LOG_INFORM_PATH, // Interspersed throughout function to trace If paths
  41. PGM_LOG_INFORM_DETAIL, // while loops, etc
  42. PGM_LOG_INFORM_REFERENCES, //
  43. PGM_LOG_EVERYTHING
  44. };
  45. #if DBG
  46. //
  47. // ASSERT
  48. //
  49. #undef ASSERT
  50. #define ASSERT(exp) \
  51. if (!(exp)) \
  52. { \
  53. DbgPrint("Assertion \"%s\" failed at file %s, line %d\n", #exp, __FILE__, __LINE__ ); \
  54. if (!PgmDynamicConfig.DoNotBreakOnAssert) \
  55. { \
  56. DbgBreakPoint(); \
  57. } \
  58. }
  59. #endif // DBG
  60. //
  61. // Data/pointer verification
  62. //
  63. #define PGM_VERIFY_HANDLE(p, V) \
  64. ((p) && (p->Verify == V))
  65. #define PGM_VERIFY_HANDLE2(p, V1, V2) \
  66. ((p) && ((p->Verify == V1) || (p->Verify == V2)))
  67. #define PGM_VERIFY_HANDLE3(p, V1, V2, V3) \
  68. ((p) && ((p->Verify == V1) || (p->Verify == V2) || (p->Verify == V3)))
  69. //----------------------------------------------------------------------------
  70. //
  71. // Sequence number macroes
  72. //
  73. #define SEQ_LT(a,b) ((SIGNED_SEQ_TYPE)((a)-(b)) < 0)
  74. #define SEQ_LEQ(a,b) ((SIGNED_SEQ_TYPE)((a)-(b)) <= 0)
  75. #define SEQ_GT(a,b) ((SIGNED_SEQ_TYPE)((a)-(b)) > 0)
  76. #define SEQ_GEQ(a,b) ((SIGNED_SEQ_TYPE)((a)-(b)) >= 0)
  77. //----------------------------------------------------------------------------
  78. //
  79. // Definitions:
  80. //
  81. #define IS_MCAST_ADDRESS(IpAddress) ((((PUCHAR)(&IpAddress))[3]) >= ((UCHAR)0xe0))
  82. #define CLASSD_ADDR(a) (( (*((uchar *)&(a))) & 0xf0) == 0xe0)
  83. //
  84. // Alloc and Free macroes
  85. //
  86. #define PGM_TAG(x) (((x)<<24)|'\0mgP')
  87. #define PgmAllocMem(_Size, _Tag) \
  88. ExAllocatePoolWithTag(NonPagedPool, (_Size),(_Tag))
  89. #define PgmFreeMem(_Ptr) ExFreePool(_Ptr)
  90. //
  91. // Misc Ke + Ex macroes
  92. //
  93. #define PgmGetCurrentIrql KeGetCurrentIrql
  94. #define PgmInterlockedInsertTailList(_pHead, _pEntry, _pStruct) \
  95. ExInterlockedInsertTailList(_pHead, _pEntry, &(_pStruct)->LockInfo.SpinLock);
  96. //----------------------------------------------------------------------------
  97. //
  98. // PgmAcquireResourceExclusive (Resource, Wait)
  99. //
  100. /*++
  101. Routine Description:
  102. Acquires the Resource by calling an executive support routine.
  103. Arguments:
  104. Return Value:
  105. None
  106. --*/
  107. //
  108. // Resource Macros
  109. //
  110. #define PgmAcquireResourceExclusive( _Resource, _Wait ) \
  111. KeEnterCriticalRegion(); \
  112. ExAcquireResourceExclusiveLite(_Resource,_Wait);
  113. //----------------------------------------------------------------------------
  114. //
  115. // PgmReleaseResource (Resource)
  116. //
  117. /*++
  118. Routine Description:
  119. Releases the Resource by calling an excutive support routine.
  120. Arguments:
  121. Return Value:
  122. None
  123. --*/
  124. #define PgmReleaseResource( _Resource ) \
  125. ExReleaseResourceLite(_Resource); \
  126. KeLeaveCriticalRegion();
  127. //----------------------------------------------------------------------------
  128. //++
  129. //
  130. // LARGE_INTEGER
  131. // PgmConvert100nsToMilliseconds(
  132. // IN LARGE_INTEGER HnsTime
  133. // );
  134. //
  135. // Routine Description:
  136. //
  137. // Converts time expressed in hundreds of nanoseconds to milliseconds.
  138. //
  139. // Arguments:
  140. //
  141. // HnsTime - Time in hundreds of nanoseconds.
  142. //
  143. // Return Value:
  144. //
  145. // Time in milliseconds.
  146. //
  147. //--
  148. #define SHIFT10000 13
  149. static LARGE_INTEGER Magic10000 = {0xe219652c, 0xd1b71758};
  150. #define PgmConvert100nsToMilliseconds(HnsTime) \
  151. RtlExtendedMagicDivide((HnsTime), Magic10000, SHIFT10000)
  152. //----------------------------------------------------------------------------
  153. //
  154. // Lock Macroes
  155. //
  156. #if DBG
  157. #define PgmInitLock(_Struct, _N) \
  158. KeInitializeSpinLock (&(_Struct)->LockInfo.SpinLock); \
  159. (_Struct)->LockInfo.LockNumber = _N;
  160. #else
  161. #define PgmInitLock(_Struct, _N) \
  162. KeInitializeSpinLock (&(_Struct)->LockInfo.SpinLock);
  163. #endif // DBG
  164. typedef KIRQL PGMLockHandle;
  165. #if DBG
  166. #define PgmLock(_Struct, _OldIrqLevel) \
  167. { \
  168. ULONG CurrProc; \
  169. ExAcquireSpinLock (&(_Struct)->LockInfo.SpinLock, &(_OldIrqLevel)); \
  170. CurrProc = KeGetCurrentProcessorNumber(); \
  171. ASSERT ((_Struct)->LockInfo.LockNumber > PgmDynamicConfig.CurrentLockNumber[CurrProc]); \
  172. PgmDynamicConfig.CurrentLockNumber[CurrProc] |= (_Struct)->LockInfo.LockNumber; \
  173. (_Struct)->LockInfo.LastLockLine = __LINE__; \
  174. }
  175. #define PgmLockAtDpc(_Struct) \
  176. { \
  177. ULONG CurrProc; \
  178. ExAcquireSpinLockAtDpcLevel (&(_Struct)->LockInfo.SpinLock); \
  179. CurrProc = KeGetCurrentProcessorNumber(); \
  180. ASSERT ((_Struct)->LockInfo.LockNumber > PgmDynamicConfig.CurrentLockNumber[CurrProc]); \
  181. PgmDynamicConfig.CurrentLockNumber[CurrProc] |= (_Struct)->LockInfo.LockNumber; \
  182. (_Struct)->LockInfo.LastLockLine = __LINE__; \
  183. }
  184. #define PgmUnlock(_Struct, _OldIrqLevel) \
  185. { \
  186. ULONG CurrProc = KeGetCurrentProcessorNumber(); \
  187. ASSERT (PgmDynamicConfig.CurrentLockNumber[CurrProc] & (_Struct)->LockInfo.LockNumber); \
  188. PgmDynamicConfig.CurrentLockNumber[CurrProc] &= ~((_Struct)->LockInfo.LockNumber); \
  189. (_Struct)->LockInfo.LastUnlockLine = __LINE__; \
  190. ExReleaseSpinLock (&(_Struct)->LockInfo.SpinLock, _OldIrqLevel); \
  191. }
  192. // ASSERT ((_Struct)->LockInfo.LockNumber > PgmDynamicConfig.CurrentLockNumber[CurrProc]);
  193. #define PgmUnlockAtDpc(_Struct) \
  194. { \
  195. ULONG CurrProc = KeGetCurrentProcessorNumber(); \
  196. ASSERT (PgmDynamicConfig.CurrentLockNumber[CurrProc] & (_Struct)->LockInfo.LockNumber); \
  197. PgmDynamicConfig.CurrentLockNumber[CurrProc] &= ~((_Struct)->LockInfo.LockNumber); \
  198. (_Struct)->LockInfo.LastUnlockLine = __LINE__; \
  199. ExReleaseSpinLockFromDpcLevel (&(_Struct)->LockInfo.SpinLock); \
  200. }
  201. // ASSERT ((_Struct)->LockInfo.LockNumber > PgmDynamicConfig.CurrentLockNumber[CurrProc]); \
  202. #else
  203. #define PgmLock(_Struct, _OldIrqLevel) \
  204. ExAcquireSpinLock (&(_Struct)->LockInfo.SpinLock, &(_OldIrqLevel));
  205. #define PgmLockAtDpc(_Struct) \
  206. ExAcquireSpinLockAtDpcLevel (&(_Struct)->LockInfo.SpinLock);
  207. #define PgmUnlock(_Struct, _OldIrqLevel) \
  208. ExReleaseSpinLock (&(_Struct)->LockInfo.SpinLock, _OldIrqLevel); \
  209. #define PgmUnlockAtDpc(_Struct) \
  210. ExReleaseSpinLockFromDpcLevel (&(_Struct)->LockInfo.SpinLock); \
  211. #endif // DBG
  212. //
  213. // Memory management macroes
  214. //
  215. #define PgmZeroMemory RtlZeroMemory
  216. #define PgmMoveMemory RtlMoveMemory
  217. #define PgmCopyMemory RtlCopyMemory
  218. #define PgmEqualMemory(_a, _b, _n) memcmp(_a,_b,_n)
  219. //
  220. // Timer Macroes
  221. //
  222. #define MILLISEC_TO_100NS 10000
  223. #define PgmInitTimer(_PgmTimer) \
  224. KeInitializeTimer (&((_PgmTimer)->t_timer));
  225. #define PgmStartTimer(_PgmTimer, _DeltaTimeInMilliSecs, _TimerExpiryRoutine, _Context) \
  226. { \
  227. LARGE_INTEGER Time; \
  228. Time.QuadPart = UInt32x32To64 (_DeltaTimeInMilliSecs, MILLISEC_TO_100NS); \
  229. Time.QuadPart = -(Time.QuadPart); \
  230. KeInitializeDpc (&((_PgmTimer)->t_dpc), (PVOID)_TimerExpiryRoutine, _Context); \
  231. KeSetTimer (&((_PgmTimer)->t_timer), Time, &((_PgmTimer))->t_dpc); \
  232. }
  233. #define PgmStopTimer(_PgmTimer) \
  234. ((int) KeCancelTimer(&((_PgmTimer)->t_timer)))
  235. //
  236. // Referencing and dereferencing macroes
  237. //
  238. #define PGM_REFERENCE_DEVICE( _pPgmDevice, _RefContext, _fLocked) \
  239. { \
  240. PGMLockHandle OldIrq; \
  241. if (!_fLocked) \
  242. { \
  243. PgmLock (_pPgmDevice, OldIrq); \
  244. } \
  245. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_INIT_PGM), "",\
  246. "\t++pPgmDevice[%x]=<%x:%d->%d>, <%d:%s>\n", \
  247. _RefContext, _pPgmDevice,_pPgmDevice->RefCount,(_pPgmDevice->RefCount+1),__LINE__,__FILE__); \
  248. ASSERT (PGM_VERIFY_HANDLE (_pPgmDevice, PGM_VERIFY_DEVICE)); \
  249. ASSERT (++_pPgmDevice->ReferenceContexts[_RefContext]); \
  250. ++_pPgmDevice->RefCount; \
  251. if (!_fLocked) \
  252. { \
  253. PgmUnlock (_pPgmDevice, OldIrq); \
  254. } \
  255. }
  256. #define PGM_REFERENCE_CONTROL( _pControl, _RefContext, _fLocked) \
  257. { \
  258. PGMLockHandle OldIrq; \
  259. if (!_fLocked) \
  260. { \
  261. PgmLock (_pControl, OldIrq); \
  262. } \
  263. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_TDI), "", \
  264. "\t++pControl[%x]=<%x:%d->%d>, <%d:%s>\n", \
  265. _RefContext, _pControl,_pControl->RefCount,(_pControl->RefCount+1),__LINE__,__FILE__); \
  266. ASSERT (PGM_VERIFY_HANDLE (_pControl, PGM_VERIFY_CONTROL)); \
  267. ASSERT (++_pControl->ReferenceContexts[_RefContext]); \
  268. ++_pControl->RefCount; \
  269. if (!_fLocked) \
  270. { \
  271. PgmUnlock (_pControl, OldIrq); \
  272. } \
  273. }
  274. #define PGM_REFERENCE_ADDRESS( _pAddress, _RefContext, _fLocked) \
  275. { \
  276. PGMLockHandle OldIrq; \
  277. if (!_fLocked) \
  278. { \
  279. PgmLock (_pAddress, OldIrq); \
  280. } \
  281. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_ADDRESS), "", \
  282. "\t++pAddress[%x]=<%x:%d->%d>, <%d:%s>\n", \
  283. _RefContext, _pAddress,_pAddress->RefCount,(_pAddress->RefCount+1),__LINE__,__FILE__); \
  284. ASSERT (PGM_VERIFY_HANDLE (_pAddress, PGM_VERIFY_ADDRESS)); \
  285. ASSERT (++_pAddress->ReferenceContexts[_RefContext]); \
  286. ++_pAddress->RefCount; \
  287. if (!_fLocked) \
  288. { \
  289. PgmUnlock (_pAddress, OldIrq); \
  290. } \
  291. }
  292. #define PGM_REFERENCE_SEND_DATA_CONTEXT( _pSendDC, _fLocked) \
  293. { \
  294. PGMLockHandle OldIrq; \
  295. if (!_fLocked) \
  296. { \
  297. PgmLock (_pSendDC->pSend, OldIrq); \
  298. } \
  299. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_SEND), "", \
  300. "\t++pSendDataContext[%x]=<%x:%d->%d>, <%d:%s>\n", \
  301. _RefContext, _pSendDC,_pSendDC->RefCount,(_pSendDC->RefCount+1),__LINE__,__FILE__); \
  302. ASSERT (PGM_VERIFY_HANDLE (_pSendDC, PGM_VERIFY_SEND_DATA_CONTEXT)); \
  303. ++_pSendDC->RefCount; \
  304. if (!_fLocked) \
  305. { \
  306. PgmUnlock (_pSendDC, OldIrq); \
  307. } \
  308. }
  309. #define PGM_REFERENCE_SESSION( _pSession, _Verify, _RefContext, _fLocked) \
  310. { \
  311. PGMLockHandle OldIrq; \
  312. if (!_fLocked) \
  313. { \
  314. PgmLock (_pSession, OldIrq); \
  315. } \
  316. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_CONNECT), "", \
  317. "\t++pSession[%x]=<%x:%d->%d>, <%d:%s>\n", \
  318. _RefContext, _pSession,_pSession->RefCount,(_pSession->RefCount+1),__LINE__,__FILE__); \
  319. ASSERT (PGM_VERIFY_HANDLE2 (_pSession, _Verify, PGM_VERIFY_SESSION_DOWN)); \
  320. ASSERT (++_pSession->ReferenceContexts[_RefContext]); \
  321. ++_pSession->RefCount; \
  322. if (!_fLocked) \
  323. { \
  324. PgmUnlock (_pSession, OldIrq); \
  325. } \
  326. }
  327. #define PGM_REFERENCE_SESSION_SEND( _pSend, _RefContext, _fLocked) \
  328. PGM_REFERENCE_SESSION (_pSend, PGM_VERIFY_SESSION_SEND, _RefContext, _fLocked)
  329. #define PGM_REFERENCE_SESSION_RECEIVE( _pRcv, _RefContext, _fLocked)\
  330. PGM_REFERENCE_SESSION (_pRcv, PGM_VERIFY_SESSION_RECEIVE, _RefContext, _fLocked)
  331. #define PGM_REFERENCE_SESSION_UNASSOCIATED( _pRcv, _RefContext, _fLocked)\
  332. PGM_REFERENCE_SESSION (_pRcv, PGM_VERIFY_SESSION_UNASSOCIATED, _RefContext, _fLocked)
  333. //
  334. // Dereferencing ...
  335. //
  336. #define PGM_DEREFERENCE_DEVICE( _pDevice, _RefContext) \
  337. { \
  338. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_INIT_PGM), "",\
  339. "\t--pDevice[%x]=<%x:%d->%d>, <%d:%s>\n", \
  340. _RefContext, _pDevice,_pDevice->RefCount,(_pDevice->RefCount-1),__LINE__,__FILE__); \
  341. PgmDereferenceDevice (_pDevice, _RefContext); \
  342. }
  343. #define PGM_DEREFERENCE_CONTROL( _pControl, _RefContext) \
  344. { \
  345. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_TDI), "", \
  346. "\t--pControl[%x]=<%x:%d->%d>, <%d:%s>\n", \
  347. _RefContext, _pControl,_pControl->RefCount,(_pControl->RefCount-1),__LINE__,__FILE__); \
  348. PgmDereferenceControl (_pControl, _RefContext); \
  349. }
  350. #define PGM_DEREFERENCE_ADDRESS( _pAddress, _RefContext) \
  351. { \
  352. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_ADDRESS), "", \
  353. "\t--pAddress[%x]=<%x:%d->%d>, <%d:%s>\n", \
  354. _RefContext, _pAddress,_pAddress->RefCount,(_pAddress->RefCount-1),__LINE__,__FILE__); \
  355. PgmDereferenceAddress (_pAddress, _RefContext); \
  356. }
  357. #define PGM_DEREFERENCE_SEND_CONTEXT( _pSendDC) \
  358. { \
  359. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_SEND), "", \
  360. "\t--pSendDC=<%x:%d->%d>, <%d:%s>\n", \
  361. _pSendDC,_pSendDC->RefCount,(_pSendDC->RefCount-1),__LINE__,__FILE__); \
  362. PgmDereferenceSendContext (_pSendDC); \
  363. }
  364. #define PGM_DEREFERENCE_SESSION( _pSession, _Verify, _RefContext) \
  365. { \
  366. PgmLog (PGM_LOG_INFORM_PATH, (DBG_DEBUG_REF | DBG_CONNECT), "", \
  367. "\t--pSession[%x]=<%x:%d->%d>, Verify=<%x>, <%d:%s>\n", \
  368. _RefContext, _pSession,_pSession->RefCount,(_pSession->RefCount-1),_Verify,__LINE__,__FILE__); \
  369. PgmDereferenceSessionCommon (_pSession, _Verify, _RefContext); \
  370. }
  371. #define PGM_DEREFERENCE_SESSION_SEND( _pSession, _RefContext) \
  372. PGM_DEREFERENCE_SESSION (_pSession, PGM_VERIFY_SESSION_SEND, _RefContext)
  373. #define PGM_DEREFERENCE_SESSION_RECEIVE( _pSession, _RefContext) \
  374. PGM_DEREFERENCE_SESSION (_pSession, PGM_VERIFY_SESSION_RECEIVE, _RefContext)
  375. #define PGM_DEREFERENCE_SESSION_UNASSOCIATED( _pSession, _RefContext) \
  376. PGM_DEREFERENCE_SESSION (_pSession, PGM_VERIFY_SESSION_UNASSOCIATED, _RefContext)
  377. //----------------------------------------------------------------------------
  378. //
  379. // PgmAttachFsp()
  380. //
  381. /*++
  382. Routine Description:
  383. This macro attaches a process to the File System Process to be sure
  384. that handles are created and released in the same process
  385. Arguments:
  386. Return Value:
  387. none
  388. --*/
  389. #define PgmAttachProcess(_pEProcess, _pApcState, _pAttached, _Context)\
  390. { \
  391. if (PsGetCurrentProcess() != _pEProcess) \
  392. { \
  393. KeStackAttachProcess(PsGetProcessPcb(_pEProcess), _pApcState); \
  394. *_pAttached = TRUE; \
  395. } \
  396. else \
  397. { \
  398. *_pAttached = FALSE; \
  399. } \
  400. }
  401. #define PgmAttachFsp(_pApcState, _pAttached, _Context) \
  402. PgmAttachProcess (PgmStaticConfig.FspProcess, _pApcState, _pAttached, _Context)
  403. #define PgmAttachToProcessForVMAccess(_pSend, _pApcState, _pAttached, _Context) \
  404. PgmAttachProcess (PgmStaticConfig.FspProcess, _pApcState, _pAttached, _Context)
  405. // PgmAttachProcess ((_pSend)->Process, _pAttached, _Context)
  406. //
  407. // PgmDetachFsp()
  408. //
  409. /*++
  410. Routine Description:
  411. This macro detaches a process from the File System Process
  412. if it was ever attached
  413. Arguments:
  414. Return Value:
  415. --*/
  416. #define PgmDetachProcess(_pApcState, _pAttached, _Context) \
  417. { \
  418. if (*_pAttached) \
  419. { \
  420. KeUnstackDetachProcess(_pApcState); \
  421. } \
  422. }
  423. #define PgmDetachFsp PgmDetachProcess
  424. //----------------------------------------------------------------------------
  425. #endif _MACROES_H_