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.

937 lines
24 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Abstract:
  4. Log Engine implementation.
  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. #define GET_SECTION_PTR(addr, pSharedInfo) (((BYTE *)addr) + pSharedInfo.FirstElementOffset)
  13. #define LOG_MANAGER_MUTEX_DEFAULT_SPIN_COUNT 1000
  14. #define LOGMANAGER_CANNOT_CONVERT_PARAMETER L"Log: Cannot convert to ansi->unicode"
  15. #define LOG_MANAGER_CONVERSION_BUFFER_DEFAULT_SIZE (1<<10)
  16. UINT
  17. GetOffsetForNewItem(
  18. PLOG_SHARED_STRUCTURES_INFO pSharedInfo,
  19. UINT Size
  20. )
  21. {
  22. ASSERT(pSharedInfo && Size);
  23. if(Size > (pSharedInfo->MaxSizeOfMemory - pSharedInfo->SizeOfUsedMemory)){
  24. return 0;
  25. }
  26. pSharedInfo->SizeOfUsedMemory += Size;
  27. return pSharedInfo->FirstElementOffset + pSharedInfo->SizeOfUsedMemory - Size;
  28. }
  29. VOID
  30. UpdateForRemovedItem(
  31. PLOG_SHARED_STRUCTURES_INFO pSharedInfo,
  32. UINT Size
  33. )
  34. {
  35. ASSERT(pSharedInfo && Size);
  36. if(Size > pSharedInfo->SizeOfUsedMemory){
  37. return;
  38. }
  39. pSharedInfo->SizeOfUsedMemory -= Size;
  40. }
  41. BOOL
  42. CLogManager::CreateConversionBuffers(
  43. UINT NumberOfConversionBuffers
  44. )
  45. {
  46. if(!NumberOfConversionBuffers){
  47. ASSERT(NumberOfConversionBuffers);
  48. return FALSE;
  49. }
  50. if(m_ConversionBuffers){
  51. ASSERT(!m_ConversionBuffers);
  52. DestroyConversionBuffers();
  53. }
  54. m_ConversionBuffers = new CBuffer[NumberOfConversionBuffers];
  55. if(!m_ConversionBuffers){
  56. ASSERT(m_ConversionBuffers);
  57. return FALSE;
  58. }
  59. m_ConversionBuffersNumber = NumberOfConversionBuffers;
  60. for(UINT i = 0; i < NumberOfConversionBuffers; i++){
  61. m_ConversionBuffers[i].PreAllocate(LOG_MANAGER_CONVERSION_BUFFER_DEFAULT_SIZE);
  62. }
  63. return TRUE;
  64. }
  65. VOID
  66. CLogManager::DestroyConversionBuffers(
  67. VOID
  68. )
  69. {
  70. if(!m_ConversionBuffers){
  71. return;
  72. }
  73. delete[m_ConversionBuffersNumber] m_ConversionBuffers;
  74. m_ConversionBuffers = NULL;
  75. m_ConversionBuffersNumber = 0;
  76. }
  77. CLogManager::CLogManager() : m_SharedMemory(), m_Mutex(), m_StackList()
  78. {
  79. m_SharedData = NULL;
  80. m_FieldsValue = NULL;
  81. m_FieldsNumber = NULL;
  82. m_ConversionBuffers = NULL;
  83. m_ConversionBuffersNumber = NULL;
  84. }
  85. CLogManager::~CLogManager()
  86. {
  87. Close();
  88. }
  89. BOOL
  90. CLogManager::InitSharedData(
  91. UINT SizeForAllSharedData
  92. )
  93. {
  94. ASSERT(m_SharedData && SizeForAllSharedData > HEADER_SIZE);
  95. memset(m_SharedData, 0, SizeForAllSharedData);
  96. PLOG_SHARED_STRUCTURES_INFO pSharedStructure;
  97. UINT offset;
  98. if(((HEADER_SIZE/SHARED_DATA_STRUCTURE_ALIGMENT) * SHARED_DATA_STRUCTURE_ALIGMENT +
  99. (HEADER_SIZE%SHARED_DATA_STRUCTURE_ALIGMENT? 1: 0)*SHARED_DATA_STRUCTURE_ALIGMENT) +
  100. (SHARED_DATA_STRUCTURE_ALIGMENT * 2) > SizeForAllSharedData){
  101. ASSERT(FALSE);
  102. return FALSE;
  103. }
  104. pSharedStructure = &((PLOG_SHARED_DATA)m_SharedData)->Fields;
  105. pSharedStructure->FirstElementOffset = ALIGN_DATA(HEADER_SIZE, SHARED_DATA_STRUCTURE_ALIGMENT);
  106. pSharedStructure->SizeOfUsedMemory = 0;
  107. pSharedStructure->MaxSizeOfMemory = ALIGN_DATA((SizeForAllSharedData - pSharedStructure->FirstElementOffset) / 2,
  108. SHARED_DATA_STRUCTURE_ALIGMENT);
  109. offset = pSharedStructure->FirstElementOffset + pSharedStructure->MaxSizeOfMemory;
  110. pSharedStructure = &((PLOG_SHARED_DATA)m_SharedData)->Filters;
  111. pSharedStructure->FirstElementOffset = offset;
  112. pSharedStructure->SizeOfUsedMemory = 0;
  113. pSharedStructure->MaxSizeOfMemory = SizeForAllSharedData - pSharedStructure->FirstElementOffset;
  114. return TRUE;
  115. }
  116. BOOL
  117. CLogManager::GetSharedData(
  118. IN PCWSTR pLogName
  119. )
  120. {
  121. BOOL alreadyExist = FALSE;
  122. CBuffer SectionName;
  123. SectionName.Allocate((wcslen(pLogName) + wcslen(L"Section") + 1) * sizeof(WCHAR));
  124. PWSTR pSectionName = (PWSTR)SectionName.GetBuffer();
  125. wcscpy(pSectionName, pLogName);
  126. wcscat(pSectionName, L"Section");
  127. if(!m_SharedMemory.Open(pSectionName, INITIAL_SIZE_OF_SHARED_SECTION, &alreadyExist)){
  128. return FALSE;
  129. }
  130. m_SharedData = (PLOG_SHARED_DATA)m_SharedMemory.GetMapOfView();
  131. if(!alreadyExist){
  132. InitSharedData(INITIAL_SIZE_OF_SHARED_SECTION);
  133. }
  134. return TRUE;
  135. }
  136. BOOL
  137. CLogManager::ReleaseSharedData(
  138. VOID
  139. )
  140. {
  141. m_SharedMemory.Close();
  142. m_SharedData = NULL;
  143. m_Mutex.Close();
  144. if(m_FieldsValue){
  145. FREE(m_FieldsValue);
  146. m_FieldsValue = NULL;
  147. m_FieldsNumber= 0;
  148. }
  149. return TRUE;
  150. }
  151. BOOL
  152. CLogManager::Init(
  153. PCWSTR pLogName,
  154. LOG_FIELD_INFO * pFields,
  155. UINT NumberOfFields
  156. )
  157. {
  158. BOOL bResult;
  159. if(!pLogName || !pFields || !NumberOfFields){
  160. ASSERT(pLogName && pFields && NumberOfFields);
  161. return FALSE;
  162. }
  163. if(!m_Mutex.Open(pLogName, TRUE, LOG_MANAGER_MUTEX_DEFAULT_SPIN_COUNT)){
  164. return FALSE;
  165. }
  166. bResult = FALSE;
  167. __try{
  168. if(!GetSharedData(pLogName)){
  169. __leave;
  170. }
  171. if(!ValidateAndAddFieldsIfOk(pFields, NumberOfFields)){
  172. __leave;
  173. }
  174. m_FieldsValue = (PLOG_FIELD_VALUE)MALLOC(sizeof(LOG_FIELD_VALUE) * NumberOfFields);
  175. if(!m_FieldsValue){
  176. __leave;
  177. }
  178. m_FieldsNumber = NumberOfFields;
  179. memset(m_FieldsValue, 0, sizeof(LOG_FIELD_VALUE) * NumberOfFields);
  180. for(UINT i = 0, iStringNumber = 0; i < NumberOfFields; i++){
  181. wcscpy(m_FieldsValue[i].Name, pFields[i].Name);
  182. m_FieldsValue[i].bMandatory = pFields[i].bMandatory;
  183. m_FieldsValue[i].Value.Type = pFields[i].Type;
  184. if(LT_SZ == pFields[i].Type){
  185. iStringNumber++;
  186. }
  187. }
  188. if(iStringNumber && !CreateConversionBuffers(iStringNumber)){
  189. __leave;
  190. }
  191. bResult = TRUE;
  192. }
  193. __finally{
  194. if(!bResult){
  195. RemoveFields();
  196. }
  197. }
  198. m_Mutex.Release();
  199. if(!bResult){
  200. Close();
  201. }
  202. return bResult;
  203. }
  204. BOOL
  205. CLogManager::ValidateAndAddFieldsIfOk(
  206. PLOG_FIELD_INFO pFields,
  207. UINT NumberOfFields
  208. )
  209. {
  210. ASSERT(pFields && NumberOfFields);
  211. PLOG_FIELD_INFO_WITH_REF_COUNT pSharedFields = (PLOG_FIELD_INFO_WITH_REF_COUNT)(m_SharedData->Fields.FirstElementOffset + (BYTE*)m_SharedData);
  212. UINT NumberOfSharedFields = m_SharedData->Fields.SizeOfUsedMemory / sizeof(LOG_FIELD_INFO_WITH_REF_COUNT);
  213. for(UINT j = 0; j < NumberOfSharedFields; j++){
  214. PLOG_FIELD_INFO_WITH_REF_COUNT pSharedField = pSharedFields + j;
  215. for(UINT i = 0; i < NumberOfFields; i++){
  216. PLOG_FIELD_INFO pField = pFields + i;
  217. if(!wcscmp(pSharedField->FieldDescription.Name, pField->Name)){
  218. if(pSharedField->FieldDescription.Type != pField->Type ||
  219. pSharedField->FieldDescription.bMandatory != pField->bMandatory){
  220. return FALSE;
  221. }
  222. break;
  223. }
  224. }
  225. if(i == NumberOfFields && pSharedField->FieldDescription.bMandatory){
  226. return FALSE;
  227. }
  228. }
  229. for(UINT i = 0; i < NumberOfFields; i++){
  230. PLOG_FIELD_INFO pField = pFields + i;
  231. BOOL bPresent = FALSE;
  232. for(UINT j = 0; j < NumberOfSharedFields; j++){
  233. PLOG_FIELD_INFO_WITH_REF_COUNT pSharedField = pSharedFields + j;
  234. if(!wcscmp(pSharedField->FieldDescription.Name, pField->Name)){
  235. pSharedField->ReferenceCount++;
  236. bPresent = TRUE;
  237. break;
  238. }
  239. }
  240. if(!bPresent){
  241. UINT offset = GetOffsetForNewItem(&m_SharedData->Fields, sizeof(LOG_FIELD_INFO_WITH_REF_COUNT));
  242. if(!offset){
  243. return FALSE;
  244. }
  245. PLOG_FIELD_INFO_WITH_REF_COUNT pNewSharedField;
  246. pNewSharedField = (PLOG_FIELD_INFO_WITH_REF_COUNT)(offset + (BYTE*)m_SharedData);
  247. pNewSharedField->ReferenceCount = 1;
  248. wcscpy(pNewSharedField->FieldDescription.Name, pField->Name);
  249. pNewSharedField->FieldDescription.Type = pField->Type;
  250. pNewSharedField->FieldDescription.bMandatory = pField->bMandatory;
  251. bPresent = TRUE;
  252. }
  253. }
  254. return TRUE;
  255. }
  256. BOOL
  257. CLogManager::RemoveFields(
  258. )
  259. {
  260. if(!m_SharedData || !m_FieldsValue){
  261. return FALSE;
  262. }
  263. ASSERT(m_FieldsValue && m_FieldsNumber);
  264. PLOG_FIELD_INFO_WITH_REF_COUNT pSharedFields = (PLOG_FIELD_INFO_WITH_REF_COUNT)(m_SharedData->Fields.FirstElementOffset + (BYTE*)m_SharedData);
  265. UINT NumberOfSharedFields = m_SharedData->Fields.SizeOfUsedMemory / sizeof(LOG_FIELD_INFO_WITH_REF_COUNT);
  266. for(int i = m_FieldsNumber - 1; i >= 0 ; i--){
  267. PLOG_FIELD_VALUE pField = m_FieldsValue + i;
  268. UINT HowBytesToCopy = 0;
  269. for(int j = NumberOfSharedFields - 1; j >= 0; j--){
  270. PLOG_FIELD_INFO_WITH_REF_COUNT pSharedField = pSharedFields + j;
  271. if(!wcscmp(pSharedField->FieldDescription.Name, pField->Name)){
  272. pSharedField->ReferenceCount--;
  273. if(!pSharedField->ReferenceCount){
  274. if(HowBytesToCopy){
  275. memcpy(pSharedField, pSharedField + 1, HowBytesToCopy);
  276. }
  277. UpdateForRemovedItem(&m_SharedData->Fields, sizeof(LOG_FIELD_INFO_WITH_REF_COUNT));
  278. break;
  279. }
  280. }
  281. HowBytesToCopy += sizeof(LOG_FIELD_INFO_WITH_REF_COUNT);
  282. }
  283. }
  284. return TRUE;
  285. }
  286. VOID
  287. CLogManager::Close()
  288. {
  289. m_Mutex.Acquiry();
  290. RemoveFields();
  291. //walk through list
  292. for(PLOG_OUTPUT_STACK pLogStack = m_StackList.BeginEnum(); pLogStack; pLogStack = m_StackList.Next()){
  293. ASSERT(pLogStack);
  294. DestroyStack(pLogStack);
  295. }
  296. m_Mutex.Release();
  297. m_StackList.RemoveAll();
  298. ReleaseSharedData();
  299. DestroyConversionBuffers();
  300. }
  301. BOOL
  302. CLogManager::AddStack(
  303. const GUID * guidFilter, PVOID pFilterData,
  304. const GUID * guidFormater, PVOID pFormaterData,
  305. const GUID * guidDevice, PVOID pDeviceData,
  306. PVOID * pvHandle
  307. )
  308. {
  309. ILogProvider * pDevice = NULL;
  310. ILogProvider * pFormater = NULL;
  311. ILogProvider * pFilter = NULL;
  312. PLOG_OUTPUT_STACK pNewStack = NULL;
  313. BOOL bResult = FALSE;
  314. BOOL bDestAlreadyExist = FALSE;
  315. if(!guidFormater){
  316. return FALSE;
  317. }
  318. m_Mutex.Acquiry();
  319. __try{
  320. if(guidDevice){
  321. pDevice = LogiCreateProvider(guidDevice);
  322. if(!pDevice || LOG_DEVICE_TYPE != pDevice->GetType()){
  323. __leave;
  324. }
  325. LOGRESULT logResult = pDevice->Init(pDeviceData, this);
  326. if(logError == logResult){
  327. __leave;
  328. }
  329. bDestAlreadyExist = (logAlreadyExist == logResult);
  330. }
  331. pFormater = LogiCreateProvider(guidFormater);
  332. if(!pFormater || LOG_FORMATTER_TYPE != pFormater->GetType() ||
  333. logError == pFormater->Init(pFormaterData, this)){
  334. __leave;
  335. }
  336. if(guidFilter){
  337. pFilter = LogiCreateProvider(guidFilter);
  338. if(!pFilter || LOG_FILTER_TYPE != pFilter->GetType() ||
  339. logError == pFilter->Init(pFilterData, this)){
  340. __leave;
  341. }
  342. }
  343. pNewStack = (PLOG_OUTPUT_STACK)MALLOC(sizeof(LOG_OUTPUT_STACK));
  344. if(!pNewStack){
  345. __leave;
  346. }
  347. pNewStack->m_Device = pDevice;
  348. pNewStack->m_Filter = pFilter;
  349. pNewStack->m_Formater = pFormater;
  350. if(pDevice){
  351. if(!ShareStack(guidFormater, pDevice->ToString(), bDestAlreadyExist)){
  352. __leave;
  353. }
  354. }
  355. {
  356. AllocBuffer(0, 0);
  357. if(pFilter){
  358. pFilter->PreProcess(this, !bDestAlreadyExist);
  359. }
  360. pFormater->PreProcess(this, !bDestAlreadyExist);
  361. if(pDevice){
  362. pDevice->PreProcess(this, !bDestAlreadyExist);
  363. }
  364. FreeBuffer();
  365. }
  366. //append to list
  367. m_StackList.Add(pNewStack);
  368. bResult = TRUE;
  369. }
  370. __finally{
  371. if(!bResult){
  372. if(pNewStack){
  373. FREE(pNewStack);
  374. }
  375. if(pFilter){
  376. LogiDestroyProvider(pFilter);
  377. }
  378. if(pFormater){
  379. LogiDestroyProvider(pFormater);
  380. }
  381. if(pDevice){
  382. UnShareStack(guidFormater, pDevice->ToString());
  383. LogiDestroyProvider(pDevice);
  384. }
  385. }
  386. if(pvHandle){
  387. *pvHandle = bResult? (PVOID)pNewStack: NULL;
  388. }
  389. }
  390. m_Mutex.Release();
  391. return bResult;
  392. }
  393. BOOL
  394. CLogManager::RemoveStack(
  395. IN PVOID pvHandle
  396. )
  397. {
  398. m_Mutex.Acquiry();
  399. //walk through list
  400. for(PLOG_OUTPUT_STACK pLogStack = m_StackList.BeginEnum(); pLogStack; pLogStack = m_StackList.Next()){
  401. ASSERT(pLogStack);
  402. if(((PVOID)pLogStack) == pvHandle){
  403. if(DestroyStack(pLogStack)){
  404. m_StackList.Remove(pLogStack);
  405. break;
  406. }
  407. }
  408. }
  409. m_Mutex.Release();
  410. return TRUE;
  411. }
  412. BOOL
  413. CLogManager::DestroyStack(
  414. IN PLOG_OUTPUT_STACK pLogStack
  415. )
  416. {
  417. BOOL bLastInstance = FALSE;
  418. PLOG_FILTER_WITH_REF_COUNT pSharedFilterData;
  419. GUID guidDevice;
  420. if(pLogStack->m_Device){
  421. pLogStack->m_Formater->GetGUID(&guidDevice);
  422. if(FindSharedStack(&guidDevice, pLogStack->m_Device->ToString(), &pSharedFilterData)){
  423. bLastInstance = 1 == pSharedFilterData->ReferenceCount;
  424. }
  425. }
  426. AllocBuffer(0, 0);
  427. if(pLogStack->m_Filter){
  428. pLogStack->m_Filter->PreDestroy(this, bLastInstance);
  429. LogiDestroyProvider(pLogStack->m_Filter);
  430. }
  431. pLogStack->m_Formater->PreDestroy(this, bLastInstance);
  432. LogiDestroyProvider(pLogStack->m_Formater);
  433. if(pLogStack->m_Device){
  434. pLogStack->m_Device->PreDestroy(this, bLastInstance);
  435. if(!UnShareStack(&guidDevice, pLogStack->m_Device->ToString())){
  436. return FALSE;
  437. }
  438. LogiDestroyProvider(pLogStack->m_Device);
  439. }
  440. FreeBuffer();
  441. FREE(pLogStack);
  442. return TRUE;
  443. }
  444. BOOL
  445. CLogManager::FindSharedStack(
  446. IN const GUID *pFormaterGUID,
  447. IN PCWSTR UniqueDestString,
  448. PLOG_FILTER_WITH_REF_COUNT * ppFilterData
  449. )
  450. {
  451. PLOG_FILTER_WITH_REF_COUNT pSharedFilterData;
  452. ASSERT(pFormaterGUID && UniqueDestString && ppFilterData);
  453. BYTE * pData = GET_SECTION_PTR(m_SharedData, m_SharedData->Filters);
  454. UINT offset = 0;
  455. while(offset < m_SharedData->Filters.SizeOfUsedMemory){
  456. pSharedFilterData = (PLOG_FILTER_WITH_REF_COUNT)(pData + offset);
  457. if(!wcscmp(pSharedFilterData->UniqueDestinationString, UniqueDestString)){//must be wcsicmp
  458. if(InlineIsEqualGUID(&pSharedFilterData->FormatterGUID, pFormaterGUID)){
  459. *ppFilterData = pSharedFilterData;
  460. return TRUE;
  461. }
  462. else{
  463. return FALSE;
  464. }
  465. }
  466. offset += pSharedFilterData->Size;
  467. };
  468. *ppFilterData = NULL;
  469. return TRUE;
  470. }
  471. BOOL
  472. CLogManager::ShareStack(
  473. IN const GUID * pFormaterGUID,
  474. IN PCWSTR UniqueDestString,
  475. IN BOOL bDestAlreadyExist
  476. )
  477. {
  478. PLOG_FILTER_WITH_REF_COUNT pSharedFilterData;
  479. UINT offset;
  480. UINT size;
  481. if(!FindSharedStack(pFormaterGUID, UniqueDestString, &pSharedFilterData)){
  482. return FALSE;
  483. }
  484. if(!pSharedFilterData){
  485. if(bDestAlreadyExist){
  486. return FALSE;
  487. }
  488. size = sizeof(LOG_FILTER_WITH_REF_COUNT) + (wcslen(UniqueDestString) + 1/*'\0'*/) * sizeof(WCHAR);
  489. offset = GetOffsetForNewItem(&m_SharedData->Filters, size);
  490. if(!offset){
  491. return FALSE;
  492. }
  493. pSharedFilterData = (PLOG_FILTER_WITH_REF_COUNT)(offset + (BYTE*)m_SharedData);
  494. pSharedFilterData->ReferenceCount = 1;
  495. pSharedFilterData->FormatterGUID = *pFormaterGUID;
  496. wcscpy(pSharedFilterData->UniqueDestinationString, UniqueDestString);
  497. pSharedFilterData->Size = size;
  498. }
  499. else{
  500. pSharedFilterData->ReferenceCount++;
  501. }
  502. return TRUE;
  503. }
  504. BOOL
  505. CLogManager::UnShareStack(
  506. IN const GUID * pFormaterGUID,
  507. IN PCWSTR UniqueDestString
  508. )
  509. {
  510. PLOG_FILTER_WITH_REF_COUNT pSharedFilterData;
  511. PLOG_FILTER_WITH_REF_COUNT pSharedNextFilterData;
  512. UINT_PTR offset;
  513. UINT size;
  514. if(!FindSharedStack(pFormaterGUID, UniqueDestString, &pSharedFilterData)){
  515. return FALSE;
  516. }
  517. if(pSharedFilterData){
  518. pSharedFilterData->ReferenceCount--;
  519. if(!pSharedFilterData->ReferenceCount){
  520. size = pSharedFilterData->Size;
  521. offset = ((BYTE *)pSharedFilterData) - GET_SECTION_PTR(m_SharedData, m_SharedData->Filters) + size;
  522. pSharedNextFilterData = (PLOG_FILTER_WITH_REF_COUNT)(GET_SECTION_PTR(m_SharedData, m_SharedData->Filters) + offset);
  523. if(offset < m_SharedData->Filters.SizeOfUsedMemory){
  524. memcpy(pSharedFilterData, pSharedNextFilterData, m_SharedData->Filters.SizeOfUsedMemory - offset);
  525. }
  526. UpdateForRemovedItem(&m_SharedData->Filters, size);
  527. }
  528. }
  529. return TRUE;
  530. }
  531. LOGRESULT
  532. CLogManager::LogMessage()
  533. {
  534. LOGRESULT logResult;
  535. BOOL bBreakPoint = FALSE;
  536. BOOL bAbortProcess = FALSE;
  537. ASSERT(0 != m_StackList.GetSize());
  538. logResult = logError;
  539. __try{
  540. //walk through list
  541. for(PLOG_OUTPUT_STACK pLogStack = m_StackList.BeginEnum(); pLogStack; pLogStack = m_StackList.Next()){
  542. ASSERT(pLogStack);
  543. if(!pLogStack){
  544. ASSERT(pLogStack);
  545. continue;
  546. }
  547. FreeBuffer();
  548. if(pLogStack->m_Filter){
  549. logResult = pLogStack->m_Filter->Process(this);
  550. if(logOk != logResult){
  551. if(logBreakPoint == logResult){
  552. bBreakPoint = TRUE;
  553. }
  554. else if(logAbortProcess == logResult){
  555. bAbortProcess = TRUE;
  556. }
  557. else{
  558. continue;
  559. }
  560. }
  561. }
  562. logResult = pLogStack->m_Formater->Process(this);
  563. if(logOk != logResult){
  564. continue;
  565. }
  566. if(pLogStack->m_Device){
  567. logResult = pLogStack->m_Device->Process(this);
  568. if(logOk != logResult){
  569. continue;
  570. }
  571. }
  572. }
  573. if(bAbortProcess){
  574. logResult = logAbortProcess;
  575. }
  576. else{
  577. logResult = bBreakPoint? logBreakPoint: logOk;
  578. }
  579. }
  580. __finally{
  581. }
  582. return logResult;
  583. }
  584. LOGRESULT
  585. STDMETHODCALLTYPE
  586. CLogManager::LogA(
  587. IN UINT NumberOfFieldsToLog
  588. IN ...
  589. )
  590. {
  591. PCSTR pTempStr;
  592. LOGRESULT logResult;
  593. PLOG_VALUE pFieldValue;
  594. va_list argList;
  595. if(NumberOfFieldsToLog > m_FieldsNumber){
  596. NumberOfFieldsToLog = m_FieldsNumber;
  597. }
  598. m_Mutex.Acquiry();
  599. logResult = logError;
  600. __try{
  601. va_start(argList, NumberOfFieldsToLog);
  602. for(UINT i = 0, iStringNumber = 0; i < NumberOfFieldsToLog; i++){
  603. pFieldValue = &m_FieldsValue[i].Value;
  604. #ifdef DEBUG
  605. //
  606. // init value union
  607. //
  608. memset(&pFieldValue->Binary, 0, sizeof(pFieldValue->Binary));
  609. #endif
  610. switch(pFieldValue->Type){
  611. case LT_DWORD:
  612. pFieldValue->Dword = va_arg(argList, DWORD);
  613. break;
  614. case LT_SZ:
  615. ASSERT(m_ConversionBuffers);
  616. pTempStr = va_arg(argList, PCSTR);
  617. if(pTempStr){
  618. if(!m_ConversionBuffers ||
  619. !(m_ConversionBuffers[iStringNumber].ReAllocate((strlen(pTempStr) + 1) * sizeof(WCHAR)))){
  620. pFieldValue->String = LOGMANAGER_CANNOT_CONVERT_PARAMETER;
  621. break;
  622. }
  623. pFieldValue->String = (PCWSTR)m_ConversionBuffers[iStringNumber].GetBuffer();
  624. swprintf((PWSTR)pFieldValue->String, L"%S", pTempStr);
  625. }
  626. else{
  627. pFieldValue->String = NULL;
  628. }
  629. iStringNumber++;
  630. break;
  631. case LT_BINARY:
  632. pFieldValue->Binary.Buffer = va_arg(argList, BYTE *);
  633. pFieldValue->Binary.Size = va_arg(argList, DWORD);
  634. break;
  635. default:
  636. ASSERT(FALSE);
  637. };
  638. }
  639. for(; i < m_FieldsNumber; i++){
  640. pFieldValue = &m_FieldsValue[i].Value;
  641. //
  642. // init value union
  643. //
  644. memset(&pFieldValue->Binary, 0, sizeof(pFieldValue->Binary));
  645. }
  646. va_end(argList);
  647. logResult = LogMessage();
  648. }
  649. __finally{
  650. m_Mutex.Release();
  651. }
  652. return logResult;
  653. }
  654. LOGRESULT
  655. STDMETHODCALLTYPE
  656. CLogManager::LogW(
  657. IN UINT NumberOfFieldsToLog
  658. IN ...
  659. )
  660. {
  661. LOGRESULT logResult;
  662. PLOG_VALUE pFieldValue;
  663. va_list argList;
  664. if(NumberOfFieldsToLog > m_FieldsNumber){
  665. NumberOfFieldsToLog = m_FieldsNumber;
  666. }
  667. m_Mutex.Acquiry();
  668. logResult = logError;
  669. __try{
  670. va_start(argList, NumberOfFieldsToLog);
  671. for(UINT i = 0; i < NumberOfFieldsToLog; i++){
  672. pFieldValue = &m_FieldsValue[i].Value;
  673. #ifdef DEBUG
  674. //
  675. // init value union
  676. //
  677. memset(&pFieldValue->Binary, 0, sizeof(pFieldValue->Binary));
  678. #endif
  679. switch(pFieldValue->Type){
  680. case LT_DWORD:
  681. pFieldValue->Dword = va_arg(argList, DWORD);
  682. break;
  683. case LT_SZ:
  684. pFieldValue->String = va_arg(argList, PCWSTR);
  685. break;
  686. case LT_BINARY:
  687. pFieldValue->Binary.Buffer = va_arg(argList, BYTE *);
  688. pFieldValue->Binary.Size = va_arg(argList, DWORD);
  689. break;
  690. default:
  691. ASSERT(FALSE);
  692. };
  693. }
  694. for(; i < m_FieldsNumber; i++){
  695. pFieldValue = &m_FieldsValue[i].Value;
  696. //
  697. // init value union
  698. //
  699. memset(&pFieldValue->Binary, 0, sizeof(pFieldValue->Binary));
  700. }
  701. va_end(argList);
  702. logResult = LogMessage();
  703. }
  704. __finally{
  705. m_Mutex.Release();
  706. }
  707. return logResult;
  708. }
  709. // interface ILogContext
  710. BOOL
  711. CLogManager::GetFieldIndexFromName(
  712. IN PCWSTR pFieldName,
  713. IN UINT* puiFieldIndex
  714. )
  715. {
  716. ASSERT(pFieldName && pFieldName);
  717. if(!pFieldName){
  718. return FALSE;
  719. }
  720. for(UINT i = 0; i < m_FieldsNumber; i++){
  721. if(!wcscmp(m_FieldsValue[i].Name, pFieldName)){//must be wcsicmp
  722. if(puiFieldIndex){
  723. *puiFieldIndex = i;
  724. }
  725. return TRUE;
  726. }
  727. }
  728. return FALSE;
  729. }
  730. ILogManager *
  731. LogCreateLog(
  732. IN PCWSTR pLogName,
  733. IN PLOG_FIELD_INFO pFields,
  734. IN UINT NumberOfFields
  735. )
  736. {
  737. CLogManager * pLogManager = new CLogManager;
  738. ASSERT(pLogManager);
  739. if(!pLogManager){
  740. return NULL;
  741. }
  742. if(!pLogManager->Init(pLogName, pFields, NumberOfFields)){
  743. delete pLogManager;
  744. return NULL;
  745. }
  746. return (ILogManager *)pLogManager;
  747. }
  748. VOID
  749. LogDestroyLog(
  750. IN ILogManager * pLog
  751. )
  752. {
  753. ASSERT(pLog);
  754. if(!pLog){
  755. return;
  756. }
  757. delete (CLogManager *)pLog;
  758. }