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.

1110 lines
33 KiB

  1. /*****************************************************************************\
  2. Author: Corey Morgan (coreym)
  3. Copyright (c) Microsoft Corporation. All rights reserved.
  4. \*****************************************************************************/
  5. #include <fwcommon.h>
  6. #include <strsafe.h>
  7. #include "evntrprv.h"
  8. LPCWSTR cszGlobalLogger = L"GlobalLogger";
  9. LPCWSTR cszKernelLogger = L"NT Kernel Logger";
  10. LPCWSTR cszPrivateLogger = L"{dc945bc4-34e5-4bc4-ab8d-cc4e9de1c2bb}";
  11. _COM_SMARTPTR_TYPEDEF(CInstance, __uuidof(CInstance));
  12. HRESULT
  13. SetGlobalLoggerSettings(
  14. DWORD StartValue,
  15. PEVENT_TRACE_PROPERTIES LoggerInfo,
  16. DWORD ClockType
  17. );
  18. BOOL
  19. FindString( LPCWSTR strBuffer, LPCWSTR strMatch )
  20. {
  21. BOOL bReturn = FALSE;
  22. LPWSTR buffer;
  23. LPWSTR match;
  24. if( NULL == strBuffer || NULL == strMatch ){
  25. return FALSE;
  26. }
  27. buffer = _wcsdup( strBuffer );
  28. match = _wcsdup( strMatch );
  29. if( buffer != NULL && match != NULL ){
  30. _wcslwr( buffer );
  31. _wcslwr( match );
  32. if( wcsstr( buffer, match ) ){
  33. bReturn = TRUE;
  34. }
  35. }
  36. if( NULL != match ){
  37. free( match );
  38. }
  39. if( NULL != buffer ){
  40. free( buffer );
  41. }
  42. return bReturn;
  43. }
  44. ULONG hextoi( LPWSTR s )
  45. {
  46. long len;
  47. ULONG num, base, hex;
  48. if (s == NULL || s[0] == L'\0') {
  49. return 0;
  50. }
  51. len = (long) wcslen(s);
  52. if (len == 0) {
  53. return 0;
  54. }
  55. hex = 0;
  56. base = 1;
  57. num = 0;
  58. while (-- len >= 0) {
  59. if (s[len] >= L'0' && s[len] <= L'9'){
  60. num = s[len] - L'0';
  61. }else if (s[len] >= L'a' && s[len] <= L'f'){
  62. num = (s[len] - L'a') + 10;
  63. }else if (s[len] >= L'A' && s[len] <= L'F'){
  64. num = (s[len] - L'A') + 10;
  65. }else if( s[len] == L'x' || s[len] == L'X'){
  66. break;
  67. }else{
  68. continue;
  69. }
  70. hex += num * base;
  71. base = base * 16;
  72. }
  73. return hex;
  74. }
  75. CEventTrace SystemEventTraceProv( PROVIDER_NAME_EVENTTRACE, L"root\\wmi" );
  76. const static WCHAR* pEventTraceErrorClass = L"\\\\.\\root\\wmi:EventTraceError";
  77. CEventTrace::CEventTrace (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
  78. Provider(lpwszName, lpwszNameSpace)
  79. {
  80. }
  81. CEventTrace::~CEventTrace ()
  82. {
  83. }
  84. HRESULT
  85. CEventTrace::EnumerateInstances( MethodContext* pMethodContext, long lFlags )
  86. {
  87. HRESULT hr = WBEM_S_NO_ERROR;
  88. ULONG i, nLoggers;
  89. DWORD dwSize;
  90. PEVENT_TRACE_PROPERTIES pLoggerInfo[MAXIMUM_LOGGERS];
  91. PEVENT_TRACE_PROPERTIES pStorage;
  92. PVOID Storage;
  93. PVOID GuidStorage = NULL;
  94. PTRACE_GUID_PROPERTIES* GuidPropertiesArray = NULL;
  95. ULONG nGuidCount = 0;
  96. dwSize = MAXIMUM_LOGGERS*(sizeof(EVENT_TRACE_PROPERTIES)+2*MAXSTR*sizeof(WCHAR));
  97. Storage = G_ALLOC(dwSize);
  98. if( Storage == NULL ){
  99. return ERROR_OUTOFMEMORY;
  100. }
  101. RtlZeroMemory(Storage, dwSize);
  102. pStorage = (PEVENT_TRACE_PROPERTIES)Storage;
  103. for (i=0; i<MAXIMUM_LOGGERS; i++) {
  104. pStorage->Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES)+2*MAXSTR*sizeof(WCHAR);
  105. pStorage->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES)+MAXSTR*sizeof(WCHAR);
  106. pStorage->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  107. pLoggerInfo[i] = pStorage;
  108. pStorage = (PEVENT_TRACE_PROPERTIES)( (char*)pStorage + pStorage->Wnode.BufferSize);
  109. }
  110. hr = QueryAllTraces(
  111. pLoggerInfo,
  112. MAXIMUM_LOGGERS,
  113. &nLoggers
  114. );
  115. if( ERROR_SUCCESS == hr ){
  116. try{
  117. if( ERROR_SUCCESS == LoadGuidArray( &GuidStorage, &nGuidCount ) ){
  118. GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)GuidStorage;
  119. }
  120. for( i=0; i<nLoggers && i<MAXIMUM_LOGGERS; i++){
  121. CInstancePtr pInstance( CreateNewInstance(pMethodContext), false );
  122. assert( NULL != pLoggerInfo[i] );
  123. if( NULL != pInstance ){
  124. if( SUCCEEDED( LoadPropertyValues(pInstance, pLoggerInfo[i], GuidPropertiesArray, nGuidCount ) )){
  125. hr = pInstance->Commit();
  126. }
  127. }
  128. }
  129. }catch(...){
  130. hr = WBEM_E_OUT_OF_MEMORY;
  131. }
  132. }
  133. G_FREE( GuidStorage );
  134. G_FREE( Storage );
  135. return hr;
  136. }
  137. HRESULT CEventTrace::GetObject ( CInstance* pInstance, long lFlags )
  138. {
  139. HRESULT hr = WBEM_E_NOT_FOUND;
  140. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  141. TRACEHANDLE LoggerHandle = 0;
  142. CHString LoggerName;
  143. pInstance->GetCHString( L"Name", LoggerName );
  144. hr = InitTraceProperties( &pLoggerInfo );
  145. if( ERROR_SUCCESS != hr ){
  146. return hr;
  147. }
  148. if( wcsncmp( (LPCWSTR)LoggerName, cszPrivateLogger, wcslen( cszPrivateLogger ) ) == 0 ){
  149. GUID guid;
  150. LPWSTR szPrivateGuid;
  151. size_t cchSize;
  152. szPrivateGuid = (LPWSTR)(LPCWSTR)LoggerName;
  153. cchSize = wcslen( szPrivateGuid );
  154. if( cchSize + 1 > wcslen( cszPrivateLogger ) ){
  155. szPrivateGuid += wcslen( cszPrivateLogger ) + 1;
  156. CLSIDFromString( szPrivateGuid, &guid );
  157. pLoggerInfo->Wnode.Guid = guid;
  158. pLoggerInfo->LogFileMode = EVENT_TRACE_PRIVATE_LOGGER_MODE;
  159. hr = QueryTraceW( 0, NULL, pLoggerInfo);
  160. }else{
  161. hr = WBEM_E_INVALID_PARAMETER;
  162. }
  163. }else{
  164. hr = QueryTraceW( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo);
  165. }
  166. if( ERROR_SUCCESS == hr ){
  167. if( hr == ERROR_SUCCESS ){
  168. PVOID GuidStorage = NULL;
  169. PTRACE_GUID_PROPERTIES* GuidPropertiesArray = NULL;
  170. ULONG nGuidCount = 0;
  171. try{
  172. if( ERROR_SUCCESS == LoadGuidArray( &GuidStorage, &nGuidCount ) ){
  173. GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)GuidStorage;
  174. }
  175. hr = LoadPropertyValues( pInstance, pLoggerInfo, GuidPropertiesArray, nGuidCount );
  176. }catch(...){
  177. hr = WBEM_E_OUT_OF_MEMORY;
  178. }
  179. G_FREE( GuidStorage );
  180. }
  181. }
  182. G_FREE( pLoggerInfo );
  183. return hr;
  184. }
  185. HRESULT CEventTrace::LoadGuidArray( PVOID* Storage, PULONG pnGuidCount )
  186. {
  187. ULONG i;
  188. ULONG nGuidArray = 16;
  189. ULONG nGuidCount = 0;
  190. DWORD dwSize;
  191. PTRACE_GUID_PROPERTIES* GuidPropertiesArray;
  192. PTRACE_GUID_PROPERTIES pStorage;
  193. HRESULT hr;
  194. do{
  195. dwSize = nGuidArray * (sizeof(TRACE_GUID_PROPERTIES) + sizeof(PTRACE_GUID_PROPERTIES));
  196. *Storage = G_ALLOC(dwSize);
  197. if(*Storage == NULL){
  198. hr = WBEM_E_OUT_OF_MEMORY;
  199. break;
  200. }
  201. RtlZeroMemory(*Storage, dwSize);
  202. GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)(*Storage);
  203. pStorage = (PTRACE_GUID_PROPERTIES)((char*)(*Storage) + nGuidArray * sizeof(PTRACE_GUID_PROPERTIES));
  204. for (i=0; i < nGuidArray; i++) {
  205. GuidPropertiesArray[i] = pStorage;
  206. pStorage = (PTRACE_GUID_PROPERTIES)((char*)pStorage + sizeof(TRACE_GUID_PROPERTIES));
  207. }
  208. hr = EnumerateTraceGuids(GuidPropertiesArray,nGuidArray,&nGuidCount);
  209. if(hr == ERROR_MORE_DATA){
  210. if( nGuidCount <= nGuidArray ){
  211. hr = WBEM_E_INVALID_PARAMETER;
  212. break;
  213. }
  214. nGuidArray = nGuidCount;
  215. G_FREE(*Storage);
  216. (*Storage) = NULL;
  217. }
  218. }while( hr == ERROR_MORE_DATA );
  219. if( ERROR_SUCCESS == hr ){
  220. *pnGuidCount = nGuidCount;
  221. }else{
  222. *pnGuidCount = 0;
  223. }
  224. return hr;
  225. }
  226. HRESULT
  227. CEventTrace::LoadPropertyValues(
  228. CInstance *pInstanceParam,
  229. PEVENT_TRACE_PROPERTIES pLoggerInfo,
  230. PTRACE_GUID_PROPERTIES *GuidPropertiesArray,
  231. ULONG nGuidCount
  232. )
  233. {
  234. LPWSTR strName;
  235. ULONG i;
  236. CInstance* pInstance = pInstanceParam;
  237. if( NULL == pLoggerInfo || NULL == pInstance ){
  238. return WBEM_E_INVALID_PARAMETER;
  239. }
  240. if( NULL != GuidPropertiesArray ){
  241. SAFEARRAY *saGuids;
  242. SAFEARRAY *saFlags;
  243. SAFEARRAY *saLevel;
  244. BSTR HUGEP *pGuidData;
  245. DWORD HUGEP *pLevelData;
  246. DWORD HUGEP *pFlagData;
  247. ULONG nGuidIndex = 0;
  248. ULONG nProviderGuids = 0;
  249. if( pLoggerInfo->Wnode.Guid == SystemTraceControlGuid ){
  250. nProviderGuids = 1;
  251. }else{
  252. for (i=0; i < nGuidCount; i++) {
  253. if( pLoggerInfo->Wnode.HistoricalContext == GuidPropertiesArray[i]->LoggerId ){
  254. nProviderGuids++;
  255. }
  256. }
  257. }
  258. if( nProviderGuids ){
  259. saGuids = SafeArrayCreateVector( VT_BSTR, 0, nProviderGuids );
  260. saFlags = SafeArrayCreateVector( VT_I4, 0, nProviderGuids );
  261. saLevel = SafeArrayCreateVector( VT_I4, 0, nProviderGuids );
  262. if( saGuids == NULL || saFlags == NULL || saLevel == NULL ){
  263. if( saGuids != NULL ){
  264. SafeArrayDestroy( saGuids );
  265. }
  266. if( saFlags != NULL ){
  267. SafeArrayDestroy( saFlags );
  268. }
  269. if( saLevel != NULL ){
  270. SafeArrayDestroy( saLevel );
  271. }
  272. }else{
  273. SafeArrayAccessData( saGuids, (void HUGEP **)&pGuidData);
  274. SafeArrayAccessData( saFlags, (void HUGEP **)&pFlagData);
  275. SafeArrayAccessData( saLevel, (void HUGEP **)&pLevelData);
  276. if( pLoggerInfo->Wnode.Guid == SystemTraceControlGuid ){
  277. WCHAR buffer[128];
  278. BSTR strGUID;
  279. StringFromGUID2( SystemTraceControlGuid, buffer, 128 );
  280. strGUID = SysAllocString( buffer );
  281. pGuidData[0] = strGUID;
  282. pLevelData[0] = 0;
  283. pFlagData[0] = pLoggerInfo->EnableFlags;
  284. }else{
  285. for (i=0; i < nGuidCount; i++) {
  286. if( pLoggerInfo->Wnode.HistoricalContext == GuidPropertiesArray[i]->LoggerId ){
  287. WCHAR buffer[128];
  288. BSTR strGUID;
  289. StringFromGUID2( GuidPropertiesArray[i]->Guid, buffer, 128 );
  290. strGUID = SysAllocString( buffer );
  291. pGuidData[nGuidIndex] = strGUID;
  292. pLevelData[nGuidIndex] = GuidPropertiesArray[i]->EnableLevel;
  293. pFlagData[nGuidIndex] = GuidPropertiesArray[i]->EnableFlags;
  294. nGuidIndex++;
  295. }
  296. }
  297. }
  298. SafeArrayUnaccessData( saGuids );
  299. SafeArrayUnaccessData( saFlags );
  300. SafeArrayUnaccessData( saLevel );
  301. VARIANT vArray;
  302. vArray.vt = VT_ARRAY|VT_I4;
  303. pInstance->SetStringArray( L"Guid", *saGuids );
  304. vArray.parray = saFlags;
  305. pInstance->SetVariant( L"EnableFlags", vArray );
  306. vArray.parray = saLevel;
  307. pInstance->SetVariant( L"Level", vArray );
  308. SafeArrayDestroy( saGuids );
  309. SafeArrayDestroy( saFlags );
  310. SafeArrayDestroy( saLevel );
  311. }
  312. }
  313. }
  314. pInstance->SetDWORD( L"BufferSize", pLoggerInfo->BufferSize );
  315. pInstance->SetDWORD( L"MinimumBuffers", pLoggerInfo->MinimumBuffers );
  316. pInstance->SetDWORD( L"MaximumBuffers", pLoggerInfo->MaximumBuffers );
  317. pInstance->SetDWORD( L"MaximumFileSize", pLoggerInfo->MaximumFileSize );
  318. pInstance->SetDWORD( L"FlushTimer", pLoggerInfo->FlushTimer );
  319. pInstance->SetDWORD( L"AgeLimit", pLoggerInfo->AgeLimit );
  320. pInstance->SetDWORD( L"LoggerId", pLoggerInfo->Wnode.HistoricalContext );
  321. pInstance->SetDWORD( L"NumberOfBuffers", pLoggerInfo->NumberOfBuffers );
  322. pInstance->SetDWORD( L"FreeBuffers", pLoggerInfo->FreeBuffers );
  323. pInstance->SetDWORD( L"EventsLost", pLoggerInfo->EventsLost );
  324. pInstance->SetDWORD( L"BuffersWritten", pLoggerInfo->BuffersWritten );
  325. pInstance->SetDWORD( L"LogBuffersLost", pLoggerInfo->LogBuffersLost );
  326. pInstance->SetDWORD( L"RealTimeBuffersLost",pLoggerInfo->RealTimeBuffersLost );
  327. pInstance->SetDWORD( L"LoggerThreadId", HandleToUlong( pLoggerInfo->LoggerThreadId ) );
  328. DecodePropertyValue(
  329. pInstance,
  330. L"LogFileMode",
  331. &pLoggerInfo->LogFileMode,
  332. DECODE_MODE_TRACE_TO_WBEM );
  333. DecodePropertyValue(
  334. pInstance,
  335. L"ClockType",
  336. &pLoggerInfo->Wnode.ClientContext,
  337. DECODE_MODE_TRACE_TO_WBEM );
  338. strName = (LPWSTR)((char*)pLoggerInfo+pLoggerInfo->LoggerNameOffset);
  339. pInstance->SetCHString( L"Name", strName );
  340. strName = (LPWSTR)((char*)pLoggerInfo+pLoggerInfo->LogFileNameOffset );
  341. pInstance->SetCHString( L"LogFileName", strName );
  342. return WBEM_S_NO_ERROR;
  343. }
  344. HRESULT
  345. CEventTrace::DecodePropertyValue(
  346. CInstance* pInstance,
  347. LPCWSTR szProperty,
  348. DWORD* pdwValue,
  349. DWORD dwFlags )
  350. {
  351. HRESULT hr = ERROR_SUCCESS;
  352. DWORD dwValue = 0;
  353. CHString Property;
  354. DWORD dwValueType = VALUETYPE_INDEX;
  355. if( NULL == pdwValue ){
  356. return WBEM_E_INVALID_PARAMETER;
  357. }
  358. if( dwFlags & DECODE_MODE_WBEM_TO_TRACE ){
  359. *pdwValue = 0;
  360. pInstance->GetCHString( szProperty, Property );
  361. if( ! Property.GetLength() ){
  362. return hr;
  363. }
  364. }else{
  365. dwValue = *pdwValue;
  366. }
  367. IWbemClassObject* pClass = pInstance->GetClassObjectInterface();
  368. if( pClass != NULL ){
  369. const ULONG cchBuffer = 1024;
  370. WCHAR buffer[cchBuffer] = L"";
  371. LONG nFlavor;
  372. VARIANT var;
  373. SAFEARRAY* saValues = NULL;
  374. SAFEARRAY* saValueMap = NULL;
  375. IWbemQualifierSet *pQualSet = NULL;
  376. pClass->GetPropertyQualifierSet( szProperty, &pQualSet );
  377. if( pQualSet != NULL ){
  378. hr = pQualSet->Get( L"ValueMap", 0, &var, &nFlavor );
  379. if( ERROR_SUCCESS == hr && (var.vt & VT_ARRAY) ){
  380. saValueMap = var.parray;
  381. }
  382. hr = pQualSet->Get( L"Values", 0, &var, &nFlavor );
  383. if( SUCCEEDED(hr) && (var.vt & VT_ARRAY) ){
  384. saValues = var.parray;
  385. }
  386. hr = pQualSet->Get( L"ValueType", 0, &var, &nFlavor );
  387. if( SUCCEEDED(hr) ){
  388. if( _wcsicmp( var.bstrVal, L"index" ) == 0 ){
  389. dwValueType = VALUETYPE_INDEX;
  390. }
  391. if( _wcsicmp( var.bstrVal, L"flag") == 0 ){
  392. dwValueType = VALUETYPE_FLAG;
  393. }
  394. }
  395. if( saValues != NULL && saValueMap != NULL ){
  396. BSTR HUGEP *pMapData;
  397. BSTR HUGEP *pValuesData;
  398. LONG uMapBound, lMapBound;
  399. LONG uValuesBound, lValuesBound;
  400. hr = SafeArrayGetUBound( saValueMap, 1, &uMapBound );
  401. if( SUCCEEDED(hr) ){
  402. hr = SafeArrayGetLBound( saValueMap, 1, &lMapBound );
  403. }
  404. if( SUCCEEDED(hr) ){
  405. hr = SafeArrayAccessData( saValueMap, (void HUGEP **)&pMapData );
  406. }
  407. if( SUCCEEDED(hr) ){
  408. hr = SafeArrayGetUBound( saValues, 1, &uValuesBound );
  409. }
  410. if( SUCCEEDED(hr) ){
  411. hr = SafeArrayGetLBound( saValues, 1, &lValuesBound );
  412. }
  413. if( SUCCEEDED(hr) ){
  414. hr = SafeArrayAccessData( saValues, (void HUGEP **)&pValuesData );
  415. }
  416. for ( LONG i=lMapBound; i<=uMapBound && SUCCEEDED(hr); i++) {
  417. LONG dwFlag;
  418. if( i<lValuesBound || i>uValuesBound ){
  419. break;
  420. }
  421. dwFlag = hextoi( pMapData[i] );
  422. if( dwFlags & DECODE_MODE_WBEM_TO_TRACE ){
  423. if( FindString( pValuesData[i], (LPCWSTR)Property ) ){
  424. switch( dwValueType ){
  425. case VALUETYPE_INDEX:
  426. dwValue = dwFlag;
  427. break;
  428. case VALUETYPE_FLAG:
  429. dwValue |= dwFlag;
  430. break;
  431. }
  432. }
  433. }else{
  434. BOOL bValue = FALSE;
  435. switch( dwValueType ){
  436. case VALUETYPE_INDEX:
  437. bValue = (dwFlag == dwValue);
  438. break;
  439. case VALUETYPE_FLAG:
  440. bValue = ((dwFlag & dwValue) == dwFlag );
  441. break;
  442. }
  443. if( bValue ){
  444. if( wcslen(buffer) ){
  445. hr = StringCchCat( buffer, cchBuffer, L"|" );
  446. }
  447. if( SUCCEEDED( hr ) ){
  448. hr = StringCchCat( buffer, cchBuffer, pValuesData[i] );
  449. }
  450. }
  451. }
  452. }
  453. SafeArrayUnaccessData( saValueMap );
  454. SafeArrayUnaccessData( saValues );
  455. SafeArrayDestroy( saValueMap );
  456. SafeArrayDestroy( saValues );
  457. if( dwFlags & DECODE_MODE_TRACE_TO_WBEM ){
  458. if( wcslen( buffer ) ){
  459. pInstance->SetCHString( szProperty, buffer );
  460. }else{
  461. hr = pQualSet->Get( L"DefaultValue", 0, &var, &nFlavor );
  462. if( ERROR_SUCCESS == hr && VT_BSTR == var.vt ){
  463. pInstance->SetCHString( szProperty, var.bstrVal );
  464. VariantClear( &var );
  465. }
  466. }
  467. }else if( dwFlags & DECODE_MODE_WBEM_TO_TRACE ){
  468. *pdwValue = dwValue;
  469. }
  470. }
  471. pQualSet->Release();
  472. }
  473. }
  474. return hr;
  475. }
  476. HRESULT CEventTrace::PutInstance ( const CInstance &Instance, long lFlags )
  477. {
  478. HRESULT hr = WBEM_E_UNSUPPORTED_PARAMETER;
  479. CHString LoggerName;
  480. CHString LogFileName;
  481. SAFEARRAY *saGuids = NULL;
  482. SAFEARRAY *saLevel = NULL;
  483. SAFEARRAY *saFlags = NULL;
  484. GUID guid = {0};
  485. DWORD dwValue;
  486. LPWSTR strName;
  487. LPWSTR strFile;
  488. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  489. TRACEHANDLE LoggerHandle = 0;
  490. BSTR HUGEP *pGuidData;
  491. VARIANT vArray;
  492. LONG lBound;
  493. if ( !(lFlags & WBEM_FLAG_CREATE_ONLY|WBEM_FLAG_UPDATE_ONLY ) ){
  494. return hr;
  495. }
  496. hr = InitTraceProperties( &pLoggerInfo );
  497. if( hr != ERROR_SUCCESS ){
  498. return hr;
  499. }
  500. Instance.GetCHString( L"Name", LoggerName );
  501. strName = (LPWSTR)((char*)pLoggerInfo + pLoggerInfo->LoggerNameOffset );
  502. hr = StringCchCopy( strName, MAXSTR, (LPCWSTR)LoggerName );
  503. if( FAILED(hr) ){
  504. return hr;
  505. }
  506. Instance.GetCHString( L"LogFileName", LogFileName );
  507. strFile = (LPWSTR)((char*)pLoggerInfo + pLoggerInfo->LogFileNameOffset );
  508. hr = StringCchCopy( strFile, MAXSTR, (LPCWSTR)LogFileName );
  509. if( FAILED(hr) ){
  510. return hr;
  511. }
  512. Instance.GetDWORD( L"BufferSize", pLoggerInfo->BufferSize );
  513. Instance.GetDWORD( L"MinimumBuffers", pLoggerInfo->MinimumBuffers );
  514. Instance.GetDWORD( L"MaximumBuffers", pLoggerInfo->MaximumBuffers );
  515. Instance.GetDWORD( L"MaximumFileSize", pLoggerInfo->MaximumFileSize );
  516. Instance.GetDWORD( L"FlushTimer", pLoggerInfo->FlushTimer );
  517. hr = DecodePropertyValue(
  518. (CInstance*)&Instance,
  519. L"LogFileMode",
  520. &dwValue,
  521. DECODE_MODE_WBEM_TO_TRACE );
  522. if( SUCCEEDED(hr) ){
  523. pLoggerInfo->LogFileMode = dwValue;
  524. }
  525. hr = DecodePropertyValue(
  526. (CInstance*)&Instance,
  527. L"ClockType",
  528. &dwValue,
  529. DECODE_MODE_WBEM_TO_TRACE );
  530. if( SUCCEEDED(hr) ){
  531. pLoggerInfo->Wnode.ClientContext = dwValue;
  532. }
  533. hr = WBEM_S_NO_ERROR;
  534. if(! Instance.GetStringArray( L"Guid", saGuids ) ){
  535. saGuids = NULL;
  536. }
  537. Instance.GetVariant( L"EnableFlags", vArray );
  538. if( VT_NULL != vArray.vt ){
  539. saFlags = vArray.parray;
  540. }
  541. Instance.GetVariant( L"Level", vArray );
  542. if( VT_NULL != vArray.vt ){
  543. saLevel = vArray.parray;
  544. }
  545. if( saGuids != NULL ){
  546. //
  547. // Need to check the guids now in case it
  548. // is the kernel logger. The kernel logger
  549. // is handled differently for both Create and Update
  550. //
  551. hr = SafeArrayGetLBound( saGuids, 1, &lBound );
  552. if( SUCCEEDED(hr) ){
  553. hr = SafeArrayAccessData( saGuids, (void HUGEP **)&pGuidData );
  554. }
  555. if( SUCCEEDED(hr) ){
  556. CLSIDFromString( pGuidData[lBound], &guid );
  557. SafeArrayUnaccessData( saGuids );
  558. }
  559. }
  560. BOOL bSystemLogger = IsEqualGUID( gCritSecGuid, guid ) || IsEqualGUID( gHeapGuid, guid );
  561. if (lFlags & WBEM_FLAG_CREATE_ONLY){
  562. if( IsEqualGUID( guid, SystemTraceControlGuid ) || bSystemLogger ){
  563. ULONG offset = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAXSTR * sizeof(WCHAR);
  564. pLoggerInfo->Wnode.Guid = guid;
  565. if( bSystemLogger ){
  566. pLoggerInfo->LogFileMode |= EVENT_TRACE_PRIVATE_LOGGER_MODE;
  567. pLoggerInfo->Wnode.HistoricalContext = 0x1000001;
  568. }
  569. hr = EtsSetExtendedFlags(
  570. saFlags,
  571. pLoggerInfo,
  572. offset
  573. );
  574. hr = StartTrace( &LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  575. if( ERROR_SUCCESS == hr && bSystemLogger ){
  576. hr = WmiEnableTrace( Instance, TRUE, saFlags, saLevel, saGuids, LoggerHandle );
  577. }
  578. }else if( LoggerName.CompareNoCase( cszGlobalLogger) == 0 ){
  579. hr = StartGlobalLogger( pLoggerInfo );
  580. }else{
  581. if( pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE ){
  582. pLoggerInfo->Wnode.Guid = guid;
  583. }
  584. hr = StartTrace( &LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  585. if( ERROR_SUCCESS == hr ){
  586. hr = WmiEnableTrace( Instance, TRUE, saFlags, saLevel, saGuids, LoggerHandle );
  587. }
  588. }
  589. }else if( lFlags & WBEM_FLAG_UPDATE_ONLY ){
  590. Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
  591. if( IsEqualGUID( guid, SystemTraceControlGuid ) || bSystemLogger ){
  592. //
  593. // The kernel logger does not use EnableTrace.
  594. // Set the flags and call Update Only
  595. //
  596. ULONG offset = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAXSTR * sizeof(WCHAR);
  597. hr = EtsSetExtendedFlags(
  598. saFlags,
  599. pLoggerInfo,
  600. offset
  601. );
  602. if( bSystemLogger ){
  603. pLoggerInfo->Wnode.Guid = guid;
  604. }
  605. hr = UpdateTrace( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  606. }else{
  607. hr = UpdateTrace( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  608. if( ERROR_SUCCESS == hr ){
  609. hr = WmiEnableTrace( Instance, TRUE, saFlags, saLevel, saGuids, LoggerHandle );
  610. }
  611. }
  612. }
  613. if( NULL != saGuids ){
  614. SafeArrayDestroy( saGuids );
  615. }
  616. if( NULL != saFlags ){
  617. SafeArrayDestroy( saFlags );
  618. }
  619. if( NULL != saLevel ){
  620. SafeArrayDestroy( saLevel );
  621. }
  622. G_FREE( pLoggerInfo );
  623. return hr;
  624. }
  625. HRESULT CEventTrace::InitTraceProperties( PEVENT_TRACE_PROPERTIES* ppLoggerInfo )
  626. {
  627. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  628. DWORD dwSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(WCHAR)*MAXSTR*2 + EtsGetMaxEnableFlags() * sizeof(ULONG);
  629. pLoggerInfo = (PEVENT_TRACE_PROPERTIES)G_ALLOC( dwSize );
  630. if( NULL == pLoggerInfo ){
  631. return ERROR_OUTOFMEMORY;
  632. }
  633. ZeroMemory( pLoggerInfo, dwSize );
  634. pLoggerInfo->Wnode.BufferSize = dwSize;
  635. pLoggerInfo->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  636. pLoggerInfo->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  637. pLoggerInfo->LogFileNameOffset = pLoggerInfo->LoggerNameOffset+MAXSTR*sizeof(WCHAR);
  638. *ppLoggerInfo = pLoggerInfo;
  639. return ERROR_SUCCESS;
  640. }
  641. HRESULT
  642. CEventTrace::WmiEnableTrace(
  643. const CInstance &Instance,
  644. bool bEnable,
  645. SAFEARRAY *saFlags,
  646. SAFEARRAY *saLevel,
  647. SAFEARRAY *saGuid,
  648. TRACEHANDLE LoggerHandle
  649. )
  650. {
  651. HRESULT hr = ERROR_SUCCESS;
  652. BSTR HUGEP *pGuidData = NULL;
  653. DWORD HUGEP *pFlagData = NULL;
  654. DWORD HUGEP *pLevelData = NULL;
  655. LONG lGuidBound,uGuidBound;
  656. LONG lFlagBound,uFlagBound;
  657. LONG lLevelBound,uLevelBound;
  658. if( NULL == saGuid ){
  659. return ERROR_SUCCESS;
  660. }
  661. hr = SafeArrayGetUBound( saGuid, 1, &uGuidBound );
  662. if( FAILED(hr) ){ return hr; }
  663. hr = SafeArrayGetLBound( saGuid, 1, &lGuidBound );
  664. if( FAILED(hr) ){ return hr; }
  665. hr = SafeArrayAccessData( saGuid, (void HUGEP **)&pGuidData );
  666. if( FAILED(hr) ){ return hr; }
  667. if( saFlags != NULL ){
  668. hr = SafeArrayGetUBound( saFlags, 1, &uFlagBound );
  669. if( SUCCEEDED(hr) ){
  670. hr = SafeArrayGetLBound( saFlags, 1, &lFlagBound );
  671. }
  672. if( SUCCEEDED(hr) ){
  673. hr = SafeArrayAccessData( saFlags, (void HUGEP **)&pFlagData );
  674. }
  675. }
  676. if( NULL == saFlags || FAILED(hr) ){
  677. uFlagBound = 0;
  678. lFlagBound = 0;
  679. }
  680. if( saLevel != NULL ){
  681. hr = SafeArrayGetUBound( saLevel, 1, &uLevelBound );
  682. if(SUCCEEDED(hr) ){
  683. hr = SafeArrayGetLBound( saLevel, 1, &lLevelBound );
  684. }
  685. if(SUCCEEDED(hr) ){
  686. hr = SafeArrayAccessData( saLevel, (void HUGEP **)&pLevelData );
  687. }
  688. }
  689. if( NULL == saLevel || FAILED(hr) ){
  690. uLevelBound = 0;
  691. lLevelBound = 0;
  692. }
  693. for ( LONG i=lGuidBound; i<=uGuidBound; i++) {
  694. GUID guid;
  695. DWORD dwLevel = 0;
  696. DWORD dwFlags = 0;
  697. if( pGuidData[i] == NULL ){
  698. continue;
  699. }
  700. if( SUCCEEDED( CLSIDFromString( pGuidData[i], &guid ) ) ){
  701. if( i>=lLevelBound && i<=uLevelBound && saLevel != NULL ){
  702. if( NULL != pLevelData ){
  703. dwLevel = pLevelData[i];
  704. }
  705. }
  706. if( i>=lFlagBound && i<=uFlagBound && saFlags != NULL ){
  707. if( NULL != pFlagData ){
  708. dwFlags = pFlagData[i];
  709. }
  710. }
  711. hr = EnableTrace( bEnable, dwFlags, dwLevel, &guid, LoggerHandle );
  712. if(IsEqualGUID( gCritSecGuid, guid ) || IsEqualGUID( gHeapGuid, guid )){
  713. break;
  714. }
  715. }
  716. }
  717. SafeArrayUnaccessData( saGuid );
  718. if( saFlags != NULL ){
  719. SafeArrayUnaccessData( saFlags );
  720. }
  721. if( saLevel != NULL ){
  722. SafeArrayUnaccessData( saLevel );
  723. }
  724. return hr;
  725. }
  726. HRESULT CEventTrace::WmiFlushTrace( const CInstance &Instance )
  727. {
  728. HRESULT hr;
  729. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  730. TRACEHANDLE LoggerHandle = 0;
  731. CHString LoggerName;
  732. hr = InitTraceProperties( &pLoggerInfo );
  733. if( hr == ERROR_SUCCESS ){
  734. Instance.GetCHString( L"Name", LoggerName );
  735. Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
  736. hr = ::FlushTraceW( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  737. G_FREE( pLoggerInfo );
  738. }
  739. return hr;
  740. }
  741. HRESULT CEventTrace::WmiStopTrace( const CInstance &Instance )
  742. {
  743. HRESULT hr;
  744. CHString LoggerName;
  745. SAFEARRAY *saGuids = NULL;
  746. LONG nGuidCount,i;
  747. GUID guid;
  748. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  749. TRACEHANDLE LoggerHandle = 0;
  750. BSTR HUGEP *pData;
  751. Instance.GetCHString( L"Name", LoggerName );
  752. hr = InitTraceProperties( &pLoggerInfo );
  753. if( ERROR_SUCCESS != hr ){
  754. return hr;
  755. }
  756. if( wcsncmp( (LPCWSTR)LoggerName, cszPrivateLogger, wcslen( cszPrivateLogger ) ) == 0 ){
  757. LPWSTR szPrivateGuid;
  758. size_t cchSize;
  759. szPrivateGuid = (LPWSTR)(LPCWSTR)LoggerName;
  760. cchSize = wcslen( szPrivateGuid );
  761. if( cchSize + 1 > wcslen( cszPrivateLogger ) ){
  762. szPrivateGuid += wcslen( cszPrivateLogger ) + 1;
  763. CLSIDFromString( szPrivateGuid, &guid );
  764. pLoggerInfo->Wnode.Guid = guid;
  765. pLoggerInfo->LogFileMode = EVENT_TRACE_PRIVATE_LOGGER_MODE;
  766. hr = ::StopTrace( 0, (LPCWSTR)LoggerName, pLoggerInfo );
  767. }else{
  768. hr = WBEM_E_INVALID_PARAMETER;
  769. }
  770. }else{
  771. Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
  772. Instance.GetStringArray( L"Guid", saGuids );
  773. if( NULL != saGuids ){
  774. hr = SafeArrayGetUBound( saGuids, 0, &nGuidCount );
  775. if( SUCCEEDED(hr) ){
  776. hr = SafeArrayAccessData( saGuids, (void HUGEP **)&pData );
  777. }
  778. if( SUCCEEDED(hr) ){
  779. for (i=0; i<nGuidCount; i++) {
  780. CLSIDFromString( pData[i], &guid );
  781. hr = EnableTrace( FALSE, 0, 0, &guid, LoggerHandle );
  782. }
  783. SafeArrayUnaccessData( saGuids );
  784. }
  785. SafeArrayDestroy( saGuids );
  786. }
  787. hr = ::StopTraceW( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  788. if( LoggerName.CompareNoCase( cszGlobalLogger ) == 0 ){
  789. hr = DeleteGlobalLogger( pLoggerInfo );
  790. }
  791. G_FREE( pLoggerInfo );
  792. }
  793. return hr;
  794. }
  795. HRESULT
  796. CEventTrace::StartGlobalLogger(
  797. IN PEVENT_TRACE_PROPERTIES pLoggerInfo
  798. )
  799. {
  800. return (SetGlobalLoggerSettings( 1L, pLoggerInfo, 0 ));
  801. }
  802. HRESULT
  803. CEventTrace::DeleteGlobalLogger(
  804. IN PEVENT_TRACE_PROPERTIES pLoggerInfo
  805. )
  806. {
  807. return (SetGlobalLoggerSettings( 0L, pLoggerInfo, 0 ) );
  808. }
  809. HRESULT
  810. CEventTrace::ExecMethod(
  811. const CInstance& Instance,
  812. const BSTR bstrMethodName,
  813. CInstance *pInParams,
  814. CInstance *pOutParams,
  815. long lFlags
  816. )
  817. {
  818. HRESULT hr = WBEM_E_PROVIDER_NOT_CAPABLE;
  819. HRESULT hResult = ERROR_SUCCESS;
  820. if( _wcsicmp( bstrMethodName, L"FlushTrace") == 0 ){
  821. hResult = WmiFlushTrace( Instance );
  822. hr = WBEM_S_NO_ERROR;
  823. }
  824. if( _wcsicmp( bstrMethodName, L"StopTrace") == 0 ){
  825. hResult = WmiStopTrace( Instance );
  826. hr = WBEM_S_NO_ERROR;
  827. }
  828. if( _wcsicmp( bstrMethodName, L"EnableTrace") == 0 ){
  829. bool bEnable;
  830. SAFEARRAY *saGuids = NULL;
  831. SAFEARRAY *saLevel = NULL;
  832. SAFEARRAY *saFlags = NULL;
  833. VARIANT vArray;
  834. TRACEHANDLE LoggerHandle;
  835. pInParams->Getbool( L"Enable", bEnable );
  836. pInParams->GetStringArray( L"Guid", saGuids );
  837. pInParams->GetVariant( L"Flags", vArray );
  838. saFlags = vArray.parray;
  839. pInParams->GetVariant( L"Level", vArray );
  840. saLevel = vArray.parray;
  841. Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
  842. hResult = WmiEnableTrace( Instance, bEnable, saFlags, saLevel, saGuids, LoggerHandle );
  843. if( NULL != saGuids ){
  844. SafeArrayDestroy( saGuids );
  845. }
  846. if( NULL != saFlags ){
  847. SafeArrayDestroy( saFlags );
  848. }
  849. if( NULL != saLevel ){
  850. SafeArrayDestroy( saLevel );
  851. }
  852. hr = WBEM_S_NO_ERROR;
  853. }
  854. pOutParams->SetDWORD( L"ReturnValue", hResult );
  855. return hr;
  856. }