Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2258 lines
68 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. //
  3. // BINMOF.CPP
  4. //
  5. // Module:
  6. // Purpose:
  7. //
  8. // Copyright (c) 1997-2001 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. //#define DBG_PRINTFA( a ) { char pBuff[128]; sprintf a ; OutputDebugStringA(pBuff); }
  23. #define WDM_REG_KEY L"Software\\Microsoft\\WBEM\\WDM"
  24. #define WDM_DREDGE_KEY L"Software\\Microsoft\\WBEM\\WDM\\DREDGE"
  25. #define DREDGE_KEY L"DREDGE"
  26. ///////////////////////////////////////////////////////////////////////////////////////////
  27. //***************************************************************************
  28. //
  29. // void * BMOFAlloc
  30. //
  31. // DESCRIPTION:
  32. //
  33. // Provides allocation service for BMOF.C. This allows users to choose
  34. // the allocation method that is used.
  35. //
  36. // PARAMETERS:
  37. //
  38. // Size Input. Size of allocation in bytes.
  39. //
  40. // RETURN VALUE:
  41. //
  42. // pointer to new data. NULL if allocation failed.
  43. //
  44. //***************************************************************************
  45. void * BMOFAlloc(size_t Size)
  46. {
  47. return malloc(Size);
  48. }
  49. //***************************************************************************
  50. //
  51. // void BMOFFree
  52. //
  53. // DESCRIPTION:
  54. //
  55. // Provides allocation service for BMOF.C. This frees what ever was
  56. // allocated via BMOFAlloc.
  57. //
  58. // PARAMETERS:
  59. //
  60. // pointer to memory to be freed.
  61. //
  62. //***************************************************************************
  63. void BMOFFree(void * pFree)
  64. {
  65. free(pFree);
  66. }
  67. ///////////////////////////////////////////////////////////////////////////////////////////////////
  68. void ConvertStringToCTypeString( WCHAR * Out, WCHAR * In )
  69. {
  70. WCHAR * token = NULL;
  71. if(In)
  72. {
  73. CAutoWChar tmpBuf(_MAX_PATH*2);
  74. if( tmpBuf.Valid() )
  75. {
  76. wcscpy((WCHAR*)tmpBuf,In);
  77. token = wcstok( (WCHAR*)tmpBuf, L"\\" );
  78. if( !token )
  79. {
  80. wcscpy(Out,In);
  81. }
  82. else
  83. {
  84. BOOL fFirst = TRUE;
  85. while( token != NULL )
  86. {
  87. if( fFirst )
  88. {
  89. wcscpy(Out,token);
  90. fFirst = FALSE;
  91. }
  92. else
  93. {
  94. wcscat(Out,L"\\\\");
  95. wcscat(Out,token);
  96. }
  97. token = wcstok( NULL, L"\\" );
  98. }
  99. }
  100. }
  101. }
  102. }
  103. ///////////////////////////////////////////////////////////////////////////////////////////
  104. //*****************************************************************************************
  105. // The binary mof class
  106. //*****************************************************************************************
  107. ///////////////////////////////////////////////////////////////////////////////////////////
  108. CWMIBinMof::CWMIBinMof()
  109. {
  110. m_pCompiler = NULL;
  111. m_pWMI = NULL;
  112. m_nInit = NOT_INITIALIZED;
  113. m_pMofResourceInfo = NULL;
  114. }
  115. /////////////////////////////////////////////////////////////////////
  116. HRESULT CWMIBinMof::InitializePtrs(CHandleMap * pList, IWbemServices __RPC_FAR * pServices,
  117. IWbemObjectSink __RPC_FAR * pHandler, IWbemContext __RPC_FAR *pCtx)
  118. {
  119. HRESULT hr = WBEM_E_FAILED;
  120. SAFE_DELETE_PTR(m_pWMI);
  121. m_pWMI = new CWMIManagement;
  122. if( m_pWMI )
  123. {
  124. m_pWMI->SetWMIPointers(pList, pServices, pHandler, pCtx);
  125. m_nInit = FULLY_INITIALIZED;
  126. hr = S_OK;
  127. }
  128. return hr;
  129. }
  130. /////////////////////////////////////////////////////////////////////
  131. HRESULT CWMIBinMof::Initialize(CWMIManagement * p,BOOL fUpdateNamespace)
  132. {
  133. HRESULT hr = WBEM_E_FAILED;
  134. if( p )
  135. {
  136. hr = InitializePtrs(p->HandleMap(),p->Services(),p->Handler(),p->Context());
  137. }
  138. else
  139. {
  140. m_nInit = PARTIALLY_INITIALIZED;
  141. hr = S_OK;
  142. }
  143. m_fUpdateNamespace = fUpdateNamespace;
  144. return hr;
  145. }
  146. /////////////////////////////////////////////////////////////////////
  147. HRESULT CWMIBinMof::Initialize(CHandleMap * pList, BOOL fUpdateNamespace,ULONG uDesiredAccess,
  148. IWbemServices __RPC_FAR * pServices, IWbemObjectSink __RPC_FAR * pHandler,
  149. IWbemContext __RPC_FAR *pCtx)
  150. {
  151. HRESULT hr = WBEM_E_FAILED;
  152. hr = InitializePtrs(pList,pServices,pHandler,pCtx);
  153. m_fUpdateNamespace = fUpdateNamespace;
  154. return hr;
  155. }
  156. /////////////////////////////////////////////////////////////////////
  157. CWMIBinMof::~CWMIBinMof()
  158. {
  159. SAFE_RELEASE_PTR(m_pCompiler);
  160. SAFE_DELETE_PTR(m_pWMI);
  161. }
  162. /////////////////////////////////////////////////////////////////////
  163. HRESULT CWMIBinMof::OpenFileAndLookForItIfItDoesNotExist(TCHAR *& pFile, HANDLE & hFile )
  164. {
  165. HRESULT hr = S_OK;
  166. //=========================================================================
  167. // Ok, hopefully CreateFile will find it
  168. //=========================================================================
  169. hFile = CreateFile(pFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  170. if( hFile == INVALID_HANDLE_VALUE )
  171. {
  172. hr = WBEM_E_FAILED;
  173. //=====================================================================
  174. // CreateFile DIDN'T find it, so look in the Windows dir
  175. //=====================================================================
  176. TCHAR pszSysDir[MAX_PATH+4];
  177. UINT uSize = GetSystemDirectory(pszSysDir, MAX_PATH);
  178. if( uSize > 0)
  179. {
  180. TCHAR * pTmp = pFile;
  181. pFile = new TCHAR[MAX_PATH*2 + 4];
  182. if( pFile )
  183. {
  184. _stprintf(pFile,L"%s\\%s",pszSysDir,pTmp);
  185. //=============================================================
  186. // Ok, now try to open again
  187. //=============================================================
  188. hFile = CreateFile(pFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  189. if( hFile != INVALID_HANDLE_VALUE )
  190. {
  191. hr = S_OK;
  192. }
  193. }
  194. SAFE_DELETE_ARRAY(pTmp);
  195. }
  196. }
  197. return hr;
  198. }
  199. /////////////////////////////////////////////////////////////////////
  200. BOOL CWMIBinMof::GetFileDateAndTime(ULONG & lLowDateTime,ULONG & lHighDateTime,WCHAR * wcsFileName)
  201. {
  202. HANDLE hFile = NULL;
  203. FILETIME ftCreationTime, ftLastAccessTime, ftLastWriteTime,ftLocal;
  204. BOOL fRc = FALSE;
  205. TCHAR * pFile = NULL;
  206. if( ExtractFileNameFromKey(pFile,wcsFileName) )
  207. {
  208. if( SUCCEEDED(OpenFileAndLookForItIfItDoesNotExist( pFile, hFile )))
  209. {
  210. if( GetFileTime( hFile, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime ))
  211. {
  212. //==========================================================
  213. // Pick up the path of the file while we are here....
  214. //==========================================================
  215. TCHAR sFullPath[MAX_PATH * 4];
  216. TCHAR *sFilename = NULL;
  217. if (GetFullPathName(pFile, MAX_PATH * 4, sFullPath, &sFilename) != 0)
  218. {
  219. #ifndef UNICODE
  220. CAnsiUnicode XLate;
  221. WCHAR * pTmp = NULL;
  222. if( SUCCEEDED(XLate.AllocateAndConvertAnsiToUnicode(sFullPath,pTmp)))
  223. {
  224. wcscpy(wcsFileName,pTmp);
  225. SAFE_DELETE_ARRAY( pTmp );
  226. }
  227. #else
  228. wcscpy(wcsFileName,sFullPath);
  229. #endif
  230. }
  231. else
  232. {
  233. DWORD dwTest = GetLastError();
  234. ERRORTRACE((THISPROVIDER,"GetFullPathName FAILED for filename: \n"));
  235. TranslateAndLog(wcsFileName);
  236. ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
  237. }
  238. FileTimeToLocalFileTime( &ftLastWriteTime, &ftLocal);
  239. lLowDateTime = (ULONG)ftLocal.dwLowDateTime;
  240. lHighDateTime = (ULONG)ftLocal.dwHighDateTime;
  241. fRc = TRUE;
  242. }
  243. else
  244. {
  245. DWORD dwTest = GetLastError();
  246. ERRORTRACE((THISPROVIDER,"GetFileTime FAILED for filename:\n"));
  247. TranslateAndLog(wcsFileName);
  248. ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
  249. }
  250. CloseHandle(hFile);
  251. }
  252. else
  253. {
  254. DWORD dwTest = GetLastError();
  255. ERRORTRACE((THISPROVIDER,"CreateFile FAILED for filename:\n"));
  256. TranslateAndLog(wcsFileName);
  257. ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
  258. }
  259. }
  260. else
  261. {
  262. DWORD dwTest = GetLastError();
  263. ERRORTRACE((THISPROVIDER,"Can't extract filename: \n"));
  264. TranslateAndLog(wcsFileName);
  265. ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
  266. }
  267. SAFE_DELETE_ARRAY( pFile )
  268. return fRc;
  269. }
  270. /////////////////////////////////////////////////////////////////////
  271. BOOL CWMIBinMof::NeedToProcessThisMof( WCHAR * wcsFileName,ULONG & lLowDateTime, ULONG & lHighDateTime )
  272. {
  273. BOOL fNeedToProcessThisMof = TRUE;
  274. HRESULT hr = WBEM_E_OUT_OF_MEMORY;
  275. IWbemClassObject * pClass=NULL;
  276. CAutoWChar wcsBuf(_MAX_PATH*4);
  277. CAutoWChar wcsTmp(_MAX_PATH*4);
  278. if( wcsTmp.Valid() && wcsBuf.Valid() )
  279. {
  280. //==================================================
  281. // Change all \ to \\
  282. //==================================================
  283. ConvertStringToCTypeString( wcsTmp,wcsFileName );
  284. swprintf(wcsBuf,L"WmiBinaryMofResource.HighDateTime=%lu,LowDateTime=%lu,Name=\"%s\"",lHighDateTime,lLowDateTime,wcsTmp);
  285. //==================================================
  286. // Get a pointer to a IWbemClassObject object
  287. // Have we ever processed this mof before?
  288. // if not, then return TRUE
  289. //==================================================
  290. if( m_fUpdateNamespace )
  291. {
  292. CBSTR cbstr(wcsBuf);
  293. hr = SERVICES->GetObject(cbstr, 0,CONTEXT, &pClass, NULL);
  294. if(WBEM_NO_ERROR == hr)
  295. {
  296. fNeedToProcessThisMof = FALSE;
  297. CVARIANT vSuccess;
  298. hr = pClass->Get(L"MofProcessed", 0, &vSuccess, 0, 0);
  299. if( hr == WBEM_NO_ERROR )
  300. {
  301. //=========================================================================
  302. // make sure it is added to the registry
  303. //=========================================================================
  304. AddThisMofToRegistryIfNeeded(WDM_REG_KEY,wcsFileName,lLowDateTime,lHighDateTime,vSuccess.GetBool());
  305. }
  306. SAFE_RELEASE_PTR( pClass);
  307. }
  308. //==============================================================================
  309. // Delete any old instances that might be hanging around for this driver
  310. //==============================================================================
  311. IEnumWbemClassObject* pEnum = NULL;
  312. CAutoWChar wcsQuery(MEMSIZETOALLOCATE);
  313. if( wcsQuery.Valid() )
  314. {
  315. ULONG uReturned = 0;
  316. swprintf(wcsQuery,L"select * from WMIBinaryMofResource where Name = \"%s\"",wcsTmp);
  317. CBSTR bstrTemp = wcsQuery;
  318. CBSTR strQryLang(L"WQL");
  319. hr = SERVICES->ExecQuery(strQryLang, bstrTemp, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT,&pEnum);
  320. if( hr == WBEM_NO_ERROR )
  321. {
  322. IWbemClassObject * pClass = NULL;
  323. while( TRUE )
  324. {
  325. if( WBEM_NO_ERROR == (hr = pEnum->Next(2000, 1, &pClass, &uReturned)))
  326. {
  327. CVARIANT vPath, vDriver;
  328. hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0);
  329. if( hr == WBEM_NO_ERROR )
  330. {
  331. if( _wcsicmp(vPath.GetStr(),wcsBuf) != 0 )
  332. {
  333. hr = SERVICES->DeleteInstance(vPath.GetStr(),WBEM_FLAG_OWNER_UPDATE,CONTEXT,NULL);
  334. ERRORTRACE((THISPROVIDER,"We have been requested to delete this mof, :%ld\n",hr));
  335. TranslateAndLog(vPath.GetStr());
  336. if( hr == WBEM_NO_ERROR )
  337. {
  338. //=====================================================
  339. // Duplicate change in registry
  340. //=====================================================
  341. DeleteMofFromRegistry( vPath.GetStr() );
  342. //==========================================================================
  343. // Gets rid of the old classes for the old versions of this driver
  344. //==========================================================================
  345. hr = pClass->Get(L"Driver", 0, &vDriver, 0, 0);
  346. if( hr == WBEM_NO_ERROR )
  347. {
  348. CNamespaceManagement Namespace(this);
  349. Namespace.DeleteOldClasses(vDriver.GetStr(),CVARIANT((long)lLowDateTime),CVARIANT((long)lHighDateTime), TRUE);
  350. }
  351. }
  352. }
  353. }
  354. }
  355. SAFE_RELEASE_PTR( pClass );
  356. if( hr != WBEM_NO_ERROR )
  357. {
  358. break;
  359. }
  360. }
  361. SAFE_RELEASE_PTR(pEnum);
  362. }
  363. }
  364. }
  365. else
  366. {
  367. if( ThisMofExistsInRegistry(WDM_DREDGE_KEY,wcsFileName, lLowDateTime, lHighDateTime, TRUE) )
  368. {
  369. fNeedToProcessThisMof = FALSE;
  370. }
  371. }
  372. }
  373. return fNeedToProcessThisMof;
  374. }
  375. /////////////////////////////////////////////////////////////////////
  376. BOOL CWMIBinMof::UpdateMofTimestampInHMOM(WCHAR * wcsKey,ULONG & lLowDateTime, ULONG & lHighDateTime, BOOL fSuccess )
  377. {
  378. BOOL fRc = FALSE;
  379. IWbemClassObject * pNewInst = NULL;
  380. IWbemClassObject * pIWbemClassObject = NULL;
  381. //==================================================
  382. // Get a pointer to a IWbemClassObject object
  383. //==================================================
  384. HRESULT hr = WBEM_NO_ERROR;
  385. if( m_fUpdateNamespace )
  386. {
  387. CVARIANT cvarName;
  388. cvarName.SetStr(L"WMIBinaryMofResource");
  389. hr = SERVICES->GetObject(cvarName, 0,CONTEXT, &pIWbemClassObject, NULL);
  390. if(WBEM_NO_ERROR == hr)
  391. {
  392. //=============================================================
  393. // Spawn a new instance
  394. //=============================================================
  395. hr = pIWbemClassObject->SpawnInstance(0, &pNewInst);
  396. SAFE_RELEASE_PTR(pIWbemClassObject);
  397. if( WBEM_NO_ERROR == hr )
  398. {
  399. CVARIANT vLow, vHigh, vName, vSuccess;
  400. vSuccess.SetBool(fSuccess);
  401. vName.SetStr(wcsKey);
  402. vLow.SetLONG(lLowDateTime);
  403. vHigh.SetLONG(lHighDateTime);
  404. hr = pNewInst->Put(L"Name", 0, &vName, NULL);
  405. if( S_OK == hr )
  406. {
  407. hr = pNewInst->Put(L"LowDateTime", 0, &vLow, NULL);
  408. if( S_OK == hr )
  409. {
  410. hr = pNewInst->Put(L"HighDateTime", 0, &vHigh, NULL);
  411. if( S_OK == hr )
  412. {
  413. hr = pNewInst->Put(L"MofProcessed", 0, &vSuccess, NULL);
  414. if( S_OK == hr )
  415. {
  416. CVARIANT vActive;
  417. vActive.SetBool(TRUE);
  418. pNewInst->Put(L"Active", 0, &vActive, NULL);
  419. }
  420. hr = SERVICES->PutInstance(pNewInst,WBEM_FLAG_OWNER_UPDATE,CONTEXT,NULL);
  421. SAFE_RELEASE_PTR(pNewInst);
  422. }
  423. }
  424. }
  425. }
  426. }
  427. }
  428. if( hr == WBEM_NO_ERROR )
  429. {
  430. //==========================================
  431. // Make sure this really is in the registry
  432. // too
  433. //==========================================
  434. if( WBEM_NO_ERROR == AddThisMofToRegistryIfNeeded(WDM_REG_KEY,wcsKey,lLowDateTime,lHighDateTime,fSuccess))
  435. {
  436. fRc = TRUE;
  437. }
  438. }
  439. return fRc;
  440. }
  441. ///////////////////////////////////////////////////////////////////
  442. BOOL CWMIBinMof::GetNextSectionFromTheEnd(WCHAR * pwcsTempPath, WCHAR * pwcsEnd )
  443. {
  444. BOOL fReturn = FALSE;
  445. WCHAR * pc = wcsrchr(pwcsTempPath,'\\');
  446. if(pc)
  447. {
  448. //==================================================
  449. // Copy what was there and set the end to NULL
  450. //==================================================
  451. pc++;
  452. wcscpy( pwcsEnd, pc );
  453. pc--;
  454. *(pc) = NULL;
  455. fReturn = TRUE;
  456. }
  457. return fReturn;
  458. }
  459. ///////////////////////////////////////////////////////////////////
  460. BOOL CWMIBinMof::UseDefaultLocaleId(WCHAR * wcsFile, WORD & wLocalId)
  461. {
  462. BOOL fLoadDefaultLocale = TRUE;
  463. //=============================================================
  464. // Parse paths - get the locale id from paths of this format:
  465. //
  466. // check for path beginning with %windir% and with MUI in second to last position
  467. // if not found, check for fixed directory: %windir%\MUI\Fallback
  468. // if not found - assume it is not MUI related and try it with FindResource
  469. //
  470. //=============================================================
  471. TCHAR szWindowsDir[_MAX_PATH];
  472. if ( GetWindowsDirectory ( szWindowsDir , sizeof ( szWindowsDir ) / sizeof(TCHAR)) )
  473. {
  474. //==========================================================
  475. // if these are windows directories
  476. //==========================================================
  477. if( 0 == _wcsnicmp( szWindowsDir, wcsFile, wcslen(szWindowsDir)))
  478. {
  479. CAutoWChar wcsTempPath(_MAX_PATH);
  480. CAutoWChar wcsBuffer(_MAX_PATH);
  481. if( wcsTempPath.Valid() && wcsBuffer.Valid() )
  482. {
  483. //======================================================
  484. // Find last \ in the string, and trim off filename
  485. //======================================================
  486. wcscpy(wcsTempPath,wcsFile);
  487. if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer ))
  488. {
  489. //==================================================
  490. // Now, get the potential locale id
  491. //==================================================
  492. if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer ))
  493. {
  494. wLocalId = (WORD) _wtoi(wcsBuffer);
  495. //==============================================
  496. // Now, get the next bit to see if it says MUI
  497. // or Fallback
  498. //==============================================
  499. if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer ))
  500. {
  501. if( 0 == _wcsicmp( L"MUI", wcsBuffer ))
  502. {
  503. fLoadDefaultLocale = FALSE;
  504. }
  505. else if( 0 == _wcsicmp( L"Fallback", wcsBuffer ) )
  506. {
  507. //==============================================
  508. // If it says Fallback, then check to make
  509. // sure the next bit says MUI
  510. //==============================================
  511. if( GetNextSectionFromTheEnd( wcsTempPath, wcsBuffer ))
  512. {
  513. if( 0 == _wcsicmp( L"MUI", wcsBuffer ) )
  514. {
  515. fLoadDefaultLocale = FALSE;
  516. }
  517. }
  518. }
  519. }
  520. }
  521. }
  522. }
  523. }
  524. }
  525. return fLoadDefaultLocale;
  526. }
  527. ///////////////////////////////////////////////////////////////////
  528. BOOL CWMIBinMof::GetPointerToBinaryResource(BYTE *& pRes,
  529. DWORD & dwSize,
  530. HGLOBAL & hResource,
  531. HINSTANCE & hInst,
  532. WCHAR * wcsResource,
  533. WCHAR * wcsFile)
  534. {
  535. TCHAR * pResource = NULL;
  536. BOOL fRc = FALSE;
  537. CAnsiUnicode xLate;
  538. DWORD dwError = 0;
  539. TCHAR * pFile = NULL;
  540. if( ExtractFileNameFromKey(pFile,wcsFile) ){
  541. #ifndef UNICODE
  542. xLate.UnicodeToAnsi(wcsResource,pResource);
  543. #else
  544. pResource = wcsResource;
  545. #endif
  546. if( pResource )
  547. {
  548. hInst = LoadLibraryEx(pFile,NULL,LOAD_LIBRARY_AS_DATAFILE);
  549. if( hInst != NULL )
  550. {
  551. HRSRC hSrc = NULL;
  552. WORD wLocaleId = 0;
  553. if( UseDefaultLocaleId(wcsResource, wLocaleId ))
  554. {
  555. hSrc = FindResource(hInst,pResource, _T("MOFDATA"));
  556. }
  557. else
  558. {
  559. hSrc = FindResourceEx(hInst,pResource, _T("MOFDATA"),wLocaleId);
  560. }
  561. if( hSrc == NULL )
  562. {
  563. FreeLibrary(hInst);
  564. dwError = GetLastError();
  565. }
  566. if( NULL != hSrc)
  567. {
  568. hResource = LoadResource( hInst,hSrc);
  569. if( hResource )
  570. {
  571. pRes = (BYTE *)LockResource(hResource);
  572. dwSize = SizeofResource(hInst,hSrc);
  573. fRc = TRUE;
  574. }
  575. }
  576. }
  577. }
  578. #ifndef UNICODE
  579. SAFE_DELETE_ARRAY(pResource );
  580. #endif
  581. SAFE_DELETE_ARRAY(pFile );
  582. }
  583. return fRc;
  584. }
  585. /////////////////////////////////////////////////////////////////////
  586. BYTE * CWMIBinMof::DecompressBinaryMof(BYTE * pRes)
  587. {
  588. DWORD dwCompType, dwCompressedSize, dwExpandedSize, dwSig, dwResSize;
  589. BYTE * pExpanded = NULL;
  590. //=========================================================
  591. // get the signature, compression type, and the sizes
  592. //=========================================================
  593. memcpy(&dwSig,pRes,sizeof(DWORD));
  594. pRes += sizeof( DWORD );
  595. memcpy(&dwCompType,pRes,sizeof(DWORD));
  596. pRes += sizeof( DWORD );
  597. memcpy(&dwCompressedSize,pRes,sizeof(DWORD));
  598. pRes += sizeof( DWORD );
  599. memcpy(&dwExpandedSize,pRes,sizeof(DWORD));
  600. pRes += sizeof( DWORD );
  601. //=========================================================
  602. // make sure the signature is valid and that the compression type is one
  603. // we understand!
  604. //=========================================================
  605. if(dwSig != BMOF_SIG ||dwCompType != 1){
  606. return NULL;
  607. }
  608. //=========================================================
  609. // Allocate storage for the compressed data and
  610. // expanded data
  611. //=========================================================
  612. try
  613. {
  614. pExpanded = (BYTE*)malloc(dwExpandedSize);
  615. if( pExpanded == NULL)
  616. {
  617. goto ExitDecompression;
  618. }
  619. }
  620. catch(...)
  621. {
  622. throw;
  623. }
  624. //=========================================================
  625. // Decompress the data
  626. //=========================================================
  627. CBaseMrciCompression * pMrci = new CBaseMrciCompression;
  628. if( pMrci )
  629. {
  630. dwResSize = pMrci->Mrci1Decompress(pRes, dwCompressedSize, pExpanded, dwExpandedSize);
  631. if(dwResSize != dwExpandedSize)
  632. {
  633. SAFE_DELETE_PTR(pMrci);
  634. goto ExitDecompression;
  635. }
  636. SAFE_DELETE_PTR(pMrci);
  637. }
  638. //=========================================================
  639. // Now, get out of here
  640. //=========================================================
  641. return pExpanded;
  642. ExitDecompression:
  643. if( pExpanded )
  644. free(pExpanded);
  645. return NULL;
  646. }
  647. /////////////////////////////////////////////////////////////////////
  648. BOOL CWMIBinMof::ExtractFileNameFromKey(TCHAR *& pKey,WCHAR * wcsKey)
  649. {
  650. WCHAR *wcsToken = NULL;
  651. CAutoWChar wcsTmp(MAX_PATH * 4);
  652. BOOL fRc = FALSE;
  653. if( wcsTmp.Valid() )
  654. {
  655. if(wcsKey)
  656. {
  657. //======================================================
  658. // Get a ptr to the first [ , if there isn't one, then
  659. // just copy the whole thing.
  660. //======================================================
  661. wcscpy(wcsTmp,wcsKey);
  662. wcsToken = wcstok(wcsTmp, L"[" );
  663. if( wcsToken != NULL )
  664. {
  665. wcscpy(wcsTmp,wcsToken);
  666. }
  667. #ifndef UNICODE
  668. CAnsiUnicode XLate;
  669. if( SUCCEEDED(XLate.UnicodeToAnsi(wcsTmp,pKey)))
  670. {
  671. fRc = TRUE;
  672. }
  673. #else
  674. pKey = new TCHAR[_tcslen(wcsTmp) + 1];
  675. if(pKey)
  676. {
  677. _tcscpy(pKey,wcsTmp);
  678. fRc = TRUE;
  679. }
  680. #endif
  681. }
  682. }
  683. return fRc;
  684. }
  685. /////////////////////////////////////////////////////////////////////
  686. void CWMIBinMof::CreateKey(WCHAR * wcsFileName, WCHAR * wcsResource,WCHAR * wcsKey)
  687. {
  688. swprintf(wcsKey,L"%s[%s]",wcsFileName, wcsResource );
  689. }
  690. /////////////////////////////////////////////////////////////////////
  691. HRESULT CWMIBinMof::SendToMofComp(DWORD dwSize,BYTE * pRes,WCHAR * wcsKey)
  692. {
  693. HRESULT hr = WBEM_NO_ERROR;
  694. if(m_pCompiler == NULL)
  695. {
  696. hr = CoCreateInstance(CLSID_WinmgmtMofCompiler, 0, CLSCTX_INPROC_SERVER,IID_IWinmgmtMofCompiler, (LPVOID *) &m_pCompiler);
  697. }
  698. if(hr == WBEM_NO_ERROR)
  699. {
  700. WBEM_COMPILE_STATUS_INFO Info;
  701. memset(&Info,0,sizeof(WBEM_COMPILE_STATUS_INFO));
  702. hr = m_pCompiler->WinmgmtCompileBuffer(dwSize, pRes, 0, 65536, 0,SERVICES,CONTEXT , &Info);
  703. if( hr != WBEM_NO_ERROR )
  704. {
  705. ERRORTRACE((THISPROVIDER,"***************\n"));
  706. ERRORTRACE((THISPROVIDER,"Mofcomp of binary mof failed for:\n"));
  707. TranslateAndLog(wcsKey);
  708. ERRORTRACE((THISPROVIDER,"WinmgmtCompileBuffer return value: %ld\n",hr));
  709. ERRORTRACE((THISPROVIDER,"Size of Mof: %ld\n",dwSize));
  710. ERRORTRACE((THISPROVIDER,"***************\n"));
  711. }
  712. else
  713. {
  714. ERRORTRACE((THISPROVIDER,"***************\n"));
  715. ERRORTRACE((THISPROVIDER,"Binary mof succeeded for:\n"));
  716. TranslateAndLog(wcsKey);
  717. ERRORTRACE((THISPROVIDER,"***************\n"));
  718. }
  719. }
  720. return hr;
  721. }
  722. /////////////////////////////////////////////////////////////////////
  723. BOOL CWMIBinMof::ExtractBinaryMofFromFile(WCHAR * wcsFile, WCHAR * wcsResource,WCHAR * wcsKey, BOOL & fMofHasChanged)
  724. {
  725. HRESULT hr;
  726. BOOL fSuccess = TRUE;
  727. CAutoWChar wcsTmp(MAX_PATH*4);
  728. if( wcsTmp.Valid() )
  729. {
  730. ULONG lLowDateTime=0,lHighDateTime=0;
  731. //=====================================
  732. // As long as we have a list, process
  733. // one at a time
  734. //=====================================
  735. lLowDateTime = 0l;
  736. lHighDateTime = 0L;
  737. fMofHasChanged = FALSE;
  738. //==============================================
  739. // Compare the file date/timestamp the date/timestamp is different, change
  740. // it.
  741. //==============================================
  742. wcscpy(wcsTmp,wcsFile);
  743. if( GetFileDateAndTime(lLowDateTime,lHighDateTime,wcsTmp) )
  744. {
  745. CreateKey(wcsTmp,wcsResource,wcsKey);
  746. // DBG_PRINTFA((pBuff,"Event:%S\n",wcsKey));
  747. if( NeedToProcessThisMof(wcsKey,lLowDateTime,lHighDateTime) )
  748. {
  749. fMofHasChanged = TRUE;
  750. if( m_fUpdateNamespace )
  751. {
  752. DWORD dwSize = 0;
  753. BYTE * pRes = NULL;
  754. HGLOBAL hResource = NULL;
  755. HINSTANCE hInst = NULL;
  756. if( GetPointerToBinaryResource(pRes,dwSize,hResource,hInst,wcsResource,wcsKey) )
  757. {
  758. hr = SendToMofComp(dwSize,pRes,wcsKey);
  759. if(hr == WBEM_S_NO_ERROR )
  760. {
  761. if( UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime, TRUE) )
  762. {
  763. CNamespaceManagement Namespace(this);
  764. Namespace.CreateClassAssociationsToDriver(wcsKey,pRes,lLowDateTime,lHighDateTime);
  765. Namespace.DeleteOldClasses(wcsKey,CVARIANT((long)lLowDateTime),CVARIANT((long)lHighDateTime), TRUE);
  766. fSuccess = TRUE;
  767. }
  768. else
  769. {
  770. UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime,FALSE);
  771. }
  772. }
  773. else
  774. {
  775. UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime,FALSE);
  776. }
  777. UnlockResource(hResource);
  778. FreeResource(hResource);
  779. FreeLibrary(hInst);
  780. }
  781. else
  782. {
  783. ERRORTRACE((THISPROVIDER,"***************\n"));
  784. ERRORTRACE((THISPROVIDER,"Could not get pointer to binary resource for file:\n"));
  785. TranslateAndLog(wcsKey);
  786. ERRORTRACE((THISPROVIDER,"***************\n"));
  787. UpdateMofTimestampInHMOM(wcsKey,lLowDateTime,lHighDateTime,FALSE);
  788. }
  789. }
  790. }
  791. else
  792. {
  793. fSuccess = TRUE;
  794. }
  795. }
  796. else
  797. {
  798. DWORD dwTest = GetLastError();
  799. ERRORTRACE((THISPROVIDER,"Something FAILED for filename: %s\n",wcsFile));
  800. ERRORTRACE((THISPROVIDER,": GetlastError returned %ld\n",dwTest));
  801. ERRORTRACE((THISPROVIDER,"***************\n"));
  802. ERRORTRACE((THISPROVIDER,"Invalid File:\n"));
  803. TranslateAndLog(wcsFile);
  804. ERRORTRACE((THISPROVIDER,"***************\n"));
  805. UpdateMofTimestampInHMOM(wcsFile,lLowDateTime,lHighDateTime,FALSE);
  806. wcscpy(wcsKey, wcsFile);
  807. }
  808. }
  809. return fSuccess;
  810. }
  811. //////////////////////////////////////////////////////////////////////////
  812. #define WDMPROV_REG_KEY L"Software\\Microsoft\\WBEM\\WDMProvider"
  813. BOOL CWMIBinMof::UserConfiguredRegistryToProcessStrandedClassesDuringEveryInit(void)
  814. {
  815. DWORD dwProcess = 0;
  816. CRegistry RegInfo ;
  817. DWORD dwRet = RegInfo.Open (HKEY_LOCAL_MACHINE, WDMPROV_REG_KEY, KEY_READ) ;
  818. if ( dwRet == ERROR_SUCCESS )
  819. {
  820. RegInfo.GetCurrentKeyValue ( L"ProcessStrandedClasses",dwProcess );
  821. }
  822. RegInfo.Close();
  823. return (BOOL) dwProcess;
  824. }
  825. /////////// //////////////////////////////////////////////////////////
  826. void CWMIBinMof::ProcessListOfWMIBinaryMofsFromWMI()
  827. {
  828. HRESULT hr = WBEM_E_FAILED;
  829. if( m_nInit == FULLY_INITIALIZED )
  830. {
  831. CAutoWChar wcsFileName(MAX_PATH*3);
  832. CAutoWChar wcsResource(MAX_PATH*3);
  833. if( wcsFileName.Valid() && wcsResource.Valid() )
  834. {
  835. KeyList ArrDriversInRegistry;
  836. //============================================================
  837. // Get list of what is currently in the registry
  838. //============================================================
  839. GetListOfDriversCurrentlyInRegistry(WDM_REG_KEY,ArrDriversInRegistry);
  840. //======================================================================
  841. // Initialize things
  842. //======================================================================
  843. BOOL fMofChanged = FALSE;
  844. m_fUpdateNamespace = TRUE;
  845. //======================================================================
  846. // Allocate working classes
  847. //======================================================================
  848. CWMIStandardShell * pWMI = new CWMIStandardShell;
  849. if( pWMI )
  850. {
  851. hr = pWMI->Initialize(NULL,FALSE,m_pWMI->HandleMap(),m_fUpdateNamespace, WMIGUID_QUERY, m_pWMI->Services(),m_pWMI->Handler(),m_pWMI->Context());
  852. if( S_OK == hr )
  853. {
  854. CNamespaceManagement * pNamespace = new CNamespaceManagement(this);
  855. if( pNamespace )
  856. {
  857. //=========================================
  858. // Query the binary guid
  859. //=========================================
  860. pNamespace->InitQuery(L"select * from WMIBinaryMofResource where Name != ");
  861. hr = pWMI->QueryAndProcessAllBinaryGuidInstances(*pNamespace, fMofChanged, &ArrDriversInRegistry);
  862. //=========================================
  863. // Get a list of binary mofs from WMI
  864. //=========================================
  865. GetListOfBinaryMofs();
  866. ULONG nTmp=0;
  867. CAutoWChar wcsTmpKey(MAX_PATH*3);
  868. BOOL fProcessStrandedClasses = FALSE;
  869. if( wcsTmpKey.Valid() )
  870. {
  871. if( m_uResourceCount > 0 )
  872. {
  873. //===============================================================
  874. // Go through and get all the resources to process one by one
  875. //===============================================================
  876. while( GetBinaryMofFileNameAndResourceName(wcsFileName,wcsResource)){
  877. //============================================================
  878. // Process the binary mof
  879. //============================================================
  880. if( ExtractBinaryMofFromFile(wcsFileName,wcsResource,wcsTmpKey,fMofChanged))
  881. {
  882. pNamespace->UpdateQuery(L" and Name != ",wcsTmpKey);
  883. }
  884. if( fMofChanged )
  885. {
  886. fProcessStrandedClasses = TRUE;
  887. }
  888. ArrDriversInRegistry.Remove(wcsTmpKey);
  889. }
  890. }
  891. }
  892. pNamespace->DeleteOldDrivers(FALSE);
  893. //===========================================================================
  894. // If we are not supposed to process stranded classes, check the reg key
  895. // to see if it wants us to anyway
  896. //===========================================================================
  897. if( !fProcessStrandedClasses )
  898. {
  899. fProcessStrandedClasses = UserConfiguredRegistryToProcessStrandedClassesDuringEveryInit();
  900. }
  901. if( fProcessStrandedClasses )
  902. {
  903. pNamespace->DeleteStrandedClasses();
  904. }
  905. DeleteOldDriversInRegistry(ArrDriversInRegistry);
  906. SAFE_DELETE_PTR(pNamespace);
  907. }
  908. }
  909. SAFE_DELETE_PTR(pWMI);
  910. }
  911. if( m_pMofResourceInfo )
  912. {
  913. WmiFreeBuffer( m_pMofResourceInfo );
  914. }
  915. }
  916. }
  917. ERRORTRACE((THISPROVIDER,"End of processing Binary MOFS***************\n"));
  918. }
  919. /////////////////////////////////////////////////////////////////////
  920. //=============================================================
  921. // THE BINARY MOF GROUP
  922. //=============================================================
  923. BOOL CWMIBinMof::GetListOfBinaryMofs()
  924. {
  925. BOOL fRc = TRUE;
  926. ULONG uRc;
  927. m_uCurrentResource = 0;
  928. m_pMofResourceInfo = NULL;
  929. m_uResourceCount = 0;
  930. try
  931. {
  932. uRc = WmiMofEnumerateResourcesW( 0, &m_uResourceCount, &m_pMofResourceInfo );
  933. if( uRc != ERROR_SUCCESS )
  934. {
  935. fRc = FALSE;
  936. }
  937. }
  938. catch(...)
  939. {
  940. fRc = FALSE;
  941. // don't throw
  942. }
  943. return fRc;
  944. }
  945. //=============================================================
  946. BOOL CWMIBinMof::GetBinaryMofFileNameAndResourceName(WCHAR * pwcsFileName,WCHAR * pwcsResource)
  947. {
  948. BOOL fRc = FALSE;
  949. //===================================================================
  950. // There are a lot of tests in here, due to strange results from
  951. // WDM Service under stress.
  952. //===================================================================
  953. if( m_uCurrentResource < m_uResourceCount ){
  954. if( m_pMofResourceInfo ){
  955. DWORD dwFileLen = wcslen(m_pMofResourceInfo[m_uCurrentResource].ImagePath);
  956. DWORD dwResourceLen = wcslen(m_pMofResourceInfo[m_uCurrentResource].ResourceName);
  957. if( dwFileLen <( MAX_PATH * 2) && dwResourceLen < (MAX_PATH * 2 )){
  958. if( IsBadReadPtr( m_pMofResourceInfo[m_uCurrentResource].ImagePath,dwFileLen) == 0 ){
  959. wcscpy( pwcsFileName, m_pMofResourceInfo[m_uCurrentResource].ImagePath );
  960. if( IsBadReadPtr( m_pMofResourceInfo[m_uCurrentResource].ResourceName,dwResourceLen) == 0 ){
  961. wcscpy( pwcsResource, m_pMofResourceInfo[m_uCurrentResource].ResourceName );
  962. m_uCurrentResource++;
  963. fRc = TRUE;
  964. }
  965. }
  966. }
  967. }
  968. }
  969. return fRc;
  970. }
  971. ////////////////////////////////////////////////////////////////////
  972. HRESULT CWMIBinMof::ExtractBinaryMofFromDataBlock(BYTE * pByte,ULONG uInstanceSize, WCHAR * wcsKey, BOOL & fMofHasChanged)
  973. {
  974. HRESULT hr = WBEM_E_FAILED;
  975. //===================================================
  976. // Get the CRC of the data buffer
  977. //===================================================
  978. DWORD dwCRC = STARTING_CRC32_VALUE;
  979. if( IsBadReadPtr( pByte,uInstanceSize) != 0 ){
  980. return WBEM_E_INVALID_OBJECT;
  981. }
  982. dwCRC = UpdateCRC32(pByte,uInstanceSize, dwCRC);
  983. FINALIZE_CRC32(dwCRC);
  984. //=========================================================
  985. // get the size of the buffer to send
  986. //=========================================================
  987. DWORD dwCompressedSize;
  988. BYTE * pTmp = pByte;
  989. pTmp += sizeof( DWORD ) * 2;
  990. memcpy(&dwCompressedSize,pTmp,sizeof(DWORD));
  991. dwCompressedSize += 16;
  992. fMofHasChanged = FALSE;
  993. //===================================================
  994. // See if we should process this class or not
  995. //===================================================
  996. ULONG lLow = dwCRC;
  997. ULONG lHigh = 0;
  998. // DBG_PRINTFA((pBuff,"Event:%S\n",wcsKey));
  999. if( NeedToProcessThisMof(wcsKey,lLow,lHigh))
  1000. {
  1001. if( !m_fUpdateNamespace )
  1002. {
  1003. fMofHasChanged = TRUE;
  1004. hr = WBEM_NO_ERROR;
  1005. }
  1006. else
  1007. {
  1008. hr = SendToMofComp(dwCompressedSize,pByte,wcsKey);
  1009. if( hr == WBEM_NO_ERROR )
  1010. {
  1011. if( UpdateMofTimestampInHMOM(wcsKey,lLow,lHigh, TRUE))
  1012. {
  1013. CNamespaceManagement Namespace(this);
  1014. Namespace.CreateClassAssociationsToDriver(wcsKey,pByte,lLow,lHigh);
  1015. Namespace.DeleteOldClasses(wcsKey,CVARIANT((long)lLow),CVARIANT((long)lHigh),TRUE);
  1016. }
  1017. else
  1018. {
  1019. UpdateMofTimestampInHMOM(wcsKey,lLow,lHigh,FALSE);
  1020. }
  1021. }
  1022. else
  1023. {
  1024. UpdateMofTimestampInHMOM(wcsKey,lLow,lHigh,FALSE);
  1025. }
  1026. }
  1027. }
  1028. else
  1029. {
  1030. hr = WBEM_NO_ERROR;
  1031. }
  1032. return hr;
  1033. }
  1034. ////////////////////////////////////////////////////////////////////
  1035. HRESULT CWMIBinMof::DeleteMofsFromEvent(CVARIANT & vImagePath,CVARIANT & vResourceName, BOOL & fMofHasChanged)
  1036. {
  1037. HRESULT hr = WBEM_E_OUT_OF_MEMORY;
  1038. CAutoWChar wcsTmp(MAX_PATH*2);
  1039. if( wcsTmp.Valid() )
  1040. {
  1041. hr = WBEM_E_INVALID_OBJECT;
  1042. //=========================================
  1043. // Initialize stuff
  1044. //=========================================
  1045. fMofHasChanged = FALSE;
  1046. //=================================================================
  1047. // if we have an image path and resource path we are working with
  1048. // file, otherwise it is a binary guidd
  1049. //=================================================================
  1050. if((vResourceName.GetType() != VT_NULL ) && ( vImagePath.GetType() != VT_NULL )){
  1051. CreateKey( vImagePath.GetStr(), vResourceName.GetStr(),wcsTmp );
  1052. }
  1053. else if( vResourceName.GetType() != VT_NULL ){
  1054. SetBinaryMofClassName(vResourceName.GetStr(),wcsTmp);
  1055. }
  1056. if( m_fUpdateNamespace )
  1057. {
  1058. CNamespaceManagement Namespace(this);
  1059. Namespace.InitQuery(L"select * from WMIBinaryMofResource where Name = ");
  1060. Namespace.UpdateQuery(L"",wcsTmp);
  1061. if( Namespace.DeleteOldDrivers(FALSE) )
  1062. {
  1063. hr = WBEM_NO_ERROR;
  1064. fMofHasChanged = TRUE;
  1065. }
  1066. }
  1067. else
  1068. {
  1069. if( ThisMofExistsInRegistry(WDM_REG_KEY,wcsTmp, 0, 0, FALSE))
  1070. {
  1071. fMofHasChanged = TRUE;
  1072. }
  1073. hr = WBEM_NO_ERROR;
  1074. }
  1075. }
  1076. return hr;
  1077. }
  1078. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1079. //**********************************************************************************************************************
  1080. // Functions for the Dredger
  1081. //**********************************************************************************************************************
  1082. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1083. // format of string containing mof info is:
  1084. // "WmiBinaryMofResource.HighDateTime=9999,LowDateTime=9999,Name="Whatever"
  1085. //
  1086. // HKLM\Software\Microsoft\WBEM\WDM\WDMBinaryMofResource
  1087. //
  1088. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1089. HRESULT CWMIBinMof::AddThisMofToRegistryIfNeeded(WCHAR * wcsKey, WCHAR * wcsFileName, ULONG & lLowDateTime, ULONG & lHighDateTime, BOOL fSuccess)
  1090. {
  1091. HRESULT hr = WBEM_E_FAILED;
  1092. CRegistry RegInfo ;
  1093. DWORD dwRet = RegInfo.CreateOpen (HKEY_LOCAL_MACHINE, wcsKey) ;
  1094. if ( dwRet == ERROR_SUCCESS )
  1095. {
  1096. CAutoWChar wcsBuf(MAX_PATH);
  1097. if( wcsBuf.Valid() )
  1098. {
  1099. if( fSuccess )
  1100. {
  1101. swprintf(wcsBuf,L"LowDateTime:%ld,HighDateTime:%ld***Binary mof compiled successfully", lLowDateTime, lHighDateTime);
  1102. }
  1103. else
  1104. {
  1105. swprintf(wcsBuf,L"LowDateTime:%ld,HighDateTime:%ld***Binary mof failed, see WMIPROV.LOG", lLowDateTime, lHighDateTime);
  1106. }
  1107. CHString sTmp = wcsBuf;
  1108. if ( RegInfo.SetCurrentKeyValue ( wcsFileName,sTmp ) == ERROR_SUCCESS )
  1109. {
  1110. hr = WBEM_S_NO_ERROR ;
  1111. }
  1112. }
  1113. else
  1114. {
  1115. hr = WBEM_E_OUT_OF_MEMORY;
  1116. }
  1117. }
  1118. RegInfo.Close();
  1119. return hr;
  1120. }
  1121. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1122. BOOL CWMIBinMof::ThisMofExistsInRegistry(WCHAR * wcsKey,WCHAR * wcsFileName, ULONG lLowDateTime, ULONG lHighDateTime, BOOL fCompareDates)
  1123. {
  1124. BOOL fExists = FALSE;
  1125. CRegistry RegInfo ;
  1126. DWORD dwRet = RegInfo.Open (HKEY_LOCAL_MACHINE, wcsKey, KEY_READ) ;
  1127. if ( dwRet == ERROR_SUCCESS )
  1128. {
  1129. CHString chsValue;
  1130. if ( RegInfo.GetCurrentKeyValue ( wcsFileName,chsValue ) == ERROR_SUCCESS )
  1131. {
  1132. if( fCompareDates )
  1133. {
  1134. CAutoWChar wcsIncomingValue(MAX_PATH);
  1135. CAutoWChar wcsTmp(MAX_PATH);
  1136. if( wcsIncomingValue.Valid() && wcsTmp.Valid() )
  1137. {
  1138. swprintf(wcsIncomingValue,L"LowDateTime:%ld,HighDateTime:%ld", lLowDateTime, lHighDateTime );
  1139. WCHAR *wcsToken = NULL;
  1140. //======================================================
  1141. // Get a ptr to the first *** , if there isn't one, then
  1142. // we have a messed up key
  1143. //======================================================
  1144. wcscpy(wcsTmp,(const WCHAR*)chsValue);
  1145. wcsToken = wcstok(wcsTmp, L"*" );
  1146. if( wcsToken != NULL )
  1147. {
  1148. if( _wcsicmp(wcsToken, wcsIncomingValue) == 0 )
  1149. {
  1150. fExists = TRUE;
  1151. }
  1152. }
  1153. }
  1154. }
  1155. else
  1156. {
  1157. fExists = TRUE;
  1158. }
  1159. }
  1160. }
  1161. RegInfo.Close();
  1162. return fExists;
  1163. }
  1164. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1165. HRESULT CWMIBinMof::DeleteMofFromRegistry(WCHAR * wcsFileName)
  1166. {
  1167. HRESULT hr = WBEM_E_FAILED;
  1168. HKEY hKey;
  1169. hr = RegOpenKey(HKEY_LOCAL_MACHINE, WDM_REG_KEY, &hKey);
  1170. if(NO_ERROR == hr)
  1171. {
  1172. hr = RegDeleteValue(hKey,wcsFileName);
  1173. CloseHandle(hKey);
  1174. }
  1175. return hr;
  1176. }
  1177. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1178. BOOL CWMIBinMof::DeleteOldDriversInRegistry(KeyList & ArrDriversInRegistry)
  1179. {
  1180. int nSize = ArrDriversInRegistry.GetSize();
  1181. for( int i=0; i < nSize; i++ )
  1182. {
  1183. DeleteMofFromRegistry(ArrDriversInRegistry.GetAt(i));
  1184. }
  1185. return TRUE;
  1186. }
  1187. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1188. BOOL CWMIBinMof::CopyWDMKeyToDredgeKey()
  1189. {
  1190. BOOL fSuccess = FALSE;
  1191. //=======================================================================
  1192. // Open up the WDM Dredge Key and enumerate the keys, copy them into
  1193. // the DredgeReg key
  1194. //=======================================================================
  1195. CRegistry WDMReg;
  1196. CRegistry WDMDregReg;
  1197. if (ERROR_SUCCESS == WDMReg.Open(HKEY_LOCAL_MACHINE, WDM_REG_KEY, KEY_READ))
  1198. {
  1199. //===============================================================
  1200. // Clean up old stuff
  1201. // Note: You need to open up the parent key, so you can delete
  1202. // the child DREDGE key
  1203. //===============================================================
  1204. if( ERROR_SUCCESS == WDMDregReg.Open(HKEY_LOCAL_MACHINE, WDM_REG_KEY, KEY_READ))
  1205. {
  1206. CHString pchs(DREDGE_KEY);
  1207. WDMDregReg.DeleteKey(&pchs);
  1208. WDMDregReg.Close();
  1209. }
  1210. if( ERROR_SUCCESS == WDMDregReg.CreateOpen(HKEY_LOCAL_MACHINE, WDM_DREDGE_KEY))
  1211. {
  1212. //===============================================================
  1213. // Go through the loop, and copy the keys
  1214. //===============================================================
  1215. BYTE *pValueData = NULL ;
  1216. WCHAR *pValueName = NULL ;
  1217. fSuccess = TRUE;
  1218. for(DWORD i = 0 ; i < WDMReg.GetValueCount(); i++)
  1219. {
  1220. DWORD dwRc = WDMReg.EnumerateAndGetValues(i, pValueName, pValueData) ;
  1221. if( dwRc == ERROR_SUCCESS )
  1222. {
  1223. CHString chsKey(pValueName);
  1224. CHString chsValue((LPCWSTR)pValueData);
  1225. if ( !WDMDregReg.SetCurrentKeyValue ( chsKey, chsValue ) == ERROR_SUCCESS )
  1226. {
  1227. fSuccess = FALSE;
  1228. }
  1229. delete []pValueData;
  1230. delete []pValueName;
  1231. }
  1232. else
  1233. {
  1234. fSuccess = FALSE;
  1235. }
  1236. if( !fSuccess )
  1237. {
  1238. break;
  1239. }
  1240. }
  1241. WDMDregReg.Close();
  1242. }
  1243. WDMReg.Close();
  1244. }
  1245. return fSuccess;
  1246. }
  1247. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1248. BOOL CWMIBinMof::GetListOfDriversCurrentlyInRegistry(WCHAR * wcsKey, KeyList & ArrDriversInRegistry)
  1249. {
  1250. BOOL fSuccess = TRUE;
  1251. CRegistry RegInfo ;
  1252. //==========================================================
  1253. // Open the key for enumeration and go through the sub keys.
  1254. //==========================================================
  1255. HKEY hKey = NULL;
  1256. HRESULT hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, wcsKey, 0, KEY_READ | KEY_QUERY_VALUE,&hKey);
  1257. if( ERROR_SUCCESS == hr )
  1258. {
  1259. WCHAR wcsKeyName[MAX_PATH+2];
  1260. DWORD dwLen = 0;
  1261. int i = 0;
  1262. while( ERROR_SUCCESS == hr )
  1263. {
  1264. dwLen = MAX_PATH+2;
  1265. hr = RegEnumValue(hKey,i,wcsKeyName, &dwLen,0,NULL,NULL,NULL);
  1266. // If we are successful reading the name
  1267. //=======================================
  1268. if(ERROR_SUCCESS == hr )
  1269. {
  1270. ArrDriversInRegistry.Add(wcsKeyName);
  1271. i++;
  1272. }
  1273. else
  1274. {
  1275. break;
  1276. }
  1277. }
  1278. RegCloseKey(hKey);
  1279. }
  1280. else
  1281. {
  1282. fSuccess = FALSE;
  1283. }
  1284. return fSuccess;
  1285. }
  1286. /////////////////////////////////////////////////////////////////////
  1287. HRESULT CWMIBinMof::ProcessBinaryMofEvent(PWNODE_HEADER WnodeHeader )
  1288. {
  1289. HRESULT hr = WBEM_E_FAILED;
  1290. m_fUpdateNamespace = TRUE;
  1291. if( m_nInit == FULLY_INITIALIZED )
  1292. {
  1293. CWMIStandardShell * pWMI = new CWMIStandardShell;
  1294. if( pWMI )
  1295. {
  1296. //=======================================================
  1297. // See if a binary mof event is being added or deleted
  1298. //=======================================================
  1299. if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_ADDED_GUID,WnodeHeader->Guid))
  1300. {
  1301. hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_ADDED,TRUE,m_pWMI->HandleMap(),m_fUpdateNamespace, WMIGUID_QUERY, m_pWMI->Services(),m_pWMI->Handler(), m_pWMI->Context());
  1302. if( S_OK == hr )
  1303. {
  1304. hr = pWMI->ProcessEvent(MOF_ADDED,WnodeHeader);
  1305. }
  1306. }
  1307. else if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_REMOVED_GUID,WnodeHeader->Guid))
  1308. {
  1309. hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_DELETED,TRUE,m_pWMI->HandleMap(),m_fUpdateNamespace, WMIGUID_QUERY, m_pWMI->Services(),m_pWMI->Handler(), m_pWMI->Context());
  1310. if( S_OK == hr )
  1311. {
  1312. hr = pWMI->ProcessEvent(MOF_DELETED,WnodeHeader);
  1313. }
  1314. }
  1315. SAFE_DELETE_PTR(pWMI);
  1316. }
  1317. }
  1318. return hr;
  1319. }
  1320. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1321. //**********************************************************************************************************************
  1322. // STUFF FOR DREDGE
  1323. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1324. //**********************************************************************************************************************
  1325. /////////////////////////////////////////////////////////////////////
  1326. // DREDGE APIS - access ONLY the DREDGE KEY
  1327. /////////////////////////////////////////////////////////////////////
  1328. BOOL CWMIBinMof::BinaryMofEventChanged(PWNODE_HEADER WnodeHeader )
  1329. {
  1330. BOOL fMofHasChanged = TRUE;
  1331. if( m_nInit != NOT_INITIALIZED )
  1332. {
  1333. HRESULT hr = WBEM_E_NOT_FOUND;
  1334. m_fUpdateNamespace = FALSE;
  1335. CWMIStandardShell * pWMI = new CWMIStandardShell;
  1336. if( pWMI )
  1337. {
  1338. //=======================================================
  1339. // See if a binary mof event is being added or deleted
  1340. //=======================================================
  1341. if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_ADDED_GUID,WnodeHeader->Guid))
  1342. {
  1343. hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_ADDED,
  1344. TRUE,
  1345. NULL,
  1346. m_fUpdateNamespace,
  1347. WMIGUID_QUERY,
  1348. NULL,
  1349. NULL,
  1350. NULL);
  1351. if( S_OK == hr )
  1352. {
  1353. hr = pWMI->ProcessEvent(MOF_ADDED,WnodeHeader);
  1354. }
  1355. }
  1356. else if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_REMOVED_GUID,WnodeHeader->Guid))
  1357. {
  1358. // DO NOTHING
  1359. hr = pWMI->Initialize(RUNTIME_BINARY_MOFS_DELETED,TRUE,
  1360. NULL,
  1361. m_fUpdateNamespace,
  1362. WMIGUID_QUERY,
  1363. NULL,
  1364. NULL,
  1365. NULL);
  1366. if( S_OK == hr )
  1367. {
  1368. // hr = pWMI->ProcessEvent(MOF_DELETED,WnodeHeader);
  1369. }
  1370. }
  1371. ERRORTRACE((THISPROVIDER,"***************\n"));
  1372. if( pWMI->HasMofChanged() )
  1373. {
  1374. ERRORTRACE((THISPROVIDER,"BinaryMofEventChanged returned TRUE:\n"));
  1375. }
  1376. else
  1377. {
  1378. ERRORTRACE((THISPROVIDER,"BinaryMofEventChanged returned FALSE:\n"));
  1379. }
  1380. fMofHasChanged = pWMI->HasMofChanged();
  1381. SAFE_DELETE_PTR(pWMI);
  1382. }
  1383. }
  1384. return fMofHasChanged;
  1385. }
  1386. /////////////////////////////////////////////////////////////////////
  1387. // DREDGE APIS - access ONLY the DREDGE KEY
  1388. /////////////////////////////////////////////////////////////////////
  1389. BOOL CWMIBinMof::BinaryMofsHaveChanged()
  1390. {
  1391. BOOL fBinaryMofHasChanged = FALSE;
  1392. if( m_nInit != NOT_INITIALIZED )
  1393. {
  1394. KeyList ArrDriversInRegistry;
  1395. HRESULT hr = WBEM_E_FAILED;
  1396. m_fUpdateNamespace = FALSE;
  1397. //============================================================
  1398. // Get list of what is currently in the registry
  1399. //============================================================
  1400. BOOL fRc = GetListOfDriversCurrentlyInRegistry(WDM_DREDGE_KEY,ArrDriversInRegistry);
  1401. if( fRc )
  1402. {
  1403. //=====================================================================
  1404. // Get a list of binary mofs from WMI
  1405. // Query WMIBinaryMofResource for list of static mofs
  1406. //=====================================================================
  1407. GetListOfBinaryMofs();
  1408. if( m_uResourceCount > 0 )
  1409. {
  1410. //===============================================================
  1411. // Go through and get all the resources to process one by one
  1412. //===============================================================
  1413. CAutoWChar FileName(MAX_PATH*2);
  1414. CAutoWChar Resource(MAX_PATH*2);
  1415. CAutoWChar TmpKey(MAX_PATH*2);
  1416. if( FileName.Valid() && Resource.Valid() && TmpKey.Valid() )
  1417. {
  1418. while( GetBinaryMofFileNameAndResourceName(FileName,Resource))
  1419. {
  1420. //============================================================
  1421. // Process the binary mof, keep going until one needs to
  1422. // be processed
  1423. //============================================================
  1424. ExtractBinaryMofFromFile(FileName,Resource,TmpKey, fBinaryMofHasChanged );
  1425. if( fBinaryMofHasChanged )
  1426. {
  1427. break;
  1428. }
  1429. ArrDriversInRegistry.Remove(TmpKey);
  1430. }
  1431. }
  1432. }
  1433. if( !fBinaryMofHasChanged )
  1434. {
  1435. //=========================================
  1436. // Query the binary guid
  1437. //=========================================
  1438. CNamespaceManagement * pNamespace = new CNamespaceManagement(this);
  1439. if( pNamespace )
  1440. {
  1441. pNamespace->InitQuery(L"select * from WMIBinaryMofResource where Name != ");
  1442. CWMIStandardShell * pWMI = new CWMIStandardShell;
  1443. if( pWMI )
  1444. {
  1445. hr = pWMI->Initialize(NULL, FALSE, NULL,m_fUpdateNamespace, WMIGUID_QUERY,NULL,NULL,NULL);
  1446. if( S_OK == hr )
  1447. {
  1448. hr = pWMI->QueryAndProcessAllBinaryGuidInstances(*pNamespace, fBinaryMofHasChanged,&ArrDriversInRegistry);
  1449. }
  1450. SAFE_DELETE_PTR(pWMI);
  1451. }
  1452. SAFE_DELETE_PTR(pNamespace);
  1453. }
  1454. else
  1455. {
  1456. hr = WBEM_E_OUT_OF_MEMORY;
  1457. }
  1458. }
  1459. /* //============================================================
  1460. // If there are any drivers left in the list, then we need
  1461. // to say that the binary mofs have changed
  1462. //============================================================
  1463. if( !fBinaryMofHasChanged )
  1464. {
  1465. if( ArrDriversInRegistry.OldDriversLeftOver() )
  1466. {
  1467. fBinaryMofHasChanged = TRUE;
  1468. }
  1469. }
  1470. */
  1471. }
  1472. else
  1473. {
  1474. //==============================================================================================
  1475. // there is no key, so now we need to return that the registry has changed, so the copy of the
  1476. // keys will be kicked off
  1477. //==============================================================================================
  1478. fBinaryMofHasChanged = TRUE;
  1479. }
  1480. if( m_pMofResourceInfo )
  1481. {
  1482. WmiFreeBuffer( m_pMofResourceInfo );
  1483. }
  1484. ERRORTRACE((THISPROVIDER,"***************\n"));
  1485. if( fBinaryMofHasChanged )
  1486. {
  1487. ERRORTRACE((THISPROVIDER,"BinaryMofsHaveChanged returned TRUE:\n"));
  1488. }
  1489. else
  1490. {
  1491. ERRORTRACE((THISPROVIDER,"BinaryMofsHaveChanged returned FALSE:\n"));
  1492. }
  1493. }
  1494. return fBinaryMofHasChanged;
  1495. }
  1496. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1497. //**********************************************************************************************************************
  1498. // Namespace Management Class
  1499. //**********************************************************************************************************************
  1500. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1501. CNamespaceManagement::CNamespaceManagement(CWMIBinMof * pOwner)
  1502. {
  1503. m_pObj = pOwner;
  1504. m_nSize = 0;
  1505. m_pwcsQuery = NULL;
  1506. m_fInit = 0;
  1507. m_pwcsSavedQuery = NULL;
  1508. m_fSavedInit = 0;
  1509. m_nSavedSize = 0;
  1510. }
  1511. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1512. CNamespaceManagement::~CNamespaceManagement()
  1513. {
  1514. SAFE_DELETE_ARRAY( m_pwcsQuery );
  1515. }
  1516. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1517. #define SERVICES_PTR m_pObj->WMI()->Services()
  1518. #define CONTEXT_PTR m_pObj->WMI()->Context()
  1519. /////////////////////////////////////////////////////////////////////////////////////////////////
  1520. // Delete stranded classes in the repository
  1521. /////////////////////////////////////////////////////////////////////////////////////////////////
  1522. BOOL CNamespaceManagement::DeleteStrandedClasses(void)
  1523. {
  1524. BOOL fRc = TRUE;
  1525. HRESULT hr = WBEM_NO_ERROR;
  1526. IEnumWbemClassObject* pEnum = NULL;
  1527. IEnumWbemClassObject* pEnumofStrandedClasses = NULL;
  1528. // ==================================================================================
  1529. // Get list of drivers
  1530. // ==================================================================================
  1531. InitQuery(L"select * from WMIBinaryMofResource");
  1532. CBSTR strQryLang(L"WQL");
  1533. CBSTR cbstrQry(m_pwcsQuery);
  1534. hr = SERVICES_PTR->ExecQuery(strQryLang,cbstrQry, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnum);
  1535. if( hr == WBEM_NO_ERROR )
  1536. {
  1537. unsigned long uReturned = 0;
  1538. CVARIANT vDriver, vLow, vHigh;
  1539. IWbemClassObject * pClass = NULL;
  1540. //================================================================================
  1541. // Initialize query for stranded classes as we go along and clean up the old
  1542. // classes
  1543. //================================================================================
  1544. InitQuery(L"select * from WDMClassesOfDriver where Driver != ");
  1545. while ( TRUE )
  1546. {
  1547. IWbemClassObject * pClass = NULL;
  1548. if( WBEM_NO_ERROR == (hr = pEnum->Next(2000, 1, &pClass, &uReturned)))
  1549. {
  1550. if( WBEM_NO_ERROR == (hr = pClass->Get(L"Name", 0, &vDriver, 0, 0)))
  1551. {
  1552. //============================================================
  1553. // Correct the query syntax for next query
  1554. //============================================================
  1555. UpdateQuery( L" and Driver != ",vDriver.GetStr());
  1556. }
  1557. }
  1558. SAFE_RELEASE_PTR(pClass );
  1559. if( hr != WBEM_NO_ERROR )
  1560. {
  1561. break;
  1562. }
  1563. }
  1564. //================================================================
  1565. // Ok, now go after the stranded classes, the ones that don't
  1566. // have any drivers for some reason
  1567. //================================================================
  1568. CBSTR strQryLang(L"WQL");
  1569. CBSTR cbstr(m_pwcsQuery);
  1570. hr = SERVICES_PTR->ExecQuery(strQryLang,cbstr, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnumofStrandedClasses);
  1571. if( hr == WBEM_NO_ERROR )
  1572. {
  1573. BOOL bDrivers = FALSE;
  1574. while( TRUE )
  1575. {
  1576. if( WBEM_NO_ERROR == (hr = pEnumofStrandedClasses->Next(2000, 1, &pClass, &uReturned)))
  1577. {
  1578. CVARIANT vPath,vClass;
  1579. pClass->Get(L"ClassName", 0, &vClass, 0, 0);
  1580. if(SUCCEEDED(hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0)))
  1581. {
  1582. hr = DeleteUnusedClassAndDriverInfo( TRUE, vPath.GetStr(),vClass.GetStr() );
  1583. }
  1584. else
  1585. {
  1586. fRc = FALSE;
  1587. break;
  1588. }
  1589. }
  1590. SAFE_RELEASE_PTR(pClass);
  1591. if( hr != WBEM_NO_ERROR )
  1592. {
  1593. break;
  1594. }
  1595. }
  1596. SAFE_RELEASE_PTR(pEnumofStrandedClasses);
  1597. if(!fRc)
  1598. {
  1599. if( hr != E_OUTOFMEMORY)
  1600. {
  1601. ERRORTRACE((THISPROVIDER,"Stranded instance exist in repository"));
  1602. }
  1603. }
  1604. }
  1605. }
  1606. SAFE_RELEASE_PTR(pEnum);
  1607. return fRc;
  1608. }
  1609. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  1610. BOOL CNamespaceManagement::DeleteOldDrivers(BOOL fCompareDates)
  1611. {
  1612. HRESULT hr = WBEM_E_FAILED;
  1613. IEnumWbemClassObject* pEnum = NULL;
  1614. BOOL fRc = TRUE;
  1615. BSTR strQry = NULL;
  1616. strQry = SysAllocString(m_pwcsQuery);
  1617. if(strQry != NULL)
  1618. {
  1619. CBSTR strQryLang(L"WQL");
  1620. hr = SERVICES_PTR->ExecQuery(strQryLang, strQry, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnum);
  1621. SysFreeString(strQry);
  1622. strQry = NULL;
  1623. }
  1624. else
  1625. {
  1626. hr = E_OUTOFMEMORY;
  1627. fRc = FALSE;
  1628. }
  1629. if( hr == WBEM_NO_ERROR )
  1630. {
  1631. IWbemClassObject * pClass = NULL;
  1632. unsigned long uReturned = 0;
  1633. CVARIANT vClass;
  1634. hr = WBEM_NO_ERROR;
  1635. //============================================================================================
  1636. // NOTE: We only deal with drivers extracted from files here, if it is a guid as the result
  1637. // of an event this is handled elsewhere
  1638. //============================================================================================
  1639. while ( hr == WBEM_NO_ERROR )
  1640. {
  1641. IWbemClassObject * pClass = NULL;
  1642. unsigned long uReturned = 0;
  1643. hr = pEnum->Next(2000, 1, &pClass, &uReturned);
  1644. if( hr == WBEM_NO_ERROR )
  1645. {
  1646. CVARIANT vLowDate, vHighDate, vName;
  1647. if( WBEM_NO_ERROR != (hr = pClass->Get(L"Name", 0, &vName, 0, 0)))
  1648. {
  1649. break;
  1650. }
  1651. if( fCompareDates )
  1652. {
  1653. vLowDate.SetLONG(0);
  1654. vHighDate.SetLONG(0);
  1655. if( WBEM_NO_ERROR != (hr = pClass->Get(L"LowDateTime", 0, &vLowDate, 0, 0)))
  1656. {
  1657. break;
  1658. }
  1659. if( WBEM_NO_ERROR != (hr = pClass->Get(L"HighDateTime", 0, &vHighDate, 0, 0)))
  1660. {
  1661. break;
  1662. }
  1663. }
  1664. ERRORTRACE((THISPROVIDER,"Deleting Old Drivers"));
  1665. if( DeleteOldClasses((WCHAR *) vName.GetStr(),vLowDate,vHighDate,fCompareDates ))
  1666. {
  1667. CVARIANT vPath;
  1668. hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0);
  1669. if( hr == WBEM_NO_ERROR )
  1670. {
  1671. CBSTR cbstrPath(vPath.GetStr());
  1672. hr = SERVICES_PTR->DeleteInstance(cbstrPath,WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
  1673. ERRORTRACE((THISPROVIDER,"We have been requested to delete this mof, it is being removed\n"));
  1674. TranslateAndLog(cbstrPath);
  1675. }
  1676. if( WBEM_NO_ERROR == hr )
  1677. {
  1678. m_pObj->DeleteMofFromRegistry((WCHAR *) vName.GetStr());
  1679. }
  1680. else
  1681. {
  1682. ERRORTRACE((THISPROVIDER,"Stranded instance: \n"));
  1683. TranslateAndLog(vPath.GetStr());
  1684. ERRORTRACE((THISPROVIDER,"DeleteInstance return value: %ld\n",hr));
  1685. ERRORTRACE((THISPROVIDER,"Current query: \n"));
  1686. TranslateAndLog(m_pwcsQuery);
  1687. }
  1688. }
  1689. }
  1690. }
  1691. SAFE_RELEASE_PTR(pEnum);
  1692. }
  1693. else
  1694. {
  1695. ERRORTRACE((THISPROVIDER,"Cannot delete driver. ExecQuery return value: %ld\n",hr));
  1696. ERRORTRACE((THISPROVIDER,"Current query: \n"));
  1697. TranslateAndLog(m_pwcsQuery);
  1698. }
  1699. return fRc;
  1700. }
  1701. /////////////////////////////////////////////////////////////////////////////////////////////////
  1702. // Function to delete Old classes for a particular driver
  1703. /////////////////////////////////////////////////////////////////////////////////////////////////
  1704. BOOL CNamespaceManagement::DeleteOldClasses(WCHAR * wcsFileName,CVARIANT & vLow, CVARIANT & vHigh, BOOL fCompareDates)
  1705. {
  1706. HRESULT hr = WBEM_E_FAILED;
  1707. CAutoWChar wcsTranslatedKey(MAX_PATH*2);
  1708. BOOL fRc = FALSE;
  1709. IEnumWbemClassObject* pEnum = NULL;
  1710. ULONG lHighDateTime = 0L;
  1711. ULONG lLowDateTime = 0L;
  1712. ERRORTRACE((THISPROVIDER,"Deleting Old Classes for Driver"));
  1713. TranslateAndLog(wcsFileName);
  1714. ERRORTRACE((THISPROVIDER,"*******\n"));
  1715. if( wcsTranslatedKey.Valid() )
  1716. {
  1717. //================================================================================
  1718. // Initialize everything we need to construct the query
  1719. //================================================================================
  1720. if( fCompareDates )
  1721. {
  1722. lLowDateTime= (ULONG)vLow.GetLONG();
  1723. lHighDateTime= (ULONG)vHigh.GetLONG();
  1724. }
  1725. ConvertStringToCTypeString( wcsTranslatedKey,wcsFileName );
  1726. //================================================================================
  1727. // Now, pick up all the old classes for this driver
  1728. //================================================================================
  1729. InitQuery(L"select * from WDMClassesOfDriver where Driver = ");
  1730. UpdateQuery(L"",wcsFileName);
  1731. UpdateQuery(L" and (HighDateTime != ",lHighDateTime);
  1732. UpdateQuery(L" or LowDateTime != ", lLowDateTime);
  1733. AddToQuery(L")");
  1734. BSTR strTmp = NULL;
  1735. strTmp = SysAllocString(m_pwcsQuery);
  1736. if(strTmp != NULL)
  1737. {
  1738. CBSTR strQryLang(L"WQL");
  1739. hr = SERVICES_PTR->ExecQuery(strQryLang, strTmp, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,CONTEXT_PTR,&pEnum);
  1740. SysFreeString(strTmp);
  1741. strTmp = NULL;
  1742. }
  1743. else
  1744. {
  1745. hr = E_OUTOFMEMORY;
  1746. fRc = FALSE;
  1747. }
  1748. if( hr == WBEM_NO_ERROR )
  1749. {
  1750. IWbemClassObject * pClass = NULL;
  1751. unsigned long uReturned = 0;
  1752. CVARIANT vClass;
  1753. CAutoWChar wcsObjectPath(MAX_PATH*4);
  1754. if( wcsObjectPath.Valid() )
  1755. {
  1756. while ( TRUE )
  1757. {
  1758. hr = pEnum->Next(2000, 1, &pClass, &uReturned);
  1759. if( hr!= WBEM_NO_ERROR )
  1760. {
  1761. break;
  1762. }
  1763. hr = pClass->Get(L"ClassName", 0, &vClass, 0, 0);
  1764. if( hr != WBEM_NO_ERROR )
  1765. {
  1766. break;
  1767. }
  1768. //===========================================================================
  1769. // Now, get this instance of tying the class with this old date
  1770. //===========================================================================
  1771. CVARIANT vPath;
  1772. hr = pClass->Get(L"__RELPATH", 0, &vPath, 0, 0);
  1773. if( hr != WBEM_NO_ERROR )
  1774. {
  1775. break;
  1776. }
  1777. //==========================================================================
  1778. // Now, just because we get a class name here doesn't mean we delete the
  1779. // class, this class could have been updated, in that case we just delete
  1780. // the instance of the WDMClassesOfDriver.
  1781. // Now, we need to check to see if this class really needs to be deleted
  1782. // or not
  1783. //==========================================================================
  1784. IWbemClassObject * pTmp = NULL;
  1785. CBSTR bTmp = vClass.GetStr();
  1786. swprintf(wcsObjectPath,L"WDMClassesOfDriver.ClassName=\"%s\",Driver=\"%s\",HighDateTime=%lu,LowDateTime=%lu",bTmp,wcsTranslatedKey,lHighDateTime,lLowDateTime);
  1787. CBSTR bstrQuery = wcsObjectPath;
  1788. hr = SERVICES_PTR->GetObject(bstrQuery,0,CONTEXT_PTR,&pTmp,NULL);
  1789. //===========================================================================
  1790. // this is simple, if we get an instance of WDMClassesOfDriver
  1791. // with the newer date, then we know it has been updated, so we don't
  1792. // delete the class
  1793. //===========================================================================
  1794. BOOL fDeleteOldClass = TRUE;
  1795. if( hr == WBEM_NO_ERROR )
  1796. {
  1797. fDeleteOldClass = FALSE;
  1798. }
  1799. hr = DeleteUnusedClassAndDriverInfo( fDeleteOldClass, vPath.GetStr(),vClass.GetStr() );
  1800. //===========================================================================
  1801. // Now, delete the WDM Instance of the Old Driver
  1802. //===========================================================================
  1803. SAFE_RELEASE_PTR( pTmp )
  1804. SAFE_RELEASE_PTR( pClass );
  1805. vClass.Clear();
  1806. }
  1807. SAFE_RELEASE_PTR(pEnum);
  1808. }
  1809. }
  1810. if( hr == WBEM_NO_ERROR || hr == WBEM_S_NO_MORE_DATA || hr == WBEM_S_FALSE)
  1811. {
  1812. fRc = TRUE;
  1813. }
  1814. }
  1815. return fRc;
  1816. }
  1817. /////////////////////////////////////////////////////////////////////
  1818. BOOL CNamespaceManagement::CreateInstance ( WCHAR * wcsDriver, WCHAR * wcsClass, ULONG lLowDateTime, ULONG lHighDateTime )
  1819. {
  1820. IWbemClassObject * pInst = NULL, * pClass = NULL;
  1821. //==================================================
  1822. // Get a pointer to a IWbemClassObject object
  1823. //==================================================
  1824. HRESULT hr;
  1825. CVARIANT cvarName;
  1826. cvarName.SetStr(L"WDMClassesOfDriver");
  1827. hr = SERVICES_PTR->GetObject(cvarName, 0,CONTEXT_PTR, &pClass, NULL);
  1828. if(FAILED(hr)){
  1829. return FALSE;
  1830. }
  1831. //=============================================================
  1832. // Spawn a new instance
  1833. //=============================================================
  1834. hr = pClass->SpawnInstance(0, &pInst);
  1835. SAFE_RELEASE_PTR(pClass);
  1836. if( FAILED(hr) ){
  1837. return hr;
  1838. }
  1839. //=============================================================
  1840. // Put the data in the instance
  1841. //=============================================================
  1842. CVARIANT vClass, vDriver, vLow, vHigh;
  1843. vClass.SetStr(wcsClass);
  1844. vDriver.SetStr(wcsDriver);
  1845. vLow.SetLONG(lLowDateTime);
  1846. vHigh.SetLONG(lHighDateTime);
  1847. hr = pInst->Put(L"Driver", 0, &vDriver, NULL);
  1848. if( hr == WBEM_S_NO_ERROR )
  1849. {
  1850. hr = pInst->Put(L"ClassName", 0, &vClass, NULL);
  1851. hr = pInst->Put(L"LowDateTime", 0, &vLow, NULL);
  1852. hr = pInst->Put(L"HighDateTime", 0, &vHigh, NULL);
  1853. if( hr == WBEM_S_NO_ERROR )
  1854. {
  1855. hr = SERVICES_PTR->PutInstance(pInst,WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
  1856. }
  1857. }
  1858. SAFE_RELEASE_PTR(pInst);
  1859. if( WBEM_NO_ERROR == hr ){
  1860. return TRUE;
  1861. }
  1862. return FALSE;
  1863. }
  1864. /////////////////////////////////////////////////////////////////////
  1865. void CNamespaceManagement::CreateClassAssociationsToDriver(WCHAR * wcsFileName, BYTE* pRes, ULONG lLowDateTime, ULONG lHighDateTime)
  1866. {
  1867. CBMOFObjList * pol;
  1868. CBMOFObj * po;
  1869. CAnsiUnicode XLate;
  1870. //===========================================================================
  1871. // Now use the helper functions from David's mofcomp stuff to extract the
  1872. // class names we are going to add the Driver qualifier to.
  1873. // list structure and use it to enumerate the objects.
  1874. //===========================================================================
  1875. BYTE * pByte = m_pObj->DecompressBinaryMof(pRes);
  1876. if( pByte ){
  1877. pol = CreateObjList(pByte);
  1878. if(pol != NULL){
  1879. ResetObjList (pol);
  1880. while(po = NextObj(pol)){
  1881. WCHAR * pName = NULL;
  1882. if(GetName(po, &pName)){
  1883. //===============================================================
  1884. // Now, we have the name of the class in pName, we have the
  1885. // name of the driver, in wcsFileName
  1886. //===============================================================
  1887. CreateInstance(wcsFileName, pName, lLowDateTime, lHighDateTime );
  1888. BMOFFree(pName);
  1889. }
  1890. BMOFFree(po);
  1891. }
  1892. BMOFFree(pol);
  1893. }
  1894. }
  1895. else{
  1896. ERRORTRACE((THISPROVIDER,"Could not tie classes to driver for file:\n"));
  1897. TranslateAndLog(wcsFileName);
  1898. }
  1899. if( pByte ){
  1900. free(pByte);
  1901. }
  1902. }
  1903. /////////////////////////////////////////////////////////////////////
  1904. HRESULT CNamespaceManagement::AllocMemory(WCHAR *& p)
  1905. {
  1906. HRESULT hr = WBEM_E_FAILED;
  1907. p = new WCHAR[m_nSize+4];
  1908. if( p )
  1909. {
  1910. memset(p,NULL,m_nSize+4);
  1911. hr = WBEM_NO_ERROR;
  1912. }
  1913. return hr;
  1914. }
  1915. /////////////////////////////////////////////////////////////////////
  1916. void CNamespaceManagement::AddToQuery(WCHAR * p)
  1917. {
  1918. int nNewSize = wcslen(p) * sizeof(WCHAR);
  1919. int nCurrentBuf = 0;
  1920. if( m_pwcsQuery )
  1921. {
  1922. nCurrentBuf = (int)(wcslen(m_pwcsQuery) + 1) * sizeof(WCHAR);
  1923. }
  1924. if( nNewSize >= (m_nSize - nCurrentBuf))
  1925. {
  1926. int nOldSize = m_nSize;
  1927. WCHAR * pOld = m_pwcsQuery;
  1928. m_nSize += MEMSIZETOALLOCATE;
  1929. if( SUCCEEDED(AllocMemory(m_pwcsQuery)))
  1930. {
  1931. memcpy(m_pwcsQuery,pOld,nOldSize);
  1932. }
  1933. SAFE_DELETE_ARRAY(pOld);
  1934. }
  1935. if( wcslen(m_pwcsQuery) == 0 )
  1936. {
  1937. wcscpy(m_pwcsQuery,p);
  1938. }
  1939. else
  1940. {
  1941. wcscat(m_pwcsQuery,p);
  1942. }
  1943. }
  1944. /////////////////////////////////////////////////////////////////////
  1945. void CNamespaceManagement::InitQuery(WCHAR * p)
  1946. {
  1947. SAFE_DELETE_ARRAY(m_pwcsQuery);
  1948. m_nSize = MEMSIZETOALLOCATE;
  1949. m_fInit = TRUE;
  1950. if(SUCCEEDED(AllocMemory(m_pwcsQuery)))
  1951. {
  1952. AddToQuery(p);
  1953. }
  1954. }
  1955. /////////////////////////////////////////////////////////////////////
  1956. void CNamespaceManagement::UpdateQuery( WCHAR * pQueryAddOn, WCHAR * wcsParam )
  1957. {
  1958. CAutoWChar wcsTranslatedKey(MAX_PATH*3);
  1959. if( wcsTranslatedKey.Valid() )
  1960. {
  1961. ConvertStringToCTypeString( wcsTranslatedKey,wcsParam );
  1962. //=============================================
  1963. // The first time only we DON'T add the query
  1964. // add on string, otherwise, we do
  1965. //=============================================
  1966. if( !m_fInit )
  1967. {
  1968. AddToQuery(pQueryAddOn);
  1969. }
  1970. AddToQuery(L"\"");
  1971. AddToQuery(wcsTranslatedKey);
  1972. AddToQuery(L"\"");
  1973. m_fInit = FALSE;
  1974. }
  1975. }
  1976. /////////////////////////////////////////////////////////////////////
  1977. void CNamespaceManagement::SaveCurrentQuery()
  1978. {
  1979. m_nSavedSize = m_nSize;
  1980. m_fSavedInit = m_fInit;
  1981. if( SUCCEEDED(AllocMemory(m_pwcsSavedQuery))){
  1982. memcpy(m_pwcsSavedQuery,m_pwcsQuery,m_nSize);
  1983. }
  1984. SAFE_DELETE_ARRAY(m_pwcsQuery);
  1985. }
  1986. /////////////////////////////////////////////////////////////////////
  1987. void CNamespaceManagement::RestoreQuery()
  1988. {
  1989. SAFE_DELETE_ARRAY(m_pwcsQuery);
  1990. m_nSize = m_nSavedSize;
  1991. m_fInit = m_fSavedInit;
  1992. if( SUCCEEDED(AllocMemory(m_pwcsQuery))){
  1993. memcpy(m_pwcsQuery, m_pwcsSavedQuery,m_nSize);
  1994. }
  1995. m_fSavedInit = 0;
  1996. m_nSavedSize = 0;
  1997. SAFE_DELETE_ARRAY(m_pwcsSavedQuery);
  1998. }
  1999. /////////////////////////////////////////////////////////////////////
  2000. void CNamespaceManagement::UpdateQuery( WCHAR * pQueryAddOn, ULONG lLong )
  2001. {
  2002. CAutoWChar wcsBuf(MAX_PATH);
  2003. if( wcsBuf.Valid() )
  2004. {
  2005. AddToQuery(pQueryAddOn);
  2006. swprintf(wcsBuf,L"%lu",lLong);
  2007. AddToQuery(wcsBuf);
  2008. m_fInit = FALSE;
  2009. }
  2010. }
  2011. /////////////////////////////////////////////////////////////////////
  2012. HRESULT CNamespaceManagement::DeleteUnusedClassAndDriverInfo(BOOL fDeleteOldClass, WCHAR * wcsPath, WCHAR * wcsClass)
  2013. {
  2014. HRESULT hr = WBEM_NO_ERROR;
  2015. if( fDeleteOldClass )
  2016. {
  2017. CBSTR bstr(wcsClass );
  2018. hr = SERVICES_PTR->DeleteClass(bstr,WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
  2019. if( hr != WBEM_NO_ERROR )
  2020. {
  2021. if( WBEM_E_NOT_FOUND != hr )
  2022. {
  2023. ERRORTRACE((THISPROVIDER,"Tried to delete class but couldn't, return code: %ld for class: \n",hr));
  2024. TranslateAndLog(wcsClass);
  2025. }
  2026. else
  2027. {
  2028. hr = WBEM_NO_ERROR;
  2029. }
  2030. }
  2031. }
  2032. if( WBEM_NO_ERROR == hr )
  2033. {
  2034. // Ok, we may or may have not deleted the class, if it was tied to a different driver, we
  2035. // shouldn't have deleted the class, but we want to delete the controlling instance, as
  2036. // that driver is no longer there.
  2037. hr = SERVICES_PTR->DeleteInstance(wcsPath,WBEM_FLAG_OWNER_UPDATE,CONTEXT_PTR,NULL);
  2038. if( WBEM_NO_ERROR != hr )
  2039. {
  2040. if( hr != WBEM_E_NOT_FOUND )
  2041. {
  2042. ERRORTRACE((THISPROVIDER,"DeleteUnUnsedClasses Stranded instance: \n"));
  2043. TranslateAndLog(wcsPath);
  2044. ERRORTRACE((THISPROVIDER,"DeleteInstance return value: %ld\n",hr));
  2045. }
  2046. }
  2047. }
  2048. return hr;
  2049. }