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.

2392 lines
77 KiB

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