Source code of Windows XP (NT5)
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.

844 lines
25 KiB

  1. /*****************************************************************************\
  2. Author: Corey Morgan (coreym)
  3. Copyright (c) 1998-2000 Microsoft Corporation
  4. \*****************************************************************************/
  5. #include <fwcommon.h>
  6. #include "evntrprv.h"
  7. LPCWSTR cszGlobalLogger = L"GlobalLogger";
  8. LPCWSTR cszKernelLogger = L"NT Kernel Logger";
  9. _COM_SMARTPTR_TYPEDEF(CInstance, __uuidof(CInstance));
  10. HRESULT
  11. SetGlobalLoggerSettings(
  12. DWORD StartValue,
  13. PEVENT_TRACE_PROPERTIES LoggerInfo,
  14. DWORD ClockType
  15. );
  16. ULONG hextoi( LPWSTR s )
  17. {
  18. long len;
  19. ULONG num, base, hex;
  20. if (s == NULL || s[0] == L'\0') {
  21. return 0;
  22. }
  23. len = (long) wcslen(s);
  24. if (len == 0) {
  25. return 0;
  26. }
  27. hex = 0;
  28. base = 1;
  29. num = 0;
  30. while (-- len >= 0) {
  31. if (s[len] >= L'0' && s[len] <= L'9'){
  32. num = s[len] - L'0';
  33. }else if (s[len] >= L'a' && s[len] <= L'f'){
  34. num = (s[len] - L'a') + 10;
  35. }else if (s[len] >= L'A' && s[len] <= L'F'){
  36. num = (s[len] - L'A') + 10;
  37. }else if( s[len] == L'x' || s[len] == L'X'){
  38. break;
  39. }else{
  40. continue;
  41. }
  42. hex += num * base;
  43. base = base * 16;
  44. }
  45. return hex;
  46. }
  47. CEventTrace SystemEventTraceProv( PROVIDER_NAME_EVENTTRACE, L"root\\wmi" );
  48. const static WCHAR* pEventTraceErrorClass = L"\\\\.\\root\\wmi:EventTraceError";
  49. CEventTrace::CEventTrace (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
  50. Provider(lpwszName, lpwszNameSpace)
  51. {
  52. }
  53. CEventTrace::~CEventTrace ()
  54. {
  55. }
  56. HRESULT
  57. CEventTrace::EnumerateInstances( MethodContext* pMethodContext, long lFlags )
  58. {
  59. HRESULT hr = WBEM_S_NO_ERROR;
  60. ULONG i, nLoggers;
  61. DWORD dwSize;
  62. PEVENT_TRACE_PROPERTIES pLoggerInfo[MAXIMUM_LOGGERS];
  63. PEVENT_TRACE_PROPERTIES pStorage;
  64. PVOID Storage;
  65. PVOID GuidStorage = NULL;
  66. PTRACE_GUID_PROPERTIES* GuidPropertiesArray = NULL;
  67. ULONG nGuidCount = 0;
  68. dwSize = MAXIMUM_LOGGERS*(sizeof(EVENT_TRACE_PROPERTIES)+2*MAXSTR*sizeof(TCHAR));
  69. Storage = G_ALLOC(dwSize);
  70. if( Storage == NULL ){
  71. return ERROR_OUTOFMEMORY;
  72. }
  73. RtlZeroMemory(Storage, dwSize);
  74. pStorage = (PEVENT_TRACE_PROPERTIES)Storage;
  75. for (i=0; i<MAXIMUM_LOGGERS; i++) {
  76. pStorage->Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES)+2*MAXSTR*sizeof(TCHAR);
  77. pStorage->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES)+MAXSTR*sizeof(TCHAR);
  78. pStorage->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  79. pLoggerInfo[i] = pStorage;
  80. pStorage = (PEVENT_TRACE_PROPERTIES)( (char*)pStorage + pStorage->Wnode.BufferSize);
  81. }
  82. hr = QueryAllTraces(
  83. pLoggerInfo,
  84. MAXIMUM_LOGGERS,
  85. &nLoggers
  86. );
  87. if( ERROR_SUCCESS == hr ){
  88. try{
  89. if( ERROR_SUCCESS == LoadGuidArray( &GuidStorage, &nGuidCount ) ){
  90. GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)GuidStorage;
  91. }
  92. for( i=0; i<nLoggers && i<MAXIMUM_LOGGERS; i++){
  93. CInstancePtr pInstance( CreateNewInstance(pMethodContext), false );
  94. assert( NULL != pLoggerInfo[i] );
  95. if( NULL != pInstance ){
  96. if( SUCCEEDED( LoadPropertyValues(pInstance, pLoggerInfo[i], GuidPropertiesArray, nGuidCount ) )){
  97. hr = pInstance->Commit();
  98. }
  99. }
  100. }
  101. }catch(...){
  102. hr = WBEM_E_OUT_OF_MEMORY;
  103. }
  104. }
  105. G_FREE( GuidStorage );
  106. G_FREE( Storage );
  107. return hr;
  108. }
  109. HRESULT CEventTrace::GetObject ( CInstance* pInstance, long lFlags )
  110. {
  111. HRESULT hr = WBEM_E_NOT_FOUND;
  112. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  113. TRACEHANDLE LoggerHandle = 0;
  114. CHString LoggerName;
  115. pInstance->GetCHString( L"Name", LoggerName );
  116. hr = InitTraceProperties( &pLoggerInfo );
  117. if( ERROR_SUCCESS == hr ){
  118. hr = QueryTraceW( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo);
  119. if( hr == ERROR_SUCCESS ){
  120. PVOID GuidStorage = NULL;
  121. PTRACE_GUID_PROPERTIES* GuidPropertiesArray = NULL;
  122. ULONG nGuidCount = 0;
  123. try{
  124. if( ERROR_SUCCESS == LoadGuidArray( &GuidStorage, &nGuidCount ) ){
  125. GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)GuidStorage;
  126. }
  127. hr = LoadPropertyValues( pInstance, pLoggerInfo, GuidPropertiesArray, nGuidCount );
  128. }catch(...){
  129. hr = WBEM_E_OUT_OF_MEMORY;
  130. }
  131. G_FREE( GuidStorage );
  132. }
  133. G_FREE( pLoggerInfo );
  134. }
  135. return hr;
  136. }
  137. HRESULT CEventTrace::LoadGuidArray( PVOID* Storage, PULONG pnGuidCount )
  138. {
  139. ULONG i;
  140. ULONG nGuidArray = 16;
  141. ULONG nGuidCount = 0;
  142. DWORD dwSize;
  143. PTRACE_GUID_PROPERTIES* GuidPropertiesArray;
  144. PTRACE_GUID_PROPERTIES pStorage;
  145. HRESULT hr;
  146. do{
  147. dwSize = nGuidArray * (sizeof(TRACE_GUID_PROPERTIES) + sizeof(PTRACE_GUID_PROPERTIES));
  148. *Storage = G_ALLOC(dwSize);
  149. if(*Storage == NULL){
  150. hr = WBEM_E_OUT_OF_MEMORY;
  151. break;
  152. }
  153. RtlZeroMemory(*Storage, dwSize);
  154. GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)(*Storage);
  155. pStorage = (PTRACE_GUID_PROPERTIES)((char*)(*Storage) + nGuidArray * sizeof(PTRACE_GUID_PROPERTIES));
  156. for (i=0; i < nGuidArray; i++) {
  157. GuidPropertiesArray[i] = pStorage;
  158. pStorage = (PTRACE_GUID_PROPERTIES)((char*)pStorage + sizeof(TRACE_GUID_PROPERTIES));
  159. }
  160. hr = EnumerateTraceGuids(GuidPropertiesArray,nGuidArray,&nGuidCount);
  161. if(hr == ERROR_MORE_DATA){
  162. if( nGuidCount <= nGuidArray ){
  163. hr = WBEM_E_INVALID_PARAMETER;
  164. break;
  165. }
  166. nGuidArray = nGuidCount;
  167. G_FREE(*Storage);
  168. (*Storage) = NULL;
  169. }
  170. }while( hr == ERROR_MORE_DATA );
  171. if( ERROR_SUCCESS == hr ){
  172. *pnGuidCount = nGuidCount;
  173. }else{
  174. *pnGuidCount = 0;
  175. }
  176. return hr;
  177. }
  178. HRESULT
  179. CEventTrace::LoadPropertyValues(
  180. CInstance *pInstanceParam,
  181. PEVENT_TRACE_PROPERTIES pLoggerInfo,
  182. PTRACE_GUID_PROPERTIES *GuidPropertiesArray,
  183. ULONG nGuidCount
  184. )
  185. {
  186. LPTSTR strName;
  187. ULONG i;
  188. CInstance* pInstance = pInstanceParam;
  189. if( NULL == pLoggerInfo || NULL == pInstance ){
  190. return WBEM_E_INVALID_PARAMETER;
  191. }
  192. if( NULL != GuidPropertiesArray ){
  193. SAFEARRAY *saGuids;
  194. SAFEARRAY *saFlags;
  195. SAFEARRAY *saLevel;
  196. BSTR HUGEP *pGuidData;
  197. DWORD HUGEP *pLevelData;
  198. DWORD HUGEP *pFlagData;
  199. ULONG nGuidIndex = 0;
  200. ULONG nProviderGuids = 0;
  201. if( pLoggerInfo->Wnode.Guid == SystemTraceControlGuid ){
  202. nProviderGuids = 1;
  203. }else{
  204. for (i=0; i < nGuidCount; i++) {
  205. if( pLoggerInfo->Wnode.HistoricalContext == GuidPropertiesArray[i]->LoggerId ){
  206. nProviderGuids++;
  207. }
  208. }
  209. }
  210. if( nProviderGuids ){
  211. saGuids = SafeArrayCreateVector( VT_BSTR, 0, nProviderGuids );
  212. saFlags = SafeArrayCreateVector( VT_I4, 0, nProviderGuids );
  213. saLevel = SafeArrayCreateVector( VT_I4, 0, nProviderGuids );
  214. if( saGuids == NULL || saFlags == NULL || saLevel == NULL ){
  215. if( saGuids != NULL ){
  216. SafeArrayDestroy( saGuids );
  217. }
  218. if( saFlags != NULL ){
  219. SafeArrayDestroy( saFlags );
  220. }
  221. if( saLevel != NULL ){
  222. SafeArrayDestroy( saLevel );
  223. }
  224. }else{
  225. SafeArrayAccessData( saGuids, (void HUGEP **)&pGuidData);
  226. SafeArrayAccessData( saFlags, (void HUGEP **)&pFlagData);
  227. SafeArrayAccessData( saLevel, (void HUGEP **)&pLevelData);
  228. if( pLoggerInfo->Wnode.Guid == SystemTraceControlGuid ){
  229. WCHAR buffer[128];
  230. BSTR strGUID;
  231. StringFromGUID2( SystemTraceControlGuid, buffer, 128 );
  232. strGUID = SysAllocString( buffer );
  233. pGuidData[0] = strGUID;
  234. pLevelData[0] = 0;
  235. pFlagData[0] = pLoggerInfo->EnableFlags;
  236. }else{
  237. for (i=0; i < nGuidCount; i++) {
  238. if( pLoggerInfo->Wnode.HistoricalContext == GuidPropertiesArray[i]->LoggerId ){
  239. WCHAR buffer[128];
  240. BSTR strGUID;
  241. StringFromGUID2( GuidPropertiesArray[i]->Guid, buffer, 128 );
  242. strGUID = SysAllocString( buffer );
  243. pGuidData[nGuidIndex] = strGUID;
  244. pLevelData[nGuidIndex] = GuidPropertiesArray[i]->EnableLevel;
  245. pFlagData[nGuidIndex] = GuidPropertiesArray[i]->EnableFlags;
  246. nGuidIndex++;
  247. }
  248. }
  249. }
  250. SafeArrayUnaccessData( saGuids );
  251. SafeArrayUnaccessData( saFlags );
  252. SafeArrayUnaccessData( saLevel );
  253. VARIANT vArray;
  254. vArray.vt = VT_ARRAY|VT_I4;
  255. pInstance->SetStringArray( L"Guid", *saGuids );
  256. vArray.parray = saFlags;
  257. pInstance->SetVariant( L"EnableFlags", vArray );
  258. vArray.parray = saLevel;
  259. pInstance->SetVariant( L"Level", vArray );
  260. SafeArrayDestroy( saGuids );
  261. SafeArrayDestroy( saFlags );
  262. SafeArrayDestroy( saLevel );
  263. }
  264. }
  265. }
  266. pInstance->SetDWORD( L"BufferSize", pLoggerInfo->BufferSize );
  267. pInstance->SetDWORD( L"MinimumBuffers", pLoggerInfo->MinimumBuffers );
  268. pInstance->SetDWORD( L"MaximumBuffers", pLoggerInfo->MaximumBuffers );
  269. pInstance->SetDWORD( L"MaximumFileSize", pLoggerInfo->MaximumFileSize );
  270. pInstance->SetDWORD( L"FlushTimer", pLoggerInfo->FlushTimer );
  271. pInstance->SetDWORD( L"AgeLimit", pLoggerInfo->AgeLimit );
  272. pInstance->SetDWORD( L"LoggerId", pLoggerInfo->Wnode.HistoricalContext );
  273. pInstance->SetDWORD( L"NumberOfBuffers", pLoggerInfo->NumberOfBuffers );
  274. pInstance->SetDWORD( L"FreeBuffers", pLoggerInfo->FreeBuffers );
  275. pInstance->SetDWORD( L"EventsLost", pLoggerInfo->EventsLost );
  276. pInstance->SetDWORD( L"BuffersWritten", pLoggerInfo->BuffersWritten );
  277. pInstance->SetDWORD( L"LogBuffersLost", pLoggerInfo->LogBuffersLost );
  278. pInstance->SetDWORD( L"RealTimeBuffersLost",pLoggerInfo->RealTimeBuffersLost );
  279. pInstance->SetDWORD( L"LoggerThreadId", HandleToUlong( pLoggerInfo->LoggerThreadId ) );
  280. DecodeFileMode( pInstance, pLoggerInfo, DECODE_MODE_TRACE_TO_WBEM );
  281. strName = (LPTSTR)((char*)pLoggerInfo+pLoggerInfo->LoggerNameOffset);
  282. pInstance->SetCHString( L"Name", strName );
  283. strName = (LPTSTR)((char*)pLoggerInfo+pLoggerInfo->LogFileNameOffset );
  284. pInstance->SetCHString( L"LogFileName", strName );
  285. return WBEM_S_NO_ERROR;
  286. }
  287. HRESULT CEventTrace::DecodeFileMode( CInstance* pInstance, PEVENT_TRACE_PROPERTIES pLoggerInfo, DWORD dwFlags )
  288. {
  289. HRESULT hr = ERROR_SUCCESS;
  290. CHString LogFileMode;
  291. if( dwFlags & DECODE_MODE_WBEM_TO_TRACE ){
  292. pInstance->GetCHString( L"LogFileMode", LogFileMode );
  293. if( ! LogFileMode.GetLength() ){
  294. return hr;
  295. }
  296. }
  297. IWbemClassObject* pClass = pInstance->GetClassObjectInterface();
  298. if( pClass != NULL ){
  299. WCHAR buffer[1024] = L"";
  300. LONG nFlavor;
  301. VARIANT var;
  302. SAFEARRAY* saValues = NULL;
  303. SAFEARRAY* saValueMap = NULL;
  304. IWbemQualifierSet *pQualSet = NULL;
  305. pClass->GetPropertyQualifierSet( L"LogFileMode", &pQualSet );
  306. if( pQualSet != NULL ){
  307. hr = pQualSet->Get( L"ValueMap", 0, &var, &nFlavor );
  308. if( ERROR_SUCCESS == hr && (var.vt & VT_ARRAY) ){
  309. saValueMap = var.parray;
  310. }
  311. hr = pQualSet->Get( L"Values", 0, &var, &nFlavor );
  312. if( ERROR_SUCCESS == hr && (var.vt & VT_ARRAY) ){
  313. saValues = var.parray;
  314. }
  315. if( saValues != NULL && saValueMap != NULL ){
  316. BSTR HUGEP *pMapData;
  317. BSTR HUGEP *pValuesData;
  318. LONG uMapBound, lMapBound;
  319. LONG uValuesBound, lValuesBound;
  320. SafeArrayGetUBound( saValueMap, 1, &uMapBound );
  321. SafeArrayGetLBound( saValueMap, 1, &lMapBound );
  322. SafeArrayAccessData( saValueMap, (void HUGEP **)&pMapData );
  323. SafeArrayGetUBound( saValues, 1, &uValuesBound );
  324. SafeArrayGetLBound( saValues, 1, &lValuesBound );
  325. SafeArrayAccessData( saValues, (void HUGEP **)&pValuesData );
  326. for ( LONG i=lMapBound; i<=uMapBound; i++) {
  327. LONG dwFlag;
  328. if( i<lValuesBound || i>uValuesBound ){
  329. break;
  330. }
  331. dwFlag = hextoi( pMapData[i] );
  332. if( dwFlags & DECODE_MODE_WBEM_TO_TRACE ){
  333. if( LogFileMode.Find( pValuesData[i] ) >= 0 ){
  334. pLoggerInfo->LogFileMode |= dwFlag;
  335. }
  336. }else{
  337. if( dwFlag & pLoggerInfo->LogFileMode ){
  338. if( wcslen(buffer) ){
  339. wcscat( buffer, L"|" );
  340. }
  341. wcscat( buffer, pValuesData[i] );
  342. }
  343. }
  344. }
  345. SafeArrayUnaccessData( saValueMap );
  346. SafeArrayUnaccessData( saValues );
  347. SafeArrayDestroy( saValueMap );
  348. SafeArrayDestroy( saValues );
  349. if( dwFlags & DECODE_MODE_TRACE_TO_WBEM ){
  350. if( wcslen( buffer ) ){
  351. pInstance->SetCHString( L"LogFileMode", buffer );
  352. }else{
  353. hr = pQualSet->Get( L"DefaultValue", 0, &var, &nFlavor );
  354. if( ERROR_SUCCESS == hr && VT_BSTR == var.vt ){
  355. pInstance->SetCHString( L"LogFileMode", var.bstrVal );
  356. VariantClear( &var );
  357. }
  358. }
  359. }
  360. }
  361. pQualSet->Release();
  362. }
  363. }
  364. return hr;
  365. }
  366. HRESULT CEventTrace::PutInstance ( const CInstance &Instance, long lFlags )
  367. {
  368. HRESULT hr = WBEM_E_UNSUPPORTED_PARAMETER;
  369. CHString LoggerName;
  370. CHString LogFileName;
  371. SAFEARRAY *saGuids = NULL;
  372. SAFEARRAY *saLevel = NULL;
  373. SAFEARRAY *saFlags = NULL;
  374. GUID guid = {0};
  375. LPWSTR strName;
  376. LPWSTR strFile;
  377. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  378. TRACEHANDLE LoggerHandle = 0;
  379. BSTR HUGEP *pGuidData;
  380. VARIANT vArray;
  381. if ( !(lFlags & WBEM_FLAG_CREATE_ONLY|WBEM_FLAG_UPDATE_ONLY ) ){
  382. return hr;
  383. }
  384. hr = InitTraceProperties( &pLoggerInfo );
  385. if( hr != ERROR_SUCCESS ){
  386. return hr;
  387. }
  388. Instance.GetCHString( L"Name", LoggerName );
  389. strName = (LPWSTR)((char*)pLoggerInfo + pLoggerInfo->LoggerNameOffset );
  390. if( wcslen( (LPCWSTR)LoggerName ) >= MAXSTR ){
  391. return WBEM_E_INVALID_PARAMETER;
  392. }
  393. wcscpy( strName, (LPCWSTR)LoggerName );
  394. Instance.GetCHString( L"LogFileName", LogFileName );
  395. strFile = (LPWSTR)((char*)pLoggerInfo + pLoggerInfo->LogFileNameOffset );
  396. if( wcslen( (LPCWSTR)LogFileName ) >= MAXSTR ){
  397. return WBEM_E_INVALID_PARAMETER;
  398. }
  399. wcscpy( strFile, (LPCWSTR)LogFileName );
  400. Instance.GetDWORD( L"BufferSize", pLoggerInfo->BufferSize );
  401. Instance.GetDWORD( L"MinimumBuffers", pLoggerInfo->MinimumBuffers );
  402. Instance.GetDWORD( L"MaximumBuffers", pLoggerInfo->MaximumBuffers );
  403. Instance.GetDWORD( L"MaximumFileSize", pLoggerInfo->MaximumFileSize );
  404. Instance.GetDWORD( L"FlushTimer", pLoggerInfo->FlushTimer );
  405. DecodeFileMode( (CInstance*)&Instance, pLoggerInfo, DECODE_MODE_WBEM_TO_TRACE );
  406. if(! Instance.GetStringArray( L"Guid", saGuids ) ){
  407. saGuids = NULL;
  408. }
  409. Instance.GetVariant( L"EnableFlags", vArray );
  410. if( VT_NULL != vArray.vt ){
  411. saFlags = vArray.parray;
  412. }
  413. Instance.GetVariant( L"Level", vArray );
  414. if( VT_NULL != vArray.vt ){
  415. saLevel = vArray.parray;
  416. }
  417. if (lFlags & WBEM_FLAG_CREATE_ONLY){
  418. LONG lBound;
  419. if( saGuids != NULL ){
  420. SafeArrayGetLBound( saGuids, 1, &lBound );
  421. SafeArrayAccessData( saGuids, (void HUGEP **)&pGuidData );
  422. CLSIDFromString( pGuidData[lBound], &guid );
  423. SafeArrayUnaccessData( saGuids );
  424. }
  425. if( IsEqualGUID( guid, SystemTraceControlGuid ) ){
  426. ULONG offset;
  427. pLoggerInfo->Wnode.Guid = SystemTraceControlGuid;
  428. offset = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAXSTR * sizeof(WCHAR);
  429. hr = EtsSetExtendedFlags(
  430. saFlags,
  431. pLoggerInfo,
  432. offset
  433. );
  434. hr = StartTrace( &LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  435. }else if( LoggerName.CompareNoCase( cszGlobalLogger) == 0 ){
  436. hr = StartGlobalLogger( pLoggerInfo );
  437. }else{
  438. hr = StartTrace( &LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  439. if( ERROR_SUCCESS == hr ){
  440. hr = WmiEnableTrace( Instance, TRUE, saFlags, saLevel, saGuids, LoggerHandle );
  441. }
  442. }
  443. if( NULL != saGuids ){
  444. SafeArrayDestroy( saGuids );
  445. }
  446. if( NULL != saFlags ){
  447. SafeArrayDestroy( saFlags );
  448. }
  449. if( NULL != saLevel ){
  450. SafeArrayDestroy( saLevel );
  451. }
  452. }else if( lFlags & WBEM_FLAG_UPDATE_ONLY ){
  453. Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
  454. hr = UpdateTrace( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  455. if( ERROR_SUCCESS == hr ){
  456. hr = WmiEnableTrace( Instance, TRUE, saFlags, saLevel, saGuids, LoggerHandle );
  457. }
  458. }
  459. G_FREE( pLoggerInfo );
  460. return hr;
  461. }
  462. HRESULT CEventTrace::InitTraceProperties( PEVENT_TRACE_PROPERTIES* ppLoggerInfo )
  463. {
  464. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  465. DWORD dwSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(WCHAR)*MAXSTR*2 + EtsGetMaxEnableFlags() * sizeof(ULONG);
  466. pLoggerInfo = (PEVENT_TRACE_PROPERTIES)G_ALLOC( dwSize );
  467. if( NULL == pLoggerInfo ){
  468. return ERROR_OUTOFMEMORY;
  469. }
  470. ZeroMemory( pLoggerInfo, dwSize );
  471. pLoggerInfo->Wnode.BufferSize = dwSize;
  472. pLoggerInfo->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  473. pLoggerInfo->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  474. pLoggerInfo->LogFileNameOffset = pLoggerInfo->LoggerNameOffset+MAXSTR*sizeof(WCHAR);
  475. *ppLoggerInfo = pLoggerInfo;
  476. return ERROR_SUCCESS;
  477. }
  478. HRESULT
  479. CEventTrace::WmiEnableTrace(
  480. const CInstance &Instance,
  481. bool bEnable,
  482. SAFEARRAY *saFlags,
  483. SAFEARRAY *saLevel,
  484. SAFEARRAY *saGuid,
  485. TRACEHANDLE LoggerHandle
  486. )
  487. {
  488. HRESULT hr = ERROR_SUCCESS;
  489. BSTR HUGEP *pGuidData;
  490. DWORD HUGEP *pFlagData;
  491. DWORD HUGEP *pLevelData;
  492. LONG lGuidBound,uGuidBound;
  493. LONG lFlagBound,uFlagBound;
  494. LONG lLevelBound,uLevelBound;
  495. if( NULL == saGuid ){
  496. return ERROR_SUCCESS;
  497. }
  498. SafeArrayGetUBound( saGuid, 1, &uGuidBound );
  499. SafeArrayGetLBound( saGuid, 1, &lGuidBound );
  500. SafeArrayAccessData( saGuid, (void HUGEP **)&pGuidData );
  501. if( saFlags != NULL ){
  502. SafeArrayGetUBound( saFlags, 1, &uFlagBound );
  503. SafeArrayGetLBound( saFlags, 1, &lFlagBound );
  504. SafeArrayAccessData( saFlags, (void HUGEP **)&pFlagData );
  505. }else{
  506. uFlagBound = 0;
  507. lFlagBound = 0;
  508. }
  509. if( saLevel != NULL ){
  510. SafeArrayGetUBound( saLevel, 1, &uLevelBound );
  511. SafeArrayGetLBound( saLevel, 1, &lLevelBound );
  512. SafeArrayAccessData( saLevel, (void HUGEP **)&pLevelData );
  513. }else{
  514. uLevelBound = 0;
  515. lLevelBound = 0;
  516. }
  517. for ( LONG i=lGuidBound; i<=uGuidBound; i++) {
  518. GUID guid;
  519. DWORD dwLevel = 0;
  520. DWORD dwFlags = 0;
  521. CLSIDFromString( pGuidData[i], &guid );
  522. if( i>=lLevelBound && i<=uLevelBound && saLevel != NULL ){
  523. dwLevel = pLevelData[i];
  524. }
  525. if( i>=lFlagBound && i<=uFlagBound && saFlags != NULL ){
  526. dwFlags = pFlagData[i];
  527. }
  528. hr = EnableTrace( bEnable, dwFlags, dwLevel, &guid, LoggerHandle );
  529. }
  530. SafeArrayUnaccessData( saGuid );
  531. if( saFlags != NULL ){
  532. SafeArrayUnaccessData( saFlags );
  533. }
  534. if( saLevel != NULL ){
  535. SafeArrayUnaccessData( saLevel );
  536. }
  537. return hr;
  538. }
  539. HRESULT CEventTrace::WmiFlushTrace( const CInstance &Instance )
  540. {
  541. HRESULT hr;
  542. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  543. TRACEHANDLE LoggerHandle = 0;
  544. CHString LoggerName;
  545. hr = InitTraceProperties( &pLoggerInfo );
  546. if( hr == ERROR_SUCCESS ){
  547. Instance.GetCHString( L"Name", LoggerName );
  548. Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
  549. hr = ::FlushTraceW( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  550. G_FREE( pLoggerInfo );
  551. }
  552. return hr;
  553. }
  554. HRESULT CEventTrace::WmiStopTrace( const CInstance &Instance )
  555. {
  556. HRESULT hr;
  557. CHString LoggerName;
  558. SAFEARRAY *saGuids = NULL;
  559. LONG nGuidCount,i;
  560. GUID guid;
  561. PEVENT_TRACE_PROPERTIES pLoggerInfo = NULL;
  562. TRACEHANDLE LoggerHandle = 0;
  563. BSTR HUGEP *pData;
  564. Instance.GetCHString( L"Name", LoggerName );
  565. Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
  566. hr = InitTraceProperties( &pLoggerInfo );
  567. if( ERROR_SUCCESS == hr ){
  568. Instance.GetStringArray( L"Guid", saGuids );
  569. if( NULL != saGuids ){
  570. SafeArrayGetUBound( saGuids, 0, &nGuidCount );
  571. SafeArrayAccessData( saGuids, (void HUGEP **)&pData );
  572. for (i=0; i<nGuidCount; i++) {
  573. CLSIDFromString( pData[i], &guid );
  574. hr = EnableTrace( FALSE, 0, 0, &guid, LoggerHandle );
  575. }
  576. SafeArrayUnaccessData( saGuids );
  577. SafeArrayDestroy( saGuids );
  578. }
  579. hr = ::StopTraceW( LoggerHandle, (LPCWSTR)LoggerName, pLoggerInfo );
  580. if( LoggerName.CompareNoCase( cszGlobalLogger ) == 0 ){
  581. hr = DeleteGlobalLogger( pLoggerInfo );
  582. }
  583. G_FREE( pLoggerInfo );
  584. }
  585. return hr;
  586. }
  587. HRESULT
  588. CEventTrace::StartGlobalLogger(
  589. IN PEVENT_TRACE_PROPERTIES pLoggerInfo
  590. )
  591. {
  592. return (SetGlobalLoggerSettings( 1L, pLoggerInfo, 0 ));
  593. }
  594. HRESULT
  595. CEventTrace::DeleteGlobalLogger(
  596. IN PEVENT_TRACE_PROPERTIES pLoggerInfo
  597. )
  598. {
  599. return (SetGlobalLoggerSettings( 0L, pLoggerInfo, 0 ) );
  600. }
  601. HRESULT
  602. CEventTrace::ExecMethod(
  603. const CInstance& Instance,
  604. const BSTR bstrMethodName,
  605. CInstance *pInParams,
  606. CInstance *pOutParams,
  607. long lFlags
  608. )
  609. {
  610. HRESULT hr = WBEM_E_PROVIDER_NOT_CAPABLE;
  611. HRESULT hResult = ERROR_SUCCESS;
  612. if( _wcsicmp( bstrMethodName, L"FlushTrace") == 0 ){
  613. hResult = WmiFlushTrace( Instance );
  614. hr = WBEM_S_NO_ERROR;
  615. }
  616. if( _wcsicmp( bstrMethodName, L"StopTrace") == 0 ){
  617. hResult = WmiStopTrace( Instance );
  618. hr = WBEM_S_NO_ERROR;
  619. }
  620. if( _wcsicmp( bstrMethodName, L"EnableTrace") == 0 ){
  621. bool bEnable;
  622. SAFEARRAY *saGuids = NULL;
  623. SAFEARRAY *saLevel = NULL;
  624. SAFEARRAY *saFlags = NULL;
  625. VARIANT vArray;
  626. TRACEHANDLE LoggerHandle;
  627. pInParams->Getbool( L"Enable", bEnable );
  628. pInParams->GetStringArray( L"Guid", saGuids );
  629. pInParams->GetVariant( L"Flags", vArray );
  630. saFlags = vArray.parray;
  631. pInParams->GetVariant( L"Level", vArray );
  632. saLevel = vArray.parray;
  633. Instance.GetWBEMINT64( L"LoggerId", LoggerHandle );
  634. hResult = WmiEnableTrace( Instance, bEnable, saFlags, saLevel, saGuids, LoggerHandle );
  635. if( NULL != saGuids ){
  636. SafeArrayDestroy( saGuids );
  637. }
  638. if( NULL != saFlags ){
  639. SafeArrayDestroy( saFlags );
  640. }
  641. if( NULL != saLevel ){
  642. SafeArrayDestroy( saLevel );
  643. }
  644. hr = WBEM_S_NO_ERROR;
  645. }
  646. pOutParams->SetDWORD( L"ReturnValue", hResult );
  647. return hr;
  648. }