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.

2480 lines
82 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  4. //
  5. //***************************************************************************
  6. #include "precomp.h"
  7. #include "wmicom.h"
  8. #include "wmimof.h"
  9. #include "wmimap.h"
  10. #include <stdlib.h>
  11. #include <winerror.h>
  12. #include <crc32.h>
  13. #include <align.h>
  14. #define NO_DATA_AVAILABLE 2
  15. #define WMI_INVALID_HIPERFPROP 3
  16. #define OffsetToPtr(Base, Offset) ((PBYTE)((PBYTE)Base + Offset))
  17. ////////////////////////////////////////////////////////////////////////////////////////////////
  18. void WINAPI EventCallbackRoutine(PWNODE_HEADER WnodeHeader, ULONG_PTR Context);
  19. #define WMIINTERFACE m_Class->GetWMIManagementPtr()
  20. ////////////////////////////////////////////////////////////////////////////////////////////////
  21. //=============================================================
  22. BOOL CWMIManagement::CancelWMIEventRegistration( GUID gGuid , ULONG_PTR uContext )
  23. {
  24. BOOL fRc = FALSE;
  25. try
  26. {
  27. if( ERROR_SUCCESS == WmiNotificationRegistration(&gGuid, FALSE,EventCallbackRoutine,uContext, NOTIFICATION_CALLBACK_DIRECT))
  28. {
  29. fRc = TRUE;
  30. }
  31. }
  32. catch(...)
  33. {
  34. // don't throw
  35. }
  36. return fRc;
  37. }
  38. //**********************************************************************************************
  39. // WMI Data block
  40. //**********************************************************************************************
  41. ////////////////////////////////////////////////////////////////////////////////////////////////
  42. void CWMIDataBlock::DumpAllWnode()
  43. {
  44. //=========================================
  45. // Dump Wnode All Node info
  46. //=========================================
  47. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  48. DEBUGTRACE((THISPROVIDER,"WNODE_ALL_DATA 0x%x\n",m_pAllWnode));
  49. DEBUGTRACE((THISPROVIDER," DataBlockOffset..............%x\n",m_pAllWnode->DataBlockOffset));
  50. DEBUGTRACE((THISPROVIDER," InstanceCount................%x\n",m_pAllWnode->InstanceCount));
  51. DEBUGTRACE((THISPROVIDER," OffsetInstanceNameOffsets....%x\n",m_pAllWnode->OffsetInstanceNameOffsets));
  52. if( m_fFixedInstance ){
  53. DEBUGTRACE((THISPROVIDER," FixedInstanceSize....%x\n",m_pAllWnode->FixedInstanceSize));
  54. }
  55. else{
  56. DEBUGTRACE((THISPROVIDER," OffsetInstanceData....%x\n",m_pAllWnode->OffsetInstanceDataAndLength[0].OffsetInstanceData));
  57. DEBUGTRACE((THISPROVIDER," LengthInstanceData....%x\n",m_pAllWnode->OffsetInstanceDataAndLength[0].LengthInstanceData));
  58. }
  59. }
  60. ////////////////////////////////////////////////////////////////////////////////////////////////
  61. void CWMIDataBlock::DumpSingleWnode()
  62. {
  63. //=========================================
  64. // Dump Wnode Single Node info
  65. //=========================================
  66. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  67. DEBUGTRACE((THISPROVIDER,"WNODE_SINGLE_INSTANCE 0x%x\n",m_pSingleWnode));
  68. DEBUGTRACE((THISPROVIDER," OffsetInstanceName....0x%x\n",m_pSingleWnode->OffsetInstanceName));
  69. DEBUGTRACE((THISPROVIDER," InstanceIndex.........0x%x\n",m_pSingleWnode->InstanceIndex));
  70. DEBUGTRACE((THISPROVIDER," DataBlockOffset.......0x%x\n",m_pSingleWnode->DataBlockOffset));
  71. DEBUGTRACE((THISPROVIDER," SizeDataBlock.........0x%x\n",m_pSingleWnode->SizeDataBlock));
  72. DEBUGTRACE((THISPROVIDER,"***************************************\n"));
  73. }
  74. ////////////////////////////////////////////////////////////////////////////////////////////////
  75. void CWMIDataBlock::DumpWnodeMsg(char * wcsMsg)
  76. {
  77. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  78. ERRORTRACE((THISPROVIDER,"%s\n",wcsMsg));
  79. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  80. }
  81. ////////////////////////////////////////////////////////////////////////////////////////////////
  82. HRESULT CWMIDataBlock::DumpWnodeInfo(char * wcsMsg)
  83. {
  84. HRESULT hr = WBEM_E_UNEXPECTED;
  85. //=========================================
  86. // Dump Wnode header info first
  87. //=========================================
  88. // WNODE definition
  89. if( m_pHeaderWnode )
  90. {
  91. if( !IsBadReadPtr( m_pHeaderWnode, m_pHeaderWnode->BufferSize))
  92. {
  93. DumpWnodeMsg(wcsMsg);
  94. if ( LoggingLevelEnabled ( 1 ) )
  95. {
  96. ERRORTRACE((THISPROVIDER,"*******************************************\n"));
  97. ERRORTRACE((THISPROVIDER,"Enable verbose logging for more information\n"));
  98. ERRORTRACE((THISPROVIDER,"*******************************************\n"));
  99. }
  100. DEBUGTRACE((THISPROVIDER,"WNODE_HEADER 0x%x\n",m_pHeaderWnode));
  101. DEBUGTRACE((THISPROVIDER," BufferSize........0x%x\n",m_pHeaderWnode->BufferSize));
  102. DEBUGTRACE((THISPROVIDER," ProviderId........0x%x\n",m_pHeaderWnode->ProviderId));
  103. DEBUGTRACE((THISPROVIDER," Version...........0x%x\n",m_pHeaderWnode->Version));
  104. if( m_pHeaderWnode->Linkage != 0 ){
  105. DEBUGTRACE((THISPROVIDER," Linkage...........%x\n",m_pHeaderWnode->Linkage));
  106. }
  107. DEBUGTRACE((THISPROVIDER," TimeStamp:LowPart.0x%x\n",m_pHeaderWnode->TimeStamp.LowPart));
  108. DEBUGTRACE((THISPROVIDER," TimeStamp:HiPart..0x%x\n",m_pHeaderWnode->TimeStamp.HighPart));
  109. WCHAR * pwcsGuid=NULL;
  110. if( S_OK == StringFromCLSID(m_pHeaderWnode->Guid,&pwcsGuid )){
  111. DEBUGTRACE((THISPROVIDER," Guid.............."));
  112. TranslateAndLog(pwcsGuid, TRUE);
  113. DEBUGTRACE((THISPROVIDER,"\n"));
  114. CoTaskMemFree(pwcsGuid);
  115. }
  116. DEBUGTRACE((THISPROVIDER," Flags.............0x%x\n",m_pHeaderWnode->Flags));
  117. //==================================================================
  118. // Now that we printed the header, we should print out the node
  119. // either single or all
  120. //==================================================================
  121. if( m_pSingleWnode ){
  122. DumpSingleWnode();
  123. }
  124. if( m_pAllWnode ){
  125. DumpAllWnode();
  126. }
  127. //==================================================================
  128. // Now, dump the memory
  129. //==================================================================
  130. DWORD dwCount;
  131. if( IsBadReadPtr( m_pHeaderWnode, m_pHeaderWnode->BufferSize) == 0 )
  132. {
  133. BYTE * pbBuffer = NULL;
  134. BYTE b1,b2,b3,b4,b5,b6,b7,b8,b9,b10;
  135. dwCount = m_pHeaderWnode->BufferSize;
  136. pbBuffer = new BYTE[dwCount+256];
  137. if( pbBuffer )
  138. {
  139. BYTE bDump[12];
  140. DEBUGTRACE((THISPROVIDER,"Writing out buffer, total size to write: %ld\n", dwCount ));
  141. memset(pbBuffer,NULL,dwCount+256);
  142. memcpy(pbBuffer,(BYTE*)m_pHeaderWnode,dwCount);
  143. BYTE * pTmp = pbBuffer;
  144. for( DWORD i = 0; i < dwCount; i +=10)
  145. {
  146. memset(bDump, NULL, 12 );
  147. memcpy(bDump, pTmp, 10);
  148. DEBUGTRACE((THISPROVIDER," %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \n",bDump[0],bDump[1],bDump[2],bDump[3],bDump[4],bDump[5],bDump[6],bDump[7],bDump[8],bDump[9]));
  149. pTmp+=10;
  150. }
  151. SAFE_DELETE_ARRAY(pbBuffer);
  152. }
  153. }
  154. }
  155. }
  156. return hr;
  157. }
  158. ////////////////////////////////////////////////////////////////////////////////////////////////
  159. HRESULT CWMIDataBlock::MapReturnCode(ULONG uRc)
  160. {
  161. if( uRc != 0 )
  162. {
  163. ERRORTRACE((THISPROVIDER,"WDM call returned error: %lu\n", uRc));
  164. }
  165. StringCchPrintfW ( m_wcsMsg, MSG_SIZE, L"WDM specific return code: %lu\n",uRc );
  166. switch(uRc){
  167. case ERROR_WMI_GUID_NOT_FOUND:
  168. return WBEM_E_NOT_SUPPORTED;
  169. break;
  170. case S_OK:
  171. return S_OK;
  172. case ERROR_NOT_SUPPORTED:
  173. case ERROR_INVALID_FUNCTION:
  174. return WBEM_E_NOT_SUPPORTED;
  175. case ERROR_WMI_SERVER_UNAVAILABLE:
  176. return WBEM_E_NOT_SUPPORTED;
  177. case NO_DATA_AVAILABLE:
  178. return S_OK;
  179. case ERROR_INVALID_HANDLE:
  180. return WBEM_E_NOT_AVAILABLE;
  181. case ERROR_WMI_DP_FAILED:
  182. StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_DRIVER_ERROR );
  183. DumpWnodeInfo(ANSI_MSG_DRIVER_ERROR);
  184. return WBEM_E_INVALID_OPERATION;
  185. case ERROR_WMI_READ_ONLY:
  186. StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_READONLY_ERROR );
  187. return WBEM_E_READ_ONLY;
  188. case ERROR_INVALID_PARAMETER:
  189. DumpWnodeInfo(ANSI_MSG_INVALID_PARAMETER);
  190. return WBEM_E_INVALID_PARAMETER;
  191. case ERROR_INVALID_DATA:
  192. StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_ARRAY_ERROR );
  193. DumpWnodeInfo(ANSI_MSG_INVALID_DATA);
  194. return WBEM_E_INVALID_PARAMETER;
  195. case ERROR_WMI_GUID_DISCONNECTED:
  196. StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_DATA_NOT_AVAILABLE );
  197. return WBEM_E_NOT_SUPPORTED;
  198. case ERROR_ACCESS_DENIED:
  199. case ERROR_INVALID_PRIMARY_GROUP:
  200. case ERROR_INVALID_OWNER:
  201. DumpWnodeInfo(ANSI_MSG_ACCESS_DENIED);
  202. return WBEM_E_ACCESS_DENIED;
  203. case ERROR_WMI_INSTANCE_NOT_FOUND:
  204. StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_DATA_INSTANCE_NOT_FOUND );
  205. DumpWnodeMsg(ANSI_MSG_DATA_INSTANCE_NOT_FOUND);
  206. return WBEM_E_NOT_SUPPORTED;
  207. }
  208. return WBEM_E_FAILED;
  209. }
  210. //******************************************************************
  211. ////////////////////////////////////////////////////////////////////
  212. // CWMIDataBlock
  213. ////////////////////////////////////////////////////////////////////
  214. //******************************************************************
  215. ////////////////////////////////////////////////////////////////////
  216. //******************************************************************
  217. //
  218. // WMIDataBlock handles the reading and writing of a WMI Data
  219. // block.
  220. //
  221. //******************************************************************
  222. ////////////////////////////////////////////////////////////////////
  223. ////////////////////////////////////////////////////////////////////
  224. CWMIDataBlock::CWMIDataBlock()
  225. {
  226. m_hCurrentWMIHandle = NULL;
  227. InitMemberVars();
  228. memset(m_wcsMsg,NULL,MSG_SIZE);
  229. }
  230. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  231. CWMIDataBlock::~CWMIDataBlock()
  232. {
  233. if( m_fCloseHandle )
  234. {
  235. if( m_hCurrentWMIHandle )
  236. {
  237. try
  238. {
  239. WmiCloseBlock(m_hCurrentWMIHandle);
  240. }
  241. catch(...){
  242. // don't throw
  243. }
  244. }
  245. }
  246. ResetDataBuffer();
  247. InitMemberVars();
  248. }
  249. ////////////////////////////////////////////////////////////////////
  250. void CWMIDataBlock::InitMemberVars()
  251. {
  252. m_fUpdateNamespace = TRUE;
  253. m_fMofHasChanged = FALSE;
  254. m_uDesiredAccess = 0;
  255. m_dwDataBufferSize = 0;
  256. m_pbDataBuffer= NULL;
  257. m_fMore = 0L;
  258. //=======================================
  259. // ptrs
  260. //=======================================
  261. m_pHeaderWnode = NULL;
  262. m_pSingleWnode = NULL;
  263. m_pAllWnode = NULL;
  264. m_dwAccumulativeSizeOfBlock = 0L;
  265. m_dwCurrentAllocSize = 0L;
  266. m_uInstanceSize = 0L;
  267. }
  268. //====================================================================
  269. HRESULT CWMIDataBlock::OpenWMIForBinaryMofGuid()
  270. {
  271. int nRc = 0;
  272. HRESULT hr = WBEM_E_FAILED;
  273. m_fCloseHandle = TRUE;
  274. try
  275. {
  276. hr = m_Class->GetGuid();
  277. if( S_OK == hr )
  278. {
  279. nRc = WmiOpenBlock(m_Class->GuidPtr(),m_uDesiredAccess, &m_hCurrentWMIHandle);
  280. if( nRc == ERROR_SUCCESS )
  281. {
  282. hr = S_OK;
  283. }
  284. }
  285. }
  286. catch(...)
  287. {
  288. hr = WBEM_E_UNEXPECTED;
  289. // don't throw
  290. }
  291. return hr;
  292. }
  293. //====================================================================
  294. int CWMIDataBlock::AssignNewHandleAndKeepItIfWMITellsUsTo()
  295. {
  296. int nRc = 0;
  297. try
  298. {
  299. nRc = WmiOpenBlock(m_Class->GuidPtr(),m_uDesiredAccess, &m_hCurrentWMIHandle);
  300. //===========================================================
  301. // Now that we opened the block successfully, check to see
  302. // if we need to keep this guy open or not, if we do
  303. // then add it to our list, otherwise don't
  304. //===========================================================
  305. if( nRc == ERROR_SUCCESS )
  306. {
  307. //=======================================================
  308. // Call WMI function here to see if we should save or
  309. // not
  310. //=======================================================
  311. WMIGUIDINFORMATION GuidInfo;
  312. GuidInfo.Size = sizeof(WMIGUIDINFORMATION);
  313. if( ERROR_SUCCESS == WmiQueryGuidInformation(m_hCurrentWMIHandle,&GuidInfo))
  314. {
  315. if(GuidInfo.IsExpensive)
  316. {
  317. if( m_fUpdateNamespace )
  318. {
  319. //================================================
  320. // Add it to our list of handles to keep
  321. //================================================
  322. m_fCloseHandle = FALSE;
  323. WMIINTERFACE->HandleMap()->Add(*(m_Class->GuidPtr()),m_hCurrentWMIHandle,m_uDesiredAccess);
  324. }
  325. }
  326. }
  327. }
  328. }
  329. catch(...)
  330. {
  331. nRc = E_UNEXPECTED;
  332. // don't throw
  333. }
  334. return nRc;
  335. }
  336. //====================================================================
  337. HRESULT CWMIDataBlock::OpenWMI()
  338. {
  339. int nRc;
  340. HRESULT hr = WBEM_E_FAILED;
  341. //=======================================================
  342. // Ok, we only want to keep the handles that are flagged
  343. // by WMI to be kept, otherwise, we just open the handle
  344. // and then close it. Because of this, we need to
  345. // check first and see if the Guid we are going after
  346. // already has a handle open, if it does, use it
  347. //=======================================================
  348. if( m_fUpdateNamespace )
  349. {
  350. CAutoBlock(WMIINTERFACE->HandleMap()->GetCriticalSection());
  351. nRc = WMIINTERFACE->HandleMap()->ExistingHandleAlreadyExistsForThisGuidUseIt( *(m_Class->GuidPtr()), m_hCurrentWMIHandle, m_fCloseHandle ,m_uDesiredAccess);
  352. if( nRc != ERROR_SUCCESS)
  353. {
  354. nRc = AssignNewHandleAndKeepItIfWMITellsUsTo();
  355. }
  356. }
  357. else
  358. {
  359. nRc = AssignNewHandleAndKeepItIfWMITellsUsTo();
  360. }
  361. hr = MapReturnCode(nRc);
  362. return hr;
  363. }
  364. ////////////////////////////////////////////////////////////////////
  365. HRESULT CWMIDataBlock::ProcessDataBlock()
  366. {
  367. HRESULT hr = S_OK;
  368. //================================================================
  369. // Data blocks can either be of fixed instance size or dynamic
  370. // instance size, call this function so we can determine what
  371. // type of data ptr we are working with
  372. // If there are no more, then break. Otherwise, we know
  373. // we are processing at least one instance
  374. //============================================================
  375. ULONG *pMaxPtrTmp = m_pMaxPtr;
  376. if( NoMore != AdjustDataBlockPtr(hr)){
  377. hr = FillOutProperties();
  378. }
  379. m_pMaxPtr = pMaxPtrTmp;
  380. //====================================================================
  381. // If we didn't succeed in processing these blocks, write it out
  382. // If invalid datablock is from Hi-Perf provider, don't log the data
  383. // to the file as this could be because of Embededclass or array
  384. // properties in the class
  385. //====================================================================
  386. if(hr == WMI_INVALID_HIPERFPROP)
  387. {
  388. hr = WBEM_E_FAILED;
  389. }
  390. else
  391. if( hr != S_OK )
  392. {
  393. DumpWnodeInfo(ANSI_MSG_INVALID_DATA_BLOCK);
  394. }
  395. return hr;
  396. }
  397. ////////////////////////////////////////////////////////////////////
  398. int CWMIDataBlock::AdjustDataBlockPtr(HRESULT & hr)
  399. {
  400. int nType = NoMore;
  401. //================================================================
  402. // Get pointer to the data offsets
  403. //================================================================
  404. // INSTANCES ARE ALWAYS ALIGNED ON 8 bytes
  405. if( m_fFixedInstance )
  406. {
  407. //========================================================
  408. // If WNODE_FLAG_FIXED_INSTANCE_SIZE is set in Flags then
  409. // FixedInstanceSize specifies the size of each data block.
  410. //========================================================
  411. // traverse all instances of requested class
  412. //========================================================
  413. if( m_nCurrentInstance == 1 )
  414. {
  415. m_pbWorkingDataPtr = m_pbCurrentDataPtr;
  416. }
  417. else
  418. {
  419. if( m_dwAccumulativeSizeOfBlock < m_pAllWnode->FixedInstanceSize )
  420. {
  421. m_pbWorkingDataPtr += m_pAllWnode->FixedInstanceSize - m_dwAccumulativeSizeOfBlock ;
  422. m_dwAccumulativeSizeOfBlock += m_pAllWnode->FixedInstanceSize - m_dwAccumulativeSizeOfBlock;
  423. }
  424. //=============================================================================
  425. // make sure we adjust for the fixed instance size, then make sure that it is
  426. // on an 8 byte boundary.
  427. // otherwise, we are going to calculate where it should go next
  428. //=============================================================================
  429. DWORD dwBytesToPad = 0 ;
  430. DWORD dwReminder = m_dwAccumulativeSizeOfBlock % 8 ;
  431. if ( 0 < dwReminder )
  432. {
  433. dwBytesToPad = 8 - dwReminder ;
  434. }
  435. if ( 0 < dwBytesToPad )
  436. {
  437. AddPadding ( dwBytesToPad ) ;
  438. m_dwAccumulativeSizeOfBlock += dwBytesToPad ;
  439. }
  440. //
  441. // just get maximum ptr where returned data are
  442. //
  443. m_pMaxPtr = (ULONG *)OffsetToPtr(m_pbWorkingDataPtr, m_pAllWnode->FixedInstanceSize);
  444. }
  445. nType = ProcessOneFixedInstance;
  446. }
  447. else
  448. {
  449. m_dwAccumulativeSizeOfBlock = 0L;
  450. //====================================================
  451. //
  452. // If WMI_FLAG_FIXED_DATA_SIZE is not set then
  453. // OffsetInstanceData data is an array of ULONGS that
  454. // specifies the offsets to the data blocks for each
  455. // instance. In this case there is an array of
  456. // InstanceCount ULONGs followed by the data blocks.
  457. //
  458. // struct {
  459. // ULONG OffsetInstanceData;
  460. // ULONG LengthInstanceData;
  461. // } OffsetInstanceDataAndLength[]; /* [InstanceCount] */
  462. //====================================================
  463. ULONG uOffset;
  464. memcpy( &uOffset, m_pbCurrentDataPtr, sizeof(ULONG) );
  465. if( uOffset == 0 )
  466. {
  467. nType = NoMore;
  468. hr = S_OK;
  469. }
  470. else
  471. {
  472. m_pbCurrentDataPtr += sizeof( ULONG );
  473. memcpy( &m_uInstanceSize, m_pbCurrentDataPtr, sizeof(ULONG) );
  474. m_pbCurrentDataPtr += sizeof( ULONG );
  475. m_pbWorkingDataPtr =(BYTE*) (ULONG *)OffsetToPtr(m_pAllWnode, uOffset);
  476. nType = ProcessUnfixedInstance;
  477. m_pMaxPtr = (ULONG *)OffsetToPtr(m_pbWorkingDataPtr, m_uInstanceSize);
  478. }
  479. }
  480. return nType;
  481. }
  482. /////////////////////////////////////////////////////////////////////////
  483. HRESULT CWMIDataBlock::ProcessNameBlock(BOOL fSetName)
  484. {
  485. HRESULT hr = WBEM_E_FAILED;
  486. WCHAR wName[NAME_SIZE+2];
  487. SHORT NameLen = 0;
  488. BYTE *pbData;
  489. ULONG * upNameOffset = NULL;
  490. memset(wName,NULL,NAME_SIZE+2);
  491. //=====================================================
  492. // Either the m_pAllWnode or m_pSingleNode is Null,
  493. // which ever isn't, is the type we are working with
  494. //=====================================================
  495. if( m_pAllWnode ){
  496. if( IsBadReadPtr( m_upNameOffsets, sizeof( ULONG *)) == 0 ){
  497. upNameOffset = ((ULONG *)OffsetToPtr(m_pAllWnode, *m_upNameOffsets));
  498. }
  499. }
  500. else{
  501. upNameOffset = m_upNameOffsets;
  502. }
  503. hr = WBEM_E_INVALID_OBJECT;
  504. if( IsBadReadPtr( upNameOffset, sizeof( ULONG *)) == 0 ){
  505. if((ULONG *) (upNameOffset) < m_pMaxPtr ){
  506. //================================================================
  507. // Get pointer to the name offsets & point to next one
  508. //================================================================
  509. pbData = (LPBYTE)upNameOffset;
  510. if( PtrOk((ULONG*)pbData,(ULONG)0) ){
  511. if( pbData ){
  512. memcpy( &NameLen, pbData, sizeof(USHORT) );
  513. pbData += sizeof(USHORT);
  514. if( NameLen > 0 ){
  515. if( PtrOk((ULONG*)pbData,(ULONG)NameLen) ){
  516. memcpy(wName,pbData,NameLen);
  517. pbData+=NameLen;
  518. hr = m_Class->SetInstanceName(wName,fSetName);
  519. }
  520. }
  521. }
  522. }
  523. }
  524. }
  525. //====================================================================
  526. // If we didn't succeed in processing these blocks, write it out
  527. //====================================================================
  528. if( hr != S_OK ){
  529. DumpWnodeInfo(ANSI_MSG_INVALID_NAME_BLOCK);
  530. }
  531. return hr;
  532. }
  533. ////////////////////////////////////////////////////////////////////
  534. HRESULT CWMIDataBlock::ProcessBinaryMofDataBlock( CVARIANT & vResourceName,WCHAR * wcsTmp, int cchSize )
  535. {
  536. HRESULT hr = WBEM_E_FAILED;
  537. ULONG *pMaxPtrTmp = m_pMaxPtr;
  538. AdjustDataBlockPtr(hr);
  539. m_pMaxPtr = pMaxPtrTmp;
  540. CWMIBinMof bMof;
  541. hr = bMof.Initialize(WMIINTERFACE,m_fUpdateNamespace);
  542. if( S_OK == hr )
  543. {
  544. if ( SUCCEEDED ( hr = bMof.SetBinaryMofClassName(vResourceName.GetStr(),wcsTmp, cchSize) ) )
  545. {
  546. hr = bMof.ExtractBinaryMofFromDataBlock(m_pbWorkingDataPtr,m_uInstanceSize,wcsTmp, m_fMofHasChanged);
  547. if( hr != S_OK )
  548. {
  549. DumpWnodeInfo(ANSI_MSG_INVALID_DATA_BLOCK);
  550. }
  551. //===============================================
  552. // Get the next node name and data ptrs ready
  553. //===============================================
  554. if( m_pAllWnode )
  555. {
  556. GetNextNode();
  557. }
  558. m_nCurrentInstance++;
  559. }
  560. }
  561. return hr;
  562. }
  563. ////////////////////////////////////////////////////////////////////
  564. HRESULT CWMIDataBlock::AddBinaryMof(CVARIANT & vImagePath,CVARIANT & vResourceName)
  565. {
  566. HRESULT hr = WBEM_E_OUT_OF_MEMORY;
  567. CAutoWChar wcsTmp(MAX_PATH*2);
  568. if( wcsTmp.Valid() )
  569. {
  570. hr = WBEM_E_INVALID_OBJECT;
  571. //=================================================================
  572. // if we have an image path and resource path, then do the normal
  573. // thing
  574. //=================================================================
  575. if((vResourceName.GetType() != VT_NULL ) && ( vImagePath.GetType() != VT_NULL ))
  576. {
  577. //=============================================================
  578. // If this was a mof that was being added, then add it
  579. //=============================================================
  580. CWMIBinMof bMof;
  581. hr = bMof.Initialize(WMIINTERFACE,m_fUpdateNamespace);
  582. if( S_OK == hr )
  583. {
  584. bMof.ExtractBinaryMofFromFile(vImagePath.GetStr(),vResourceName.GetStr(),wcsTmp, MAX_PATH*2, m_fMofHasChanged);
  585. }
  586. }
  587. else if( vResourceName.GetType() != VT_NULL ){
  588. //=================================================================
  589. // if we have a resource to query for
  590. //=================================================================
  591. CProcessStandardDataBlock * pTmp = new CProcessStandardDataBlock();
  592. if( pTmp )
  593. {
  594. try
  595. {
  596. pTmp->UpdateNamespace(m_fUpdateNamespace);
  597. pTmp->SetClassProcessPtr(m_Class);
  598. hr = pTmp->OpenWMIForBinaryMofGuid();
  599. if( hr == S_OK )
  600. {
  601. hr = pTmp->QuerySingleInstance(vResourceName.GetStr());
  602. if( hr == S_OK )
  603. {
  604. hr = pTmp->ProcessBinaryMofDataBlock(vResourceName,wcsTmp, MAX_PATH*2);
  605. m_fMofHasChanged = pTmp->HasMofChanged();
  606. }
  607. else
  608. {
  609. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  610. ERRORTRACE((THISPROVIDER,"Instance failed for: "));
  611. TranslateAndLog(vResourceName.GetStr());
  612. ERRORTRACE((THISPROVIDER,"***************************************\n"));
  613. }
  614. }
  615. SAFE_DELETE_PTR(pTmp);
  616. }
  617. catch(...)
  618. {
  619. SAFE_DELETE_PTR(pTmp);
  620. hr = WBEM_E_UNEXPECTED;
  621. throw;
  622. }
  623. }
  624. }
  625. }
  626. return hr;
  627. }
  628. ////////////////////////////////////////////////////////////////////
  629. HRESULT CWMIDataBlock::ProcessBinaryMof()
  630. {
  631. //================================================================
  632. // The binary mof blocks are always going to be two strings,
  633. // 1). Image Path
  634. // 2). Mof resource name
  635. //
  636. // If the image path and resource name are both filled in, then
  637. // we need to go open the file and extract the binary mof as
  638. // usual.
  639. // If the Imagepath is empty, then the mof resource name is going
  640. // to contain the static instance name to query for, we then
  641. // process that.
  642. //================================================================
  643. CVARIANT vImagePath, vResourceName;
  644. CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
  645. m_dwAccumulativeSizeOfBlock = 0;
  646. HRESULT hr = MapWMIData.GetDataFromDataBlock(vImagePath,VT_BSTR,0);
  647. if( SUCCEEDED(hr) )
  648. {
  649. hr = MapWMIData.GetDataFromDataBlock(vResourceName,VT_BSTR,0);
  650. if( hr == S_OK )
  651. {
  652. if( m_Class->GetHardCodedGuidType() == MOF_ADDED )
  653. {
  654. hr = AddBinaryMof( vImagePath, vResourceName);
  655. }
  656. else
  657. {
  658. CWMIBinMof bMof;
  659. hr = bMof.Initialize(WMIINTERFACE,m_fUpdateNamespace);
  660. if( S_OK == hr )
  661. {
  662. hr = bMof.DeleteMofsFromEvent(vImagePath, vResourceName, m_fMofHasChanged);
  663. }
  664. }
  665. }
  666. }
  667. return hr;
  668. }
  669. ////////////////////////////////////////////////////////////////////
  670. BOOL CWMIDataBlock::ResetMissingQualifierValue(WCHAR * pwcsProperty, CVARIANT & vToken )
  671. {
  672. BOOL fRc = FALSE;
  673. CVARIANT vQual;
  674. CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
  675. //============================================================
  676. // We are only going to support this for numerical types
  677. //============================================================
  678. HRESULT hr = m_Class->GetQualifierValue(pwcsProperty, L"MissingValue", (CVARIANT*)&vQual);
  679. if( hr == S_OK ){
  680. if( vQual.GetType() != VT_EMPTY ){
  681. if( Map.SetDefaultMissingQualifierValue( vQual, m_Class->PropertyType(), vToken ) ){
  682. fRc = TRUE;
  683. }
  684. }
  685. }
  686. return fRc;
  687. }
  688. ////////////////////////////////////////////////////////////////////
  689. BOOL CWMIDataBlock::ResetMissingQualifierValue(WCHAR * pwcsProperty, SAFEARRAY *& pSafe)
  690. {
  691. BOOL fRc = FALSE;
  692. CVARIANT vQual;
  693. CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
  694. //============================================================
  695. // We are only going to support this for numerical types
  696. //============================================================
  697. HRESULT hr = m_Class->GetQualifierValue(pwcsProperty, L"MissingValue", (CVARIANT*)&vQual);
  698. if( hr == S_OK ){
  699. if( vQual.GetType() != VT_EMPTY )
  700. {
  701. SAFEARRAY * psa = V_ARRAY((VARIANT*)vQual);
  702. CSAFEARRAY Safe(psa);
  703. CVARIANT vElement;
  704. DWORD dwCount = Safe.GetNumElements();
  705. //============================================================
  706. // Now, process it
  707. //============================================================
  708. if( dwCount > 0 ){
  709. // Set each element of the array
  710. for (DWORD i = 0; i < dwCount; i++){
  711. if( S_OK == Safe.Get(i,&vElement) ){
  712. long lType = m_Class->PropertyType();
  713. if( Map.SetDefaultMissingQualifierValue( vQual, lType, vElement ) ){
  714. Map.PutInArray(pSafe,(long *)&i,lType,(VARIANT * )vElement);
  715. fRc = TRUE;
  716. }
  717. }
  718. }
  719. }
  720. Safe.Unbind();
  721. }
  722. }
  723. return fRc;
  724. }
  725. ////////////////////////////////////////////////////////////////////
  726. HRESULT CWMIDataBlock::RegisterWMIEvent( WCHAR * wcsGuid, ULONG_PTR uContext, CLSID & Guid, BOOL fRegistered)
  727. {
  728. ULONG Status;
  729. HRESULT hr = WBEM_E_UNEXPECTED;
  730. if( SetGuid(wcsGuid, Guid) ){
  731. try
  732. {
  733. if( !fRegistered )
  734. {
  735. Status = WmiNotificationRegistration(&Guid, TRUE, EventCallbackRoutine, uContext, NOTIFICATION_CALLBACK_DIRECT);
  736. }
  737. else
  738. {
  739. Status = WmiNotificationRegistration(&Guid, TRUE, EventCallbackRoutine, uContext, NOTIFICATION_CHECK_ACCESS );
  740. }
  741. hr = MapReturnCode(Status);
  742. }
  743. catch(...)
  744. {
  745. // don't throw
  746. }
  747. }
  748. else
  749. {
  750. Status = GetLastError();
  751. }
  752. if( hr != S_OK )
  753. {
  754. ERRORTRACE((THISPROVIDER,"WmiNotificationRegistration failed ...%ld\n",Status));
  755. }
  756. return hr;
  757. }
  758. //=============================================================
  759. void CWMIDataBlock::GetNextNode()
  760. {
  761. BOOL fRc = FALSE;
  762. //============================================================================================
  763. // If we still have more instances to get, then get them
  764. //============================================================================================
  765. if( m_nCurrentInstance < m_nTotalInstances ){
  766. m_upNameOffsets++;
  767. fRc = TRUE;
  768. }
  769. else{
  770. //========================================================================================
  771. // Otherwise, lets see if we have another NODE to get, if not, then we are done.
  772. //========================================================================================
  773. if (m_pAllWnode->WnodeHeader.Linkage != 0){
  774. m_pAllWnode = (PWNODE_ALL_DATA)OffsetToPtr(m_pAllWnode, m_pAllWnode->WnodeHeader.Linkage);
  775. m_pHeaderWnode = &(m_pAllWnode->WnodeHeader);
  776. m_nTotalInstances = m_pAllWnode->InstanceCount;
  777. m_nCurrentInstance = 0;
  778. m_upNameOffsets = (ULONG *)OffsetToPtr(m_pAllWnode, m_pAllWnode->OffsetInstanceNameOffsets);
  779. if( ParseHeader() ){
  780. fRc = InitializeDataPtr();
  781. }
  782. fRc = TRUE;
  783. }
  784. }
  785. m_fMore = fRc;
  786. }
  787. ////////////////////////////////////////////////////////////////////////
  788. HRESULT CWMIDataBlock::ReadWMIDataBlockAndPutIntoWbemInstance()
  789. {
  790. //===============================================
  791. // Read the data and name blocks
  792. //===============================================
  793. HRESULT hr = ProcessDataBlock();
  794. if( hr == S_OK ){
  795. //=======================================================
  796. // if this isn't a binary mof to process, then we will
  797. // process the name block, otherwise we will return
  798. // as binary mofs do not have any more useful info in
  799. // them in the name block - we already have what we need
  800. // from the data block ( at this present time anyway...)
  801. //=======================================================
  802. if( !m_Class->GetHardCodedGuidType() ){
  803. hr = ProcessNameBlock(TRUE);
  804. if( hr == S_OK ){
  805. //===============================================
  806. // Get the next node name and data ptrs ready
  807. //===============================================
  808. if( m_pAllWnode ){
  809. GetNextNode();
  810. }
  811. m_nCurrentInstance++;
  812. }
  813. }
  814. }
  815. return hr;
  816. }
  817. //=============================================================
  818. HRESULT CWMIDataBlock::ReAllocateBuffer(DWORD dwAddOn)
  819. {
  820. HRESULT hr = WBEM_E_FAILED;
  821. m_dwCurrentAllocSize += MEMSIZETOALLOCATE * ((dwAddOn / MEMSIZETOALLOCATE) +1);
  822. // save the old buffer ptr
  823. BYTE * pOld = m_pbDataBuffer;
  824. if( pOld ){
  825. // save the location of where we are
  826. ULONG_PTR dwHowmany;
  827. dwHowmany = (ULONG_PTR)m_pbWorkingDataPtr - (ULONG_PTR)m_pbDataBuffer;
  828. // get the new buffer
  829. m_pbDataBuffer = new BYTE[m_dwCurrentAllocSize+1];
  830. if( m_pbDataBuffer )
  831. {
  832. // copy what we have so far
  833. memcpy(m_pbDataBuffer,pOld,dwHowmany);
  834. // Set the working ptr to the current place
  835. m_pbWorkingDataPtr = m_pbDataBuffer;
  836. m_pbWorkingDataPtr += dwHowmany;
  837. // delete the old buffer
  838. SAFE_DELETE_ARRAY(pOld);
  839. hr = S_OK;
  840. }
  841. else
  842. {
  843. m_dwCurrentAllocSize -= MEMSIZETOALLOCATE * ((dwAddOn / MEMSIZETOALLOCATE) +1);
  844. m_pbDataBuffer = pOld;
  845. }
  846. }
  847. return hr;
  848. }
  849. //=============================================================
  850. HRESULT CWMIDataBlock::AllocateBuffer(DWORD dwSize)
  851. {
  852. HRESULT hr = WBEM_E_FAILED;
  853. m_pbDataBuffer = new byte[dwSize+2];
  854. if( m_pbDataBuffer )
  855. {
  856. hr = S_OK;
  857. }
  858. return hr;
  859. }
  860. //=============================================================
  861. void CWMIDataBlock::ResetDataBuffer()
  862. {
  863. if(m_dwCurrentAllocSize)
  864. {
  865. m_dwDataBufferSize = 0;
  866. m_dwCurrentAllocSize = 0;
  867. SAFE_DELETE_ARRAY(m_pbDataBuffer);
  868. }
  869. }
  870. //=============================================================
  871. HRESULT CWMIDataBlock::SetAllInstancePtr( PWNODE_ALL_DATA pwAllNode )
  872. {
  873. m_pbDataBuffer = (BYTE*)pwAllNode;
  874. return(SetAllInstanceInfo());
  875. }
  876. //=============================================================
  877. HRESULT CWMIDataBlock::SetSingleInstancePtr( PWNODE_SINGLE_INSTANCE pwSingleNode )
  878. {
  879. m_pbDataBuffer = (BYTE*)pwSingleNode;
  880. return(SetSingleInstanceInfo());
  881. }
  882. //=============================================================
  883. HRESULT CWMIDataBlock::SetAllInstanceInfo()
  884. {
  885. HRESULT hr = WBEM_E_INVALID_OBJECT;
  886. if( m_pbDataBuffer ){
  887. m_pAllWnode = (PWNODE_ALL_DATA)m_pbDataBuffer;
  888. m_upNameOffsets = (ULONG *)OffsetToPtr(m_pAllWnode, m_pAllWnode->OffsetInstanceNameOffsets);
  889. m_nCurrentInstance = 1;
  890. m_nTotalInstances = m_pAllWnode->InstanceCount;
  891. m_pHeaderWnode = &(m_pAllWnode->WnodeHeader);
  892. m_pSingleWnode = NULL;
  893. if( m_nTotalInstances > 0 ){
  894. if( ParseHeader() ){
  895. if( InitializeDataPtr()){
  896. hr = S_OK;
  897. }
  898. }
  899. }
  900. else{
  901. hr = WBEM_S_NO_MORE_DATA;
  902. }
  903. }
  904. return hr;
  905. }
  906. //=============================================================
  907. HRESULT CWMIDataBlock::SetSingleInstanceInfo()
  908. {
  909. HRESULT hr = WBEM_E_INVALID_OBJECT;
  910. if( m_pbDataBuffer ){
  911. m_pSingleWnode = (PWNODE_SINGLE_INSTANCE)m_pbDataBuffer;
  912. m_upNameOffsets = (ULONG *)OffsetToPtr(m_pSingleWnode, m_pSingleWnode->OffsetInstanceName);
  913. m_nCurrentInstance = 1;
  914. m_nTotalInstances = 1;
  915. m_pAllWnode = NULL;
  916. m_pHeaderWnode = &(m_pSingleWnode->WnodeHeader);
  917. if( ParseHeader() ){
  918. if( InitializeDataPtr()){
  919. hr = S_OK;
  920. }
  921. }
  922. }
  923. return hr;
  924. }
  925. //=============================================================
  926. BOOL CWMIDataBlock::InitializeDataPtr()
  927. {
  928. //=====================================================
  929. // Either the m_pAllWnode or m_pSingleNode is Null,
  930. // which ever isn't, is the type we are working with
  931. //=====================================================
  932. if(m_pAllWnode){
  933. if( m_fFixedInstance ){
  934. m_pbCurrentDataPtr =(BYTE*) (ULONG *)OffsetToPtr(m_pAllWnode, m_pAllWnode->DataBlockOffset);
  935. //==========================================================================================
  936. // for the case of binary mofs, we need to know the size of the instance to calculate the
  937. // crc, so we need to put the whole size of the fixed instance buffer.
  938. //==========================================================================================
  939. m_uInstanceSize = m_pAllWnode->FixedInstanceSize;
  940. }
  941. else{
  942. m_pbCurrentDataPtr =(BYTE*)(ULONG*) m_pAllWnode->OffsetInstanceDataAndLength;
  943. }
  944. m_pMaxPtr = (ULONG *)OffsetToPtr(m_pAllWnode, m_pHeaderWnode->BufferSize);
  945. }
  946. else{
  947. if( m_pSingleWnode ){
  948. m_fFixedInstance = TRUE;
  949. m_pbCurrentDataPtr = (BYTE*)(ULONG *)OffsetToPtr(m_pSingleWnode, m_pSingleWnode->DataBlockOffset);
  950. m_pMaxPtr = (ULONG *)OffsetToPtr(m_pSingleWnode, m_pHeaderWnode->BufferSize);
  951. //==========================================================================================
  952. // for the case of binary mofs, we need to know the size of the instance to calculate the
  953. // crc, so we need to put the whole size of the fixed instance buffer.
  954. //==========================================================================================
  955. m_uInstanceSize = m_pSingleWnode->SizeDataBlock;
  956. }
  957. }
  958. if( (ULONG*)m_pbCurrentDataPtr > (ULONG*) m_pMaxPtr ){
  959. return FALSE;
  960. }
  961. if( (ULONG*) m_pbCurrentDataPtr < (ULONG*) m_pAllWnode ){
  962. return FALSE;
  963. }
  964. return TRUE;
  965. }
  966. //=============================================================
  967. BOOL CWMIDataBlock::ParseHeader()
  968. {
  969. BOOL fRc;
  970. //====================================================
  971. // Check out class to see if it is valid first
  972. //====================================================
  973. if( !m_pHeaderWnode ){
  974. return FALSE;
  975. }
  976. m_ulVersion = m_pHeaderWnode->Version;
  977. if ((m_pHeaderWnode->BufferSize == 0)){
  978. fRc = FALSE;
  979. }
  980. else{
  981. if (m_pHeaderWnode->Flags & WNODE_FLAG_FIXED_INSTANCE_SIZE){
  982. m_fFixedInstance = TRUE;
  983. }
  984. else{
  985. m_fFixedInstance = FALSE;
  986. }
  987. fRc = TRUE;
  988. }
  989. return fRc;
  990. }
  991. ////////////////////////////////////////////////////////////////////////
  992. HRESULT CWMIDataBlock::WriteArrayTypes(WCHAR * pwcsProperty, CVARIANT & v)
  993. {
  994. LONG lType = 0;
  995. DWORD dwCount = 0;
  996. HRESULT hr = WBEM_E_INVALID_PARAMETER;
  997. CVARIANT vValue;
  998. BOOL fDynamic = FALSE;
  999. m_Class->GetSizeOfArray( lType,dwCount, fDynamic);
  1000. if( fDynamic && dwCount == 0 )
  1001. {
  1002. return WBEM_S_NO_ERROR;
  1003. }
  1004. //============================================================
  1005. // Make sure we get a valid ptr
  1006. //============================================================
  1007. VARIANT *p = (VARIANT *)v;
  1008. SAFEARRAY * psa = V_ARRAY(p);
  1009. if( IsBadReadPtr( psa, sizeof(SAFEARRAY) != 0)){
  1010. ERRORTRACE((THISPROVIDER,"*****************************************\n"));
  1011. ERRORTRACE((THISPROVIDER,"Class ... %S\n", m_Class->GetClassName()));
  1012. ERRORTRACE((THISPROVIDER,"Current property ... %S\n", pwcsProperty));
  1013. ERRORTRACE((THISPROVIDER,"\n"));
  1014. ERRORTRACE((THISPROVIDER,"array ptr ... %x\n", psa));
  1015. ERRORTRACE((THISPROVIDER,"*****************************************\n"));
  1016. return hr;
  1017. }
  1018. CSAFEARRAY Safe(psa);
  1019. //============================================================
  1020. // Make sure there is really what we expect in the array
  1021. // NOTE: The MAX represents the fixed size of the array,
  1022. // while if it is a dynamic array, the size is determined
  1023. // by the property listed in the WMIDATASIZE is property.
  1024. // either way, the size returned above is the size the
  1025. // array is supposed to be, if it isn't error out.
  1026. //============================================================
  1027. DWORD dwNumElements = Safe.GetNumElements();
  1028. if( dwNumElements != dwCount )
  1029. {
  1030. Safe.Unbind();
  1031. ERRORTRACE((THISPROVIDER,"*****************************************\n"));
  1032. ERRORTRACE((THISPROVIDER,"Class ... %S\n", m_Class->GetClassName()));
  1033. ERRORTRACE((THISPROVIDER,"Current property ... %S\n", pwcsProperty));
  1034. ERRORTRACE((THISPROVIDER,"\n"));
  1035. ERRORTRACE((THISPROVIDER,"Expected size ... %d\n", dwCount));
  1036. ERRORTRACE((THISPROVIDER,"Current size ... %d\n", dwNumElements));
  1037. ERRORTRACE((THISPROVIDER,"*****************************************"));
  1038. // Don't need to destroy, it will be destroyed
  1039. return WBEM_E_INVALID_PARAMETER;
  1040. }
  1041. //============================================================
  1042. // Set missing qualifier value to the value from the NULL
  1043. //============================================================
  1044. if( vValue.GetType() == VT_NULL ){
  1045. ResetMissingQualifierValue(pwcsProperty,psa);
  1046. }
  1047. // if the array is not array of embedded instances
  1048. // then check if the buffer allocated is enough
  1049. if(lType != VT_UNKNOWN)
  1050. {
  1051. // This function check if enought memory is allocated and if not
  1052. // allocates memory
  1053. if(S_OK != GetBufferReady ( m_Class->PropertySize() * ( dwCount + 1 ) ) )
  1054. {
  1055. return WBEM_E_FAILED;
  1056. }
  1057. }
  1058. //============================================================
  1059. // Now, process it
  1060. //============================================================
  1061. if( dwCount > 0 ){
  1062. // Set each element of the array
  1063. for (DWORD i = 0; i < dwCount; i++){
  1064. if( lType == VT_UNKNOWN ){
  1065. // embedded object
  1066. IUnknown * pUnk = NULL;
  1067. hr = Safe.Get(i, &pUnk);
  1068. if( pUnk ){
  1069. hr = WriteEmbeddedClass(pUnk,vValue);
  1070. }
  1071. else{
  1072. hr = WBEM_E_FAILED;
  1073. }
  1074. }
  1075. else{
  1076. CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
  1077. if(!MapWMIData.SetDataInDataBlock(&Safe,i,vValue,lType,m_Class->PropertySize()) ){
  1078. hr = WBEM_E_FAILED;
  1079. break;
  1080. }
  1081. else{
  1082. hr = S_OK;
  1083. }
  1084. }
  1085. if (WBEM_S_NO_ERROR != hr){
  1086. break;
  1087. }
  1088. }
  1089. }
  1090. Safe.Unbind();
  1091. // Don't need to destroy, it will be destroyed
  1092. return hr;
  1093. }
  1094. ////////////////////////////////////////////////////////////////////////
  1095. HRESULT CWMIDataBlock::ProcessArrayTypes(VARIANT & vToken,WCHAR * pwcsProperty)
  1096. {
  1097. LONG lConvertedType = 0, lType = 0;
  1098. DWORD dwCount = 0;
  1099. BOOL fDynamic = TRUE;
  1100. HRESULT hr = m_Class->GetSizeOfArray( lType,dwCount, fDynamic);
  1101. if( hr != S_OK ){
  1102. return hr;
  1103. }
  1104. if( dwCount > 0 )
  1105. {
  1106. CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
  1107. //======================================================
  1108. // Allocate array with the converted data type.
  1109. // WMI and CIM data types do not match, so use the
  1110. // mapping class to get the correct size of the target
  1111. // property for CIM
  1112. //======================================================
  1113. lConvertedType = MapWMIData.ConvertType(lType);
  1114. SAFEARRAY * psa = OMSSafeArrayCreate((unsigned short)lConvertedType,dwCount);
  1115. if(psa == NULL)
  1116. {
  1117. return WBEM_E_FAILED;
  1118. }
  1119. //=======================================================
  1120. // Now, get the MissingValue for each element of the
  1121. // array
  1122. //=======================================================
  1123. lConvertedType = lType;
  1124. BOOL fMissingValue = FALSE;
  1125. CVARIANT vQual;
  1126. SAFEARRAY * psaMissingValue = NULL;
  1127. long lMax = 0;
  1128. CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
  1129. hr = m_Class->GetQualifierValue( pwcsProperty, L"MissingValue", (CVARIANT *)&vQual );
  1130. if( hr == S_OK )
  1131. {
  1132. if( vQual.GetType() != VT_EMPTY )
  1133. {
  1134. if( vQual.GetType() & VT_ARRAY )
  1135. {
  1136. //============================================================
  1137. // Make sure we get a valid ptr
  1138. //============================================================
  1139. psaMissingValue = V_ARRAY((VARIANT*)&vQual);
  1140. fMissingValue = TRUE;
  1141. // Don't need to destroy, it will be destroyed in the deconstructor
  1142. }
  1143. }
  1144. }
  1145. CSAFEARRAY SafeMissingValue(psaMissingValue);
  1146. if( fMissingValue )
  1147. {
  1148. lMax = SafeMissingValue.GetNumElements();
  1149. }
  1150. for (long i = 0; i < (long)dwCount; i++)
  1151. {
  1152. CVARIANT v;
  1153. if( lType == VT_UNKNOWN )
  1154. {
  1155. // embedded object
  1156. hr = ProcessEmbeddedClass(v);
  1157. if( S_OK == hr )
  1158. {
  1159. MapWMIData.PutInArray(psa,(long *)&i,lConvertedType,(VARIANT * )v);
  1160. }
  1161. }
  1162. else
  1163. {
  1164. hr = MapWMIData.GetDataFromDataBlock(v,lType,m_Class->PropertySize());
  1165. if( hr != S_OK )
  1166. {
  1167. StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_INVALID_BLOCK_POINTER );
  1168. }
  1169. else
  1170. {
  1171. BOOL fPutProperty = TRUE;
  1172. if( fMissingValue )
  1173. {
  1174. if( i < lMax )
  1175. {
  1176. CVARIANT vElement;
  1177. if( Map.MissingQualifierValueMatches( &SafeMissingValue, i, vElement, v.GetType(), v ) )
  1178. {
  1179. fPutProperty = FALSE;
  1180. }
  1181. }
  1182. }
  1183. if( fPutProperty )
  1184. {
  1185. MapWMIData.PutInArray(psa,(long *)&i,lConvertedType,(VARIANT * )v);
  1186. }
  1187. }
  1188. }
  1189. if (WBEM_S_NO_ERROR != hr)
  1190. {
  1191. break;
  1192. }
  1193. }
  1194. SafeMissingValue.Unbind();
  1195. vToken.vt = (VARTYPE)(lConvertedType | CIM_FLAG_ARRAY);
  1196. vToken.parray = psa;
  1197. }
  1198. else{
  1199. hr = WBEM_S_NO_MORE_DATA;
  1200. }
  1201. return hr;
  1202. }
  1203. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1204. HRESULT CWMIDataBlock::ProcessEmbeddedClass(CVARIANT & v)
  1205. {
  1206. HRESULT hr = WBEM_E_FAILED;
  1207. CWMIProcessClass EmbeddedClass(0);
  1208. hr = EmbeddedClass.Initialize();
  1209. if( S_OK == hr )
  1210. {
  1211. hr = EmbeddedClass.InitializeEmbeddedClass(m_Class);
  1212. DWORD dwAccumulativeSize = 0;
  1213. CAutoChangePointer p(&m_Class,&EmbeddedClass);
  1214. if( hr == S_OK ){
  1215. //=============================================
  1216. // Align the embedded class properly
  1217. //=============================================
  1218. int nSize = 0L;
  1219. hr = EmbeddedClass.GetLargestDataTypeInClass(nSize);
  1220. // NTRaid:136388
  1221. // 07/12/00
  1222. if( hr == S_OK && nSize > 0){
  1223. CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
  1224. if( Map.NaturallyAlignData(nSize, READ_IT)){
  1225. dwAccumulativeSize = m_dwAccumulativeSizeOfBlock - nSize;
  1226. hr = S_OK;
  1227. }
  1228. else{
  1229. hr = WBEM_E_FAILED;
  1230. }
  1231. }
  1232. else
  1233. if(nSize <= 0 && hr == S_OK)
  1234. {
  1235. hr = WBEM_E_FAILED;
  1236. }
  1237. }
  1238. //=============================================
  1239. // Get the class
  1240. //=============================================
  1241. if( hr == S_OK ){
  1242. hr = FillOutProperties();
  1243. if( hr == S_OK ){
  1244. m_dwAccumulativeSizeOfBlock += dwAccumulativeSize;
  1245. //=============================================
  1246. // Save the object
  1247. //=============================================
  1248. EmbeddedClass.SaveEmbeddedClass(v);
  1249. }
  1250. }
  1251. }
  1252. return hr;
  1253. }
  1254. //////////////////////////////////////////////////////////////////////////////////
  1255. HRESULT CWMIDataBlock::WriteEmbeddedClass( IUnknown * pUnknown,CVARIANT & v)
  1256. {
  1257. HRESULT hr = WBEM_E_FAILED;
  1258. CWMIProcessClass EmbeddedClass(0);
  1259. hr = EmbeddedClass.Initialize();
  1260. if( S_OK == hr )
  1261. {
  1262. hr = EmbeddedClass.InitializeEmbeddedClass(m_Class);
  1263. CAutoChangePointer p(&m_Class,&EmbeddedClass);
  1264. //=============================================
  1265. hr = EmbeddedClass.ReadEmbeddedClassInstance(pUnknown,v);
  1266. if( hr == S_OK ){
  1267. //=============================================
  1268. // Align the embedded class properly
  1269. //=============================================
  1270. int nSize = 0L;
  1271. hr = EmbeddedClass.GetLargestDataTypeInClass(nSize);
  1272. if( hr == S_OK && nSize > 0){
  1273. CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
  1274. if( Map.NaturallyAlignData(nSize,WRITE_IT)){
  1275. m_dwAccumulativeSizeOfBlock -= nSize;
  1276. hr = ConstructDataBlock(FALSE);
  1277. }
  1278. else{
  1279. hr = WBEM_E_FAILED;
  1280. }
  1281. }
  1282. else{
  1283. hr = WBEM_E_FAILED;
  1284. }
  1285. }
  1286. }
  1287. return hr;
  1288. }
  1289. ///////////////////////////////////////////////////////////////////////
  1290. HRESULT CWMIDataBlock::SetSingleItem()
  1291. {
  1292. WCHAR * pwcsInst = NULL;
  1293. ULONG uRc = E_UNEXPECTED;
  1294. if( SUCCEEDED(m_Class->GetInstanceName(pwcsInst)))
  1295. {
  1296. try
  1297. {
  1298. uRc = WmiSetSingleItem( m_hCurrentWMIHandle, pwcsInst, m_Class->WMIDataId(), m_ulVersion, m_dwDataBufferSize, m_pbDataBuffer);
  1299. }
  1300. catch(...)
  1301. {
  1302. // don't throw
  1303. }
  1304. SAFE_DELETE_ARRAY(pwcsInst);
  1305. }
  1306. return(MapReturnCode(uRc));
  1307. }
  1308. ////////////////////////////////////////////////////////////////////////
  1309. HRESULT CWMIDataBlock::GetBufferReady(DWORD dwCount)
  1310. {
  1311. //
  1312. // is accumulation passing allocation already?
  1313. //
  1314. if( ( m_dwAccumulativeSizeOfBlock + dwCount ) >= m_dwCurrentAllocSize )
  1315. {
  1316. if( FAILED(ReAllocateBuffer(dwCount)))
  1317. {
  1318. return WBEM_E_FAILED;
  1319. }
  1320. }
  1321. return S_OK;
  1322. }
  1323. ////////////////////////////////////////////////////////////////////////
  1324. HRESULT CWMIDataBlock::WriteDataToBufferAndIfSinglePropertySubmitToWMI( BOOL fInit, BOOL fPutProperty)
  1325. {
  1326. HRESULT hr = WBEM_E_FAILED;
  1327. CIMTYPE lType;
  1328. WCHAR * pwcsProperty;
  1329. CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
  1330. if( fInit ){
  1331. if( !GetDataBlockReady(MEMSIZETOALLOCATE,FALSE) ){
  1332. return WBEM_E_FAILED;
  1333. }
  1334. }
  1335. //=============================================================
  1336. // get first delimiter in the ordered string
  1337. //=============================================================
  1338. pwcsProperty = m_Class->FirstProperty();
  1339. while (NULL != pwcsProperty){
  1340. CVARIANT vValue;
  1341. vValue.Clear();
  1342. memset(&vValue,0,sizeof(CVARIANT));
  1343. //======================================================
  1344. // Get a property type and value
  1345. //======================================================
  1346. hr = m_Class->GetPropertyInInstance(pwcsProperty, vValue, lType);
  1347. //======================================================
  1348. // We need to put in defaults if there are some
  1349. // available
  1350. //======================================================
  1351. if( hr == S_OK ){
  1352. if( ( vValue.GetType() == VT_NULL )&&
  1353. ( m_Class->PropertyType() != CIM_STRING &&
  1354. m_Class->PropertyType() != CIM_DATETIME &&
  1355. m_Class->PropertyCategory() != CWMIProcessClass::Array))
  1356. {
  1357. ERRORTRACE((THISPROVIDER,"*****************************************\n"));
  1358. ERRORTRACE((THISPROVIDER,"Class ... %S\n", m_Class->GetClassName()));
  1359. ERRORTRACE((THISPROVIDER,"Current property ... %S\n", pwcsProperty));
  1360. ERRORTRACE((THISPROVIDER,"\n"));
  1361. ERRORTRACE((THISPROVIDER,"value type ... VT_NULL\n"));
  1362. ERRORTRACE((THISPROVIDER,"cim type ... %d\n", lType));
  1363. ERRORTRACE((THISPROVIDER,"property type ... %d\n", m_Class->PropertyType()));
  1364. ERRORTRACE((THISPROVIDER,"*****************************************\n"));
  1365. hr = WBEM_E_INVALID_PARAMETER;
  1366. break;
  1367. }
  1368. }
  1369. if( SUCCEEDED(hr) ) {
  1370. //==================================================
  1371. // Check to see if the buffer is big enough
  1372. //==================================================
  1373. if( S_OK != GetBufferReady(m_Class->PropertySize())) {
  1374. return WBEM_E_FAILED;
  1375. }
  1376. //==================================================
  1377. // Add the current buffer size
  1378. //==================================================
  1379. switch( m_Class->PropertyCategory()) {
  1380. case CWMIProcessClass::EmbeddedClass:
  1381. hr = WriteEmbeddedClass((IUnknown *)NULL,vValue);
  1382. break;
  1383. case CWMIProcessClass::Array:
  1384. hr = WriteArrayTypes(pwcsProperty,vValue);
  1385. break;
  1386. case CWMIProcessClass::Data:
  1387. //============================================================
  1388. // Set missing qualifier value to the value from the NULL
  1389. //============================================================
  1390. if( vValue.GetType() == VT_NULL ) {
  1391. ResetMissingQualifierValue(pwcsProperty,vValue);
  1392. }
  1393. if( !MapWMIData.SetDataInDataBlock( NULL,0,vValue,m_Class->PropertyType(),m_Class->PropertySize())) {
  1394. hr = WBEM_E_FAILED;
  1395. }
  1396. break;
  1397. }
  1398. //=================================================
  1399. // If we could not set it, then get out
  1400. //=================================================
  1401. if( hr != S_OK ){
  1402. break;
  1403. }
  1404. //=================================================
  1405. // If we are supposed to put the single property
  1406. // at this point, then write it, otherwise, keep
  1407. // accumulating it. If it is == NULL, we don't
  1408. // want it.
  1409. //=================================================
  1410. if( fPutProperty ){
  1411. //=================================================================================
  1412. // If we are supposed to set just this property, then do so, otherwise don't
  1413. //=================================================================================
  1414. m_dwDataBufferSize = m_dwAccumulativeSizeOfBlock;
  1415. if( m_Class->GetPutProperty() ){
  1416. if( ( vValue.GetType() == VT_NULL )&& ( m_Class->PropertyType() != CIM_STRING && m_Class->PropertyType() != CIM_DATETIME )){
  1417. ERRORTRACE((THISPROVIDER,"Datatype does not support NULL values\n"));
  1418. hr = WBEM_E_INVALID_PARAMETER;
  1419. }
  1420. else{
  1421. hr = SetSingleItem();
  1422. if( hr != S_OK ){
  1423. break;
  1424. }
  1425. if( !GetDataBlockReady(MEMSIZETOALLOCATE,FALSE) ){
  1426. return hr;
  1427. }
  1428. }
  1429. }
  1430. m_dwAccumulativeSizeOfBlock = 0;
  1431. }
  1432. //=================================================
  1433. }
  1434. m_dwDataBufferSize = m_dwAccumulativeSizeOfBlock;
  1435. pwcsProperty = m_Class->NextProperty();
  1436. }
  1437. return hr;
  1438. }
  1439. ////////////////////////////////////////////////////////////////////////
  1440. HRESULT CWMIDataBlock::ConstructDataBlock(BOOL fInit)
  1441. {
  1442. return( WriteDataToBufferAndIfSinglePropertySubmitToWMI(fInit,FALSE) );
  1443. }
  1444. ////////////////////////////////////////////////////////////////////////
  1445. HRESULT CWMIDataBlock::PutSingleProperties()
  1446. {
  1447. return( WriteDataToBufferAndIfSinglePropertySubmitToWMI(TRUE,TRUE) );
  1448. }
  1449. ////////////////////////////////////////////////////////////////////////
  1450. BOOL CWMIDataBlock::GetListOfPropertiesToPut(int nWhich, CVARIANT & vList)
  1451. {
  1452. BOOL fRc = FALSE;
  1453. //=========================================================
  1454. // if nWhich == PUT_PROPERTIES_ONLY, we aren't going to
  1455. // do anything special, as, by default, the fPutProperty
  1456. // flag on the property is set to TRUE, so, in the
  1457. // processing above, we will put the properties that are
  1458. // not NULL. The only problem we have now, is if
  1459. // __PUT_EXT_PROPERTIES is set to TRUE, then we have to
  1460. // loop through all of the properties to see it they
  1461. // are in our __PUT_EXT_PROPERTIES list, if they are NOT
  1462. // then we are going to set the fPutProperty flag on that
  1463. // property to FALSE, so we won't process it above.
  1464. //=========================================================
  1465. if( nWhich == PUT_PROPERTIES_ONLY ){
  1466. fRc = TRUE;
  1467. }
  1468. else{
  1469. //=====================================================
  1470. // Make sure we get a valid ptr
  1471. //=====================================================
  1472. SAFEARRAY * psa = V_ARRAY((VARIANT*)vList);
  1473. if( IsBadReadPtr( psa, sizeof(SAFEARRAY) != 0))
  1474. {
  1475. return FALSE;
  1476. }
  1477. CSAFEARRAY Safe(psa);
  1478. DWORD dwCount = Safe.GetNumElements();
  1479. // Set each element of the array
  1480. for (DWORD i = 0; i < dwCount; i++){
  1481. CBSTR bstrProperty;
  1482. WCHAR * pwcsProperty = NULL;
  1483. //=================================================
  1484. // Loop thru all the properties in the class and
  1485. // see which ones are in the list to be PUT
  1486. //=================================================
  1487. pwcsProperty = m_Class->FirstProperty();
  1488. while( pwcsProperty != NULL ){
  1489. BOOL fFound = FALSE;
  1490. for (DWORD j = 0; j < dwCount; j++)
  1491. {
  1492. if( S_OK != Safe.Get(j, &bstrProperty))
  1493. {
  1494. return FALSE;
  1495. }
  1496. if( wbem_wcsicmp( bstrProperty, pwcsProperty ) == 0 )
  1497. {
  1498. fFound = TRUE;
  1499. break;
  1500. }
  1501. }
  1502. if( !fFound ){
  1503. m_Class->SetPutProperty(FALSE);
  1504. }
  1505. pwcsProperty = m_Class->NextProperty();
  1506. }
  1507. }
  1508. Safe.Unbind();
  1509. // Don't need to destroy, it will be destroyed
  1510. fRc = TRUE;
  1511. }
  1512. return fRc;
  1513. }
  1514. //=============================================================
  1515. BOOL CWMIDataBlock::GetDataBlockReady(DWORD dwSize,BOOL fReadingData)
  1516. {
  1517. BOOL fRc = FALSE;
  1518. ResetDataBuffer();
  1519. m_dwCurrentAllocSize = dwSize;
  1520. if( SUCCEEDED(AllocateBuffer(m_dwCurrentAllocSize)))
  1521. {
  1522. m_pbCurrentDataPtr = m_pbWorkingDataPtr = m_pbDataBuffer;
  1523. //===================================================
  1524. // If we are writing data, we will let the size
  1525. // remain at 0, otherwise set it to what the max
  1526. // is we can read.
  1527. //===================================================
  1528. if(fReadingData){
  1529. m_dwDataBufferSize = dwSize;
  1530. }
  1531. fRc = TRUE;
  1532. }
  1533. else
  1534. {
  1535. m_dwCurrentAllocSize = 0;
  1536. }
  1537. return fRc;
  1538. }
  1539. //=============================================================
  1540. void CWMIDataBlock::AddPadding(DWORD dwBytesToPad)
  1541. {
  1542. m_pbWorkingDataPtr += dwBytesToPad ;
  1543. }
  1544. //=============================================================
  1545. inline BOOL CWMIDataBlock::PtrOk(ULONG * pPtr,ULONG uHowMany)
  1546. {
  1547. ULONG * pNewPtr;
  1548. pNewPtr = (ULONG *)OffsetToPtr(pPtr,uHowMany);
  1549. if(pNewPtr <= m_pMaxPtr){
  1550. return TRUE;
  1551. }
  1552. return FALSE;
  1553. }
  1554. //=============================================================
  1555. BOOL CWMIDataBlock::CurrentPtrOk(ULONG uHowMany)
  1556. {
  1557. return(PtrOk((ULONG *)m_pbWorkingDataPtr,uHowMany));
  1558. }
  1559. //=============================================================
  1560. void CWMIDataBlock::GetWord(WORD & wWord)
  1561. {
  1562. memcpy( &wWord,m_pbWorkingDataPtr,sizeof(WORD));
  1563. m_pbWorkingDataPtr += sizeof(WORD);
  1564. }
  1565. //=============================================================
  1566. void CWMIDataBlock::GetDWORD(DWORD & dwWord)
  1567. {
  1568. memcpy( &dwWord,m_pbWorkingDataPtr,sizeof(DWORD));
  1569. m_pbWorkingDataPtr += sizeof(DWORD);
  1570. }
  1571. //=============================================================
  1572. void CWMIDataBlock::GetFloat(float & fFloat)
  1573. {
  1574. memcpy( &fFloat,m_pbWorkingDataPtr,sizeof(float));
  1575. m_pbWorkingDataPtr += sizeof(float);
  1576. }
  1577. //=============================================================
  1578. void CWMIDataBlock::GetDouble(DOUBLE & dDouble)
  1579. {
  1580. memcpy( &dDouble,m_pbWorkingDataPtr,sizeof(DOUBLE));
  1581. m_pbWorkingDataPtr += sizeof(DOUBLE);
  1582. }
  1583. //=============================================================
  1584. HRESULT CWMIDataBlock::GetSInt64( WCHAR * pwcsBuffer, DWORD cchSize )
  1585. {
  1586. HRESULT hr = WBEM_E_FAILED;
  1587. signed __int64 * pInt64;
  1588. pInt64 = (__int64 *)m_pbWorkingDataPtr;
  1589. if ( SUCCEEDED ( hr = StringCchPrintfW ( pwcsBuffer, cchSize, L"%I64d", *pInt64 ) ) )
  1590. {
  1591. m_pbWorkingDataPtr += sizeof( signed __int64);
  1592. }
  1593. return hr;
  1594. }
  1595. //=============================================================
  1596. void CWMIDataBlock::GetQWORD(unsigned __int64 & uInt64)
  1597. {
  1598. memcpy( &uInt64,m_pbWorkingDataPtr,sizeof(unsigned __int64));
  1599. m_pbWorkingDataPtr += sizeof(unsigned __int64);
  1600. }
  1601. //=============================================================
  1602. HRESULT CWMIDataBlock::GetUInt64( WCHAR * pwcsBuffer, DWORD cchSize )
  1603. {
  1604. HRESULT hr = WBEM_E_FAILED;
  1605. unsigned __int64 * puInt64;
  1606. puInt64 = (unsigned __int64 *)m_pbWorkingDataPtr;
  1607. if ( SUCCEEDED ( hr = StringCchPrintfW ( pwcsBuffer,cchSize, L"%I64u", *puInt64 ) ) )
  1608. {
  1609. m_pbWorkingDataPtr += sizeof(unsigned __int64);
  1610. }
  1611. return hr;
  1612. }
  1613. //=============================================================
  1614. void CWMIDataBlock::GetString(WCHAR * pwcsBuffer,WORD wCount,WORD wBufferSize)
  1615. {
  1616. memset(pwcsBuffer,NULL,wBufferSize);
  1617. memcpy(pwcsBuffer,m_pbWorkingDataPtr, wCount);
  1618. m_pbWorkingDataPtr += wCount;
  1619. }
  1620. //=============================================================
  1621. void CWMIDataBlock::GetByte(BYTE & bByte)
  1622. {
  1623. memcpy( &bByte,m_pbWorkingDataPtr,sizeof(BYTE));
  1624. m_pbWorkingDataPtr += sizeof(BYTE);
  1625. }
  1626. //=============================================================
  1627. void CWMIDataBlock::SetWord(WORD wWord)
  1628. {
  1629. memcpy(m_pbWorkingDataPtr,&wWord,sizeof(WORD));
  1630. m_pbWorkingDataPtr += sizeof(WORD);
  1631. }
  1632. //=============================================================
  1633. void CWMIDataBlock::SetDWORD(DWORD dwWord)
  1634. {
  1635. memcpy(m_pbWorkingDataPtr,&dwWord,sizeof(DWORD));
  1636. m_pbWorkingDataPtr += sizeof(DWORD);
  1637. }
  1638. //=============================================================
  1639. void CWMIDataBlock::SetFloat(float fFloat)
  1640. {
  1641. memcpy(m_pbWorkingDataPtr,&fFloat,sizeof(float));
  1642. m_pbWorkingDataPtr += sizeof(float);
  1643. }
  1644. //=============================================================
  1645. void CWMIDataBlock::SetDouble(DOUBLE dDouble)
  1646. {
  1647. memcpy( m_pbWorkingDataPtr,&dDouble,sizeof(DOUBLE));
  1648. m_pbWorkingDataPtr += sizeof(DOUBLE);
  1649. }
  1650. //=============================================================
  1651. void CWMIDataBlock::SetSInt64(__int64 Int64)
  1652. {
  1653. memcpy(m_pbWorkingDataPtr,&Int64,sizeof(__int64));
  1654. m_pbWorkingDataPtr += sizeof(__int64);
  1655. }
  1656. //=============================================================
  1657. void CWMIDataBlock::SetUInt64(unsigned __int64 UInt64)
  1658. {
  1659. memcpy(m_pbWorkingDataPtr,&UInt64,sizeof(unsigned __int64));
  1660. m_pbWorkingDataPtr += sizeof(unsigned __int64);
  1661. }
  1662. //=============================================================
  1663. void CWMIDataBlock::SetString(WCHAR * pwcsBuffer,WORD wCount)
  1664. {
  1665. memcpy(m_pbWorkingDataPtr,pwcsBuffer, wCount);
  1666. m_pbWorkingDataPtr += wCount;
  1667. }
  1668. //=============================================================
  1669. void CWMIDataBlock::SetByte(byte bByte)
  1670. {
  1671. memcpy(m_pbWorkingDataPtr,&bByte,sizeof(byte));
  1672. m_pbWorkingDataPtr += sizeof(byte);
  1673. }
  1674. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1675. //*************************************************************************************************
  1676. //
  1677. // CProcessStandardDataBlock
  1678. //
  1679. //*************************************************************************************************
  1680. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  1681. CProcessStandardDataBlock::CProcessStandardDataBlock()
  1682. {
  1683. m_Class = NULL;
  1684. m_pMethodInput = NULL;
  1685. m_pMethodOutput = NULL;
  1686. }
  1687. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  1688. CProcessStandardDataBlock::~CProcessStandardDataBlock()
  1689. {
  1690. }
  1691. ////////////////////////////////////////////////////////////////////
  1692. // WMIRaid:2445
  1693. HRESULT CProcessStandardDataBlock::FillOutProperties()
  1694. {
  1695. HRESULT hr = WBEM_E_INVALID_OBJECT;
  1696. if( m_Class->GetHardCodedGuidType() )
  1697. {
  1698. hr = ProcessBinaryMof();
  1699. }
  1700. else if(m_Class->GetANewInstance()){
  1701. //=========================================================
  1702. // get the properties from the class and read the WMI Data
  1703. //=========================================================
  1704. hr = WBEM_S_NO_ERROR;
  1705. WCHAR * pwcsProperty=NULL;
  1706. CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
  1707. m_dwAccumulativeSizeOfBlock = 0L;
  1708. pwcsProperty = m_Class->FirstProperty();
  1709. while (NULL != pwcsProperty)
  1710. {
  1711. CVARIANT vToken;
  1712. //=========================================================
  1713. // See if it is an array or not
  1714. //=========================================================
  1715. switch( m_Class->PropertyCategory()){
  1716. case CWMIProcessClass::EmbeddedClass:
  1717. hr = ProcessEmbeddedClass(vToken);
  1718. if( hr == S_OK )
  1719. {
  1720. m_Class->PutPropertyInInstance(&vToken);
  1721. }
  1722. break;
  1723. case CWMIProcessClass::Array:
  1724. VARIANT v;
  1725. VariantInit(&v);
  1726. hr = ProcessArrayTypes(v,pwcsProperty);
  1727. if( hr == WBEM_S_NO_MORE_DATA )
  1728. {
  1729. hr = S_OK;
  1730. }
  1731. else if( SUCCEEDED(hr) )
  1732. {
  1733. hr = m_Class->PutPropertyInInstance(&v);
  1734. }
  1735. VariantClear(&v);
  1736. break;
  1737. case CWMIProcessClass::Data:
  1738. hr = MapWMIData.GetDataFromDataBlock(vToken, m_Class->PropertyType(), m_Class->PropertySize());
  1739. if( SUCCEEDED(hr) )
  1740. {
  1741. CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
  1742. //============================================================
  1743. // We are only going to support this for numerical types
  1744. //============================================================
  1745. CVARIANT vQual;
  1746. hr = m_Class->GetQualifierValue( pwcsProperty, L"MissingValue", (CVARIANT *)&vQual);
  1747. if( hr == S_OK )
  1748. {
  1749. if( vQual.GetType() != VT_EMPTY )
  1750. {
  1751. if( !(Map.MissingQualifierValueMatches( NULL, 0,vQual, vToken.GetType(), vToken ) ))
  1752. {
  1753. hr = m_Class->PutPropertyInInstance(&vToken);
  1754. }
  1755. }
  1756. else
  1757. {
  1758. hr = m_Class->PutPropertyInInstance(&vToken);
  1759. }
  1760. }
  1761. else
  1762. {
  1763. hr = m_Class->PutPropertyInInstance(&vToken);
  1764. }
  1765. }
  1766. else
  1767. {
  1768. StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_INVALID_BLOCK_POINTER );
  1769. }
  1770. break;
  1771. }
  1772. pwcsProperty = m_Class->NextProperty();
  1773. }
  1774. //===============================================
  1775. // Set the active value
  1776. //===============================================
  1777. m_Class->SetActiveProperty();
  1778. }
  1779. return hr;
  1780. }
  1781. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  1782. HRESULT CProcessStandardDataBlock::CreateOutParameterBlockForMethods()
  1783. {
  1784. HRESULT hr = WBEM_E_FAILED;
  1785. BOOL fRc = FALSE;
  1786. //========================================================
  1787. // If we don't have a class, then we don't have to
  1788. // worry about creating a block
  1789. //========================================================
  1790. if( !m_pMethodOutput->ValidClass() ){
  1791. ResetDataBuffer();
  1792. return S_OK;
  1793. }
  1794. DWORD dwSize = 0L;
  1795. hr = m_pMethodOutput->GetSizeOfClass(dwSize);
  1796. if( hr == S_OK ){
  1797. // Allocate space for property
  1798. m_dwDataBufferSize = dwSize;
  1799. if( dwSize > 0 ){
  1800. GetDataBlockReady(dwSize,TRUE);
  1801. }
  1802. }
  1803. return hr;
  1804. }
  1805. //=============================================================
  1806. HRESULT CProcessStandardDataBlock::CreateInParameterBlockForMethods( BYTE *& Buffer, ULONG & uBufferSize)
  1807. {
  1808. HRESULT hr = WBEM_E_FAILED;
  1809. BOOL fRc = FALSE;
  1810. //========================================================
  1811. // If we don't have a class, then we don't have to
  1812. // worry about creating a block
  1813. //========================================================
  1814. if( !m_pMethodInput->ValidClass() ){
  1815. Buffer = NULL;
  1816. uBufferSize = 0;
  1817. return S_OK;
  1818. }
  1819. //========================================================
  1820. // When it goes out of scope, it will reset m_Class back
  1821. // to what it was
  1822. //========================================================
  1823. CAutoChangePointer p(&m_Class,m_pMethodInput);
  1824. DEBUGTRACE((THISPROVIDER,"Constructing the data block\n"));
  1825. hr = ConstructDataBlock(TRUE);
  1826. if( S_OK == hr ){
  1827. uBufferSize = (ULONG)m_dwDataBufferSize;
  1828. Buffer = new byte[ uBufferSize +1];
  1829. if( Buffer )
  1830. {
  1831. try
  1832. {
  1833. memcpy( Buffer, m_pbDataBuffer, uBufferSize );
  1834. ResetDataBuffer();
  1835. hr = S_OK;
  1836. }
  1837. catch(...)
  1838. {
  1839. SAFE_DELETE_ARRAY(Buffer);
  1840. hr = WBEM_E_UNEXPECTED;
  1841. throw;
  1842. }
  1843. }
  1844. }
  1845. return hr;
  1846. }
  1847. //=============================================================
  1848. HRESULT CProcessStandardDataBlock::ProcessMethodInstanceParameters()
  1849. {
  1850. HRESULT hr = WBEM_E_FAILED;
  1851. // Create out-param
  1852. // ================
  1853. m_pMaxPtr = (ULONG *)OffsetToPtr(m_pbDataBuffer, m_dwDataBufferSize);
  1854. m_nCurrentInstance = 1;
  1855. m_nTotalInstances = 1;
  1856. m_pAllWnode = NULL;
  1857. m_pHeaderWnode = NULL;
  1858. m_pbCurrentDataPtr = m_pbWorkingDataPtr = m_pbDataBuffer;
  1859. CAutoChangePointer p(&m_Class,m_pMethodOutput);
  1860. hr = FillOutProperties();
  1861. if( hr == S_OK )
  1862. {
  1863. hr = m_pMethodOutput->SendInstanceBack();
  1864. }
  1865. return hr;
  1866. }
  1867. //=============================================================
  1868. // NTRaid:127832
  1869. // 07/12/00
  1870. //=============================================================
  1871. HRESULT CProcessStandardDataBlock::ExecuteMethod(ULONG MethodId, WCHAR * MethodInstanceName, ULONG InputValueBufferSize,
  1872. BYTE * InputValueBuffer )
  1873. {
  1874. ULONG uRc = E_UNEXPECTED;
  1875. try
  1876. {
  1877. uRc = WmiExecuteMethod(m_hCurrentWMIHandle, MethodInstanceName, MethodId, InputValueBufferSize,
  1878. InputValueBuffer,&m_dwDataBufferSize,m_pbDataBuffer);
  1879. if( uRc == ERROR_INSUFFICIENT_BUFFER )
  1880. {
  1881. if( GetDataBlockReady(m_dwDataBufferSize,TRUE))
  1882. {
  1883. uRc = WmiExecuteMethod(m_hCurrentWMIHandle, MethodInstanceName, MethodId, InputValueBufferSize,
  1884. InputValueBuffer,&m_dwDataBufferSize,m_pbDataBuffer);
  1885. }
  1886. }
  1887. }
  1888. catch(...)
  1889. {
  1890. uRc = E_UNEXPECTED;
  1891. // don't throw
  1892. }
  1893. if( uRc == ERROR_SUCCESS ){
  1894. //===========================================================
  1895. // If we have an out class, process it, otherwise, we are
  1896. // done so set hr to success.
  1897. //===========================================================g
  1898. if( m_pMethodOutput->ValidClass() )
  1899. {
  1900. if(SUCCEEDED(ProcessMethodInstanceParameters())){
  1901. uRc = ERROR_SUCCESS;
  1902. }
  1903. }
  1904. }
  1905. return MapReturnCode(uRc);
  1906. }
  1907. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  1908. ULONG CProcessStandardDataBlock::GetDataBufferAndQueryAllData(DWORD dwSize)
  1909. {
  1910. ULONG uRc = E_UNEXPECTED;
  1911. if(GetDataBlockReady(dwSize,TRUE))
  1912. {
  1913. try
  1914. {
  1915. uRc = WmiQueryAllData(m_hCurrentWMIHandle, &m_dwDataBufferSize,m_pbDataBuffer);
  1916. }
  1917. catch(...)
  1918. {
  1919. uRc = E_UNEXPECTED;
  1920. // don't throw
  1921. }
  1922. }
  1923. return uRc;
  1924. }
  1925. /////////////////////////////////////////////////////////////////////
  1926. HRESULT CProcessStandardDataBlock::QueryAllData()
  1927. {
  1928. HRESULT hr = WBEM_E_FAILED;
  1929. //============================================================
  1930. // Get the instances
  1931. //============================================================
  1932. ULONG uRc = GetDataBufferAndQueryAllData(sizeof(WNODE_ALL_DATA));
  1933. if( uRc == ERROR_INSUFFICIENT_BUFFER )
  1934. {
  1935. //=================================================
  1936. // We just want to try one more time to get it,
  1937. // if it fails, then bail out. m_dwDataBufferSize
  1938. // should now have the correct size needed in it
  1939. //=================================================
  1940. uRc = GetDataBufferAndQueryAllData(m_dwDataBufferSize);
  1941. }
  1942. //=====================================================
  1943. // Ok, since we are querying for all instances, make
  1944. // sure the header node says that all of the instances
  1945. // are fine, if not reallocate
  1946. //=====================================================
  1947. if( uRc == ERROR_SUCCESS )
  1948. {
  1949. if( S_OK ==(hr = SetAllInstanceInfo()))
  1950. {
  1951. if (m_pHeaderWnode->Flags & WNODE_FLAG_TOO_SMALL)
  1952. {
  1953. while( TRUE )
  1954. {
  1955. //==========================================================
  1956. // keep on querying until we get the correct size
  1957. // This error may come from the driver
  1958. //==========================================================
  1959. uRc = GetDataBufferAndQueryAllData(m_dwDataBufferSize);
  1960. if( uRc == ERROR_SUCCESS )
  1961. {
  1962. if( S_OK ==(hr = SetAllInstanceInfo()))
  1963. {
  1964. if (!(m_pHeaderWnode->Flags & WNODE_FLAG_TOO_SMALL))
  1965. {
  1966. break;
  1967. }
  1968. }
  1969. } // end GetDataBufferAndQueryAllData
  1970. } // end of while
  1971. } // end of WNODE_FLAG_TOO_SMALL test
  1972. } // end of SetAllInstanceInfo
  1973. }
  1974. //==========================================================================
  1975. // if uRc succeeded, then the return code is already set by SetAllInstance
  1976. // otherwise need to map it out
  1977. //==========================================================================
  1978. if( uRc != ERROR_SUCCESS )
  1979. {
  1980. hr = MapReturnCode(uRc);
  1981. }
  1982. return hr;
  1983. }
  1984. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  1985. ULONG CProcessStandardDataBlock::GetDataBufferAndQuerySingleInstance(DWORD dwSize,WCHAR * wcsInstanceName)
  1986. {
  1987. ULONG uRc = E_UNEXPECTED;
  1988. if(GetDataBlockReady(dwSize,TRUE))
  1989. {
  1990. try
  1991. {
  1992. uRc = WmiQuerySingleInstance(m_hCurrentWMIHandle, wcsInstanceName, &m_dwDataBufferSize, m_pbDataBuffer);
  1993. }
  1994. catch(...)
  1995. {
  1996. uRc = E_UNEXPECTED;
  1997. // don't throw
  1998. }
  1999. }
  2000. return uRc;
  2001. }
  2002. ///////////////////////////////////////////////////////////////////////
  2003. HRESULT CProcessStandardDataBlock::QuerySingleInstance(WCHAR * wcsInstanceName)
  2004. {
  2005. //============================================================
  2006. // Get the instances
  2007. //============================================================
  2008. DWORD dwChar = wcslen(wcsInstanceName);
  2009. DWORD dwSize = ROUND_UP_COUNT(sizeof(WNODE_SINGLE_INSTANCE) + dwChar ,8);
  2010. ULONG uRc = GetDataBufferAndQuerySingleInstance(dwSize,wcsInstanceName);
  2011. if( uRc == ERROR_INSUFFICIENT_BUFFER )
  2012. {
  2013. uRc = GetDataBufferAndQuerySingleInstance(m_dwDataBufferSize,wcsInstanceName);
  2014. }
  2015. if( uRc == ERROR_SUCCESS )
  2016. {
  2017. return(SetSingleInstanceInfo());
  2018. }
  2019. return(MapReturnCode(uRc));
  2020. }
  2021. ///////////////////////////////////////////////////////////////////////
  2022. // NTRaid : 136392
  2023. // 07/12/00
  2024. HRESULT CProcessStandardDataBlock::SetSingleInstance()
  2025. {
  2026. ULONG uRc = S_OK;
  2027. WCHAR * pwcsInst = NULL;
  2028. if( SUCCEEDED(m_Class->GetInstanceName(pwcsInst)))
  2029. {
  2030. try
  2031. {
  2032. uRc = WmiSetSingleInstance( m_hCurrentWMIHandle, pwcsInst,1,m_dwDataBufferSize,m_pbDataBuffer);
  2033. }
  2034. catch(...)
  2035. {
  2036. uRc = E_UNEXPECTED;
  2037. // don't throw
  2038. }
  2039. SAFE_DELETE_ARRAY(pwcsInst);
  2040. }
  2041. return(MapReturnCode(uRc));
  2042. }
  2043. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  2044. //*******************************************************************************************************
  2045. //
  2046. // CProcessHiPerfDataBlock
  2047. //
  2048. //*******************************************************************************************************
  2049. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  2050. HRESULT CProcessHiPerfDataBlock::OpenHiPerfHandle()
  2051. {
  2052. HRESULT hr = WBEM_E_FAILED;
  2053. ULONG uRc = ERROR_SUCCESS;
  2054. //========================================================
  2055. // Open the handle
  2056. //========================================================
  2057. try
  2058. {
  2059. uRc = WmiOpenBlock(m_Class->GuidPtr(),m_uDesiredAccess, &m_hCurrentWMIHandle);
  2060. if( uRc == ERROR_SUCCESS )
  2061. {
  2062. // WMIINTERFACE->HandleMap()->Add(*(m_Class->GuidPtr()),m_hCurrentWMIHandle);
  2063. }
  2064. }
  2065. catch(...)
  2066. {
  2067. hr = E_UNEXPECTED;
  2068. // don't throw
  2069. }
  2070. return MapReturnCode(uRc);
  2071. }
  2072. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  2073. ULONG CProcessHiPerfDataBlock::GetDataBufferAndHiPerfQueryAllData(DWORD dwSize,WMIHANDLE * List, long lHandleCount)
  2074. {
  2075. ULONG uRc = E_UNEXPECTED;
  2076. if(GetDataBlockReady(dwSize,TRUE))
  2077. {
  2078. try
  2079. {
  2080. uRc = WmiQueryAllDataMultiple(List, lHandleCount, &m_dwDataBufferSize,m_pbDataBuffer);
  2081. }
  2082. catch(...)
  2083. {
  2084. uRc = E_UNEXPECTED;
  2085. // don't throw
  2086. }
  2087. }
  2088. return uRc;
  2089. }
  2090. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  2091. HRESULT CProcessHiPerfDataBlock::HiPerfQueryAllData(WMIHANDLE * List,long lHandleCount)
  2092. {
  2093. HRESULT hr = WBEM_E_FAILED;
  2094. //============================================================
  2095. // Get the instances
  2096. //============================================================
  2097. ULONG uRc = GetDataBufferAndHiPerfQueryAllData(sizeof(WNODE_ALL_DATA)*lHandleCount,List,lHandleCount);
  2098. if( uRc == ERROR_INSUFFICIENT_BUFFER )
  2099. {
  2100. //=================================================
  2101. // We just want to try one more time to get it,
  2102. // if it fails, then bail out. m_dwDataBufferSize
  2103. // should now have the correct size needed in it
  2104. //=================================================
  2105. uRc = GetDataBufferAndHiPerfQueryAllData(m_dwDataBufferSize,List,lHandleCount);
  2106. }
  2107. //=====================================================
  2108. // Ok, since we are querying for all instances, make
  2109. // sure the header node says that all of the instances
  2110. // are fine, if not reallocate
  2111. //=====================================================
  2112. if( uRc == ERROR_SUCCESS )
  2113. {
  2114. if( S_OK ==(hr = SetAllInstanceInfo()))
  2115. {
  2116. if (m_pHeaderWnode->Flags & WNODE_FLAG_TOO_SMALL)
  2117. {
  2118. while( TRUE )
  2119. {
  2120. //==========================================================
  2121. // keep on querying until we get the correct size
  2122. // This error may come from the driver
  2123. //==========================================================
  2124. uRc = GetDataBufferAndHiPerfQueryAllData(m_dwDataBufferSize,List,lHandleCount);
  2125. if( uRc == ERROR_SUCCESS )
  2126. {
  2127. if( S_OK ==(hr = SetAllInstanceInfo()))
  2128. {
  2129. if (!(m_pHeaderWnode->Flags & WNODE_FLAG_TOO_SMALL))
  2130. {
  2131. break;
  2132. }
  2133. }
  2134. } // end GetDataBufferAndQueryAllData
  2135. } // end of while
  2136. } // end of WNODE_FLAG_TOO_SMALL test
  2137. } // end of SetAllInstanceInfo
  2138. }
  2139. //==========================================================================
  2140. // if uRc succeeded, then the return code is already set by SetAllInstance
  2141. // otherwise need to map it out
  2142. //==========================================================================
  2143. if( uRc != ERROR_SUCCESS )
  2144. {
  2145. hr = MapReturnCode(uRc);
  2146. }
  2147. return(hr);
  2148. }
  2149. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  2150. ULONG CProcessHiPerfDataBlock::GetDataBufferAndHiPerfQuerySingleInstance( DWORD dwSize,WMIHANDLE *List, PWCHAR * pInstances,long lHandleCount)
  2151. {
  2152. ULONG uRc = E_UNEXPECTED;
  2153. if(GetDataBlockReady(dwSize,TRUE))
  2154. {
  2155. try
  2156. {
  2157. uRc = WmiQuerySingleInstanceMultiple( List, pInstances, lHandleCount, &m_dwDataBufferSize, m_pbDataBuffer);
  2158. }
  2159. catch(...)
  2160. {
  2161. uRc = E_UNEXPECTED;
  2162. // don't throw
  2163. }
  2164. }
  2165. return uRc;
  2166. }
  2167. ///////////////////////////////////////////////////////////////////////
  2168. HRESULT CProcessHiPerfDataBlock::HiPerfQuerySingleInstance(WMIHANDLE *List, PWCHAR * pInstances, DWORD dwInstanceNameSize, long lHandleCount)
  2169. {
  2170. //============================================================
  2171. // Get the instances
  2172. //============================================================
  2173. ULONG uRc = GetDataBufferAndHiPerfQuerySingleInstance((sizeof(WNODE_SINGLE_INSTANCE)*lHandleCount) + dwInstanceNameSize ,List,pInstances,lHandleCount);
  2174. if( uRc == ERROR_INSUFFICIENT_BUFFER )
  2175. {
  2176. uRc = GetDataBufferAndHiPerfQuerySingleInstance(m_dwDataBufferSize,List,pInstances,lHandleCount);
  2177. }
  2178. if( uRc == ERROR_SUCCESS )
  2179. {
  2180. return(SetSingleInstanceInfo());
  2181. }
  2182. return(MapReturnCode(uRc));
  2183. }
  2184. ////////////////////////////////////////////////////////////////////
  2185. HRESULT CProcessHiPerfDataBlock::FillOutProperties()
  2186. {
  2187. HRESULT hr = WBEM_E_INVALID_OBJECT;
  2188. //=========================================================
  2189. // get the properties from the class and read the WMI Data
  2190. //=========================================================
  2191. if(m_Class->GetANewInstance()){
  2192. WCHAR * pwcsProperty=NULL;
  2193. CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
  2194. m_dwAccumulativeSizeOfBlock = 0L;
  2195. pwcsProperty = m_Class->FirstProperty();
  2196. while (NULL != pwcsProperty){
  2197. //=========================================================
  2198. // We do not support arrays or embedded classes
  2199. //=========================================================
  2200. if( ( CWMIProcessClass::EmbeddedClass == m_Class->PropertyCategory()) ||
  2201. ( CWMIProcessClass::Array == m_Class->PropertyCategory() ) ){
  2202. hr = WMI_INVALID_HIPERFPROP;
  2203. ERRORTRACE((THISPROVIDER,"Class %S has embedded class or array property\n",m_Class->GetClassName()));
  2204. break;
  2205. }
  2206. hr = MapWMIData.GetDataFromDataBlock(m_Class->GetAccessInstancePtr(), m_Class->GetPropertyHandle(), m_Class->PropertyType(), m_Class->PropertySize());
  2207. if( FAILED(hr) ){
  2208. break;
  2209. }
  2210. pwcsProperty = m_Class->NextProperty();
  2211. }
  2212. }
  2213. //====================================================================
  2214. // Now, fill in the specific HI PERF properties
  2215. //====================================================================
  2216. if( hr == S_OK )
  2217. {
  2218. hr = m_Class->SetHiPerfProperties(m_pHeaderWnode->TimeStamp);
  2219. }
  2220. return hr;
  2221. }
  2222. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2223. // This function searches the standard HandleMap for the handle and if it isn't there, it is added.
  2224. // The hiperf handles are added/mapped elsewhere.
  2225. ///////////////////////////////////////////////////////////
  2226. HRESULT CProcessHiPerfDataBlock::GetWMIHandle(HANDLE & lWMIHandle)
  2227. {
  2228. HRESULT hr = WBEM_E_FAILED;
  2229. lWMIHandle = 0;
  2230. hr = WMIINTERFACE->HandleMap()->GetHandle(*(m_Class->GuidPtr()),lWMIHandle);
  2231. if( hr != ERROR_SUCCESS )
  2232. {
  2233. hr = OpenHiPerfHandle();
  2234. if( SUCCEEDED(hr))
  2235. {
  2236. lWMIHandle = m_hCurrentWMIHandle;
  2237. hr = WMIINTERFACE->HandleMap()->Add( *(m_Class->GuidPtr()), lWMIHandle,WMIGUID_QUERY );
  2238. }
  2239. }
  2240. return hr;
  2241. }