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.

620 lines
19 KiB

  1. /*++
  2. Copyright (C) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. smtprov.cpp
  5. Abstract:
  6. This object is used to store the list of all current
  7. trace providers in the system.
  8. --*/
  9. #include "Stdafx.h"
  10. #include <wbemidl.h>
  11. #include <initguid.h>
  12. #include <wmistr.h>
  13. #include <evntrace.h>
  14. #include "smtracsv.h"
  15. #include "smtprov.h"
  16. USE_HANDLE_MACROS("SMLOGCFG(smtprov.cpp)");
  17. #define WIN32_FROM_HRESULT(x)((x) & 0x0000FFFF)
  18. LPCWSTR CSmTraceProviders::m_cszBackslash = L"\\";
  19. LPCWSTR CSmTraceProviders::m_cszKernelLogger = KERNEL_LOGGER_NAMEW; // From evntrace.h
  20. LPCWSTR CSmTraceProviders::m_cszDefaultNamespace = L"root\\wmi";
  21. LPCWSTR CSmTraceProviders::m_cszTraceProviderClass = L"EventTrace";
  22. LPCWSTR CSmTraceProviders::m_cszDescription = L"Description";
  23. LPCWSTR CSmTraceProviders::m_cszGuid = L"Guid";
  24. //
  25. // Constructor
  26. CSmTraceProviders::CSmTraceProviders ( CSmTraceLogService* pSvc )
  27. : m_pWbemServices ( NULL ),
  28. m_pTraceLogService ( pSvc ),
  29. m_iBootState ( -1 )
  30. {
  31. m_KernelTraceProvider.strDescription = L"";
  32. m_KernelTraceProvider.strGuid = L"";
  33. return;
  34. }
  35. //
  36. // Destructor
  37. CSmTraceProviders::~CSmTraceProviders ( )
  38. {
  39. ASSERT ( 0 == (INT)m_arrGenTraceProvider.GetSize ( ) );
  40. m_arrGenTraceProvider.RemoveAll ( );
  41. return;
  42. }
  43. //
  44. // Open function. Initialize provider array from Wbem.
  45. //
  46. DWORD
  47. CSmTraceProviders::Open ( const CString& rstrMachineName )
  48. {
  49. DWORD dwStatus = ERROR_SUCCESS;
  50. DWORD dwLength;
  51. CString strTemp;
  52. MFC_TRY
  53. if ( !rstrMachineName.IsEmpty ( ) ) {
  54. m_strMachineName = rstrMachineName;
  55. if ( 0 != lstrcmpi ( m_cszBackslash, m_strMachineName.Left(1) ) ) {
  56. strTemp = m_cszBackslash;
  57. strTemp += m_cszBackslash;
  58. m_strMachineName = strTemp + m_strMachineName;
  59. }
  60. } else {
  61. // get the local machine name & default name space if the caller
  62. // has passed in a NULL machine name
  63. dwLength = MAX_COMPUTERNAME_LENGTH + 1;
  64. if ( GetComputerName (
  65. m_strMachineName.GetBufferSetLength( dwLength ),
  66. &dwLength ) ) {
  67. m_strMachineName.ReleaseBuffer();
  68. strTemp = m_cszBackslash;
  69. strTemp += m_cszBackslash;
  70. m_strMachineName = strTemp + m_strMachineName;
  71. } else {
  72. dwStatus = GetLastError();
  73. m_strMachineName.ReleaseBuffer();
  74. }
  75. }
  76. MFC_CATCH_DWSTATUS
  77. if ( ERROR_SUCCESS != dwStatus ) {
  78. m_strMachineName.Empty();
  79. }
  80. return dwStatus;
  81. }
  82. //
  83. // Close Function
  84. // Frees allocated memory
  85. //
  86. DWORD
  87. CSmTraceProviders::Close ( )
  88. {
  89. DWORD dwStatus = ERROR_SUCCESS;
  90. m_arrGenTraceProvider.RemoveAll ( );
  91. if ( NULL != m_pWbemServices ) {
  92. m_pWbemServices->Release ( );
  93. m_pWbemServices = NULL;
  94. }
  95. return dwStatus;
  96. }
  97. //
  98. // AddProvider
  99. // Add the specified provider strings to the array
  100. //
  101. DWORD
  102. CSmTraceProviders::AddProvider (
  103. const CString& rstrDescription,
  104. const CString& rstrGuid,
  105. INT iIsEnabled,
  106. INT iIsActive )
  107. {
  108. DWORD dwStatus = ERROR_SUCCESS;
  109. SLQ_TRACE_PROVIDER slqTProv;
  110. // If inactive, cannot be enabled.
  111. ASSERT ( ( 0 == iIsActive ) ? ( 0 == iIsEnabled ) : TRUE );
  112. MFC_TRY
  113. slqTProv.strDescription = rstrDescription;
  114. slqTProv.strGuid = rstrGuid;
  115. slqTProv.iIsEnabled = iIsEnabled;
  116. slqTProv.iIsActive = iIsActive;
  117. m_arrGenTraceProvider.Add( slqTProv );
  118. MFC_CATCH_DWSTATUS
  119. return dwStatus;
  120. }
  121. //
  122. // ConnectToServer
  123. // Connects to the Wbem server.
  124. //
  125. HRESULT
  126. CSmTraceProviders::ConnectToServer ( void )
  127. {
  128. HRESULT hr = NOERROR;
  129. if ( NULL == m_pWbemServices ) {
  130. IWbemLocator *pWbemLocator = NULL;
  131. IWbemServices *pWbemServices = NULL;
  132. // connect to locator
  133. hr = CoCreateInstance (
  134. CLSID_WbemLocator,
  135. 0,
  136. CLSCTX_INPROC_SERVER,
  137. IID_IWbemLocator,
  138. ( LPVOID * )&pWbemLocator );
  139. if ( SUCCEEDED (hr) ) {
  140. BSTR bstrTemp = NULL;
  141. CString strNamespace;
  142. MFC_TRY
  143. strNamespace = m_strMachineName;
  144. strNamespace += m_cszBackslash;
  145. strNamespace += m_cszDefaultNamespace;
  146. bstrTemp = strNamespace.AllocSysString();
  147. MFC_CATCH_HR
  148. if ( SUCCEEDED ( hr ) ) {
  149. // try to connect to the service
  150. hr = pWbemLocator->ConnectServer (
  151. bstrTemp,
  152. NULL,
  153. NULL,
  154. 0,
  155. 0L,
  156. 0,
  157. 0,
  158. &pWbemServices );
  159. ::SysFreeString ( bstrTemp );
  160. }
  161. if ( SUCCEEDED ( hr ) ) {
  162. hr = CoSetProxyBlanket((IUnknown*)pWbemServices,
  163. RPC_C_AUTHN_WINNT,
  164. RPC_C_AUTHZ_NONE,
  165. NULL,
  166. RPC_C_AUTHN_LEVEL_PKT,
  167. RPC_C_IMP_LEVEL_IMPERSONATE,
  168. NULL,
  169. EOAC_NONE);
  170. }
  171. // free the locator
  172. pWbemLocator->Release ( );
  173. }
  174. if ( SUCCEEDED ( hr ) ) {
  175. m_pWbemServices = pWbemServices;
  176. }
  177. }
  178. return hr;
  179. }
  180. //
  181. // GetBootState
  182. // Connects to the registry.
  183. //
  184. HRESULT
  185. CSmTraceProviders::GetBootState ( INT& riBootState )
  186. {
  187. HRESULT hr = NOERROR;
  188. if ( -1 == m_iBootState ) {
  189. HKEY hKeyMachine;
  190. ASSERT ( NULL != m_pTraceLogService );
  191. hKeyMachine = m_pTraceLogService->GetMachineKey ( );
  192. if ( NULL != hKeyMachine ) {
  193. HKEY hKeyOption;
  194. DWORD dwStatus = ERROR_SUCCESS;
  195. dwStatus = RegOpenKeyEx (
  196. hKeyMachine,
  197. (LPCWSTR)L"System\\CurrentControlSet\\Control\\Safeboot\\Option",
  198. 0,
  199. KEY_READ,
  200. &hKeyOption );
  201. // The Option key and OptionValue value only exist if booting in
  202. // safe mode, so failure indicates Normal mode (0).
  203. // Safe mode = 1, Safe mode with network = 2.
  204. if ( ERROR_SUCCESS == dwStatus ) {
  205. DWORD dwType = 0;
  206. DWORD dwBufSize = sizeof (INT );
  207. dwStatus = RegQueryValueExW (
  208. hKeyOption,
  209. L"OptionValue",
  210. NULL,
  211. &dwType,
  212. (LPBYTE)&m_iBootState,
  213. &dwBufSize);
  214. if ( ERROR_SUCCESS != dwStatus ) {
  215. // Normal mode
  216. m_iBootState = 0;
  217. }
  218. RegCloseKey(hKeyOption);
  219. } else {
  220. // Normal mode
  221. m_iBootState = 0;
  222. }
  223. } else {
  224. // Unable to access registry
  225. hr = E_FAIL;
  226. }
  227. }
  228. riBootState = m_iBootState;
  229. return hr;
  230. }
  231. //
  232. // SyncWithConfiguration
  233. // Reads the current list of providers from Wbem
  234. // and reloads the internal values to match
  235. //
  236. HRESULT
  237. CSmTraceProviders::SyncWithConfiguration ( void )
  238. {
  239. typedef struct _LOG_INFO {
  240. EVENT_TRACE_PROPERTIES Properties;
  241. WCHAR szLoggerName[MAX_PATH+1]; // Must follow Properties
  242. } LOG_INFO, FAR* PLOG_INFO;
  243. IEnumWbemClassObject *pEnumProviders = NULL;
  244. CString strDescription;
  245. CString strGuid;
  246. CString strBracketedGuid;
  247. BSTR bstrTemp;
  248. INT iIndex;
  249. INT iIsEnabled =0;
  250. HRESULT hr;
  251. PTRACE_GUID_PROPERTIES* arrGuidProperties = NULL;
  252. ULONG ulGuidCount;
  253. PVOID pGuidStorage = NULL;
  254. m_arrGenTraceProvider.RemoveAll ( );
  255. hr = ConnectToServer( );
  256. if ( SUCCEEDED ( hr ) ) {
  257. hr = LoadGuidArray( &pGuidStorage, &ulGuidCount );
  258. }
  259. if ( SUCCEEDED ( hr ) ) {
  260. arrGuidProperties = (PTRACE_GUID_PROPERTIES *)pGuidStorage;
  261. ASSERT ( NULL != arrGuidProperties );
  262. }
  263. //If Connection succeeded and registered Guids gathered.
  264. if ( SUCCEEDED ( hr ) ) {
  265. // Create an enumerator of the Trace Provider class
  266. MFC_TRY
  267. bstrTemp = SysAllocString(m_cszTraceProviderClass);
  268. hr = m_pWbemServices->CreateClassEnum (
  269. bstrTemp,
  270. WBEM_FLAG_SHALLOW|WBEM_FLAG_USE_AMENDED_QUALIFIERS,
  271. NULL,
  272. &pEnumProviders );
  273. ::SysFreeString ( bstrTemp );
  274. MFC_CATCH_HR
  275. if ( SUCCEEDED ( hr ) ) {
  276. BSTR bsDescription = NULL;
  277. BSTR bsGuid = NULL;
  278. VARIANT vValue;
  279. DWORD dwRtnCount;
  280. IWbemQualifierSet *pQualSet = NULL;
  281. IWbemClassObject *pThisClass = NULL;
  282. WCHAR szSystemTraceControlGuid[39];
  283. ULONG Status;
  284. VariantInit ( &vValue );
  285. ZeroMemory ( szSystemTraceControlGuid, sizeof ( szSystemTraceControlGuid ) );
  286. ::StringFromGUID2( SystemTraceControlGuid, szSystemTraceControlGuid, 39);
  287. MFC_TRY
  288. bsDescription = SysAllocString(m_cszDescription);
  289. bsGuid = SysAllocString(m_cszGuid);
  290. MFC_CATCH_HR
  291. if ( SUCCEEDED ( hr ) ) {
  292. iIsEnabled = 0;
  293. while ( SUCCEEDED ( hr ) ) {
  294. hr = pEnumProviders->Next (
  295. 0, // timeout
  296. 1, // return only 1 object
  297. &pThisClass,
  298. &dwRtnCount );
  299. if ( SUCCEEDED ( hr ) ) {
  300. // no more classes
  301. if ( dwRtnCount == 0 ) break;
  302. pThisClass->GetQualifierSet ( &pQualSet );
  303. if ( pQualSet != NULL ) {
  304. hr = pQualSet->Get ( bsGuid, 0, &vValue, 0 );
  305. if ( SUCCEEDED ( hr ) ) {
  306. strGuid = ( LPWSTR )V_BSTR ( &vValue );
  307. VariantClear ( &vValue );
  308. hr = pQualSet->Get ( bsDescription, 0, &vValue, 0 );
  309. if ( SUCCEEDED ( hr ) ) {
  310. strDescription = ( LPWSTR )V_BSTR ( &vValue );
  311. VariantClear ( &vValue );
  312. } else {
  313. hr = ERROR_SUCCESS;
  314. strDescription = strGuid;
  315. }
  316. }
  317. pQualSet->Release();
  318. }
  319. // The Win2000 Kernel trace provider is handled separately.
  320. if ( SUCCEEDED ( hr ) ) {
  321. MFC_TRY
  322. if ( L'{' != strGuid[0] ) {
  323. strBracketedGuid.Format ( L"{%s}", strGuid );
  324. } else {
  325. strBracketedGuid = strGuid;
  326. }
  327. MFC_CATCH_HR
  328. if ( 0 == strBracketedGuid.CompareNoCase( szSystemTraceControlGuid ) ) {
  329. PLOG_INFO pLoggerInfo = NULL;
  330. TRACEHANDLE LoggerHandle = 0;
  331. // Kernel trace provider. Need to pass GUID as name.
  332. MFC_TRY
  333. pLoggerInfo = new LOG_INFO;
  334. ZeroMemory ( pLoggerInfo, sizeof ( LOG_INFO ) );
  335. pLoggerInfo->Properties.LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
  336. pLoggerInfo->Properties.Wnode.BufferSize = sizeof( LOG_INFO );
  337. pLoggerInfo->Properties.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
  338. pLoggerInfo->Properties.Wnode.Guid = SystemTraceControlGuid;
  339. Status = QueryTrace(LoggerHandle, m_cszKernelLogger, &(pLoggerInfo->Properties) );
  340. iIsEnabled = (Status == 0) ? 1 : 0;
  341. m_KernelTraceProvider.strDescription = strDescription;
  342. m_KernelTraceProvider.strGuid = strBracketedGuid;
  343. m_KernelTraceProvider.iIsEnabled = iIsEnabled;
  344. m_KernelTraceProvider.iIsActive = 1;
  345. MFC_CATCH_HR
  346. if ( NULL != pLoggerInfo ) {
  347. delete pLoggerInfo;
  348. }
  349. } else {
  350. //loop on all the registered guids
  351. INT iIsActive = 0;
  352. GUID guidTemp; // Todo: Init
  353. BOOL bSuccess;
  354. ZeroMemory ( &guidTemp, sizeof (GUID) );
  355. bSuccess = wGUIDFromString (strGuid, &guidTemp );
  356. if ( bSuccess ) {
  357. for (iIndex = 0 ; iIndex < (INT)ulGuidCount; iIndex ++){
  358. if ( guidTemp == arrGuidProperties[iIndex]->Guid ) {
  359. DWORD dwStatus;
  360. iIsActive = 1;
  361. dwStatus = AddProvider (
  362. strDescription,
  363. strBracketedGuid,
  364. arrGuidProperties[iIndex]->IsEnable,
  365. iIsActive );
  366. if ( ERROR_OUTOFMEMORY == dwStatus ) {
  367. hr = E_OUTOFMEMORY;
  368. } else if ( ERROR_SUCCESS != dwStatus ) {
  369. hr = E_FAIL;
  370. }
  371. break;
  372. }
  373. }
  374. } // Todo: Error message on invalid Guid string.
  375. if ( 0 == iIsActive ) {
  376. DWORD dwStatus;
  377. dwStatus = AddProvider (
  378. strDescription,
  379. strBracketedGuid,
  380. 0,
  381. iIsActive );
  382. if ( ERROR_OUTOFMEMORY == dwStatus ) {
  383. hr = E_OUTOFMEMORY;
  384. } else if ( ERROR_SUCCESS != dwStatus ) {
  385. hr = E_FAIL;
  386. }
  387. }
  388. }
  389. }
  390. pThisClass->Release ( );
  391. }
  392. }
  393. ::SysFreeString ( bsGuid );
  394. ::SysFreeString ( bsDescription );
  395. }
  396. }
  397. }
  398. // Done with these objects.
  399. if ( NULL != pGuidStorage ) {
  400. G_FREE ( pGuidStorage );
  401. }
  402. if ( NULL != pEnumProviders ) {
  403. pEnumProviders->Release ( );
  404. }
  405. return hr;
  406. }
  407. //
  408. // Get specified provider in provider list
  409. //
  410. SLQ_TRACE_PROVIDER*
  411. CSmTraceProviders::GetProviderInfo ( INT iIndex )
  412. {
  413. return &m_arrGenTraceProvider[iIndex];
  414. }
  415. //
  416. // Return a pointer to the Kernel provider.
  417. //
  418. SLQ_TRACE_PROVIDER*
  419. CSmTraceProviders::GetKernelProviderInfo ( void )
  420. {
  421. return &m_KernelTraceProvider;
  422. }
  423. //
  424. // Return the index of the provider specified by Guid
  425. //
  426. INT
  427. CSmTraceProviders::IndexFromGuid ( const CString& rstrGuid )
  428. {
  429. int iIndex;
  430. int iCount = (INT)m_arrGenTraceProvider.GetSize ( );
  431. for ( iIndex = 0; iIndex < iCount; iIndex++ ) {
  432. if ( 0 == m_arrGenTraceProvider[iIndex].strGuid.CompareNoCase( rstrGuid ) ) {
  433. break;
  434. }
  435. }
  436. // Signal not found with -1.
  437. if ( iIndex == iCount ) {
  438. iIndex = -1;
  439. }
  440. return iIndex;
  441. }
  442. //
  443. // Get provider list count
  444. //
  445. INT
  446. CSmTraceProviders::GetGenProvCount ( )
  447. {
  448. return (INT)m_arrGenTraceProvider.GetSize ( );
  449. }
  450. //
  451. // LoadGuidArray copied from evntrprv.cpp 9/12/01
  452. //
  453. HRESULT
  454. CSmTraceProviders::LoadGuidArray( PVOID* Storage, PULONG pnGuidCount )
  455. {
  456. ULONG i;
  457. ULONG nGuidArray = 16;
  458. ULONG nGuidCount = 0;
  459. DWORD dwSize;
  460. PTRACE_GUID_PROPERTIES* GuidPropertiesArray;
  461. PTRACE_GUID_PROPERTIES pStorage;
  462. HRESULT hr = ERROR_SUCCESS;
  463. do {
  464. dwSize = nGuidArray * (sizeof(TRACE_GUID_PROPERTIES) + sizeof(PTRACE_GUID_PROPERTIES));
  465. MFC_TRY
  466. *Storage = G_ALLOC(dwSize);
  467. MFC_CATCH_HR
  468. if ( FAILED (hr) || *Storage == NULL) {
  469. if (*Storage == NULL) {
  470. hr = E_OUTOFMEMORY;
  471. }
  472. break;
  473. } else {
  474. RtlZeroMemory(*Storage, dwSize);
  475. GuidPropertiesArray = (PTRACE_GUID_PROPERTIES *)(*Storage);
  476. pStorage = (PTRACE_GUID_PROPERTIES)((char*)(*Storage) + nGuidArray * sizeof(PTRACE_GUID_PROPERTIES));
  477. for (i=0; i < nGuidArray; i++) {
  478. GuidPropertiesArray[i] = pStorage;
  479. pStorage = (PTRACE_GUID_PROPERTIES)((char*)pStorage + sizeof(TRACE_GUID_PROPERTIES));
  480. }
  481. hr = EnumerateTraceGuids(GuidPropertiesArray,nGuidArray,&nGuidCount);
  482. if ( hr == ERROR_MORE_DATA ) {
  483. if( nGuidCount <= nGuidArray ){
  484. hr = WBEM_E_INVALID_PARAMETER;
  485. break;
  486. }
  487. nGuidArray = nGuidCount;
  488. G_FREE(*Storage);
  489. (*Storage) = NULL;
  490. }
  491. }
  492. }while( hr == ERROR_MORE_DATA );
  493. if( ERROR_SUCCESS == hr ){
  494. *pnGuidCount = nGuidCount;
  495. }else{
  496. *pnGuidCount = 0;
  497. }
  498. return hr;
  499. }