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.

204 lines
6.2 KiB

  1. /*
  2. Copyright (c) 1998-2000 Microsoft Corporation. All rights reserved.
  3. */
  4. //
  5. // KernHelp.cpp
  6. //
  7. // Wrappers for kernel functions to make synth core cross compilable
  8. //
  9. #define STR_MODULENAME "DDKSynth.sys:KernHelp: "
  10. extern "C" {
  11. #include <wdm.h>
  12. };
  13. #include "ksdebug.h"
  14. #include "KernHelp.h"
  15. #pragma code_seg()
  16. /*****************************************************************************
  17. * InitializeCriticalSection()
  18. *****************************************************************************
  19. * In kernel mode, we use a KMUTEX to implement our critical section.
  20. * Initialize the KMUTEX.
  21. */
  22. VOID InitializeCriticalSection(LPCRITICAL_SECTION CritSect)
  23. {
  24. KeInitializeMutex((PKMUTEX)CritSect, 1);
  25. }
  26. /*****************************************************************************
  27. * EnterCriticalSection()
  28. *****************************************************************************
  29. * In kernel mode, we use a KMUTEX to implement our critical section.
  30. * Grab (wait for) the KMUTEX.
  31. */
  32. VOID EnterCriticalSection(LPCRITICAL_SECTION CritSect)
  33. {
  34. KeWaitForSingleObject((PKMUTEX)CritSect,
  35. Executive,
  36. KernelMode,
  37. FALSE,
  38. 0);
  39. }
  40. /*****************************************************************************
  41. * LeaveCriticalSection()
  42. *****************************************************************************
  43. * In kernel mode, we use a KMUTEX to implement our critical section.
  44. * Release the KMUTEX.
  45. */
  46. VOID LeaveCriticalSection(LPCRITICAL_SECTION CritSect)
  47. {
  48. KeReleaseMutex((PKMUTEX)CritSect, FALSE);
  49. }
  50. /*****************************************************************************
  51. * DeleteCriticalSection()
  52. *****************************************************************************
  53. * In kernel mode, we use a KMUTEX to implement our critical section.
  54. * No need to delete anything.
  55. */
  56. VOID DeleteCriticalSection(LPCRITICAL_SECTION CritSect)
  57. {
  58. // NOP in kernel
  59. //
  60. }
  61. // GetRegValueDword
  62. //
  63. // Must be called at passive level
  64. //
  65. /*****************************************************************************
  66. * GetRegValueDword()
  67. *****************************************************************************
  68. * Convenience function to encapsulate registry reads.
  69. */
  70. int GetRegValueDword(LPTSTR RegPath,LPTSTR ValueName,PULONG Value)
  71. {
  72. int ReturnValue = 0;
  73. NTSTATUS Status;
  74. OBJECT_ATTRIBUTES ObjectAttributes;
  75. HANDLE KeyHandle;
  76. KEY_VALUE_PARTIAL_INFORMATION *Information;
  77. ULONG InformationSize;
  78. UNICODE_STRING UnicodeRegPath;
  79. UNICODE_STRING UnicodeValueName;
  80. RtlInitUnicodeString(&UnicodeRegPath, RegPath);
  81. RtlInitUnicodeString(&UnicodeValueName, ValueName);
  82. InitializeObjectAttributes(&ObjectAttributes,
  83. &UnicodeRegPath,
  84. OBJ_KERNEL_HANDLE, // Flags
  85. NULL, // Root directory
  86. NULL); // Security descriptor
  87. Status = ZwOpenKey(&KeyHandle,
  88. KEY_QUERY_VALUE,
  89. &ObjectAttributes);
  90. if (Status != STATUS_SUCCESS)
  91. {
  92. return 0;
  93. }
  94. InformationSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG);
  95. Information = (KEY_VALUE_PARTIAL_INFORMATION*)ExAllocatePoolWithTag(PagedPool, InformationSize,'ISmD'); // DmSI
  96. if (Information == NULL)
  97. {
  98. ZwClose(KeyHandle);
  99. return 0;
  100. }
  101. Status = ZwQueryValueKey(KeyHandle,
  102. &UnicodeValueName,
  103. KeyValuePartialInformation,
  104. Information,
  105. sizeof(Information),
  106. &InformationSize);
  107. if (Status == STATUS_SUCCESS)
  108. {
  109. if (Information->Type == REG_DWORD && Information->DataLength == sizeof(ULONG))
  110. {
  111. RtlCopyMemory(Value, Information->Data, sizeof(ULONG));
  112. ReturnValue = 1;
  113. }
  114. }
  115. ExFreePool(Information);
  116. ZwClose(KeyHandle);
  117. return ReturnValue;
  118. }
  119. /*****************************************************************************
  120. * GetTheCurrentTime()
  121. *****************************************************************************
  122. * Get the current time, in milliseconds (KeQuerySystemTime returns units of
  123. * 100ns each).
  124. */
  125. ULONG GetTheCurrentTime()
  126. {
  127. LARGE_INTEGER Time;
  128. KeQuerySystemTime(&Time);
  129. return (ULONG)(Time.QuadPart / (10 * 1000));
  130. }
  131. /*****************************************************************************
  132. * KernHelpGetSysAddrForMdl()
  133. *****************************************************************************
  134. * Safely map the MDL to system address space. This mapping
  135. * may fail "when the system runs out of system PTEs", and
  136. * without the flag set below, this condition causes a bugcheck
  137. * rather than a NULL return.
  138. */
  139. PVOID KernHelpGetSysAddrForMdl(PMDL pMdl)
  140. {
  141. PVOID MappedAddress;
  142. #if UNDER_NT
  143. MappedAddress = MmGetSystemAddressForMdlSafe(pMdl,NormalPagePriority);
  144. #else // !UNDER_NT
  145. CSHORT LocalCopyOfMdlFlagBit;
  146. //
  147. // Note the manipulation of the MDL flags is only done if needed.
  148. // The driver is responsible for ensuring that it is not simultaneously
  149. // modifying this field anywhere else and synchronizing if needed.
  150. //
  151. LocalCopyOfMdlFlagBit = (pMdl->MdlFlags & MDL_MAPPING_CAN_FAIL);
  152. if (LocalCopyOfMdlFlagBit == 0)
  153. {
  154. pMdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
  155. }
  156. MappedAddress = MmGetSystemAddressForMdl(pMdl);
  157. //
  158. // Carefully restore only the single "can-fail" bit state. This is
  159. // because the call above will change the state of other flag bits and
  160. // we don't want this restore to wipe out those changes. Wiping out the
  161. // other changes will cause not-so-obvious effects like eventually
  162. // exhausting the system PTE pool and other resources, which will crash
  163. // the entire system.
  164. //
  165. if (LocalCopyOfMdlFlagBit == 0)
  166. {
  167. pMdl->MdlFlags &= ~MDL_MAPPING_CAN_FAIL;
  168. }
  169. #endif // !UNDER_NT
  170. return MappedAddress;
  171. }