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.

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