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.

282 lines
9.1 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. request.c
  5. Abstract:
  6. Implements WMI requests to different data providers
  7. Author:
  8. 16-Jan-1997 AlanWar
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include "wmiump.h"
  13. #include "trcapi.h"
  14. #include "wmiumkm.h"
  15. #include "request.h"
  16. //
  17. // This is the handle to the WMI kernel mode device
  18. extern HANDLE EtwpKMHandle;
  19. //
  20. // This is the one-deep Win32 event queue used to supply events for
  21. // overlapped I/O to the WMI device.
  22. extern HANDLE EtwpWin32Event;
  23. ULONG EtwpSendRegisterKMRequest(
  24. HANDLE DeviceHandle,
  25. ULONG Ioctl,
  26. PVOID InBuffer,
  27. ULONG InBufferSize,
  28. PVOID OutBuffer,
  29. ULONG MaxBufferSize,
  30. ULONG *ReturnSize,
  31. LPOVERLAPPED Overlapped
  32. )
  33. /*+++
  34. Routine Description:
  35. This is a special SendKMRequest routine for RegisterTraceGuids.
  36. We will reject MofResource from the RegisterTraceGuids call if it
  37. did not come from Admin or LocalSystem. To determine that we need
  38. to attempt to send the Ioctl through WMIAdminDevice first. If that
  39. fails, we send the request the normal way, ie., through WMI data device.
  40. Arguments:
  41. Ioctl is the IOCTL code to send to the WMI device
  42. Buffer is the input buffer for the call to the WMI device
  43. InBufferSize is the size of the buffer passed to the device
  44. OutBuffer is the output buffer for the call to the WMI device
  45. MaxBufferSize is the maximum number of bytes that can be written
  46. into the buffer
  47. *ReturnSize on return has the actual number of bytes written in buffer
  48. Overlapped is an option OVERLAPPED struct that is used to make the
  49. call async
  50. Return Value:
  51. ERROR_SUCCESS or an error code
  52. ---*/
  53. {
  54. ULONG Status;
  55. HANDLE KMHandle;
  56. //
  57. // First, we try to open the WMI Admin device
  58. //
  59. KMHandle = EtwpCreateFileW(WMIAdminDeviceName_W,
  60. GENERIC_READ | GENERIC_WRITE,
  61. 0,
  62. NULL,
  63. OPEN_EXISTING,
  64. FILE_ATTRIBUTE_NORMAL |
  65. FILE_FLAG_OVERLAPPED,
  66. NULL);
  67. if ( (KMHandle == INVALID_HANDLE_VALUE) || (KMHandle == NULL))
  68. {
  69. //
  70. // Send the Request through WMI Data Device
  71. //
  72. Status = EtwpSendWmiKMRequest( DeviceHandle,
  73. Ioctl,
  74. InBuffer,
  75. InBufferSize,
  76. OutBuffer,
  77. MaxBufferSize,
  78. ReturnSize,
  79. Overlapped
  80. );
  81. }
  82. else
  83. {
  84. Status = EtwpSendWmiKMRequest( KMHandle,
  85. Ioctl,
  86. InBuffer,
  87. InBufferSize,
  88. OutBuffer,
  89. MaxBufferSize,
  90. ReturnSize,
  91. Overlapped
  92. );
  93. EtwpCloseHandle(KMHandle);
  94. }
  95. return(Status);
  96. }
  97. ULONG EtwpRegisterGuids(
  98. IN LPGUID MasterGuid,
  99. IN LPGUID ControlGuid,
  100. IN LPCWSTR MofImagePath,
  101. IN LPCWSTR MofResourceName,
  102. OUT ULONG64 *LoggerContext,
  103. OUT HANDLE *RegistrationHandle
  104. )
  105. {
  106. ULONG Status, StringPos, StringSize, WmiRegSize;
  107. ULONG SizeNeeded, InSizeNeeded, OutSizeNeeded;
  108. WCHAR GuidObjectName[WmiGuidObjectNameLength+1];
  109. OBJECT_ATTRIBUTES ObjectAttributes;
  110. UNICODE_STRING GuidString;
  111. PWMIREGREQUEST WmiRegRequest;
  112. PUCHAR Buffer;
  113. PUCHAR RegInfoBuffer;
  114. PWMIREGRESULTS WmiRegResults;
  115. ULONG ReturnSize;
  116. PWMIREGINFOW pWmiRegInfo;
  117. PWMIREGGUID WmiRegGuidPtr;
  118. LPGUID pGuid;
  119. PWCHAR StringPtr;
  120. //
  121. // Allocate a buffer large enough for all in and out parameters
  122. //
  123. // Allocate space to call IOCTL_WMI_REGISTER_GUIDS
  124. //
  125. InSizeNeeded = sizeof(WMIREGREQUEST) +
  126. sizeof(WMIREGINFOW) +
  127. sizeof(WMIREGGUIDW);
  128. if (MofImagePath == NULL) {
  129. MofImagePath = L"";
  130. }
  131. if (MofResourceName != NULL) {
  132. InSizeNeeded += (wcslen(MofResourceName) + 2) * sizeof(WCHAR);
  133. }
  134. InSizeNeeded += (wcslen(MofImagePath) + 2) * sizeof(WCHAR);
  135. InSizeNeeded = (InSizeNeeded + 7) & ~7;
  136. OutSizeNeeded = sizeof(WMIREGRESULTS);
  137. if (InSizeNeeded > OutSizeNeeded)
  138. {
  139. SizeNeeded = InSizeNeeded;
  140. } else {
  141. SizeNeeded = OutSizeNeeded;
  142. }
  143. Buffer = EtwpAlloc(SizeNeeded);
  144. if (Buffer != NULL)
  145. {
  146. RtlZeroMemory(Buffer, SizeNeeded);
  147. //
  148. // Build the object attributes
  149. //
  150. WmiRegRequest = (PWMIREGREQUEST)Buffer;
  151. WmiRegRequest->ObjectAttributes = &ObjectAttributes;
  152. WmiRegRequest->WmiRegInfo32Size = sizeof(WMIREGINFOW);
  153. WmiRegRequest->WmiRegGuid32Size = sizeof(WMIREGGUIDW);
  154. RegInfoBuffer = Buffer + sizeof(WMIREGREQUEST);
  155. Status = EtwpBuildGuidObjectAttributes(MasterGuid,
  156. &ObjectAttributes,
  157. &GuidString,
  158. GuidObjectName);
  159. if (Status == ERROR_SUCCESS)
  160. {
  161. WmiRegRequest->Cookie = 0;
  162. pWmiRegInfo = (PWMIREGINFOW) (Buffer + sizeof(WMIREGREQUEST));
  163. WmiRegSize = SizeNeeded - sizeof(WMIREGREQUEST);
  164. StringPos = sizeof(WMIREGINFOW) + sizeof(WMIREGGUIDW);
  165. pWmiRegInfo->BufferSize = WmiRegSize;
  166. pWmiRegInfo->GuidCount = 1;
  167. WmiRegGuidPtr = &pWmiRegInfo->WmiRegGuid[0];
  168. WmiRegGuidPtr->Flags = (WMIREG_FLAG_TRACED_GUID |
  169. WMIREG_FLAG_TRACE_CONTROL_GUID);
  170. WmiRegGuidPtr->Guid = *ControlGuid;
  171. // Copy MOF resource path and name into WmiRegInfo
  172. if (MofResourceName != NULL) {
  173. pWmiRegInfo->MofResourceName = StringPos;
  174. StringPtr = (PWCHAR)OffsetToPtr(pWmiRegInfo, StringPos);
  175. Status = EtwpCopyStringToCountedUnicode(MofResourceName,
  176. StringPtr,
  177. &StringSize,
  178. FALSE);
  179. if (Status != ERROR_SUCCESS) {
  180. EtwpFree(Buffer);
  181. EtwpSetLastError(Status);
  182. return Status;
  183. }
  184. StringPos += StringSize;
  185. #if DBG
  186. EtwpAssert(StringPos <= WmiRegSize);
  187. #endif
  188. }
  189. if (MofImagePath != NULL) {
  190. pWmiRegInfo->RegistryPath = StringPos;
  191. StringPtr = (PWCHAR)OffsetToPtr(pWmiRegInfo, StringPos);
  192. Status = EtwpCopyStringToCountedUnicode(MofImagePath,
  193. StringPtr,
  194. &StringSize,
  195. FALSE);
  196. if (Status != ERROR_SUCCESS) {
  197. EtwpFree(Buffer);
  198. EtwpSetLastError(Status);
  199. return Status;
  200. }
  201. StringPos += StringSize;
  202. #if DBG
  203. EtwpAssert(StringPos <= WmiRegSize);
  204. #endif
  205. }
  206. Status = EtwpSendRegisterKMRequest (NULL,
  207. IOCTL_WMI_REGISTER_GUIDS,
  208. Buffer,
  209. InSizeNeeded,
  210. Buffer,
  211. OutSizeNeeded,
  212. &ReturnSize,
  213. NULL);
  214. if (Status == ERROR_SUCCESS)
  215. {
  216. //
  217. // Successful call, return the out parameters
  218. //
  219. WmiRegResults = (PWMIREGRESULTS)Buffer;
  220. *RegistrationHandle = WmiRegResults->RequestHandle.Handle;
  221. *LoggerContext = WmiRegResults->LoggerContext;
  222. #if DBG
  223. if ( (WmiRegResults->MofIgnored) && (MofResourceName != NULL)
  224. && (MofImagePath != NULL))
  225. {
  226. EtwpDebugPrint(("ETW: Mof %ws from %ws ignored\n",
  227. MofImagePath, MofResourceName));
  228. }
  229. #endif
  230. }
  231. }
  232. EtwpFree(Buffer);
  233. } else {
  234. Status = ERROR_NOT_ENOUGH_MEMORY;
  235. }
  236. return(Status);
  237. }