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.

878 lines
25 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Abstract:
  4. Implementation of stock Log Providers.
  5. Author:
  6. Souren Aghajanyan (sourenag) 24-Sep-2001
  7. Revision History:
  8. <alias> <date> <comments>
  9. --*/
  10. #include "pch.h"
  11. #include "log_man.h"
  12. #include "stockpr.h"
  13. #include "mem.h"
  14. BOOL
  15. pFieldValidation(
  16. IN ILogContext * pLogContext,
  17. IN PFIELD_VALIDATION_DATA StructArray,
  18. IN UINT ArraySize
  19. )
  20. {
  21. ASSERT(pLogContext && StructArray && ArraySize);
  22. for(UINT i = 0; i < ArraySize; i++){
  23. BOOL bMandatoryField = StructArray[i].Mandatory;
  24. if(!StructArray[i].FieldName){
  25. if(bMandatoryField){
  26. return FALSE;
  27. }
  28. continue;
  29. }
  30. if(pLogContext->GetFieldIndexFromName(StructArray[i].FieldName,
  31. StructArray[i].FieldIndexPtr)){
  32. PLOG_FIELD_VALUE pValue = pLogContext->GetFieldValue(*StructArray[i].FieldIndexPtr);
  33. if(!pValue || StructArray[i].Type != pValue->Value.Type){
  34. ASSERT(pValue && StructArray[i].Type == pValue->Value.Type);
  35. return FALSE;
  36. }
  37. }
  38. else{
  39. if(bMandatoryField){
  40. return FALSE;
  41. }
  42. }
  43. }
  44. return TRUE;
  45. }
  46. PCWSTR
  47. pGetStandardLogSeverityString(
  48. IN DWORD dwSeverity
  49. )
  50. {
  51. PCWSTR pSeverity;
  52. switch(dwSeverity){
  53. case LOG_ASSERT:
  54. pSeverity = L"Assert";
  55. break;
  56. case LOG_FATAL_ERROR:
  57. pSeverity = L"FatalError";
  58. break;
  59. case LOG_ERROR:
  60. pSeverity = L"Error";
  61. break;
  62. case LOG_WARNING:
  63. pSeverity = L"Warning";
  64. break;
  65. case DBG_INFO:
  66. case LOG_INFO:
  67. pSeverity = L"Info";
  68. break;
  69. case DBG_ASSERT:
  70. pSeverity = L"Assert";
  71. break;
  72. case DBG_NAUSEA:
  73. pSeverity = L"Nausea";
  74. break;
  75. case DBG_VERBOSE:
  76. pSeverity = L"Nausea";
  77. break;
  78. case DBG_STATS:
  79. pSeverity = L"Stats";
  80. break;
  81. case DBG_WARNING:
  82. pSeverity = L"Warning";
  83. break;
  84. case DBG_ERROR:
  85. pSeverity = L"Error";
  86. break;
  87. case DBG_WHOOPS:
  88. pSeverity = L"Whoops";
  89. break;
  90. case DBG_TRACK:
  91. pSeverity = L"Track";
  92. break;
  93. case DBG_TIME:
  94. pSeverity = L"Time";
  95. break;
  96. default:
  97. ASSERT(FALSE);
  98. pSeverity = L"UndefinedLogType";
  99. }
  100. return pSeverity;
  101. }
  102. BOOL
  103. pIsLogSeverityCorrect(
  104. IN DWORD dwSeverity,
  105. OUT BOOL * pbDebugType
  106. )
  107. {
  108. BOOL bDebugType = FALSE;
  109. switch(dwSeverity){
  110. case LOG_ASSERT:
  111. case LOG_FATAL_ERROR:
  112. case LOG_ERROR:
  113. case LOG_WARNING:
  114. case LOG_INFO:
  115. bDebugType = FALSE;
  116. break;
  117. case DBG_ASSERT:
  118. case DBG_NAUSEA:
  119. case DBG_INFO:
  120. case DBG_VERBOSE:
  121. case DBG_STATS:
  122. case DBG_WARNING:
  123. case DBG_ERROR:
  124. case DBG_WHOOPS:
  125. case DBG_TRACK:
  126. case DBG_TIME:
  127. bDebugType = TRUE;
  128. break;
  129. default:
  130. ASSERT(FALSE);
  131. return FALSE;
  132. }
  133. if(pbDebugType){
  134. *pbDebugType = bDebugType;
  135. }
  136. return TRUE;
  137. }
  138. CStandardSetupLogFilter::CStandardSetupLogFilter(
  139. VOID
  140. )
  141. {
  142. m_uiSeverityFieldNumber = UNDEFINED_FIELD_INDEX;
  143. m_SeverityThreshold = LOG_INFO;
  144. m_bSuppressDebugMessages = TRUE;
  145. }
  146. LOGRESULT
  147. CStandardSetupLogFilter::Init(
  148. IN PVOID pvCustomData,
  149. IN ILogContext * pLogContext
  150. )
  151. {
  152. UINT uiFieldIndex;
  153. if(!pvCustomData){
  154. return logOk;
  155. }
  156. PCWSTR pFieldName = ((PLOG_SETUPLOG_FILTER_PROV_INIT_DATA)pvCustomData)->FieldName;
  157. if(!pFieldName){
  158. return logError;
  159. }
  160. if(!pLogContext->GetFieldIndexFromName(pFieldName, &uiFieldIndex)){
  161. return logError;
  162. }
  163. m_uiSeverityFieldNumber = uiFieldIndex;
  164. PLOG_FIELD_VALUE pValue = pLogContext->GetFieldValue(uiFieldIndex);
  165. if(!pValue || LT_DWORD != pValue->Value.Type){
  166. ASSERT(pValue && LT_DWORD == pValue->Value.Type);
  167. return logError;
  168. }
  169. if(!pIsLogSeverityCorrect(((PLOG_SETUPLOG_FILTER_PROV_INIT_DATA)pvCustomData)->SeverityThreshold, NULL)){
  170. return logError;
  171. }
  172. m_SeverityThreshold = ((PLOG_SETUPLOG_FILTER_PROV_INIT_DATA)pvCustomData)->SeverityThreshold;
  173. m_bSuppressDebugMessages = ((PLOG_SETUPLOG_FILTER_PROV_INIT_DATA)pvCustomData)->SuppressDebugMessages;
  174. return logOk;
  175. }
  176. LOGRESULT
  177. CStandardSetupLogFilter::Process(ILogContext * pLogContext)
  178. {
  179. if(m_uiSeverityFieldNumber == UNDEFINED_FIELD_INDEX){
  180. return logOk;
  181. }
  182. DWORD dwSeverityLevel = pLogContext->GetFieldValue(m_uiSeverityFieldNumber)->Value.Dword;
  183. ASSERT(LT_DWORD == pLogContext->GetFieldValue(m_uiSeverityFieldNumber)->Value.Type);
  184. BOOL bDbg;
  185. if(!pIsLogSeverityCorrect(dwSeverityLevel, &bDbg)){
  186. return logError;
  187. }
  188. if(bDbg){
  189. if(m_bSuppressDebugMessages){
  190. return logDoNotContinue;
  191. }
  192. }
  193. else{
  194. if(((LOG_SETUPLOG_SEVERITY)dwSeverityLevel) > m_SeverityThreshold){
  195. return logDoNotContinue;
  196. }
  197. }
  198. return logOk;
  199. }
  200. CStandardSetupLogFormatter::CStandardSetupLogFormatter(
  201. VOID
  202. )
  203. {
  204. m_uiSeverityFieldNumber = UNDEFINED_FIELD_INDEX;
  205. m_uiMessageFieldNumber = UNDEFINED_FIELD_INDEX;
  206. }
  207. LOGRESULT
  208. CStandardSetupLogFormatter::Init(
  209. IN PVOID pvCustomData,
  210. IN ILogContext * pLogContext
  211. )
  212. {
  213. ASSERT(pLogContext);
  214. if(!pvCustomData){
  215. return logError;
  216. }
  217. {
  218. FIELD_VALIDATION_DATA
  219. fieldsInfo[] = {
  220. {
  221. ((PLOG_SETUPLOG_FORMAT_PROV_INIT_DATA)pvCustomData)->SeverityFieldName,
  222. LT_DWORD,
  223. &m_uiSeverityFieldNumber,
  224. FALSE
  225. },
  226. {
  227. ((PLOG_SETUPLOG_FORMAT_PROV_INIT_DATA)pvCustomData)->MessageFieldName,
  228. LT_SZ,
  229. &m_uiMessageFieldNumber,
  230. TRUE
  231. }
  232. };
  233. if(!pFieldValidation(pLogContext, fieldsInfo, sizeof(fieldsInfo) / sizeof(fieldsInfo[0]))){
  234. return logError;
  235. };
  236. }
  237. if(!pLogContext->PreAllocBuffer(DEFAULT_MEMORY_SIZE, 0)){
  238. return logError;
  239. }
  240. return logOk;
  241. }
  242. LOGRESULT
  243. CStandardSetupLogFormatter::Process(
  244. IN ILogContext * pLogContext
  245. )
  246. {
  247. PCWSTR pMessage;
  248. PCWSTR pSeverity;
  249. UINT size;
  250. ASSERT(UNDEFINED_FIELD_INDEX == m_uiSeverityFieldNumber || (LT_DWORD == pLogContext->GetFieldValue(m_uiSeverityFieldNumber)->Value.Type));
  251. ASSERT(LT_SZ == pLogContext->GetFieldValue(m_uiMessageFieldNumber)->Value.Type);
  252. pMessage = pLogContext->GetFieldValue(m_uiMessageFieldNumber)->Value.String;
  253. if(!pMessage){
  254. ASSERT(pMessage);
  255. return logError;
  256. }
  257. size = wcslen(pMessage);
  258. pSeverity = NULL;
  259. if(UNDEFINED_FIELD_INDEX != m_uiSeverityFieldNumber){
  260. ASSERT(LT_DWORD == pLogContext->GetFieldValue(m_uiSeverityFieldNumber)->Value.Type);
  261. pSeverity = pGetStandardLogSeverityString(
  262. pLogContext->GetFieldValue(m_uiSeverityFieldNumber)->Value.Dword);
  263. size += wcslen(pSeverity);
  264. }
  265. size += 3;//strlen("/r/n/0");
  266. size *= sizeof(CHAR);
  267. PSTR pBuffer = (PSTR)pLogContext->AllocBuffer(size, NULL);
  268. if(pSeverity){
  269. sprintf(pBuffer, "%-11S %S\r\n", pSeverity, pMessage);
  270. }
  271. else{
  272. sprintf(pBuffer, "%S\r\n", pMessage);
  273. }
  274. pLogContext->ReAllocBuffer(strlen(pBuffer) * sizeof(pBuffer[0]), NULL);
  275. return logOk;
  276. }
  277. CFileDevice::~CFileDevice(
  278. VOID
  279. )
  280. {
  281. m_File.Close();
  282. if(m_pPath){
  283. FREE(m_pPath);
  284. }
  285. }
  286. LOGRESULT
  287. CFileDevice::Init(
  288. IN PVOID pvCustomData,
  289. IN ILogContext * pLogContext
  290. )
  291. {
  292. UINT Size;
  293. BOOL bAlreadyExist;
  294. if(!pvCustomData){
  295. return logError;
  296. }
  297. if(!((PLOG_DEVICE_PROV_INIT_DATA)pvCustomData)->PathName){
  298. return logError;
  299. }
  300. Size = wcslen(((PLOG_DEVICE_PROV_INIT_DATA)pvCustomData)->PathName);
  301. if(!Size){
  302. return logError;
  303. }
  304. bAlreadyExist = FALSE;
  305. if(!m_File.Open(((PLOG_DEVICE_PROV_INIT_DATA)pvCustomData)->PathName,
  306. TRUE,
  307. ((PLOG_DEVICE_PROV_INIT_DATA)pvCustomData)->dwFlags&DEVICE_CREATE_NEW,
  308. ((PLOG_DEVICE_PROV_INIT_DATA)pvCustomData)->dwFlags&DEVICE_WRITE_THROUGH,
  309. &bAlreadyExist)){
  310. return logError;
  311. }
  312. if(m_pPath){
  313. FREE(m_pPath);
  314. }
  315. m_pPath = (PWSTR)MALLOC((Size + 1) * sizeof(m_pPath[0]));
  316. wcscpy(m_pPath, ((PLOG_DEVICE_PROV_INIT_DATA)pvCustomData)->PathName);
  317. // wcslwr(m_pPath);
  318. return bAlreadyExist? logAlreadyExist: logOk;
  319. }
  320. LOGRESULT
  321. CFileDevice::Process(
  322. IN ILogContext * pLogContext
  323. )
  324. {
  325. UINT Size = 0;
  326. PVOID pBuffer = pLogContext->GetBuffer(&Size, NULL);
  327. if(!pBuffer || !Size){
  328. return logContinue;
  329. }
  330. m_File.Append(pBuffer, Size);
  331. return logOk;
  332. }
  333. CDebugFormatterAndDevice::CDebugFormatterAndDevice(
  334. VOID
  335. )
  336. {
  337. m_uiSeverityFieldNumber = UNDEFINED_FIELD_INDEX;
  338. m_uiMessageFieldNumber = UNDEFINED_FIELD_INDEX;
  339. m_uiConditionFieldNumber = UNDEFINED_FIELD_INDEX;
  340. m_uiSourceLineFieldNumber = UNDEFINED_FIELD_INDEX;
  341. m_uiSourceFileFieldNumber = UNDEFINED_FIELD_INDEX;
  342. m_uiSourceFunctionFieldNumber = UNDEFINED_FIELD_INDEX;
  343. }
  344. LOGRESULT
  345. CDebugFormatterAndDevice::Init(
  346. IN PVOID pvCustomData,
  347. IN ILogContext * pLogContext
  348. )
  349. {
  350. ASSERT(pLogContext);
  351. if(!pvCustomData){
  352. return logError;
  353. }
  354. {
  355. FIELD_VALIDATION_DATA
  356. fieldsInfo[] = {
  357. {
  358. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->SeverityFieldName,
  359. LT_DWORD,
  360. &m_uiSeverityFieldNumber,
  361. FALSE
  362. },
  363. {
  364. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->MessageFieldName,
  365. LT_SZ,
  366. &m_uiMessageFieldNumber,
  367. TRUE
  368. },
  369. {
  370. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->ConditionFieldName,
  371. LT_SZ,
  372. &m_uiConditionFieldNumber,
  373. FALSE
  374. },
  375. {
  376. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->SourceLineFieldName,
  377. LT_DWORD,
  378. &m_uiSourceLineFieldNumber,
  379. FALSE
  380. },
  381. {
  382. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->SourceFileFieldName,
  383. LT_SZ,
  384. &m_uiSourceFileFieldNumber,
  385. FALSE
  386. },
  387. {
  388. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->SourceFunctionFieldName,
  389. LT_SZ,
  390. &m_uiSourceFunctionFieldNumber,
  391. FALSE
  392. },
  393. };
  394. if(!pFieldValidation(pLogContext, fieldsInfo, sizeof(fieldsInfo) / sizeof(fieldsInfo[0]))){
  395. return logError;
  396. }
  397. }
  398. if(!pLogContext->PreAllocBuffer(DEFAULT_MEMORY_SIZE, 0)){
  399. return logError;
  400. }
  401. return logOk;
  402. }
  403. LOGRESULT CDebugFormatterAndDevice::Process(
  404. IN ILogContext * pLogContext
  405. )
  406. {
  407. PCWSTR pMessage;
  408. PCWSTR pSeverity;
  409. PCWSTR pFileName;
  410. PCWSTR pFunctionName;
  411. PCWSTR pCondition = NULL;
  412. DWORD dwSourceLineNumber;
  413. UINT size;
  414. BOOL bAssert = FALSE;
  415. pMessage = pLogContext->GetFieldValue(m_uiMessageFieldNumber)->Value.String;
  416. if(!pMessage){
  417. ASSERT(pMessage);
  418. return logError;
  419. }
  420. size = wcslen(pMessage);
  421. if(UNDEFINED_FIELD_INDEX != m_uiSeverityFieldNumber){
  422. ASSERT(LT_DWORD == pLogContext->GetFieldValue(m_uiSeverityFieldNumber)->Value.Type);
  423. DWORD dwSeverityLevel = pLogContext->GetFieldValue(m_uiSeverityFieldNumber)->Value.Dword;
  424. pSeverity = pGetStandardLogSeverityString(dwSeverityLevel);
  425. if(LOG_ASSERT == dwSeverityLevel ||
  426. DBG_ASSERT == dwSeverityLevel){
  427. pCondition = pLogContext->GetFieldValue(m_uiConditionFieldNumber)->Value.String;
  428. bAssert = TRUE;
  429. if(pCondition){
  430. size += wcslen(pSeverity);
  431. }
  432. else{
  433. ASSERT(pCondition);
  434. }
  435. }
  436. size += wcslen(pSeverity);
  437. }
  438. pFunctionName = pLogContext->GetFieldValue(m_uiSourceFunctionFieldNumber)->Value.String;
  439. pFileName = pLogContext->GetFieldValue(m_uiSourceFileFieldNumber)->Value.String;
  440. if(pFileName){
  441. size += wcslen(pFileName);
  442. if(pFunctionName){
  443. size += wcslen(pFunctionName);
  444. }
  445. }
  446. size += DEBUG_STRING_DEFAULT_PADDING_SIZE;//strlen("(%d) : /r/n/t/r/n/0");
  447. size *= sizeof(CHAR);
  448. PSTR pBuffer = (PSTR)pLogContext->AllocBuffer(size, NULL);
  449. pBuffer[0] = '\0';
  450. dwSourceLineNumber = pLogContext->GetFieldValue(m_uiSourceLineFieldNumber)->Value.Dword;
  451. if(pFileName){
  452. if(pFunctionName){
  453. sprintf(pBuffer, "%S(%d) : %S\r\n\t", pFileName, dwSourceLineNumber, pFunctionName);
  454. }
  455. else{
  456. sprintf(pBuffer, "%S(%d) : ", pFileName, dwSourceLineNumber);
  457. }
  458. }
  459. if(pSeverity){
  460. if(pCondition){
  461. sprintf(pBuffer, "%s%-S(%S)\t%S\r\n", pBuffer, pSeverity, pCondition, pMessage);
  462. }
  463. else{
  464. sprintf(pBuffer, "%s%-20S%S\r\n", pBuffer, pSeverity, pMessage);
  465. }
  466. }
  467. else{
  468. sprintf(pBuffer, "%s%S\r\n", pBuffer, pMessage);
  469. }
  470. OutputDebugStringA(pBuffer);
  471. pLogContext->FreeBuffer();
  472. return logDoNotContinue;
  473. }
  474. CDebugFilter::CDebugFilter(
  475. VOID
  476. )
  477. {
  478. m_uiSeverityFieldNumber = UNDEFINED_FIELD_INDEX;
  479. m_uiMessageFieldNumber = UNDEFINED_FIELD_INDEX;
  480. m_uiConditionFieldNumber = UNDEFINED_FIELD_INDEX;
  481. m_uiSourceLineFieldNumber = UNDEFINED_FIELD_INDEX;
  482. m_uiSourceFileFieldNumber = UNDEFINED_FIELD_INDEX;
  483. m_uiSourceFunctionFieldNumber = UNDEFINED_FIELD_INDEX;
  484. if(!GetModuleFileNameA(NULL, m_ProgramName, MAX_PATH)){
  485. strcpy(m_ProgramName, "<program name unknown>");
  486. }
  487. }
  488. LOGRESULT
  489. CDebugFilter::Init(
  490. IN PVOID pvCustomData,
  491. IN ILogContext * pLogContext
  492. )
  493. {
  494. ASSERT(pLogContext);
  495. if(!pvCustomData){
  496. return logError;
  497. }
  498. {
  499. // PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA initStruct =
  500. // (PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData;
  501. FIELD_VALIDATION_DATA
  502. fieldsInfo[] = {
  503. {
  504. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->SeverityFieldName,
  505. LT_DWORD,
  506. &m_uiSeverityFieldNumber,
  507. TRUE
  508. },
  509. {
  510. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->MessageFieldName,
  511. LT_SZ,
  512. &m_uiMessageFieldNumber,
  513. TRUE
  514. },
  515. {
  516. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->ConditionFieldName,
  517. LT_SZ,
  518. &m_uiConditionFieldNumber,
  519. FALSE
  520. },
  521. {
  522. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->SourceLineFieldName,
  523. LT_DWORD,
  524. &m_uiSourceLineFieldNumber,
  525. FALSE
  526. },
  527. {
  528. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->SourceFileFieldName,
  529. LT_SZ,
  530. &m_uiSourceFileFieldNumber,
  531. FALSE
  532. },
  533. {
  534. ((PLOG_DEBUG_FORMAT_AND_DEVICE_PROV_INIT_DATA)pvCustomData)->SourceFunctionFieldName,
  535. LT_SZ,
  536. &m_uiSourceFunctionFieldNumber,
  537. FALSE
  538. },
  539. };
  540. if(!pFieldValidation(pLogContext, fieldsInfo, sizeof(fieldsInfo) / sizeof(fieldsInfo[0]))){
  541. return logError;
  542. }
  543. }
  544. if(!pLogContext->AllocBuffer(DEFAULT_MEMORY_SIZE, 0)){
  545. return logError;
  546. }
  547. return logOk;
  548. }
  549. LOGRESULT
  550. CDebugFilter::Process(
  551. IN ILogContext * pLogContext
  552. )
  553. {
  554. PCWSTR pMessage;
  555. PCWSTR pSeverity;
  556. PCWSTR pFileName;
  557. PCWSTR pFunctionName;
  558. PCWSTR pCondition = NULL;
  559. DWORD dwSourceLineNumber;
  560. UINT size;
  561. BOOL bAssert = FALSE;
  562. LOGRESULT result;
  563. pMessage = pLogContext->GetFieldValue(m_uiMessageFieldNumber)->Value.String;
  564. if(!pMessage){
  565. ASSERT(pMessage);
  566. return logError;
  567. }
  568. size = wcslen(pMessage);
  569. if(UNDEFINED_FIELD_INDEX == m_uiSeverityFieldNumber){
  570. return logError;
  571. }
  572. ASSERT(LT_DWORD == pLogContext->GetFieldValue(m_uiSeverityFieldNumber)->Value.Type);
  573. DWORD dwSeverityLevel = pLogContext->GetFieldValue(m_uiSeverityFieldNumber)->Value.Dword;
  574. pSeverity = pGetStandardLogSeverityString(dwSeverityLevel);
  575. if(LOG_ASSERT == dwSeverityLevel ||
  576. DBG_ASSERT == dwSeverityLevel){
  577. pCondition = pLogContext->GetFieldValue(m_uiConditionFieldNumber)->Value.String;
  578. bAssert = TRUE;
  579. if(pCondition){
  580. size += wcslen(pSeverity);
  581. }
  582. else{
  583. ASSERT(pCondition);
  584. }
  585. }
  586. size += wcslen(pSeverity);
  587. pFunctionName = pLogContext->GetFieldValue(m_uiSourceFunctionFieldNumber)->Value.String;
  588. pFileName = pLogContext->GetFieldValue(m_uiSourceFileFieldNumber)->Value.String;
  589. if(pFileName){
  590. size += wcslen(pFileName);
  591. if(pFunctionName){
  592. size += wcslen(pFunctionName);
  593. }
  594. }
  595. size += DEBUG_STRING_DEFAULT_PADDING_SIZE;
  596. size *= sizeof(CHAR);
  597. PSTR pBuffer = (PSTR)pLogContext->AllocBuffer(size, NULL);
  598. pBuffer[0] = '\0';
  599. dwSourceLineNumber = pLogContext->GetFieldValue(m_uiSourceLineFieldNumber)->Value.Dword;
  600. if(_snprintf(pBuffer, size,
  601. "Debug %s!%S%S\n\nProgram: %s%S%S%S%d%S%S%S%S%S"
  602. "\n\n(Press Retry to debug the application)",
  603. "Assertion Failed",
  604. pMessage? L"\n\n": L"",
  605. pMessage? pMessage: L"",
  606. m_ProgramName,
  607. pFileName? L"\nFile: ": L"",
  608. pFileName? pFileName: L"",
  609. dwSourceLineNumber ? L"\nLine: ": L"",
  610. dwSourceLineNumber,
  611. pFunctionName? L"\nFunction: ": L"",
  612. pFunctionName? pFunctionName: L"",
  613. pCondition? L"\n\n": L"",
  614. pCondition? L"Expression: ": L"",
  615. pCondition? pCondition : L"") < 0){
  616. strcpy(pBuffer, "Too Long Message");
  617. }
  618. if(bAssert){
  619. result = ShowAssert(pBuffer);
  620. }
  621. else{
  622. result = logContinue;
  623. }
  624. pLogContext->FreeBuffer();
  625. return result;
  626. }
  627. LOGRESULT
  628. CDebugFilter::ShowAssert(
  629. IN PCSTR pMessage
  630. )
  631. {
  632. HWND hWndParent = GetActiveWindow();
  633. if(hWndParent != NULL){
  634. hWndParent = GetLastActivePopup(hWndParent);
  635. }
  636. MSG msg;
  637. BOOL bQuit = PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
  638. int res = MessageBoxA(hWndParent,
  639. pMessage,
  640. "Assertion Failed!",
  641. MB_TASKMODAL | MB_ICONHAND | MB_ABORTRETRYIGNORE | MB_SETFOREGROUND);
  642. if(bQuit){
  643. PostQuitMessage((INT) msg.wParam);
  644. }
  645. if(IDIGNORE == res){
  646. return logContinue;
  647. }
  648. if(IDRETRY == res){
  649. return logBreakPoint;
  650. }
  651. return logAbortProcess;
  652. }
  653. LOGRESULT
  654. CXMLLogFormatter::Init(
  655. IN PVOID pvCustomData,
  656. IN ILogContext * pLogContext
  657. )
  658. {
  659. strcpy(m_xmlDataFormatString, "<z:row");
  660. for(UINT i = 0, iLen = pLogContext->GetFieldsCount(); i < iLen; i++){
  661. PLOG_FIELD_VALUE pField = pLogContext->GetFieldValue(i);
  662. if(0 > _snprintf(m_xmlDataFormatString,
  663. sizeof(m_xmlDataFormatString) / sizeof(m_xmlDataFormatString[0]),
  664. "%s %S=\"%%%c\"",
  665. m_xmlDataFormatString,
  666. pField->Name,
  667. (LT_DWORD == pField->Value.Type)? 'd': 'S')){
  668. return logError;
  669. }
  670. }
  671. strcat(m_xmlDataFormatString, "/>\n");
  672. return logOk;
  673. }
  674. LOGRESULT
  675. CXMLLogFormatter::WriteHeader(
  676. IN PVOID pvCustomData,
  677. IN ILogContext * pLogContext
  678. )
  679. {
  680. ASSERT(pLogContext);
  681. CHAR * xmlHeader = (CHAR *)pLogContext->AllocBuffer(XML_HEADER_INITIAL_SIZE, 0);//BUG
  682. strcpy(xmlHeader, "<xml xmlns:s=\"uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882\"\n xmlns:dt=\"uuid:C2F41010-65B3-11d1-A29F-00AA00C14882\"\n xmlns:rs=\"urn:schemas-microsoft-com:rowset\"\n xmlns:z=\"#RowsetSchema\">\n");
  683. strcat(xmlHeader, "<s:Schema id=\"RowsetSchema\">\n");
  684. strcat(xmlHeader, "<s:ElementType name=\"row\" content=\"eltOnly\" rs:updatable=\"true\">\n");
  685. for(UINT i = 0, iLen = pLogContext->GetFieldsCount(); i < iLen; i++){
  686. PLOG_FIELD_VALUE pField = pLogContext->GetFieldValue(i);
  687. sprintf(xmlHeader,
  688. "%s<s:AttributeType name=\"%S\" rs:number=\"%d\">\n""<s:datatype dt:type=\"%s\"/>\n""</s:AttributeType>\n",
  689. xmlHeader, pField->Name, i,
  690. (LT_DWORD == pField->Value.Type)? "int": "string");
  691. }
  692. strcat(xmlHeader, "</s:ElementType>\n");
  693. strcat(xmlHeader, "</s:Schema>\n");
  694. strcat(xmlHeader, "<rs:data>\n");
  695. pLogContext->ReAllocBuffer(strlen(xmlHeader), 0);
  696. return logOk;
  697. }
  698. LOGRESULT
  699. CXMLLogFormatter::Process(
  700. IN ILogContext * pLogContext
  701. )
  702. {
  703. CHAR * xmlData = (CHAR *)pLogContext->ReAllocBuffer(XML_HEADER_INITIAL_SIZE, 0);//BUG
  704. PVOID * pValues = (PVOID *)_alloca(pLogContext->GetFieldsCount() * sizeof(PVOID));
  705. for(UINT i = 0, iLen = pLogContext->GetFieldsCount(); i < iLen; i++){
  706. PLOG_FIELD_VALUE pField = pLogContext->GetFieldValue(i);
  707. pValues[i] = pField->Value.PVoid;
  708. }
  709. va_list args = (char *)(pValues);
  710. vsprintf(xmlData, m_xmlDataFormatString, args);
  711. va_end (args);
  712. pLogContext->ReAllocBuffer(strlen(xmlData), 0);
  713. return logOk;
  714. }
  715. VOID
  716. CXMLLogFormatter::PreProcess(
  717. IN ILogContext * pLogContext,
  718. IN BOOL bFirstInstance
  719. )
  720. {
  721. if(bFirstInstance){
  722. WriteHeader(NULL, pLogContext);
  723. }
  724. }
  725. VOID
  726. CXMLLogFormatter::PreDestroy(
  727. IN ILogContext * pLogContext,
  728. IN BOOL bLastInstance
  729. )
  730. {
  731. if(bLastInstance){
  732. #define XML_END_OF_FILE "</rs:data>\n</xml>\n"
  733. PSTR pBuffer = (PSTR)pLogContext->AllocBuffer(strlen(XML_END_OF_FILE) + 1, 0);
  734. strcpy(pBuffer, XML_END_OF_FILE);
  735. pLogContext->ReAllocBuffer(strlen(pBuffer), 0);
  736. }
  737. else{
  738. pLogContext->AllocBuffer(0, 0);
  739. }
  740. }