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.

369 lines
10 KiB

  1. //++
  2. // File Name:
  3. // test.c
  4. //
  5. // Contents:
  6. // Generic test program
  7. //--
  8. //
  9. // Header files
  10. //
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <wchar.h>
  14. #include <nt.h>
  15. #include <ntverp.h>
  16. #include <fcntl.h>
  17. #include <io.h>
  18. #include <sys/stat.h>
  19. #include <ntrtl.h>
  20. #include <nturtl.h>
  21. #include <wtypes.h>
  22. #include <windows.h>
  23. #include <winioctl.h>
  24. #include <wmistr.h>
  25. #include <evntrace.h>
  26. #include <tchar.h>
  27. #include "..\kmpioctl.h"
  28. #define MAXSTR 1024
  29. // begin_wmikm
  30. typedef struct _WMI_LOGGER_INFORMATION {
  31. WNODE_HEADER Wnode; // Had to do this since wmium.h comes later
  32. //
  33. // data provider by caller
  34. ULONG BufferSize; // buffer size for logging (in kbytes)
  35. ULONG MinimumBuffers; // minimum to preallocate
  36. ULONG MaximumBuffers; // maximum buffers allowed
  37. ULONG MaximumFileSize; // maximum logfile size (in MBytes)
  38. ULONG LogFileMode; // sequential, circular
  39. ULONG FlushTimer; // buffer flush timer, in seconds
  40. ULONG EnableFlags; // trace enable flags
  41. LONG AgeLimit; // aging decay time, in minutes
  42. union {
  43. HANDLE LogFileHandle; // handle to logfile
  44. ULONG64 LogFileHandle64;
  45. };
  46. // data returned to caller
  47. // end_wmikm
  48. union {
  49. // begin_wmikm
  50. ULONG NumberOfBuffers; // no of buffers in use
  51. // end_wmikm
  52. ULONG InstanceCount; // Number of Provider Instances
  53. };
  54. union {
  55. // begin_wmikm
  56. ULONG FreeBuffers; // no of buffers free
  57. // end_wmikm
  58. ULONG InstanceId; // Current Provider's Id for UmLogger
  59. };
  60. union {
  61. // begin_wmikm
  62. ULONG EventsLost; // event records lost
  63. // end_wmikm
  64. ULONG NumberOfProcessors; // Passed on to UmLogger
  65. };
  66. // begin_wmikm
  67. ULONG BuffersWritten; // no of buffers written to file
  68. ULONG LogBuffersLost; // no of logfile write failures
  69. ULONG RealTimeBuffersLost; // no of rt delivery failures
  70. union {
  71. HANDLE LoggerThreadId; // thread id of Logger
  72. ULONG64 LoggerThreadId64; // thread is of Logger
  73. };
  74. union {
  75. UNICODE_STRING LogFileName; // used only in WIN64
  76. UNICODE_STRING64 LogFileName64; // Logfile name: only in WIN32
  77. };
  78. // mandatory data provided by caller
  79. union {
  80. UNICODE_STRING LoggerName; // Logger instance name in WIN64
  81. UNICODE_STRING64 LoggerName64; // Logger Instance name in WIN32
  82. };
  83. // private
  84. union {
  85. PVOID Checksum;
  86. ULONG64 Checksum64;
  87. };
  88. union {
  89. PVOID LoggerExtension;
  90. ULONG64 LoggerExtension64;
  91. };
  92. } WMI_LOGGER_INFORMATION, *PWMI_LOGGER_INFORMATION;
  93. //
  94. // Forward declarations of local functions...
  95. //
  96. static VOID
  97. SendIoctl(
  98. ULONG ioctl,
  99. PVOID Buffer,
  100. ULONG Size
  101. );
  102. static VOID
  103. ErrorMessage(
  104. LPTSTR lpOrigin,
  105. DWORD dwMessageId
  106. );
  107. static VOID
  108. InitString(
  109. OUT PUNICODE_STRING DestinationString,
  110. IN PCWSTR SourceString
  111. );
  112. void
  113. PrintLoggerStatus(
  114. IN PWMI_LOGGER_INFORMATION LoggerInfo,
  115. IN ULONG Status
  116. );
  117. //
  118. // Main entry point...
  119. //
  120. VOID __cdecl
  121. main(
  122. int argc,
  123. char **argv
  124. )
  125. {
  126. ULONG ioctl = IOCTL_TRACEKMP_TRACE_EVENT;
  127. WMI_LOGGER_INFORMATION LoggerInfo;
  128. WCHAR LoggerName[MAXSTR];
  129. WCHAR LogFileName[MAXSTR];
  130. wcscpy(LoggerName, L"TraceKmp");
  131. wcscpy(LogFileName, L"C:\\tracekmp.etl");
  132. RtlZeroMemory(&LoggerInfo, sizeof(LoggerInfo));
  133. LoggerInfo.Wnode.BufferSize = sizeof(LoggerInfo);
  134. LoggerInfo.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  135. InitString(&LoggerInfo.LoggerName, LoggerName);
  136. InitString(&LoggerInfo.LogFileName, LogFileName);
  137. while (--argc > 0) {
  138. ++argv;
  139. if (**argv == '-' || **argv == '/') {
  140. if (!strcmp(&argv[0][1], "start")) {
  141. ioctl = IOCTL_TRACEKMP_START;
  142. }
  143. else if (!strcmp(&argv[0][1], "stop")) {
  144. ioctl = IOCTL_TRACEKMP_STOP;
  145. }
  146. else if (!strcmp(&argv[0][1], "query")) {
  147. ioctl = IOCTL_TRACEKMP_QUERY;
  148. }
  149. else if (!strcmp(&argv[0][1], "update")) {
  150. ioctl = IOCTL_TRACEKMP_UPDATE;
  151. }
  152. else if (!strcmp(&argv[0][1], "flush")) {
  153. ioctl = IOCTL_TRACEKMP_FLUSH;
  154. }
  155. }
  156. }
  157. SendIoctl( ioctl, (PVOID) &LoggerInfo, sizeof(LoggerInfo) );
  158. ExitProcess( ERROR_SUCCESS );
  159. }
  160. static VOID
  161. SendIoctl(
  162. ULONG ioctl,
  163. PVOID Buffer,
  164. ULONG Size
  165. )
  166. {
  167. HANDLE hDevice;
  168. DWORD dwErrorCode = ERROR_SUCCESS;
  169. DWORD dwBytesReturned;
  170. hDevice = CreateFile(
  171. "\\\\.\\TRACEKMP",
  172. GENERIC_WRITE,
  173. 0,
  174. NULL,
  175. OPEN_EXISTING,
  176. FILE_ATTRIBUTE_NORMAL,
  177. NULL );
  178. if( hDevice == INVALID_HANDLE_VALUE )
  179. {
  180. dwErrorCode = GetLastError();
  181. ErrorMessage( "CreateFile", dwErrorCode );
  182. ExitProcess( dwErrorCode );
  183. }
  184. printf("Sending ioctl %X\n", ioctl);
  185. if( !DeviceIoControl(
  186. hDevice,
  187. ioctl,
  188. Buffer,
  189. Size,
  190. Buffer,
  191. Size,
  192. &dwBytesReturned,
  193. NULL ))
  194. {
  195. dwErrorCode = GetLastError();
  196. ErrorMessage( "DeviceIoControl", dwErrorCode );
  197. ExitProcess( dwErrorCode );
  198. }
  199. PrintLoggerStatus(Buffer, dwErrorCode);
  200. CloseHandle( hDevice );
  201. }
  202. //
  203. // This helper routine converts a system-service error
  204. // code into a text message and prints it on StdOutput
  205. //
  206. static VOID
  207. ErrorMessage(
  208. LPTSTR lpOrigin, // Indicates error location
  209. DWORD dwMessageId // ERROR_XXX code value
  210. )
  211. {
  212. LPTSTR msgBuffer; // string returned from system
  213. DWORD cBytes; // length of returned string
  214. cBytes = FormatMessage(
  215. FORMAT_MESSAGE_FROM_SYSTEM |
  216. FORMAT_MESSAGE_ALLOCATE_BUFFER,
  217. NULL,
  218. dwMessageId,
  219. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  220. (TCHAR *)&msgBuffer,
  221. 500,
  222. NULL );
  223. if( msgBuffer )
  224. {
  225. msgBuffer[ cBytes ] = TEXT('\0');
  226. printf( "Error: %s -- %s\n", lpOrigin, msgBuffer );
  227. LocalFree( msgBuffer );
  228. }
  229. else
  230. {
  231. printf( "FormatMessage error: %d\n", GetLastError());
  232. }
  233. }
  234. static VOID
  235. InitString(
  236. OUT PUNICODE_STRING DestinationString,
  237. IN PCWSTR SourceString
  238. )
  239. {
  240. ULONG Length;
  241. DestinationString->Buffer = (PWSTR)SourceString;
  242. if ( SourceString ) {
  243. Length = wcslen( SourceString ) * sizeof( WCHAR );
  244. DestinationString->Length = (USHORT)Length;
  245. DestinationString->MaximumLength = (USHORT)(Length + sizeof(UNICODE_NULL));
  246. }
  247. else {
  248. DestinationString->MaximumLength = 0;
  249. DestinationString->Length = 0;
  250. }
  251. }
  252. void
  253. PrintLoggerStatus(
  254. IN PWMI_LOGGER_INFORMATION LoggerInfo,
  255. IN ULONG Status
  256. )
  257. {
  258. LPWSTR LoggerName, LogFileName;
  259. LoggerName = LoggerInfo->LoggerName.Buffer;
  260. LogFileName = LoggerInfo->LogFileName.Buffer;
  261. _tprintf(_T("Operation Status: %uL\n"), Status);
  262. // _tprintf(_T("%s\n"), ErrorMessage("PrintLoggerStatus", Status));
  263. _tprintf(_T("Logger Name: %ws\n"),
  264. (LoggerName == NULL) ?
  265. L" " : LoggerName);
  266. _tprintf(_T("Logger Id: %I64x\n"), LoggerInfo->Wnode.HistoricalContext);
  267. _tprintf(_T("Logger Thread Id: %d\n"), LoggerInfo->LoggerThreadId);
  268. if (Status != 0)
  269. return;
  270. _tprintf(_T("Buffer Size: %d Kb\n"), LoggerInfo->BufferSize);
  271. _tprintf(_T("Maximum Buffers: %d\n"), LoggerInfo->MaximumBuffers);
  272. _tprintf(_T("Minimum Buffers: %d\n"), LoggerInfo->MinimumBuffers);
  273. _tprintf(_T("Number of Buffers: %d\n"), LoggerInfo->NumberOfBuffers);
  274. _tprintf(_T("Free Buffers: %d\n"), LoggerInfo->FreeBuffers);
  275. _tprintf(_T("Buffers Written: %d\n"), LoggerInfo->BuffersWritten);
  276. _tprintf(_T("Events Lost: %d\n"), LoggerInfo->EventsLost);
  277. _tprintf(_T("Log Buffers Lost: %d\n"), LoggerInfo->LogBuffersLost);
  278. _tprintf(_T("Real Time Buffers Lost: %d\n"), LoggerInfo->RealTimeBuffersLost);
  279. if (LogFileName == NULL) {
  280. _tprintf(_T("Buffering Mode: "));
  281. }
  282. else {
  283. _tprintf(_T("Log File Mode: "));
  284. }
  285. if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
  286. _tprintf(_T("Circular\n"));
  287. }
  288. else if (LoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
  289. _tprintf(_T("Sequential\n"));
  290. }
  291. else {
  292. _tprintf(_T("Sequential\n"));
  293. }
  294. if (LoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) {
  295. _tprintf(_T("Real Time mode enabled"));
  296. _tprintf(_T("\n"));
  297. }
  298. if (LoggerInfo->MaximumFileSize > 0)
  299. _tprintf(_T("Maximum File Size: %d Mb\n"), LoggerInfo->MaximumFileSize);
  300. if (LoggerInfo->FlushTimer > 0)
  301. _tprintf(_T("Buffer Flush Timer: %d secs\n"), LoggerInfo->FlushTimer);
  302. /*
  303. if (LoggerInfo->EnableFlags != 0) {
  304. _tprintf(_T("Enabled tracing: "));
  305. if ((LoggerName != NULL) && (!_tcscmp(LoggerName,NT_LOGGER))) {
  306. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
  307. _tprintf(_T("Process "));
  308. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
  309. _tprintf(_T("Thread "));
  310. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
  311. _tprintf(_T("Disk "));
  312. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
  313. _tprintf(_T("File "));
  314. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
  315. _tprintf(_T("PageFaults "));
  316. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
  317. _tprintf(_T("HardFaults "));
  318. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
  319. _tprintf(_T("ImageLoad "));
  320. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
  321. _tprintf(_T("TcpIp "));
  322. if (LoggerInfo->EnableFlags & EVENT_TRACE_FLAG_REGISTRY)
  323. _tprintf(_T("Registry "));
  324. }else{
  325. _tprintf(_T("0x%08x"), LoggerInfo->EnableFlags );
  326. }
  327. _tprintf(_T("\n"));
  328. }
  329. */
  330. if (LogFileName != NULL) {
  331. _tprintf(_T("Log Filename: %ws\n"), LogFileName);
  332. }
  333. }