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.

3132 lines
93 KiB

  1. // begin_sdk
  2. /*++
  3. Copyright (c) 1997-2000 Microsoft Corporation
  4. Module Name:
  5. tracedmp.c
  6. Abstract:
  7. Sample trace consumer program. Converts binary
  8. Event Trace Log (ETL) to CSV format
  9. // end_sdk
  10. Author:
  11. Jee Fung Pang (jeepang) 03-Dec-1997
  12. Revision History:
  13. Corey Morgan (coreym) 24-May-2000 Added MOF version support
  14. Insung Park (insungp) 16-Jan-2001
  15. tracedmp no longer uses MOF data file. All the layout information
  16. comes from the WBEM namespace. Also added support for float numbers.
  17. Also added comments for all the functions.
  18. // begin_sdk
  19. --*/
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <windows.h>
  23. #include <wbemidl.h>
  24. #include <shellapi.h>
  25. #include <tchar.h>
  26. #include <wmistr.h>
  27. #include <objbase.h>
  28. #include <initguid.h>
  29. #include <evntrace.h>
  30. #include <objidl.h>
  31. #define MAXLOGFILES 16
  32. #define MAXSTR 1024
  33. #define MOFWSTR 16360
  34. #define MOFSTR 32720
  35. #define MAXTYPE 256
  36. #define UC(x) ( (UINT)((x) & 0xFF) )
  37. #define NTOHS(x) ( (UC(x) * 256) + UC((x) >> 8) )
  38. // Maximum number of properties per WBEM class object: may need to be changed
  39. #define MAXPROPS 256
  40. #define DUMP_FILE_NAME _T("DumpFile.csv")
  41. #define SUMMARY_FILE_NAME _T("Summary.txt")
  42. #define DEFAULT_LOGFILE_NAME _T("C:\\Logfile.Etl")
  43. #define DEFAULT_NAMESPACE _T("root\\wmi")
  44. #define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
  45. #define CHECK_WBEM_HR( hr ) if( WBEM_NO_ERROR != hr ){ WbemError(hr); goto cleanup; }
  46. #define InitializeListHead(ListHead) (\
  47. (ListHead)->Flink = (ListHead)->Blink = (ListHead))
  48. #define InsertTailList(ListHead,Entry) {\
  49. PLIST_ENTRY _EX_Blink;\
  50. PLIST_ENTRY _EX_ListHead;\
  51. _EX_ListHead = (ListHead);\
  52. _EX_Blink = _EX_ListHead->Blink;\
  53. (Entry)->Flink = _EX_ListHead;\
  54. (Entry)->Blink = _EX_Blink;\
  55. _EX_Blink->Flink = (Entry);\
  56. _EX_ListHead->Blink = (Entry);\
  57. }
  58. #define RemoveEntryList(Entry) {\
  59. PLIST_ENTRY _EX_Blink;\
  60. PLIST_ENTRY _EX_Flink;\
  61. _EX_Flink = (Entry)->Flink;\
  62. _EX_Blink = (Entry)->Blink;\
  63. _EX_Blink->Flink = _EX_Flink;\
  64. _EX_Flink->Blink = _EX_Blink;\
  65. }
  66. #define GUID_TYPE_EVENTTRACE _T("EventTrace")
  67. #define GUID_TYPE_HEADER _T("Header")
  68. #define GUID_TYPE_UNKNOWN _T("Unknown")
  69. #define GUID_TYPE_DEFAULT _T("Default")
  70. #define EVENT_TYPE_DEFAULT (-1)
  71. #define EVENT_LEVEL_DEFAULT (-1)
  72. #define EVENT_VERSION_DEFAULT (-1)
  73. #define STR_ItemChar _T("ItemChar")
  74. #define STR_ItemWChar _T("ItemWChar")
  75. #define STR_ItemUChar _T("ItemUChar")
  76. #define STR_ItemCharShort _T("ItemCharShort")
  77. #define STR_ItemShort _T("ItemShort")
  78. #define STR_ItemUShort _T("ItemUShort")
  79. #define STR_ItemLong _T("ItemLong")
  80. #define STR_ItemULong _T("ItemULong")
  81. #define STR_ItemULongX _T("ItemULongX")
  82. #define STR_ItemLongLong _T("ItemLongLong")
  83. #define STR_ItemULongLong _T("ItemULongLong")
  84. #define STR_ItemFloat _T("ItemFloat");
  85. #define STR_ItemDouble _T("ItemDouble");
  86. #define STR_ItemString _T("ItemString")
  87. #define STR_ItemWString _T("ItemWString")
  88. // end_sdk
  89. #define STR_ItemRString _T("ItemRString")
  90. #define STR_ItemRWString _T("ItemRWString")
  91. // begin_sdk
  92. #define STR_ItemPString _T("ItemPString")
  93. #define STR_ItemPWString _T("ItemPWString")
  94. #define STR_ItemDSString _T("ItemDSString")
  95. #define STR_ItemDSWString _T("ItemDSWString")
  96. #define STR_ItemMLString _T("ItemMLString")
  97. #define STR_ItemSid _T("ItemSid")
  98. #define STR_ItemIPAddr _T("ItemIPAddr")
  99. #define STR_ItemPort _T("ItemPort")
  100. #define STR_ItemNWString _T("ItemNWString")
  101. #define STR_ItemPtr _T("ItemPtr")
  102. #define STR_ItemGuid _T("ItemGuid")
  103. // end_sdk
  104. #define STR_ItemVariant _T("ItemVariant")
  105. // begin_sdk
  106. #define STR_ItemBool _T("ItemBool")
  107. // end_sdk
  108. #define STR_ItemCPUTime _T("ItemCPUTime")
  109. #define STR_ItemOptArgs _T("ItemOptArgs")
  110. // begin_sdk
  111. // Data types supported in this consumer.
  112. typedef enum _ITEM_TYPE {
  113. // end_sdk
  114. ItemCPUTime,
  115. ItemOptArgs,
  116. // begin_sdk
  117. ItemChar,
  118. ItemWChar,
  119. ItemUChar,
  120. ItemCharShort,
  121. ItemShort,
  122. ItemUShort,
  123. ItemLong,
  124. ItemULong,
  125. ItemULongX,
  126. ItemLongLong,
  127. ItemULongLong,
  128. ItemFloat,
  129. ItemDouble,
  130. ItemString,
  131. ItemWString,
  132. // end_sdk
  133. ItemRString,
  134. ItemRWString,
  135. // begin_sdk
  136. ItemPString,
  137. ItemPWString,
  138. ItemDSString,
  139. ItemDSWString,
  140. ItemSid,
  141. ItemIPAddr,
  142. ItemPort,
  143. ItemMLString,
  144. ItemNWString, // Non-null terminated Wide Char String
  145. ItemPtr,
  146. ItemGuid,
  147. // end_sdk
  148. ItemVariant,
  149. // begin_sdk
  150. ItemBool,
  151. ItemUnknown
  152. } ITEM_TYPE;
  153. // Construct that represents an event layout
  154. typedef struct _MOF_INFO {
  155. LIST_ENTRY Entry;
  156. LPTSTR strDescription; // Class Name
  157. ULONG EventCount;
  158. GUID Guid;
  159. PLIST_ENTRY ItemHeader;
  160. LPTSTR strType; // Type Name
  161. SHORT TypeIndex;
  162. SHORT Version;
  163. CHAR Level;
  164. } MOF_INFO, *PMOF_INFO;
  165. typedef struct _ITEM_DESC *PITEM_DESC;
  166. // Construct that represents one data item
  167. typedef struct _ITEM_DESC {
  168. LIST_ENTRY Entry;
  169. LPTSTR strDescription;
  170. ULONG DataSize;
  171. ITEM_TYPE ItemType;
  172. UINT ArraySize;
  173. } ITEM_DESC;
  174. void
  175. PrintHelpMessage();
  176. PMOF_INFO
  177. GetNewMofInfo(
  178. GUID guid,
  179. SHORT nType,
  180. SHORT nVersion,
  181. CHAR nLevel
  182. );
  183. void
  184. AddMofInfo(
  185. PLIST_ENTRY List,
  186. LPTSTR strType,
  187. ITEM_TYPE nType,
  188. UINT ArraySize
  189. );
  190. HRESULT
  191. WbemConnect(
  192. IWbemServices** pWbemServices
  193. );
  194. ULONG GetArraySize(
  195. IN IWbemQualifierSet *pQualSet
  196. );
  197. ITEM_TYPE
  198. GetItemType(
  199. IN CIMTYPE_ENUMERATION CimType,
  200. IN IWbemQualifierSet *pQualSet
  201. );
  202. PMOF_INFO
  203. GetPropertiesFromWBEM(
  204. IWbemClassObject *pTraceSubClasses,
  205. GUID Guid,
  206. SHORT nVersion,
  207. CHAR nLevel,
  208. SHORT nType
  209. );
  210. PMOF_INFO
  211. GetGuids(
  212. GUID Guid,
  213. SHORT nVersion,
  214. CHAR nLevel,
  215. SHORT nType
  216. );
  217. ULONG
  218. ahextoi(
  219. TCHAR *s
  220. );
  221. // end_sdk
  222. static
  223. void
  224. reduceW(
  225. WCHAR *Src
  226. );
  227. static
  228. void
  229. reduceA(
  230. char *Src
  231. );
  232. // begin_sdk
  233. PMOF_INFO
  234. GetMofInfoHead(
  235. GUID Guid,
  236. SHORT nType,
  237. SHORT nVersion,
  238. CHAR nLevel
  239. );
  240. ULONG
  241. CheckFile(
  242. LPTSTR fileName
  243. );
  244. void
  245. CleanupEventList(
  246. VOID
  247. );
  248. ULONG
  249. WINAPI
  250. BufferCallback(
  251. PEVENT_TRACE_LOGFILE pLog
  252. );
  253. void
  254. WINAPI
  255. DumpEvent(
  256. PEVENT_TRACE pEvent
  257. );
  258. void
  259. RemoveMofInfo(
  260. PLIST_ENTRY pMofInfo
  261. );
  262. void
  263. GuidToString(
  264. PTCHAR s,
  265. LPGUID piid
  266. );
  267. HRESULT
  268. ParseTime(
  269. LPTSTR strTime,
  270. SYSTEMTIME* pstTime
  271. );
  272. // output files
  273. FILE* DumpFile = NULL;
  274. FILE* SummaryFile = NULL;
  275. static ULONG TotalBuffersRead = 0;
  276. static ULONG TotalEventsLost = 0;
  277. static ULONG TotalEventCount = 0;
  278. static ULONG TimerResolution = 10;
  279. // end_sdk
  280. static ULONG SysTimerResolution = 100000;
  281. // begin_sdk
  282. static ULONGLONG StartTime = 0;
  283. static ULONGLONG EndTime = 0;
  284. static BOOL fNoEndTime = FALSE;
  285. static __int64 ElapseTime;
  286. PCHAR MofData = NULL;
  287. size_t MofLength = 0;
  288. BOOLEAN fSummaryOnly = FALSE;
  289. BOOLEAN fDebugDisplay = FALSE;
  290. // end_sdk
  291. BOOLEAN fIgnorePerfClock = FALSE;
  292. // begin_sdk
  293. BOOLEAN fRealTimeCircular = FALSE;
  294. ULONG PointerSize = sizeof(PVOID) * 8;
  295. // Global head for event layout linked list
  296. PLIST_ENTRY EventListHead = NULL;
  297. // log files
  298. PEVENT_TRACE_LOGFILE EvmFile[MAXLOGFILES];
  299. ULONG LogFileCount = 0;
  300. BOOL g_bUserMode = FALSE;
  301. // end_sdk
  302. TCHAR ComputerName[MAXSTR];
  303. DWORD ComputerNameLength = 0;
  304. // begin_sdk
  305. // cached Wbem pointer
  306. IWbemServices *pWbemServices = NULL;
  307. int __cdecl main (int argc, LPTSTR* argv)
  308. /*++
  309. Routine Description:
  310. It is the main function.
  311. Arguments:
  312. Usage: tracedmp [options] <EtlFile1 EtlFile2 ...>| [-h | -? | -help]
  313. -o <file> Output CSV file
  314. -rt [LoggerName] Realtime tracedmp from the logger [LoggerName]
  315. -summary Summary.txt only
  316. -begin HH:MM DD/MM/YY
  317. -end HH:MM DD/MM/YY
  318. -h
  319. -help
  320. -? Display usage information
  321. Return Value:
  322. Error Code defined in winerror.h : If the function succeeds,
  323. it returns ERROR_SUCCESS (== 0).
  324. --*/
  325. {
  326. TCHAR DumpFileName[MAXSTR];
  327. TCHAR SummaryFileName[MAXSTR];
  328. LPTSTR *targv;
  329. FILETIME ftStart;
  330. FILETIME ftEnd;
  331. SYSTEMTIME st;
  332. #ifdef UNICODE
  333. LPTSTR *cmdargv;
  334. #endif
  335. PEVENT_TRACE_LOGFILE pLogFile;
  336. ULONG Status = ERROR_SUCCESS;
  337. ULONG i, j;
  338. TRACEHANDLE HandleArray[MAXLOGFILES];
  339. #ifdef UNICODE
  340. if ((cmdargv = CommandLineToArgvW(
  341. GetCommandLineW(), // pointer to a command-line string
  342. &argc // receives the argument count
  343. )) == NULL)
  344. {
  345. return(GetLastError());
  346. };
  347. targv = cmdargv ;
  348. #else
  349. targv = argv;
  350. #endif
  351. RtlZeroMemory( &ftStart, sizeof(FILETIME) );
  352. RtlZeroMemory( &ftEnd, sizeof(FILETIME) );
  353. _tcscpy(DumpFileName, DUMP_FILE_NAME);
  354. _tcscpy(SummaryFileName, SUMMARY_FILE_NAME);
  355. while (--argc > 0) {
  356. ++targv;
  357. if (**targv == '-' || **targv == '/') { // argument found
  358. if( **targv == '/' ){
  359. **targv = '-';
  360. }
  361. if ( !_tcsicmp(targv[0], _T("-begin") )) {
  362. if (argc > 1) {
  363. if (targv[1][0] != '-' && targv[1][0] != '/') {
  364. TCHAR buffer[MAXSTR];
  365. _tcscpy( buffer, targv[1] );
  366. _tcscat( buffer, _T(" ") );
  367. ++targv; --argc;
  368. if (targv[1][0] != '-' && targv[1][0] != '/'){
  369. _tcscat( buffer, targv[1] );
  370. ParseTime( buffer, &st );
  371. SystemTimeToFileTime( &st, &ftStart );
  372. ++targv; --argc;
  373. }
  374. }
  375. }
  376. }
  377. else if ( !_tcsicmp(targv[0], _T("-end")) ) {
  378. if (argc > 1) {
  379. if (targv[1][0] != '-' && targv[1][0] != '/') {
  380. TCHAR buffer[MAXSTR];
  381. _tcscpy( buffer, targv[1] );
  382. _tcscat( buffer, _T(" ") );
  383. ++targv; --argc;
  384. if (targv[1][0] != '-' && targv[1][0] != '/'){
  385. _tcscat( buffer, targv[1] );
  386. ParseTime( buffer, &st );
  387. SystemTimeToFileTime( &st, &ftEnd );
  388. ++targv; --argc;
  389. }
  390. }
  391. }
  392. }
  393. else if ( !_tcsicmp(targv[0], _T("-summary")) ) {
  394. fSummaryOnly = TRUE;
  395. }
  396. else if ( !_tcsicmp(targv[0], _T("-debug")) ) {
  397. fDebugDisplay = TRUE;
  398. }
  399. // end_sdk
  400. else if ( !_tcsicmp(targv[0], _T("-IgnorePerfClock")) ) {
  401. fIgnorePerfClock = TRUE;
  402. }
  403. // begin_sdk
  404. else if ( !_tcsicmp(targv[0], _T("-RealTimeCircular")) ) {
  405. fRealTimeCircular = TRUE;
  406. }
  407. else if (targv[0][1] == 'h' || targv[0][1] == 'H'
  408. || targv[0][1] == '?')
  409. {
  410. PrintHelpMessage();
  411. return 0;
  412. }
  413. else if ( !_tcsicmp(targv[0], _T("-rt")) ) {
  414. TCHAR LoggerName[MAXSTR];
  415. _tcscpy(LoggerName, KERNEL_LOGGER_NAME);
  416. if (argc > 1) {
  417. if (targv[1][0] != '-' && targv[1][0] != '/') {
  418. ++targv; --argc;
  419. _tcscpy(LoggerName, targv[0]);
  420. }
  421. }
  422. pLogFile = (PEVENT_TRACE_LOGFILE) malloc(sizeof(EVENT_TRACE_LOGFILE));
  423. if (pLogFile == NULL){
  424. _tprintf(_T("Allocation Failure\n"));
  425. Status = ERROR_OUTOFMEMORY;
  426. goto cleanup;
  427. }
  428. RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
  429. EvmFile[LogFileCount] = pLogFile;
  430. EvmFile[LogFileCount]->LogFileName = NULL;
  431. EvmFile[LogFileCount]->LoggerName =
  432. (LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
  433. if ( EvmFile[LogFileCount]->LoggerName == NULL ) {
  434. _tprintf(_T("Allocation Failure\n"));
  435. Status = ERROR_OUTOFMEMORY;
  436. goto cleanup;
  437. }
  438. _tcscpy(EvmFile[LogFileCount]->LoggerName, LoggerName);
  439. _tprintf(_T("Setting RealTime mode for %s\n"),
  440. EvmFile[LogFileCount]->LoggerName);
  441. EvmFile[LogFileCount]->Context = NULL;
  442. EvmFile[LogFileCount]->BufferCallback = BufferCallback;
  443. EvmFile[LogFileCount]->BuffersRead = 0;
  444. EvmFile[LogFileCount]->CurrentTime = 0;
  445. EvmFile[LogFileCount]->EventCallback = &DumpEvent;
  446. EvmFile[LogFileCount]->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
  447. LogFileCount++;
  448. }
  449. else if ( !_tcsicmp(targv[0], _T("-o")) ) {
  450. if (argc > 1) {
  451. if (targv[1][0] != '-' && targv[1][0] != '/') {
  452. TCHAR drive[10];
  453. TCHAR path[MAXSTR];
  454. TCHAR file[MAXSTR];
  455. TCHAR ext[MAXSTR];
  456. ++targv; --argc;
  457. _tfullpath(DumpFileName, targv[0], MAXSTR);
  458. _tsplitpath( DumpFileName, drive, path, file, ext );
  459. _tcscpy(ext,_T("csv"));
  460. _tmakepath( DumpFileName, drive, path, file, ext );
  461. _tcscpy(ext,_T("txt"));
  462. _tmakepath( SummaryFileName, drive, path, file, ext );
  463. }
  464. }
  465. }
  466. }
  467. else {
  468. pLogFile = (PEVENT_TRACE_LOGFILE) malloc(sizeof(EVENT_TRACE_LOGFILE));
  469. if (pLogFile == NULL){
  470. _tprintf(_T("Allocation Failure\n"));
  471. Status = ERROR_OUTOFMEMORY;
  472. goto cleanup;
  473. }
  474. RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
  475. EvmFile[LogFileCount] = pLogFile;
  476. EvmFile[LogFileCount]->LoggerName = NULL;
  477. EvmFile[LogFileCount]->LogFileName =
  478. (LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
  479. if (EvmFile[LogFileCount]->LogFileName == NULL) {
  480. _tprintf(_T("Allocation Failure\n"));
  481. Status = ERROR_OUTOFMEMORY;
  482. goto cleanup;
  483. }
  484. _tfullpath(EvmFile[LogFileCount]->LogFileName, targv[0], MAXSTR);
  485. _tprintf(_T("Setting log file to: %s\n"),
  486. EvmFile[LogFileCount]->LogFileName);
  487. // If one of the log files is not readable, exit.
  488. if (!CheckFile(EvmFile[LogFileCount]->LogFileName)) {
  489. _tprintf(_T("Cannot open logfile for reading\n"));
  490. Status = ERROR_INVALID_PARAMETER;
  491. goto cleanup;
  492. }
  493. EvmFile[LogFileCount]->Context = NULL;
  494. EvmFile[LogFileCount]->BufferCallback = BufferCallback;
  495. EvmFile[LogFileCount]->BuffersRead = 0;
  496. EvmFile[LogFileCount]->CurrentTime = 0;
  497. EvmFile[LogFileCount]->EventCallback = &DumpEvent;
  498. LogFileCount++;
  499. }
  500. }
  501. if (LogFileCount <= 0) {
  502. PrintHelpMessage();
  503. return Status;
  504. }
  505. for (i = 0; i < LogFileCount; i++) {
  506. TRACEHANDLE x;
  507. // end_sdk
  508. if (fIgnorePerfClock)
  509. EvmFile[i]->LogfileHeader.ReservedFlags |= 0x00000002;
  510. // begin_sdk
  511. if (fRealTimeCircular)
  512. EvmFile[i]->LogfileHeader.ReservedFlags |= 0x00000004;
  513. x = OpenTrace(EvmFile[i]);
  514. HandleArray[i] = x;
  515. if (HandleArray[i] == 0) {
  516. Status = GetLastError();
  517. _tprintf(_T("Error Opening Trace %d with status=%d\n"),
  518. i, Status);
  519. for (j = 0; j < i; j++)
  520. CloseTrace(HandleArray[j]);
  521. goto cleanup;
  522. }
  523. }
  524. if (!fSummaryOnly)
  525. {
  526. DumpFile = _tfopen(DumpFileName, _T("w"));
  527. if (DumpFile == NULL) {
  528. Status = ERROR_INVALID_PARAMETER;
  529. _tprintf(_T("DumpFile is NULL\n"));
  530. goto cleanup;
  531. }
  532. }
  533. SummaryFile = _tfopen(SummaryFileName, _T("w"));
  534. if (SummaryFile == NULL) {
  535. Status = ERROR_INVALID_PARAMETER;
  536. _tprintf(_T("SummaryFile is NULL\n"));
  537. goto cleanup;
  538. }
  539. if (!fSummaryOnly)
  540. {
  541. _ftprintf(DumpFile,
  542. _T("%12s, %10s,%7s,%21s,%11s,%11s, User Data\n"),
  543. _T("Event Name"), _T("Type"), _T("TID"), _T("Clock-Time"),
  544. _T("Kernel(ms)"), _T("User(ms)")
  545. );
  546. }
  547. Status = ProcessTrace(
  548. HandleArray,
  549. LogFileCount,
  550. &ftStart,
  551. &ftEnd
  552. );
  553. if (Status != ERROR_SUCCESS) {
  554. _tprintf(_T("Error processing with status=%dL (GetLastError=0x%x)\n"),
  555. Status, GetLastError());
  556. }
  557. for (j = 0; j < LogFileCount; j++){
  558. Status = CloseTrace(HandleArray[j]);
  559. if (Status != ERROR_SUCCESS) {
  560. _tprintf(_T("Error Closing Trace %d with status=%d\n"), j, Status);
  561. }
  562. }
  563. _ftprintf(SummaryFile,_T("Files Processed:\n"));
  564. for (i=0; i<LogFileCount; i++) {
  565. _ftprintf(SummaryFile,_T("\t%s\n"),EvmFile[i]->LogFileName);
  566. }
  567. ElapseTime = EndTime - StartTime;
  568. _ftprintf(SummaryFile,
  569. _T("Total Buffers Processed %d\n")
  570. _T("Total Events Processed %d\n")
  571. _T("Total Events Lost %d\n")
  572. _T("Start Time 0x%016I64X\n")
  573. _T("End Time 0x%016I64X\n")
  574. _T("Elapsed Time %I64d sec\n"),
  575. TotalBuffersRead,
  576. TotalEventCount,
  577. TotalEventsLost,
  578. StartTime,
  579. EndTime,
  580. (ElapseTime / 10000000) );
  581. _ftprintf(SummaryFile,
  582. _T("+-------------------------------------------------------------------------------------+\n")
  583. _T("|%10s %-20s %-10s %-36s |\n")
  584. _T("+-------------------------------------------------------------------------------------+\n"),
  585. _T("EventCount"),
  586. _T("EventName"),
  587. _T("EventType"),
  588. _T("Guid")
  589. );
  590. CleanupEventList();
  591. _ftprintf(SummaryFile,
  592. _T("+-------------------------------------------------------------------------------------+\n")
  593. );
  594. cleanup:
  595. if (!fSummaryOnly && DumpFile != NULL) {
  596. _tprintf(_T("Event traces dumped to %s\n"), DumpFileName);
  597. fclose(DumpFile);
  598. }
  599. if(SummaryFile != NULL){
  600. _tprintf(_T("Event Summary dumped to %s\n"), SummaryFileName);
  601. fclose(SummaryFile);
  602. }
  603. for (i = 0; i < LogFileCount; i ++)
  604. {
  605. if (EvmFile[i]->LoggerName != NULL)
  606. {
  607. free(EvmFile[i]->LoggerName);
  608. EvmFile[i]->LoggerName = NULL;
  609. }
  610. if (EvmFile[i]->LogFileName != NULL)
  611. {
  612. free(EvmFile[i]->LogFileName);
  613. EvmFile[i]->LogFileName = NULL;
  614. }
  615. free(EvmFile[i]);
  616. }
  617. #ifdef UNICODE
  618. GlobalFree(cmdargv);
  619. #endif
  620. SetLastError(Status);
  621. if(Status != ERROR_SUCCESS ){
  622. _tprintf(_T("Exit Status: %d\n"), Status);
  623. }
  624. if (MofData != NULL)
  625. free(MofData);
  626. return Status;
  627. }
  628. HRESULT
  629. ParseTime(
  630. LPTSTR strTime,
  631. SYSTEMTIME* pstTime
  632. )
  633. /*++
  634. Routine Description:
  635. Parse time given in a string into SYSTEMTIME.
  636. Arguments:
  637. strTime - String that shows time.
  638. pstTime - Struct to contain the parsed time information.
  639. Return Value:
  640. Error Code defined in winerror.h : If the function succeeds,
  641. it returns ERROR_SUCCESS (== 0).
  642. --*/
  643. {
  644. TCHAR buffer[MAXSTR];
  645. LPTSTR str, str2;
  646. ZeroMemory( pstTime, sizeof( SYSTEMTIME ) );
  647. if( pstTime == NULL ){
  648. return ERROR_BAD_ARGUMENTS;
  649. }
  650. _tcscpy( buffer, strTime );
  651. str = _tcstok( buffer, _T(" \n\t") );
  652. str2 = _tcstok( NULL, _T(" \n\t") );
  653. while( str ){
  654. if( _tcsstr( str, _T(":") ) ){
  655. LPTSTR strHour = _tcstok( str, _T(":") );
  656. LPTSTR strMinute = _tcstok( NULL, _T(":") );
  657. if( NULL != strHour ){
  658. pstTime->wHour = (USHORT)_ttoi( strHour );
  659. }
  660. if( NULL != strMinute ){
  661. pstTime->wMinute = (USHORT)_ttoi( strMinute );
  662. }
  663. }
  664. if( _tcsstr( str, _T("/") ) || _tcsstr( str, _T("\\") ) ){
  665. LPTSTR strMonth = _tcstok( str, _T("/\\") );
  666. LPTSTR strDay = _tcstok( NULL, _T("/\\") );
  667. LPTSTR strYear = _tcstok( NULL, _T("/\\") );
  668. if( NULL != strMonth ){
  669. pstTime->wMonth = (USHORT)_ttoi( strMonth );
  670. }
  671. if( NULL != strDay ){
  672. pstTime->wDay = (USHORT)_ttoi( strDay );
  673. }
  674. if( NULL != strYear ){
  675. pstTime->wYear = (USHORT)_ttoi( strYear );
  676. }
  677. }
  678. str = str2;
  679. str2 = NULL;
  680. }
  681. return ERROR_SUCCESS;
  682. }
  683. // end_sdk
  684. static
  685. void
  686. reduceA(
  687. char *Src
  688. )
  689. /*++
  690. Routine Description:
  691. Reduces an ANSI string. Used only for ItemRString.
  692. Arguments:
  693. Src - String to be reduced.
  694. Return Value:
  695. None.
  696. --*/
  697. {
  698. char *Start = Src;
  699. if (!Src)
  700. return;
  701. while (*Src)
  702. {
  703. if ('\t' == *Src)
  704. *Src = ' ';
  705. else if (',' == *Src)
  706. *Src = ' ';
  707. else if ('\n' == *Src)
  708. *Src = ','; // maybe a bug
  709. else if ('\r' == *Src)
  710. *Src = ' ';
  711. ++Src;
  712. }
  713. --Src;
  714. while ((Start < Src) && ((' ' == *Src) || (',' == *Src)))
  715. {
  716. *Src = 0x00;
  717. --Src;
  718. }
  719. }
  720. static
  721. void
  722. reduceW(
  723. WCHAR *Src
  724. )
  725. /*++
  726. Routine Description:
  727. Reduces a wide string. Used only for ItemRWString.
  728. Arguments:
  729. Src - Wide string to be reduced.
  730. Return Value:
  731. None.
  732. --*/
  733. {
  734. WCHAR *Start = Src;
  735. if (!Src)
  736. return;
  737. while (*Src)
  738. {
  739. if (L'\t' == *Src)
  740. *Src = L' ';
  741. else if (L',' == *Src)
  742. *Src = L' ';
  743. else if (L'\n' == *Src)
  744. *Src = L',';
  745. else if (L'\r' == *Src)
  746. *Src = L' ';
  747. ++Src;
  748. }
  749. --Src;
  750. while ((Start < Src) && ((L' ' == *Src) || (L',' == *Src)))
  751. {
  752. *Src = 0x00;
  753. --Src;
  754. }
  755. }
  756. // begin_sdk
  757. ULONG
  758. WINAPI
  759. BufferCallback(
  760. PEVENT_TRACE_LOGFILE pLog
  761. )
  762. /*++
  763. Routine Description:
  764. Callback method for processing a buffer. Does not do anything but
  765. updating global counters.
  766. Arguments:
  767. pLog - Pointer to a log file.
  768. Return Value:
  769. Always TRUE.
  770. --*/
  771. {
  772. TotalBuffersRead++;
  773. TotalEventsLost += pLog->EventsLost;
  774. return (TRUE);
  775. }
  776. void
  777. WINAPI
  778. DumpEvent(
  779. PEVENT_TRACE pEvent
  780. )
  781. /*++
  782. Routine Description:
  783. Callback method for processing an event. It obtains the layout
  784. information by calling GetMofInfoHead(), which returns the pointer
  785. to the PMOF_INFO corresponding to the event type. Then it writes
  786. to the output file.
  787. NOTE: Only character arrays are supported in this program.
  788. Arguments:
  789. pEvent - Pointer to an event.
  790. Return Value:
  791. None.
  792. --*/
  793. {
  794. PEVENT_TRACE_HEADER pHeader;
  795. ULONG i;
  796. PITEM_DESC pItem;
  797. char str[MOFSTR];
  798. WCHAR wstr[MOFWSTR];
  799. PCHAR ptr;
  800. ULONG ulongword;
  801. LONG longword;
  802. USHORT ushortword;
  803. SHORT shortword;
  804. PMOF_INFO pMofInfo;
  805. PLIST_ENTRY Head, Next;
  806. char iChar;
  807. WCHAR iwChar;
  808. ULONG MofDataUsed;
  809. TotalEventCount++;
  810. if (pEvent == NULL) {
  811. _tprintf(_T("Warning: Null Event\n"));
  812. return;
  813. }
  814. pHeader = (PEVENT_TRACE_HEADER) &pEvent->Header;
  815. if( IsEqualGUID(&(pEvent->Header.Guid), &EventTraceGuid) &&
  816. pEvent->Header.Class.Type == EVENT_TRACE_TYPE_INFO ) {
  817. PTRACE_LOGFILE_HEADER head = (PTRACE_LOGFILE_HEADER)pEvent->MofData;
  818. if( NULL != head ){
  819. g_bUserMode = (head->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE);
  820. if(head->TimerResolution > 0){
  821. // end_sdk
  822. SysTimerResolution = head->TimerResolution;
  823. // begin_sdk
  824. TimerResolution = head->TimerResolution / 10000;
  825. }
  826. StartTime = head->StartTime.QuadPart;
  827. EndTime = head->EndTime.QuadPart;
  828. fNoEndTime = (EndTime == 0);
  829. PointerSize = head->PointerSize * 8;
  830. // Set pointer size
  831. if (PointerSize < 16){ // minimum is 16 bits
  832. PointerSize = 32; // default is 32 bits
  833. }
  834. }
  835. }
  836. if (fNoEndTime && EndTime < (ULONGLONG) pHeader->TimeStamp.QuadPart) {
  837. EndTime = pHeader->TimeStamp.QuadPart;
  838. }
  839. if (MofData == NULL) {
  840. MofLength = pEvent->MofLength + sizeof(UNICODE_NULL);
  841. MofData = (PCHAR) malloc(MofLength);
  842. }
  843. else if ((pEvent->MofLength + sizeof(UNICODE_NULL)) > MofLength) {
  844. MofLength = pEvent->MofLength + sizeof(UNICODE_NULL);
  845. MofData = (PCHAR) realloc(MofData, MofLength);
  846. }
  847. if (MofData == NULL) {
  848. _tprintf(_T("Allocation Failure\n"));
  849. return;
  850. }
  851. if (NULL == pEvent->MofData && pEvent->MofLength != 0) {
  852. _tprintf(_T("Incorrect MOF size\n"));
  853. return;
  854. }
  855. if (NULL != (pEvent->MofData)) {
  856. memcpy(MofData, pEvent->MofData, pEvent->MofLength);
  857. }
  858. MofData[pEvent->MofLength] = 0;
  859. MofData[pEvent->MofLength+1] = 0;
  860. ptr = MofData;
  861. MofDataUsed = 0;
  862. // Find the MOF information for this event
  863. pMofInfo = GetMofInfoHead (
  864. pEvent->Header.Guid,
  865. pEvent->Header.Class.Type,
  866. pEvent->Header.Class.Version,
  867. pEvent->Header.Class.Level
  868. );
  869. if( NULL == pMofInfo ){
  870. return;
  871. }
  872. pMofInfo->EventCount++;
  873. if( fSummaryOnly == TRUE ){
  874. return;
  875. }
  876. if( pMofInfo->strDescription != NULL ){
  877. _ftprintf( DumpFile, _T("%12s, "), pMofInfo->strDescription );
  878. }else{
  879. TCHAR strGuid[MAXSTR];
  880. GuidToString( strGuid, &pMofInfo->Guid );
  881. _ftprintf( DumpFile, _T("%12s, "), strGuid );
  882. }
  883. if(pMofInfo->strType != NULL && wcslen(pMofInfo->strType) ){
  884. _ftprintf( DumpFile, _T("%10s, "), pMofInfo->strType );
  885. }else{
  886. _ftprintf( DumpFile, _T("%10d, "), pEvent->Header.Class.Type );
  887. }
  888. // Thread ID
  889. _ftprintf( DumpFile, _T("0x%04X, "), pHeader->ThreadId );
  890. // System Time
  891. _ftprintf( DumpFile, _T("%20I64u, "), pHeader->TimeStamp.QuadPart);
  892. if( g_bUserMode == FALSE ){
  893. // Kernel Time
  894. _ftprintf(DumpFile, _T("%10lu, "), pHeader->KernelTime * TimerResolution);
  895. // User Time
  896. _ftprintf(DumpFile, _T("%10lu, "), pHeader->UserTime * TimerResolution);
  897. }else{
  898. // processor Time
  899. _ftprintf(DumpFile, _T("%I64u, "), pHeader->ProcessorTime);
  900. }
  901. Head = pMofInfo->ItemHeader;
  902. Next = Head->Flink;
  903. if ((Head == Next) && (pEvent->MofLength > 0)) {
  904. _ftprintf(DumpFile, _T("DataSize=%d, "), pEvent->MofLength);
  905. }
  906. while (Head != Next) {
  907. pItem = CONTAINING_RECORD(Next, ITEM_DESC, Entry);
  908. Next = Next->Flink;
  909. MofDataUsed = (ULONG) (ptr - MofData);
  910. if (MofDataUsed >= pEvent->MofLength){
  911. break;
  912. }
  913. switch (pItem->ItemType)
  914. {
  915. case ItemChar:
  916. case ItemUChar:
  917. for( i=0;i<pItem->ArraySize;i++){
  918. iChar = *((PCHAR) ptr);
  919. _ftprintf(DumpFile, _T("%c"), iChar);
  920. ptr += sizeof(CHAR);
  921. }
  922. _ftprintf(DumpFile, _T(", "));
  923. break;
  924. case ItemWChar:
  925. for(i=0;i<pItem->ArraySize;i++){
  926. iwChar = *((PWCHAR) ptr);
  927. _ftprintf(DumpFile, _T(",%wc"), iwChar);
  928. ptr += sizeof(WCHAR);
  929. }
  930. _ftprintf(DumpFile, _T(", "));
  931. break;
  932. case ItemCharShort:
  933. iChar = *((PCHAR) ptr);
  934. _ftprintf(DumpFile, _T("%d, "), iChar);
  935. ptr += sizeof(CHAR);
  936. break;
  937. case ItemShort:
  938. shortword = * ((PSHORT) ptr);
  939. _ftprintf(DumpFile, _T("%6d, "), shortword);
  940. ptr += sizeof (SHORT);
  941. break;
  942. case ItemUShort:
  943. ushortword = *((PUSHORT) ptr);
  944. _ftprintf(DumpFile, _T("%6u, "), ushortword);
  945. ptr += sizeof (USHORT);
  946. break;
  947. case ItemLong:
  948. longword = *((PLONG) ptr);
  949. _ftprintf(DumpFile, _T("%8d, "), longword);
  950. ptr += sizeof (LONG);
  951. break;
  952. case ItemULong:
  953. ulongword = *((PULONG) ptr);
  954. _ftprintf(DumpFile, _T("%8lu, "), ulongword);
  955. ptr += sizeof (ULONG);
  956. break;
  957. case ItemULongX:
  958. ulongword = *((PULONG) ptr);
  959. _ftprintf(DumpFile, _T("0x%08X, "), ulongword);
  960. ptr += sizeof (ULONG);
  961. break;
  962. case ItemLongLong:
  963. {
  964. LONGLONG n64;
  965. n64 = *((LONGLONG*) ptr);
  966. ptr += sizeof(LONGLONG);
  967. _ftprintf(DumpFile, _T("%16I64d, "), n64);
  968. break;
  969. }
  970. case ItemULongLong:
  971. {
  972. ULONGLONG n64;
  973. n64 = *((ULONGLONG*) ptr);
  974. ptr += sizeof(ULONGLONG);
  975. _ftprintf(DumpFile, _T("%16I64u, "), n64);
  976. break;
  977. }
  978. case ItemFloat:
  979. {
  980. float f32;
  981. f32 = *((float*) ptr);
  982. ptr += sizeof(float);
  983. _ftprintf(DumpFile, _T("%f, "), f32);
  984. break;
  985. }
  986. case ItemDouble:
  987. {
  988. double f64;
  989. f64 = *((double*) ptr);
  990. ptr += sizeof(double);
  991. _ftprintf(DumpFile, _T("%f, "), f64);
  992. break;
  993. }
  994. case ItemPtr :
  995. {
  996. unsigned __int64 pointer;
  997. if (PointerSize == 64) {
  998. pointer = *((unsigned __int64 *) ptr);
  999. _ftprintf(DumpFile, _T("0x%X, "), pointer);
  1000. }
  1001. else { // assumes 32 bit otherwise
  1002. ulongword = *((PULONG) ptr);
  1003. _ftprintf(DumpFile, _T("0x%08X, "), ulongword);
  1004. }
  1005. ptr += PointerSize / 8;
  1006. //
  1007. // If target source is Win64, then use Ptr, else use ulongword
  1008. //
  1009. break;
  1010. }
  1011. case ItemIPAddr:
  1012. {
  1013. ulongword = *((PULONG) ptr);
  1014. // Convert it to readable form
  1015. _ftprintf(DumpFile, _T("%03d.%03d.%03d.%03d, "),
  1016. (ulongword >> 0) & 0xff,
  1017. (ulongword >> 8) & 0xff,
  1018. (ulongword >> 16) & 0xff,
  1019. (ulongword >> 24) & 0xff);
  1020. ptr += sizeof (ULONG);
  1021. break;
  1022. }
  1023. case ItemPort:
  1024. {
  1025. _ftprintf(DumpFile, _T("%u, "), NTOHS((USHORT) *ptr));
  1026. ptr += sizeof (USHORT);
  1027. break;
  1028. }
  1029. case ItemString:
  1030. // end_sdk
  1031. case ItemRString:
  1032. // begin_sdk
  1033. {
  1034. USHORT pLen = (USHORT)strlen((CHAR*) ptr);
  1035. if (pLen > 0)
  1036. {
  1037. strcpy(str, ptr);
  1038. // end_sdk
  1039. if (pItem->ItemType == ItemRString)
  1040. {
  1041. reduceA(str);
  1042. }
  1043. // begin_sdk
  1044. for (i=pLen-1; i>0; i--) {
  1045. if (str[i] == 0xFF)
  1046. str[i] = 0;
  1047. else break;
  1048. }
  1049. #ifdef UNICODE
  1050. MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, MOFWSTR);
  1051. _ftprintf(DumpFile, _T("\"%ws\","), wstr);
  1052. #else
  1053. _ftprintf(DumpFile, _T("\"%s\","), str);
  1054. #endif
  1055. }
  1056. ptr += (pLen + 1);
  1057. break;
  1058. }
  1059. case ItemWString:
  1060. // end_sdk
  1061. case ItemRWString:
  1062. // begin_sdk
  1063. {
  1064. size_t pLen = 0;
  1065. size_t i;
  1066. if (*(WCHAR *) ptr)
  1067. {
  1068. // end_sdk
  1069. if (pItem->ItemType == ItemRWString)
  1070. {
  1071. reduceW((WCHAR *) ptr);
  1072. }
  1073. // begin_sdk
  1074. pLen = ((wcslen((WCHAR*)ptr) + 1) * sizeof(WCHAR));
  1075. memcpy(wstr, ptr, pLen);
  1076. for (i = (pLen/2)-1; i > 0; i--)
  1077. {
  1078. if (((USHORT) wstr[i] == (USHORT) 0xFFFF))
  1079. {
  1080. wstr[i] = (USHORT) 0;
  1081. }
  1082. else break;
  1083. }
  1084. wstr[pLen / 2] = wstr[(pLen / 2) + 1]= '\0';
  1085. _ftprintf(DumpFile, _T("\"%ws\","), wstr);
  1086. }
  1087. ptr += pLen;
  1088. break;
  1089. }
  1090. case ItemDSString: // Counted String
  1091. {
  1092. USHORT pLen = (USHORT)(256 * ((USHORT) * ptr) + ((USHORT) * (ptr + 1)));
  1093. ptr += sizeof(USHORT);
  1094. if (pLen > (pEvent->MofLength - MofDataUsed - 1)) {
  1095. pLen = (USHORT) (pEvent->MofLength - MofDataUsed - 1);
  1096. }
  1097. if (pLen > 0)
  1098. {
  1099. strcpy(str, ptr);
  1100. #ifdef UNICODE
  1101. MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, MOFWSTR);
  1102. fwprintf(DumpFile, _T("\"%ws\","), wstr);
  1103. #else
  1104. fprintf(DumpFile, _T("\"%s\","), str);
  1105. #endif
  1106. }
  1107. ptr += (pLen + 1);
  1108. break;
  1109. }
  1110. case ItemPString: // Counted String
  1111. {
  1112. USHORT pLen = * ((USHORT *) ptr);
  1113. ptr += sizeof(USHORT);
  1114. if (pLen > (pEvent->MofLength - MofDataUsed)) {
  1115. pLen = (USHORT) (pEvent->MofLength - MofDataUsed);
  1116. }
  1117. if (pLen > MOFSTR * sizeof(CHAR)) {
  1118. pLen = MOFSTR * sizeof(CHAR);
  1119. }
  1120. if (pLen > 0) {
  1121. memcpy(str, ptr, pLen);
  1122. str[pLen] = '\0';
  1123. #ifdef UNICODE
  1124. MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, MOFWSTR);
  1125. _ftprintf(DumpFile, _T("\"%ws\","), wstr);
  1126. #else
  1127. _ftprintf(DumpFile, _T("\"%s\","), str);
  1128. #endif
  1129. }
  1130. ptr += pLen;
  1131. break;
  1132. }
  1133. case ItemDSWString: // DS Counted Wide Strings
  1134. case ItemPWString: // Counted Wide Strings
  1135. {
  1136. USHORT pLen = (USHORT)(( pItem->ItemType == ItemDSWString)
  1137. ? (256 * ((USHORT) * ptr) + ((USHORT) * (ptr + 1)))
  1138. : (* ((USHORT *) ptr)));
  1139. ptr += sizeof(USHORT);
  1140. if (pLen > (pEvent->MofLength - MofDataUsed)) {
  1141. pLen = (USHORT) (pEvent->MofLength - MofDataUsed);
  1142. }
  1143. if (pLen > MOFWSTR * sizeof(WCHAR)) {
  1144. pLen = MOFWSTR * sizeof(WCHAR);
  1145. }
  1146. if (pLen > 0) {
  1147. memcpy(wstr, ptr, pLen);
  1148. wstr[pLen / sizeof(WCHAR)] = L'\0';
  1149. _ftprintf(DumpFile, _T("\"%ws\","), wstr);
  1150. }
  1151. ptr += pLen;
  1152. break;
  1153. }
  1154. case ItemNWString: // Non Null Terminated String
  1155. {
  1156. USHORT Size;
  1157. Size = (USHORT)(pEvent->MofLength - (ULONG)(ptr - MofData));
  1158. if( Size > MOFSTR )
  1159. {
  1160. Size = MOFSTR;
  1161. }
  1162. if (Size > 0)
  1163. {
  1164. memcpy(wstr, ptr, Size);
  1165. wstr[Size / 2] = '\0';
  1166. _ftprintf(DumpFile, _T("\"%ws\","), wstr);
  1167. }
  1168. ptr += Size;
  1169. break;
  1170. }
  1171. case ItemMLString: // Multi Line String
  1172. {
  1173. USHORT pLen;
  1174. char * src, * dest;
  1175. BOOL inQ = FALSE;
  1176. BOOL skip = FALSE;
  1177. UINT lineCount = 0;
  1178. ptr += sizeof(UCHAR) * 2;
  1179. pLen = (USHORT)strlen(ptr);
  1180. if (pLen > 0)
  1181. {
  1182. src = ptr;
  1183. dest = str;
  1184. while (* src != '\0'){
  1185. if (* src == '\n'){
  1186. if (!lineCount){
  1187. * dest++ = ' ';
  1188. }
  1189. lineCount++;
  1190. }else if (* src == '\"'){
  1191. if (inQ){
  1192. char strCount[32];
  1193. char * cpy;
  1194. sprintf(strCount, "{%dx}", lineCount);
  1195. cpy = & strCount[0];
  1196. while (* cpy != '\0'){
  1197. * dest ++ = * cpy ++;
  1198. }
  1199. }
  1200. inQ = !inQ;
  1201. }else if (!skip){
  1202. *dest++ = *src;
  1203. }
  1204. skip = (lineCount > 1 && inQ);
  1205. src++;
  1206. }
  1207. *dest = '\0';
  1208. #ifdef UNICODE
  1209. MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, MOFWSTR);
  1210. _ftprintf(DumpFile, _T("\"%ws\","), wstr);
  1211. #else
  1212. _ftprintf(DumpFile, _T("\"%s\","), str);
  1213. #endif
  1214. }
  1215. ptr += (pLen);
  1216. break;
  1217. }
  1218. case ItemSid:
  1219. {
  1220. TCHAR UserName[64];
  1221. TCHAR Domain[64];
  1222. TCHAR FullName[256];
  1223. ULONG asize = 0;
  1224. ULONG bsize = 0;
  1225. ULONG Sid[64];
  1226. PULONG pSid = & Sid[0];
  1227. SID_NAME_USE Se;
  1228. ULONG nSidLength;
  1229. pSid = (PULONG) ptr;
  1230. if (*pSid == 0){
  1231. ptr += 4;
  1232. _ftprintf(DumpFile, _T("%4d, "), *pSid);
  1233. }
  1234. else
  1235. {
  1236. ptr += 8; // skip the TOKEN_USER structure
  1237. nSidLength = 8 + (4*ptr[1]);
  1238. asize = 64;
  1239. bsize = 64;
  1240. if (LookupAccountSidW(
  1241. NULL,
  1242. (PSID) ptr,
  1243. (LPTSTR) & UserName[0],
  1244. & asize,
  1245. (LPTSTR) & Domain[0],
  1246. & bsize,
  1247. & Se))
  1248. {
  1249. LPTSTR pFullName = &FullName[0];
  1250. _stprintf( pFullName,_T("\\\\%s\\%s"), Domain, UserName);
  1251. asize = (ULONG) _tcslen(pFullName);
  1252. if (asize > 0){
  1253. _ftprintf(DumpFile, _T("\"%s\", "), pFullName);
  1254. }
  1255. }
  1256. else
  1257. {
  1258. _ftprintf(DumpFile, _T("\"System\", "));
  1259. }
  1260. SetLastError( ERROR_SUCCESS );
  1261. ptr += nSidLength;
  1262. }
  1263. break;
  1264. }
  1265. case ItemGuid:
  1266. {
  1267. TCHAR s[64];
  1268. GuidToString(s, (LPGUID)ptr);
  1269. _ftprintf(DumpFile, _T("%s, "), s);
  1270. ptr += sizeof(GUID);
  1271. break;
  1272. }
  1273. // end_sdk
  1274. case ItemVariant:
  1275. {
  1276. //
  1277. // Variable Size. First ULONG gives the sizee and the rest is blob
  1278. //
  1279. ulongword = *((PULONG) ptr);
  1280. ptr += sizeof(ULONG);
  1281. _ftprintf(DumpFile, _T("DataSize=%d, "), ulongword);
  1282. // No need to dump the contents of the Blob itself.
  1283. ptr += ulongword;
  1284. break;
  1285. }
  1286. // begin_sdk
  1287. case ItemBool:
  1288. {
  1289. BOOL Flag = (BOOL)*ptr;
  1290. _ftprintf(DumpFile, _T("%5s, "), (Flag) ? _T("TRUE") : _T("FALSE"));
  1291. ptr += sizeof(BOOL);
  1292. break;
  1293. }
  1294. default:
  1295. ptr += sizeof (int);
  1296. }
  1297. }
  1298. //Instance ID
  1299. _ftprintf(DumpFile, _T("%d,"), pEvent->InstanceId);
  1300. //Parent Instance ID
  1301. _ftprintf(DumpFile, _T("%d\n"), pEvent->ParentInstanceId);
  1302. }
  1303. ULONG
  1304. CheckFile(
  1305. LPTSTR fileName
  1306. )
  1307. /*++
  1308. Routine Description:
  1309. Checks whether a file exists and is readable.
  1310. Arguments:
  1311. fileName - File name.
  1312. Return Value:
  1313. Non-zero if the file exists and is readable. Zero otherwise.
  1314. --*/
  1315. {
  1316. HANDLE hFile;
  1317. ULONG Status;
  1318. hFile = CreateFile(
  1319. fileName,
  1320. GENERIC_READ,
  1321. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1322. NULL,
  1323. OPEN_EXISTING,
  1324. FILE_ATTRIBUTE_NORMAL,
  1325. NULL
  1326. );
  1327. Status = (hFile != INVALID_HANDLE_VALUE);
  1328. CloseHandle(hFile);
  1329. return Status;
  1330. }
  1331. PMOF_INFO
  1332. GetMofInfoHead(
  1333. GUID Guid,
  1334. SHORT nType,
  1335. SHORT nVersion,
  1336. CHAR nLevel
  1337. )
  1338. /*++
  1339. Routine Description:
  1340. Find a matching event layout in the global linked list. If it
  1341. is not found in the list, it calls GetGuids() to examine the WBEM
  1342. namespace.
  1343. If the global list is empty, it first creates a header.
  1344. Arguments:
  1345. Guid - GUID for the event under consideration.
  1346. nType - Event Type
  1347. nVersion - Event Version
  1348. nLevel - Event Level (not supported in this program)
  1349. Return Value:
  1350. Pointer to MOF_INFO for the current event. If the layout
  1351. information is not found anywhere, GetMofInfoHead() creates
  1352. a dummy and returns it.
  1353. --*/
  1354. {
  1355. PLIST_ENTRY Head, Next;
  1356. PMOF_INFO pMofInfo;
  1357. PMOF_INFO pBestMatch = NULL;
  1358. SHORT nMatchLevel = 0;
  1359. SHORT nMatchCheck;
  1360. // Search the eventList for this Guid and find the head
  1361. if (EventListHead == NULL) {
  1362. // Initialize the MOF List and add the global header guid to it
  1363. EventListHead = (PLIST_ENTRY) malloc(sizeof(LIST_ENTRY));
  1364. if (EventListHead == NULL)
  1365. return NULL;
  1366. InitializeListHead(EventListHead);
  1367. pMofInfo = GetNewMofInfo( EventTraceGuid, EVENT_TYPE_DEFAULT, 0, 0 );
  1368. if( pMofInfo != NULL ){
  1369. InsertTailList( EventListHead, &pMofInfo->Entry );
  1370. pMofInfo->strDescription = (LPTSTR)malloc((_tcslen(GUID_TYPE_EVENTTRACE)+1)*sizeof(TCHAR));
  1371. if( pMofInfo->strDescription != NULL ){
  1372. _tcscpy( pMofInfo->strDescription, GUID_TYPE_EVENTTRACE );
  1373. }
  1374. pMofInfo->strType = (LPTSTR)malloc((_tcslen(GUID_TYPE_HEADER)+1)*sizeof(TCHAR));
  1375. if( pMofInfo->strType != NULL ){
  1376. _tcscpy( pMofInfo->strType, GUID_TYPE_HEADER );
  1377. }
  1378. }
  1379. }
  1380. // Traverse the list and look for the Mof info head for this Guid.
  1381. Head = EventListHead;
  1382. Next = Head->Flink;
  1383. while (Head != Next) {
  1384. nMatchCheck = 0;
  1385. pMofInfo = CONTAINING_RECORD(Next, MOF_INFO, Entry);
  1386. Next = Next->Flink;
  1387. if( IsEqualGUID(&pMofInfo->Guid, &Guid) ){
  1388. if( pMofInfo->TypeIndex == nType ){
  1389. nMatchCheck++;
  1390. }
  1391. if( pMofInfo->Version == nVersion ){
  1392. nMatchCheck++;
  1393. }
  1394. if( nMatchCheck == 2 ){ // Exact Match
  1395. return pMofInfo;
  1396. }
  1397. if( nMatchCheck > nMatchLevel ){ // Close Match
  1398. nMatchLevel = nMatchCheck;
  1399. pBestMatch = pMofInfo;
  1400. }
  1401. if( pMofInfo->TypeIndex == EVENT_TYPE_DEFAULT && // Total Guess
  1402. pBestMatch == NULL ){
  1403. pBestMatch = pMofInfo;
  1404. }
  1405. }
  1406. }
  1407. if(pBestMatch != NULL){
  1408. return pBestMatch;
  1409. }
  1410. // If one does not exist in the list, look it up in the file.
  1411. pMofInfo = GetGuids( Guid, nVersion, nLevel, nType );
  1412. // If still not found, create a unknown place holder
  1413. if( NULL == pMofInfo ){
  1414. pMofInfo = GetNewMofInfo( Guid, nType, nVersion, nLevel );
  1415. if( pMofInfo != NULL ){
  1416. pMofInfo->strDescription = (LPTSTR)malloc((_tcslen(GUID_TYPE_UNKNOWN)+1)*sizeof(TCHAR));
  1417. if( pMofInfo->strDescription != NULL ){
  1418. _tcscpy( pMofInfo->strDescription, GUID_TYPE_UNKNOWN );
  1419. }
  1420. InsertTailList( EventListHead, &pMofInfo->Entry );
  1421. }
  1422. }
  1423. return pMofInfo;
  1424. }
  1425. void
  1426. RemoveMofInfo(
  1427. PLIST_ENTRY pMofInfo
  1428. )
  1429. /*++
  1430. Routine Description:
  1431. Removes and frees data item structs from a given list.
  1432. Arguments:
  1433. pMofInfo - Pointer to the MOF_INFO to be purged of data item structs.
  1434. Return Value:
  1435. None.
  1436. --*/
  1437. {
  1438. PLIST_ENTRY Head, Next;
  1439. PITEM_DESC pItem;
  1440. Head = pMofInfo;
  1441. Next = Head->Flink;
  1442. while (Head != Next) {
  1443. pItem = CONTAINING_RECORD(Next, ITEM_DESC, Entry);
  1444. Next = Next->Flink;
  1445. RemoveEntryList(&pItem->Entry);
  1446. free(pItem);
  1447. }
  1448. }
  1449. void
  1450. CleanupEventList(
  1451. VOID
  1452. )
  1453. /*++
  1454. Routine Description:
  1455. Cleans up a global event list.
  1456. Arguments:
  1457. Return Value:
  1458. None.
  1459. --*/
  1460. {
  1461. PLIST_ENTRY Head, Next;
  1462. PMOF_INFO pMofInfo;
  1463. TCHAR s[256];
  1464. TCHAR wstr[256];
  1465. PTCHAR str;
  1466. if (EventListHead == NULL) {
  1467. return;
  1468. }
  1469. Head = EventListHead;
  1470. Next = Head->Flink;
  1471. while (Head != Next) {
  1472. RtlZeroMemory(&wstr, 256);
  1473. pMofInfo = CONTAINING_RECORD(Next, MOF_INFO, Entry);
  1474. if (pMofInfo->EventCount > 0) {
  1475. GuidToString(&s[0], &pMofInfo->Guid);
  1476. str = s;
  1477. if( pMofInfo->strDescription != NULL ){
  1478. _tcscpy( wstr, pMofInfo->strDescription );
  1479. }
  1480. _ftprintf(SummaryFile,_T("|%10d %-20s %-10s %36s|\n"),
  1481. pMofInfo->EventCount,
  1482. wstr,
  1483. pMofInfo->strType ? pMofInfo->strType : GUID_TYPE_DEFAULT,
  1484. str);
  1485. }
  1486. RemoveEntryList(&pMofInfo->Entry);
  1487. RemoveMofInfo(pMofInfo->ItemHeader);
  1488. free(pMofInfo->ItemHeader);
  1489. if (pMofInfo->strDescription != NULL)
  1490. free(pMofInfo->strDescription);
  1491. if (pMofInfo->strType != NULL)
  1492. free(pMofInfo->strType);
  1493. Next = Next->Flink;
  1494. free(pMofInfo);
  1495. }
  1496. free(EventListHead);
  1497. }
  1498. void
  1499. GuidToString(
  1500. PTCHAR s,
  1501. LPGUID piid
  1502. )
  1503. /*++
  1504. Routine Description:
  1505. Converts a GUID into a string.
  1506. Arguments:
  1507. s - String that will have the converted GUID.
  1508. piid - GUID
  1509. Return Value:
  1510. None.
  1511. --*/
  1512. {
  1513. _stprintf(s, _T("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
  1514. piid->Data1, piid->Data2,
  1515. piid->Data3,
  1516. piid->Data4[0], piid->Data4[1],
  1517. piid->Data4[2], piid->Data4[3],
  1518. piid->Data4[4], piid->Data4[5],
  1519. piid->Data4[6], piid->Data4[7]);
  1520. return;
  1521. }
  1522. void
  1523. AddMofInfo(
  1524. PLIST_ENTRY List,
  1525. LPTSTR strType,
  1526. ITEM_TYPE nType,
  1527. UINT ArraySize
  1528. )
  1529. /*++
  1530. Routine Description:
  1531. Creates a data item information struct (ITEM_DESC) and appends
  1532. it to all MOF_INFOs in the given list.
  1533. GetPropertiesFromWBEM() creates a list of MOF_INFOs for multiple
  1534. types, stores them in a temporary list and calls this function for
  1535. each data item information it encounters.
  1536. Arguments:
  1537. List - List of MOF_INFOs.
  1538. strType - Item description in string.
  1539. nType - ITEM_TYPE defined at the beginning of this file.
  1540. ArraySize - Size of array of this type of items, if applicable.
  1541. Return Value:
  1542. None.
  1543. --*/
  1544. {
  1545. PITEM_DESC pItem;
  1546. PMOF_INFO pMofInfo;
  1547. PLIST_ENTRY Head = List;
  1548. PLIST_ENTRY Next = Head->Flink;
  1549. while (Head != Next) {
  1550. pMofInfo = CONTAINING_RECORD(Next, MOF_INFO, Entry);
  1551. Next = Next->Flink;
  1552. if( NULL != pMofInfo ){
  1553. pItem = (PITEM_DESC) malloc(sizeof(ITEM_DESC));
  1554. if( NULL == pItem ){
  1555. return;
  1556. }
  1557. ZeroMemory( pItem, sizeof(ITEM_DESC) );
  1558. pItem->ItemType = nType;
  1559. pItem->ArraySize = ArraySize;
  1560. pItem->strDescription = (LPTSTR) malloc( (_tcslen(strType)+1)*sizeof(TCHAR));
  1561. if( NULL == pItem->strDescription ){
  1562. free( pItem );
  1563. return;
  1564. }
  1565. _tcscpy(pItem->strDescription, strType);
  1566. InsertTailList( (pMofInfo->ItemHeader), &pItem->Entry);
  1567. }
  1568. }
  1569. }
  1570. PMOF_INFO
  1571. GetNewMofInfo(
  1572. GUID guid,
  1573. SHORT nType,
  1574. SHORT nVersion,
  1575. CHAR nLevel
  1576. )
  1577. /*++
  1578. Routine Description:
  1579. Creates a new MOF_INFO with given data.
  1580. Arguments:
  1581. guid - Event GUID.
  1582. nType - Event type.
  1583. nVersion - Event version.
  1584. nLevel - Event level (not supported in this program).
  1585. Return Value:
  1586. Pointer to the created MOF_INFO. NULL if malloc failed.
  1587. --*/
  1588. {
  1589. PMOF_INFO pMofInfo;
  1590. pMofInfo = (PMOF_INFO)malloc(sizeof(MOF_INFO));
  1591. if( NULL == pMofInfo ){
  1592. return NULL;
  1593. }
  1594. RtlZeroMemory(pMofInfo, sizeof(MOF_INFO));
  1595. memcpy(&pMofInfo->Guid, &guid, sizeof(GUID) );
  1596. pMofInfo->ItemHeader = (PLIST_ENTRY)malloc(sizeof(LIST_ENTRY));
  1597. if( NULL == pMofInfo->ItemHeader ){
  1598. free( pMofInfo );
  1599. return NULL;
  1600. }
  1601. InitializeListHead(pMofInfo->ItemHeader);
  1602. pMofInfo->TypeIndex = nType;
  1603. pMofInfo->Level = nLevel;
  1604. pMofInfo->Version = nVersion;
  1605. return pMofInfo;
  1606. }
  1607. void
  1608. FlushMofList(
  1609. PLIST_ENTRY ListHead
  1610. )
  1611. /*++
  1612. Routine Description:
  1613. Flushes MOF_INFOs in a temporary list into the global list.
  1614. Arguments:
  1615. ListHead - Pointer to the head of a temporary list.
  1616. Return Value:
  1617. None.
  1618. --*/
  1619. {
  1620. PMOF_INFO pMofInfo;
  1621. PLIST_ENTRY Head = ListHead;
  1622. PLIST_ENTRY Next = Head->Flink;
  1623. while( Head != Next ){
  1624. pMofInfo = CONTAINING_RECORD(Next, MOF_INFO, Entry);
  1625. Next = Next->Flink;
  1626. RemoveEntryList(&pMofInfo->Entry);
  1627. InsertTailList( EventListHead, &pMofInfo->Entry);
  1628. }
  1629. }
  1630. HRESULT
  1631. WbemConnect(
  1632. IWbemServices** pWbemServices
  1633. )
  1634. /*++
  1635. Routine Description:
  1636. Connects to WBEM and returns a pointer to WbemServices.
  1637. Arguments:
  1638. pWbemServices - Pointer to the connected WbemServices.
  1639. Return Value:
  1640. ERROR_SUCCESS if successful. Error flag otherwise.
  1641. --*/
  1642. {
  1643. IWbemLocator *pLocator = NULL;
  1644. BSTR bszNamespace = SysAllocString( L"root\\wmi" );
  1645. HRESULT hr = CoInitialize(0);
  1646. hr = CoCreateInstance(
  1647. CLSID_WbemLocator,
  1648. 0,
  1649. CLSCTX_INPROC_SERVER,
  1650. IID_IWbemLocator,
  1651. (LPVOID *) &pLocator
  1652. );
  1653. if ( ERROR_SUCCESS != hr )
  1654. goto cleanup;
  1655. hr = pLocator->ConnectServer(
  1656. bszNamespace,
  1657. NULL,
  1658. NULL,
  1659. NULL,
  1660. 0L,
  1661. NULL,
  1662. NULL,
  1663. pWbemServices
  1664. );
  1665. if ( ERROR_SUCCESS != hr )
  1666. goto cleanup;
  1667. hr = CoSetProxyBlanket(
  1668. *pWbemServices,
  1669. RPC_C_AUTHN_WINNT,
  1670. RPC_C_AUTHZ_NONE,
  1671. NULL,
  1672. RPC_C_AUTHN_LEVEL_PKT,
  1673. RPC_C_IMP_LEVEL_IMPERSONATE,
  1674. NULL,
  1675. EOAC_NONE
  1676. );
  1677. cleanup:
  1678. SysFreeString( bszNamespace );
  1679. if( pLocator ){
  1680. pLocator->Release();
  1681. pLocator = NULL;
  1682. }
  1683. return hr;
  1684. }
  1685. ULONG GetArraySize(
  1686. IN IWbemQualifierSet *pQualSet
  1687. )
  1688. /*++
  1689. Routine Description:
  1690. Examines a given qualifier set and returns the array size.
  1691. NOTE: WBEM stores the size of an array in "MAX" qualifier.
  1692. Arguments:
  1693. pQualSet - Pointer to a qualifier set.
  1694. Return Value:
  1695. The size of the array. The default is 1.
  1696. --*/
  1697. {
  1698. ULONG ArraySize = 1;
  1699. VARIANT pVal;
  1700. BSTR bszMaxLen;
  1701. HRESULT hRes;
  1702. if (pQualSet == NULL){
  1703. return ArraySize;
  1704. }
  1705. bszMaxLen = SysAllocString(L"MAX");
  1706. VariantInit(&pVal);
  1707. hRes = pQualSet->Get(bszMaxLen,
  1708. 0,
  1709. &pVal,
  1710. 0);
  1711. SysFreeString(bszMaxLen);
  1712. if (ERROR_SUCCESS == hRes && pVal.vt == VT_I4 ){
  1713. ArraySize = pVal.lVal;
  1714. }
  1715. VariantClear(&pVal);
  1716. return ArraySize;
  1717. }
  1718. ITEM_TYPE
  1719. GetItemType(
  1720. IN CIMTYPE_ENUMERATION CimType,
  1721. IN IWbemQualifierSet *pQualSet
  1722. )
  1723. /*++
  1724. Routine Description:
  1725. Examines a given qualifier set for a property and returns the type.
  1726. Arguments:
  1727. CimType - WBEM type (different from ITEM_TYPE) of a property.
  1728. pQualSet - Pointer to a qualifier set for a property under consideration.
  1729. Return Value:
  1730. The type (in ITEM_TYPE) of a property.
  1731. --*/
  1732. {
  1733. ITEM_TYPE Type;
  1734. VARIANT pVal;
  1735. HRESULT hRes;
  1736. BSTR bszQualName;
  1737. WCHAR strFormat[10];
  1738. WCHAR strTermination[30];
  1739. WCHAR strTemp[30];
  1740. BOOLEAN IsPointer = FALSE;
  1741. strFormat[0] = '\0';
  1742. strTermination[0] = '\0';
  1743. strTemp[0] = '\0';
  1744. if (pQualSet == NULL)
  1745. return ItemUnknown;
  1746. bszQualName = SysAllocString(L"format");
  1747. VariantInit(&pVal);
  1748. hRes = pQualSet->Get(bszQualName,
  1749. 0,
  1750. &pVal,
  1751. 0);
  1752. SysFreeString(bszQualName);
  1753. if (ERROR_SUCCESS == hRes && NULL != pVal.bstrVal)
  1754. wcscpy(strFormat, pVal.bstrVal);
  1755. bszQualName = SysAllocString(L"StringTermination");
  1756. VariantClear(&pVal);
  1757. hRes = pQualSet->Get(bszQualName,
  1758. 0,
  1759. &pVal,
  1760. 0);
  1761. SysFreeString(bszQualName);
  1762. if (ERROR_SUCCESS == hRes && NULL != pVal.bstrVal)
  1763. wcscpy(strTermination, pVal.bstrVal);
  1764. bszQualName = SysAllocString(L"pointer");
  1765. VariantClear(&pVal);
  1766. hRes = pQualSet->Get(bszQualName,
  1767. 0,
  1768. &pVal,
  1769. 0);
  1770. SysFreeString(bszQualName);
  1771. if (ERROR_SUCCESS == hRes)
  1772. IsPointer = TRUE;
  1773. // Major fix required to get rid of temp
  1774. bszQualName = SysAllocString(L"extension");
  1775. VariantClear(&pVal);
  1776. hRes = pQualSet->Get(bszQualName,
  1777. 0,
  1778. &pVal,
  1779. 0);
  1780. SysFreeString(bszQualName);
  1781. if (ERROR_SUCCESS == hRes && NULL != pVal.bstrVal)
  1782. wcscpy(strTemp, pVal.bstrVal);
  1783. VariantClear(&pVal);
  1784. CimType = (CIMTYPE_ENUMERATION)(CimType & (~CIM_FLAG_ARRAY));
  1785. switch (CimType) {
  1786. case CIM_EMPTY:
  1787. Type = ItemUnknown;
  1788. break;
  1789. case CIM_SINT8:
  1790. Type = ItemCharShort;
  1791. if (!_wcsicmp(strFormat, L"c")){
  1792. Type = ItemChar;
  1793. }
  1794. break;
  1795. case CIM_UINT8:
  1796. Type = ItemUChar;
  1797. break;
  1798. case CIM_SINT16:
  1799. Type = ItemShort;
  1800. break;
  1801. case CIM_UINT16:
  1802. Type = ItemUShort;
  1803. break;
  1804. case CIM_SINT32:
  1805. Type = ItemLong;
  1806. break;
  1807. case CIM_UINT32:
  1808. Type = ItemULong;
  1809. if (!_wcsicmp(strFormat, L"x")){
  1810. Type = ItemULongX;
  1811. }
  1812. break;
  1813. case CIM_SINT64:
  1814. Type = ItemLongLong;
  1815. break;
  1816. case CIM_UINT64:
  1817. Type = ItemULongLong;
  1818. break;
  1819. case CIM_REAL32:
  1820. Type = ItemFloat;
  1821. break;
  1822. case CIM_REAL64:
  1823. Type = ItemDouble;
  1824. break;
  1825. case CIM_BOOLEAN:
  1826. // ItemBool
  1827. Type = ItemBool;
  1828. break;
  1829. case CIM_STRING:
  1830. if (!_wcsicmp(strTermination, L"NullTerminated")) {
  1831. if (!_wcsicmp(strFormat, L"w"))
  1832. Type = ItemWString;
  1833. else
  1834. Type = ItemString;
  1835. }
  1836. else if (!_wcsicmp(strTermination, L"Counted")) {
  1837. if (!_wcsicmp(strFormat, L"w"))
  1838. Type = ItemPWString;
  1839. else
  1840. Type = ItemPString;
  1841. }
  1842. else if (!_wcsicmp(strTermination, L"ReverseCounted")) {
  1843. if (!_wcsicmp(strFormat, L"w"))
  1844. Type = ItemDSWString;
  1845. else
  1846. Type = ItemDSString;
  1847. }
  1848. else if (!_wcsicmp(strTermination, L"NotCounted")) {
  1849. Type = ItemNWString;
  1850. }else{
  1851. Type = ItemString;
  1852. }
  1853. break;
  1854. case CIM_CHAR16:
  1855. // ItemWChar
  1856. Type = ItemWChar;
  1857. break;
  1858. case CIM_OBJECT :
  1859. if (!_wcsicmp(strTemp, L"Port"))
  1860. Type = ItemPort;
  1861. // end_sdk
  1862. else if (!_wcsicmp(strTemp, L"RString"))
  1863. Type = ItemRString;
  1864. else if (!_wcsicmp(strTemp, L"RWString"))
  1865. Type = ItemRWString;
  1866. // begin_sdk
  1867. else if (!_wcsicmp(strTemp, L"IPAddr"))
  1868. Type = ItemIPAddr;
  1869. else if (!_wcsicmp(strTemp, L"Sid"))
  1870. Type = ItemSid;
  1871. else if (!_wcsicmp(strTemp, L"Guid"))
  1872. Type = ItemGuid;
  1873. // end_sdk
  1874. else if (!_wcsicmp(strTemp, L"Variant"))
  1875. Type = ItemVariant;
  1876. // begin_sdk
  1877. break;
  1878. case CIM_DATETIME:
  1879. case CIM_REFERENCE:
  1880. case CIM_ILLEGAL:
  1881. default:
  1882. Type = ItemUnknown;
  1883. break;
  1884. }
  1885. if (IsPointer)
  1886. Type = ItemPtr;
  1887. return Type;
  1888. }
  1889. PMOF_INFO
  1890. GetPropertiesFromWBEM(
  1891. IWbemClassObject *pTraceSubClasses,
  1892. GUID Guid,
  1893. SHORT nVersion,
  1894. CHAR nLevel,
  1895. SHORT nType
  1896. )
  1897. /*++
  1898. Routine Description:
  1899. Constructs a linked list with the information read from the WBEM
  1900. namespace, given the WBEM pointer to the version subtree. It enumerates
  1901. through all type classes in WBEM, and constructs MOF_INFOs for all of
  1902. them (for caching purpose). Meanwhile, it looks for the event layout
  1903. that mathces the passed event, and returns the pointer to the matching
  1904. MOF_INFO at the end.
  1905. Arguments:
  1906. pTraceSubClasses - WBEM pointer to the version subtree.
  1907. Guid - GUID of the passed event.
  1908. nVersion - version of the passed event.
  1909. nLevel - level of the passed event.
  1910. nType - type of the passed event.
  1911. Return Value:
  1912. Pointer to MOF_INFO corresponding to the passed event.
  1913. If the right type is not found, it returns the pointer to
  1914. the generic MOF_INFO for the event version.
  1915. --*/
  1916. {
  1917. IEnumWbemClassObject *pEnumTraceSubSubClasses = NULL;
  1918. IWbemClassObject *pTraceSubSubClasses = NULL;
  1919. IWbemQualifierSet *pQualSet = NULL;
  1920. PMOF_INFO pMofInfo = NULL, pMofLookup = NULL, pMofTemplate = NULL;
  1921. BSTR bszClassName = NULL;
  1922. BSTR bszSubClassName = NULL;
  1923. BSTR bszWmiDataId = NULL;
  1924. BSTR bszEventType = NULL;
  1925. BSTR bszEventTypeName = NULL;
  1926. BSTR bszFriendlyName = NULL;
  1927. BSTR bszPropName = NULL;
  1928. TCHAR strClassName[MAXSTR];
  1929. TCHAR strType[MAXSTR];
  1930. #ifndef UNICODE
  1931. CHAR TempString[MAXSTR];
  1932. #endif
  1933. LONG pVarType;
  1934. SHORT nEventType = EVENT_TYPE_DEFAULT;
  1935. LIST_ENTRY ListHead;
  1936. HRESULT hRes;
  1937. VARIANT pVal;
  1938. VARIANT pTypeVal;
  1939. VARIANT pTypeNameVal;
  1940. VARIANT pClassName;
  1941. ULONG lEventTypeWbem;
  1942. ULONG HUGEP *pTypeData;
  1943. BSTR HUGEP *pTypeNameData;
  1944. SAFEARRAY *PropArray = NULL;
  1945. SAFEARRAY *TypeArray = NULL;
  1946. SAFEARRAY *TypeNameArray = NULL;
  1947. long lLower, lUpper, lCount, IdIndex;
  1948. long lTypeLower, lTypeUpper;
  1949. long lTypeNameLower, lTypeNameUpper;
  1950. ULONG ArraySize;
  1951. ITEM_TYPE ItemType;
  1952. InitializeListHead(&ListHead);
  1953. VariantInit(&pVal);
  1954. VariantInit(&pTypeVal);
  1955. VariantInit(&pTypeNameVal);
  1956. VariantInit(&pClassName);
  1957. bszClassName = SysAllocString(L"__CLASS");
  1958. bszWmiDataId = SysAllocString(L"WmiDataId");
  1959. bszEventType = SysAllocString(L"EventType");
  1960. bszEventTypeName = SysAllocString(L"EventTypeName");
  1961. bszFriendlyName = SysAllocString(L"DisplayName");
  1962. hRes = pTraceSubClasses->Get(bszClassName, // property name
  1963. 0L,
  1964. &pVal, // output to this variant
  1965. NULL,
  1966. NULL);
  1967. if (ERROR_SUCCESS == hRes){
  1968. if (pQualSet) {
  1969. pQualSet->Release();
  1970. pQualSet = NULL;
  1971. }
  1972. // Get Qualifier Set to obtain the friendly name.
  1973. pTraceSubClasses->GetQualifierSet(&pQualSet);
  1974. hRes = pQualSet->Get(bszFriendlyName,
  1975. 0,
  1976. &pClassName,
  1977. 0);
  1978. if (ERROR_SUCCESS == hRes && pClassName.bstrVal != NULL) {
  1979. #ifdef UNICODE
  1980. wcscpy(strClassName, pClassName.bstrVal);
  1981. #else
  1982. WideCharToMultiByte(CP_ACP,
  1983. 0,
  1984. pClassName.bstrVal,
  1985. wcslen(pClassName.bstrVal),
  1986. TempString,
  1987. (MAXSTR * sizeof(CHAR)),
  1988. NULL,
  1989. NULL
  1990. );
  1991. strcpy(strClassName, TempString);
  1992. strClassName[wcslen(pClassName.bstrVal)] = '\0';
  1993. #endif
  1994. }
  1995. else {
  1996. #ifdef UNICODE
  1997. strClassName[0] = L'\0';
  1998. #else
  1999. strClassName[0] = '\0';
  2000. #endif
  2001. }
  2002. // Put Event Header
  2003. pMofInfo = GetNewMofInfo(Guid,
  2004. EVENT_TYPE_DEFAULT,
  2005. EVENT_VERSION_DEFAULT,
  2006. EVENT_LEVEL_DEFAULT
  2007. );
  2008. if (pMofInfo != NULL) {
  2009. pMofTemplate = pMofInfo;
  2010. pMofLookup = pMofInfo;
  2011. InsertTailList(&ListHead, &pMofInfo->Entry);
  2012. pMofInfo->strDescription = (LPTSTR)malloc((_tcslen(strClassName) + 1) * sizeof(TCHAR));
  2013. if (NULL != pMofInfo->strDescription) {
  2014. _tcscpy(pMofInfo->strDescription, strClassName);
  2015. }
  2016. }
  2017. else{
  2018. goto cleanup;
  2019. }
  2020. // Create an enumerator to find derived classes.
  2021. bszSubClassName = SysAllocString(pVal.bstrVal);
  2022. hRes = pWbemServices->CreateClassEnum (
  2023. bszSubClassName, // class name
  2024. WBEM_FLAG_SHALLOW | WBEM_FLAG_USE_AMENDED_QUALIFIERS, // shallow search
  2025. NULL,
  2026. &pEnumTraceSubSubClasses
  2027. );
  2028. SysFreeString ( bszSubClassName );
  2029. if (ERROR_SUCCESS == hRes) {
  2030. ULONG uReturnedSub = 1;
  2031. while(uReturnedSub == 1){
  2032. // For each event in the subclass
  2033. pTraceSubSubClasses = NULL;
  2034. hRes = pEnumTraceSubSubClasses->Next(5000, // timeout in five seconds
  2035. 1, // return just one instance
  2036. &pTraceSubSubClasses, // pointer to a Sub class
  2037. &uReturnedSub); // number obtained: one
  2038. if (ERROR_SUCCESS == hRes && uReturnedSub == 1) {
  2039. if (pQualSet) {
  2040. pQualSet->Release();
  2041. pQualSet = NULL;
  2042. }
  2043. // Get Qualifier Set.
  2044. pTraceSubSubClasses->GetQualifierSet(&pQualSet);
  2045. // Get Type number among Qualifiers
  2046. VariantClear(&pTypeVal);
  2047. hRes = pQualSet->Get(bszEventType,
  2048. 0,
  2049. &pTypeVal,
  2050. 0);
  2051. if (ERROR_SUCCESS == hRes) {
  2052. TypeArray = NULL;
  2053. TypeNameArray = NULL;
  2054. if (pTypeVal.vt & VT_ARRAY) { // EventType is an array
  2055. TypeArray = pTypeVal.parray;
  2056. VariantClear(&pTypeNameVal);
  2057. hRes = pQualSet->Get(bszEventTypeName,
  2058. 0,
  2059. &pTypeNameVal,
  2060. 0);
  2061. if ((ERROR_SUCCESS == hRes) && (pTypeNameVal.vt & VT_ARRAY)) {
  2062. TypeNameArray = pTypeNameVal.parray;
  2063. }
  2064. if (TypeArray != NULL) {
  2065. hRes = SafeArrayGetLBound(TypeArray, 1, &lTypeLower);
  2066. if (ERROR_SUCCESS != hRes) {
  2067. break;
  2068. }
  2069. hRes = SafeArrayGetUBound(TypeArray, 1, &lTypeUpper);
  2070. if (ERROR_SUCCESS != hRes) {
  2071. break;
  2072. }
  2073. if (lTypeUpper < 0) {
  2074. break;
  2075. }
  2076. SafeArrayAccessData(TypeArray, (void HUGEP **)&pTypeData );
  2077. if (TypeNameArray != NULL) {
  2078. hRes = SafeArrayGetLBound(TypeNameArray, 1, &lTypeNameLower);
  2079. if (ERROR_SUCCESS != hRes) {
  2080. break;
  2081. }
  2082. hRes = SafeArrayGetUBound(TypeNameArray, 1, &lTypeNameUpper);
  2083. if (ERROR_SUCCESS != hRes) {
  2084. break;
  2085. }
  2086. if (lTypeNameUpper < 0)
  2087. break;
  2088. SafeArrayAccessData(TypeNameArray, (void HUGEP **)&pTypeNameData );
  2089. }
  2090. for (lCount = lTypeLower; lCount <= lTypeUpper; lCount++) {
  2091. lEventTypeWbem = pTypeData[lCount];
  2092. nEventType = (SHORT)lEventTypeWbem;
  2093. pMofInfo = GetNewMofInfo(Guid, nEventType, nVersion, nLevel);
  2094. if (pMofInfo != NULL) {
  2095. InsertTailList(&ListHead, &pMofInfo->Entry);
  2096. if (pMofTemplate != NULL && pMofTemplate->strDescription != NULL) {
  2097. pMofInfo->strDescription = (LPTSTR)malloc((_tcslen(pMofTemplate->strDescription) + 1) * sizeof(TCHAR));
  2098. if (pMofInfo->strDescription != NULL) {
  2099. _tcscpy(pMofInfo->strDescription, pMofTemplate->strDescription);
  2100. }
  2101. }
  2102. if (nType == nEventType) {
  2103. // Type matched
  2104. pMofLookup = pMofInfo;
  2105. }
  2106. if (TypeNameArray != NULL) {
  2107. if ((lCount >= lTypeNameLower) && (lCount <= lTypeNameUpper)) {
  2108. pMofInfo->strType = (LPTSTR)malloc((wcslen((LPWSTR)pTypeNameData[lCount]) + 1) * sizeof(TCHAR));
  2109. if (pMofInfo->strType != NULL){
  2110. #ifdef UNICODE
  2111. wcscpy(pMofInfo->strType, (LPWSTR)(pTypeNameData[lCount]));
  2112. #else
  2113. WideCharToMultiByte(CP_ACP,
  2114. 0,
  2115. (LPWSTR)(pTypeNameData[lCount]),
  2116. wcslen((LPWSTR)(pTypeNameData[lCount])),
  2117. TempString,
  2118. (MAXSTR * sizeof(CHAR)),
  2119. NULL,
  2120. NULL
  2121. );
  2122. TempString[wcslen((LPWSTR)(pTypeNameData[lCount]))] = '\0';
  2123. strcpy(pMofInfo->strType, TempString);
  2124. #endif
  2125. }
  2126. }
  2127. }
  2128. }
  2129. }
  2130. SafeArrayUnaccessData(TypeArray);
  2131. SafeArrayDestroy(TypeArray);
  2132. VariantInit(&pTypeVal);
  2133. if (TypeNameArray != NULL) {
  2134. SafeArrayUnaccessData(TypeNameArray);
  2135. SafeArrayDestroy(TypeNameArray);
  2136. VariantInit(&pTypeNameVal);
  2137. }
  2138. }
  2139. else {
  2140. // If the Types are not found, then bail
  2141. break;
  2142. }
  2143. }
  2144. else { // EventType is scalar
  2145. hRes = VariantChangeType(&pTypeVal, &pTypeVal, 0, VT_I2);
  2146. if (ERROR_SUCCESS == hRes)
  2147. nEventType = (SHORT)V_I2(&pTypeVal);
  2148. else
  2149. nEventType = (SHORT)V_I4(&pTypeVal);
  2150. VariantClear(&pTypeNameVal);
  2151. hRes = pQualSet->Get(bszEventTypeName,
  2152. 0,
  2153. &pTypeNameVal,
  2154. 0);
  2155. if (ERROR_SUCCESS == hRes) {
  2156. #ifdef UNICODE
  2157. wcscpy(strType, pTypeNameVal.bstrVal);
  2158. #else
  2159. WideCharToMultiByte(CP_ACP,
  2160. 0,
  2161. pTypeNameVal.bstrVal,
  2162. wcslen(pTypeNameVal.bstrVal),
  2163. TempString,
  2164. (MAXSTR * sizeof(CHAR)),
  2165. NULL,
  2166. NULL
  2167. );
  2168. strcpy(strType, TempString);
  2169. strType[wcslen(pTypeNameVal.bstrVal)] = '\0';
  2170. #endif
  2171. }
  2172. else{
  2173. #ifdef UNICODE
  2174. strType[0] = L'\0';
  2175. #else
  2176. strType[0] = '\0';
  2177. #endif
  2178. }
  2179. pMofInfo = GetNewMofInfo(Guid, nEventType, nVersion, nLevel);
  2180. if (pMofInfo != NULL) {
  2181. InsertTailList(&ListHead, &pMofInfo->Entry);
  2182. if (pMofTemplate != NULL && pMofTemplate->strDescription != NULL) {
  2183. pMofInfo->strDescription = (LPTSTR)malloc((_tcslen(pMofTemplate->strDescription) + 1) * sizeof(TCHAR));
  2184. if (pMofInfo->strDescription != NULL) {
  2185. _tcscpy(pMofInfo->strDescription, pMofTemplate->strDescription);
  2186. }
  2187. }
  2188. if (nType == nEventType) {
  2189. // Type matched
  2190. pMofLookup = pMofInfo;
  2191. }
  2192. pMofInfo->strType = (LPTSTR)malloc((_tcslen(strType) + 1) * sizeof(TCHAR));
  2193. if (pMofInfo->strType != NULL){
  2194. _tcscpy(pMofInfo->strType, strType);
  2195. }
  2196. }
  2197. }
  2198. // Get event layout
  2199. VariantClear(&pVal);
  2200. IdIndex = 1;
  2201. V_VT(&pVal) = VT_I4;
  2202. V_I4(&pVal) = IdIndex;
  2203. // For each property
  2204. PropArray = NULL;
  2205. while (pTraceSubSubClasses->GetNames(bszWmiDataId, // only properties with WmiDataId qualifier
  2206. WBEM_FLAG_ONLY_IF_IDENTICAL,
  2207. &pVal, // WmiDataId number starting from 1
  2208. &PropArray) == WBEM_NO_ERROR) {
  2209. hRes = SafeArrayGetLBound(PropArray, 1, &lLower);
  2210. if (ERROR_SUCCESS != hRes) {
  2211. break;
  2212. }
  2213. hRes = SafeArrayGetUBound(PropArray, 1, &lUpper);
  2214. if (ERROR_SUCCESS != hRes) {
  2215. break;
  2216. }
  2217. if (lUpper < 0)
  2218. break;
  2219. // This loop will iterate just once.
  2220. for (lCount = lLower; lCount <= lUpper; lCount++) {
  2221. hRes = SafeArrayGetElement(PropArray, &lCount, &bszPropName);
  2222. if (ERROR_SUCCESS != hRes) {
  2223. break;
  2224. }
  2225. hRes = pTraceSubSubClasses->Get(bszPropName, // Property name
  2226. 0L,
  2227. NULL,
  2228. &pVarType, // CIMTYPE of the property
  2229. NULL);
  2230. if (ERROR_SUCCESS != hRes) {
  2231. break;
  2232. }
  2233. // Get the Qualifier set for the property
  2234. if (pQualSet) {
  2235. pQualSet->Release();
  2236. pQualSet = NULL;
  2237. }
  2238. hRes = pTraceSubSubClasses->GetPropertyQualifierSet(bszPropName,
  2239. &pQualSet);
  2240. if (ERROR_SUCCESS != hRes) {
  2241. break;
  2242. }
  2243. ItemType = GetItemType((CIMTYPE_ENUMERATION)pVarType, pQualSet);
  2244. if( pVarType & CIM_FLAG_ARRAY ){
  2245. ArraySize = GetArraySize(pQualSet);
  2246. }else{
  2247. ArraySize = 1;
  2248. }
  2249. #ifdef UNICODE
  2250. AddMofInfo(&ListHead,
  2251. bszPropName,
  2252. ItemType,
  2253. ArraySize);
  2254. #else
  2255. WideCharToMultiByte(CP_ACP,
  2256. 0,
  2257. bszPropName,
  2258. wcslen(bszPropName),
  2259. TempString,
  2260. (MAXSTR * sizeof(CHAR)),
  2261. NULL,
  2262. NULL
  2263. );
  2264. TempString[wcslen(bszPropName)] = '\0';
  2265. AddMofInfo(&ListHead,
  2266. TempString,
  2267. ItemType,
  2268. ArraySize);
  2269. #endif
  2270. }
  2271. SafeArrayDestroy(PropArray);
  2272. PropArray = NULL;
  2273. V_I4(&pVal) = ++IdIndex;
  2274. } // end enumerating through WmiDataId
  2275. FlushMofList(&ListHead);
  2276. } // if getting event type was successful
  2277. } // if enumeration returned a subclass successfully
  2278. } // end enumerating subclasses
  2279. } // if enumeration was created successfully
  2280. } // if getting class name was successful
  2281. cleanup:
  2282. VariantClear(&pVal);
  2283. VariantClear(&pTypeVal);
  2284. VariantClear(&pClassName);
  2285. SysFreeString(bszClassName);
  2286. SysFreeString(bszWmiDataId);
  2287. SysFreeString(bszEventType);
  2288. SysFreeString(bszEventTypeName);
  2289. SysFreeString(bszFriendlyName);
  2290. // Should not free bszPropName becuase it is already freed by SafeArrayDestroy
  2291. FlushMofList(&ListHead);
  2292. return pMofLookup;
  2293. }
  2294. PMOF_INFO
  2295. GetGuids (GUID Guid,
  2296. SHORT nVersion,
  2297. CHAR nLevel,
  2298. SHORT nType
  2299. )
  2300. /*++
  2301. Routine Description:
  2302. Aceesses the MOF data information from WBEM, creates a linked list,
  2303. and returns a pointer that matches the passed event.
  2304. This function finds the right subtree within the WBEM namespace,
  2305. and calls GetPropertiesFromWBEM() to create the list.
  2306. Arguments:
  2307. Guid - GUID of the passed event.
  2308. nVersion - version of the passed event.
  2309. nLevel - level of the passed event.
  2310. nType - type of the passed event.
  2311. Return Value:
  2312. PMOF_INFO to MOF_INFO structure that matches the passed event.
  2313. NULL if no match is found.
  2314. --*/
  2315. {
  2316. IEnumWbemClassObject *pEnumTraceSubClasses = NULL, *pEnumTraceSubSubClasses = NULL;
  2317. IWbemClassObject *pTraceSubClasses = NULL, *pTraceSubSubClasses = NULL;
  2318. IWbemQualifierSet *pQualSet = NULL;
  2319. BSTR bszInstance = NULL;
  2320. BSTR bszPropertyName = NULL;
  2321. BSTR bszSubClassName = NULL;
  2322. BSTR bszGuid = NULL;
  2323. BSTR bszVersion = NULL;
  2324. WCHAR strGuid[MAXSTR], strTargetGuid[MAXSTR];
  2325. HRESULT hRes;
  2326. VARIANT pVal;
  2327. VARIANT pGuidVal;
  2328. VARIANT pVersionVal;
  2329. UINT nCounter=0;
  2330. BOOLEAN MatchFound;
  2331. SHORT nEventVersion = EVENT_VERSION_DEFAULT;
  2332. PMOF_INFO pMofLookup = NULL;
  2333. VariantInit(&pVal);
  2334. VariantInit(&pGuidVal);
  2335. VariantInit(&pVersionVal);
  2336. if (NULL == pWbemServices) {
  2337. hRes = WbemConnect( &pWbemServices );
  2338. if ( ERROR_SUCCESS != hRes ) {
  2339. goto cleanup;
  2340. }
  2341. }
  2342. // Convert traget GUID to string for later comparison
  2343. #ifdef UNICODE
  2344. GuidToString(strTargetGuid, &Guid);
  2345. #else
  2346. CHAR TempString[MAXSTR];
  2347. GuidToString(TempString, &Guid);
  2348. MultiByteToWideChar(CP_ACP, 0, TempString, -1, strTargetGuid, MAXSTR);
  2349. #endif
  2350. bszInstance = SysAllocString(L"EventTrace");
  2351. bszPropertyName = SysAllocString(L"__CLASS");
  2352. bszGuid = SysAllocString(L"Guid");
  2353. bszVersion = SysAllocString(L"EventVersion");
  2354. pEnumTraceSubClasses = NULL;
  2355. // Get an enumerator for all classes under "EventTace".
  2356. hRes = pWbemServices->CreateClassEnum (
  2357. bszInstance,
  2358. WBEM_FLAG_SHALLOW | WBEM_FLAG_USE_AMENDED_QUALIFIERS,
  2359. NULL,
  2360. &pEnumTraceSubClasses );
  2361. SysFreeString (bszInstance);
  2362. if (ERROR_SUCCESS == hRes) {
  2363. ULONG uReturned = 1;
  2364. MatchFound = FALSE;
  2365. while (uReturned == 1) {
  2366. pTraceSubClasses = NULL;
  2367. // Get the next ClassObject.
  2368. hRes = pEnumTraceSubClasses->Next(5000, // timeout in five seconds
  2369. 1, // return just one instance
  2370. &pTraceSubClasses, // pointer to Event Trace Sub Class
  2371. &uReturned); // number obtained: one or zero
  2372. if (ERROR_SUCCESS == hRes && (uReturned == 1)) {
  2373. // Get the class name
  2374. hRes = pTraceSubClasses->Get(bszPropertyName, // property name
  2375. 0L,
  2376. &pVal, // output to this variant
  2377. NULL,
  2378. NULL);
  2379. if (ERROR_SUCCESS == hRes){
  2380. bszSubClassName = SysAllocString(pVal.bstrVal);
  2381. // Create an enumerator to find derived classes.
  2382. hRes = pWbemServices->CreateClassEnum (
  2383. bszSubClassName,
  2384. WBEM_FLAG_SHALLOW | WBEM_FLAG_USE_AMENDED_QUALIFIERS,
  2385. NULL,
  2386. &pEnumTraceSubSubClasses
  2387. );
  2388. SysFreeString ( bszSubClassName );
  2389. bszSubClassName = NULL;
  2390. VariantClear(&pVal);
  2391. if (ERROR_SUCCESS == hRes) {
  2392. ULONG uReturnedSub = 1;
  2393. while(uReturnedSub == 1){
  2394. pTraceSubSubClasses = NULL;
  2395. // enumerate through the resultset.
  2396. hRes = pEnumTraceSubSubClasses->Next(5000, // timeout in five seconds
  2397. 1, // return just one instance
  2398. &pTraceSubSubClasses, // pointer to a Sub class
  2399. &uReturnedSub); // number obtained: one or zero
  2400. if (ERROR_SUCCESS == hRes && uReturnedSub == 1) {
  2401. // Get the subclass name
  2402. hRes = pTraceSubSubClasses->Get(bszPropertyName, // Class name
  2403. 0L,
  2404. &pVal, // output to this variant
  2405. NULL,
  2406. NULL);
  2407. VariantClear(&pVal);
  2408. if (ERROR_SUCCESS == hRes){
  2409. // Get Qualifier Set.
  2410. if (pQualSet) {
  2411. pQualSet->Release();
  2412. pQualSet = NULL;
  2413. }
  2414. pTraceSubSubClasses->GetQualifierSet (&pQualSet );
  2415. // Get GUID among Qualifiers
  2416. hRes = pQualSet->Get(bszGuid,
  2417. 0,
  2418. &pGuidVal,
  2419. 0);
  2420. if (ERROR_SUCCESS == hRes) {
  2421. wcscpy(strGuid, (LPWSTR)V_BSTR(&pGuidVal));
  2422. VariantClear ( &pGuidVal );
  2423. if (!wcsstr(strGuid, L"{"))
  2424. swprintf(strGuid , L"{%s}", strGuid);
  2425. if (!_wcsicmp(strTargetGuid, strGuid)) {
  2426. hRes = pQualSet->Get(bszVersion,
  2427. 0,
  2428. &pVersionVal,
  2429. 0);
  2430. if (ERROR_SUCCESS == hRes) {
  2431. hRes = VariantChangeType(&pVersionVal, &pVersionVal, 0, VT_I2);
  2432. if (ERROR_SUCCESS == hRes)
  2433. nEventVersion = (SHORT)V_I2(&pVersionVal);
  2434. else
  2435. nEventVersion = (SHORT)V_I4(&pVersionVal);
  2436. VariantClear(&pVersionVal);
  2437. if (nVersion == nEventVersion) {
  2438. // Match is found.
  2439. // Now put all events in this subtree into the list
  2440. MatchFound = TRUE;
  2441. pMofLookup = GetPropertiesFromWBEM( pTraceSubSubClasses,
  2442. Guid,
  2443. nVersion,
  2444. nLevel,
  2445. nType
  2446. );
  2447. break;
  2448. }
  2449. }
  2450. else {
  2451. // if there is no version number for this event,
  2452. // the current one is the only one
  2453. // Now put all events in this subtree into the list
  2454. MatchFound = TRUE;
  2455. pMofLookup = GetPropertiesFromWBEM( pTraceSubSubClasses,
  2456. Guid,
  2457. EVENT_VERSION_DEFAULT,
  2458. nLevel,
  2459. nType
  2460. );
  2461. break;
  2462. }
  2463. }
  2464. }
  2465. }
  2466. }
  2467. } // end while enumerating sub classes
  2468. if (MatchFound) {
  2469. break;
  2470. }
  2471. if (pEnumTraceSubSubClasses) {
  2472. pEnumTraceSubSubClasses->Release();
  2473. pEnumTraceSubSubClasses = NULL;
  2474. }
  2475. } // if creating enumeration was successful
  2476. else {
  2477. pEnumTraceSubSubClasses = NULL;
  2478. }
  2479. } // if getting class name was successful
  2480. }
  2481. nCounter++;
  2482. // if match is found, break out of the top level search
  2483. if (MatchFound)
  2484. break;
  2485. } // end while enumerating top classes
  2486. if( pEnumTraceSubClasses ){
  2487. pEnumTraceSubClasses->Release();
  2488. pEnumTraceSubClasses = NULL;
  2489. }
  2490. } // if creating enumeration for top level is successful
  2491. cleanup:
  2492. VariantClear(&pGuidVal);
  2493. VariantClear(&pVersionVal);
  2494. SysFreeString(bszGuid);
  2495. SysFreeString(bszPropertyName);
  2496. SysFreeString(bszVersion);
  2497. if( pEnumTraceSubClasses ){
  2498. pEnumTraceSubClasses->Release();
  2499. pEnumTraceSubClasses = NULL;
  2500. }
  2501. if (pEnumTraceSubSubClasses){
  2502. pEnumTraceSubSubClasses->Release();
  2503. pEnumTraceSubSubClasses = NULL;
  2504. }
  2505. if (pQualSet) {
  2506. pQualSet->Release();
  2507. pQualSet = NULL;
  2508. }
  2509. return pMofLookup;
  2510. }
  2511. ULONG
  2512. ahextoi(
  2513. TCHAR *s
  2514. )
  2515. /*++
  2516. Routine Description:
  2517. Converts a hex number to an integer.
  2518. Arguments:
  2519. s - Input string containing a hex number.
  2520. Return Value:
  2521. ULONG denoted by the hex string s.
  2522. --*/
  2523. {
  2524. long len;
  2525. ULONG num, base, hex;
  2526. if (s == NULL)
  2527. return 0;
  2528. if (*s == 0)
  2529. return 0;
  2530. len = (long) _tcslen(s);
  2531. if (len == 0 || len >= MAXSTR )
  2532. return 0;
  2533. hex = 0; base = 1; num = 0;
  2534. while (--len >= 0) {
  2535. if ( (s[len] == 'x' || s[len] == 'X') &&
  2536. (s[len-1] == '0') )
  2537. break;
  2538. if (s[len] >= '0' && s[len] <= '9')
  2539. num = s[len] - '0';
  2540. else if (s[len] >= 'a' && s[len] <= 'f')
  2541. num = (s[len] - 'a') + 10;
  2542. else if (s[len] >= 'A' && s[len] <= 'F')
  2543. num = (s[len] - 'A') + 10;
  2544. else
  2545. continue;
  2546. hex += num * base;
  2547. base = base * 16;
  2548. }
  2549. return hex;
  2550. }
  2551. void
  2552. RemoveWhiteSpace(
  2553. TCHAR *s
  2554. )
  2555. /*++
  2556. Routine Description:
  2557. Removes white space (' ', '\n', and '\t') from the given string.
  2558. Arguments:
  2559. s - Input and output string.
  2560. Return Value:
  2561. None
  2562. --*/
  2563. {
  2564. UINT i = 0;
  2565. UINT j = 0;
  2566. TCHAR TempString[MAXSTR];
  2567. if (s == NULL)
  2568. return;
  2569. _tcscpy(TempString, s);
  2570. while (TempString[i] != '\0') {
  2571. if (TempString[i] != ' ' && TempString[i] != '\t' && TempString[i] != '\n')
  2572. s[j++] = TempString[i];
  2573. ++i;
  2574. }
  2575. s[j] = '\0';
  2576. }
  2577. // end_sdk
  2578. void
  2579. DisplayVersionInfo()
  2580. /*++
  2581. Routine Description:
  2582. prints out a version information.
  2583. Arguments:
  2584. None.
  2585. Return Value:
  2586. None.
  2587. --*/
  2588. {
  2589. TCHAR buffer[512];
  2590. TCHAR strProgram[MAXSTR];
  2591. DWORD dw;
  2592. BYTE* pVersionInfo;
  2593. LPTSTR pVersion = NULL;
  2594. LPTSTR pProduct = NULL;
  2595. LPTSTR pCopyRight = NULL;
  2596. dw = GetModuleFileName(NULL, strProgram, MAXSTR);
  2597. if( dw>0 ){
  2598. dw = GetFileVersionInfoSize( strProgram, &dw );
  2599. if( dw > 0 ){
  2600. pVersionInfo = (BYTE*)malloc(dw);
  2601. if( NULL != pVersionInfo ){
  2602. if(GetFileVersionInfo( strProgram, 0, dw, pVersionInfo )){
  2603. LPDWORD lptr = NULL;
  2604. VerQueryValue( pVersionInfo, _T("\\VarFileInfo\\Translation"), (void**)&lptr, (UINT*)&dw );
  2605. if( lptr != NULL ){
  2606. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("ProductVersion") );
  2607. VerQueryValue( pVersionInfo, buffer, (void**)&pVersion, (UINT*)&dw );
  2608. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("OriginalFilename") );
  2609. VerQueryValue( pVersionInfo, buffer, (void**)&pProduct, (UINT*)&dw );
  2610. _stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("LegalCopyright") );
  2611. VerQueryValue( pVersionInfo, buffer, (void**)&pCopyRight, (UINT*)&dw );
  2612. }
  2613. if( pProduct != NULL && pVersion != NULL && pCopyRight != NULL ){
  2614. _tprintf( _T("\nMicrosoft (R) %s (%s)\n%s\n\n"), pProduct, pVersion, pCopyRight );
  2615. }
  2616. }
  2617. free( pVersionInfo );
  2618. }
  2619. }
  2620. }
  2621. }
  2622. // begin_sdk
  2623. void
  2624. PrintHelpMessage()
  2625. /*++
  2626. Routine Description:
  2627. Prints out help messages.
  2628. Arguments:
  2629. None
  2630. Return Value:
  2631. None
  2632. --*/
  2633. {
  2634. // end_sdk
  2635. DisplayVersionInfo();
  2636. // begin_sdk
  2637. _tprintf(
  2638. _T("Usage: tracedmp [options] <EtlFile1 EtlFile2 ...>| [-h | -? | -help]\n")
  2639. _T("\t-o <file> Output CSV file\n")
  2640. _T("\t-rt [LoggerName] Realtime tracedmp from the logger [LoggerName]\n")
  2641. _T("\t-summary Summary.txt only\n")
  2642. _T("\t-begin HH:MM DD/MM/YY\n")
  2643. _T("\t-end HH:MM DD/MM/YY\n")
  2644. _T("\t-h\n")
  2645. _T("\t-help\n")
  2646. _T("\t-? Display usage information\n")
  2647. _T("\n")
  2648. _T("\tDefault Etl File is C:\\Logfile.etl\n")
  2649. _T("\tDefault output file is dumpfile.csv\n")
  2650. );
  2651. }
  2652. // end_sdk