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.

2830 lines
100 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. //
  3. // BINMOF.CPP
  4. //
  5. // Module:
  6. // Purpose:
  7. //
  8. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  9. //
  10. /////////////////////////////////////////////////////////////////////
  11. #include "wmicom.h"
  12. #include "wmimof.h"
  13. #include <wchar.h>
  14. #include <stdio.h>
  15. #include "wdmshell.h"
  16. #include <cregcls.h>
  17. #include <bmof.h>
  18. #include <mrcicode.h>
  19. #include <mofcomp.h>
  20. #include <crc32.h>
  21. #include <TCHAR.h>
  22. #include <autoptr.h>
  23. #include <comdef.h>
  24. #include <strutils.h>
  25. //
  26. // auto variables
  27. //
  28. #include <ScopeGuard.h>
  29. #if defined(_M_IA64)
  30. //
  31. // NTBUG#744176
  32. //
  33. template void deleteArray<unsigned char>(unsigned char*);
  34. template void deleteArray<unsigned short>(unsigned short*);
  35. template void deletePtr<CWMIStandardShell>(const CWMIStandardShell*);
  36. template void deletePtr<CNamespaceManagement>(const CNamespaceManagement*);
  37. #endif
  38. #define WDM_REG_KEY L"Software\\Microsoft\\WBEM\\WDM"
  39. #define WDM_DREDGE_KEY L"Software\\Microsoft\\WBEM\\WDM\\DREDGE"
  40. #define DREDGE_KEY L"DREDGE"
  41. ///////////////////////////////////////////////////////////////////////////////////////////
  42. //***************************************************************************
  43. //
  44. // void * BMOFAlloc
  45. //
  46. // DESCRIPTION:
  47. //
  48. // Provides allocation service for BMOF.C. This allows users to choose
  49. // the allocation method that is used.
  50. //
  51. // PARAMETERS:
  52. //
  53. // Size Input. Size of allocation in bytes.
  54. //
  55. // RETURN VALUE:
  56. //
  57. // pointer to new data. NULL if allocation failed.
  58. //
  59. //***************************************************************************
  60. void * BMOFAlloc(size_t Size)
  61. {
  62. return malloc(Size);
  63. }
  64. //***************************************************************************
  65. //
  66. // void BMOFFree
  67. //
  68. // DESCRIPTION:
  69. //
  70. // Provides allocation service for BMOF.C. This frees what ever was
  71. // allocated via BMOFAlloc.
  72. //
  73. // PARAMETERS:
  74. //
  75. // pointer to memory to be freed.
  76. //
  77. //***************************************************************************
  78. void BMOFFree(void * pFree)
  79. {
  80. free(pFree);
  81. }
  82. ///////////////////////////////////////////////////////////////////////////////////////////////////
  83. HRESULT ConvertStringToCTypeString( WCHAR * Out, int cchSizeOut, WCHAR * In )
  84. {
  85. HRESULT hr = WBEM_E_INVALID_PARAMETER;
  86. WCHAR * token = NULL;
  87. if(In)
  88. {
  89. CAutoWChar tmpBuf(_MAX_PATH*2);
  90. if( tmpBuf.Valid() )
  91. {
  92. if ( hr = SUCCEEDED ( StringCchCopyW ((WCHAR*)tmpBuf,_MAX_PATH*2,In) ) )
  93. {
  94. token = wcstok( (WCHAR*)tmpBuf, L"\\" );
  95. if( !token )
  96. {
  97. hr = StringCchCopyW (Out,cchSizeOut,In);
  98. }
  99. else
  100. {
  101. hr = WBEM_S_FALSE;
  102. BOOL fFirst = TRUE;
  103. while( SUCCEEDED ( hr ) && token != NULL )
  104. {
  105. if( fFirst )
  106. {
  107. hr = StringCchCopyW(Out,cchSizeOut,token);
  108. fFirst = FALSE;
  109. }
  110. else
  111. {
  112. if ( SUCCEEDED ( hr = StringCchCatW(Out,cchSizeOut,L"\\\\") ) )
  113. {
  114. hr = StringCchCatW(Out,cchSizeOut,token);
  115. }
  116. }
  117. token = wcstok( NULL, L"\\" );
  118. }
  119. }
  120. }
  121. }
  122. }
  123. return hr;
  124. }
  125. ///////////////////////////////////////////////////////////////////////////////////////////
  126. //*****************************************************************************************
  127. // The binary mof class
  128. //*****************************************************************************************
  129. ///////////////////////////////////////////////////////////////////////////////////////////
  130. CWMIBinMof::CWMIBinMof()
  131. {
  132. m_pCompiler = NULL;
  133. m_pWMI = NULL;
  134. m_nInit = NOT_INITIALIZED;
  135. m_pMofResourceInfo = NULL;
  136. }
  137. /////////////////////////////////////////////////////////////////////
  138. HRESULT CWMIBinMof::InitializePtrs (
  139. CHandleMap * pList,
  140. IWbemServices __RPC_FAR * pServices,
  141. IWbemServices __RPC_FAR * pRepository,
  142. IWbemObjectSink __RPC_FAR * pHandler,
  143. IWbemContext __RPC_FAR *pCtx
  144. )
  145. {
  146. HRESULT hr = WBEM_E_FAILED;
  147. SAFE_DELETE_PTR(m_pWMI);
  148. m_pWMI = new CWMIManagement;
  149. if( m_pWMI )
  150. {
  151. m_pWMI->SetWMIPointers(pList, pServices, pRepository, pHandler, pCtx);
  152. m_nInit = FULLY_INITIALIZED;
  153. hr = S_OK;
  154. }
  155. return hr;
  156. }
  157. /////////////////////////////////////////////////////////////////////
  158. HRESULT CWMIBinMof::Initialize(CWMIManagement * p,BOOL fUpdateNamespace)
  159. {
  160. HRESULT hr = WBEM_E_FAILED;
  161. if( p )
  162. {
  163. hr = InitializePtrs(p->HandleMap(),p->Services(),p->Repository(),p->Handler(),p->Context());
  164. }
  165. else
  166. {
  167. m_nInit = PARTIALLY_INITIALIZED;
  168. hr = S_OK;
  169. }
  170. m_fUpdateNamespace = fUpdateNamespace;
  171. return hr;
  172. }
  173. /////////////////////////////////////////////////////////////////////
  174. HRESULT CWMIBinMof::Initialize (
  175. CHandleMap * pList,
  176. BOOL fUpdateNamespace,
  177. ULONG uDesiredAccess,
  178. IWbemServices __RPC_FAR * pServices,
  179. IWbemServices __RPC_FAR * pRepository,
  180. IWbemObjectSink __RPC_FAR * pHandler,
  181. IWbemContext __RPC_FAR *pCtx
  182. )
  183. {
  184. HRESULT hr = WBEM_E_FAILED;
  185. hr = InitializePtrs(pList,pServices,pRepository,pHandler,pCtx);
  186. m_fUpdateNamespace = fUpdateNamespace;
  187. return hr;
  188. }
  189. /////////////////////////////////////////////////////////////////////
  190. CWMIBinMof::~CWMIBinMof()
  191. {
  192. SAFE_RELEASE_PTR(m_pCompiler);
  193. SAFE_DELETE_PTR(m_pWMI);
  194. }
  195. /////////////////////////////////////////////////////////////////////
  196. HRESULT CWMIBinMof::OpenFileAndLookForItIfItDoesNotExist(wmilib::auto_buffer<TCHAR> & pFile, HANDLE & hFile )
  197. {
  198. HRESULT hr = S_OK;
  199. //=========================================================================
  200. // Ok, hopefully CreateFile will find it
  201. //=========================================================================
  202. hFile = CreateFile(pFile.get(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  203. if( hFile != INVALID_HANDLE_VALUE )
  204. {
  205. return S_OK;
  206. }
  207. // cache last error value
  208. DWORD dwLastError = ::GetLastError ();
  209. hr = WBEM_E_FAILED;
  210. //=====================================================================
  211. // CreateFile DIDN'T find it, so look in the Windows dir
  212. //=====================================================================
  213. wmilib::auto_ptr<TCHAR> pszSysDir( new TCHAR[MAX_PATH+1]);
  214. if ( NULL == pszSysDir.get() ) return WBEM_E_OUT_OF_MEMORY;;
  215. UINT uSize = GetSystemDirectory(pszSysDir.get(), MAX_PATH+1);
  216. if( 0 == uSize )
  217. {
  218. ::SetLastError ( dwLastError );
  219. return WBEM_E_FAILED;
  220. }
  221. if ( uSize > MAX_PATH )
  222. {
  223. pszSysDir.reset( new TCHAR [ uSize + 1 ]);
  224. if ( NULL == pszSysDir.get()) return WBEM_E_OUT_OF_MEMORY;
  225. if (!GetSystemDirectory( pszSysDir.get(), uSize + 1 ) )
  226. {
  227. return WBEM_E_FAILED;
  228. }
  229. }
  230. wmilib::auto_buffer<TCHAR> pFileNew( new TCHAR[MAX_PATH*2 + 1]);
  231. if( NULL == pFileNew.get() ) return WBEM_E_OUT_OF_MEMORY;
  232. if (FAILED( hr = StringCchPrintfW ( pFileNew.get(), MAX_PATH*2 + 1, L"%s\\%s", pszSysDir.get(), pFile.get())))
  233. {
  234. ::SetLastError ( dwLastError );
  235. return WBEM_E_FAILED;
  236. }
  237. //=============================================================
  238. // Ok, now try to open again
  239. //=============================================================
  240. hFile = CreateFile(pFileNew.get(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  241. if( hFile == INVALID_HANDLE_VALUE )
  242. {
  243. ::SetLastError ( dwLastError );
  244. return WBEM_E_FAILED;
  245. }
  246. pFile.reset(pFileNew.release());
  247. return S_OK;
  248. }
  249. /////////////////////////////////////////////////////////////////////
  250. BOOL CWMIBinMof::GetFileDateAndTime(ULONG & lLowDateTime,ULONG & lHighDateTime,WCHAR * wcsFileName, int cchSize)
  251. {
  252. HANDLE hFile = NULL;
  253. FILETIME ftCreationTime, ftLastAccessTime, ftLastWriteTime,ftLocal;
  254. BOOL fRc = FALSE;
  255. wmilib::auto_buffer<TCHAR> pFile;
  256. if( ExtractFileNameFromKey(pFile,wcsFileName,cchSize) )
  257. {
  258. if( SUCCEEDED(OpenFileAndLookForItIfItDoesNotExist( pFile, hFile )))
  259. {
  260. if( GetFileTime( hFile, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime ))
  261. {
  262. //==========================================================
  263. // Pick up the path of the file while we are here....
  264. //==========================================================
  265. TCHAR sFullPath[MAX_PATH * 4];
  266. TCHAR *sFilename = NULL;
  267. if (GetFullPathName(pFile.get(), MAX_PATH * 4, sFullPath, &sFilename) != 0)
  268. {
  269. StringCchCopyW ( wcsFileName, MAX_PATH*4, sFullPath );
  270. }
  271. else
  272. {
  273. DWORD dwTest = GetLastError();
  274. ERRORTRACE((THISPROVIDER,"GetFullPathName FAILED for filename: \n"));
  275. TranslateAndLog(wcsFileName);
  276. ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
  277. }
  278. FileTimeToLocalFileTime( &ftLastWriteTime, &ftLocal);
  279. lLowDateTime = (ULONG)ftLocal.dwLowDateTime;
  280. lHighDateTime = (ULONG)ftLocal.dwHighDateTime;
  281. fRc = TRUE;
  282. }
  283. else
  284. {
  285. DWORD dwTest = GetLastError();
  286. ERRORTRACE((THISPROVIDER,"GetFileTime FAILED for filename:\n"));
  287. TranslateAndLog(wcsFileName);
  288. ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
  289. }
  290. CloseHandle(hFile);
  291. }
  292. else
  293. {
  294. DWORD dwTest = GetLastError();
  295. ERRORTRACE((THISPROVIDER,"CreateFile FAILED for filename:\n"));
  296. TranslateAndLog(wcsFileName);
  297. ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
  298. }
  299. }
  300. else
  301. {
  302. DWORD dwTest = GetLastError();
  303. ERRORTRACE((THISPROVIDER,"Can't extract filename: \n"));
  304. TranslateAndLog(wcsFileName);
  305. ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
  306. }
  307. return fRc;
  308. }
  309. /////////////////////////////////////////////////////////////////////
  310. BOOL CWMIBinMof::NeedToProcessThisMof( WCHAR * wcsFileName,ULONG & lLowDateTime, ULONG & lHighDateTime )
  311. {
  312. BOOL fNeedToProcessThisMof = TRUE;
  313. HRESULT hr = WBEM_E_OUT_OF_MEMORY;
  314. IWbemClassObject * pClass=NULL;
  315. CAutoWChar wcsBuf(_MAX_PATH*4);
  316. CAutoWChar wcsTmp(_MAX_PATH*4);
  317. if( wcsTmp.Valid() && wcsBuf.Valid() )
  318. {
  319. //==================================================
  320. // Change all \ to \\
  321. //==================================================
  322. if ( SUCCEEDED ( hr = ConvertStringToCTypeString( wcsTmp,_MAX_PATH*4,wcsFileName ) ) )
  323. {
  324. if ( SUCCEEDED ( hr = StringCchPrintfW(wcsBuf,_MAX_PATH*4,L"WmiBinaryMofResource.HighDateTime=%lu,LowDateTime=%lu,Name=\"%s\"",lHighDateTime,lLowDateTime,wcsTmp) ) )
  325. {
  326. //==================================================
  327. // Get a pointer to a IWbemClassObject object
  328. // Have we ever processed this mof before?
  329. // if not, then return TRUE
  330. //==================================================
  331. if( m_fUpdateNamespace )
  332. {
  333. CBSTR cbstr(wcsBuf);
  334. hr = REPOSITORY->GetObject(cbstr, 0,CONTEXT, &pClass, NULL);
  335. if(WBEM_NO_ERROR == hr)
  336. {
  337. fNeedToProcessThisMof = FALSE;
  338. CVARIANT vSuccess;
  339. hr = pClass->Get(L"MofProcessed", 0, &vSuccess, 0, 0);
  340. if( hr == WBEM_NO_ERROR )
  341. {
  342. //=========================================================================
  343. // make sure it is added to the registry
  344. //=========================================================================
  345. AddThisMofToRegistryIfNeeded(WDM_REG_KEY,wcsFileName,lLowDateTime,lHighDateTime,vSuccess.GetBool());
  346. }
  347. SAFE_RELEASE_PTR( pClass);
  348. }
  349. //==============================================================================
  350. // Delete any old instances that might be hanging around for this driver
  351. //==============================================================================
  352. IEnumWbemClassObject* pEnum = NULL;
  353. CAutoWChar wcsQuery(MEMSIZETOALLOCATE);
  354. if( wcsQuery.Valid() )
  355. {
  356. ULONG uReturned = 0;
  357. if ( SUCCEEDED ( hr = StringCchPrintfW(wcsQuery,MEMSIZETOALLOCATE,L"select * from WMIBinaryMofResource where Name = \"%s\"",wcsTmp) ) )
  358. {
  359. CBSTR bstrTemp = wcsQuery;
  360. CBSTR strQryLang(L"WQL");
  361. hr = REPOSITORY->ExecQuery(strQryLang, bstrTemp, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT,&pEnum);
  362. if( hr == WBEM_NO_ERROR )
  363. {
  364. IWbemClassObject * pClass = NULL;
  365. while( TRUE )
  366. {
  367. if( WBEM_NO_ERROR == (hr = pEnum->Next(2000, 1, &pClass, &uReturned)))
  368. {
  369. CVARIANT vPath, vDriver;
  370. hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0);
  371. if( hr == WBEM_NO_ERROR )
  372. {
  373. if( vPath.GetStr() )
  374. {
  375. if( wbem_wcsicmp(vPath.GetStr(),wcsBuf) != 0 )
  376. {
  377. hr = REPOSITORY->DeleteInstance(vPath.GetStr(),0,CONTEXT,NULL);
  378. if ( FAILED ( hr ) )
  379. {
  380. ERRORTRACE((THISPROVIDER,"We have been requested to delete this mof:\n"));
  381. TranslateAndLog(vPath.GetStr());
  382. ERRORTRACE((THISPROVIDER,"It failed with 0x%08lx\n", hr));
  383. }
  384. else
  385. {
  386. DEBUGTRACE((THISPROVIDER,"We have been requested to delete this mof:\n"));
  387. TranslateAndLog(vPath.GetStr(), TRUE);
  388. }
  389. if( hr == WBEM_NO_ERROR )
  390. {
  391. //=====================================================
  392. // Duplicate change in registry
  393. //=====================================================
  394. DeleteMofFromRegistry( vPath.GetStr() );
  395. //==========================================================================
  396. // Gets rid of the old classes for the old versions of this driver
  397. //==========================================================================
  398. hr = pClass->Get(L"Driver", 0, &vDriver, 0, 0);
  399. if( hr == WBEM_NO_ERROR )
  400. {
  401. CNamespaceManagement Namespace(this);
  402. Namespace.DeleteOldClasses(vDriver.GetStr(),CVARIANT((long)lLowDateTime),CVARIANT((long)lHighDateTime), TRUE);
  403. }
  404. }
  405. }
  406. }
  407. }
  408. }
  409. SAFE_RELEASE_PTR( pClass );
  410. if( hr != WBEM_NO_ERROR )
  411. {
  412. break;
  413. }
  414. }
  415. SAFE_RELEASE_PTR(pEnum);
  416. }
  417. }
  418. }
  419. }
  420. else
  421. {
  422. if( ThisMofExistsInRegistry(WDM_DREDGE_KEY,wcsFileName, lLowDateTime, lHighDateTime, TRUE) )
  423. {
  424. fNeedToProcessThisMof = FALSE;
  425. }
  426. }
  427. }
  428. }
  429. }
  430. return fNeedToProcessThisMof;
  431. }
  432. /////////////////////////////////////////////////////////////////////
  433. BOOL CWMIBinMof::UpdateMofTimestampInHMOM(WCHAR * wcsKey,ULONG & lLowDateTime, ULONG & lHighDateTime, BOOL fSuccess )
  434. {
  435. BOOL fRc = FALSE;
  436. IWbemClassObject * pNewInst = NULL;
  437. IWbemClassObject * pIWbemClassObject = NULL;
  438. //==================================================
  439. // Get a pointer to a IWbemClassObject object
  440. //==================================================
  441. HRESULT hr = WBEM_NO_ERROR;
  442. if( m_fUpdateNamespace )
  443. {
  444. CVARIANT cvarName;
  445. cvarName.SetStr(L"WMIBinaryMofResource");
  446. hr = REPOSITORY->GetObject(cvarName, 0,CONTEXT, &pIWbemClassObject, NULL);
  447. if(WBEM_NO_ERROR == hr)
  448. {
  449. //=============================================================
  450. // Spawn a new instance
  451. //=============================================================
  452. hr = pIWbemClassObject->SpawnInstance(0, &pNewInst);
  453. SAFE_RELEASE_PTR(pIWbemClassObject);
  454. if( WBEM_NO_ERROR == hr )
  455. {
  456. CVARIANT vLow, vHigh, vName, vSuccess;
  457. vSuccess.SetBool(fSuccess);
  458. vName.SetStr(wcsKey);
  459. vLow.SetLONG(lLowDateTime);
  460. vHigh.SetLONG(lHighDateTime);
  461. hr = pNewInst->Put(L"Name", 0, &vName, NULL);
  462. if( S_OK == hr )
  463. {
  464. hr = pNewInst->Put(L"LowDateTime", 0, &vLow, NULL);
  465. if( S_OK == hr )
  466. {
  467. hr = pNewInst->Put(L"HighDateTime", 0, &vHigh, NULL);
  468. if( S_OK == hr )
  469. {
  470. hr = pNewInst->Put(L"MofProcessed", 0, &vSuccess, NULL);
  471. if( S_OK == hr )
  472. {
  473. CVARIANT vActive;
  474. vActive.SetBool(TRUE);
  475. pNewInst->Put(L"Active", 0, &vActive, NULL);
  476. }
  477. hr = REPOSITORY->PutInstance(pNewInst,WBEM_FLAG_CREATE_OR_UPDATE,CONTEXT,NULL);
  478. SAFE_RELEASE_PTR(pNewInst);
  479. }
  480. }
  481. }
  482. }
  483. }
  484. }
  485. if( hr == WBEM_NO_ERROR )
  486. {
  487. //==========================================
  488. // Make sure this really is in the registry
  489. // too
  490. //==========================================
  491. if( WBEM_NO_ERROR == AddThisMofToRegistryIfNeeded(WDM_REG_KEY,wcsKey,lLowDateTime,lHighDateTime,fSuccess))
  492. {
  493. fRc = TRUE;
  494. }
  495. }
  496. return fRc;
  497. }
  498. ///////////////////////////////////////////////////////////////////
  499. BOOL CWMIBinMof::GetNextSectionFromTheEnd(WCHAR * pwcsTempPath, WCHAR * pwcsEnd, int cchSize )
  500. {
  501. BOOL fReturn = FALSE;
  502. WCHAR * pc = wcsrchr(pwcsTempPath,'\\');
  503. if(pc)
  504. {
  505. //==================================================
  506. // Copy what was there and set the end to NULL
  507. //==================================================
  508. pc++;
  509. if ( *pc )
  510. {
  511. if ( SUCCEEDED ( StringCchCopyW ( pwcsEnd, cchSize, pc ) ) )
  512. {
  513. fReturn = TRUE;
  514. }
  515. }
  516. pc--;
  517. *(pc) = NULL;
  518. }
  519. return fReturn;
  520. }
  521. ///////////////////////////////////////////////////////////////////
  522. BOOL CWMIBinMof::UseDefaultLocaleId(WCHAR * wcsFile, WORD & wLocalId)
  523. {
  524. BOOL fLoadDefaultLocale = TRUE;
  525. //=============================================================
  526. // Parse paths - get the locale id from paths of this format:
  527. //
  528. // check for path beginning with %windir% and with MUI in second to last position
  529. // if not found, check for fixed directory: %windir%\MUI\Fallback
  530. // if not found - assume it is not MUI related and try it with FindResource
  531. //
  532. //=============================================================
  533. TCHAR* szWindowsDir = new TCHAR[_MAX_PATH + 1];
  534. if ( szWindowsDir )
  535. {
  536. UINT uSize = GetWindowsDirectory ( szWindowsDir , _MAX_PATH + 1);
  537. if ( uSize )
  538. {
  539. if ( uSize > MAX_PATH )
  540. {
  541. SAFE_DELETE_ARRAY ( szWindowsDir );
  542. szWindowsDir = new TCHAR [ uSize + 1 ];
  543. if ( szWindowsDir )
  544. {
  545. if ( ! GetWindowsDirectory( szWindowsDir, uSize + 1 ) )
  546. {
  547. SAFE_DELETE_ARRAY ( szWindowsDir );
  548. return fLoadDefaultLocale;
  549. }
  550. }
  551. else
  552. {
  553. return fLoadDefaultLocale;
  554. }
  555. }
  556. //==========================================================
  557. // if these are windows directories
  558. //==========================================================
  559. if( 0 == wbem_wcsnicmp( szWindowsDir, wcsFile, wcslen(szWindowsDir)))
  560. {
  561. CAutoWChar wcsTempPath(_MAX_PATH);
  562. CAutoWChar wcsBuffer(_MAX_PATH);
  563. if( wcsTempPath.Valid() && wcsBuffer.Valid() )
  564. {
  565. //======================================================
  566. // Find last \ in the string, and trim off filename
  567. //======================================================
  568. if ( SUCCEEDED ( StringCchCopyW (wcsTempPath,_MAX_PATH,wcsFile) ) )
  569. {
  570. if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer, _MAX_PATH ))
  571. {
  572. //==================================================
  573. // Now, get the potential locale id
  574. //==================================================
  575. if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer, _MAX_PATH ))
  576. {
  577. wLocalId = (WORD) _wtoi(wcsBuffer);
  578. //==============================================
  579. // Now, get the next bit to see if it says MUI
  580. // or Fallback
  581. //==============================================
  582. if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer, _MAX_PATH ))
  583. {
  584. if( 0 == wbem_wcsicmp( L"MUI", wcsBuffer ))
  585. {
  586. fLoadDefaultLocale = FALSE;
  587. }
  588. else if( 0 == wbem_wcsicmp( L"Fallback", wcsBuffer ) )
  589. {
  590. //==============================================
  591. // If it says Fallback, then check to make
  592. // sure the next bit says MUI
  593. //==============================================
  594. if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer, _MAX_PATH ))
  595. {
  596. if( 0 == wbem_wcsicmp( L"MUI", wcsBuffer ) )
  597. {
  598. fLoadDefaultLocale = FALSE;
  599. }
  600. }
  601. }
  602. }
  603. }
  604. }
  605. }
  606. }
  607. }
  608. }
  609. SAFE_DELETE_ARRAY ( szWindowsDir );
  610. }
  611. return fLoadDefaultLocale;
  612. }
  613. ///////////////////////////////////////////////////////////////////
  614. BOOL CWMIBinMof::GetPointerToBinaryResource(BYTE *& pRes,
  615. DWORD & dwSize,
  616. HGLOBAL & hResource,
  617. HINSTANCE & hInst,
  618. WCHAR * wcsResource,
  619. WCHAR * wcsFile,
  620. int cchSizeFile)
  621. {
  622. TCHAR * pResource = NULL;
  623. BOOL fRc = FALSE;
  624. DWORD dwError = 0;
  625. wmilib::auto_buffer<TCHAR> pFile;
  626. if( ExtractFileNameFromKey(pFile,wcsFile,cchSizeFile) ){
  627. pResource = wcsResource;
  628. if( pResource )
  629. {
  630. hInst = LoadLibraryEx(pFile.get(),NULL,LOAD_LIBRARY_AS_DATAFILE);
  631. if( hInst != NULL )
  632. {
  633. HRSRC hSrc = NULL;
  634. WORD wLocaleId = 0;
  635. if( UseDefaultLocaleId(wcsResource, wLocaleId ))
  636. {
  637. hSrc = FindResource(hInst,pResource, _T("MOFDATA"));
  638. }
  639. else
  640. {
  641. hSrc = FindResourceEx(hInst,pResource, _T("MOFDATA"),wLocaleId);
  642. }
  643. if( hSrc == NULL )
  644. {
  645. FreeLibrary(hInst);
  646. dwError = GetLastError();
  647. }
  648. if( NULL != hSrc)
  649. {
  650. hResource = LoadResource( hInst,hSrc);
  651. if( hResource )
  652. {
  653. pRes = (BYTE *)LockResource(hResource);
  654. dwSize = SizeofResource(hInst,hSrc);
  655. fRc = TRUE;
  656. }
  657. }
  658. }
  659. }
  660. #ifndef UNICODE
  661. SAFE_DELETE_ARRAY(pResource );
  662. #endif
  663. }
  664. return fRc;
  665. }
  666. /////////////////////////////////////////////////////////////////////
  667. BYTE * CWMIBinMof::DecompressBinaryMof(BYTE * pRes)
  668. {
  669. DWORD dwCompType, dwCompressedSize, dwExpandedSize, dwSig, dwResSize;
  670. BYTE * pExpanded = NULL;
  671. //=========================================================
  672. // get the signature, compression type, and the sizes
  673. //=========================================================
  674. memcpy(&dwSig,pRes,sizeof(DWORD));
  675. pRes += sizeof( DWORD );
  676. memcpy(&dwCompType,pRes,sizeof(DWORD));
  677. pRes += sizeof( DWORD );
  678. memcpy(&dwCompressedSize,pRes,sizeof(DWORD));
  679. pRes += sizeof( DWORD );
  680. memcpy(&dwExpandedSize,pRes,sizeof(DWORD));
  681. pRes += sizeof( DWORD );
  682. //=========================================================
  683. // make sure the signature is valid and that the compression type is one
  684. // we understand!
  685. //=========================================================
  686. if(dwSig != BMOF_SIG ||dwCompType != 1){
  687. return NULL;
  688. }
  689. //=========================================================
  690. // Allocate storage for the compressed data and
  691. // expanded data
  692. //=========================================================
  693. try
  694. {
  695. pExpanded = (BYTE*)malloc(dwExpandedSize);
  696. if( pExpanded == NULL)
  697. {
  698. goto ExitDecompression;
  699. }
  700. }
  701. catch(...)
  702. {
  703. throw;
  704. }
  705. //=========================================================
  706. // Decompress the data
  707. //=========================================================
  708. CBaseMrciCompression * pMrci = new CBaseMrciCompression;
  709. if( pMrci )
  710. {
  711. dwResSize = pMrci->Mrci1Decompress(pRes, dwCompressedSize, pExpanded, dwExpandedSize);
  712. if(dwResSize != dwExpandedSize)
  713. {
  714. SAFE_DELETE_PTR(pMrci);
  715. goto ExitDecompression;
  716. }
  717. SAFE_DELETE_PTR(pMrci);
  718. }
  719. //=========================================================
  720. // Now, get out of here
  721. //=========================================================
  722. return pExpanded;
  723. ExitDecompression:
  724. if( pExpanded )
  725. free(pExpanded);
  726. return NULL;
  727. }
  728. /////////////////////////////////////////////////////////////////////
  729. BOOL CWMIBinMof::ExtractFileNameFromKey(wmilib::auto_buffer<TCHAR> & pKey,WCHAR * wcsKey,int cchSize)
  730. {
  731. WCHAR *wcsToken = NULL;
  732. CAutoWChar wcsTmp(MAX_PATH * 4);
  733. BOOL fRc = FALSE;
  734. if( wcsTmp.Valid() )
  735. {
  736. if(wcsKey)
  737. {
  738. //======================================================
  739. // Get a ptr to the first [ , if there isn't one, then
  740. // just copy the whole thing.
  741. //======================================================
  742. if ( SUCCEEDED ( StringCchCopyW (wcsTmp,MAX_PATH*4,wcsKey) ) )
  743. {
  744. wcsToken = wcstok(wcsTmp, L"[" );
  745. if( wcsToken != NULL )
  746. {
  747. StringCchCopyW(wcsTmp,MAX_PATH*4,wcsToken);
  748. }
  749. int cchSizeNew = lstrlenW ( wcsTmp ) + 1;
  750. pKey.reset(new TCHAR[cchSizeNew]);
  751. if(pKey.get())
  752. {
  753. if ( SUCCEEDED ( StringCchCopyW (pKey.get(),cchSizeNew,wcsTmp) ) )
  754. {
  755. fRc = TRUE;
  756. }
  757. }
  758. }
  759. }
  760. }
  761. return fRc;
  762. }
  763. /////////////////////////////////////////////////////////////////////
  764. HRESULT CWMIBinMof::CreateKey(WCHAR * wcsFileName, WCHAR * wcsResource,WCHAR * wcsKey, int cchSizeKey)
  765. {
  766. return StringCchPrintfW(wcsKey,cchSizeKey,L"%s[%s]",wcsFileName, wcsResource );
  767. }
  768. /////////////////////////////////////////////////////////////////////
  769. HRESULT CWMIBinMof::SendToMofComp(DWORD dwSize,BYTE * pRes,WCHAR * wcsKey)
  770. {
  771. HRESULT hr = WBEM_NO_ERROR;
  772. if(m_pCompiler == NULL)
  773. {
  774. hr = CoCreateInstance(CLSID_WinmgmtMofCompiler, 0, CLSCTX_INPROC_SERVER,IID_IWinmgmtMofCompiler, (LPVOID *) &m_pCompiler);
  775. }
  776. if(hr == WBEM_NO_ERROR)
  777. {
  778. WBEM_COMPILE_STATUS_INFO Info;
  779. memset(&Info,0,sizeof(WBEM_COMPILE_STATUS_INFO));
  780. hr = m_pCompiler->WinmgmtCompileBuffer (
  781. dwSize,
  782. pRes,
  783. WBEM_FLAG_CONNECT_PROVIDERS,
  784. WBEM_FLAG_OWNER_UPDATE,
  785. WBEM_FLAG_OWNER_UPDATE,
  786. SERVICES,
  787. CONTEXT,
  788. &Info
  789. );
  790. if( hr != WBEM_NO_ERROR )
  791. {
  792. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  793. ERRORTRACE((THISPROVIDER,"Mofcomp of binary mof failed for:\n"));
  794. TranslateAndLog(wcsKey);
  795. ERRORTRACE((THISPROVIDER,"WinmgmtCompileBuffer return value: %ld\n",hr));
  796. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  797. ERRORTRACE((THISPROVIDER,"WBEM_COMPILE_STATUS_INFO:\n"));
  798. ERRORTRACE((THISPROVIDER,"\tphase:\t%d\n",Info.lPhaseError));
  799. ERRORTRACE((THISPROVIDER,"\thresult:\t0x%x\n",Info.hRes));
  800. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  801. ERRORTRACE((THISPROVIDER,"Size of Mof: %ld\n",dwSize));
  802. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  803. }
  804. else
  805. {
  806. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  807. DEBUGTRACE((THISPROVIDER,"Binary mof succeeded for:\n"));
  808. TranslateAndLog(wcsKey, TRUE);
  809. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  810. }
  811. }
  812. return hr;
  813. }
  814. /////////////////////////////////////////////////////////////////////
  815. BOOL CWMIBinMof::ExtractBinaryMofFromFile(WCHAR * wcsFile, WCHAR * wcsResource,WCHAR * wcsKey, int cchSizeKey, BOOL & fMofHasChanged)
  816. {
  817. HRESULT hr;
  818. BOOL fSuccess = FALSE;
  819. CAutoWChar wcsTmp(MAX_PATH*4);
  820. try
  821. {
  822. if( wcsTmp.Valid() )
  823. {
  824. ULONG lLowDateTime=0,lHighDateTime=0;
  825. //=====================================
  826. // As long as we have a list, process
  827. // one at a time
  828. //=====================================
  829. lLowDateTime = 0l;
  830. lHighDateTime = 0L;
  831. fMofHasChanged = FALSE;
  832. //==============================================
  833. // Compare the file date/timestamp the date/timestamp is different, change
  834. // it.
  835. //==============================================
  836. if ( SUCCEEDED ( StringCchCopyW(wcsTmp,MAX_PATH*4,wcsFile) ) )
  837. {
  838. if( GetFileDateAndTime(lLowDateTime,lHighDateTime,wcsTmp,MAX_PATH*4) )
  839. {
  840. if ( SUCCEEDED ( CreateKey(wcsTmp,wcsResource,wcsKey,cchSizeKey) ) )
  841. {
  842. if( NeedToProcessThisMof(wcsKey,lLowDateTime,lHighDateTime) )
  843. {
  844. fMofHasChanged = TRUE;
  845. if( m_fUpdateNamespace )
  846. {
  847. DWORD dwSize = 0;
  848. BYTE * pRes = NULL;
  849. HGLOBAL hResource = NULL;
  850. HINSTANCE hInst = NULL;
  851. if( GetPointerToBinaryResource(pRes,dwSize,hResource,hInst,wcsResource,wcsKey,cchSizeKey) )
  852. {
  853. hr = SendToMofComp(dwSize,pRes,wcsKey);
  854. if(hr == WBEM_S_NO_ERROR )
  855. {
  856. if( UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime, TRUE) )
  857. {
  858. CNamespaceManagement Namespace(this);
  859. Namespace.CreateClassAssociationsToDriver(wcsKey,pRes,lLowDateTime,lHighDateTime);
  860. Namespace.DeleteOldClasses(wcsKey,CVARIANT((long)lLowDateTime),CVARIANT((long)lHighDateTime), TRUE);
  861. fSuccess = TRUE;
  862. }
  863. else
  864. {
  865. UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime,FALSE);
  866. }
  867. }
  868. else
  869. {
  870. UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime,FALSE);
  871. }
  872. UnlockResource(hResource);
  873. FreeResource(hResource);
  874. FreeLibrary(hInst);
  875. }
  876. else
  877. {
  878. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  879. ERRORTRACE((THISPROVIDER,"Could not get pointer to binary resource for file:\n"));
  880. TranslateAndLog(wcsKey);
  881. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  882. UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime,FALSE);
  883. }
  884. }
  885. }
  886. else
  887. {
  888. fSuccess = TRUE;
  889. }
  890. }
  891. }
  892. else
  893. {
  894. UpdateMofTimestampInHMOM(wcsFile,lLowDateTime,lHighDateTime,FALSE);
  895. StringCchCopyW(wcsKey, cchSizeKey, wcsFile);
  896. }
  897. }
  898. }
  899. }
  900. catch ( CHeap_Exception & exc )
  901. {
  902. fSuccess = FALSE ;
  903. }
  904. return fSuccess;
  905. }
  906. //////////////////////////////////////////////////////////////////////////
  907. #define WDMPROV_REG_KEY L"Software\\Microsoft\\WBEM\\WDMProvider"
  908. BOOL CWMIBinMof::UserConfiguredRegistryToProcessStrandedClassesDuringEveryInit(void)
  909. {
  910. DWORD dwProcess = 0;
  911. CRegistry RegInfo ;
  912. DWORD dwRet = RegInfo.Open (HKEY_LOCAL_MACHINE, WDMPROV_REG_KEY, KEY_READ) ;
  913. if ( dwRet == ERROR_SUCCESS )
  914. {
  915. RegInfo.GetCurrentKeyValue ( L"ProcessStrandedClasses",dwProcess );
  916. }
  917. RegInfo.Close();
  918. return (BOOL) dwProcess;
  919. }
  920. /////////// //////////////////////////////////////////////////////////
  921. void CWMIBinMof::ProcessListOfWMIBinaryMofsFromWMI()
  922. {
  923. HRESULT hr = WBEM_E_FAILED;
  924. try
  925. {
  926. if( m_nInit == FULLY_INITIALIZED )
  927. {
  928. CAutoWChar wcsFileName(MAX_PATH*3);
  929. CAutoWChar wcsResource(MAX_PATH*3);
  930. if( wcsFileName.Valid() && wcsResource.Valid() )
  931. {
  932. KeyList ArrDriversInRegistry;
  933. //============================================================
  934. // Get list of what is currently in the registry
  935. //============================================================
  936. GetListOfDriversCurrentlyInRegistry(WDM_REG_KEY,ArrDriversInRegistry);
  937. //======================================================================
  938. // Initialize things
  939. //======================================================================
  940. BOOL fMofChanged = FALSE;
  941. m_fUpdateNamespace = TRUE;
  942. //======================================================================
  943. // Allocate working classes
  944. //======================================================================
  945. CWMIStandardShell * pWMI = new CWMIStandardShell;
  946. if( pWMI )
  947. {
  948. ON_BLOCK_EXIT ( deletePtr < CWMIStandardShell >, pWMI ) ;
  949. hr = pWMI->Initialize (
  950. NULL,
  951. FALSE,
  952. m_pWMI->HandleMap(),
  953. m_fUpdateNamespace,
  954. WMIGUID_QUERY,
  955. m_pWMI->Services(),
  956. m_pWMI->Repository(),
  957. m_pWMI->Handler(),
  958. m_pWMI->Context()
  959. );
  960. if( S_OK == hr )
  961. {
  962. CNamespaceManagement * pNamespace = new CNamespaceManagement(this);
  963. if( pNamespace )
  964. {
  965. ON_BLOCK_EXIT ( deletePtr < CNamespaceManagement >, pNamespace ) ;
  966. //=========================================
  967. // Query the binary guid
  968. //=========================================
  969. if ( SUCCEEDED ( hr = pNamespace->InitQuery(L"select * from WMIBinaryMofResource where Name != ") ) )
  970. {
  971. pWMI->QueryAndProcessAllBinaryGuidInstances(*pNamespace, fMofChanged, &ArrDriversInRegistry);
  972. //=========================================
  973. // Get a list of binary mofs from WMI
  974. //=========================================
  975. GetListOfBinaryMofs();
  976. ULONG nTmp=0;
  977. CAutoWChar wcsTmpKey(MAX_PATH*3);
  978. BOOL fProcessStrandedClasses = FALSE;
  979. if( wcsTmpKey.Valid() )
  980. {
  981. if( m_uResourceCount > 0 )
  982. {
  983. //===============================================================
  984. // Go through and get all the resources to process one by one
  985. //===============================================================
  986. while( GetBinaryMofFileNameAndResourceName(wcsFileName,MAX_PATH*3,wcsResource,MAX_PATH*3) && SUCCEEDED ( hr ) )
  987. {
  988. //============================================================
  989. // Process the binary mof
  990. //============================================================
  991. if( ExtractBinaryMofFromFile(wcsFileName,wcsResource,wcsTmpKey,MAX_PATH*3,fMofChanged))
  992. {
  993. hr = pNamespace->UpdateQuery(L" and Name != ",wcsTmpKey);
  994. }
  995. if( fMofChanged )
  996. {
  997. fProcessStrandedClasses = TRUE;
  998. }
  999. ArrDriversInRegistry.Remove(wcsTmpKey);
  1000. }
  1001. }
  1002. }
  1003. if ( SUCCEEDED ( hr ) )
  1004. {
  1005. pNamespace->DeleteOldDrivers(FALSE);
  1006. //===========================================================================
  1007. // If we are not supposed to process stranded classes, check the reg key
  1008. // to see if it wants us to anyway
  1009. //===========================================================================
  1010. if( !fProcessStrandedClasses )
  1011. {
  1012. fProcessStrandedClasses = UserConfiguredRegistryToProcessStrandedClassesDuringEveryInit();
  1013. }
  1014. if( fProcessStrandedClasses )
  1015. {
  1016. pNamespace->DeleteStrandedClasses();
  1017. }
  1018. DeleteOldDriversInRegistry(ArrDriversInRegistry);
  1019. }
  1020. else
  1021. {
  1022. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  1023. DEBUGTRACE((THISPROVIDER,"Failure in processing binary mofs\n"));
  1024. DEBUGTRACE((THISPROVIDER,"Resources %d\n", m_uResourceCount));
  1025. DEBUGTRACE((THISPROVIDER,"Current %d\n", m_uCurrentResource));
  1026. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  1027. }
  1028. }
  1029. }
  1030. }
  1031. }
  1032. if( m_pMofResourceInfo )
  1033. {
  1034. WmiFreeBuffer( m_pMofResourceInfo );
  1035. }
  1036. }
  1037. }
  1038. }
  1039. catch ( CHeap_Exception & exc )
  1040. {
  1041. }
  1042. DEBUGTRACE((THISPROVIDER,"End of processing Binary MOFS\n"));
  1043. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  1044. }
  1045. /////////////////////////////////////////////////////////////////////
  1046. //=============================================================
  1047. // THE BINARY MOF GROUP
  1048. //=============================================================
  1049. BOOL CWMIBinMof::GetListOfBinaryMofs()
  1050. {
  1051. BOOL fRc = TRUE;
  1052. ULONG uRc;
  1053. m_uCurrentResource = 0;
  1054. m_pMofResourceInfo = NULL;
  1055. m_uResourceCount = 0;
  1056. try
  1057. {
  1058. uRc = WmiMofEnumerateResourcesW( 0, &m_uResourceCount, &m_pMofResourceInfo );
  1059. if( uRc != ERROR_SUCCESS )
  1060. {
  1061. fRc = FALSE;
  1062. }
  1063. }
  1064. catch(...)
  1065. {
  1066. fRc = FALSE;
  1067. // don't throw
  1068. }
  1069. return fRc;
  1070. }
  1071. //=============================================================
  1072. BOOL CWMIBinMof::GetBinaryMofFileNameAndResourceName(WCHAR * pwcsFileName, int cchSizeFile, WCHAR * pwcsResource, int cchSizeResource )
  1073. {
  1074. BOOL fRc = FALSE;
  1075. //===================================================================
  1076. // There are a lot of tests in here, due to strange results from
  1077. // WDM Service under stress.
  1078. //===================================================================
  1079. if( m_uCurrentResource < m_uResourceCount ){
  1080. if( m_pMofResourceInfo ){
  1081. DWORD dwFileLen = wcslen(m_pMofResourceInfo[m_uCurrentResource].ImagePath);
  1082. DWORD dwResourceLen = wcslen(m_pMofResourceInfo[m_uCurrentResource].ResourceName);
  1083. if( IsBadReadPtr( m_pMofResourceInfo[m_uCurrentResource].ImagePath,dwFileLen) == 0 )
  1084. {
  1085. if ( SUCCEEDED ( StringCchCopyW( pwcsFileName, cchSizeFile, m_pMofResourceInfo[m_uCurrentResource].ImagePath ) ) )
  1086. {
  1087. if( IsBadReadPtr( m_pMofResourceInfo[m_uCurrentResource].ResourceName,dwResourceLen) == 0 )
  1088. {
  1089. if ( SUCCEEDED ( StringCchCopyW ( pwcsResource, cchSizeResource, m_pMofResourceInfo[m_uCurrentResource].ResourceName ) ) )
  1090. {
  1091. m_uCurrentResource++;
  1092. fRc = TRUE;
  1093. }
  1094. }
  1095. }
  1096. }
  1097. }
  1098. }
  1099. return fRc;
  1100. }
  1101. ////////////////////////////////////////////////////////////////////
  1102. HRESULT CWMIBinMof::ExtractBinaryMofFromDataBlock(BYTE * pByte,ULONG uInstanceSize, WCHAR * wcsKey, BOOL & fMofHasChanged)
  1103. {
  1104. HRESULT hr = WBEM_E_FAILED;
  1105. //===================================================
  1106. // Get the CRC of the data buffer
  1107. //===================================================
  1108. DWORD dwCRC = STARTING_CRC32_VALUE;
  1109. if( IsBadReadPtr( pByte,uInstanceSize) != 0 ){
  1110. return WBEM_E_INVALID_OBJECT;
  1111. }
  1112. dwCRC = UpdateCRC32(pByte,uInstanceSize, dwCRC);
  1113. FINALIZE_CRC32(dwCRC);
  1114. //=========================================================
  1115. // get the size of the buffer to send
  1116. //=========================================================
  1117. DWORD dwCompressedSize;
  1118. BYTE * pTmp = pByte;
  1119. pTmp += sizeof( DWORD ) * 2;
  1120. memcpy(&dwCompressedSize,pTmp,sizeof(DWORD));
  1121. dwCompressedSize += 16;
  1122. fMofHasChanged = FALSE;
  1123. //===================================================
  1124. // See if we should process this class or not
  1125. //===================================================
  1126. ULONG lLow = dwCRC;
  1127. ULONG lHigh = 0;
  1128. try
  1129. {
  1130. if( NeedToProcessThisMof(wcsKey,lLow,lHigh))
  1131. {
  1132. if( !m_fUpdateNamespace )
  1133. {
  1134. fMofHasChanged = TRUE;
  1135. hr = WBEM_NO_ERROR;
  1136. }
  1137. else
  1138. {
  1139. hr = SendToMofComp(dwCompressedSize,pByte,wcsKey);
  1140. if( hr == WBEM_NO_ERROR )
  1141. {
  1142. if( UpdateMofTimestampInHMOM(wcsKey,lLow,lHigh, TRUE))
  1143. {
  1144. CNamespaceManagement Namespace(this);
  1145. Namespace.CreateClassAssociationsToDriver(wcsKey,pByte,lLow,lHigh);
  1146. Namespace.DeleteOldClasses(wcsKey,CVARIANT((long)lLow),CVARIANT((long)lHigh),TRUE);
  1147. }
  1148. else
  1149. {
  1150. UpdateMofTimestampInHMOM(wcsKey,lLow,lHigh,FALSE);
  1151. }
  1152. }
  1153. else
  1154. {
  1155. UpdateMofTimestampInHMOM(wcsKey,lLow,lHigh,FALSE);
  1156. }
  1157. }
  1158. }
  1159. else
  1160. {
  1161. hr = WBEM_NO_ERROR;
  1162. }
  1163. }
  1164. catch ( CHeap_Exception & exc )
  1165. {
  1166. hr = WBEM_E_OUT_OF_MEMORY ;
  1167. }
  1168. return hr;
  1169. }
  1170. ////////////////////////////////////////////////////////////////////
  1171. HRESULT CWMIBinMof::DeleteMofsFromEvent(CVARIANT & vImagePath,CVARIANT & vResourceName, BOOL & fMofHasChanged)
  1172. {
  1173. HRESULT hr = WBEM_E_OUT_OF_MEMORY;
  1174. CAutoWChar wcsTmp(MAX_PATH*2);
  1175. if( wcsTmp.Valid() )
  1176. {
  1177. hr = WBEM_E_INVALID_OBJECT;
  1178. //=========================================
  1179. // Initialize stuff
  1180. //=========================================
  1181. fMofHasChanged = FALSE;
  1182. try
  1183. {
  1184. //=================================================================
  1185. // if we have an image path and resource path we are working with
  1186. // file, otherwise it is a binary guidd
  1187. //=================================================================
  1188. if((vResourceName.GetType() != VT_NULL ) && ( vImagePath.GetType() != VT_NULL )){
  1189. hr = CreateKey( vImagePath.GetStr(), vResourceName.GetStr(),wcsTmp, MAX_PATH*2 );
  1190. }
  1191. else if( vResourceName.GetType() != VT_NULL ){
  1192. hr = SetBinaryMofClassName(vResourceName.GetStr(),wcsTmp, MAX_PATH*2);
  1193. }
  1194. if ( SUCCEEDED ( hr ) )
  1195. {
  1196. if( m_fUpdateNamespace )
  1197. {
  1198. CNamespaceManagement Namespace(this);
  1199. if ( SUCCEEDED ( hr = Namespace.InitQuery(L"select * from WMIBinaryMofResource where Name = ") ) )
  1200. {
  1201. if ( SUCCEEDED ( hr = Namespace.UpdateQuery(L"",wcsTmp) ) )
  1202. {
  1203. if( Namespace.DeleteOldDrivers(FALSE) )
  1204. {
  1205. hr = WBEM_NO_ERROR;
  1206. fMofHasChanged = TRUE;
  1207. }
  1208. }
  1209. }
  1210. }
  1211. else
  1212. {
  1213. if( ThisMofExistsInRegistry(WDM_REG_KEY,wcsTmp, 0, 0, FALSE))
  1214. {
  1215. fMofHasChanged = TRUE;
  1216. }
  1217. hr = WBEM_NO_ERROR;
  1218. }
  1219. }
  1220. }
  1221. catch ( CHeap_Exception & exc )
  1222. {
  1223. hr = WBEM_E_OUT_OF_MEMORY ;
  1224. }
  1225. }
  1226. return hr;
  1227. }
  1228. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1229. //**********************************************************************************************************************
  1230. // Functions for the Dredger
  1231. //**********************************************************************************************************************
  1232. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1233. // format of string containing mof info is:
  1234. // "WmiBinaryMofResource.HighDateTime=9999,LowDateTime=9999,Name="Whatever"
  1235. //
  1236. // HKLM\Software\Microsoft\WBEM\WDM\WDMBinaryMofResource
  1237. //
  1238. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1239. HRESULT CWMIBinMof::AddThisMofToRegistryIfNeeded(WCHAR * wcsKey, WCHAR * wcsFileName, ULONG & lLowDateTime, ULONG & lHighDateTime, BOOL fSuccess)
  1240. {
  1241. HRESULT hr = WBEM_E_FAILED;
  1242. CRegistry RegInfo ;
  1243. DWORD dwRet = RegInfo.CreateOpen (HKEY_LOCAL_MACHINE, wcsKey) ;
  1244. if ( dwRet == ERROR_SUCCESS )
  1245. {
  1246. CAutoWChar wcsBuf(MAX_PATH);
  1247. if( wcsBuf.Valid() )
  1248. {
  1249. if( fSuccess )
  1250. {
  1251. StringCchPrintfW(wcsBuf,MAX_PATH,L"LowDateTime:%ld,HighDateTime:%ld***Binary mof compiled successfully", lLowDateTime, lHighDateTime);
  1252. }
  1253. else
  1254. {
  1255. StringCchPrintfW(wcsBuf,MAX_PATH,L"LowDateTime:%ld,HighDateTime:%ld***Binary mof failed, see WMIPROV.LOG", lLowDateTime, lHighDateTime);
  1256. }
  1257. CHString sTmp = wcsBuf;
  1258. if ( RegInfo.SetCurrentKeyValue ( wcsFileName,sTmp ) == ERROR_SUCCESS )
  1259. {
  1260. hr = WBEM_S_NO_ERROR ;
  1261. }
  1262. }
  1263. else
  1264. {
  1265. hr = WBEM_E_OUT_OF_MEMORY;
  1266. }
  1267. }
  1268. RegInfo.Close();
  1269. return hr;
  1270. }
  1271. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1272. BOOL CWMIBinMof::ThisMofExistsInRegistry(WCHAR * wcsKey,WCHAR * wcsFileName, ULONG lLowDateTime, ULONG lHighDateTime, BOOL fCompareDates)
  1273. {
  1274. BOOL fExists = FALSE;
  1275. CRegistry RegInfo ;
  1276. DWORD dwRet = RegInfo.Open (HKEY_LOCAL_MACHINE, wcsKey, KEY_READ) ;
  1277. if ( dwRet == ERROR_SUCCESS )
  1278. {
  1279. CHString chsValue;
  1280. if ( RegInfo.GetCurrentKeyValue ( wcsFileName,chsValue ) == ERROR_SUCCESS )
  1281. {
  1282. if( fCompareDates )
  1283. {
  1284. CAutoWChar wcsIncomingValue(MAX_PATH);
  1285. CAutoWChar wcsTmp(MAX_PATH);
  1286. if( wcsIncomingValue.Valid() && wcsTmp.Valid() )
  1287. {
  1288. if ( SUCCEEDED ( StringCchPrintfW (wcsIncomingValue, MAX_PATH, L"LowDateTime:%ld,HighDateTime:%ld", lLowDateTime, lHighDateTime ) ) )
  1289. {
  1290. WCHAR *wcsToken = NULL;
  1291. //======================================================
  1292. // Get a ptr to the first *** , if there isn't one, then
  1293. // we have a messed up key
  1294. //======================================================
  1295. if ( SUCCEEDED ( StringCchCopyW ( wcsTmp, MAX_PATH, (const WCHAR*)chsValue ) ) )
  1296. {
  1297. wcsToken = wcstok(wcsTmp, L"*" );
  1298. if( wcsToken != NULL )
  1299. {
  1300. if( wbem_wcsicmp(wcsToken, wcsIncomingValue) == 0 )
  1301. {
  1302. fExists = TRUE;
  1303. }
  1304. }
  1305. }
  1306. }
  1307. }
  1308. }
  1309. else
  1310. {
  1311. fExists = TRUE;
  1312. }
  1313. }
  1314. }
  1315. RegInfo.Close();
  1316. return fExists;
  1317. }
  1318. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1319. HRESULT CWMIBinMof::DeleteMofFromRegistry(WCHAR * wcsFileName)
  1320. {
  1321. HRESULT hr = WBEM_E_FAILED;
  1322. HKEY hKey;
  1323. hr = RegOpenKey(HKEY_LOCAL_MACHINE, WDM_REG_KEY, &hKey);
  1324. if(NO_ERROR == hr)
  1325. {
  1326. hr = RegDeleteValue(hKey,wcsFileName);
  1327. CloseHandle(hKey);
  1328. }
  1329. return hr;
  1330. }
  1331. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1332. BOOL CWMIBinMof::DeleteOldDriversInRegistry(KeyList & ArrDriversInRegistry)
  1333. {
  1334. int nSize = ArrDriversInRegistry.GetSize();
  1335. for( int i=0; i < nSize; i++ )
  1336. {
  1337. DeleteMofFromRegistry(ArrDriversInRegistry.GetAt(i));
  1338. }
  1339. return TRUE;
  1340. }
  1341. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1342. BOOL CWMIBinMof::CopyWDMKeyToDredgeKey()
  1343. {
  1344. BOOL fSuccess = FALSE;
  1345. //=======================================================================
  1346. // Open up the WDM Dredge Key and enumerate the keys, copy them into
  1347. // the DredgeReg key
  1348. //=======================================================================
  1349. CRegistry WDMReg;
  1350. CRegistry WDMDregReg;
  1351. try
  1352. {
  1353. if (ERROR_SUCCESS == WDMReg.Open(HKEY_LOCAL_MACHINE, WDM_REG_KEY, KEY_READ))
  1354. {
  1355. ON_BLOCK_EXIT_OBJ ( WDMReg, CRegistry::Close ) ;
  1356. //===============================================================
  1357. // Clean up old stuff
  1358. // Note: You need to open up the parent key, so you can delete
  1359. // the child DREDGE key
  1360. //===============================================================
  1361. if( ERROR_SUCCESS == WDMDregReg.Open(HKEY_LOCAL_MACHINE, WDM_REG_KEY, KEY_READ))
  1362. {
  1363. ON_BLOCK_EXIT_OBJ ( WDMDregReg, CRegistry::Close ) ;
  1364. CHString pchs(DREDGE_KEY);
  1365. WDMDregReg.DeleteKey ( &pchs ) ;
  1366. }
  1367. if( ERROR_SUCCESS == WDMDregReg.CreateOpen(HKEY_LOCAL_MACHINE, WDM_DREDGE_KEY))
  1368. {
  1369. ON_BLOCK_EXIT_OBJ ( WDMDregReg, CRegistry::Close ) ;
  1370. //===============================================================
  1371. // Go through the loop, and copy the keys
  1372. //===============================================================
  1373. BYTE *pValueData = NULL ;
  1374. WCHAR *pValueName = NULL ;
  1375. fSuccess = TRUE;
  1376. for(DWORD i = 0 ; i < WDMReg.GetValueCount(); i++)
  1377. {
  1378. DWORD dwRc = WDMReg.EnumerateAndGetValues(i, pValueName, pValueData) ;
  1379. if( dwRc == ERROR_SUCCESS )
  1380. {
  1381. ON_BLOCK_EXIT ( deleteArray < TCHAR >, pValueName ) ;
  1382. ON_BLOCK_EXIT ( deleteArray < BYTE >, pValueData ) ;
  1383. CHString chsKey(pValueName);
  1384. CHString chsValue((LPCWSTR)pValueData);
  1385. if ( !WDMDregReg.SetCurrentKeyValue ( chsKey, chsValue ) == ERROR_SUCCESS )
  1386. {
  1387. fSuccess = FALSE;
  1388. }
  1389. }
  1390. else
  1391. {
  1392. fSuccess = FALSE;
  1393. }
  1394. if( !fSuccess )
  1395. {
  1396. break;
  1397. }
  1398. }
  1399. }
  1400. }
  1401. }
  1402. catch ( CHeap_Exception & exc )
  1403. {
  1404. fSuccess = FALSE ;
  1405. }
  1406. return fSuccess;
  1407. }
  1408. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1409. BOOL CWMIBinMof::GetListOfDriversCurrentlyInRegistry(WCHAR * wcsKey, KeyList & ArrDriversInRegistry)
  1410. {
  1411. BOOL fSuccess = TRUE;
  1412. //==========================================================
  1413. // Open the key for enumeration and go through the sub keys.
  1414. //==========================================================
  1415. HKEY hKey = NULL;
  1416. HRESULT hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, wcsKey, 0, KEY_READ | KEY_QUERY_VALUE,&hKey);
  1417. if( ERROR_SUCCESS == hr )
  1418. {
  1419. WCHAR wcsKeyName[MAX_PATH+2];
  1420. DWORD dwLen = 0;
  1421. int i = 0;
  1422. while( ERROR_SUCCESS == hr )
  1423. {
  1424. dwLen = MAX_PATH+2;
  1425. hr = RegEnumValue(hKey,i,wcsKeyName, &dwLen,0,NULL,NULL,NULL);
  1426. // If we are successful reading the name
  1427. //=======================================
  1428. if(ERROR_SUCCESS == hr )
  1429. {
  1430. ArrDriversInRegistry.Add(wcsKeyName);
  1431. i++;
  1432. }
  1433. else
  1434. {
  1435. break;
  1436. }
  1437. }
  1438. RegCloseKey(hKey);
  1439. }
  1440. else
  1441. {
  1442. fSuccess = FALSE;
  1443. }
  1444. return fSuccess;
  1445. }
  1446. /////////////////////////////////////////////////////////////////////
  1447. HRESULT CWMIBinMof::ProcessBinaryMofEvent(PWNODE_HEADER WnodeHeader )
  1448. {
  1449. HRESULT hr = WBEM_E_FAILED;
  1450. m_fUpdateNamespace = TRUE;
  1451. if( m_nInit == FULLY_INITIALIZED )
  1452. {
  1453. CWMIStandardShell * pWMI = new CWMIStandardShell;
  1454. if( pWMI )
  1455. {
  1456. //=======================================================
  1457. // See if a binary mof event is being added or deleted
  1458. //=======================================================
  1459. if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_ADDED_GUID,WnodeHeader->Guid))
  1460. {
  1461. hr = pWMI->Initialize (
  1462. RUNTIME_BINARY_MOFS_ADDED,
  1463. TRUE,
  1464. m_pWMI->HandleMap(),
  1465. m_fUpdateNamespace,
  1466. WMIGUID_QUERY,
  1467. m_pWMI->Services(),
  1468. m_pWMI->Repository(),
  1469. m_pWMI->Handler(),
  1470. m_pWMI->Context()
  1471. );
  1472. if( S_OK == hr )
  1473. {
  1474. hr = pWMI->ProcessEvent(MOF_ADDED,WnodeHeader);
  1475. }
  1476. }
  1477. else if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_REMOVED_GUID,WnodeHeader->Guid))
  1478. {
  1479. hr = pWMI->Initialize (
  1480. RUNTIME_BINARY_MOFS_DELETED,
  1481. TRUE,
  1482. m_pWMI->HandleMap(),
  1483. m_fUpdateNamespace,
  1484. WMIGUID_QUERY,
  1485. m_pWMI->Services(),
  1486. m_pWMI->Repository(),
  1487. m_pWMI->Handler(),
  1488. m_pWMI->Context()
  1489. );
  1490. if( S_OK == hr )
  1491. {
  1492. hr = pWMI->ProcessEvent(MOF_DELETED,WnodeHeader);
  1493. }
  1494. }
  1495. SAFE_DELETE_PTR(pWMI);
  1496. }
  1497. }
  1498. return hr;
  1499. }
  1500. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1501. //**********************************************************************************************************************
  1502. // STUFF FOR DREDGE
  1503. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1504. //**********************************************************************************************************************
  1505. /////////////////////////////////////////////////////////////////////
  1506. // DREDGE APIS - access ONLY the DREDGE KEY
  1507. /////////////////////////////////////////////////////////////////////
  1508. BOOL CWMIBinMof::BinaryMofEventChanged(PWNODE_HEADER WnodeHeader )
  1509. {
  1510. BOOL fMofHasChanged = TRUE;
  1511. if( m_nInit != NOT_INITIALIZED )
  1512. {
  1513. HRESULT hr = WBEM_E_NOT_FOUND;
  1514. m_fUpdateNamespace = FALSE;
  1515. CWMIStandardShell * pWMI = new CWMIStandardShell;
  1516. if( pWMI )
  1517. {
  1518. //=======================================================
  1519. // See if a binary mof event is being added or deleted
  1520. //=======================================================
  1521. if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_ADDED_GUID,WnodeHeader->Guid))
  1522. {
  1523. hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_ADDED,
  1524. TRUE,
  1525. NULL,
  1526. m_fUpdateNamespace,
  1527. WMIGUID_QUERY,
  1528. NULL,
  1529. NULL,
  1530. NULL,
  1531. NULL);
  1532. if( S_OK == hr )
  1533. {
  1534. hr = pWMI->ProcessEvent(MOF_ADDED,WnodeHeader);
  1535. }
  1536. }
  1537. else if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_REMOVED_GUID,WnodeHeader->Guid))
  1538. {
  1539. // DO NOTHING
  1540. hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_DELETED,TRUE,
  1541. NULL,
  1542. m_fUpdateNamespace,
  1543. WMIGUID_QUERY,
  1544. NULL,
  1545. NULL,
  1546. NULL,
  1547. NULL);
  1548. if( S_OK == hr )
  1549. {
  1550. // only provider will handle deletion of driver
  1551. // hr = pWMI->ProcessEvent(MOF_DELETED,WnodeHeader);
  1552. }
  1553. }
  1554. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  1555. if( pWMI->HasMofChanged() )
  1556. {
  1557. DEBUGTRACE((THISPROVIDER,"BinaryMofEventChanged returned TRUE:\n"));
  1558. }
  1559. else
  1560. {
  1561. DEBUGTRACE((THISPROVIDER,"BinaryMofEventChanged returned FALSE:\n"));
  1562. }
  1563. fMofHasChanged = pWMI->HasMofChanged();
  1564. SAFE_DELETE_PTR(pWMI);
  1565. }
  1566. }
  1567. return fMofHasChanged;
  1568. }
  1569. /////////////////////////////////////////////////////////////////////
  1570. // DREDGE APIS - access ONLY the DREDGE KEY
  1571. /////////////////////////////////////////////////////////////////////
  1572. BOOL CWMIBinMof::BinaryMofsHaveChanged()
  1573. {
  1574. BOOL fBinaryMofHasChanged = FALSE;
  1575. if( m_nInit != NOT_INITIALIZED )
  1576. {
  1577. KeyList ArrDriversInRegistry;
  1578. HRESULT hr = WBEM_E_FAILED;
  1579. m_fUpdateNamespace = FALSE;
  1580. //============================================================
  1581. // Get list of what is currently in the registry
  1582. //============================================================
  1583. BOOL fRc = GetListOfDriversCurrentlyInRegistry(WDM_DREDGE_KEY,ArrDriversInRegistry);
  1584. if( fRc )
  1585. {
  1586. //=====================================================================
  1587. // Get a list of binary mofs from WMI
  1588. // Query WMIBinaryMofResource for list of static mofs
  1589. //=====================================================================
  1590. GetListOfBinaryMofs();
  1591. if( m_uResourceCount > 0 )
  1592. {
  1593. //===============================================================
  1594. // Go through and get all the resources to process one by one
  1595. //===============================================================
  1596. CAutoWChar FileName(MAX_PATH*2);
  1597. CAutoWChar Resource(MAX_PATH*2);
  1598. CAutoWChar TmpKey(MAX_PATH*2);
  1599. if( FileName.Valid() && Resource.Valid() && TmpKey.Valid() )
  1600. {
  1601. while( GetBinaryMofFileNameAndResourceName(FileName,MAX_PATH*2,Resource,MAX_PATH*2))
  1602. {
  1603. //============================================================
  1604. // Process the binary mof, keep going until one needs to
  1605. // be processed
  1606. //============================================================
  1607. ExtractBinaryMofFromFile(FileName,Resource,TmpKey, MAX_PATH*2,fBinaryMofHasChanged );
  1608. if( fBinaryMofHasChanged )
  1609. {
  1610. break;
  1611. }
  1612. ArrDriversInRegistry.Remove(TmpKey);
  1613. }
  1614. }
  1615. }
  1616. if( !fBinaryMofHasChanged )
  1617. {
  1618. //=========================================
  1619. // Query the binary guid
  1620. //=========================================
  1621. CNamespaceManagement * pNamespace = new CNamespaceManagement(this);
  1622. if( pNamespace )
  1623. {
  1624. if ( SUCCEEDED ( hr = pNamespace->InitQuery(L"select * from WMIBinaryMofResource where Name != ") ) )
  1625. {
  1626. CWMIStandardShell * pWMI = new CWMIStandardShell;
  1627. if( pWMI )
  1628. {
  1629. hr = pWMI->Initialize(NULL, FALSE, NULL,m_fUpdateNamespace, WMIGUID_QUERY,NULL,NULL,NULL,NULL);
  1630. if( S_OK == hr )
  1631. {
  1632. pWMI->QueryAndProcessAllBinaryGuidInstances(*pNamespace, fBinaryMofHasChanged,&ArrDriversInRegistry);
  1633. }
  1634. SAFE_DELETE_PTR(pWMI);
  1635. }
  1636. }
  1637. SAFE_DELETE_PTR(pNamespace);
  1638. }
  1639. else
  1640. {
  1641. hr = WBEM_E_OUT_OF_MEMORY;
  1642. }
  1643. }
  1644. /* //============================================================
  1645. // If there are any drivers left in the list, then we need
  1646. // to say that the binary mofs have changed
  1647. //============================================================
  1648. if( !fBinaryMofHasChanged )
  1649. {
  1650. if( ArrDriversInRegistry.OldDriversLeftOver() )
  1651. {
  1652. fBinaryMofHasChanged = TRUE;
  1653. }
  1654. }
  1655. */
  1656. }
  1657. else
  1658. {
  1659. //==============================================================================================
  1660. // there is no key, so now we need to return that the registry has changed, so the copy of the
  1661. // keys will be kicked off
  1662. //==============================================================================================
  1663. fBinaryMofHasChanged = TRUE;
  1664. }
  1665. if( m_pMofResourceInfo )
  1666. {
  1667. WmiFreeBuffer( m_pMofResourceInfo );
  1668. }
  1669. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  1670. if( fBinaryMofHasChanged )
  1671. {
  1672. DEBUGTRACE((THISPROVIDER,"BinaryMofsHaveChanged returned TRUE:\n"));
  1673. }
  1674. else
  1675. {
  1676. DEBUGTRACE((THISPROVIDER,"BinaryMofsHaveChanged returned FALSE:\n"));
  1677. }
  1678. }
  1679. return fBinaryMofHasChanged;
  1680. }
  1681. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1682. //**********************************************************************************************************************
  1683. // Namespace Management Class
  1684. //**********************************************************************************************************************
  1685. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1686. CNamespaceManagement::CNamespaceManagement(CWMIBinMof * pOwner)
  1687. {
  1688. m_pObj = pOwner;
  1689. m_nSize = 0;
  1690. m_pwcsQuery = NULL;
  1691. m_fInit = 0;
  1692. m_pwcsSavedQuery = NULL;
  1693. m_fSavedInit = 0;
  1694. m_nSavedSize = 0;
  1695. }
  1696. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1697. CNamespaceManagement::~CNamespaceManagement()
  1698. {
  1699. SAFE_DELETE_ARRAY( m_pwcsQuery );
  1700. }
  1701. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1702. #define SERVICES_PTR m_pObj->WMI()->Services()
  1703. #define REPOSITORY_PTR m_pObj->WMI()->Repository()
  1704. #define CONTEXT_PTR m_pObj->WMI()->Context()
  1705. /////////////////////////////////////////////////////////////////////////////////////////////////
  1706. //
  1707. // IsClassPseudoSystem
  1708. // ===================================
  1709. //
  1710. // returns false if class doesn't belong to set of
  1711. // pseudo system classes which should be not deleted
  1712. //
  1713. /////////////////////////////////////////////////////////////////////////////////////////////////
  1714. BOOL CNamespaceManagement::IsClassPseudoSystem ( LPCWSTR wcsClass )
  1715. {
  1716. BOOL fResult = FALSE ;
  1717. if ( wcsClass )
  1718. {
  1719. static LPWSTR wcsPseudoSystem [] = {
  1720. L"WMIEvent",
  1721. L"Win32_Perf",
  1722. L"Win32_PerfRawData",
  1723. L"Win32_PerfFormattedData"
  1724. };
  1725. static DWORD dwPseudoSystem = sizeof ( wcsPseudoSystem ) / sizeof ( wcsPseudoSystem [ 0 ] ) ;
  1726. for ( DWORD dwIndex = 0; dwIndex < dwPseudoSystem; dwIndex++ )
  1727. {
  1728. if ( 0 == wbem_wcsicmp ( wcsClass, wcsPseudoSystem [ dwIndex ] ) )
  1729. {
  1730. fResult = TRUE ;
  1731. break ;
  1732. }
  1733. }
  1734. }
  1735. return fResult ;
  1736. }
  1737. /////////////////////////////////////////////////////////////////////////////////////////////////
  1738. //
  1739. // IsClassAsociatedWithDifferentDriver
  1740. // ===================================
  1741. //
  1742. // returns false if there is no other driver referencing class
  1743. // we assume that there is driver when internally failing
  1744. //
  1745. /////////////////////////////////////////////////////////////////////////////////////////////////
  1746. BOOL CNamespaceManagement::IsClassAsociatedWithDifferentDriver ( LPCWSTR wcsClass, LPCWSTR wcsDriverToCompare )
  1747. {
  1748. BOOL fResult = TRUE ;
  1749. BOOL fFind = FALSE ;
  1750. HRESULT hr = S_OK ;
  1751. CBSTR strQueryLang(L"WQL");
  1752. LPCWSTR wcsQuery = L"\"" ;
  1753. LPCWSTR query1 = L"select * from WDMClassesOfDriver where ClassName = \"" ;
  1754. DWORD dwQuery1 = sizeof ( L"select * from WDMClassesOfDriver where ClassName = \"" ) / sizeof ( WCHAR ) ;
  1755. DWORD dw1 = wcslen ( wcsClass ) + dwQuery1 + 1 ;
  1756. LPWSTR wcsQuery1 = new WCHAR [ dw1 ] ;
  1757. wmilib::auto_buffer < WCHAR > smartwcsQuery1 ( wcsQuery1 ) ;
  1758. if ( SUCCEEDED ( hr = StringCchCopyW ( wcsQuery1, dw1, query1 ) ) )
  1759. {
  1760. if ( SUCCEEDED ( hr = StringCchCatW ( wcsQuery1, dw1, wcsClass ) ) )
  1761. {
  1762. hr = StringCchCatW ( wcsQuery1, dw1, wcsQuery ) ;
  1763. }
  1764. }
  1765. if ( SUCCEEDED ( hr ) )
  1766. {
  1767. _COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, __uuidof(IEnumWbemClassObject));
  1768. IEnumWbemClassObjectPtr pEnum;
  1769. hr = REPOSITORY_PTR->ExecQuery ( strQueryLang, CBSTR ( wcsQuery1 ), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, CONTEXT_PTR, &pEnum );
  1770. if ( SUCCEEDED ( hr ) )
  1771. {
  1772. DWORD uReturned = 0L ;
  1773. _COM_SMARTPTR_TYPEDEF(IWbemClassObject, __uuidof(IWbemClassObject));
  1774. IWbemClassObjectPtr pClass;
  1775. LPCWSTR query2 = L"select * from WMIBinaryMofResource where Name = \"" ;
  1776. DWORD dwQuery2 = sizeof ( L"select * from WMIBinaryMofResource where Name = \"" ) / sizeof ( WCHAR ) ;
  1777. while ( WBEM_S_NO_ERROR == hr )
  1778. {
  1779. hr = pEnum->Next ( WBEM_INFINITE, 1, &pClass, &uReturned ) ;
  1780. if ( WBEM_S_NO_ERROR == hr )
  1781. {
  1782. CVARIANT vDriver ;
  1783. hr = pClass->Get ( L"Driver", 0, &vDriver, 0, 0 );
  1784. if ( SUCCEEDED ( hr ) )
  1785. {
  1786. if ( wcsDriverToCompare )
  1787. {
  1788. if ( 0 == ( wbem_wcsicmp ( wcsDriverToCompare, vDriver.GetStr() ) ) )
  1789. {
  1790. //
  1791. // we know that this driver has a class
  1792. //
  1793. continue ;
  1794. }
  1795. }
  1796. DWORD dwDriver = 2 * ( wcslen ( vDriver.GetStr() ) + 1 ) ;
  1797. CAutoWChar wcsDriver( dwDriver );
  1798. if ( SUCCEEDED ( hr = ConvertStringToCTypeString ( wcsDriver, dwDriver, vDriver.GetStr() ) ) )
  1799. {
  1800. DWORD dw2 = wcslen ( wcsDriver ) + dwQuery2 + 1;
  1801. LPWSTR wcsQuery2 = new WCHAR [ dw2 ] ;
  1802. wmilib::auto_buffer < WCHAR > smartwcsQuery2 ( wcsQuery2 ) ;
  1803. if ( SUCCEEDED ( hr = StringCchCopyW ( wcsQuery2, dw2, query2 ) ) )
  1804. {
  1805. if ( SUCCEEDED ( hr = StringCchCatW ( wcsQuery2, dw2, wcsDriver ) ) )
  1806. {
  1807. hr = StringCchCatW ( wcsQuery2, dw2, wcsQuery ) ;
  1808. }
  1809. }
  1810. if ( SUCCEEDED ( hr ) )
  1811. {
  1812. IEnumWbemClassObjectPtr pEnum1;
  1813. hr = REPOSITORY_PTR->ExecQuery ( strQueryLang, CBSTR ( wcsQuery2 ), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, CONTEXT_PTR, &pEnum1 );
  1814. if ( SUCCEEDED ( hr ) )
  1815. {
  1816. DWORD uReturned1 = 0L ;
  1817. IWbemClassObjectPtr pClass1;
  1818. hr = pEnum1->Next ( WBEM_INFINITE, 1, &pClass1, &uReturned1 ) ;
  1819. if ( WBEM_S_NO_ERROR == hr )
  1820. {
  1821. //
  1822. // we are associated with some live driver for this class
  1823. //
  1824. fFind = TRUE ;
  1825. break ;
  1826. }
  1827. else
  1828. {
  1829. if ( WBEM_S_FALSE == hr )
  1830. {
  1831. //
  1832. // we get empty enumerator back (continue with other drivers)
  1833. //
  1834. hr = WBEM_S_NO_ERROR ;
  1835. }
  1836. else
  1837. {
  1838. if ( FAILED ( hr ) )
  1839. {
  1840. // get object failure
  1841. ERRORTRACE ( ( THISPROVIDER, "QUERY:\n" ) ) ;
  1842. TranslateAndLog ( wcsQuery2 ) ;
  1843. ERRORTRACE ( ( THISPROVIDER, "Failure to get class object out of enumerator with error 0x%08lx\n", hr));
  1844. }
  1845. }
  1846. }
  1847. }
  1848. else
  1849. {
  1850. // exec query failure
  1851. ERRORTRACE ( ( THISPROVIDER, "Failed to execute following QUERY:\n" ) ) ;
  1852. TranslateAndLog ( wcsQuery2 ) ;
  1853. ERRORTRACE ( ( THISPROVIDER, "Error 0x%08lx\n", hr));
  1854. }
  1855. }
  1856. else
  1857. {
  1858. // out of memory
  1859. ERRORTRACE ( ( THISPROVIDER, "String creation failed: ", hr ) ) ;
  1860. TranslateAndLog ( wcsQuery2 ) ;
  1861. ERRORTRACE ( ( THISPROVIDER, "Error 0x%08lx\n", hr ) ) ;
  1862. }
  1863. }
  1864. else
  1865. {
  1866. // convert failure
  1867. ERRORTRACE ( ( THISPROVIDER, "Convertion failure ... probably OUT OF MEMORY !\n" ) ) ;
  1868. }
  1869. }
  1870. else
  1871. {
  1872. // get property failed
  1873. ERRORTRACE ( ( THISPROVIDER, "QUERY:\n" ) ) ;
  1874. TranslateAndLog ( wcsQuery1 ) ;
  1875. ERRORTRACE ( ( THISPROVIDER, "Failure to get property value from class object with error 0x%08lx\n", hr));
  1876. }
  1877. }
  1878. else
  1879. {
  1880. if ( WBEM_S_FALSE == hr )
  1881. {
  1882. //
  1883. // we did get empty enumerator back
  1884. //
  1885. if ( FALSE == fFind )
  1886. {
  1887. //
  1888. // we didn't find live driver here
  1889. //
  1890. fResult = FALSE ;
  1891. }
  1892. }
  1893. else
  1894. {
  1895. // get object failure
  1896. ERRORTRACE ( ( THISPROVIDER, "QUERY:\n" ) ) ;
  1897. TranslateAndLog ( wcsQuery1 ) ;
  1898. ERRORTRACE ( ( THISPROVIDER, "Failure to get class object out of enumerator with error 0x%08lx\n", hr));
  1899. }
  1900. }
  1901. }
  1902. }
  1903. else
  1904. {
  1905. // exec query failure
  1906. ERRORTRACE ( ( THISPROVIDER, "Failed to execute following QUERY:\n" ) ) ;
  1907. TranslateAndLog ( wcsQuery1 ) ;
  1908. ERRORTRACE ( ( THISPROVIDER, "Error 0x%08lx\n", hr));
  1909. }
  1910. }
  1911. else
  1912. {
  1913. // out of memory
  1914. ERRORTRACE ( ( THISPROVIDER, "String creation failed: ", hr ) ) ;
  1915. TranslateAndLog ( wcsQuery1 ) ;
  1916. ERRORTRACE ( ( THISPROVIDER, "Error 0x%08lx\n", hr ) ) ;
  1917. }
  1918. return fResult ;
  1919. }
  1920. /////////////////////////////////////////////////////////////////////////////////////////////////
  1921. // Delete stranded classes in the repository
  1922. /////////////////////////////////////////////////////////////////////////////////////////////////
  1923. BOOL CNamespaceManagement::DeleteStrandedClasses(void)
  1924. {
  1925. BOOL fRc = TRUE;
  1926. HRESULT hr = WBEM_NO_ERROR;
  1927. IEnumWbemClassObject* pEnum = NULL;
  1928. IEnumWbemClassObject* pEnumofStrandedClasses = NULL;
  1929. // ==================================================================================
  1930. // Get list of drivers
  1931. // ==================================================================================
  1932. if ( SUCCEEDED ( hr = InitQuery(L"select * from WMIBinaryMofResource") ) )
  1933. {
  1934. CBSTR strQryLang(L"WQL");
  1935. CBSTR cbstrQry(m_pwcsQuery);
  1936. hr = REPOSITORY_PTR->ExecQuery(strQryLang,cbstrQry, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnum);
  1937. if( hr == WBEM_NO_ERROR )
  1938. {
  1939. unsigned long uReturned = 0;
  1940. CVARIANT vDriver, vLow, vHigh;
  1941. IWbemClassObject * pClass = NULL;
  1942. //================================================================================
  1943. // Initialize query for stranded classes as we go along and clean up the old
  1944. // classes
  1945. //================================================================================
  1946. if ( SUCCEEDED ( hr = InitQuery(L"select * from WDMClassesOfDriver where Driver != ") ) )
  1947. {
  1948. while ( TRUE )
  1949. {
  1950. IWbemClassObject * pClass = NULL;
  1951. if( WBEM_NO_ERROR == (hr = pEnum->Next(2000, 1, &pClass, &uReturned)))
  1952. {
  1953. if( WBEM_NO_ERROR == (hr = pClass->Get(L"Name", 0, &vDriver, 0, 0)))
  1954. {
  1955. //============================================================
  1956. // Correct the query syntax for next query
  1957. //============================================================
  1958. hr = UpdateQuery( L" and Driver != ",vDriver.GetStr());
  1959. }
  1960. }
  1961. SAFE_RELEASE_PTR(pClass );
  1962. if( hr != WBEM_NO_ERROR )
  1963. {
  1964. break;
  1965. }
  1966. }
  1967. //================================================================
  1968. // Ok, now go after the stranded classes, the ones that don't
  1969. // have any drivers for some reason
  1970. //================================================================
  1971. CBSTR strQryLang(L"WQL");
  1972. CBSTR cbstr(m_pwcsQuery);
  1973. hr = REPOSITORY_PTR->ExecQuery(strQryLang,cbstr, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnumofStrandedClasses);
  1974. if( hr == WBEM_NO_ERROR )
  1975. {
  1976. BOOL bDrivers = FALSE;
  1977. while( TRUE )
  1978. {
  1979. if( WBEM_NO_ERROR == (hr = pEnumofStrandedClasses->Next(2000, 1, &pClass, &uReturned)))
  1980. {
  1981. CVARIANT vPath,vClass;
  1982. pClass->Get(L"ClassName", 0, &vClass, 0, 0);
  1983. if(SUCCEEDED(hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0)))
  1984. {
  1985. //
  1986. // we need to recognize if class is not associated with
  1987. // different driver prior to its deletion
  1988. //
  1989. // (upgrade scenario where diff driver was exposing same classes)
  1990. //
  1991. BOOL fDeleteClass = ! IsClassAsociatedWithDifferentDriver ( vClass.GetStr() );
  1992. //
  1993. // we do not care if there was error in deletion
  1994. // as it usually means there was no such a class
  1995. // previously
  1996. //
  1997. hr = DeleteUnusedClassAndDriverInfo( fDeleteClass, vClass.GetStr(), vPath.GetStr() );
  1998. }
  1999. else
  2000. {
  2001. fRc = FALSE;
  2002. break;
  2003. }
  2004. }
  2005. SAFE_RELEASE_PTR(pClass);
  2006. if( hr != WBEM_NO_ERROR )
  2007. {
  2008. break;
  2009. }
  2010. }
  2011. SAFE_RELEASE_PTR(pEnumofStrandedClasses);
  2012. if(!fRc)
  2013. {
  2014. if( hr != E_OUTOFMEMORY)
  2015. {
  2016. ERRORTRACE((THISPROVIDER,"Stranded instance exist in repository\n"));
  2017. }
  2018. }
  2019. }
  2020. }
  2021. }
  2022. SAFE_RELEASE_PTR(pEnum);
  2023. }
  2024. return fRc;
  2025. }
  2026. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  2027. BOOL CNamespaceManagement::DeleteOldDrivers(BOOL fCompareDates)
  2028. {
  2029. HRESULT hr = WBEM_E_FAILED;
  2030. IEnumWbemClassObject* pEnum = NULL;
  2031. BOOL fRc = TRUE;
  2032. BSTR strQry = NULL;
  2033. strQry = SysAllocString(m_pwcsQuery);
  2034. if(strQry != NULL)
  2035. {
  2036. CBSTR strQryLang(L"WQL");
  2037. hr = REPOSITORY_PTR->ExecQuery(strQryLang, strQry, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnum);
  2038. SysFreeString(strQry);
  2039. strQry = NULL;
  2040. }
  2041. else
  2042. {
  2043. hr = E_OUTOFMEMORY;
  2044. fRc = FALSE;
  2045. }
  2046. if( hr == WBEM_NO_ERROR )
  2047. {
  2048. IWbemClassObject * pClass = NULL;
  2049. unsigned long uReturned = 0;
  2050. CVARIANT vClass;
  2051. hr = WBEM_NO_ERROR;
  2052. //============================================================================================
  2053. // NOTE: We only deal with drivers extracted from files here, if it is a guid as the result
  2054. // of an event this is handled elsewhere
  2055. //============================================================================================
  2056. while ( hr == WBEM_NO_ERROR )
  2057. {
  2058. IWbemClassObject * pClass = NULL;
  2059. unsigned long uReturned = 0;
  2060. hr = pEnum->Next(2000, 1, &pClass, &uReturned);
  2061. if( hr == WBEM_NO_ERROR )
  2062. {
  2063. CVARIANT vLowDate, vHighDate, vName;
  2064. if( WBEM_NO_ERROR != (hr = pClass->Get(L"Name", 0, &vName, 0, 0)))
  2065. {
  2066. break;
  2067. }
  2068. if( fCompareDates )
  2069. {
  2070. vLowDate.SetLONG(0);
  2071. vHighDate.SetLONG(0);
  2072. if( WBEM_NO_ERROR != (hr = pClass->Get(L"LowDateTime", 0, &vLowDate, 0, 0)))
  2073. {
  2074. break;
  2075. }
  2076. if( WBEM_NO_ERROR != (hr = pClass->Get(L"HighDateTime", 0, &vHighDate, 0, 0)))
  2077. {
  2078. break;
  2079. }
  2080. }
  2081. DEBUGTRACE((THISPROVIDER,"Deleting Old Drivers\n"));
  2082. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  2083. if( DeleteOldClasses((WCHAR *) vName.GetStr(),vLowDate,vHighDate,fCompareDates ))
  2084. {
  2085. CVARIANT vPath;
  2086. hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0);
  2087. if( hr == WBEM_NO_ERROR )
  2088. {
  2089. CBSTR cbstrPath(vPath.GetStr());
  2090. hr = REPOSITORY_PTR->DeleteInstance(cbstrPath,0,CONTEXT_PTR,NULL);
  2091. if ( FAILED ( hr ) )
  2092. {
  2093. ERRORTRACE((THISPROVIDER,"We have been requested to delete this instance:\n"));
  2094. TranslateAndLog(vPath.GetStr());
  2095. ERRORTRACE((THISPROVIDER,"It failed with 0x%08lx\n", hr));
  2096. }
  2097. else
  2098. {
  2099. DEBUGTRACE((THISPROVIDER,"We have been requested to delete this instance:\n"));
  2100. TranslateAndLog(vPath.GetStr(), TRUE);
  2101. }
  2102. if( WBEM_NO_ERROR == hr )
  2103. {
  2104. m_pObj->DeleteMofFromRegistry((WCHAR *) vName.GetStr());
  2105. }
  2106. }
  2107. else
  2108. {
  2109. ERRORTRACE((THISPROVIDER,"Get returned value: 0x%08lx\n",hr));
  2110. }
  2111. }
  2112. }
  2113. }
  2114. SAFE_RELEASE_PTR(pEnum);
  2115. }
  2116. else
  2117. {
  2118. ERRORTRACE((THISPROVIDER,"Cannot delete driver. ExecQuery return value: 0x%08lx\n",hr));
  2119. ERRORTRACE((THISPROVIDER,"Current query: \n"));
  2120. TranslateAndLog(m_pwcsQuery);
  2121. }
  2122. return fRc;
  2123. }
  2124. /////////////////////////////////////////////////////////////////////////////////////////////////
  2125. // Function to delete Old classes for a particular driver
  2126. /////////////////////////////////////////////////////////////////////////////////////////////////
  2127. BOOL CNamespaceManagement::DeleteOldClasses(WCHAR * wcsFileName,CVARIANT & vLow, CVARIANT & vHigh, BOOL fCompareDates)
  2128. {
  2129. HRESULT hr = WBEM_E_FAILED;
  2130. CAutoWChar wcsTranslatedKey(MAX_PATH*2);
  2131. BOOL fRc = FALSE;
  2132. IEnumWbemClassObject* pEnum = NULL;
  2133. ULONG lHighDateTime = 0L;
  2134. ULONG lLowDateTime = 0L;
  2135. DEBUGTRACE((THISPROVIDER,"Deleting Old Classes for Driver\n"));
  2136. TranslateAndLog(wcsFileName, TRUE);
  2137. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  2138. if( wcsTranslatedKey.Valid() )
  2139. {
  2140. //================================================================================
  2141. // Initialize everything we need to construct the query
  2142. //================================================================================
  2143. if( fCompareDates )
  2144. {
  2145. lLowDateTime= (ULONG)vLow.GetLONG();
  2146. lHighDateTime= (ULONG)vHigh.GetLONG();
  2147. }
  2148. if ( SUCCEEDED ( hr = ConvertStringToCTypeString( wcsTranslatedKey,MAX_PATH*2,wcsFileName ) ) )
  2149. {
  2150. //================================================================================
  2151. // Now, pick up all the old classes for this driver
  2152. //================================================================================
  2153. if ( SUCCEEDED ( hr = InitQuery(L"select * from WDMClassesOfDriver where Driver = ") ) )
  2154. {
  2155. if ( SUCCEEDED ( hr = UpdateQuery(L"",wcsFileName) ) )
  2156. {
  2157. if ( SUCCEEDED ( hr = UpdateQuery(L" and (HighDateTime != ",lHighDateTime) ) )
  2158. {
  2159. if ( SUCCEEDED ( hr = UpdateQuery(L" or LowDateTime != ", lLowDateTime) ) )
  2160. {
  2161. if ( SUCCEEDED ( hr = AddToQuery(L")") ) )
  2162. {
  2163. BSTR strTmp = NULL;
  2164. strTmp = SysAllocString(m_pwcsQuery);
  2165. if(strTmp != NULL)
  2166. {
  2167. CBSTR strQryLang(L"WQL");
  2168. hr = REPOSITORY_PTR->ExecQuery(strQryLang, strTmp, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnum);
  2169. SysFreeString(strTmp);
  2170. strTmp = NULL;
  2171. }
  2172. else
  2173. {
  2174. hr = E_OUTOFMEMORY;
  2175. fRc = FALSE;
  2176. }
  2177. if( hr == WBEM_NO_ERROR )
  2178. {
  2179. IWbemClassObject * pClass = NULL;
  2180. unsigned long uReturned = 0;
  2181. CVARIANT vClass;
  2182. while ( TRUE )
  2183. {
  2184. hr = pEnum->Next(2000, 1, &pClass, &uReturned);
  2185. if( hr!= WBEM_NO_ERROR )
  2186. {
  2187. break;
  2188. }
  2189. hr = pClass->Get(L"ClassName", 0, &vClass, 0, 0);
  2190. if( hr != WBEM_NO_ERROR )
  2191. {
  2192. SAFE_RELEASE_PTR( pClass );
  2193. break;
  2194. }
  2195. //===========================================================================
  2196. // Now, get this instance of tying the class with this old date
  2197. //===========================================================================
  2198. CVARIANT vPath;
  2199. hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0);
  2200. if( hr != WBEM_NO_ERROR )
  2201. {
  2202. SAFE_RELEASE_PTR( pClass );
  2203. break;
  2204. }
  2205. //==========================================================================
  2206. // Now, just because we get a class name here doesn't mean we delete the
  2207. // class, this class could have been updated, in that case we just delete
  2208. // the instance of the WDMClassesOfDriver.
  2209. // Now, we need to check to see if this class really needs to be deleted
  2210. // or not
  2211. //==========================================================================
  2212. BOOL bProceedDeletion = FALSE ;
  2213. BOOL fDeleteOldClass = TRUE ;
  2214. if ( FALSE == fCompareDates )
  2215. {
  2216. //
  2217. // we need to recognize if class is not associated with
  2218. // different driver prior to its deletion
  2219. //
  2220. // (upgrade scenario where diff driver was exposing same classes)
  2221. //
  2222. fDeleteOldClass = ! IsClassAsociatedWithDifferentDriver ( vClass.GetStr(), wcsFileName );
  2223. bProceedDeletion = TRUE ;
  2224. }
  2225. else
  2226. {
  2227. IWbemClassObject * pTmp = NULL;
  2228. CBSTR bTmp = vClass.GetStr();
  2229. if( bTmp )
  2230. {
  2231. CAutoWChar wcsObjectPath(MAX_PATH*4);
  2232. if( wcsObjectPath.Valid() )
  2233. {
  2234. if ( SUCCEEDED ( hr = StringCchPrintfW(wcsObjectPath,MAX_PATH*4,L"WDMClassesOfDriver.ClassName=\"%s\",Driver=\"%s\",HighDateTime=%lu,LowDateTime=%lu",bTmp,wcsTranslatedKey,lHighDateTime,lLowDateTime) ) )
  2235. {
  2236. //===========================================================================
  2237. // this is simple, if we get an instance of WDMClassesOfDriver
  2238. // with the newer date, then we know it has been updated, so we don't
  2239. // delete the class
  2240. //===========================================================================
  2241. if ( WBEM_NO_ERROR == REPOSITORY_PTR->GetObject ( CBSTR ( wcsObjectPath ), 0, CONTEXT_PTR, &pTmp, NULL ) )
  2242. {
  2243. fDeleteOldClass = FALSE;
  2244. }
  2245. //===========================================================================
  2246. // Now, delete the WDM Instance of the Old Driver
  2247. //===========================================================================
  2248. SAFE_RELEASE_PTR( pTmp );
  2249. bProceedDeletion = TRUE ;
  2250. }
  2251. }
  2252. }
  2253. }
  2254. if ( bProceedDeletion )
  2255. {
  2256. //
  2257. // we do not care if there was error in deletion
  2258. // as it usually means there was no such a class
  2259. // previously
  2260. //
  2261. hr = DeleteUnusedClassAndDriverInfo( fDeleteOldClass, vClass.GetStr(), vPath.GetStr() );
  2262. }
  2263. SAFE_RELEASE_PTR( pClass );
  2264. vClass.Clear();
  2265. }
  2266. SAFE_RELEASE_PTR(pEnum);
  2267. }
  2268. if( hr == WBEM_NO_ERROR || hr == WBEM_S_NO_MORE_DATA || hr == WBEM_S_FALSE)
  2269. {
  2270. fRc = TRUE;
  2271. }
  2272. }
  2273. }
  2274. }
  2275. }
  2276. }
  2277. }
  2278. }
  2279. return fRc;
  2280. }
  2281. /////////////////////////////////////////////////////////////////////
  2282. BOOL CNamespaceManagement::CreateInstance ( WCHAR * wcsDriver, WCHAR * wcsClass, ULONG lLowDateTime, ULONG lHighDateTime )
  2283. {
  2284. IWbemClassObject * pInst = NULL, * pClass = NULL;
  2285. //==================================================
  2286. // Get a pointer to a IWbemClassObject object
  2287. //==================================================
  2288. HRESULT hr;
  2289. CVARIANT cvarName;
  2290. cvarName.SetStr(L"WDMClassesOfDriver");
  2291. hr = REPOSITORY_PTR->GetObject(cvarName, 0,CONTEXT_PTR, &pClass, NULL);
  2292. if(FAILED(hr)){
  2293. return FALSE;
  2294. }
  2295. //=============================================================
  2296. // Spawn a new instance
  2297. //=============================================================
  2298. hr = pClass->SpawnInstance(0, &pInst);
  2299. SAFE_RELEASE_PTR(pClass);
  2300. if( FAILED(hr) ){
  2301. return hr;
  2302. }
  2303. //=============================================================
  2304. // Put the data in the instance
  2305. //=============================================================
  2306. CVARIANT vClass, vDriver, vLow, vHigh;
  2307. vClass.SetStr(wcsClass);
  2308. vDriver.SetStr(wcsDriver);
  2309. vLow.SetLONG(lLowDateTime);
  2310. vHigh.SetLONG(lHighDateTime);
  2311. hr = pInst->Put(L"Driver", 0, &vDriver, NULL);
  2312. if( hr == WBEM_S_NO_ERROR )
  2313. {
  2314. hr = pInst->Put(L"ClassName", 0, &vClass, NULL);
  2315. hr = pInst->Put(L"LowDateTime", 0, &vLow, NULL);
  2316. hr = pInst->Put(L"HighDateTime", 0, &vHigh, NULL);
  2317. if( hr == WBEM_S_NO_ERROR )
  2318. {
  2319. hr = REPOSITORY_PTR->PutInstance(pInst,WBEM_FLAG_CREATE_OR_UPDATE,CONTEXT_PTR,NULL);
  2320. }
  2321. }
  2322. SAFE_RELEASE_PTR(pInst);
  2323. if( WBEM_NO_ERROR == hr ){
  2324. return TRUE;
  2325. }
  2326. return FALSE;
  2327. }
  2328. /////////////////////////////////////////////////////////////////////
  2329. void CNamespaceManagement::CreateClassAssociationsToDriver(WCHAR * wcsFileName, BYTE* pRes, ULONG lLowDateTime, ULONG lHighDateTime)
  2330. {
  2331. CBMOFObjList * pol;
  2332. CBMOFObj * po;
  2333. //===========================================================================
  2334. // Now use the helper functions from David's mofcomp stuff to extract the
  2335. // class names we are going to add the Driver qualifier to.
  2336. // list structure and use it to enumerate the objects.
  2337. //===========================================================================
  2338. BYTE * pByte = m_pObj->DecompressBinaryMof(pRes);
  2339. if( pByte ){
  2340. pol = CreateObjList(pByte);
  2341. if(pol != NULL){
  2342. ResetObjList (pol);
  2343. while(po = NextObj(pol)){
  2344. WCHAR * pName = NULL;
  2345. if(GetName(po, &pName)){
  2346. //===============================================================
  2347. // Now, we have the name of the class in pName, we have the
  2348. // name of the driver, in wcsFileName
  2349. //===============================================================
  2350. CreateInstance(wcsFileName, pName, lLowDateTime, lHighDateTime );
  2351. BMOFFree(pName);
  2352. }
  2353. BMOFFree(po);
  2354. }
  2355. BMOFFree(pol);
  2356. }
  2357. }
  2358. else{
  2359. ERRORTRACE((THISPROVIDER,"Could not tie classes to driver for file:\n"));
  2360. TranslateAndLog(wcsFileName);
  2361. }
  2362. if( pByte ){
  2363. free(pByte);
  2364. }
  2365. }
  2366. /////////////////////////////////////////////////////////////////////
  2367. HRESULT CNamespaceManagement::AllocMemory(WCHAR *& p)
  2368. {
  2369. HRESULT hr = WBEM_E_FAILED;
  2370. p = ( WCHAR* ) new BYTE[m_nSize+4];
  2371. if( p )
  2372. {
  2373. memset(p,NULL,m_nSize+4);
  2374. hr = WBEM_NO_ERROR;
  2375. }
  2376. else
  2377. {
  2378. WBEM_E_OUT_OF_MEMORY;
  2379. }
  2380. return hr;
  2381. }
  2382. /////////////////////////////////////////////////////////////////////
  2383. HRESULT CNamespaceManagement::AddToQuery(WCHAR * p)
  2384. {
  2385. HRESULT hr = WBEM_E_FAILED;
  2386. int nNewSize = wcslen(p) * sizeof(WCHAR);
  2387. int nCurrentBuf = 0;
  2388. if( m_pwcsQuery )
  2389. {
  2390. nCurrentBuf = (int)(wcslen(m_pwcsQuery) + 1) * sizeof(WCHAR);
  2391. }
  2392. if( nNewSize >= (m_nSize - nCurrentBuf))
  2393. {
  2394. int nOldSize = m_nSize;
  2395. WCHAR * pOld = m_pwcsQuery;
  2396. m_nSize += MEMSIZETOALLOCATE;
  2397. m_pwcsQuery = NULL;
  2398. if( SUCCEEDED( hr = AllocMemory(m_pwcsQuery)))
  2399. {
  2400. memcpy(m_pwcsQuery,pOld,nOldSize);
  2401. }
  2402. SAFE_DELETE_ARRAY(pOld);
  2403. }
  2404. else
  2405. {
  2406. // no need to re-allocate
  2407. hr = WBEM_S_FALSE;
  2408. }
  2409. if ( SUCCEEDED ( hr ) )
  2410. {
  2411. if( m_pwcsQuery )
  2412. {
  2413. if( wcslen(m_pwcsQuery) == 0 )
  2414. {
  2415. hr = StringCbCopyW(m_pwcsQuery,m_nSize,p);
  2416. }
  2417. else
  2418. {
  2419. hr = StringCbCatW(m_pwcsQuery,m_nSize,p);
  2420. }
  2421. }
  2422. else
  2423. {
  2424. // this is so bad
  2425. hr = WBEM_E_FAILED;
  2426. }
  2427. }
  2428. return hr;
  2429. }
  2430. /////////////////////////////////////////////////////////////////////
  2431. HRESULT CNamespaceManagement::InitQuery(WCHAR * p)
  2432. {
  2433. HRESULT hr = WBEM_S_NO_ERROR;
  2434. SAFE_DELETE_ARRAY(m_pwcsQuery);
  2435. m_nSize = MEMSIZETOALLOCATE;
  2436. m_fInit = TRUE;
  2437. if(SUCCEEDED(hr = AllocMemory(m_pwcsQuery)))
  2438. {
  2439. hr = AddToQuery(p);
  2440. }
  2441. return hr;
  2442. }
  2443. /////////////////////////////////////////////////////////////////////
  2444. HRESULT CNamespaceManagement::UpdateQuery( WCHAR * pQueryAddOn, WCHAR * wcsParam )
  2445. {
  2446. HRESULT hr = WBEM_E_OUT_OF_MEMORY;
  2447. CAutoWChar wcsTranslatedKey(MAX_PATH*3);
  2448. if( wcsTranslatedKey.Valid() )
  2449. {
  2450. if ( SUCCEEDED ( hr = ConvertStringToCTypeString( wcsTranslatedKey,MAX_PATH*3,wcsParam ) ) )
  2451. {
  2452. //=============================================
  2453. // The first time only we DON'T add the query
  2454. // add on string, otherwise, we do
  2455. //=============================================
  2456. if( !m_fInit )
  2457. {
  2458. hr = AddToQuery(pQueryAddOn);
  2459. }
  2460. if ( SUCCEEDED ( hr ) )
  2461. {
  2462. if ( SUCCEEDED ( hr = AddToQuery(L"\"") ) )
  2463. {
  2464. if ( SUCCEEDED ( hr = AddToQuery(wcsTranslatedKey) ) )
  2465. {
  2466. if ( SUCCEEDED ( hr = AddToQuery(L"\"") ) )
  2467. {
  2468. m_fInit = FALSE;
  2469. }
  2470. }
  2471. }
  2472. }
  2473. }
  2474. }
  2475. return hr;
  2476. }
  2477. /////////////////////////////////////////////////////////////////////
  2478. void CNamespaceManagement::SaveCurrentQuery()
  2479. {
  2480. m_nSavedSize = m_nSize;
  2481. m_fSavedInit = m_fInit;
  2482. if( SUCCEEDED(AllocMemory(m_pwcsSavedQuery))){
  2483. memcpy(m_pwcsSavedQuery,m_pwcsQuery,m_nSize);
  2484. }
  2485. SAFE_DELETE_ARRAY(m_pwcsQuery);
  2486. }
  2487. /////////////////////////////////////////////////////////////////////
  2488. void CNamespaceManagement::RestoreQuery()
  2489. {
  2490. SAFE_DELETE_ARRAY(m_pwcsQuery);
  2491. m_nSize = m_nSavedSize;
  2492. m_fInit = m_fSavedInit;
  2493. if( SUCCEEDED(AllocMemory(m_pwcsQuery))){
  2494. memcpy(m_pwcsQuery, m_pwcsSavedQuery,m_nSize);
  2495. }
  2496. m_fSavedInit = 0;
  2497. m_nSavedSize = 0;
  2498. SAFE_DELETE_ARRAY(m_pwcsSavedQuery);
  2499. }
  2500. /////////////////////////////////////////////////////////////////////
  2501. HRESULT CNamespaceManagement::UpdateQuery( WCHAR * pQueryAddOn, ULONG lLong )
  2502. {
  2503. HRESULT hr = WBEM_E_OUT_OF_MEMORY;
  2504. CAutoWChar wcsBuf(MAX_PATH);
  2505. if( wcsBuf.Valid() )
  2506. {
  2507. if ( SUCCEEDED ( hr = AddToQuery(pQueryAddOn) ) )
  2508. {
  2509. if ( SUCCEEDED ( hr = StringCchPrintfW(wcsBuf,MAX_PATH,L"%lu",lLong) ) )
  2510. {
  2511. if ( SUCCEEDED ( hr = AddToQuery(wcsBuf) ) )
  2512. {
  2513. m_fInit = FALSE;
  2514. }
  2515. }
  2516. }
  2517. }
  2518. return hr;
  2519. }
  2520. /////////////////////////////////////////////////////////////////////
  2521. HRESULT CNamespaceManagement::DeleteUnusedClassAndDriverInfo( BOOL fDeleteOldClass, WCHAR * wcsClass, WCHAR * wcsPath )
  2522. {
  2523. HRESULT hr = WBEM_NO_ERROR;
  2524. if( fDeleteOldClass )
  2525. {
  2526. if ( FALSE == IsClassPseudoSystem ( wcsClass ) )
  2527. {
  2528. hr = SERVICES_PTR->DeleteClass(CBSTR(wcsClass),WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
  2529. if( hr != WBEM_NO_ERROR )
  2530. {
  2531. if( WBEM_E_NOT_FOUND != hr )
  2532. {
  2533. ERRORTRACE((THISPROVIDER,"Tried to delete class but couldn't, return code: 0x%08lx for class: \n",hr));
  2534. TranslateAndLog(wcsClass);
  2535. }
  2536. else
  2537. {
  2538. hr = WBEM_NO_ERROR;
  2539. }
  2540. }
  2541. }
  2542. else
  2543. {
  2544. DEBUGTRACE ( ( THISPROVIDER,"Tried to delete class but skipped: \n" ) );
  2545. DEBUGTRACE ( ( THISPROVIDER,"%S is PSEUDO system class \n", wcsClass ) ); ;
  2546. }
  2547. }
  2548. if( WBEM_NO_ERROR == hr )
  2549. {
  2550. // Ok, we may or may have not deleted the class, if it was tied to a different driver, we
  2551. // shouldn't have deleted the class, but we want to delete the controlling instance, as
  2552. // that driver is no longer there.
  2553. hr = SERVICES_PTR->DeleteInstance(CBSTR(wcsPath),WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
  2554. if( WBEM_NO_ERROR != hr )
  2555. {
  2556. if( hr != WBEM_E_NOT_FOUND )
  2557. {
  2558. ERRORTRACE((THISPROVIDER,"Tried to delete instance but couldn't, return code: 0x%08lx for instance: \n ",hr));
  2559. TranslateAndLog(wcsPath);
  2560. }
  2561. }
  2562. }
  2563. return hr;
  2564. }