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.

424 lines
9.9 KiB

  1. //#pragma hdrstop
  2. /*++
  3. Kernel mode definitions and function prototypes for wdm model
  4. --*/
  5. #ifndef WDM_INCD
  6. #define WDM_INCD
  7. #pragma PAGEDCODE
  8. #ifdef __cplusplus
  9. extern "C"{
  10. #endif
  11. #include <wdm.h>
  12. #include <stdio.h>
  13. #include <stdarg.h>
  14. #ifndef IRP_MN_QUERY_LEGACY_BUS_INFORMATION
  15. #define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
  16. #endif
  17. #if DBG && defined(_X86_)
  18. #undef ASSERT
  19. #define ASSERT(e) if(!(e)){DbgPrint("Assertion failure in"\
  20. __FILE__", line %d: " #e "\n", __LINE__);\
  21. _asm int 3\
  22. }
  23. #endif
  24. #define BOOL BOOLEAN
  25. #define FALSE 0
  26. typedef UCHAR* PBYTE;
  27. #define MSEC *(-(LONGLONG)10000); //milliseconds
  28. ///////////////////////////////////////////////////////////////////////////////
  29. /************************* LISTS MANIPULATION MACROS **************************/
  30. // Doubly-linked list manipulation routines. Implemented as macros
  31. // but logically these are procedures.
  32. /*
  33. typedef struct _LIST_ENTRY {
  34. struct _LIST_ENTRY * volatile Flink;
  35. struct _LIST_ENTRY * volatile Blink;
  36. } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
  37. */
  38. #ifndef LIST_ENTRY_DEF
  39. #define LIST_ENTRY_DEF
  40. // VOID
  41. // InitializeListHead(
  42. // PLIST_ENTRY ListHead
  43. // );
  44. #define InitializeListHead(ListHead) (\
  45. (ListHead)->Flink = (ListHead)->Blink = (ListHead))
  46. // BOOLEAN
  47. // IsListEmpty(
  48. // PLIST_ENTRY ListHead
  49. // );
  50. #define IsListEmpty(ListHead) \
  51. ((ListHead)->Flink == (ListHead))
  52. // PLIST_ENTRY
  53. // RemoveHeadList(
  54. // PLIST_ENTRY ListHead
  55. // );
  56. #define RemoveHeadList(ListHead) \
  57. (ListHead)->Flink;\
  58. {RemoveEntryList((ListHead)->Flink)}
  59. // PLIST_ENTRY
  60. // RemoveTailList(
  61. // PLIST_ENTRY ListHead
  62. // );
  63. #define RemoveTailList(ListHead) \
  64. (ListHead)->Blink;\
  65. {RemoveEntryList((ListHead)->Blink)}
  66. // VOID
  67. // RemoveEntryList(
  68. // PLIST_ENTRY Entry
  69. // );
  70. #define RemoveEntryList(Entry) {\
  71. PLIST_ENTRY _EX_Blink;\
  72. PLIST_ENTRY _EX_Flink;\
  73. _EX_Flink = (Entry)->Flink;\
  74. _EX_Blink = (Entry)->Blink;\
  75. _EX_Blink->Flink = _EX_Flink;\
  76. _EX_Flink->Blink = _EX_Blink;\
  77. }
  78. // VOID
  79. // InsertTailList(
  80. // PLIST_ENTRY ListHead,
  81. // PLIST_ENTRY Entry
  82. // );
  83. #define InsertTailList(ListHead,Entry) {\
  84. PLIST_ENTRY _EX_Blink;\
  85. PLIST_ENTRY _EX_ListHead;\
  86. _EX_ListHead = (ListHead);\
  87. _EX_Blink = _EX_ListHead->Blink;\
  88. (Entry)->Flink = _EX_ListHead;\
  89. (Entry)->Blink = _EX_Blink;\
  90. _EX_Blink->Flink = (Entry);\
  91. _EX_ListHead->Blink = (Entry);\
  92. }
  93. // VOID
  94. // InsertHeadList(
  95. // PLIST_ENTRY ListHead,
  96. // PLIST_ENTRY Entry
  97. // );
  98. #define InsertHeadList(ListHead,Entry) {\
  99. PLIST_ENTRY _EX_Flink;\
  100. PLIST_ENTRY _EX_ListHead;\
  101. _EX_ListHead = (ListHead);\
  102. _EX_Flink = _EX_ListHead->Flink;\
  103. (Entry)->Flink = _EX_Flink;\
  104. (Entry)->Blink = _EX_ListHead;\
  105. _EX_Flink->Blink = (Entry);\
  106. _EX_ListHead->Flink = (Entry);\
  107. }
  108. // PSINGLE_LIST_ENTRY
  109. // PopEntryList(
  110. // PSINGLE_LIST_ENTRY ListHead
  111. // );
  112. #define PopEntryList(ListHead) \
  113. (ListHead)->Next;\
  114. {\
  115. PSINGLE_LIST_ENTRY FirstEntry;\
  116. FirstEntry = (ListHead)->Next;\
  117. if (FirstEntry != NULL) { \
  118. (ListHead)->Next = FirstEntry->Next;\
  119. } \
  120. }
  121. // VOID
  122. // PushEntryList(
  123. // PSINGLE_LIST_ENTRY ListHead,
  124. // PSINGLE_LIST_ENTRY Entry
  125. // );
  126. #define PushEntryList(ListHead,Entry) \
  127. (Entry)->Next = (ListHead)->Next; \
  128. (ListHead)->Next = (Entry)
  129. #endif //LIST_ENTRY
  130. #ifndef CONTAINING_RECORD
  131. #define CONTAINING_RECORD(address, type, field) ((type *)( \
  132. (PCHAR)(address) - \
  133. (ULONG_PTR)(&((type *)0)->field)))
  134. #endif
  135. /*******************************************************************************/
  136. #ifndef FIELDOFFSET
  137. #define FIELDOFFSET(type, field) ((DWORD)(&((type *)0)->field))
  138. #endif
  139. #ifndef CONTAINING_RECORD
  140. #define CONTAINING_RECORD(address, type, field) ((type *)( \
  141. (PCHAR)(address) - \
  142. (ULONG_PTR)(&((type *)0)->field)))
  143. #endif
  144. /**********************************************************************************/
  145. #ifdef __cplusplus
  146. }
  147. #endif
  148. // Macros to verify allocated objects
  149. #define ALLOCATED_OK(obj) \
  150. ((obj!=(VOID *)0) && NT_SUCCESS((obj)->m_Status))
  151. #define DISPOSE_OBJECT(obj) \
  152. {if((obj!=(VOID *)0)) obj->dispose(); obj = NULL;}
  153. #define RETURN_VERIFIED_OBJECT(obj) \
  154. if(ALLOCATED_OK(obj)) return obj; \
  155. else \
  156. { \
  157. DISPOSE_OBJECT(obj); \
  158. return NULL; \
  159. }
  160. // derived class Unicode string
  161. #define TYPE_SYSTEM_ALLOCATED 0
  162. #define TYPE_DRIVER_ALLOCATED 1
  163. extern ULONG ObjectCounter;
  164. //::DBG_PRINT("=== Deleting Object %8.8lX",ptr);\
  165. // Overrides for library new and delete operators.
  166. /*
  167. inline VOID* __cdecl operator new(ULONG size, POOL_TYPE iType)\
  168. {PVOID pMem; if(pMem = ::ExAllocatePoolWithTag(iType,size,'_GRU'))\
  169. { ObjectCounter++; ::RtlZeroMemory(pMem,size); DBG_PRINT("\n=== New Object %8.8lX, %d\n",pMem,ObjectCounter);\
  170. return pMem; \
  171. } else return NULL; };
  172. inline VOID __cdecl operator delete(VOID* ptr)\
  173. { if(ptr){ObjectCounter--; DBG_PRINT("\n=== Deleting Object %8.8lX, %d\n",ptr,ObjectCounter); ::ExFreePool((PVOID)ptr);}\
  174. };
  175. */
  176. #pragma LOCKEDCODE
  177. inline VOID* __cdecl operator new(size_t size, POOL_TYPE iType)\
  178. {PVOID pMem; if(pMem = ::ExAllocatePoolWithTag(iType,size,'URG_'))\
  179. { ObjectCounter++; ::RtlZeroMemory(pMem,size);\
  180. return pMem; \
  181. } else return NULL; };
  182. inline VOID __cdecl operator delete(VOID* ptr)\
  183. { if(ptr){ObjectCounter--; ::ExFreePool((PVOID)ptr);}\
  184. };
  185. #include "generic.h"
  186. #pragma PAGEDCODE
  187. template <class T>
  188. class CLinkedList
  189. {
  190. public:
  191. NTSTATUS m_Status;
  192. VOID self_delete(VOID){delete this;};
  193. virtual VOID dispose(VOID){self_delete();};
  194. protected:
  195. LIST_ENTRY head;
  196. KSPIN_LOCK splock;
  197. public:
  198. CLinkedList()
  199. {
  200. InitializeListHead(&head);
  201. KeInitializeSpinLock(&splock);
  202. };
  203. BOOLEAN IsEmpty(VOID) { return IsListEmpty(&head); };
  204. ~CLinkedList()
  205. { // if list is still not empty, free all items
  206. T *p;
  207. while (p=(T *) ExInterlockedRemoveHeadList(&head,&splock))
  208. {
  209. CONTAINING_RECORD(p,T,entry)->dispose();
  210. }
  211. };
  212. VOID New(T *p)
  213. {
  214. ExInterlockedInsertTailList(&head,&(p->entry),&splock);
  215. };
  216. VOID insertHead(T *p)
  217. {
  218. ExInterlockedInsertHeadList(&head,&(p->entry),&splock);
  219. };
  220. T* removeHead(VOID)
  221. {
  222. T *p=(T *) ExInterlockedRemoveHeadList(&head,&splock);
  223. if (p) p=CONTAINING_RECORD(p,T,entry);
  224. return p;
  225. };
  226. VOID remove(T *p)
  227. {
  228. RemoveEntryList(&(p->entry));
  229. };
  230. T* getNext(T* p)
  231. {
  232. if (p)
  233. {
  234. PLIST_ENTRY Next;
  235. Next = p->entry.Flink;
  236. if (Next && (Next!= &head))
  237. {
  238. T* pp=CONTAINING_RECORD(Next,T,entry);
  239. return pp;
  240. }
  241. else return NULL;
  242. }
  243. return NULL;
  244. };
  245. T* getFirst()
  246. {
  247. PLIST_ENTRY Next = head.Flink;
  248. if (Next && Next!= &head)
  249. {
  250. T* p = CONTAINING_RECORD(Next,T,entry);
  251. return p;
  252. }
  253. return NULL;
  254. };
  255. };
  256. #pragma PAGEDCODE
  257. class CUString
  258. {
  259. public:
  260. NTSTATUS m_Status;
  261. VOID self_delete(VOID){delete this;};
  262. virtual VOID dispose(VOID){self_delete();};
  263. private:
  264. UCHAR m_bType;
  265. public:
  266. UNICODE_STRING m_String;
  267. public:
  268. CUString(USHORT nSize)
  269. {
  270. m_Status = STATUS_INSUFFICIENT_RESOURCES;
  271. m_bType = TYPE_DRIVER_ALLOCATED;
  272. RtlInitUnicodeString(&m_String,NULL);
  273. m_String.MaximumLength = nSize;
  274. m_String.Buffer = (USHORT *)
  275. ExAllocatePool(PagedPool,nSize);
  276. if (!m_String.Buffer) return; // leaving status the way it is
  277. RtlZeroMemory(m_String.Buffer,m_String.MaximumLength);
  278. m_Status = STATUS_SUCCESS;
  279. };
  280. CUString(PWCHAR uszString)
  281. {
  282. m_Status = STATUS_SUCCESS;
  283. m_bType = TYPE_SYSTEM_ALLOCATED;
  284. RtlInitUnicodeString(&m_String,uszString);
  285. };
  286. CUString(ANSI_STRING* pString)
  287. {
  288. m_Status = STATUS_SUCCESS;
  289. m_bType = TYPE_SYSTEM_ALLOCATED;
  290. RtlAnsiStringToUnicodeString(&m_String,pString,TRUE);
  291. };
  292. CUString(PCSTR pString)
  293. {
  294. ANSI_STRING AnsiString;
  295. m_Status = STATUS_SUCCESS;
  296. m_bType = TYPE_SYSTEM_ALLOCATED;
  297. RtlInitAnsiString(&AnsiString,pString);
  298. RtlAnsiStringToUnicodeString(&m_String,&AnsiString,TRUE);
  299. };
  300. CUString(PUNICODE_STRING uString)
  301. {
  302. m_Status = STATUS_INSUFFICIENT_RESOURCES;
  303. m_bType = TYPE_DRIVER_ALLOCATED;
  304. RtlInitUnicodeString(&m_String,NULL);
  305. m_String.MaximumLength = MAXIMUM_FILENAME_LENGTH;
  306. m_String.Buffer = (USHORT *)
  307. ExAllocatePool(PagedPool,MAXIMUM_FILENAME_LENGTH);
  308. if (!m_String.Buffer) return; // leaving status the way it is
  309. RtlZeroMemory(m_String.Buffer,m_String.MaximumLength);
  310. RtlCopyUnicodeString(&m_String,uString);
  311. m_Status = STATUS_SUCCESS;
  312. };
  313. CUString(LONG iVal, LONG iBase)
  314. {
  315. m_Status = STATUS_INSUFFICIENT_RESOURCES;
  316. m_bType = TYPE_DRIVER_ALLOCATED;
  317. RtlInitUnicodeString(&m_String,NULL);
  318. USHORT iSize=1;
  319. LONG iValCopy=(!iVal)?1:iVal;
  320. while (iValCopy>=1)
  321. {
  322. iValCopy/=iBase;
  323. iSize++;
  324. } // now iSize carries the number of digits
  325. iSize*=sizeof(WCHAR);
  326. m_String.MaximumLength = iSize;
  327. m_String.Buffer = (USHORT *)
  328. ExAllocatePool(PagedPool,iSize);
  329. if (!m_String.Buffer) return;
  330. RtlZeroMemory(m_String.Buffer,m_String.MaximumLength);
  331. m_Status = RtlIntegerToUnicodeString(iVal, iBase, &m_String);
  332. };
  333. ~CUString()
  334. {
  335. if ((m_bType == TYPE_DRIVER_ALLOCATED) && m_String.Buffer)
  336. ExFreePool(m_String.Buffer);
  337. };
  338. VOID append(UNICODE_STRING *uszString)
  339. {
  340. m_Status = RtlAppendUnicodeStringToString(&m_String,uszString);
  341. };
  342. VOID copyTo(CUString *pTarget)
  343. {
  344. RtlCopyUnicodeString(&pTarget->m_String,&m_String);
  345. };
  346. BOOL operator==(CUString cuArg)
  347. {
  348. return (!RtlCompareUnicodeString(&m_String,
  349. &cuArg.m_String,FALSE));
  350. };
  351. LONG inline getLength() { return m_String.Length; };
  352. PWCHAR inline getString() { return m_String.Buffer; };
  353. VOID inline setLength(USHORT i) { m_String.Length = i; };
  354. };
  355. // already included
  356. #endif