Leaked source code of windows server 2003
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.

397 lines
8.5 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name :
  4. kernutil.h
  5. Abstract:
  6. Kernel mode utilities
  7. Revision History:
  8. --*/
  9. #ifndef __KERNUTIL_H__
  10. #define __KERNUTIL_H__
  11. BOOL InitializeKernelUtilities();
  12. VOID UninitializeKernelUtilities();
  13. //
  14. // For frequent identically-sized allocations, Lookaside Lists are faster
  15. // and less susceptible to the low memory conditions (though not exempt)
  16. //
  17. class NPagedLookasideList : public TopObj
  18. {
  19. private:
  20. NPAGED_LOOKASIDE_LIST _Lookaside;
  21. public:
  22. NPagedLookasideList(ULONG Size, ULONG Tag)
  23. {
  24. SetClassName("NPagedLookasideList");
  25. ExInitializeNPagedLookasideList(&_Lookaside, DRALLOCATEPOOL, DRFREEPOOL,
  26. 0, Size, Tag, 0);
  27. }
  28. virtual ~NPagedLookasideList()
  29. {
  30. ExDeleteNPagedLookasideList(&_Lookaside);
  31. }
  32. //
  33. // Ordinarily I'd want tracing here, but it's more important these be
  34. // inline for retail
  35. //
  36. inline PVOID Allocate()
  37. {
  38. return ExAllocateFromNPagedLookasideList(&_Lookaside);
  39. }
  40. inline VOID Free(PVOID Entry)
  41. {
  42. ExFreeToNPagedLookasideList(&_Lookaside, Entry);
  43. }
  44. //
  45. // Memory Management Operators
  46. //
  47. inline void *__cdecl operator new(size_t sz)
  48. {
  49. return DRALLOCATEPOOL(NonPagedPool, sz, 'LLPN');
  50. }
  51. inline void __cdecl operator delete(void *ptr)
  52. {
  53. DRFREEPOOL(ptr);
  54. }
  55. };
  56. class PagedLookasideList : public TopObj
  57. {
  58. private:
  59. PAGED_LOOKASIDE_LIST _Lookaside;
  60. public:
  61. PagedLookasideList(ULONG Size, ULONG Tag)
  62. {
  63. SetClassName("PagedLookasideList");
  64. ExInitializePagedLookasideList(&_Lookaside, DRALLOCATEPOOL, DRFREEPOOL,
  65. 0, Size, Tag, 0);
  66. }
  67. virtual ~PagedLookasideList()
  68. {
  69. ExDeletePagedLookasideList(&_Lookaside);
  70. }
  71. //
  72. // Ordinarily I'd want tracing here, but it's more important these be
  73. // inline for retail
  74. //
  75. inline PVOID Allocate()
  76. {
  77. return ExAllocateFromPagedLookasideList(&_Lookaside);
  78. }
  79. inline VOID Free(PVOID Entry)
  80. {
  81. ExFreeToPagedLookasideList(&_Lookaside, Entry);
  82. }
  83. inline void *__cdecl operator new(size_t sz)
  84. {
  85. return DRALLOCATEPOOL(NonPagedPool, sz, 'LLgP');
  86. }
  87. inline void __cdecl operator delete(void *ptr)
  88. {
  89. DRFREEPOOL(ptr);
  90. }
  91. };
  92. class KernelResource : public TopObj
  93. {
  94. private:
  95. ERESOURCE _Resource;
  96. public:
  97. KernelResource();
  98. virtual ~KernelResource();
  99. inline VOID AcquireResourceExclusive()
  100. {
  101. KeEnterCriticalRegion();
  102. ExAcquireResourceExclusiveLite(&_Resource, TRUE);
  103. }
  104. inline VOID AcquireResourceShared()
  105. {
  106. KeEnterCriticalRegion();
  107. ExAcquireResourceSharedLite(&_Resource, TRUE);
  108. }
  109. inline VOID ReleaseResource()
  110. {
  111. ExReleaseResourceLite(&_Resource);
  112. KeLeaveCriticalRegion();
  113. }
  114. inline ULONG IsAcquiredShared()
  115. {
  116. return ExIsResourceAcquiredSharedLite(&_Resource);
  117. }
  118. inline BOOLEAN IsAcquiredExclusive()
  119. {
  120. return ExIsResourceAcquiredExclusiveLite(&_Resource);
  121. }
  122. inline BOOLEAN IsAcquired()
  123. {
  124. return (IsAcquiredShared() != 0) || IsAcquiredExclusive();
  125. }
  126. };
  127. class KernelEvent : public TopObj
  128. {
  129. private:
  130. KEVENT _KernelEvent;
  131. static NPagedLookasideList *_Lookaside;
  132. public:
  133. KernelEvent(IN EVENT_TYPE Type, IN BOOLEAN State)
  134. {
  135. KeInitializeEvent(&_KernelEvent, Type, State);
  136. }
  137. virtual ~KernelEvent()
  138. {
  139. }
  140. static inline BOOL StaticInitialization()
  141. {
  142. _Lookaside = new NPagedLookasideList(sizeof(KernelEvent), 'tnvE');
  143. return _Lookaside != NULL;
  144. }
  145. static inline VOID StaticUninitialization()
  146. {
  147. if (_Lookaside != NULL) {
  148. delete _Lookaside;
  149. _Lookaside = NULL;
  150. }
  151. }
  152. NTSTATUS Wait(IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode,
  153. IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout = NULL)
  154. {
  155. return KeWaitForSingleObject(&_KernelEvent, WaitReason, WaitMode,
  156. Alertable, Timeout);
  157. }
  158. inline LONG SetEvent(KPRIORITY Increment = IO_NO_INCREMENT,
  159. BOOLEAN Wait = FALSE)
  160. {
  161. return KeSetEvent(&_KernelEvent, Increment, Wait);
  162. }
  163. inline LONG ResetEvent()
  164. {
  165. return KeResetEvent(&_KernelEvent);
  166. }
  167. inline VOID ClearEvent()
  168. {
  169. KeClearEvent(&_KernelEvent);
  170. }
  171. //
  172. // Maybe need to WaitForMultipleObjects
  173. //
  174. inline PKEVENT GetEvent()
  175. {
  176. return &_KernelEvent;
  177. }
  178. //
  179. // Memory Management Operators
  180. //
  181. inline void *__cdecl operator new(size_t sz)
  182. {
  183. return _Lookaside->Allocate();
  184. }
  185. inline void __cdecl operator delete(void *ptr)
  186. {
  187. _Lookaside->Free(ptr);
  188. }
  189. };
  190. class SharedLock
  191. {
  192. private:
  193. KernelResource &_Lock;
  194. public:
  195. SharedLock(KernelResource &Lock) : _Lock(Lock)
  196. {
  197. _Lock.AcquireResourceShared();
  198. }
  199. ~SharedLock()
  200. {
  201. _Lock.ReleaseResource();
  202. }
  203. };
  204. class ExclusiveLock
  205. {
  206. private:
  207. KernelResource &_Lock;
  208. public:
  209. ExclusiveLock(KernelResource &Lock) : _Lock(Lock)
  210. {
  211. _Lock.AcquireResourceExclusive();
  212. }
  213. ~ExclusiveLock()
  214. {
  215. _Lock.ReleaseResource();
  216. }
  217. };
  218. class DoubleList;
  219. class ListEntry {
  220. friend class DoubleList; // so it can access _List and constructor
  221. private:
  222. LIST_ENTRY _List; // really here for DoubleList
  223. ListEntry(PVOID Node)
  224. {
  225. _Node = Node;
  226. }
  227. PVOID _Node; // What it is we're tracking in the list
  228. static NPagedLookasideList *_Lookaside;
  229. public:
  230. PVOID Node() { return _Node; }
  231. static inline BOOL StaticInitialization()
  232. {
  233. _Lookaside = new NPagedLookasideList(sizeof(ListEntry), 'tsiL');
  234. return _Lookaside != NULL;
  235. }
  236. static inline VOID StaticUninitialization()
  237. {
  238. if (_Lookaside != NULL) {
  239. delete _Lookaside;
  240. _Lookaside = NULL;
  241. }
  242. }
  243. //
  244. // Memory Management Operators
  245. //
  246. inline void *__cdecl operator new(size_t sz)
  247. {
  248. return _Lookaside->Allocate();
  249. }
  250. inline void __cdecl operator delete(void *ptr)
  251. {
  252. _Lookaside->Free(ptr);
  253. }
  254. };
  255. class DoubleList : public TopObj {
  256. private:
  257. LIST_ENTRY _List;
  258. KernelResource _Resource; // Writes require an exclusive lock
  259. // reads require a shared lock
  260. public:
  261. DoubleList()
  262. {
  263. SetClassName("DoubleList");
  264. InitializeListHead(&_List);
  265. }
  266. BOOL CreateEntry(PVOID Node);
  267. //
  268. // Enumeration of the list
  269. //
  270. // You can't add to the list while enumerating
  271. //
  272. // Sample enumeration of the list
  273. // In this sample find a smart pointer
  274. //
  275. /*
  276. SmartPtr<NodeThing> *NodeEnum;
  277. SmartPtr<NodeThing> NodeFound;
  278. DoubleList List;
  279. ListEntry *ListEnum;
  280. List.LockShared(); // or exclusive
  281. ListEnum = List.First();
  282. while (ListEnum != NULL) {
  283. //
  284. // do something with ListEnum->Node()
  285. //
  286. // In this sample, look to see if it is
  287. // the item we're looking for
  288. //
  289. NodeEnum = (SmartPtr<NodeThing> *)ListEnum->Node();
  290. if ((*NodeEnum)->NodeThingProperty == NodeThingPropertyCriteria) {
  291. NodeFound = (*NodeEnum);
  292. //
  293. // These aren't guaranteed valid once the resource is released
  294. //
  295. NodeEnum = NULL;
  296. ListEnum = NULL;
  297. break;
  298. }
  299. ListEnum = List.Next(ListEnum);
  300. }
  301. List.Unlock();
  302. // Do something with NodeFound;
  303. if (NodeFound != NULL) {
  304. }
  305. */
  306. //
  307. VOID RemoveEntry(ListEntry *Entry);
  308. ListEntry *First();
  309. ListEntry *Next(ListEntry *ListEnum);
  310. inline VOID LockShared()
  311. {
  312. _Resource.AcquireResourceShared();
  313. }
  314. inline VOID LockExclusive()
  315. {
  316. _Resource.AcquireResourceExclusive();
  317. }
  318. inline VOID Unlock()
  319. {
  320. _Resource.ReleaseResource();
  321. }
  322. };
  323. #endif // __KERNUTIL_H__