Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cKernel.h
Go to the documentation of this file.
1 //
6 
7 #ifndef _INC_CKernel_H
8 #define _INC_CKernel_H
9 #if _MSC_VER >= 1000
10 #pragma once
11 #endif // _MSC_VER >= 1000
12 
13 #if DBG || defined(_DEBUG)
14 // either DBG or _DEBUG is set then both MUST be set.
15 #ifndef DBG
16 #define DBG 1
17 #elif ! DBG
18 #error "DBG conflicts with _DEBUG"
19 #endif
20 #ifndef _DEBUG
21 #define _DEBUG
22 #endif
23 #endif
24 
25 #ifdef _DEBUG
26 // #define USE_WINXP // just for testing purposes.
27 #endif
28 
29 #include <ntddk.h>
30 
31 #include <stddef.h> // offsetof
32 #include <stdarg.h> // va_list
33 
34 #ifndef _countof
35 #define _countof(a) (sizeof(a)/sizeof((a)[0])) // same as dimensionof(a) ? = count of elements of an array
36 #endif
37 #define HANDLE_NULL NULL
38 typedef int COMPARE_t;
39 
40 // Useful partly documented Kernel Functions.
41 extern "C"
42 {
44  NTSYSAPI NTSTATUS NTAPI ObOpenObjectByPointer( // opposite of ObReferenceObjectByHandle
45  PVOID Object,
46  ULONG HandleAttributes,
47  PACCESS_STATE PassedAccessState, // optional
48  ACCESS_MASK DesiredAccess,
49  POBJECT_TYPE ObjectType,
50  KPROCESSOR_MODE AccessMode,
51  PHANDLE Handle);
52 
54  NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess( // like NtQueryInformationProcess but for kernel mode.
55  IN HANDLE ProcessHandle,
56  IN PROCESSINFOCLASS ProcessInformationClass,
57  OUT PVOID ProcessInformation,
58  IN ULONG ProcessInformationLength,
59  OUT PULONG uReturnLength OPTIONAL);
60 };
61 
62 namespace GrayKernel
63 {
64 #ifdef _DEBUG
65  enum DL_TYPE
66  {
70  DL_DEFAULT = -2,
71  DL_NONE = -1,
72  DL_ERROR = 0,
73  DL_WARN,
74  DL_TRACE,
75  DL_BLAB,
76  };
77 
78 #ifndef DEBUG_VARIABLE
79 #define DEBUG_VARIABLE DBG_DebugLevel
80  extern DL_TYPE DBG_DebugLevel;
81 #endif
82 
83 #define DBG_CR "\n"
84 
85 #ifndef DBG_PREFIX
86 #define DBG_PREFIX "KCOM: "
87 #endif
88 #ifndef DBG_COMPONENTID
89 #define DBG_COMPONENTID DPFLTR_IHVDRIVER_ID // DPFLTR_SYSTEM_ID
90 #endif
91 
92 #if 0
93 #define DBG_MSG_F(_Level) ::GrayKernel::DBG_##_Level##_F
94 #define DBG_MSG_F_DECL(_Level) \
95 inline void _cdecl DBG_MSG_F(_Level)( const char* pszFormat, ... ) \
96 { \
97  va_list vargs; \
98  va_start( vargs, pszFormat ); \
99  vDbgPrintExWithPrefix( DBG_PREFIX, DBG_COMPONENTID, DL_##_Level, (PCH) pszFormat, vargs ); \
100  va_end( vargs ); \
101 }
102  DBG_MSG_F_DECL(ERROR)
103  DBG_MSG_F_DECL(WARN)
104  DBG_MSG_F_DECL(TRACE)
105  DBG_MSG_F_DECL(BLAB)
106 #else
107 #define DBG_MSG_F(_Level) DbgPrint( DBG_PREFIX ); DbgPrint
108 #endif
109 
110  // Saves the runtime overhead of pushing the args if the call is not required.
111 #define DBG_ERROR(_stmt) { if (DEBUG_VARIABLE>=DL_ERROR) { DBG_MSG_F(ERROR) _stmt; }}
112 #define DBG_WARN(_stmt) { if (DEBUG_VARIABLE>=DL_WARN) { DBG_MSG_F(WARN) _stmt; }}
113 #define DBG_TRACE(_stmt) { if (DEBUG_VARIABLE>=DL_TRACE) { DBG_MSG_F(TRACE) _stmt; }}
114 #define DBG_BLAB(_stmt) { if (DEBUG_VARIABLE>=DL_BLAB) { DBG_MSG_F(BLAB) _stmt; }}
115 
116 // Assert/Halt with ULONG arguments.
117 #define ASSERT3(exp, p1, p2, p3) { if (!(exp)) { ::KeBugCheckEx(0xDEAD1FE0, (DBG_FILE_ID << 16) + __LINE__, p1, p2, p3); }}
118 
119 #undef ASSERT
120 #define ASSERT(exp) { if (!(exp)) { DBG_ERROR(( "ASSERT:'%s'" DBG_CR, #exp )); DbgBreakPoint(); }}
121 
122 #else // _DEBUG
123 
124  // No debug
125 #define DBG_ERROR(stmt)
126 #define DBG_WARN(stmt)
127 #define DBG_TRACE(stmt)
128 #define DBG_BLAB(stmt)
129 
130 #define ASSERT3(exp, p1, p2, p3)
131 #endif // ! _DEBUG
132 
133 //*******************************************************************
134 
135 #ifdef USE_WINXP // works for XP only.
136 #define CKeMem_Free(p,_UTAG) ::ExFreePoolWithTag(p,_UTAG);
137 #else
138 #define CKeMem_Free(p,_UTAG) ::ExFreePool(p);
139 #endif
140 
141  template <class TYPE, ULONG _UTAG = 'IKUn' >
142  struct CKeMem
143  {
146  public:
148  public:
149  void InitMem(TYPE* p = nullptr)
150  {
151  m_p = p;
152  }
153  bool AllocMem(POOL_TYPE ePoolType, SIZE_T nNumberOfBytes = sizeof(TYPE))
154  {
156  m_p = (TYPE*) ::ExAllocatePoolWithTag(ePoolType, nNumberOfBytes, _UTAG);
157  return IsValidMem();
158  }
159  NTSTATUS AllocMemQuota(POOL_TYPE ePoolType, SIZE_T nNumberOfBytes = sizeof(TYPE))
160  {
162  NTSTATUS lStatus = STATUS_SUCCESS;
163  m_p = nullptr;
164  // This can throw an exception. so try to catch it.
165  __try
166  {
167  m_p = (TYPE*)ExAllocatePoolWithQuotaTag(ePoolType, nNumberOfBytes, _UTAG);
168  }
169  __except (EXCEPTION_EXECUTE_HANDLER)
170  {
171  lStatus = GetExceptionCode();
172  }
173  return lStatus;
174  }
175  void FreeLast()
176  {
177  if (m_p == nullptr)
178  return;
179  CKeMem_Free(m_p, _UTAG);
180  }
181  void Free()
182  {
183  if (m_p == nullptr)
184  return;
185  CKeMem_Free(m_p, _UTAG);
186  m_p = nullptr;
187  }
189  {
190  TYPE* p = m_p;
191  ASSERT(p != nullptr);
192  m_p = nullptr;
193  return p;
194  }
195  bool IsValidMem() const
196  {
197  return m_p != nullptr;
198  }
199  operator const TYPE*() const
200  {
201  return m_p;
202  }
203  operator TYPE*()
204  {
205  return m_p;
206  }
208  {
209  return m_p;
210  }
211  };
212 
213  template< ULONG _UTAG >
214  struct CKeDynamic
215  {
218  public:
219  void DestroyThis()
220  {
221  CKeMem_Free(this, _UTAG);
222  }
223  };
224 
225  //**************************************************************************
226 
227  struct __declspec(novtable) CKeMDL : public _MDL
228  {
232  public:
233  void FreeMdl()
234  {
235  ASSERT(this != nullptr);
236  ::IoFreeMdl(this);
237  }
238  void ProbeAndLockPages(IN KPROCESSOR_MODE eAccessMode = KernelMode, IN LOCK_OPERATION eOperation = IoModifyAccess)
239  {
241  ASSERT(this != nullptr);
242  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
243  MmProbeAndLockPages(this, eAccessMode, eOperation);
244  }
245  void MapLockedPages(KPROCESSOR_MODE eAccessMode = KernelMode)
246  {
248  ASSERT(this != nullptr);
249  MmMapLockedPages(this, eAccessMode);
250  }
251  void UnlockPages()
252  {
253  ASSERT(this != nullptr);
254  MmUnlockPages(this);
255  }
256  };
257 
258  //**************************************************************************
259 
261  {
264  public:
265  LONG m_lVal;
266  public:
267  void Init(LONG lVal = 0)
268  {
269  m_lVal = lVal;
270  }
271  LONG Increment()
272  {
273  return InterlockedIncrement(&m_lVal);
274  }
275  LONG Decrement()
276  {
277  return InterlockedDecrement(&m_lVal);
278  }
279  LONG Exchange(LONG lVal = 0)
280  {
281  return InterlockedExchange(&m_lVal, lVal);
282  }
283  LONG ExchangeAdd(LONG lValAdd)
284  {
285  return InterlockedExchangeAdd(&m_lVal, lValAdd);
286  }
287  LONG ExchangeIf(LONG lValCompare, LONG lVal = 0)
288  {
291  return InterlockedCompareExchange(&m_lVal, lVal, lValCompare);
292  }
293  operator LONG() const
294  {
295  return m_lVal;
296  }
297  };
298 
299 #if defined(_M_IA64)
300  struct CKeInterlocked64
301  {
304  public:
305  LONGLONG m_qVal;
306  public:
307  CKeInterlocked64()
308  {}
309  CKeInterlocked64(LONGLONG qVal) : m_qVal(qVal)
310  {}
311  void Init(LONGLONG qVal = 0)
312  {
313  m_qVal = qVal;
314  }
315  LONGLONG Increment()
316  {
317  return InterlockedIncrement64(&m_qVal);
318  }
319  LONGLONG Decrement()
320  {
321  return InterlockedDecrement64(&m_qVal);
322  }
323  LONGLONG Exchange(LONGLONG qVal = 0)
324  {
325  return InterlockedExchange64(&m_qVal, qVal);
326  }
327  LONGLONG ExchangeAdd(LONGLONG qValAdd)
328  {
329  return InterlockedExchangeAdd64(&m_qVal, qValAdd);
330  }
331  LONGLONG ExchangeIf(LONGLONG qValCompare, LONGLONG qVal = 0)
332  {
335  return InterlockedCompareExchange64(&m_qVal, qVal, qValCompare);
336  }
337  operator LONGLONG() const
338  {
339  return m_qVal;
340  }
341  };
342 #endif
343 
344  template <class TYPE>
346  {
349  public:
351  public:
352  void InitPtr(TYPE* pVal = nullptr)
353  {
354  m_pVal = pVal;
355  }
356  TYPE* Exchange(TYPE* pVal = nullptr)
357  {
359  return (TYPE*)InterlockedExchangePointer(&m_pVal, pVal);
360  }
361  TYPE* ExchangeIf(TYPE* pValCompare, TYPE* pVal = nullptr)
362  {
364  return (TYPE*)InterlockedCompareExchangePointer(&m_pVal, pVal, pValCompare);
365  }
366  operator TYPE*() const
367  {
368  return m_pVal;
369  }
371  {
372  return m_pVal;
373  }
374  };
375 
376  template <class TYPE>
377  struct CKeInterlockedPtrX : public CKeInterlockedPtr<TYPE>
378  {
380  public:
381  CKeInterlockedPtrX(TYPE* pVal = nullptr)
382  {
383  InitPtr(pVal);
384  }
385  };
386 
387  //**************************************************************************
388  struct CKeSpinLock
389  {
392  public:
393  KSPIN_LOCK m_SpinLock;
394  public:
396  {
397  ::KeInitializeSpinLock(&m_SpinLock);
398  }
399  operator KSPIN_LOCK&()
400  {
401  return m_SpinLock;
402  }
403  operator PKSPIN_LOCK()
404  {
405  return &m_SpinLock;
406  }
407  };
408 
410  {
413  public:
414  PKSPIN_LOCK m_pSpinLock;
415  KIRQL m_OldIrql;
416  public:
417  CKeSpinLockLock(PKSPIN_LOCK pSpinLock)
418  : m_pSpinLock(pSpinLock)
419  {
421  ASSERT(pSpinLock != nullptr);
422 #if 0
423  m_OldIrql = KeAcquireSpinLockRaiseToDpc(pSpinLock);
424 #else
425  m_OldIrql = ::KfAcquireSpinLock(pSpinLock);
426 #endif
427  }
429  {
430  ::KeReleaseSpinLock(m_pSpinLock, m_OldIrql);
431  }
432  };
433 
435  {
439  public:
440  PKSPIN_LOCK m_pSpinLock;
441  public:
442  CKeSpinLockDpcLevel(PKSPIN_LOCK pSpinLock)
443  : m_pSpinLock(pSpinLock)
444  {
445  // ASSUME KeInitializeSpinLock(pSpinLock) was called.
446  ASSERT(pSpinLock != nullptr);
447  ::KeAcquireSpinLockAtDpcLevel(pSpinLock);
448  }
450  {
451  ::KeReleaseSpinLockFromDpcLevel(m_pSpinLock);
452  }
453  };
454 
455  //********************************************************************
456 
458  {
462  private:
463  LARGE_INTEGER m_Val;
464  CKeSpinLock m_SpinLock;
465  public:
467  {
468  RtlZeroMemory(&m_Val, sizeof(m_Val));
469  m_SpinLock.InitSpinLock();
470  }
471  void Add(ULONG uDelta = 1)
472  {
473  CKeSpinLockLock lock(m_SpinLock);
474  RtlLargeIntegerAdd(m_Val, (RtlConvertUlongToLargeInteger(uDelta)));
475  }
476  void Subtract(ULONG uDelta = 1)
477  {
478  CKeSpinLockLock lock(m_SpinLock);
479  RtlLargeIntegerSubtract(m_Val, (RtlConvertUlongToLargeInteger(uDelta)));
480  }
481  bool IsZero()
482  {
483  CKeSpinLockLock lock(m_SpinLock);
484  ASSERT(RtlLargeIntegerGreaterOrEqualToZero(m_Val));
485  return RtlLargeIntegerEqualToZero(m_Val) ? true : false;
486  }
487  ULONG get_Low() const
488  {
489  return m_Val.LowPart;
490  }
491  };
492 
493  //********************************************************************
494 
495  struct CKeTime
496  {
502 
503  void InitTime()
504  {
505  m_TimeVal.QuadPart = 0;
506  }
508  {
509  ::KeQuerySystemTime(&m_TimeVal);
510  }
511  int get_AgeSec() const
512  {
513  // @return Time diff in seconds.
514  LARGE_INTEGER uTimeNow;
515  ::KeQuerySystemTime(&uTimeNow);
516  LONGLONG nDiff = uTimeNow.QuadPart - m_TimeVal.QuadPart;
517  int iDiffSec = (int)(nDiff / (1000 * 1000 * 10));
518  return iDiffSec;
519  }
521  {
522 #ifndef _WDMDDK_
523  LARGE_INTEGER localTime;
524  ::ExSystemTimeToLocalTime(&m_TimeVal, &localTime);
525  m_TimeVal = localTime;
526 #else
527 #define LOCAL_TIME_SHIFT (5*60*60) // in minutes.
528  m_TimeVal.QuadPart += (LONGLONG)(10000) * 1000 * LOCAL_TIME_SHIFT;
529 #endif // ! _WDMDDK_
530  }
531  void GetTimeFields(PTIME_FIELDS pTimeFields)
532  {
533  ASSERT(pTimeFields != nullptr);
534  ::RtlTimeToTimeFields(&m_TimeVal, pTimeFields);
535  }
536  public:
537  LARGE_INTEGER m_TimeVal;
538  };
539 
540  //**************************************************************************
541 
542  template <class TYPE>
543  struct __declspec(novtable) CKeObject : public TYPE
544  {
564 
565  void ReferenceObject()
566  {
567  // Increment the ref on this.
568  ASSERT(this != nullptr);
569  ASSERT(::KeGetCurrentIrql() == PASSIVE_LEVEL);
570  ::ObReferenceObject(this);
571  }
572  void ReleaseObject()
573  {
574  ASSERT(this != nullptr);
575  ASSERT(::KeGetCurrentIrql() == PASSIVE_LEVEL);
576  ::ObDereferenceObject(this);
577  }
578 
579  TYPE* get_Ptr()
580  {
581  return this;
582  }
583  const TYPE* get_CPtr() const
584  {
585  return this;
586  }
587  CSHORT get_ObjectType() const
588  {
589  // @return IO_TYPE_FILE,IO_TYPE_DEVICE,IO_TYPE_IRP,etc..
590  // ASSUME _DRIVER_OBJECT type header.
591  ASSERT(this != nullptr);
592  return Type;
593  }
594  CSHORT get_ObjectSize() const
595  {
596  // ASSUME _DRIVER_OBJECT type header.
597  ASSERT(this != nullptr);
598  return Size;
599  }
600  };
601 
602  template <class TYPE>
604  {
609 
610  CKeObjectPtr(TYPE* pObject = nullptr)
611  : m_pObject((CKeObject<TYPE>*) pObject)
612  {
613  // Assume already referenced 1 time.
614  }
615  NTSTATUS ReferenceByHandle(IN HANDLE Handle,
616  IN ACCESS_MASK uDesiredAccess = FILE_ANY_ACCESS,
617  IN POBJECT_TYPE pObjectType = nullptr,
618  IN KPROCESSOR_MODE eAccessMode = KernelMode,
619  OUT POBJECT_HANDLE_INFORMATION pHandleInformation = nullptr)
620  {
621  // Set and reference by handle.
622  ASSERT(m_pObject == nullptr);
623  ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
624  return ObReferenceObjectByHandle(Handle, // Object Handle
625  uDesiredAccess, // Desired Access
626  pObjectType, // Object Type
627  eAccessMode, // Processor mode
628  (PVOID*)&m_pObject, // File Object pointer
629  pHandleInformation // Object Handle information
630  );
631  }
633  {
634  // Increment the ref on this.
635  ASSERT(m_pObject != nullptr);
636  m_pObject->ReferenceObject();
637  }
639  {
640  if (m_pObject == nullptr)
641  return;
642  m_pObject->ReleaseObject();
643  m_pObject = nullptr;
644  }
645  CKeObject<TYPE>* DetachObject()
646  {
647  CKeObject<TYPE>* pObject = m_pObject;
648  m_pObject = nullptr;
649  return pObject;
650  }
651  void ReleaseLast()
652  {
653  if (m_pObject == nullptr)
654  return;
655  m_pObject->ReleaseObject();
656  }
658  {
659  return (TYPE**)&m_pObject;
660  }
661  CKeObject<TYPE>* get_ObjectPtr() const
662  {
663  return m_pObject;
664  }
665  bool IsValidObj() const
666  {
667  return m_pObject != nullptr;
668  }
669  operator const TYPE*() const
670  {
671  return m_pObject;
672  }
673  operator TYPE*()
674  {
675  return m_pObject;
676  }
678  {
679  return m_pObject;
680  }
681  private:
682  CKeObject<TYPE>* m_pObject;
683  };
684 
685 #if 0
686  template <class TYPE>
687  struct CKeObjectPtrX : public CKeObjectPtr<TYPE>
688  {
691  public:
692  CKeObjectPtrX(TYPE* pObject = nullptr)
693  : CKeObjectPtr(pObject)
694  {
695  // Assume already referenced 1 time.
696  }
697  ~CKeObjectPtrX()
698  {
699  ReleaseLast();
700  }
701  };
702 #endif
703 
704  struct CKeHandle
705  {
710 
711  CKeHandle(HANDLE Handle = HANDLE_NULL)
712  : m_Handle(Handle)
713  {}
715  {
716  if (m_Handle != HANDLE_NULL)
717  {
718  ZwClose(m_Handle);
719  }
720  }
721  HANDLE* get_HandlePtr()
722  {
723  ASSERT(m_Handle == HANDLE_NULL); // prevent leaks.
724  return &m_Handle;
725  }
726  NTSTATUS CloseHandle()
727  {
728  if (m_Handle == HANDLE_NULL)
729  return STATUS_SUCCESS;
730  HANDLE HandleTmp = m_Handle;
732  return ZwClose(HandleTmp);
733  }
734  NTSTATUS OpenByPointer(PVOID pObject,
735  ULONG uHandleAttributes = OBJ_KERNEL_HANDLE,
736  PACCESS_STATE pPassedAccessState = nullptr, // optional
737  ACCESS_MASK uDesiredAccess = FILE_ANY_ACCESS,
738  POBJECT_TYPE pObjectType = nullptr,
739  KPROCESSOR_MODE eAccessMode = KernelMode
740  )
741  {
742  // NOTE: This is documented on MSDN
743  return ::ObOpenObjectByPointer(pObject, // Object
744  uHandleAttributes, // HandleAttributes = OBJ_EXCLUSIVE,OBJ_INHERIT
745  pPassedAccessState, // PassedAccessState
746  uDesiredAccess, // DesiredAccess
747  pObjectType, // ObjectType
748  eAccessMode, // AccessMode = UserMode,KernelMode
749  &m_Handle);
750  }
751  operator HANDLE() const
752  {
753  return m_Handle;
754  }
755  protected:
756  HANDLE m_Handle;
757  };
758 
759  //**************************************************************************
760 
761  struct CKeTimerD
762  {
765  public:
766  void InitTimer(IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
767  {
768  ::KeInitializeTimer(&m_Timer);
769  ::KeInitializeDpc(&m_Dpc, DeferredRoutine, DeferredContext);
770  }
771  void SetTimer(LARGE_INTEGER& dueTime)
772  {
773  ::KeSetTimer(
774  &m_Timer,
775  dueTime,
776  &m_Dpc);
777  }
778  void SetTimerEx(LARGE_INTEGER& dueTime, ULONG period)
779  {
780  ::KeSetTimerEx(
781  &m_Timer,
782  dueTime, period,
783  &m_Dpc);
784  }
785  void CancelTimer()
786  {
787  ::KeCancelTimer(&m_Timer);
788  }
790  {
791  CancelTimer();
792  ::KeRemoveQueueDpc(&m_Dpc);
793  }
794  public:
795  KTIMER m_Timer;
796  KDPC m_Dpc; // defer procedure call.
797  };
798 
799  //**************************************************************************
800 
801  struct CKeEvent : public _KEVENT
802  {
805  void InitEvent()
806  {
807  ::KeInitializeEvent(this, NotificationEvent, false);
808  }
809  void ClearEvent()
810  {
811  ASSERT(::KeGetCurrentIrql() <= DISPATCH_LEVEL);
812  ::KeClearEvent(this);
813  }
814  LONG SetEvent()
815  {
816  ASSERT(::KeGetCurrentIrql() <= DISPATCH_LEVEL);
817  return ::KeSetEvent(this, IO_NO_INCREMENT, false);
818  }
819  NTSTATUS WaitForEvent()
820  {
822  ASSERT(::KeGetCurrentIrql() == PASSIVE_LEVEL);
823  return ::KeWaitForSingleObject(
824  this, // Object to wait on.
825  Executive, // Reason for waiting
826  KernelMode, // Processor mode
827  false, // Alertable
828  nullptr // Timeout
829  );
830  }
831  };
832 
833  //**************************************************************************
834  struct CKeStringUS : public UNICODE_STRING
835  {
840  {
841  if (Buffer != nullptr)
842  RtlUpcaseUnicodeString(nullptr, this, false);
843  }
844  void InitStr()
845  {
847  Length = 0;
848  MaximumLength = 0;
849  Buffer = nullptr;
850  }
851  void InitStatic(const WCHAR* pStr, USHORT wLength)
852  {
854  ASSERT(pStr != nullptr);
855  Length = wLength;
856  MaximumLength = wLength + 1;
857  Buffer = (PWSTR)pStr;
858  }
859  void InitStatic(const WCHAR* pStr)
860  {
863  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
864  ASSERT(pStr != nullptr);
865  RtlInitUnicodeString(this, (PWSTR)pStr);
866  ASSERT(Length < MaximumLength);
867  }
868  void InitBuffer(PWSTR pBuffer, USHORT uMaximumLength)
869  {
871  Length = 0;
872  MaximumLength = uMaximumLength;
873  Buffer = pBuffer;
874  }
875  void InitBufferZ(PWSTR pBuffer, USHORT uMaximumLength)
876  {
878  RtlZeroMemory(pBuffer, uMaximumLength);
879  InitBuffer(pBuffer, uMaximumLength);
880  }
881  bool IsValidStr() const
882  {
883  return(Buffer != nullptr);
884  }
885  operator PCWSTR() const
886  {
887  return Buffer;
888  }
889  operator PWSTR()
890  {
891  return Buffer;
892  }
893  PWSTR DetachStr()
894  {
896  PWSTR pBuffer = Buffer;
897  ASSERT(pBuffer != nullptr);
898  InitStr();
899  return pBuffer;
900  }
901 
902  COMPARE_t CompareStr(const UNICODE_STRING& rString2, BOOLEAN bCaseInSensitive = false) const
903  {
904  return RtlCompareUnicodeString((UNICODE_STRING*)this, (UNICODE_STRING*)&rString2, bCaseInSensitive);
905  }
906 
907  NTSTATUS FromInteger(IN ULONG uValue, IN ULONG uBase = 10)
908  {
909  return RtlIntegerToUnicodeString(uValue, uBase, this);
910  }
911  NTSTATUS ToInteger(ULONG& uValue, ULONG nBase = 10) const
912  {
914  return RtlUnicodeStringToInteger((UNICODE_STRING*)(this), nBase, &uValue);
915  }
916  NTSTATUS FromInt64(IN ULONGLONG Value, IN ULONG nBase = 10)
917  {
918  return RtlInt64ToUnicodeString(Value, nBase, this);
919  }
920  NTSTATUS FromAnsi(PANSI_STRING pStr, bool bAlloc = false)
921  {
923  return RtlAnsiStringToUnicodeString(this, pStr, bAlloc);
924  }
925  NTSTATUS AppendStr(const UNICODE_STRING& str)
926  {
928  return RtlAppendUnicodeStringToString((UNICODE_STRING*)this, (UNICODE_STRING*)&str);
929  }
930  NTSTATUS AppendStr(PCWSTR pwSource)
931  {
933  return RtlAppendUnicodeToString(this, pwSource);
934  }
935  void AppendStr(NTSTATUS& lStatus, PCWSTR pwSource)
936  {
938  if (!NT_SUCCESS(lStatus))
939  return;
940  lStatus = RtlAppendUnicodeToString(this, pwSource);
941  }
942 
943  NTSTATUS AppendInteger(ULONG uValue, ULONG uBase = 10)
944  {
945  WCHAR numStrBuf[20];
946  CKeStringUS numStr;
947  numStr.InitBuffer(numStrBuf, sizeof(numStrBuf));
948  NTSTATUS lStatus = numStr.FromInteger(uValue, uBase);
949  if (!NT_SUCCESS(lStatus))
950  return lStatus;
951  return AppendStr(numStr);
952  }
953  void FreeSys()
954  {
955  if (Buffer != nullptr)
956  {
957  RtlFreeUnicodeString(this);
958  InitStr();
959  }
960  }
961  };
962 
963  struct CKeStringU : public CKeStringUS
964  {
970  static const ULONG CKeStringU_TAG = 'KStU';
971  public:
973  {
974  InitStr();
975  }
976  CKeStringU(PCWSTR pStr)
977  {
978  CreateStr(pStr); // Make copy of pStr
979  }
981  {
982  FreeStringLast();
983  }
984  void FreeString()
985  {
986  if (Buffer != nullptr)
987  {
988  CKeMem_Free(Buffer, CKeStringU_TAG);
989  InitStr();
990  }
991  }
992  NTSTATUS AppendStr(PCWSTR pStr, USHORT nLengthStr)
993  {
995  ASSERT(pStr != nullptr);
996  ASSERT(!(nLengthStr & 1));
997  if (nLengthStr <= 0)
998  return STATUS_SUCCESS;
999  size_t nLengthNew = Length + nLengthStr;
1000  if (nLengthNew >= MaximumLength)
1001  {
1002  // must reallocate string.
1003  PWSTR pBufferOld = Buffer;
1004  Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, nLengthNew + sizeof(WCHAR), CKeStringU_TAG);
1005  if (Buffer == nullptr)
1006  {
1007  Buffer = pBufferOld; // just put the old one back.
1008  return STATUS_INSUFFICIENT_RESOURCES;
1009  }
1010  MaximumLength = (USHORT)nLengthNew + sizeof(WCHAR);
1011  if (pBufferOld != nullptr)
1012  {
1013  RtlCopyMemory(Buffer, pBufferOld, Length);
1014  CKeMem_Free(pBufferOld, CKeStringU_TAG);
1015  }
1016  }
1017  ASSERT(Buffer != nullptr);
1018  RtlCopyMemory(((PUCHAR)Buffer) + Length, pStr, nLengthStr);
1019  Buffer[nLengthNew / sizeof(WCHAR)] = '\0';
1020  Length = (USHORT)nLengthNew; // in bytes.
1021  ASSERT(Length < MaximumLength);
1022  return STATUS_SUCCESS;
1023  }
1024  NTSTATUS AppendStr(PCWSTR pStr)
1025  {
1026  ASSERT(pStr != nullptr);
1027  return AppendStr(pStr, (USHORT)(wcslen(pStr) * sizeof(WCHAR))); // len in chars to bytes.
1028  }
1029  NTSTATUS AppendStr(const UNICODE_STRING& str)
1030  {
1031  return AppendStr(str.Buffer, str.Length);
1032  }
1033 
1034  void AppendStr(NTSTATUS& lStatus, PCWSTR pStr)
1035  {
1036  if (!NT_SUCCESS(lStatus))
1037  return;
1038  lStatus = AppendStr(pStr);
1039  }
1040  void AppendStr(NTSTATUS& lStatus, PCWSTR pStr, USHORT nLengthStr)
1041  {
1042  if (!NT_SUCCESS(lStatus))
1043  return;
1044  lStatus = AppendStr(pStr, nLengthStr);
1045  }
1046  void AppendStr(NTSTATUS& lStatus, const UNICODE_STRING& str)
1047  {
1048  if (!NT_SUCCESS(lStatus))
1049  return;
1050  lStatus = AppendStr(str);
1051  }
1052 
1053  NTSTATUS AppendInteger(ULONG uValue, ULONG uBase = 10)
1054  {
1055  WCHAR numStrBuf[20];
1056  CKeStringUS numStr;
1057  numStr.InitBuffer(numStrBuf, sizeof(numStrBuf));
1058  NTSTATUS lStatus = numStr.FromInteger(uValue, uBase);
1059  if (!NT_SUCCESS(lStatus))
1060  return lStatus;
1061  return AppendStr(numStr);
1062  }
1063  void AppendInteger(NTSTATUS& lStatus, ULONG uValue, ULONG uBase = 10)
1064  {
1065  // AppendStr( lStatus, str.Buffer, str.Length );
1066  if (!NT_SUCCESS(lStatus))
1067  return;
1068  lStatus = AppendInteger(uValue, uBase);
1069  }
1070 
1071  // Dangerous functions can cause leaks.
1072  NTSTATUS CreateStr(PCWSTR pStr, USHORT nLengthStr)
1073  {
1076  ASSERT(KeGetCurrentIrql() <= PASSIVE_LEVEL);
1077  ASSERT(!(nLengthStr & 1));
1078  ASSERT(pStr != nullptr);
1079  Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, nLengthStr + sizeof(WCHAR), CKeStringU_TAG);
1080  if (Buffer == nullptr)
1081  {
1082  Length = 0;
1083  MaximumLength = 0;
1084  return STATUS_INSUFFICIENT_RESOURCES;
1085  }
1086  MaximumLength = (USHORT)nLengthStr; // int bytes.
1087  ASSERT(Buffer != nullptr);
1088  RtlCopyMemory(Buffer, pStr, nLengthStr);
1089  Buffer[nLengthStr / sizeof(WCHAR)] = '\0';
1090  Length = (USHORT)nLengthStr; // int bytes.
1091  return STATUS_SUCCESS;
1092  }
1093  NTSTATUS CreateStr(const UNICODE_STRING& str)
1094  {
1095  return CreateStr(str.Buffer, str.Length);
1096  }
1097  NTSTATUS CreateStr(PCWSTR pStr)
1098  {
1100  ASSERT(pStr != nullptr);
1101  return CreateStr(pStr, (USHORT)(wcslen(pStr) * sizeof(WCHAR))); // len in chars to bytes.
1102  }
1103  protected:
1105  {
1106  if (Buffer != nullptr)
1107  {
1108  CKeMem_Free(Buffer, CKeStringU_TAG);
1109  }
1110  }
1111  };
1112 
1113  //**************************************************************************
1114  struct CKeStringAS : public ANSI_STRING
1115  {
1119 
1120  void InitStr()
1121  {
1122  Length = 0;
1123  MaximumLength = 0;
1124  Buffer = nullptr;
1125  }
1126  void InitStatic(const char* pStr)
1127  {
1129  RtlInitAnsiString(this, (PCHAR)pStr);
1130  }
1131  void InitBuffer(char* pBuffer, USHORT uMaximumLength)
1132  {
1134  Length = 0;
1135  MaximumLength = uMaximumLength;
1136  Buffer = pBuffer;
1137  }
1138  bool IsValidStr() const
1139  {
1140  return(Buffer != nullptr);
1141  }
1142  operator PCHAR()
1143  {
1144  return Buffer;
1145  }
1146  NTSTATUS ToInteger(ULONG& uValue, ULONG nBase = 10) const
1147  {
1149  return RtlCharToInteger(Buffer, nBase, &uValue);
1150  }
1151 
1152 #if 0
1153  void FromInteger(ULONG uValue, ULONG nBase = 10, int iWidth = 32)
1154  {
1155  CHAR buffer[32];
1156  if (iWidth >= sizeof(buffer) - 1)
1157  iWidth = sizeof(buffer) - 1;
1158  PCHAR pBufEnd = buffer + sizeof(buffer) - 1;
1159  *pBufEnd = '\0';
1160  PCHAR pBuf = pBufEnd;
1161  do
1162  {
1163  ULONG d = uValue % nBase;
1164  *(--pBuf) = (CHAR)(d + ((d < 10) ? '0' : ('A' - 10)));
1165  uValue /= nBase;
1166  iWidth--;
1167  } while (uValue);
1168  for (; iWidth > 0; iWidth--)
1169  {
1170  *(--pBuf) = '0';
1171  }
1172  AppendStr(pBuf, pBufEnd - pBuf);
1173  }
1174 #endif
1175 
1176  NTSTATUS FromUnicode(PUNICODE_STRING pStr, bool bAlloc = false)
1177  {
1179  return RtlUnicodeStringToAnsiString(this, pStr, bAlloc);
1180  }
1181 
1182  NTSTATUS AppendStr(const char* pStr, USHORT uLenStr)
1183  {
1184  // Append the string for as much room as we have. then fail.
1185  ASSERT(pStr != nullptr);
1186  ASSERT(Length < MaximumLength);
1187  NTSTATUS lStatus;
1188  if (Length + uLenStr >= MaximumLength)
1189  {
1190  // Not long enough to hold it all.
1191  lStatus = STATUS_BUFFER_TOO_SMALL;
1192  uLenStr = (MaximumLength - Length) - 1;
1193  }
1194  else
1195  {
1196  lStatus = STATUS_SUCCESS;
1197  }
1198  RtlCopyMemory(Buffer + Length, pStr, uLenStr);
1199  Length += uLenStr;
1200  Buffer[Length] = '\0';
1201  ASSERT(Length < MaximumLength);
1202  return lStatus;
1203  }
1204  NTSTATUS AppendStr(const ANSI_STRING& str)
1205  {
1207  return AppendStr(str.Buffer, str.Length);
1208  }
1209  NTSTATUS AppendStr(const char* pStr)
1210  {
1212  ASSERT(pStr != nullptr);
1213  return AppendStr(pStr, strlen(pStr));
1214  }
1215 
1216  NTSTATUS AppendStr(const WCHAR* pStr, USHORT uLenStr)
1217  {
1221  ASSERT(pStr != nullptr);
1222  ASSERT(Length < MaximumLength);
1223  NTSTATUS lStatus;
1224  if (Length + uLenStr >= MaximumLength)
1225  {
1226  // Not long enough to hold it all.
1227  lStatus = STATUS_BUFFER_TOO_SMALL;
1228  uLenStr = (MaximumLength - Length) - 1;
1229  }
1230  else
1231  {
1232  lStatus = STATUS_SUCCESS;
1233  }
1234  USHORT uLenChars = uLenStr / sizeof(WCHAR);
1235  for (; uLenChars--; Length++, pStr++)
1236  {
1237  WCHAR ch = *pStr;
1238  Buffer[Length] = (ch & 0xFF00) ? '?' : (CHAR)(ch);
1239  }
1240  Buffer[Length] = '\0';
1241  ASSERT(Length < MaximumLength);
1242  return lStatus;
1243  }
1244  NTSTATUS AppendStr(const WCHAR* pStr)
1245  {
1246  ASSERT(pStr != nullptr);
1247  return AppendStr(pStr, (USHORT)(wcslen(pStr) * sizeof(WCHAR)));
1248  }
1249  void FreeSys()
1250  {
1251  if (Buffer != nullptr)
1252  {
1253  RtlFreeAnsiString(this);
1254  InitStr();
1255  }
1256  }
1257  };
1258 
1259  //**************************************************************************
1260 
1261  struct CKeList : public LIST_ENTRY
1262  {
1266 
1267  //*****************************************
1268  // This is a list head.
1269  void InitList()
1270  {
1271  ::InitializeListHead(this); // points to itself. (Flink==this)
1272  ASSERT(Flink == this);
1273  }
1274  bool IsListEmptyX() const
1275  {
1276  return ::IsListEmpty(this) ? true : false;
1277  }
1278  PLIST_ENTRY get_Head() const
1279  {
1280  ASSERT(Flink != nullptr); // must be init and in a list.
1281  return(Flink);
1282  }
1283  int get_Count() const
1284  {
1285  ASSERT(Flink != nullptr);
1286  PLIST_ENTRY pEntry = Flink;
1287  int iCount = 0;
1288  for (; pEntry != this; iCount++)
1289  {
1290  pEntry = pEntry->Flink;
1291  }
1292  return iCount;
1293  }
1294  PLIST_ENTRY RemoveHead()
1295  {
1297  if (IsListEmptyX())
1298  return nullptr;
1299  PLIST_ENTRY pTmp = RemoveHeadList(this);
1300  return(pTmp);
1301  }
1302  void AddHead(PLIST_ENTRY pObj)
1303  {
1304  ASSERT(this != nullptr);
1305  ASSERT(pObj != nullptr);
1306  ASSERT(Blink != nullptr); // must be init list
1307  InsertHeadList(this, pObj);
1308  }
1309  void AddTail(PLIST_ENTRY pObj)
1310  {
1311  ASSERT(this != nullptr);
1312  ASSERT(pObj != nullptr);
1313  ASSERT(Flink != nullptr); // must be init list
1314  InsertTailList(this, pObj);
1315  }
1316  void AddTailLocked(PLIST_ENTRY pObj, PKSPIN_LOCK pSpinLock)
1317  {
1318  ASSERT(pObj != nullptr);
1319  ASSERT(Flink != nullptr); // must be init list
1320  ASSERT(pSpinLock != nullptr);
1321  ExInterlockedInsertTailList(this, pObj, pSpinLock);
1322  }
1323 
1324  //*****************************************
1325  // This is a list element.
1326  bool IsListLinked() const
1327  {
1328  ASSERT(this != nullptr);
1329  if (Flink == nullptr)
1330  return false;
1331  if (Flink == this)
1332  return false;
1333  return(true);
1334  }
1335  PLIST_ENTRY get_Prev() const
1336  {
1337  ASSERT(Blink != nullptr); // must be init and in a list.
1338  return(Blink);
1339  }
1340  PLIST_ENTRY get_Next() const
1341  {
1342  ASSERT(Flink != nullptr); // must be init and in a list.
1343  return(Flink);
1344  }
1346  {
1348  ASSERT(IsListLinked()); // was in a list!
1349  RemoveEntryList(this);
1350  Flink = nullptr; // not in any list.
1351  Blink = nullptr; // not in any list.
1352  }
1353  };
1354 
1355  template< class TYPE, int _OFFSET_ENTRY = 0 >
1356  struct CKeListT : public CKeList
1357  {
1361 
1362  static inline TYPE* GetCast(PLIST_ENTRY pObj)
1363  {
1365  ASSERT(pObj != nullptr);
1366  return((TYPE*)(((PUCHAR)pObj) - _OFFSET_ENTRY));
1367  }
1368  static inline PLIST_ENTRY GetCast(TYPE* pObj)
1369  {
1371  ASSERT(pObj != nullptr);
1372  return((PLIST_ENTRY)(((PUCHAR)pObj) + _OFFSET_ENTRY));
1373  }
1374  TYPE* get_Head() const
1375  {
1376  ASSERT(Flink != nullptr); // must be init and in a list.
1377  return(GetCast(Flink));
1378  }
1380  {
1382  if (IsListEmptyX())
1383  return nullptr;
1384  PLIST_ENTRY pTmp = RemoveHeadList(this);
1385  return(GetCast(pTmp));
1386  }
1387  bool IsLast(TYPE* pObj) const
1388  {
1389  return(GetCast(pObj) == this); // points back to the list.
1390  }
1392  {
1395  PLIST_ENTRY pEntry = Flink;
1396  ASSERT(pEntry != nullptr);
1397  while (!IsListEmptyX())
1398  {
1399  PLIST_ENTRY pEntryNext = pEntry->Flink;
1400  RemoveEntryList(pEntry);
1401  GetCast(pEntry)->DestroyThis();
1402  pEntry = pEntryNext; // Move To The Next
1403  }
1404  }
1405  void AddHead(TYPE* pObj)
1406  {
1407  __super::AddHead(GetCast(pObj));
1408  }
1409  void AddTail(TYPE* pObj)
1410  {
1411  __super::AddTail(GetCast(pObj));
1412  }
1413  void AddTailLocked(TYPE* pObj, PKSPIN_LOCK pSpinLock)
1414  {
1415  __super::AddTailLocked(GetCast(pObj), pSpinLock);
1416  }
1417  TYPE* GetNext(TYPE* pObj) const
1418  {
1419  return GetCast(pObj->m_ListEntry.get_Next());
1420  }
1421  };
1422 
1423  //*********************************************************
1424 
1425  template< ULONG _UTAG >
1426  struct CKeListObj : public CKeDynamic<_UTAG>
1427  {
1431  bool IsListLinked() const
1432  {
1433  return(m_ListEntry.IsListLinked());
1434  }
1436  {
1438  }
1439  public:
1440  CKeList m_ListEntry; // LIST_ENTRY info
1441  };
1442 
1443  //*********************************************************
1444 
1445  template< class TYPE, int _OFFSET_ENTRY = offsetof(TYPE, m_ListEntry) >
1446  struct CKePool
1447  {
1450  public:
1451  static inline TYPE* GetCast(PLIST_ENTRY pObj)
1452  {
1454  ASSERT(pObj != nullptr);
1455  return((TYPE*)(((PUCHAR)pObj) - _OFFSET_ENTRY));
1456  }
1457  static inline PLIST_ENTRY GetCast(TYPE* pObj)
1458  {
1460  ASSERT(pObj != nullptr);
1461  return((PLIST_ENTRY)(((PUCHAR)pObj) + _OFFSET_ENTRY));
1462  }
1463  void InitPool()
1464  {
1465  m_FreeList.InitList(); // points to itself.
1466  m_UsedList.InitList();
1468  }
1469  bool IsFreeListEmpty() const
1470  {
1471  return m_FreeList.IsListEmptyX();
1472  }
1473  bool IsUsedListEmpty() const
1474  {
1475  return m_UsedList.IsListEmptyX();
1476  }
1478  {
1479  CKeSpinLockLock lock(m_SpinLock); // Locks the list.
1480  return m_FreeList.get_Count();
1481  }
1483  {
1484  CKeSpinLockLock lock(m_SpinLock); // Locks the list.
1485  return m_UsedList.get_Count();
1486  }
1487  void AddFreeObjZ(TYPE* pObj)
1488  {
1490  ASSERT(pObj != nullptr);
1491  ASSERT(!pObj->IsListLinked());
1492  AddFreeObj(pObj);
1493  }
1494 
1495  // Destroy
1497  {
1499  return m_FreeList.DestroyList();
1500  }
1502  {
1504  return m_UsedList.DestroyList();
1505  }
1506 
1507  protected:
1508  // Add and Remove
1509  void AddFreeObj(TYPE* pObj)
1510  {
1511  m_FreeList.AddTailLocked(pObj, m_SpinLock);
1512  }
1513  void AddUsedObj(TYPE* pObj)
1514  {
1515  m_UsedList.AddTailLocked(pObj, m_SpinLock);
1516  }
1518  {
1520  return m_FreeList.RemoveHead();
1521  }
1522  bool IsUsedLast(TYPE* pObj) const
1523  {
1525  return(m_UsedList.IsLast(pObj));
1526  }
1528  {
1530  return(m_UsedList.get_Head());
1531  }
1532  TYPE* GetNext(TYPE* pObj) const
1533  {
1535  return GetCast(pObj->m_ListEntry.get_Next());
1536  }
1537  protected:
1541  };
1542 
1543  //************************************************************************************
1544 
1545  struct CKeIRP : public CKeObject<_IRP>
1546  {
1551  public:
1552  NTSTATUS get_IoStatus() const
1553  {
1554  ASSERT(this != nullptr);
1555  return(IoStatus.Status);
1556  }
1557  SIZE_T get_IoInformationSize() const
1558  {
1560  return IoStatus.Information;
1561  }
1563  {
1564  ASSERT(this != nullptr);
1565  return(AssociatedIrp.SystemBuffer);
1566  }
1567 
1568  void FreeIrp()
1569  {
1570  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
1571  IoFreeIrp(this);
1572  }
1574  {
1575  ASSERT(this != nullptr);
1576  RemoveEntryList(&Tail.Overlay.ListEntry);
1577  }
1578  PDRIVER_CANCEL SetCancelRoutine(PDRIVER_CANCEL pCancelRoutine = nullptr)
1579  {
1580  ASSERT(this != nullptr);
1581  return IoSetCancelRoutine(this, pCancelRoutine);
1582  }
1583  BOOLEAN CancelIrp()
1584  {
1585  ASSERT(this != nullptr);
1586  return IoCancelIrp(this);
1587  }
1589  {
1591  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
1592  ASSERT(this != nullptr);
1593  IoMarkIrpPending(this);
1594  }
1595  void CompleteRequest(CCHAR cPriorityBoost = IO_NO_INCREMENT)
1596  {
1599  ASSERT(this != nullptr);
1600  IoCompleteRequest(this, cPriorityBoost);
1601  }
1602  void CompleteRequestStatus(NTSTATUS lStatus = STATUS_SUCCESS, ULONG_PTR uInformation = 0, CCHAR cPriorityBoost = IO_NO_INCREMENT)
1603  {
1604  IoStatus.Status = lStatus;
1605  IoStatus.Information = uInformation;
1606  CompleteRequest(cPriorityBoost);
1607  }
1608  NTSTATUS CallDriver(IN PDEVICE_OBJECT pDeviceObject)
1609  {
1610  // Typically used to pass along to the next device in a chain. pLowerDeviceObject
1611  ASSERT(this != nullptr);
1612  ASSERT(pDeviceObject != nullptr);
1613  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
1614  return IoCallDriver(pDeviceObject, this);
1615  }
1616 
1617  // Stack Location
1618  PIO_STACK_LOCATION get_StackLocation() const
1619  {
1620  ASSERT(this != nullptr);
1621  return ::IoGetCurrentIrpStackLocation(const_cast<_IRP*>(get_CPtr()));
1622  }
1624  {
1625  ASSERT(this != nullptr);
1626  IoSkipCurrentIrpStackLocation(this);
1627  }
1628  NTSTATUS SkipStackLocation(PDEVICE_OBJECT pLowerDeviceObject)
1629  {
1632  return CallDriver(pLowerDeviceObject);
1633  }
1634  PIO_STACK_LOCATION get_NextStackLocation() const
1635  {
1636  return IoGetNextIrpStackLocation(const_cast<_IRP*>(get_CPtr()));
1637  }
1639  {
1640  IoCopyCurrentIrpStackLocationToNext(this);
1641  }
1643  {
1644  IoSetNextIrpStackLocation(this);
1645  }
1646  void SetCompletionRoutine(PIO_COMPLETION_ROUTINE pRoutine, void* pCompletionContext, UCHAR uControlFlags)
1647  {
1650  ASSERT((uControlFlags) ? (pRoutine != nullptr) : true);
1651  PIO_STACK_LOCATION pIrpStack = get_NextStackLocation();
1652  ASSERT(pIrpStack != nullptr);
1653  pIrpStack->CompletionRoutine = pRoutine;
1654  pIrpStack->Context = pCompletionContext;
1655  pIrpStack->Control = uControlFlags;
1656  }
1657  void SetCompletionRoutine(PIO_COMPLETION_ROUTINE pRoutine, void* pCompletionContext, bool bInvokeOnSuccess, bool bInvokeOnError, bool bInvokeOnCancel)
1658  {
1660  IoSetCompletionRoutine(this, // The IRP
1661  pRoutine, // The completion routine
1662  pCompletionContext, // The completion context
1663  bInvokeOnSuccess, // Invoke On Success
1664  bInvokeOnError, // Invoke On Error
1665  bInvokeOnCancel); // Invoke On Cancel
1666  }
1667  };
1668 
1670  {
1674  public:
1676  {
1677  m_queue.InitList();
1678  }
1680  {
1681  ASSERT(m_queue.IsListEmptyX());
1682  }
1683  static inline void RemoveIrpFromQueue(IN PIRP pIrp)
1684  {
1685  ASSERT(pIrp != nullptr);
1686  RemoveEntryList(&pIrp->Tail.Overlay.ListEntry);
1687  }
1688  void AddIrpToQueue(IN PIRP pIrp)
1689  {
1691  ASSERT(this != nullptr);
1692  m_queue.AddTail((CKeIRP*)pIrp);
1693  }
1694  void AddIrpToHead(IN PIRP pIrp)
1695  {
1697  ASSERT(this != nullptr);
1698  m_queue.AddHead((CKeIRP*)pIrp);
1699  }
1700  void CompleteIrpQueue(IN CCHAR cPriorityBoost = IO_SERIAL_INCREMENT)
1701  {
1703  ASSERT(this != nullptr);
1704  for (;;)
1705  {
1706  CKeIRP* pIrp = m_queue.RemoveHead();
1707  if (pIrp == nullptr)
1708  return;
1709  // TraceIrp("complete", pIrp, &pIrp->get_IoStatus(), TRACE_FLAG_RESULTS);
1710  pIrp->CompleteRequest(cPriorityBoost);
1711  }
1712  }
1713  protected:
1714  CKeListT< CKeIRP, offsetof(CKeIRP, Tail.Overlay.ListEntry) > m_queue;
1715  };
1716 
1717  //************************************************************************************
1718 
1719  struct CKeDeviceObject;
1720 
1721  struct CKeFileObject : public CKeObject<_FILE_OBJECT>
1722  {
1726  {
1727  ASSERT(this != nullptr);
1728  ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
1729  return (CKeDeviceObject*)IoGetRelatedDeviceObject(this);
1730  }
1731  };
1732  typedef CKeObjectPtr<_FILE_OBJECT> CKeFileObjectPtr; // CKeFileObject=_FILE_OBJECT
1733 
1734  struct CKeFileHandle : public CKeHandle
1735  {
1739 
1740 #if 0
1741  NTSTATUS CreateFile(OBJECT_ATTRIBUTES& objectAttributes, IO_STATUS_BLOCK& ioStatusBlock)
1742  {
1743  // ASSUME InitializeObjectAttributes already called.
1744  return ZwCreateFile(
1745  get_HandlePtr(),
1746  SYNCHRONIZE | FILE_APPEND_DATA,
1747  &objectAttributes,
1748  &ioStatusBlock,
1749  nullptr,
1750  FILE_ATTRIBUTE_NORMAL,
1751  FILE_SHARE_READ | FILE_SHARE_WRITE,
1752  FILE_OPEN_IF,
1753  FILE_SYNCHRONOUS_IO_NONALERT,
1754  nullptr,
1755  0);
1756  }
1757 #endif
1758 
1759  NTSTATUS WriteFile(IO_STATUS_BLOCK* pIoStatusBlock, PVOID pBuffer, ULONG nLength)
1760  {
1761  return ::ZwWriteFile(m_Handle,
1762  nullptr,
1763  nullptr,
1764  nullptr,
1765  pIoStatusBlock,
1766  pBuffer,
1767  nLength,
1768  nullptr,
1769  nullptr);
1770  }
1771  };
1772 
1773  //************************************************************************************
1774 
1776  {
1779  CKeRegistry(ULONG uRelativeTo, PWSTR pPath)
1780  : m_uRelativeTo(uRelativeTo)
1781  , m_pPath(pPath)
1782  {}
1783 
1784  NTSTATUS CreateKey()
1785  {
1786  return RtlCreateRegistryKey(m_uRelativeTo, m_pPath);
1787  }
1788  NTSTATUS CheckKey()
1789  {
1790  return RtlCheckRegistryKey(m_uRelativeTo, m_pPath);
1791  }
1792  NTSTATUS WriteValue(IN PCWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength)
1793  {
1797  return RtlWriteRegistryValue(m_uRelativeTo, m_pPath,
1798  ValueName, ValueType, ValueData, ValueLength);
1799  }
1800  NTSTATUS DeleteValue(IN PCWSTR ValueName = nullptr)
1801  {
1803  return RtlDeleteRegistryValue(m_uRelativeTo, m_pPath, ValueName);
1804  }
1805  NTSTATUS QueryValues(RTL_QUERY_REGISTRY_TABLE* pQueryTable, IN PVOID pContext = nullptr, IN PVOID pEnvironment = nullptr)
1806  {
1807  return RtlQueryRegistryValues(m_uRelativeTo, m_pPath, pQueryTable, pContext, pEnvironment);
1808  }
1809 
1810  NTSTATUS WriteValueStr(IN PCWSTR ValueName, UNICODE_STRING& str)
1811  {
1812  return WriteValue(ValueName, REG_SZ, str.Buffer, str.Length + sizeof(WCHAR));
1813  }
1814  NTSTATUS WriteValueStr(IN PCWSTR ValueName, const WCHAR* pStr)
1815  {
1816  CKeStringUS str;
1817  str.InitStatic(pStr);
1818  return WriteValue(ValueName, REG_SZ, str.Buffer, str.Length + sizeof(WCHAR));
1819  }
1820 
1821  public:
1823  PWSTR m_pPath;
1824  };
1825 
1826  //************************************************************************************
1827 
1828  struct CKeDeviceObject : public CKeObject<_DEVICE_OBJECT>
1829  {
1833  {
1834  ASSERT(this != nullptr);
1835  IoDeleteDevice(this);
1836  }
1838  {
1839  // Detach if attached. reverse IoAttachDeviceToDeviceStack()
1840  ASSERT(this != nullptr);
1841  IoDetachDevice(this);
1842  }
1843  NTSTATUS GetDeviceProperty(DEVICE_REGISTRY_PROPERTY eDeviceProperty, IN ULONG uBufferLength, OUT PVOID pPropertyBuffer, OUT PULONG puResultLength)
1844  {
1845  // Get some registered property of the device.
1846  // eDeviceProperty = DevicePropertyPhysicalDeviceObjectName
1847  ASSERT(this != nullptr);
1848  return IoGetDeviceProperty(this,
1849  eDeviceProperty,
1850  uBufferLength,
1851  pPropertyBuffer,
1852  puResultLength);
1853  }
1854  };
1855  typedef CKeObjectPtr<_DEVICE_OBJECT> CKeDeviceObjectPtr; // CKeDeviceObject = _DEVICE_OBJECT
1856 
1858  {
1863  static const ULONG CKeDeviceExt_SIGNATURE = 0x1FE04322; // Unlikely id code.
1864 
1865  void InitDeviceExt(USHORT uSize, PDEVICE_OBJECT pDeviceObj)
1866  {
1867  ASSERT(this != nullptr);
1868  ASSERT(pDeviceObj != nullptr);
1869  m_wType = 255; // NOT the same as IO_TYPE_DEVICE_OBJECT_EXTENSION
1870  m_wSize = uSize; // size of the total structure. Windows seems to think 0 is OK here for _DEVOBJ_EXTENSION?
1871  m_pDeviceObject = (CKeDeviceObject*)pDeviceObj;
1872  m_uDeviceSignature = CKeDeviceExt_SIGNATURE;
1873  ASSERT(IsDeviceValid());
1874  }
1875  static inline CKeDeviceExt* GetDeviceExt(PDEVICE_OBJECT pDeviceObj)
1876  {
1877  ASSERT(pDeviceObj != nullptr);
1878  ASSERT(pDeviceObj->DeviceExtension != nullptr);
1879  return (CKeDeviceExt*)(pDeviceObj->DeviceExtension);
1880  }
1881  bool IsDeviceValid() const
1882  {
1883  // ASSERT( g_Driver.IsDriverValid());
1884  if (m_uDeviceSignature != CKeDeviceExt_SIGNATURE)
1885  return false;
1886  ASSERT(((UINT_PTR)this) > sizeof(*this) + 256);
1887  ASSERT(m_wSize > sizeof(*this));
1888  return(m_pDeviceObject != nullptr);
1889  }
1890  bool IsDeviceValid(IN PDEVICE_OBJECT _pDeviceObject) const
1891  {
1892  if (!IsDeviceValid())
1893  return false;
1894  if (_pDeviceObject != m_pDeviceObject) // back pointer is correct?
1895  return false;
1896  return true;
1897  }
1899  {
1900  ASSERT(IsDeviceValid());
1901  m_uDeviceSignature = 0;
1902  // Note that on 4.0 and later systems, this will result in a recursive fast detach.
1903  m_pDeviceObject->DeleteDevice();
1904  // NOTE: 'delete *this' has now occurred !!!
1905  }
1907  {
1908  return m_pDeviceObject;
1909  }
1910 
1911  CKeDeviceObject* AttachToDeviceStack(PDEVICE_OBJECT pDeviceObjectAttach)
1912  {
1915  ASSERT(m_pDeviceObject != nullptr);
1916  ASSERT(pDeviceObjectAttach != nullptr);
1917  return (CKeDeviceObject*)IoAttachDeviceToDeviceStack(m_pDeviceObject, pDeviceObjectAttach);
1918  }
1919 
1921  {
1923  ASSERT(IsDeviceValid());
1924  m_pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1925  }
1926 
1927  private:
1929  CSHORT m_wType;
1930  USHORT m_wSize;
1931  CKeDeviceObject* m_pDeviceObject;
1932 
1933  ULONG m_uDeviceSignature;
1934  };
1935 
1936  struct CKeDriverObject : public CKeObject<_DRIVER_OBJECT>
1937  {
1940  };
1941 
1942  struct CKeDriver
1943  {
1950 
1951  void InitDriver(PDRIVER_OBJECT pDriverObject)
1952  {
1953  // called from DriverEntry()
1954  ASSERT(pDriverObject != nullptr);
1955  m_pDriverObject = (CKeDriverObject*)pDriverObject;
1956  RtlInitUnicodeString(&m_ServiceKeyName, nullptr);
1957  }
1958  bool IsDriverValid() const
1959  {
1960  return(m_pDriverObject != nullptr);
1961  }
1963  {
1964  return m_pDriverObject;
1965  }
1967  {
1968  ASSERT(m_pDriverObject != nullptr);
1969  return (CKeDeviceObject*)(m_pDriverObject->DeviceObject);
1970  }
1972  {
1973  return (CKeStringU&)m_ServiceKeyName;
1974  }
1975 
1976  NTSTATUS CreateDevice(ULONG uDeviceExtensionSize,
1977  IN PUNICODE_STRING puDeviceName OPTIONAL,
1978  IN DEVICE_TYPE eDeviceType,
1979  IN ULONG uDeviceCharacteristics,
1980  IN bool bExclusive,
1981  OUT PDEVICE_OBJECT *ppDeviceObject)
1982  {
1983  // see IoCreateDeviceSecure?
1984  // eDeviceType = FILE_DEVICE_BEEP
1985  ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
1986  return IoCreateDevice(
1987  m_pDriverObject,
1988  uDeviceExtensionSize,
1989  puDeviceName,
1990  eDeviceType,
1991  uDeviceCharacteristics, // No standard device characteristics FILE_READ_ONLY_DEVICE
1992  bExclusive, // DO_EXCLUSIVE = only one handle to this may be open?
1993  ppDeviceObject);
1994  }
1995 
1996  private:
1997  CKeDriverObject * m_pDriverObject;
1999  UNICODE_STRING m_ServiceKeyName;
2000  };
2001  // extern CKeDriver g_Driver;
2002 };
2003 
2004 #endif // _INC_CKernel_H
#define TYPE
Definition: StrT.cpp:38
#define ASSERT(exp)
Definition: cDebugAssert.h:87
NTSYSAPI NTSTATUS NTAPI ObOpenObjectByPointer(PVOID Object, ULONG HandleAttributes, PACCESS_STATE PassedAccessState, ACCESS_MASK DesiredAccess, POBJECT_TYPE ObjectType, KPROCESSOR_MODE AccessMode, PHANDLE Handle)
Documented on MSDN.
#define CKeMem_Free(p, _UTAG)
Definition: cKernel.h:138
NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG uReturnLength OPTIONAL)
Documented on MSDN with Caveat.
#define HANDLE_NULL
Definition: cKernel.h:37
int COMPARE_t
Definition: cKernel.h:38
Definition: cKernel.cpp:10
CKeObjectPtr< _FILE_OBJECT > CKeFileObjectPtr
Definition: cKernel.h:1732
CKeObjectPtr< _DEVICE_OBJECT > CKeDeviceObjectPtr
Definition: cKernel.h:1855
__DECL_IMPORT TYPE Decrement(TYPE volatile *pnValue) noexcept
__DECL_IMPORT TYPE Increment(TYPE volatile *pnValue) noexcept
__DECL_IMPORT TYPE ExchangeAdd(TYPE volatile *pnValue, TYPE nValue) noexcept
__DECL_IMPORT TYPE Exchange(TYPE volatile *pnValue, TYPE nValue) noexcept
INT32 __cdecl InterlockedExchangeAdd(INT32 volatile *pDest, INT32 Value) noexcept
Definition: cInterlockedVal.h:160
INT32 __cdecl InterlockedDecrement(INT32 volatile *pDest) noexcept
Definition: cInterlockedVal.h:133
INT32 __cdecl InterlockedCompareExchange(INT32 volatile *pDest, INT32 nValNew, INT32 nValComp) noexcept
Definition: cInterlockedVal.h:49
INT32 __cdecl InterlockedIncrement(INT32 volatile *pDest) noexcept
Definition: cInterlockedVal.h:115
INT32 __cdecl InterlockedExchange(INT32 volatile *pDest, INT32 Value) noexcept
Definition: cInterlockedVal.h:151
Definition: cKernel.h:1858
void Flag_Init_Clear()
Definition: cKernel.h:1920
bool IsDeviceValid() const
Definition: cKernel.h:1881
void DeleteDevice()
Definition: cKernel.h:1898
bool IsDeviceValid(IN PDEVICE_OBJECT _pDeviceObject) const
Definition: cKernel.h:1890
CKeDeviceObject * get_DeviceObject() const
Definition: cKernel.h:1906
void InitDeviceExt(USHORT uSize, PDEVICE_OBJECT pDeviceObj)
Definition: cKernel.h:1865
static const ULONG CKeDeviceExt_SIGNATURE
Definition: cKernel.h:1863
static CKeDeviceExt * GetDeviceExt(PDEVICE_OBJECT pDeviceObj)
Definition: cKernel.h:1875
CKeDeviceObject * AttachToDeviceStack(PDEVICE_OBJECT pDeviceObjectAttach)
Definition: cKernel.h:1911
Definition: cKernel.h:1829
void DetachDeviceStack()
Definition: cKernel.h:1837
NTSTATUS GetDeviceProperty(DEVICE_REGISTRY_PROPERTY eDeviceProperty, IN ULONG uBufferLength, OUT PVOID pPropertyBuffer, OUT PULONG puResultLength)
Definition: cKernel.h:1843
void DeleteDevice()
Definition: cKernel.h:1832
Definition: cKernel.h:1937
Definition: cKernel.h:1943
bool IsDriverValid() const
Definition: cKernel.h:1958
CKeDeviceObject * get_DeviceFirst() const
Definition: cKernel.h:1966
NTSTATUS CreateDevice(ULONG uDeviceExtensionSize, IN PUNICODE_STRING puDeviceName OPTIONAL, IN DEVICE_TYPE eDeviceType, IN ULONG uDeviceCharacteristics, IN bool bExclusive, OUT PDEVICE_OBJECT *ppDeviceObject)
Definition: cKernel.h:1976
CKeDriverObject * get_DriverObject() const
Definition: cKernel.h:1962
CKeStringU & get_RegistryPath()
Definition: cKernel.h:1971
void InitDriver(PDRIVER_OBJECT pDriverObject)
Definition: cKernel.h:1951
Definition: cKernel.h:215
void DestroyThis()
Definition: cKernel.h:219
Definition: cKernel.h:802
void InitEvent()
Definition: cKernel.h:805
LONG SetEvent()
Definition: cKernel.h:814
NTSTATUS WaitForEvent()
Definition: cKernel.h:819
void ClearEvent()
Definition: cKernel.h:809
Definition: cKernel.h:1735
NTSTATUS WriteFile(IO_STATUS_BLOCK *pIoStatusBlock, PVOID pBuffer, ULONG nLength)
Definition: cKernel.h:1759
Definition: cKernel.h:1722
CKeDeviceObject * get_RelatedDeviceObject()
Definition: cKernel.h:1725
Definition: cKernel.h:705
HANDLE * get_HandlePtr()
Definition: cKernel.h:721
HANDLE m_Handle
Definition: cKernel.h:756
~CKeHandle()
Definition: cKernel.h:714
NTSTATUS CloseHandle()
Definition: cKernel.h:726
NTSTATUS OpenByPointer(PVOID pObject, ULONG uHandleAttributes=OBJ_KERNEL_HANDLE, PACCESS_STATE pPassedAccessState=nullptr, ACCESS_MASK uDesiredAccess=FILE_ANY_ACCESS, POBJECT_TYPE pObjectType=nullptr, KPROCESSOR_MODE eAccessMode=KernelMode)
Definition: cKernel.h:734
CKeHandle(HANDLE Handle=NULL)
Definition: cKernel.h:711
Definition: cKernel.h:1546
void SkipStackLocation()
Definition: cKernel.h:1623
NTSTATUS CallDriver(IN PDEVICE_OBJECT pDeviceObject)
Definition: cKernel.h:1608
void CopyStackLocationToNext()
Definition: cKernel.h:1638
NTSTATUS get_IoStatus() const
Definition: cKernel.h:1552
SIZE_T get_IoInformationSize() const
Definition: cKernel.h:1557
void CompleteRequestStatus(NTSTATUS lStatus=STATUS_SUCCESS, ULONG_PTR uInformation=0, CCHAR cPriorityBoost=IO_NO_INCREMENT)
Definition: cKernel.h:1602
void CompleteRequest(CCHAR cPriorityBoost=IO_NO_INCREMENT)
Definition: cKernel.h:1595
PVOID get_AssocSystemBuffer() const
Definition: cKernel.h:1562
void RemoveIrpFromQueue()
Definition: cKernel.h:1573
void FreeIrp()
Definition: cKernel.h:1568
void SetCompletionRoutine(PIO_COMPLETION_ROUTINE pRoutine, void *pCompletionContext, bool bInvokeOnSuccess, bool bInvokeOnError, bool bInvokeOnCancel)
Definition: cKernel.h:1657
NTSTATUS SkipStackLocation(PDEVICE_OBJECT pLowerDeviceObject)
Definition: cKernel.h:1628
void SetNextStackLocation()
Definition: cKernel.h:1642
void SetCompletionRoutine(PIO_COMPLETION_ROUTINE pRoutine, void *pCompletionContext, UCHAR uControlFlags)
Definition: cKernel.h:1646
BOOLEAN CancelIrp()
Definition: cKernel.h:1583
void MarkIrpPending()
Definition: cKernel.h:1588
PIO_STACK_LOCATION get_StackLocation() const
Definition: cKernel.h:1618
PIO_STACK_LOCATION get_NextStackLocation() const
Definition: cKernel.h:1634
PDRIVER_CANCEL SetCancelRoutine(PDRIVER_CANCEL pCancelRoutine=nullptr)
Definition: cKernel.h:1578
Definition: cKernel.h:261
LONG Increment()
Definition: cKernel.h:271
void Init(LONG lVal=0)
Definition: cKernel.h:267
LONG ExchangeAdd(LONG lValAdd)
Definition: cKernel.h:283
LONG m_lVal
Definition: cKernel.h:265
LONG Decrement()
Definition: cKernel.h:275
LONG Exchange(LONG lVal=0)
Definition: cKernel.h:279
LONG ExchangeIf(LONG lValCompare, LONG lVal=0)
Definition: cKernel.h:287
Definition: cKernel.h:378
CKeInterlockedPtrX(TYPE *pVal=nullptr)
Definition: cKernel.h:381
Definition: cKernel.h:346
TYPE * Exchange(TYPE *pVal=nullptr)
Definition: cKernel.h:356
void InitPtr(TYPE *pVal=nullptr)
Definition: cKernel.h:352
TYPE * ExchangeIf(TYPE *pValCompare, TYPE *pVal=nullptr)
Definition: cKernel.h:361
TYPE *& InitRef()
Definition: cKernel.h:370
TYPE * m_pVal
Definition: cKernel.h:350
Definition: cKernel.h:1670
void AddIrpToHead(IN PIRP pIrp)
Definition: cKernel.h:1694
CKeListT< CKeIRP, offsetof(CKeIRP, Tail.Overlay.ListEntry) > m_queue
Definition: cKernel.h:1714
~CKeIrpQueue()
Definition: cKernel.h:1679
void CompleteIrpQueue(IN CCHAR cPriorityBoost=IO_SERIAL_INCREMENT)
Definition: cKernel.h:1700
CKeIrpQueue()
Definition: cKernel.h:1675
static void RemoveIrpFromQueue(IN PIRP pIrp)
Definition: cKernel.h:1683
void AddIrpToQueue(IN PIRP pIrp)
Definition: cKernel.h:1688
Definition: cKernel.h:1427
void RemoveFromList()
Definition: cKernel.h:1435
bool IsListLinked() const
Definition: cKernel.h:1431
CKeList m_ListEntry
Definition: cKernel.h:1440
Definition: cKernel.h:1357
TYPE * get_Head() const
Definition: cKernel.h:1374
static TYPE * GetCast(PLIST_ENTRY pObj)
Definition: cKernel.h:1362
bool IsLast(TYPE *pObj) const
Definition: cKernel.h:1387
void DestroyList()
Definition: cKernel.h:1391
TYPE * GetNext(TYPE *pObj) const
Definition: cKernel.h:1417
static PLIST_ENTRY GetCast(TYPE *pObj)
Definition: cKernel.h:1368
TYPE * RemoveHead()
Definition: cKernel.h:1379
void AddTail(TYPE *pObj)
Definition: cKernel.h:1409
void AddHead(TYPE *pObj)
Definition: cKernel.h:1405
void AddTailLocked(TYPE *pObj, PKSPIN_LOCK pSpinLock)
Definition: cKernel.h:1413
Definition: cKernel.h:1262
void AddTailLocked(PLIST_ENTRY pObj, PKSPIN_LOCK pSpinLock)
Definition: cKernel.h:1316
PLIST_ENTRY get_Prev() const
Definition: cKernel.h:1335
PLIST_ENTRY RemoveHead()
Definition: cKernel.h:1294
void InitList()
Definition: cKernel.h:1269
bool IsListLinked() const
Definition: cKernel.h:1326
PLIST_ENTRY get_Next() const
Definition: cKernel.h:1340
void AddTail(PLIST_ENTRY pObj)
Definition: cKernel.h:1309
void RemoveFromList()
Definition: cKernel.h:1345
void AddHead(PLIST_ENTRY pObj)
Definition: cKernel.h:1302
bool IsListEmptyX() const
Definition: cKernel.h:1274
int get_Count() const
Definition: cKernel.h:1283
PLIST_ENTRY get_Head() const
Definition: cKernel.h:1278
Definition: cKernel.h:143
TYPE * m_p
Definition: cKernel.h:147
void Free()
Definition: cKernel.h:181
bool IsValidMem() const
Definition: cKernel.h:195
TYPE * DetachMem()
Definition: cKernel.h:188
void FreeLast()
Definition: cKernel.h:175
NTSTATUS AllocMemQuota(POOL_TYPE ePoolType, SIZE_T nNumberOfBytes=sizeof(TYPE))
Definition: cKernel.h:159
TYPE * operator->()
Definition: cKernel.h:207
bool AllocMem(POOL_TYPE ePoolType, SIZE_T nNumberOfBytes=sizeof(TYPE))
Definition: cKernel.h:153
void InitMem(TYPE *p=nullptr)
Definition: cKernel.h:149
Definition: cKernel.h:604
bool IsValidObj() const
Definition: cKernel.h:665
TYPE * operator->()
Definition: cKernel.h:677
void ReleaseObject()
Definition: cKernel.h:638
NTSTATUS ReferenceByHandle(IN HANDLE Handle, IN ACCESS_MASK uDesiredAccess=FILE_ANY_ACCESS, IN POBJECT_TYPE pObjectType=nullptr, IN KPROCESSOR_MODE eAccessMode=KernelMode, OUT POBJECT_HANDLE_INFORMATION pHandleInformation=nullptr)
Definition: cKernel.h:615
TYPE ** get_ObjectPPtr()
Definition: cKernel.h:657
void ReferenceObject()
Definition: cKernel.h:632
CKeObjectPtr(TYPE *pObject=nullptr)
Definition: cKernel.h:610
CKeObject< TYPE > * get_ObjectPtr() const
Definition: cKernel.h:661
CKeObject< TYPE > * DetachObject()
Definition: cKernel.h:645
void ReleaseLast()
Definition: cKernel.h:651
Definition: cKernel.h:1447
TYPE * RemoveFreeObj()
Definition: cKernel.h:1517
void AddUsedObj(TYPE *pObj)
Definition: cKernel.h:1513
static TYPE * GetCast(PLIST_ENTRY pObj)
Definition: cKernel.h:1451
void AddFreeObjZ(TYPE *pObj)
Definition: cKernel.h:1487
bool IsFreeListEmpty() const
Definition: cKernel.h:1469
void DestroyUsedList()
Definition: cKernel.h:1501
bool IsUsedListEmpty() const
Definition: cKernel.h:1473
bool IsUsedLast(TYPE *pObj) const
Definition: cKernel.h:1522
CKeListT< TYPE, _OFFSET_ENTRY > m_UsedList
Definition: cKernel.h:1539
TYPE * get_UsedFirst() const
Definition: cKernel.h:1527
int get_FreeCount()
Definition: cKernel.h:1477
int get_UsedCount()
Definition: cKernel.h:1482
CKeListT< TYPE, _OFFSET_ENTRY > m_FreeList
Definition: cKernel.h:1538
void InitPool()
Definition: cKernel.h:1463
void AddFreeObj(TYPE *pObj)
Definition: cKernel.h:1509
CKeSpinLock m_SpinLock
Definition: cKernel.h:1540
TYPE * GetNext(TYPE *pObj) const
Definition: cKernel.h:1532
static PLIST_ENTRY GetCast(TYPE *pObj)
Definition: cKernel.h:1457
void DestroyFreeList()
Definition: cKernel.h:1496
Definition: cKernel.h:1776
NTSTATUS WriteValueStr(IN PCWSTR ValueName, UNICODE_STRING &str)
Definition: cKernel.h:1810
PWSTR m_pPath
e.g. L"SERIALCOMM"
Definition: cKernel.h:1823
NTSTATUS WriteValueStr(IN PCWSTR ValueName, const WCHAR *pStr)
Definition: cKernel.h:1814
NTSTATUS QueryValues(RTL_QUERY_REGISTRY_TABLE *pQueryTable, IN PVOID pContext=nullptr, IN PVOID pEnvironment=nullptr)
Definition: cKernel.h:1805
CKeRegistry(ULONG uRelativeTo, PWSTR pPath)
Definition: cKernel.h:1779
NTSTATUS WriteValue(IN PCWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength)
Definition: cKernel.h:1792
NTSTATUS DeleteValue(IN PCWSTR ValueName=nullptr)
Definition: cKernel.h:1800
NTSTATUS CreateKey()
Definition: cKernel.h:1784
ULONG m_uRelativeTo
RTL_REGISTRY_ABSOLUTE, RTL_REGISTRY_DEVICEMAP, RTL_REGISTRY_MAXIMUM, etc.
Definition: cKernel.h:1822
NTSTATUS CheckKey()
Definition: cKernel.h:1788
Definition: cKernel.h:435
CKeSpinLockDpcLevel(PKSPIN_LOCK pSpinLock)
Definition: cKernel.h:442
~CKeSpinLockDpcLevel()
Definition: cKernel.h:449
PKSPIN_LOCK m_pSpinLock
Must keep a pointer to it to auto unlock on destructor.
Definition: cKernel.h:440
Definition: cKernel.h:458
void Add(ULONG uDelta=1)
Definition: cKernel.h:471
void Subtract(ULONG uDelta=1)
Definition: cKernel.h:476
bool IsZero()
Definition: cKernel.h:481
void InitLargeInteger()
Definition: cKernel.h:466
ULONG get_Low() const
Definition: cKernel.h:487
Definition: cKernel.h:410
~CKeSpinLockLock()
Definition: cKernel.h:428
KIRQL m_OldIrql
IRQL before the lock.
Definition: cKernel.h:415
PKSPIN_LOCK m_pSpinLock
Must keep a pointer to it to auto unlock on destructor.
Definition: cKernel.h:414
CKeSpinLockLock(PKSPIN_LOCK pSpinLock)
Definition: cKernel.h:417
Definition: cKernel.h:389
void InitSpinLock()
Definition: cKernel.h:395
KSPIN_LOCK m_SpinLock
Definition: cKernel.h:393
Definition: cKernel.h:1115
NTSTATUS FromUnicode(PUNICODE_STRING pStr, bool bAlloc=false)
Definition: cKernel.h:1176
NTSTATUS AppendStr(const char *pStr, USHORT uLenStr)
Definition: cKernel.h:1182
void InitBuffer(char *pBuffer, USHORT uMaximumLength)
Definition: cKernel.h:1131
void FreeSys()
Definition: cKernel.h:1249
NTSTATUS AppendStr(const WCHAR *pStr)
Definition: cKernel.h:1244
bool IsValidStr() const
Definition: cKernel.h:1138
NTSTATUS AppendStr(const ANSI_STRING &str)
Definition: cKernel.h:1204
NTSTATUS AppendStr(const WCHAR *pStr, USHORT uLenStr)
Definition: cKernel.h:1216
NTSTATUS AppendStr(const char *pStr)
Definition: cKernel.h:1209
void InitStatic(const char *pStr)
Definition: cKernel.h:1126
void InitStr()
Definition: cKernel.h:1120
NTSTATUS ToInteger(ULONG &uValue, ULONG nBase=10) const
Definition: cKernel.h:1146
Definition: cKernel.h:835
NTSTATUS AppendInteger(ULONG uValue, ULONG uBase=10)
Definition: cKernel.h:943
COMPARE_t CompareStr(const UNICODE_STRING &rString2, BOOLEAN bCaseInSensitive=false) const
Definition: cKernel.h:902
void InitBufferZ(PWSTR pBuffer, USHORT uMaximumLength)
Definition: cKernel.h:875
NTSTATUS FromAnsi(PANSI_STRING pStr, bool bAlloc=false)
Definition: cKernel.h:920
void UpcaseString()
Definition: cKernel.h:839
NTSTATUS FromInt64(IN ULONGLONG Value, IN ULONG nBase=10)
Definition: cKernel.h:916
NTSTATUS ToInteger(ULONG &uValue, ULONG nBase=10) const
Definition: cKernel.h:911
bool IsValidStr() const
Definition: cKernel.h:881
void AppendStr(NTSTATUS &lStatus, PCWSTR pwSource)
Definition: cKernel.h:935
void FreeSys()
Definition: cKernel.h:953
void InitBuffer(PWSTR pBuffer, USHORT uMaximumLength)
Definition: cKernel.h:868
NTSTATUS FromInteger(IN ULONG uValue, IN ULONG uBase=10)
Definition: cKernel.h:907
PWSTR DetachStr()
Definition: cKernel.h:893
void InitStatic(const WCHAR *pStr, USHORT wLength)
Definition: cKernel.h:851
NTSTATUS AppendStr(const UNICODE_STRING &str)
Definition: cKernel.h:925
NTSTATUS AppendStr(PCWSTR pwSource)
Definition: cKernel.h:930
void InitStatic(const WCHAR *pStr)
Definition: cKernel.h:859
void InitStr()
Definition: cKernel.h:844
Definition: cKernel.h:964
void AppendInteger(NTSTATUS &lStatus, ULONG uValue, ULONG uBase=10)
Definition: cKernel.h:1063
CKeStringU()
Definition: cKernel.h:972
NTSTATUS AppendStr(PCWSTR pStr)
Definition: cKernel.h:1024
void AppendStr(NTSTATUS &lStatus, const UNICODE_STRING &str)
Definition: cKernel.h:1046
void AppendStr(NTSTATUS &lStatus, PCWSTR pStr, USHORT nLengthStr)
Definition: cKernel.h:1040
NTSTATUS AppendStr(PCWSTR pStr, USHORT nLengthStr)
Definition: cKernel.h:992
CKeStringU(PCWSTR pStr)
Definition: cKernel.h:976
static const ULONG CKeStringU_TAG
Definition: cKernel.h:970
void AppendStr(NTSTATUS &lStatus, PCWSTR pStr)
Definition: cKernel.h:1034
NTSTATUS CreateStr(const UNICODE_STRING &str)
Definition: cKernel.h:1093
void FreeString()
Definition: cKernel.h:984
NTSTATUS AppendInteger(ULONG uValue, ULONG uBase=10)
Definition: cKernel.h:1053
NTSTATUS CreateStr(PCWSTR pStr)
Definition: cKernel.h:1097
NTSTATUS AppendStr(const UNICODE_STRING &str)
Definition: cKernel.h:1029
void FreeStringLast()
Definition: cKernel.h:1104
~CKeStringU()
Definition: cKernel.h:980
NTSTATUS CreateStr(PCWSTR pStr, USHORT nLengthStr)
Definition: cKernel.h:1072
Definition: cKernel.h:496
int get_AgeSec() const
Definition: cKernel.h:511
void InitTime()
Definition: cKernel.h:503
void GetTimeFields(PTIME_FIELDS pTimeFields)
Definition: cKernel.h:531
LARGE_INTEGER m_TimeVal
very high precision time.
Definition: cKernel.h:537
void MakeLocalTime()
Definition: cKernel.h:520
void QuerySystemTime()
Definition: cKernel.h:507
Definition: cKernel.h:762
void CancelTimerEx()
Definition: cKernel.h:789
void InitTimer(IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: cKernel.h:766
KDPC m_Dpc
Definition: cKernel.h:796
void CancelTimer()
Definition: cKernel.h:785
void SetTimer(LARGE_INTEGER &dueTime)
Definition: cKernel.h:771
void SetTimerEx(LARGE_INTEGER &dueTime, ULONG period)
Definition: cKernel.h:778
KTIMER m_Timer
Definition: cKernel.h:795