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.

1713 lines
46 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved
  3. Module Name:
  4. wsbtrc.cpp
  5. Abstract:
  6. This component is a trace object.
  7. Author:
  8. Chuck Bardeen [cbardeen] 29-Oct-1996
  9. Revision History:
  10. Brian Dodd [brian] 09-May-1996 - Added event logging
  11. --*/
  12. #include "stdafx.h"
  13. #include "time.h"
  14. #undef WsbThrow
  15. #define WsbThrow(hr) throw(hr)
  16. #include "wsbtrc.h"
  17. // Local data
  18. static WCHAR message[1024]; // Space for formatting a message
  19. HRESULT
  20. CWsbTrace::FinalConstruct(
  21. void
  22. )
  23. /*++
  24. Implements:
  25. IWsbTrace::FinalConstruct
  26. --*/
  27. {
  28. HRESULT hr = S_OK;
  29. try {
  30. // Set up global values
  31. g_pWsbTrace = 0;
  32. g_WsbTraceModules = WSB_TRACE_BIT_NONE;
  33. // Establish Base object
  34. WsbAffirmHr(CComObjectRoot::FinalConstruct() );
  35. // Initialize member data
  36. m_TraceOn = FALSE;
  37. m_TraceSettings = WSB_TRACE_BIT_NONE;
  38. m_TraceFileName = OLESTR("");
  39. m_TraceOutput = WSB_TRACE_OUT_NONE;
  40. m_CommitEachEntry = FALSE;
  41. m_TimeStamp = FALSE;
  42. m_TraceCount = FALSE;
  43. m_TraceThreadId = FALSE;
  44. m_TraceFilePointer = INVALID_HANDLE_VALUE;
  45. m_WrapMode = FALSE;
  46. m_RegistrySetting = OLESTR("");
  47. m_TraceEntryExit = g_WsbTraceEntryExit;
  48. m_LogLevel = g_WsbLogLevel;
  49. m_TraceFileCopyName = OLESTR("");
  50. m_TraceMultipleFilePattern = OLESTR("");
  51. m_TraceMultipleFileCount = 0;
  52. m_TraceCountHandle = NULL;
  53. m_pTraceCountGlobal = NULL;
  54. } WsbCatch( hr );
  55. return( hr );
  56. }
  57. void
  58. CWsbTrace::FinalRelease(
  59. void
  60. )
  61. /*++
  62. Implements:
  63. IWsbTrace::FinalRelease
  64. --*/
  65. {
  66. HRESULT hr = S_OK;
  67. // Stop Trace
  68. StopTrace();
  69. // Free base class
  70. //
  71. CComObjectRoot::FinalRelease( );
  72. }
  73. HRESULT
  74. CWsbTrace::StartTrace(
  75. void
  76. )
  77. /*++
  78. Implements:
  79. IWsbTrace::StartTrace
  80. --*/
  81. {
  82. HRESULT hr = S_OK;
  83. try {
  84. if (g_pWsbTrace == 0) {
  85. //
  86. // Set global variable for quick checking
  87. //
  88. WsbAffirmHr(((IUnknown*)(IWsbTrace *)this)->QueryInterface(IID_IWsbTrace, (void**) &g_pWsbTrace));
  89. //
  90. // We don't want the reference count bumped for this global so release it here.
  91. g_pWsbTrace->Release();
  92. }
  93. //
  94. // Get hold of the trace count
  95. //
  96. if (m_pTraceCountGlobal == NULL) {
  97. m_pTraceCountGlobal = &g_WsbTraceCount;
  98. m_TraceCountHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
  99. NULL,
  100. PAGE_READWRITE,
  101. 0,
  102. sizeof(ULONG),
  103. L"Global\\RemoteStorageTraceCountPrivate"
  104. );
  105. if (m_TraceCountHandle == NULL) {
  106. if (GetLastError() == ERROR_ALREADY_EXISTS) {
  107. //
  108. // Already open, just get hold of the mapping
  109. //
  110. m_TraceCountHandle = OpenFileMapping(FILE_MAP_WRITE,
  111. FALSE,
  112. L"Global\\RemoteStorageTraceCountPrivate");
  113. } else {
  114. swprintf( message, OLESTR("CWsbTrace::StartTrace: CreateFileMapping failed %d\n"), GetLastError());
  115. g_pWsbTrace->Print(message);
  116. }
  117. }
  118. if (m_TraceCountHandle != NULL) {
  119. m_pTraceCountGlobal = (PLONG) MapViewOfFile(m_TraceCountHandle,
  120. FILE_MAP_WRITE,
  121. 0,
  122. 0,
  123. sizeof(ULONG));
  124. if (!m_pTraceCountGlobal) {
  125. CloseHandle(m_TraceCountHandle);
  126. m_pTraceCountGlobal = &g_WsbTraceCount;
  127. m_TraceCountHandle = NULL;
  128. swprintf( message, OLESTR("CWsbTrace::StartTrace: MapViewOfFile failed %d\n"), GetLastError());
  129. g_pWsbTrace->Print(message);
  130. }
  131. }
  132. }
  133. //
  134. // Set local variable to remember the state
  135. //
  136. m_TraceOn = TRUE;
  137. //
  138. // If there is a file name defined and file tracing is on
  139. // Create/open the trace file.
  140. //
  141. try {
  142. if ((m_TraceOutput & WSB_TRACE_OUT_FILE) &&
  143. (wcslen(m_TraceFileName) != 0) ) {
  144. DWORD attributes;
  145. DWORD bytesReturned;
  146. USHORT inBuffer = COMPRESSION_FORMAT_DEFAULT;
  147. DWORD last_error = 0;
  148. //
  149. // If the main file is open, close it.
  150. //
  151. if (INVALID_HANDLE_VALUE != m_TraceFilePointer) {
  152. CloseHandle(m_TraceFilePointer);
  153. m_TraceFilePointer = INVALID_HANDLE_VALUE;
  154. }
  155. // Adjust the file name (for multiple trace files)
  156. AdjustFileNames();
  157. //
  158. // If there is a copy file specified, copy to it
  159. //
  160. if (m_TraceOutput & WSB_TRACE_OUT_FILE_COPY) {
  161. if (!MoveFileEx(m_TraceFileName, m_TraceFileCopyName,
  162. (MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))) {
  163. // If copy fails, keep going
  164. last_error = GetLastError();
  165. swprintf( message, OLESTR("CWsbTrace::StartTrace: MoveFileEx failed:%ld\r\n"),
  166. last_error);
  167. g_pWsbTrace->Print(message);
  168. }
  169. }
  170. // Open/create the trace file
  171. if (m_CommitEachEntry) {
  172. attributes = FILE_FLAG_WRITE_THROUGH;
  173. } else {
  174. attributes = FILE_ATTRIBUTE_NORMAL;
  175. }
  176. m_TraceFilePointer = CreateFile(m_TraceFileName,
  177. GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,
  178. CREATE_ALWAYS, attributes, NULL);
  179. if (INVALID_HANDLE_VALUE == m_TraceFilePointer) {
  180. last_error = GetLastError();
  181. swprintf( message, OLESTR("CWsbTrace::StartTrace: CreateFile failed:%ld\r\n"),
  182. last_error);
  183. g_pWsbTrace->Print(message);
  184. WsbThrow(E_FAIL);
  185. }
  186. // Make the trace file compressed (if possible)
  187. if (0 == DeviceIoControl(m_TraceFilePointer, FSCTL_SET_COMPRESSION,
  188. &inBuffer, sizeof(inBuffer), 0, 0, &bytesReturned, 0)) {
  189. // Failed to make file compressed -- not a fatal error
  190. last_error = GetLastError();
  191. swprintf( message,
  192. OLESTR("CWsbTrace::StartTrace: DeviceIoControl(COMPRESSION) failed:%ld\r\n"),
  193. last_error);
  194. g_pWsbTrace->Print(message);
  195. }
  196. }
  197. } WsbCatch( hr );
  198. swprintf( message, OLESTR("Trace Started (%d-%ls)\r\n"),
  199. VER_PRODUCTBUILD, RsBuildVersionAsString(RS_BUILD_VERSION));
  200. WsbAffirmHr(g_pWsbTrace->Print(message));
  201. } WsbCatch (hr);
  202. return(hr);
  203. }
  204. HRESULT
  205. CWsbTrace::StopTrace(
  206. void
  207. )
  208. /*++
  209. Implements:
  210. IWsbTrace::StopTrace
  211. --*/
  212. {
  213. HRESULT hr = S_OK;
  214. try {
  215. //
  216. // Set global variable for quick checking
  217. //
  218. if (g_pWsbTrace != 0) {
  219. g_pWsbTrace->Print(OLESTR("Trace Stopped\r\n"));
  220. //
  221. // Don't release here.
  222. //
  223. //g_pWsbTrace->Release();
  224. g_pWsbTrace = 0;
  225. }
  226. //
  227. // Set local variable to remember the state
  228. //
  229. m_TraceOn = FALSE;
  230. //
  231. // Close the file handle
  232. //
  233. if (m_TraceFilePointer != INVALID_HANDLE_VALUE) {
  234. CloseHandle(m_TraceFilePointer);
  235. m_TraceFilePointer = INVALID_HANDLE_VALUE;
  236. }
  237. if (m_TraceCountHandle != NULL) {
  238. BOOL b;
  239. CloseHandle(m_TraceCountHandle);
  240. m_TraceCountHandle = NULL;
  241. //
  242. // We should have a macro to assert without
  243. // throwing HR's
  244. // After one is added, a good assert here would be:
  245. // ASSERT(m_pTraceCountGlobal != NULL);
  246. //
  247. b = UnmapViewOfFile(m_pTraceCountGlobal);
  248. //
  249. // And another here would be:
  250. // ASSERT(b);
  251. //
  252. m_pTraceCountGlobal = NULL;
  253. }
  254. } WsbCatch (hr);
  255. return(hr);
  256. }
  257. HRESULT
  258. CWsbTrace::AdjustFileNames(
  259. void
  260. )
  261. /*++
  262. Routine Description:
  263. Make sure trace flags are set correctly and parse file names if we
  264. haven't already. If we're doing multiple trace files (instead of
  265. wrapping), adjust the trace and copy file names.
  266. Arguments:
  267. None.
  268. Return Value:
  269. S_OK - Success
  270. --*/
  271. {
  272. HRESULT hr = S_OK;
  273. try {
  274. // If we haven't yet, parse file names & set flags.
  275. if (!(m_TraceOutput & WSB_TRACE_OUT_FLAGS_SET)) {
  276. OLECHAR *pc_original;
  277. OLECHAR *pc_bslash;
  278. CWsbStringPtr str_temp(m_TraceFileName);
  279. // Reset flags & file info
  280. m_TraceOutput &= ~WSB_TRACE_OUT_MULTIPLE_FILES;
  281. m_TraceOutput &= ~WSB_TRACE_OUT_FILE_COPY;
  282. m_TraceFileDir = "";
  283. m_TraceMultipleFilePattern = "";
  284. m_TraceFileCopyDir = "";
  285. // Parse the trace file name. One or more '*'s means we should
  286. // do multiple trace files. The number of '*'s indicates
  287. // how many digits to use for the file count. Separate the
  288. // directory from the file name.
  289. pc_bslash = wcsrchr(str_temp, OLECHAR('\\'));
  290. if (pc_bslash) {
  291. *pc_bslash = OLECHAR('\0');
  292. // Get the trace directory
  293. m_TraceFileDir = str_temp;
  294. m_TraceFileDir.Append("\\");
  295. // Point to the file name (which may contain a pattern)
  296. pc_bslash++;
  297. } else {
  298. // No directory specified
  299. pc_bslash = static_cast<OLECHAR *>(str_temp);
  300. }
  301. // Get the file name
  302. m_TraceMultipleFilePattern = pc_bslash;
  303. // Look for '*'s in the file name
  304. pc_original = wcschr(pc_bslash, OLECHAR('*'));
  305. // Convert a file pattern for use in sprintf
  306. if (pc_original) {
  307. OLECHAR format[16];
  308. OLECHAR *pc_copy;
  309. int star_count = 0;
  310. // Count *'s
  311. while (OLECHAR('*') == *pc_original) {
  312. star_count++;
  313. pc_original++;
  314. }
  315. // Create file name pattern: replace '*'s with printf
  316. // type format specification (e.g. "%3.3d")
  317. pc_copy = wcschr(m_TraceMultipleFilePattern, OLECHAR('*'));
  318. WsbAffirm(pc_copy, E_FAIL);
  319. *pc_copy = OLECHAR('\0');
  320. swprintf(format, OLESTR("%%%d.%dd"), star_count, star_count);
  321. m_TraceMultipleFilePattern.Append(format);
  322. m_TraceMultipleFilePattern.Append(pc_original);
  323. // Set multiple flag
  324. m_TraceOutput |= WSB_TRACE_OUT_MULTIPLE_FILES;
  325. }
  326. // If we're doing file copies, set the flag.
  327. if (wcslen(m_TraceFileCopyName)) {
  328. m_TraceOutput |= WSB_TRACE_OUT_FILE_COPY;
  329. // Get the copy directory
  330. str_temp = m_TraceFileCopyName;
  331. pc_bslash = wcsrchr(str_temp, OLECHAR('\\'));
  332. if (pc_bslash) {
  333. *pc_bslash = OLECHAR('\0');
  334. m_TraceFileCopyDir = str_temp;
  335. m_TraceFileCopyDir.Append("\\");
  336. // Point to the copy file name
  337. pc_bslash++;
  338. } else {
  339. pc_bslash = static_cast<OLECHAR *>(str_temp);
  340. }
  341. // If we're not doing multiple trace files, make sure
  342. // we have a copy file name. (If we are doing multiple
  343. // trace files, the copy file name is create below.)
  344. if (!(m_TraceOutput & WSB_TRACE_OUT_MULTIPLE_FILES) &&
  345. 0 == wcslen(pc_bslash)) {
  346. m_TraceFileCopyName = m_TraceFileCopyDir;
  347. m_TraceFileCopyName.Append(m_TraceMultipleFilePattern);
  348. }
  349. }
  350. // Increment file count and indicate flags are set
  351. m_TraceMultipleFileCount++;
  352. m_TraceOutput |= WSB_TRACE_OUT_FLAGS_SET;
  353. }
  354. // If we have a file pattern, create the new actual file names
  355. if (m_TraceOutput & WSB_TRACE_OUT_MULTIPLE_FILES) {
  356. OLECHAR newName[256];
  357. // Create the file name from the pattern and the file count
  358. wsprintf(newName, m_TraceMultipleFilePattern,
  359. m_TraceMultipleFileCount);
  360. // Combine trace directory and file name
  361. m_TraceFileName = m_TraceFileDir;
  362. m_TraceFileName.Append(newName);
  363. // Create a new trace file copy name also
  364. if (m_TraceOutput & WSB_TRACE_OUT_FILE_COPY) {
  365. m_TraceFileCopyName = m_TraceFileCopyDir;
  366. m_TraceFileCopyName.Append(newName);
  367. }
  368. }
  369. } WsbCatch( hr );
  370. return( hr );
  371. }
  372. HRESULT
  373. CWsbTrace::SetTraceOn(
  374. LONGLONG traceElement
  375. )
  376. /*++
  377. Implements:
  378. IWsbTrace::SetTraceOn
  379. --*/
  380. {
  381. HRESULT hr = S_OK;
  382. //
  383. // Turn on the global trace bits for easy checking
  384. //
  385. g_WsbTraceModules = g_WsbTraceModules | traceElement;
  386. //
  387. // Turn on the local trace bits
  388. //
  389. m_TraceSettings = g_WsbTraceModules;
  390. return( hr );
  391. }
  392. HRESULT
  393. CWsbTrace::SetTraceOff(
  394. LONGLONG traceElement
  395. )
  396. /*++
  397. Implements:
  398. IWsbTrace::SetTraceOff
  399. --*/
  400. {
  401. HRESULT hr = S_OK;
  402. //
  403. // Turn off the global trace bits for easy checking
  404. //
  405. g_WsbTraceModules = g_WsbTraceModules & (~traceElement);
  406. //
  407. // Turn on the local trace bits
  408. //
  409. m_TraceSettings = g_WsbTraceModules;
  410. return( hr );
  411. }
  412. HRESULT
  413. CWsbTrace::GetTraceSettings(
  414. LONGLONG *pTraceElements
  415. )
  416. /*++
  417. Implements:
  418. IWsbTrace::GetTraceSettings
  419. --*/
  420. {
  421. HRESULT hr = S_OK;
  422. try
  423. {
  424. WsbAffirm(pTraceElements != 0, E_POINTER);
  425. *pTraceElements = g_WsbTraceModules;
  426. } WsbCatch( hr );
  427. return( hr );
  428. }
  429. HRESULT
  430. CWsbTrace::GetTraceSetting(
  431. LONGLONG traceElement,
  432. BOOL *pOn )
  433. /*++
  434. Implements:
  435. IWsbTrace::GetTraceSetting
  436. --*/
  437. {
  438. HRESULT hr = S_OK;
  439. //
  440. // Find the bit and return TRUE if it is set,
  441. // otherwise return FALSE
  442. //
  443. try
  444. {
  445. WsbAffirm(pOn != 0, E_POINTER);
  446. *pOn = FALSE;
  447. if ((g_WsbTraceModules & traceElement) == traceElement) {
  448. *pOn = TRUE;
  449. }
  450. } WsbCatch( hr );
  451. return( hr );
  452. }
  453. HRESULT
  454. CWsbTrace::DirectOutput(
  455. ULONG output
  456. )
  457. /*++
  458. Implements:
  459. IWsbTrace::DirectOutput
  460. --*/
  461. {
  462. HRESULT hr = S_OK;
  463. m_TraceOutput = output;
  464. return( hr );
  465. }
  466. HRESULT
  467. CWsbTrace::SetTraceFileControls(
  468. OLECHAR *pTraceFileName,
  469. BOOL commitEachEntry,
  470. LONGLONG maxTraceFileSize,
  471. OLECHAR *pTraceFileCopyName
  472. )
  473. /*++
  474. Implements:
  475. IWsbTrace::SetTraceFileControls
  476. --*/
  477. {
  478. HRESULT hr = S_OK;
  479. try {
  480. if (pTraceFileName) {
  481. m_TraceFileName = pTraceFileName;
  482. m_TraceOutput &= ~WSB_TRACE_OUT_FLAGS_SET;
  483. }
  484. m_CommitEachEntry = commitEachEntry;
  485. m_MaxTraceFileSize = maxTraceFileSize;
  486. if (pTraceFileCopyName) {
  487. m_TraceFileCopyName = pTraceFileCopyName;
  488. m_TraceOutput &= ~WSB_TRACE_OUT_FLAGS_SET;
  489. }
  490. } WsbCatch( hr );
  491. return( hr );
  492. }
  493. HRESULT
  494. CWsbTrace::GetTraceFileControls(
  495. OLECHAR **ppTraceFileName,
  496. BOOL *pCommitEachEntry,
  497. LONGLONG *pMaxTraceFileSize,
  498. OLECHAR **ppTraceFileCopyName
  499. )
  500. /*++
  501. Implements:
  502. IWsbTrace::GetTraceFileControls
  503. --*/
  504. {
  505. HRESULT hr = S_OK;
  506. try {
  507. if (ppTraceFileName) {
  508. CWsbStringPtr fileName;
  509. fileName = m_TraceFileName;
  510. fileName.GiveTo(ppTraceFileName);
  511. }
  512. if (pCommitEachEntry) {
  513. *pCommitEachEntry = m_CommitEachEntry;
  514. }
  515. if (pMaxTraceFileSize) {
  516. *pMaxTraceFileSize = m_MaxTraceFileSize;
  517. }
  518. if (ppTraceFileCopyName) {
  519. CWsbStringPtr fileCopyName;
  520. fileCopyName = m_TraceFileCopyName;
  521. fileCopyName.GiveTo(ppTraceFileCopyName);
  522. }
  523. } WsbCatch( hr );
  524. return( hr );
  525. }
  526. HRESULT
  527. CWsbTrace::Print(
  528. OLECHAR *traceString
  529. )
  530. /*++
  531. Implements:
  532. IWsbTrace::Print
  533. --*/
  534. {
  535. HRESULT hr = S_OK;
  536. CWsbStringPtr outString;
  537. DWORD threadId;
  538. OLECHAR tmpString[50];
  539. try {
  540. //
  541. // Add the timeStamp if it is requested
  542. //
  543. if (m_TimeStamp) {
  544. SYSTEMTIME stime;
  545. GetLocalTime(&stime);
  546. swprintf(tmpString, OLESTR("%2.02u/%2.02u %2.2u:%2.2u:%2.2u.%3.3u "),
  547. stime.wMonth, stime.wDay,
  548. stime.wHour, stime.wMinute,
  549. stime.wSecond, stime.wMilliseconds);
  550. outString.Append(tmpString);
  551. outString.Append(" ");
  552. }
  553. //
  554. // Add the trace count if requested
  555. //
  556. if (m_TraceCount) {
  557. OLECHAR tmpString[50];
  558. swprintf(tmpString, OLESTR("%8.8lX"), *(m_pTraceCountGlobal));
  559. outString.Append(tmpString);
  560. InterlockedIncrement(m_pTraceCountGlobal);
  561. outString.Append(" ");
  562. }
  563. //
  564. // Add the thread ID if requested
  565. //
  566. if (m_TraceThreadId) {
  567. threadId = GetCurrentThreadId();
  568. if (threadId < 0x0000FFFF) {
  569. swprintf(tmpString, OLESTR("%4.4lX"), threadId);
  570. } else {
  571. swprintf(tmpString, OLESTR("%8.8lX"), threadId);
  572. }
  573. outString.Append(tmpString);
  574. outString.Append(" ");
  575. }
  576. outString.Append(traceString);
  577. //
  578. // Make sure no one else writes when we do
  579. //
  580. Lock();
  581. try {
  582. if ((m_TraceOutput & WSB_TRACE_OUT_DEBUG_SCREEN) == WSB_TRACE_OUT_DEBUG_SCREEN) {
  583. //
  584. // Write to debug console
  585. //
  586. OutputDebugString(outString);
  587. }
  588. if ((m_TraceOutput & WSB_TRACE_OUT_STDOUT) == WSB_TRACE_OUT_STDOUT) {
  589. //
  590. // Write the string to the local console
  591. //
  592. wprintf(L"%ls", (WCHAR *) outString);
  593. }
  594. if ((m_TraceOutput & WSB_TRACE_OUT_FILE) == WSB_TRACE_OUT_FILE) {
  595. //
  596. // Make sure the file exists, etc.
  597. //
  598. if (m_TraceFilePointer != INVALID_HANDLE_VALUE) {
  599. //
  600. // Write the string to the trace file
  601. //
  602. WsbAffirmHr(Write(outString));
  603. //
  604. // See if we have used our space
  605. //
  606. WsbAffirmHr(WrapTraceFile());
  607. }
  608. }
  609. } WsbCatch( hr );
  610. Unlock();
  611. } WsbCatch( hr );
  612. return( hr );
  613. }
  614. HRESULT
  615. CWsbTrace::WrapTraceFile(
  616. void
  617. )
  618. /*++
  619. Implements:
  620. IWsbTrace::WrapTraceFile
  621. --*/
  622. {
  623. HRESULT hr = S_OK;
  624. static BOOL stopping = FALSE;
  625. try {
  626. LARGE_INTEGER offset;
  627. //
  628. // Find out where we are writing to the file
  629. //
  630. offset.HighPart = 0;
  631. offset.LowPart = SetFilePointer(m_TraceFilePointer, 0, &offset.HighPart, FILE_CURRENT);
  632. WsbAffirm(0xFFFFFFFF != offset.LowPart || NO_ERROR == GetLastError(), E_FAIL);
  633. //
  634. // See if we are past the max size desired
  635. //
  636. if (!stopping && offset.QuadPart >= m_MaxTraceFileSize) {
  637. // If we are doing multiple files, close this one and
  638. // open a new one
  639. if (m_TraceOutput & WSB_TRACE_OUT_MULTIPLE_FILES) {
  640. // Close the current trace file
  641. stopping = TRUE;
  642. StopTrace();
  643. // Increment the file count
  644. m_TraceMultipleFileCount++;
  645. // Create a new trace file
  646. StartTrace();
  647. stopping = FALSE;
  648. // otherwise go into wrap mode
  649. } else {
  650. // We have gone too far so start back at the top and indicating we are wrapping.
  651. offset.HighPart = 0;
  652. offset.LowPart = SetFilePointer(m_TraceFilePointer, 0, &offset.HighPart, FILE_BEGIN);
  653. WsbAffirm(0xFFFFFFFF != offset.LowPart || NO_ERROR == GetLastError(), E_FAIL);
  654. m_WrapMode = TRUE;
  655. }
  656. }
  657. if (m_WrapMode) {
  658. // Save where we are in the file
  659. offset.LowPart = SetFilePointer(m_TraceFilePointer, 0, &offset.HighPart, FILE_CURRENT);
  660. WsbAffirm(0xFFFFFFFF != offset.LowPart || NO_ERROR == GetLastError(), E_FAIL);
  661. // Write the wrap line
  662. WsbAffirmHr(Write(OLESTR("!!! TRACE WRAPPED !!!\r\n")));
  663. /* Go back to offset before wrap line saved */
  664. offset.LowPart = SetFilePointer(m_TraceFilePointer, offset.LowPart,
  665. &offset.HighPart, FILE_BEGIN);
  666. WsbAffirm(0xFFFFFFFF != offset.LowPart || NO_ERROR == GetLastError(), E_FAIL);
  667. }
  668. } WsbCatch( hr );
  669. return( hr );
  670. }
  671. HRESULT
  672. CWsbTrace::SetOutputFormat(
  673. BOOL timeStamp,
  674. BOOL traceCount,
  675. BOOL traceThreadId
  676. )
  677. /*++
  678. Implements:
  679. IWsbTrace::SetOutputFormat
  680. --*/
  681. {
  682. HRESULT hr = S_OK;
  683. try {
  684. m_TimeStamp = timeStamp;
  685. m_TraceCount = traceCount;
  686. m_TraceThreadId = traceThreadId;
  687. } WsbCatch( hr );
  688. return( hr );
  689. }
  690. HRESULT
  691. CWsbTrace::GetOutputFormat(
  692. BOOL *pTimeStamp,
  693. BOOL *pTraceCount,
  694. BOOL *pTraceThreadId
  695. )
  696. /*++
  697. Implements:
  698. IWsbTrace::GetOutputFormat
  699. --*/
  700. {
  701. HRESULT hr = S_OK;
  702. try {
  703. WsbAffirm(0 != pTimeStamp, E_POINTER);
  704. WsbAffirm(0 != pTraceCount, E_POINTER);
  705. WsbAffirm(0 != pTraceThreadId, E_POINTER);
  706. *pTimeStamp = m_TimeStamp;
  707. *pTraceCount = m_TraceCount;
  708. *pTraceThreadId = m_TraceThreadId;
  709. } WsbCatch( hr );
  710. return( hr );
  711. }
  712. HRESULT
  713. CWsbTrace::GetRegistryEntry(
  714. OLECHAR **pRegistryEntry
  715. )
  716. /*++
  717. Implements:
  718. IWsbTrace::GetRegistryEntry
  719. --*/
  720. {
  721. HRESULT hr = S_OK;
  722. try {
  723. WsbAffirm(0 != pRegistryEntry, E_POINTER);
  724. CWsbStringPtr entry;
  725. entry = m_RegistrySetting;
  726. WsbAffirmHr(entry.GiveTo(pRegistryEntry));
  727. } WsbCatch( hr );
  728. return( hr );
  729. }
  730. HRESULT
  731. CWsbTrace::SetRegistryEntry(
  732. OLECHAR *registryEntry
  733. )
  734. /*++
  735. Implements:
  736. IWsbTrace::SetRegistryEntry
  737. --*/
  738. {
  739. HRESULT hr = S_OK;
  740. m_RegistrySetting = registryEntry;
  741. return( hr );
  742. }
  743. HRESULT
  744. CWsbTrace::LoadFromRegistry(
  745. void
  746. )
  747. /*++
  748. Implements:
  749. IWsbTrace::LoadFromRegistry
  750. --*/
  751. {
  752. HRESULT hr = S_OK;
  753. try {
  754. if (wcslen(m_RegistrySetting) > 0) {
  755. WsbAffirmHr(WsbEnsureRegistryKeyExists (NULL, m_RegistrySetting));
  756. WsbAffirmHr(LoadFileSettings());
  757. WsbAffirmHr(LoadTraceSettings());
  758. WsbAffirmHr(LoadOutputDestinations());
  759. WsbAffirmHr(LoadFormat());
  760. WsbAffirmHr(LoadStart());
  761. } else {
  762. hr = E_FAIL;
  763. }
  764. } WsbCatch( hr );
  765. return( hr );
  766. }
  767. HRESULT
  768. CWsbTrace::LoadFileSettings(
  769. void
  770. )
  771. /*++
  772. Implements:
  773. IWsbTrace::LoadFileSettings
  774. --*/
  775. {
  776. HRESULT hr = S_OK;
  777. try {
  778. DWORD sizeGot;
  779. OLECHAR dataString[512];
  780. OLECHAR *stopString;
  781. CWsbStringPtr l_TraceFileName=L"Trace";
  782. LONGLONG l_TraceFileSize=0;
  783. BOOL l_TraceCommit=FALSE;
  784. CWsbStringPtr l_TraceFileCopyName;
  785. //
  786. // Get the values
  787. //
  788. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_FILE_NAME,
  789. dataString, 512, &sizeGot);
  790. if (hr == S_OK) {
  791. l_TraceFileName = dataString;
  792. }
  793. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_FILE_MAX_SIZE,
  794. dataString, 512, &sizeGot);
  795. if (hr == S_OK) {
  796. l_TraceFileSize = wcstoul( dataString, &stopString, 10 );
  797. }
  798. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_FILE_COMMIT,
  799. dataString, 100, &sizeGot);
  800. if (hr == S_OK) {
  801. if (0 == wcstoul(dataString, &stopString, 10)) {
  802. l_TraceCommit = FALSE;
  803. } else {
  804. l_TraceCommit = TRUE;
  805. }
  806. }
  807. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_FILE_COPY_NAME,
  808. dataString, 512, &sizeGot);
  809. if (hr == S_OK) {
  810. l_TraceFileCopyName = dataString;
  811. }
  812. hr = S_OK;
  813. WsbAffirmHr(SetTraceFileControls(l_TraceFileName, l_TraceCommit,
  814. l_TraceFileSize, l_TraceFileCopyName));
  815. } WsbCatch( hr );
  816. return( hr );
  817. }
  818. HRESULT
  819. CWsbTrace::LoadTraceSettings(
  820. void
  821. )
  822. /*++
  823. Implements:
  824. IWsbTrace::LoadTraceSettings
  825. --*/
  826. {
  827. HRESULT hr = S_OK;
  828. try {
  829. DWORD sizeGot;
  830. OLECHAR dataString[100];
  831. OLECHAR *stopString;
  832. BOOL value = FALSE;
  833. LONG number = 0;
  834. LONGLONG l_TraceSettings = WSB_TRACE_BIT_NONE;
  835. BOOL l_TraceEntryExit = TRUE;
  836. WORD w_LogLevel = WSB_LOG_LEVEL_DEFAULT;
  837. BOOL b_SnapShotOn = FALSE;
  838. WORD w_SnapShotLevel = 0;
  839. CWsbStringPtr p_SnapShotPath = L"SnapShotPath";
  840. BOOL b_SnapShotResetTrace = FALSE;
  841. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_PLATFORM,
  842. dataString, 100, &sizeGot);
  843. if (hr == S_OK) {
  844. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  845. if (value) {
  846. l_TraceSettings |= WSB_TRACE_BIT_PLATFORM;
  847. }
  848. }
  849. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_RMS,
  850. dataString, 100, &sizeGot);
  851. if (hr == S_OK) {
  852. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  853. if (value) {
  854. l_TraceSettings |= WSB_TRACE_BIT_RMS;
  855. }
  856. }
  857. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_SEG,
  858. dataString, 100, &sizeGot);
  859. if (hr == S_OK) {
  860. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  861. if (value) {
  862. l_TraceSettings |= WSB_TRACE_BIT_SEG;
  863. }
  864. }
  865. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_META,
  866. dataString, 100, &sizeGot);
  867. if (hr == S_OK) {
  868. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  869. if (value) {
  870. l_TraceSettings |= WSB_TRACE_BIT_META;
  871. }
  872. }
  873. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_HSMENG,
  874. dataString, 100, &sizeGot);
  875. if (hr == S_OK) {
  876. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  877. if (value) {
  878. l_TraceSettings |= WSB_TRACE_BIT_HSMENG;
  879. }
  880. }
  881. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_HSMSERV,
  882. dataString, 100, &sizeGot);
  883. if (hr == S_OK) {
  884. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  885. if (value) {
  886. l_TraceSettings |= WSB_TRACE_BIT_HSMSERV;
  887. }
  888. }
  889. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_JOB,
  890. dataString, 100, &sizeGot);
  891. if (hr == S_OK) {
  892. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  893. if (value) {
  894. l_TraceSettings |= WSB_TRACE_BIT_JOB;
  895. }
  896. }
  897. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_HSMTSKMGR,
  898. dataString, 100, &sizeGot);
  899. if (hr == S_OK) {
  900. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  901. if (value) {
  902. l_TraceSettings |= WSB_TRACE_BIT_HSMTSKMGR;
  903. }
  904. }
  905. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_FSA,
  906. dataString, 100, &sizeGot);
  907. if (hr == S_OK) {
  908. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  909. if (value) {
  910. l_TraceSettings |= WSB_TRACE_BIT_FSA;
  911. }
  912. }
  913. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_DATAMIGRATER,
  914. dataString, 100, &sizeGot);
  915. if (hr == S_OK) {
  916. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  917. if (value) {
  918. l_TraceSettings |= WSB_TRACE_BIT_DATAMIGRATER;
  919. }
  920. }
  921. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_DATARECALLER,
  922. dataString, 100, &sizeGot);
  923. if (hr == S_OK) {
  924. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  925. if (value) {
  926. l_TraceSettings |= WSB_TRACE_BIT_DATARECALLER;
  927. }
  928. }
  929. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_DATAVERIFIER,
  930. dataString, 100, &sizeGot);
  931. if (hr == S_OK) {
  932. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  933. if (value) {
  934. l_TraceSettings |= WSB_TRACE_BIT_DATAVERIFIER;
  935. }
  936. }
  937. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_UI,
  938. dataString, 100, &sizeGot);
  939. if (hr == S_OK) {
  940. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  941. if (value) {
  942. l_TraceSettings |= WSB_TRACE_BIT_UI;
  943. }
  944. }
  945. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_ENTRY_EXIT,
  946. dataString, 100, &sizeGot);
  947. if (hr == S_OK) {
  948. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  949. if (value == FALSE) {
  950. l_TraceEntryExit = FALSE;
  951. }
  952. }
  953. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_DATAMOVER,
  954. dataString, 100, &sizeGot);
  955. if (hr == S_OK) {
  956. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  957. if (value) {
  958. l_TraceSettings |= WSB_TRACE_BIT_DATAMOVER;
  959. }
  960. }
  961. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_HSMCONN,
  962. dataString, 100, &sizeGot);
  963. if (hr == S_OK) {
  964. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  965. if (value) {
  966. l_TraceSettings |= WSB_TRACE_BIT_HSMCONN;
  967. }
  968. }
  969. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_IDB,
  970. dataString, 100, &sizeGot);
  971. if (hr == S_OK) {
  972. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  973. if (value) {
  974. l_TraceSettings |= WSB_TRACE_BIT_IDB;
  975. }
  976. }
  977. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_COPYMEDIA,
  978. dataString, 100, &sizeGot);
  979. if (hr == S_OK) {
  980. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  981. if (value) {
  982. l_TraceSettings |= WSB_TRACE_BIT_COPYMEDIA;
  983. }
  984. }
  985. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_DO_PERSISTENCE,
  986. dataString, 100, &sizeGot);
  987. if (hr == S_OK) {
  988. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  989. if (value) {
  990. l_TraceSettings |= WSB_TRACE_BIT_PERSISTENCE;
  991. }
  992. }
  993. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_LOG_LEVEL,
  994. dataString, 100, &sizeGot);
  995. if (hr == S_OK) {
  996. w_LogLevel = (WORD)wcstoul( dataString, &stopString, 10 ); // No conversion returns zero!
  997. }
  998. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_LOG_SNAP_SHOT_ON,
  999. dataString, 100, &sizeGot);
  1000. if (hr == S_OK) {
  1001. b_SnapShotOn = (BOOL) wcstoul( dataString, &stopString, 10 );
  1002. }
  1003. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_LOG_SNAP_SHOT_LEVEL,
  1004. dataString, 100, &sizeGot);
  1005. if (hr == S_OK) {
  1006. w_SnapShotLevel = (WORD) wcstoul( dataString, &stopString, 10 );
  1007. }
  1008. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_LOG_SNAP_SHOT_PATH,
  1009. dataString, 512, &sizeGot);
  1010. if (hr == S_OK) {
  1011. p_SnapShotPath = dataString;
  1012. }
  1013. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_LOG_SNAP_SHOT_RESET_TRACE,
  1014. dataString, 100, &sizeGot);
  1015. if (hr == S_OK) {
  1016. b_SnapShotResetTrace = (BOOL) wcstoul( dataString, &stopString, 10 );
  1017. }
  1018. hr = S_OK;
  1019. WsbAffirmHr(SetTraceSettings(l_TraceSettings));
  1020. WsbAffirmHr(SetTraceEntryExit(l_TraceEntryExit));
  1021. WsbAffirmHr(SetLogLevel(w_LogLevel));
  1022. WsbAffirmHr(SetLogSnapShot(b_SnapShotOn, w_SnapShotLevel,
  1023. p_SnapShotPath, b_SnapShotResetTrace ));
  1024. } WsbCatch( hr );
  1025. return( hr );
  1026. }
  1027. HRESULT
  1028. CWsbTrace::LoadOutputDestinations(
  1029. void
  1030. )
  1031. /*++
  1032. Implements:
  1033. IWsbTrace::LoadOutputDestinations
  1034. --*/
  1035. {
  1036. HRESULT hr = S_OK;
  1037. try {
  1038. DWORD sizeGot;
  1039. OLECHAR dataString[100];
  1040. OLECHAR *stopString;
  1041. BOOL value = FALSE;
  1042. ULONG l_TraceOutput = WSB_TRACE_OUT_NONE;
  1043. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_TO_STDOUT,
  1044. dataString, 100, &sizeGot);
  1045. if (hr == S_OK) {
  1046. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  1047. if (value) {
  1048. l_TraceOutput = l_TraceOutput | WSB_TRACE_OUT_STDOUT;
  1049. }
  1050. }
  1051. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_TO_DEBUG,
  1052. dataString, 100, &sizeGot);
  1053. if (hr == S_OK) {
  1054. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  1055. if (value) {
  1056. l_TraceOutput = l_TraceOutput | WSB_TRACE_OUT_DEBUG_SCREEN;
  1057. }
  1058. }
  1059. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_TO_FILE,
  1060. dataString, 100, &sizeGot);
  1061. if (hr == S_OK) {
  1062. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  1063. if (value) {
  1064. l_TraceOutput = l_TraceOutput | WSB_TRACE_OUT_FILE;
  1065. }
  1066. }
  1067. hr = S_OK;
  1068. WsbAffirmHr(DirectOutput(l_TraceOutput));
  1069. } WsbCatch( hr );
  1070. return( hr );
  1071. }
  1072. HRESULT
  1073. CWsbTrace::LoadFormat(
  1074. void
  1075. )
  1076. /*++
  1077. Implements:
  1078. IWsbTrace::LoadFormat
  1079. --*/
  1080. {
  1081. HRESULT hr = S_OK;
  1082. try {
  1083. DWORD sizeGot;
  1084. OLECHAR dataString[100];
  1085. OLECHAR *stopString;
  1086. BOOL countValue = FALSE;
  1087. BOOL timeValue = FALSE;
  1088. BOOL threadValue = FALSE;
  1089. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_COUNT,
  1090. dataString, 100, &sizeGot);
  1091. if (hr == S_OK) {
  1092. countValue = (BOOL) wcstoul( dataString, &stopString, 10 );
  1093. }
  1094. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_TIMESTAMP,
  1095. dataString, 100, &sizeGot);
  1096. if (hr == S_OK) {
  1097. timeValue = (BOOL) wcstoul( dataString, &stopString, 10 );
  1098. }
  1099. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_THREADID,
  1100. dataString, 100, &sizeGot);
  1101. if (hr == S_OK) {
  1102. threadValue = (BOOL) wcstoul( dataString, &stopString, 10 );
  1103. }
  1104. hr = S_OK;
  1105. WsbAffirmHr(SetOutputFormat(timeValue, countValue, threadValue));
  1106. } WsbCatch( hr );
  1107. return( hr );
  1108. }
  1109. HRESULT
  1110. CWsbTrace::SetTraceEntryExit(
  1111. BOOL traceEntryExit
  1112. )
  1113. /*++
  1114. Implements:
  1115. IWsbTrace::SetTraceEntryExit
  1116. --*/
  1117. {
  1118. HRESULT hr = S_OK;
  1119. g_WsbTraceEntryExit = traceEntryExit;
  1120. m_TraceEntryExit = traceEntryExit;
  1121. return( hr );
  1122. }
  1123. HRESULT
  1124. CWsbTrace::GetTraceEntryExit(
  1125. BOOL *pTraceEntryExit
  1126. )
  1127. /*++
  1128. Implements:
  1129. IWsbTrace::GetTraceEntryExit
  1130. --*/
  1131. {
  1132. HRESULT hr = S_OK;
  1133. try {
  1134. WsbAssert(0 != pTraceEntryExit, E_POINTER);
  1135. *pTraceEntryExit = m_TraceEntryExit;
  1136. } WsbCatch( hr );
  1137. return( hr );
  1138. }
  1139. HRESULT
  1140. CWsbTrace::SetLogLevel(
  1141. WORD logLevel
  1142. )
  1143. /*++
  1144. Implements:
  1145. IWsbTrace::SetLogLevel
  1146. --*/
  1147. {
  1148. HRESULT hr = S_OK;
  1149. g_WsbLogLevel = logLevel;
  1150. m_LogLevel = logLevel;
  1151. return( hr );
  1152. }
  1153. HRESULT
  1154. CWsbTrace::GetLogLevel(
  1155. WORD *pLogLevel
  1156. )
  1157. /*++
  1158. Implements:
  1159. IWsbTrace::GetLogLevel
  1160. --*/
  1161. {
  1162. HRESULT hr = S_OK;
  1163. try {
  1164. WsbAssert(0 != pLogLevel, E_POINTER);
  1165. *pLogLevel = m_LogLevel;
  1166. } WsbCatch( hr );
  1167. return( hr );
  1168. }
  1169. HRESULT
  1170. CWsbTrace::SetLogSnapShot(
  1171. BOOL on,
  1172. WORD level,
  1173. OLECHAR *snapShotPath,
  1174. BOOL resetTrace
  1175. )
  1176. /*++
  1177. Implements:
  1178. IWsbTrace::SetLogSnapShot
  1179. --*/
  1180. {
  1181. HRESULT hr = S_OK;
  1182. g_WsbLogSnapShotOn = on;
  1183. g_WsbLogSnapShotLevel = level;
  1184. if (snapShotPath != 0) {
  1185. wcscpy(g_pWsbLogSnapShotPath, snapShotPath);
  1186. }
  1187. g_WsbLogSnapShotResetTrace = resetTrace;
  1188. return( hr );
  1189. }
  1190. HRESULT
  1191. CWsbTrace::GetLogSnapShot(
  1192. BOOL *pOn,
  1193. WORD *pLevel,
  1194. OLECHAR **pSnapShotPath,
  1195. BOOL *pResetTrace
  1196. )
  1197. /*++
  1198. Implements:
  1199. IWsbTrace::GetLogSnapShot
  1200. --*/
  1201. {
  1202. HRESULT hr = S_OK;
  1203. try {
  1204. WsbAssert(0 != pOn, E_POINTER);
  1205. WsbAssert(0 != pLevel, E_POINTER);
  1206. WsbAssert(0 != pSnapShotPath, E_POINTER);
  1207. WsbAssert(0 != pResetTrace, E_POINTER);
  1208. *pOn = g_WsbLogSnapShotOn;
  1209. CWsbStringPtr path;
  1210. path = g_pWsbLogSnapShotPath;
  1211. path.GiveTo(pSnapShotPath);
  1212. *pLevel = g_WsbLogSnapShotLevel;
  1213. *pResetTrace = g_WsbLogSnapShotResetTrace;
  1214. } WsbCatch( hr );
  1215. return( hr );
  1216. }
  1217. HRESULT
  1218. CWsbTrace::LoadStart(
  1219. void
  1220. )
  1221. /*++
  1222. Implements:
  1223. IWsbTrace::LoadStart
  1224. --*/
  1225. {
  1226. HRESULT hr = S_OK;
  1227. try {
  1228. DWORD sizeGot;
  1229. OLECHAR dataString[100];
  1230. OLECHAR *stopString;
  1231. BOOL value = FALSE;
  1232. hr = WsbGetRegistryValueString(NULL, m_RegistrySetting, WSB_TRACE_ON,
  1233. dataString, 100, &sizeGot);
  1234. if (hr == S_OK) {
  1235. value = (BOOL) wcstoul( dataString, &stopString, 10 );
  1236. if (value) {
  1237. StartTrace();
  1238. } else {
  1239. StopTrace();
  1240. }
  1241. }
  1242. hr = S_OK;
  1243. } WsbCatch( hr );
  1244. return( hr );
  1245. }
  1246. // Write - write a WCHAR string to the output file as multibyte chars.
  1247. HRESULT
  1248. CWsbTrace::Write(
  1249. OLECHAR *pString
  1250. )
  1251. {
  1252. HRESULT hr = S_OK;
  1253. const int safe_size = 1024;
  1254. static char buf[safe_size + 16];
  1255. try {
  1256. int nbytes;
  1257. int nchars_todo;
  1258. int nchars_remaining;
  1259. OLECHAR *pSource;
  1260. OLECHAR *pTest;
  1261. BOOL needToAddReturn = FALSE;
  1262. CWsbStringPtr endOfLine("\r\n");
  1263. // Get the total number of chars. in the string
  1264. pSource = pString;
  1265. nchars_remaining = wcslen(pSource);
  1266. pTest = (pString + nchars_remaining - 1);
  1267. //
  1268. // Make sure that if this is a terminating line
  1269. // that it is a \r\n termination not just a
  1270. // \n.
  1271. //
  1272. if (*pTest == '\n') {
  1273. pTest--;
  1274. if (*pTest != '\r') {
  1275. needToAddReturn = TRUE;
  1276. nchars_remaining--;
  1277. }
  1278. }
  1279. // Loop until all chars. are written
  1280. while (nchars_remaining) {
  1281. DWORD bytesWritten;
  1282. if (nchars_remaining * sizeof(OLECHAR) > safe_size) {
  1283. nchars_todo = safe_size / sizeof(OLECHAR);
  1284. } else {
  1285. nchars_todo = nchars_remaining;
  1286. }
  1287. // Convert characters from wide to narrow
  1288. do {
  1289. nbytes = wcstombs(buf, pSource, nchars_todo);
  1290. if (nbytes <= 0) {
  1291. // Hit a bad character; try fewer characters
  1292. nchars_todo /= 2;
  1293. if (0 == nchars_todo) {
  1294. // Skip the next character
  1295. nchars_todo = 1;
  1296. nbytes = 1;
  1297. buf[0] = '?';
  1298. }
  1299. }
  1300. } while (nbytes <= 0);
  1301. WsbAffirm(WriteFile(m_TraceFilePointer, buf, nbytes,
  1302. &bytesWritten, NULL), E_FAIL);
  1303. WsbAffirm(static_cast<int>(bytesWritten) == nbytes, E_FAIL);
  1304. nchars_remaining -= nchars_todo;
  1305. pSource += nchars_todo;
  1306. }
  1307. if (needToAddReturn) {
  1308. DWORD bytesWritten;
  1309. nbytes = wcstombs(buf, (OLECHAR *)endOfLine, 2);
  1310. WsbAffirm(nbytes > 0, E_FAIL);
  1311. WsbAffirm(WriteFile(m_TraceFilePointer, buf, nbytes,
  1312. &bytesWritten, NULL), E_FAIL);
  1313. WsbAffirm(static_cast<int>(bytesWritten) == nbytes, E_FAIL);
  1314. }
  1315. } WsbCatch( hr );
  1316. return( hr );
  1317. }
  1318. HRESULT
  1319. CWsbTrace::SetTraceSettings(
  1320. LONGLONG traceElements
  1321. )
  1322. /*++
  1323. Implements:
  1324. IWsbTrace::SetTraceSettings
  1325. --*/
  1326. {
  1327. HRESULT hr = S_OK;
  1328. try
  1329. {
  1330. g_WsbTraceModules = traceElements;
  1331. m_TraceSettings = g_WsbTraceModules;
  1332. } WsbCatch( hr );
  1333. return( hr );
  1334. }