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.

391 lines
13 KiB

  1. /*****************************************************************************\
  2. Author: Insung Park (insungp)
  3. Copyright (c) 1998-2000 Microsoft Corporation
  4. \*****************************************************************************/
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <nt.h>
  8. #include <ntrtl.h>
  9. #include <nturtl.h>
  10. #include <windows.h>
  11. #include <shellapi.h>
  12. #include <tchar.h>
  13. #include <wmistr.h>
  14. #include <initguid.h>
  15. #include <evntrace.h>
  16. #include <wmiguid.h>
  17. #include <ntwmi.h>
  18. #include <ntperf.h>
  19. #include <fwcommon.h>
  20. LPCWSTR cszGlobalLoggerKey = L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\WMI\\GlobalLogger";
  21. LPCWSTR cszStartValue = L"Start";
  22. LPCWSTR cszBufferSizeValue = L"BufferSize";
  23. LPCWSTR cszMaximumBufferValue = L"MaximumBuffers";
  24. LPCWSTR cszMinimumBufferValue = L"MinimumBuffers";
  25. LPCWSTR cszFlushTimerValue = L"FlushTimer";
  26. LPCWSTR cszFileNameValue = L"FileName";
  27. LPCWSTR cszEnableKernelValue = L"EnableKernelFlags";
  28. LPCWSTR cszClockTypeValue = L"ClockType";
  29. HRESULT
  30. SetGlobalLoggerSettings(
  31. DWORD StartValue,
  32. PEVENT_TRACE_PROPERTIES LoggerInfo,
  33. DWORD ClockType
  34. )
  35. /*++
  36. Since it is a standalone utility, there is no need for extensive comments.
  37. Routine Description:
  38. Depending on the value given in "StartValue", it sets or resets event
  39. trace registry. If the StartValue is 0 (Global logger off), it deletes
  40. all the keys (that the user may have set previsouly).
  41. Users are allowed to set or reset individual keys using this function,
  42. but only when "-start GlobalLogger" is used.
  43. The section that uses non NTAPIs is not guaranteed to work.
  44. Arguments:
  45. StartValue - The "Start" value to be set in the registry.
  46. 0: Global logger off
  47. 1: Global logger on
  48. LoggerInfo - The poniter to the resident EVENT_TRACE_PROPERTIES instance.
  49. whose members are used to set registry keys.
  50. ClockType - The type of the clock to be set. Use pLoggerInfo->Wnode.ClientContext
  51. Return Value:
  52. Error Code defined in winerror.h : If the function succeeds,
  53. it returns ERROR_SUCCESS.
  54. --*/
  55. {
  56. DWORD dwValue;
  57. NTSTATUS status;
  58. HANDLE KeyHandle;
  59. OBJECT_ATTRIBUTES ObjectAttributes;
  60. UNICODE_STRING UnicodeLoggerKey, UnicodeString;
  61. ULONG Disposition, TitleIndex;
  62. RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES));
  63. RtlInitUnicodeString((&UnicodeLoggerKey),(cszGlobalLoggerKey));
  64. InitializeObjectAttributes(
  65. &ObjectAttributes,
  66. &UnicodeLoggerKey,
  67. OBJ_CASE_INSENSITIVE,
  68. NULL,
  69. NULL
  70. );
  71. // instead of opening, create a new key because it may not exist.
  72. // if one exists already, that handle will be passed.
  73. // if none exists, it will create one.
  74. status = NtCreateKey(&KeyHandle,
  75. KEY_QUERY_VALUE | KEY_SET_VALUE,
  76. &ObjectAttributes,
  77. 0L, // not used within this call anyway.
  78. NULL,
  79. REG_OPTION_NON_VOLATILE,
  80. &Disposition);
  81. RtlFreeUnicodeString(&UnicodeLoggerKey);
  82. if(!NT_SUCCESS(status)) {
  83. return RtlNtStatusToDosError(status);
  84. }
  85. TitleIndex = 0L;
  86. if (StartValue == 1) { // ACTION_START: set filename only when it is given by a user.
  87. // setting BufferSize
  88. if (LoggerInfo->BufferSize > 0) {
  89. dwValue = LoggerInfo->BufferSize;
  90. RtlInitUnicodeString((&UnicodeString),(cszBufferSizeValue));
  91. status = NtSetValueKey(
  92. KeyHandle,
  93. &UnicodeString,
  94. TitleIndex,
  95. REG_DWORD,
  96. (LPBYTE)&dwValue,
  97. sizeof(dwValue)
  98. );
  99. RtlFreeUnicodeString(&UnicodeString);
  100. if (!NT_SUCCESS(status)) {
  101. NtClose(KeyHandle);
  102. return RtlNtStatusToDosError(status);
  103. }
  104. TitleIndex++;
  105. }
  106. // setting MaximumBuffers
  107. if (LoggerInfo->MaximumBuffers > 0) {
  108. dwValue = LoggerInfo->MaximumBuffers;
  109. RtlInitUnicodeString((&UnicodeString),(cszMaximumBufferValue));
  110. status = NtSetValueKey(
  111. KeyHandle,
  112. &UnicodeString,
  113. TitleIndex,
  114. REG_DWORD,
  115. (LPBYTE)&dwValue,
  116. sizeof(dwValue)
  117. );
  118. RtlFreeUnicodeString(&UnicodeString);
  119. if (!NT_SUCCESS(status)) {
  120. NtClose(KeyHandle);
  121. return RtlNtStatusToDosError(status);
  122. }
  123. TitleIndex++;
  124. }
  125. // setting MinimumBuffers
  126. if (LoggerInfo->MinimumBuffers > 0) {
  127. dwValue = LoggerInfo->MinimumBuffers;
  128. RtlInitUnicodeString((&UnicodeString),(cszMinimumBufferValue));
  129. status = NtSetValueKey(
  130. KeyHandle,
  131. &UnicodeString,
  132. TitleIndex,
  133. REG_DWORD,
  134. (LPBYTE)&dwValue,
  135. sizeof(dwValue)
  136. );
  137. RtlFreeUnicodeString(&UnicodeString);
  138. if (!NT_SUCCESS(status)) {
  139. NtClose(KeyHandle);
  140. return RtlNtStatusToDosError(status);
  141. }
  142. TitleIndex++;
  143. }
  144. // setting FlushTimer
  145. if (LoggerInfo->FlushTimer > 0) {
  146. dwValue = LoggerInfo->FlushTimer;
  147. RtlInitUnicodeString((&UnicodeString),(cszFlushTimerValue));
  148. status = NtSetValueKey(
  149. KeyHandle,
  150. &UnicodeString,
  151. TitleIndex,
  152. REG_DWORD,
  153. (LPBYTE)&dwValue,
  154. sizeof(dwValue)
  155. );
  156. RtlFreeUnicodeString(&UnicodeString);
  157. if (!NT_SUCCESS(status)) {
  158. NtClose(KeyHandle);
  159. return RtlNtStatusToDosError(status);
  160. }
  161. TitleIndex++;
  162. }
  163. // setting EnableFlags
  164. if (LoggerInfo->EnableFlags > 0) {
  165. dwValue = LoggerInfo->EnableFlags;
  166. RtlInitUnicodeString((&UnicodeString),(cszEnableKernelValue));
  167. status = NtSetValueKey(
  168. KeyHandle,
  169. &UnicodeString,
  170. TitleIndex,
  171. REG_DWORD,
  172. (LPBYTE)&dwValue,
  173. sizeof(dwValue)
  174. );
  175. RtlFreeUnicodeString(&UnicodeString);
  176. if (!NT_SUCCESS(status)) {
  177. NtClose(KeyHandle);
  178. return RtlNtStatusToDosError(status);
  179. }
  180. TitleIndex++;
  181. }
  182. dwValue = 0;
  183. if (LoggerInfo->LogFileNameOffset > 0) {
  184. UNICODE_STRING UnicodeFileName;
  185. RtlInitUnicodeString((&UnicodeFileName), (PWCHAR)(LoggerInfo->LogFileNameOffset + (PCHAR) LoggerInfo));
  186. RtlInitUnicodeString((&UnicodeString),(cszFileNameValue));
  187. status = NtSetValueKey(
  188. KeyHandle,
  189. &UnicodeString,
  190. TitleIndex,
  191. REG_SZ,
  192. UnicodeFileName.Buffer,
  193. UnicodeFileName.Length + sizeof(UNICODE_NULL)
  194. );
  195. RtlFreeUnicodeString(&UnicodeString);
  196. RtlFreeUnicodeString(&UnicodeFileName);
  197. if (!NT_SUCCESS(status)) {
  198. NtClose(KeyHandle);
  199. return RtlNtStatusToDosError(status);
  200. }
  201. TitleIndex++;
  202. }
  203. }
  204. else { // if ACTION_STOP then delete the keys that users might have set previously.
  205. // delete buffer size
  206. RtlInitUnicodeString((&UnicodeString),(cszBufferSizeValue));
  207. status = NtDeleteValueKey(
  208. KeyHandle,
  209. &UnicodeString
  210. );
  211. RtlFreeUnicodeString(&UnicodeString);
  212. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  213. NtClose(KeyHandle);
  214. return RtlNtStatusToDosError(status);
  215. }
  216. // delete maximum buffers
  217. RtlInitUnicodeString((&UnicodeString),(cszMaximumBufferValue));
  218. status = NtDeleteValueKey(
  219. KeyHandle,
  220. &UnicodeString
  221. );
  222. RtlFreeUnicodeString(&UnicodeString);
  223. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  224. NtClose(KeyHandle);
  225. return RtlNtStatusToDosError(status);
  226. }
  227. // delete minimum buffers
  228. RtlInitUnicodeString((&UnicodeString),(cszMinimumBufferValue));
  229. status = NtDeleteValueKey(
  230. KeyHandle,
  231. &UnicodeString
  232. );
  233. RtlFreeUnicodeString(&UnicodeString);
  234. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  235. NtClose(KeyHandle);
  236. return RtlNtStatusToDosError(status);
  237. }
  238. // delete flush timer
  239. RtlInitUnicodeString((&UnicodeString),(cszFlushTimerValue));
  240. status = NtDeleteValueKey(
  241. KeyHandle,
  242. &UnicodeString
  243. );
  244. RtlFreeUnicodeString(&UnicodeString);
  245. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  246. NtClose(KeyHandle);
  247. return RtlNtStatusToDosError(status);
  248. }
  249. // delete enable falg
  250. RtlInitUnicodeString((&UnicodeString),(cszEnableKernelValue));
  251. status = NtDeleteValueKey(
  252. KeyHandle,
  253. &UnicodeString
  254. );
  255. RtlFreeUnicodeString(&UnicodeString);
  256. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  257. NtClose(KeyHandle);
  258. return RtlNtStatusToDosError(status);
  259. }
  260. // delete filename
  261. RtlInitUnicodeString((&UnicodeString),(cszFileNameValue));
  262. status = NtDeleteValueKey(
  263. KeyHandle,
  264. &UnicodeString
  265. );
  266. RtlFreeUnicodeString(&UnicodeString);
  267. if (!NT_SUCCESS(status) && status != STATUS_OBJECT_NAME_NOT_FOUND) {
  268. NtClose(KeyHandle);
  269. return RtlNtStatusToDosError(status);
  270. }
  271. }
  272. // setting ClockType
  273. if (ClockType > 0) {
  274. dwValue = ClockType;
  275. RtlInitUnicodeString((&UnicodeString),(cszClockTypeValue));
  276. status = NtSetValueKey(
  277. KeyHandle,
  278. &UnicodeString,
  279. TitleIndex,
  280. REG_DWORD,
  281. (LPBYTE)&dwValue,
  282. sizeof(dwValue)
  283. );
  284. RtlFreeUnicodeString(&UnicodeString);
  285. if (!NT_SUCCESS(status)) {
  286. NtClose(KeyHandle);
  287. return RtlNtStatusToDosError(status);
  288. }
  289. TitleIndex++;
  290. }
  291. // Setting StartValue
  292. dwValue = StartValue;
  293. RtlInitUnicodeString((&UnicodeString),(cszStartValue));
  294. status = NtSetValueKey(
  295. KeyHandle,
  296. &UnicodeString,
  297. TitleIndex,
  298. REG_DWORD,
  299. (LPBYTE)&dwValue,
  300. sizeof(dwValue)
  301. );
  302. RtlFreeUnicodeString(&UnicodeString);
  303. if (!NT_SUCCESS(status)) {
  304. NtClose(KeyHandle);
  305. return RtlNtStatusToDosError(status);
  306. }
  307. TitleIndex++;
  308. NtClose(KeyHandle);
  309. return 0;
  310. }
  311. ULONG
  312. EtsGetMaxEnableFlags ()
  313. {
  314. return PERF_NUM_MASKS;
  315. }
  316. HRESULT
  317. EtsSetExtendedFlags(
  318. SAFEARRAY *saFlags,
  319. PEVENT_TRACE_PROPERTIES pLoggerInfo,
  320. ULONG offset
  321. )
  322. {
  323. LONG lBound, uBound;
  324. ULONG HUGEP *pFlagData;
  325. if( NULL != saFlags ){
  326. SafeArrayGetLBound( saFlags, 1, &lBound );
  327. SafeArrayGetUBound( saFlags, 1, &uBound );
  328. SafeArrayAccessData( saFlags, (void HUGEP **)&pFlagData );
  329. pLoggerInfo->EnableFlags = pFlagData[lBound];
  330. if (pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_EXTENSION) {
  331. USHORT i;
  332. PTRACE_ENABLE_FLAG_EXTENSION FlagExt;
  333. UCHAR nFlag = (UCHAR) (uBound - lBound);
  334. if ( nFlag <= PERF_NUM_MASKS ) {
  335. PULONG pFlags;
  336. pLoggerInfo->EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
  337. FlagExt = (PTRACE_ENABLE_FLAG_EXTENSION)
  338. &pLoggerInfo->EnableFlags;
  339. FlagExt->Offset = offset;
  340. FlagExt->Length = (UCHAR) nFlag;
  341. pFlags = (PULONG) ( offset + (PCHAR) pLoggerInfo );
  342. for (i=1; i<=nFlag; i++) {
  343. pFlags[i-1] = pFlagData[lBound + i];
  344. }
  345. }
  346. }
  347. SafeArrayUnaccessData( saFlags );
  348. }
  349. return ERROR_SUCCESS;
  350. }