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.

872 lines
26 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. main.c
  5. Abstract:
  6. TRACELIB dll main file
  7. Author:
  8. 08-Apr-1998 mraghu
  9. Revision History:
  10. --*/
  11. #include <stdio.h>
  12. #include "cpdata.h"
  13. #include "tracectr.h"
  14. SYSTEM_RECORD CurrentSystem;
  15. static ULONG lCachedFlushTimer = 1;
  16. PTRACE_CONTEXT_BLOCK TraceContext = NULL;
  17. RTL_CRITICAL_SECTION TLCritSect;
  18. BOOLEAN fDSOnly = FALSE;
  19. BOOLEAN XPorHigher = FALSE;
  20. ULONGLONG DSStartTime = 0;
  21. ULONGLONG DSEndTime = 0;
  22. ULONG TotalBuffersRead = 0;
  23. ULONG TotalBuffersExpected = 0;
  24. WCHAR TempPrintFile[MAXSTR] = L"";
  25. WCHAR TempIisFile[MAXSTR] = L"";
  26. FARPROC EtwpIpv4ToStringA = NULL;
  27. FARPROC EtwpIpv4ToStringW = NULL;
  28. FARPROC EtwpIpv6ToStringA = NULL;
  29. FARPROC EtwpIpv6ToStringW = NULL;
  30. HINSTANCE ntdll;
  31. extern LIST_ENTRY g_ValueMapTable;
  32. ULONG
  33. WINAPI
  34. TerminateOnBufferCallback(
  35. PEVENT_TRACE_LOGFILE pLog
  36. );
  37. extern WriteProc(
  38. LPWSTR filename,
  39. ULONG flags,
  40. PVOID pUserContext
  41. );
  42. HRESULT
  43. OnProcess(
  44. PTRACE_CONTEXT_BLOCK TraceContext
  45. );
  46. ULONG GetMoreBuffers(
  47. PEVENT_TRACE_LOGFILE logfile
  48. );
  49. void
  50. ReorderThreadList()
  51. {
  52. PLIST_ENTRY Head, Next;
  53. PTHREAD_RECORD Thread;
  54. int i;
  55. PPROCESS_RECORD Process;
  56. for (i=0; i < THREAD_HASH_TABLESIZE; i++) {
  57. Head = &CurrentSystem.ThreadHashList[i];
  58. Next = Head->Flink;
  59. while (Next != Head) {
  60. Thread = CONTAINING_RECORD( Next, THREAD_RECORD, Entry );
  61. Next = Next->Flink;
  62. RemoveEntryList( &Thread->Entry );
  63. Process = Thread->pProcess;
  64. if(Process != NULL){
  65. InsertTailList( &Process->ThreadListHead, &Thread->Entry );
  66. }
  67. }
  68. }
  69. }
  70. ULONG
  71. CPDAPI
  72. GetMaxLoggers()
  73. {
  74. return MAXLOGGERS;
  75. }
  76. //
  77. // The second argument is only for merging trace files. pMergedEventsLost
  78. // can be NULL.
  79. // EventsLost in the file header may not have the correct event lost count
  80. // when merging multiple files.
  81. //
  82. ULONG
  83. CPDAPI
  84. InitTraceContextW(
  85. PTRACE_BASIC_INFOW pUserInfo,
  86. PULONG pMergedEventsLost
  87. )
  88. {
  89. UINT i, j;
  90. PFILE_OBJECT *fileTable;
  91. ULONG SizeNeeded, SizeIncrement;
  92. char * pStorage;
  93. HRESULT hr;
  94. BOOL bProcessing = FALSE;
  95. OSVERSIONINFO OSVersion;
  96. if (pUserInfo == NULL) {
  97. return ERROR_INVALID_DATA;
  98. }
  99. //
  100. // Must provide at least one logfile or a trace seassion to process
  101. //
  102. if ( (pUserInfo->LoggerCount == 0) && (pUserInfo->LogFileCount == 0) ) {
  103. return ERROR_INVALID_DATA;
  104. }
  105. //
  106. // Can not process both RealTime stream and a logfile at the same time
  107. //
  108. if ( (pUserInfo->LoggerCount > 0) && (pUserInfo->LogFileCount > 0) ) {
  109. return ERROR_INVALID_DATA;
  110. }
  111. //
  112. // Compute the Size Needed for allocation.
  113. //
  114. SizeNeeded = sizeof(TRACE_CONTEXT_BLOCK);
  115. // Add LogFileName Strings
  116. for (i = 0; i < pUserInfo->LogFileCount; i++) {
  117. SizeNeeded += sizeof(WCHAR) * ( wcslen( pUserInfo->LogFileName[i] ) + 1);
  118. SizeNeeded = (SizeNeeded + 7) & ~7;
  119. }
  120. // Add LoggerName Strings
  121. for (i = 0; i < pUserInfo->LoggerCount; i++) {
  122. SizeNeeded += sizeof(WCHAR) * ( wcslen(pUserInfo->LoggerName[i]) + 1);
  123. SizeNeeded = (SizeNeeded + 7) & ~7;
  124. }
  125. //
  126. // Add ProcFile, MofFile, DumpFile, SummaryFile, TempFile name strings
  127. if (pUserInfo->ProcFileName != NULL) {
  128. SizeNeeded += sizeof(WCHAR) * (wcslen(pUserInfo->ProcFileName) + 1);
  129. SizeNeeded = (SizeNeeded + 7) & ~7;
  130. }
  131. if (pUserInfo->MofFileName != NULL) {
  132. SizeNeeded += sizeof(WCHAR) * (wcslen(pUserInfo->MofFileName) + 1);
  133. SizeNeeded = (SizeNeeded + 7) & ~7;
  134. }
  135. if (pUserInfo->DefMofFileName != NULL) {
  136. SizeNeeded += sizeof(WCHAR) * (wcslen(pUserInfo->DefMofFileName) + 1);
  137. SizeNeeded = (SizeNeeded + 7) & ~7;
  138. }
  139. if (pUserInfo->DumpFileName != NULL) {
  140. SizeNeeded += sizeof(WCHAR) * (wcslen(pUserInfo->DumpFileName) + 1);
  141. SizeNeeded = (SizeNeeded + 7) & ~7;
  142. }
  143. if (pUserInfo->MergeFileName != NULL) {
  144. SizeNeeded += sizeof(WCHAR) * (wcslen(pUserInfo->MergeFileName) + 1);
  145. SizeNeeded = (SizeNeeded + 7) & ~7;
  146. }
  147. if (pUserInfo->CompFileName != NULL) {
  148. SizeNeeded += sizeof(WCHAR) * (wcslen(pUserInfo->CompFileName) + 1);
  149. SizeNeeded = (SizeNeeded + 7) & ~7;
  150. }
  151. if (pUserInfo->SummaryFileName != NULL) {
  152. SizeNeeded += sizeof(WCHAR) * (wcslen(pUserInfo->SummaryFileName) + 1);
  153. SizeNeeded = (SizeNeeded + 7) & ~7;
  154. }
  155. if (pUserInfo->XSLDocName != NULL) {
  156. SizeNeeded += sizeof(WCHAR) * (wcslen(pUserInfo->XSLDocName) + 1);
  157. SizeNeeded = (SizeNeeded + 7) & ~7;
  158. }
  159. //
  160. // Add Room for the FileTable Caching
  161. //
  162. SizeNeeded += sizeof(PFILE_OBJECT) * MAX_FILE_TABLE_SIZE;
  163. //
  164. // Add Room for Thread Hash List
  165. //
  166. SizeNeeded += sizeof(LIST_ENTRY) * THREAD_HASH_TABLESIZE;
  167. //
  168. // Add Room for URL Hash List
  169. //
  170. SizeNeeded += sizeof(LIST_ENTRY) * URL_HASH_TABLESIZE;
  171. //
  172. // Allocate Memory for TraceContext
  173. //
  174. pStorage = malloc(SizeNeeded);
  175. if (pStorage == NULL) {
  176. return ERROR_OUTOFMEMORY;
  177. }
  178. RtlZeroMemory(pStorage, SizeNeeded);
  179. TraceContext = (PTRACE_CONTEXT_BLOCK)pStorage;
  180. pStorage += sizeof(TRACE_CONTEXT_BLOCK);
  181. //
  182. // Initialize HandleArray
  183. //
  184. for (i=0; i < MAXLOGGERS; i++) {
  185. TraceContext->HandleArray[i] = (TRACEHANDLE)INVALID_HANDLE_VALUE;
  186. }
  187. //
  188. // Copy LogFileNames
  189. //
  190. for (i = 0; i < pUserInfo->LogFileCount; i++) {
  191. TraceContext->LogFileName[i] = (LPWSTR)pStorage;
  192. StringCchCopyW(TraceContext->LogFileName[i],
  193. wcslen(pUserInfo->LogFileName[i]) + 1,
  194. pUserInfo->LogFileName[i]);
  195. SizeIncrement = (wcslen(TraceContext->LogFileName[i]) + 1) * sizeof(WCHAR);
  196. SizeIncrement = (SizeIncrement + 7) & ~7;
  197. pStorage += SizeIncrement;
  198. }
  199. //
  200. // Copy LoggerNames
  201. //
  202. for (i = 0; i < pUserInfo->LoggerCount; i++) {
  203. j = i + pUserInfo->LogFileCount;
  204. TraceContext->LoggerName[j] =(LPWSTR) pStorage;
  205. StringCchCopyW(TraceContext->LoggerName[i],
  206. wcslen(pUserInfo->LoggerName[i]) + 1,
  207. pUserInfo->LoggerName[i]);
  208. SizeIncrement = (wcslen(TraceContext->LoggerName[j]) + 1) * sizeof(WCHAR);
  209. SizeIncrement = (SizeIncrement + 7) & ~7;
  210. pStorage += SizeIncrement;
  211. }
  212. //
  213. // Copy Other File Names
  214. //
  215. if (pUserInfo->ProcFileName != NULL) {
  216. TraceContext->ProcFileName = (LPWSTR)pStorage;
  217. StringCchCopyW(TraceContext->ProcFileName,
  218. wcslen(pUserInfo->ProcFileName) + 1,
  219. pUserInfo->ProcFileName);
  220. SizeIncrement = (wcslen(TraceContext->ProcFileName) + 1) * sizeof(WCHAR);
  221. SizeIncrement = (SizeIncrement + 7) & ~7;
  222. pStorage += SizeIncrement;
  223. }
  224. if (pUserInfo->DumpFileName != NULL) {
  225. TraceContext->DumpFileName = (LPWSTR)pStorage;
  226. StringCchCopyW(TraceContext->DumpFileName,
  227. wcslen(pUserInfo->DumpFileName) + 1,
  228. pUserInfo->DumpFileName);
  229. SizeIncrement = (wcslen(TraceContext->DumpFileName) + 1) * sizeof(WCHAR);
  230. SizeIncrement = (SizeIncrement + 7) & ~7;
  231. pStorage += SizeIncrement;
  232. }
  233. if (pUserInfo->MofFileName != NULL) {
  234. TraceContext->MofFileName = (LPWSTR)pStorage;
  235. StringCchCopyW(TraceContext->MofFileName,
  236. wcslen(pUserInfo->MofFileName) + 1,
  237. pUserInfo->MofFileName);
  238. SizeIncrement = (wcslen(TraceContext->MofFileName) + 1) * sizeof(WCHAR);
  239. SizeIncrement = (SizeIncrement + 7) & ~7;
  240. pStorage += SizeIncrement;
  241. }
  242. if (pUserInfo->DefMofFileName != NULL) {
  243. TraceContext->DefMofFileName = (LPWSTR)pStorage;
  244. StringCchCopyW(TraceContext->DefMofFileName,
  245. wcslen(pUserInfo->DefMofFileName) + 1,
  246. pUserInfo->DefMofFileName);
  247. SizeIncrement = (wcslen(TraceContext->DefMofFileName) + 1) * sizeof(WCHAR);
  248. SizeIncrement = (SizeIncrement + 7) & ~7;
  249. pStorage += SizeIncrement;
  250. }
  251. if (pUserInfo->MergeFileName != NULL) {
  252. TraceContext->MergeFileName = (LPWSTR)pStorage;
  253. StringCchCopyW(TraceContext->MergeFileName,
  254. wcslen(pUserInfo->MergeFileName) + 1,
  255. pUserInfo->MergeFileName);
  256. SizeIncrement = (wcslen(TraceContext->MergeFileName) + 1) * sizeof(WCHAR);
  257. SizeIncrement = (SizeIncrement + 7) & ~7;
  258. pStorage += SizeIncrement;
  259. }
  260. if (pUserInfo->CompFileName != NULL) {
  261. TraceContext->CompFileName = (LPWSTR)pStorage;
  262. StringCchCopyW(TraceContext->CompFileName,
  263. wcslen(pUserInfo->CompFileName) + 1,
  264. pUserInfo->CompFileName);
  265. SizeIncrement = (wcslen(TraceContext->CompFileName) + 1) * sizeof(WCHAR);
  266. SizeIncrement = (SizeIncrement + 7) & ~7;
  267. pStorage += SizeIncrement;
  268. }
  269. if (pUserInfo->SummaryFileName != NULL) {
  270. TraceContext->SummaryFileName = (LPWSTR)pStorage;
  271. StringCchCopyW(TraceContext->SummaryFileName,
  272. wcslen(pUserInfo->SummaryFileName) + 1,
  273. pUserInfo->SummaryFileName);
  274. SizeIncrement = (wcslen(TraceContext->SummaryFileName) + 1) * sizeof(WCHAR);
  275. SizeIncrement = (SizeIncrement + 7) & ~7;
  276. pStorage += SizeIncrement;
  277. }
  278. if (pUserInfo->XSLDocName != NULL) {
  279. TraceContext->XSLDocName = (LPWSTR)pStorage;
  280. StringCchCopyW(TraceContext->XSLDocName,
  281. wcslen(pUserInfo->XSLDocName) + 1,
  282. pUserInfo->XSLDocName);
  283. SizeIncrement = (wcslen(TraceContext->XSLDocName) + 1) * sizeof(WCHAR);
  284. SizeIncrement = (SizeIncrement + 7) & ~7;
  285. pStorage += SizeIncrement;
  286. }
  287. TraceContext->LogFileCount = pUserInfo->LogFileCount;
  288. TraceContext->LoggerCount = pUserInfo->LoggerCount;
  289. TraceContext->StartTime = pUserInfo->StartTime;
  290. TraceContext->EndTime = pUserInfo->EndTime;
  291. TraceContext->Flags = pUserInfo->Flags;
  292. TraceContext->hEvent = pUserInfo->hEvent;
  293. TraceContext->pUserContext = pUserInfo->pUserContext;
  294. RtlZeroMemory(&CurrentSystem, sizeof(SYSTEM_RECORD));
  295. InitializeListHead ( &CurrentSystem.ProcessListHead );
  296. InitializeListHead ( &CurrentSystem.GlobalThreadListHead );
  297. InitializeListHead ( &CurrentSystem.GlobalDiskListHead );
  298. InitializeListHead ( &CurrentSystem.HotFileListHead );
  299. InitializeListHead ( &CurrentSystem.WorkloadListHead );
  300. InitializeListHead ( &CurrentSystem.InstanceListHead );
  301. InitializeListHead ( &CurrentSystem.EventListHead );
  302. InitializeListHead ( &CurrentSystem.GlobalModuleListHead );
  303. InitializeListHead ( &CurrentSystem.ProcessFileListHead );
  304. InitializeListHead ( &CurrentSystem.PrintJobListHead);
  305. InitializeListHead ( &CurrentSystem.HttpReqListHead);
  306. InitializeListHead ( &CurrentSystem.PendingHttpReqListHead);
  307. InitializeListHead ( &CurrentSystem.ClientListHead);
  308. InitializeListHead ( &CurrentSystem.SiteListHead);
  309. InitializeListHead ( &CurrentSystem.LogicalDriveHead);
  310. InitializeListHead ( &CurrentSystem.FreePrintJobListHead);
  311. InitializeListHead ( &CurrentSystem.FreeTransListHead);
  312. InitializeListHead ( &CurrentSystem.FreeHttpReqListHead);
  313. InitializeListHead ( &CurrentSystem.FreeURLListHead);
  314. InitializeListHead ( &g_ValueMapTable );
  315. CurrentSystem.FileTable = (PFILE_OBJECT *) pStorage;
  316. pStorage += ( sizeof(PFILE_OBJECT) * MAX_FILE_TABLE_SIZE);
  317. CurrentSystem.ThreadHashList = (PLIST_ENTRY)pStorage;
  318. pStorage += (sizeof(LIST_ENTRY) * THREAD_HASH_TABLESIZE);
  319. RtlZeroMemory(CurrentSystem.ThreadHashList, sizeof(LIST_ENTRY) * THREAD_HASH_TABLESIZE);
  320. for (i=0; i < THREAD_HASH_TABLESIZE; i++) {
  321. InitializeListHead (&CurrentSystem.ThreadHashList[i]);
  322. }
  323. CurrentSystem.URLHashList = (PLIST_ENTRY)pStorage;
  324. pStorage += (sizeof(LIST_ENTRY) * URL_HASH_TABLESIZE);
  325. RtlZeroMemory(CurrentSystem.URLHashList, sizeof(LIST_ENTRY) * URL_HASH_TABLESIZE);
  326. for (i=0; i < URL_HASH_TABLESIZE; i++) {
  327. InitializeListHead (&CurrentSystem.URLHashList[i]);
  328. }
  329. if( (pUserInfo->Flags & TRACE_DUMP) && NULL != pUserInfo->DumpFileName ){
  330. TraceContext->Flags |= TRACE_DUMP;
  331. }
  332. if( (pUserInfo->Flags & TRACE_SUMMARY) && NULL != pUserInfo->SummaryFileName ){
  333. TraceContext->Flags |= TRACE_SUMMARY;
  334. }
  335. if( (pUserInfo->Flags & TRACE_INTERPRET) && NULL != pUserInfo->CompFileName ){
  336. TraceContext->Flags |= TRACE_INTERPRET;
  337. }
  338. hr = GetTempName( TempPrintFile, MAXSTR );
  339. CHECK_HR(hr);
  340. CurrentSystem.TempPrintFile = _wfopen( TempPrintFile, L"w+");
  341. if( CurrentSystem.TempPrintFile == NULL ){
  342. hr = GetLastError();
  343. }
  344. CHECK_HR(hr);
  345. hr = GetTempName( TempIisFile, MAXSTR );
  346. CHECK_HR(hr);
  347. CurrentSystem.TempIisFile = _wfopen( TempIisFile, L"w+");
  348. if( CurrentSystem.TempIisFile == NULL ){
  349. hr = GetLastError();
  350. }
  351. CHECK_HR(hr);
  352. CurrentSystem.fNoEndTime = FALSE;
  353. fileTable = CurrentSystem.FileTable;
  354. for ( i= 0; i<MAX_FILE_TABLE_SIZE; i++){ fileTable[i] = NULL; }
  355. //
  356. // Set the default Processing Flags to Dump
  357. //
  358. if( pUserInfo->Flags & TRACE_EXTENDED_FMT ){
  359. TraceContext->Flags |= TRACE_EXTENDED_FMT;
  360. }
  361. if( pUserInfo->Flags & TRACE_REDUCE ) {
  362. TraceContext->Flags |= TRACE_REDUCE;
  363. TraceContext->Flags |= TRACE_BASIC_REPORT;
  364. }
  365. if( pUserInfo->Flags & TRACE_TRANSFORM_XML ){
  366. TraceContext->Flags |= TRACE_TRANSFORM_XML;
  367. }
  368. if( pUserInfo->StatusFunction != NULL ){
  369. TraceContext->StatusFunction = pUserInfo->StatusFunction;
  370. }
  371. if (TraceContext->Flags & TRACE_DS_ONLY) {
  372. fDSOnly = TRUE;
  373. DSStartTime = pUserInfo->DSStartTime;
  374. DSEndTime = pUserInfo->DSEndTime;
  375. }
  376. if( TraceContext->Flags & TRACE_MERGE_ETL ){
  377. // Update merged events lost count.
  378. ULONG EventsLost;
  379. hr = EtwRelogEtl( TraceContext, &EventsLost );
  380. if (NULL != pMergedEventsLost) {
  381. *pMergedEventsLost = EventsLost;
  382. }
  383. goto cleanup;
  384. }
  385. OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  386. if (GetVersionEx(&OSVersion)) {
  387. XPorHigher = (OSVersion.dwMajorVersion > 5) ||
  388. ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion >= 1));
  389. if (XPorHigher) {
  390. ntdll = LoadLibraryW(L"ntdll.dll");
  391. if (ntdll != NULL) {
  392. EtwpIpv4ToStringA = GetProcAddress(ntdll, "RtlIpv4AddressToStringA");
  393. EtwpIpv4ToStringW = GetProcAddress(ntdll, "RtlIpv4AddressToStringW");
  394. EtwpIpv6ToStringA = GetProcAddress(ntdll, "RtlIpv6AddressToStringA");
  395. EtwpIpv6ToStringW = GetProcAddress(ntdll, "RtlIpv6AddressToStringW");
  396. }
  397. }
  398. }
  399. bProcessing = TRUE;
  400. RtlInitializeCriticalSection(&TLCritSect);
  401. //
  402. // Startup a Thread to update the counters.
  403. // For Logfile replay we burn a thread and throttle it at the
  404. // BufferCallbacks.
  405. //
  406. hr = OnProcess(TraceContext);// Then process Trace Event Data.
  407. ShutdownThreads();
  408. ShutdownProcesses();
  409. ReorderThreadList();
  410. cleanup:
  411. if( ERROR_SUCCESS != hr ){
  412. __try{
  413. if( TraceContext->hDumpFile ){
  414. fclose( TraceContext->hDumpFile );
  415. }
  416. if( bProcessing ){
  417. Cleanup();
  418. RtlDeleteCriticalSection(&TLCritSect);
  419. }
  420. if( CurrentSystem.ComputerName != NULL ) {
  421. free(CurrentSystem.ComputerName);
  422. }
  423. if( CurrentSystem.TempPrintFile != NULL ){
  424. fclose( CurrentSystem.TempPrintFile );
  425. CurrentSystem.TempPrintFile = NULL;
  426. DeleteFile( TempPrintFile );
  427. }
  428. if( CurrentSystem.TempIisFile != NULL ){
  429. fclose( CurrentSystem.TempIisFile );
  430. CurrentSystem.TempIisFile = NULL;
  431. DeleteFile( TempIisFile );
  432. }
  433. if( NULL != TraceContext ){
  434. free(TraceContext);
  435. TraceContext = NULL;
  436. }
  437. } __except (EXCEPTION_EXECUTE_HANDLER) {
  438. }
  439. }
  440. return hr;
  441. }
  442. // Buffer Callback. Used to send a flag to the logstream processing thread.
  443. //
  444. ULONG
  445. GetMoreBuffers(
  446. PEVENT_TRACE_LOGFILE logfile
  447. )
  448. {
  449. TotalBuffersRead++;
  450. if( NULL != TraceContext->StatusFunction ){
  451. if( TotalBuffersExpected > 0 && (TotalBuffersRead % 2 == 0) ){
  452. __try{
  453. TraceContext->StatusFunction(
  454. TRACE_STATUS_PROCESSING,
  455. (double)TotalBuffersRead/(double)TotalBuffersExpected
  456. );
  457. } __except (EXCEPTION_EXECUTE_HANDLER) {
  458. TraceContext->StatusFunction = NULL;
  459. }
  460. }
  461. }
  462. if (TraceContext->hEvent) {
  463. SetEvent(TraceContext->hEvent);
  464. }
  465. //
  466. // While processing logfile playback, we can throttle the processing
  467. // of buffers by the FlushTimer value (in Seconds)
  468. //
  469. if (TraceContext->Flags & TRACE_LOG_REPLAY) {
  470. _sleep(TraceContext->LoggerInfo->FlushTimer * 1000);
  471. }
  472. if(logfile->EventsLost) {
  473. #if DBG
  474. DbgPrint("(TRACECTR) GetMorBuffers(Lost: %9d Filled: %9d\n",
  475. logfile->EventsLost, logfile->Filled );
  476. #endif
  477. }
  478. return (TRUE);
  479. }
  480. ULONG
  481. CPDAPI
  482. DeinitTraceContext(
  483. PTRACE_BASIC_INFOW pUserInfo
  484. )
  485. {
  486. ULONG Status = ERROR_SUCCESS;
  487. ULONG LogFileCount, i;
  488. if (TraceContext == NULL) {
  489. return ERROR_INVALID_HANDLE;
  490. }
  491. LogFileCount = TraceContext->LogFileCount + TraceContext->LoggerCount;
  492. for (i=0; i < LogFileCount; i++) {
  493. if (TraceContext->HandleArray[i] != (TRACEHANDLE)INVALID_HANDLE_VALUE) {
  494. CloseTrace(TraceContext->HandleArray[i]);
  495. TraceContext->HandleArray[i] = (TRACEHANDLE)INVALID_HANDLE_VALUE;
  496. }
  497. }
  498. //
  499. // Write the Summary File
  500. //
  501. if (TraceContext->Flags & TRACE_SUMMARY) {
  502. WriteSummary();
  503. }
  504. if (TraceContext->Flags & TRACE_REDUCE) {
  505. if ((TraceContext->ProcFileName != NULL) &&
  506. (lstrlenW(TraceContext->ProcFileName) ) ){
  507. WCHAR buffer[MAXSTR];
  508. HRESULT hr;
  509. if( TraceContext->Flags & TRACE_TRANSFORM_XML &&
  510. TraceContext->XSLDocName != NULL ){
  511. GetTempName( buffer, MAXSTR );
  512. }else{
  513. hr = StringCchCopy( buffer, MAXSTR, TraceContext->ProcFileName );
  514. }
  515. WriteProc( buffer,
  516. TraceContext->Flags,
  517. TraceContext->pUserContext
  518. );
  519. if( TraceContext->Flags & TRACE_TRANSFORM_XML &&
  520. TraceContext->XSLDocName != NULL ){
  521. Status = TransformXML(
  522. buffer,
  523. TraceContext->XSLDocName,
  524. TraceContext->ProcFileName );
  525. DeleteFile( buffer );
  526. }
  527. }
  528. }
  529. if( CurrentSystem.ComputerName != NULL ) {
  530. free(CurrentSystem.ComputerName);
  531. }
  532. if( CurrentSystem.TempPrintFile != NULL ){
  533. fclose( CurrentSystem.TempPrintFile );
  534. CurrentSystem.TempPrintFile = NULL;
  535. DeleteFile( TempPrintFile );
  536. }
  537. if( CurrentSystem.TempIisFile != NULL ){
  538. fclose( CurrentSystem.TempIisFile );
  539. CurrentSystem.TempIisFile = NULL;
  540. DeleteFile( TempIisFile );
  541. }
  542. if (TraceContext->Flags & TRACE_DUMP) {
  543. if (TraceContext->hDumpFile != NULL) {
  544. fclose(TraceContext->hDumpFile);
  545. }
  546. }
  547. Cleanup();
  548. RtlDeleteCriticalSection(&TLCritSect);
  549. free (TraceContext);
  550. TraceContext = NULL;
  551. return (Status);
  552. }
  553. void
  554. CountFileBuffers( LPWSTR szFile )
  555. {
  556. HANDLE hFile;
  557. DWORD dwStatus;
  558. DWORD dwFileSize;
  559. ULONG BufferSize;
  560. BOOL bStatus;
  561. DWORD dwBytesRead;
  562. hFile = CreateFile(
  563. szFile,
  564. GENERIC_READ,
  565. FILE_SHARE_READ | FILE_SHARE_WRITE,
  566. NULL,
  567. OPEN_EXISTING,
  568. FILE_ATTRIBUTE_NORMAL,
  569. NULL
  570. );
  571. if( hFile == INVALID_HANDLE_VALUE){
  572. dwStatus = GetLastError();
  573. }else{
  574. dwFileSize = GetFileSize( hFile, NULL );
  575. if( INVALID_FILE_SIZE != dwFileSize && dwFileSize > 0){
  576. bStatus = ReadFile(
  577. hFile,
  578. &BufferSize,
  579. sizeof(ULONG),
  580. &dwBytesRead,
  581. NULL );
  582. if( bStatus && BufferSize > 0 ){
  583. TotalBuffersExpected += (dwFileSize / BufferSize );
  584. }
  585. }
  586. CloseHandle(hFile);
  587. }
  588. }
  589. HRESULT
  590. OnProcess(
  591. PTRACE_CONTEXT_BLOCK TraceContext
  592. )
  593. {
  594. ULONG LogFileCount;
  595. ULONG i;
  596. ULONG Status;
  597. PEVENT_TRACE_LOGFILE LogFile[MAXLOGGERS];
  598. BOOL bRealTime;
  599. RtlZeroMemory( &LogFile[0], sizeof(PVOID) * MAXLOGGERS );
  600. if( TraceContext->LogFileCount > 0 ){
  601. LogFileCount = TraceContext->LogFileCount;
  602. bRealTime = FALSE;
  603. }else{
  604. LogFileCount = TraceContext->LoggerCount;
  605. bRealTime = TRUE;
  606. }
  607. for (i = 0; i < LogFileCount; i++) {
  608. LogFile[i] = malloc(sizeof(EVENT_TRACE_LOGFILE));
  609. if (LogFile[i] == NULL) {
  610. Status = ERROR_OUTOFMEMORY;
  611. goto cleanup;
  612. }
  613. RtlZeroMemory(LogFile[i], sizeof(EVENT_TRACE_LOGFILE));
  614. if (bRealTime) {
  615. LogFile[i]->LoggerName = TraceContext->LoggerName[i];
  616. LogFile[i]->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
  617. }
  618. else {
  619. LogFile[i]->BufferCallback = (PEVENT_TRACE_BUFFER_CALLBACK)&TerminateOnBufferCallback;
  620. LogFile[i]->LogFileName = TraceContext->LogFileName[i];
  621. CountFileBuffers( LogFile[i]->LogFileName );
  622. }
  623. }
  624. if (!bRealTime) {
  625. for (i = 0; i < LogFileCount; i++) {
  626. TraceContext->HandleArray[i] = OpenTrace(LogFile[i]);
  627. if ((TRACEHANDLE)INVALID_HANDLE_VALUE == TraceContext->HandleArray[i] ) {
  628. Status = GetLastError();
  629. goto cleanup;
  630. }
  631. Status = ProcessTrace( &(TraceContext->HandleArray[i]), 1, NULL, NULL);
  632. if( ERROR_CANCELLED != Status && ERROR_SUCCESS != Status ){
  633. goto cleanup;
  634. }
  635. }
  636. for (i = 0; i < LogFileCount; i++){
  637. Status = CloseTrace(TraceContext->HandleArray[i]);
  638. }
  639. }
  640. for (i=0; i<LogFileCount; i++) {
  641. LogFile[i]->BufferCallback = (PEVENT_TRACE_BUFFER_CALLBACK)&GetMoreBuffers;
  642. LogFile[i]->EventCallback = (PEVENT_CALLBACK)GeneralEventCallback;
  643. TraceContext->HandleArray[i] = OpenTrace( (PEVENT_TRACE_LOGFILE)LogFile[i]);
  644. if ( TraceContext->HandleArray[i] == (TRACEHANDLE)INVALID_HANDLE_VALUE) {
  645. Status = GetLastError();
  646. goto cleanup;
  647. }
  648. }
  649. if( TraceContext->Flags & TRACE_DUMP ){
  650. FILE* f = _wfopen ( TraceContext->DumpFileName, L"w" );
  651. if( f == NULL) {
  652. Status = GetLastError();
  653. goto cleanup;
  654. }
  655. if( TraceContext->Flags & TRACE_EXTENDED_FMT ){
  656. fwprintf( f,
  657. L"%12s, %10s, %8s,%8s,%8s,%11s,%21s,%11s,%11s, User Data\n",
  658. L"Event Name", L"Type",
  659. L"Type", L"Level", L"Version",
  660. L"TID", L"Clock-Time",
  661. L"Kernel(ms)", L"User(ms)"
  662. );
  663. }else{
  664. fwprintf( f,
  665. L"%12s, %10s,%11s,%21s,%11s,%11s, User Data\n",
  666. L"Event Name", L"Type", L"TID", L"Clock-Time",
  667. L"Kernel(ms)", L"User(ms)"
  668. );
  669. }
  670. TraceContext->hDumpFile = f;
  671. }
  672. DeclareKernelEvents();
  673. if( bRealTime ){
  674. GetSystemTimeAsFileTime((LPFILETIME)&CurrentSystem.StartTime);
  675. }
  676. Status = ProcessTrace(TraceContext->HandleArray,
  677. LogFileCount,
  678. NULL,
  679. NULL);
  680. if( bRealTime && (0 == CurrentSystem.EndTime )) {
  681. GetSystemTimeAsFileTime((LPFILETIME)&CurrentSystem.EndTime);
  682. }
  683. if( bRealTime && (ERROR_WMI_INSTANCE_NOT_FOUND == Status) ){
  684. Status = ERROR_SUCCESS;
  685. }
  686. CurrentSystem.ElapseTime = (ULONG) ( CurrentSystem.EndTime
  687. - CurrentSystem.StartTime);
  688. cleanup:
  689. for (i=0; i < LogFileCount; i++){
  690. if( (TRACEHANDLE)INVALID_HANDLE_VALUE != TraceContext->HandleArray[i] ){
  691. CloseTrace(TraceContext->HandleArray[i]);
  692. TraceContext->HandleArray[i] = (TRACEHANDLE)INVALID_HANDLE_VALUE;
  693. }
  694. if( NULL != LogFile[i] ){
  695. free(LogFile[i]);
  696. }
  697. }
  698. return Status;
  699. }