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

//***************************************************************************
//
// Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "precomp.h"
#include "wmicom.h"
#include "wmimof.h"
#include "wmimap.h"
#include <stdlib.h>
#include <winerror.h>
#include <crc32.h>
#include <align.h>
#define NO_DATA_AVAILABLE 2
#define WMI_INVALID_HIPERFPROP 3
#define OffsetToPtr(Base, Offset) ((PBYTE)((PBYTE)Base + Offset))
////////////////////////////////////////////////////////////////////////////////////////////////
void WINAPI EventCallbackRoutine(PWNODE_HEADER WnodeHeader, ULONG_PTR Context);
#define WMIINTERFACE m_Class->GetWMIManagementPtr()
////////////////////////////////////////////////////////////////////////////////////////////////
//=============================================================
BOOL CWMIManagement::CancelWMIEventRegistration( GUID gGuid , ULONG_PTR uContext )
{
BOOL fRc = FALSE;
try
{
if( ERROR_SUCCESS == WmiNotificationRegistration(&gGuid, FALSE,EventCallbackRoutine,uContext, NOTIFICATION_CALLBACK_DIRECT))
{
fRc = TRUE;
}
}
catch(...)
{
// don't throw
}
return fRc;
}
//**********************************************************************************************
// WMI Data block
//**********************************************************************************************
////////////////////////////////////////////////////////////////////////////////////////////////
void CWMIDataBlock::DumpAllWnode()
{
//=========================================
// Dump Wnode All Node info
//=========================================
DEBUGTRACE((THISPROVIDER,"***************************************\n"));
DEBUGTRACE((THISPROVIDER,"WNODE_ALL_DATA 0x%x\n",m_pAllWnode));
DEBUGTRACE((THISPROVIDER," DataBlockOffset..............%x\n",m_pAllWnode->DataBlockOffset));
DEBUGTRACE((THISPROVIDER," InstanceCount................%x\n",m_pAllWnode->InstanceCount));
DEBUGTRACE((THISPROVIDER," OffsetInstanceNameOffsets....%x\n",m_pAllWnode->OffsetInstanceNameOffsets));
if( m_fFixedInstance ){
DEBUGTRACE((THISPROVIDER," FixedInstanceSize....%x\n",m_pAllWnode->FixedInstanceSize));
}
else{
DEBUGTRACE((THISPROVIDER," OffsetInstanceData....%x\n",m_pAllWnode->OffsetInstanceDataAndLength[0].OffsetInstanceData));
DEBUGTRACE((THISPROVIDER," LengthInstanceData....%x\n",m_pAllWnode->OffsetInstanceDataAndLength[0].LengthInstanceData));
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void CWMIDataBlock::DumpSingleWnode()
{
//=========================================
// Dump Wnode Single Node info
//=========================================
DEBUGTRACE((THISPROVIDER,"***************************************\n"));
DEBUGTRACE((THISPROVIDER,"WNODE_SINGLE_INSTANCE 0x%x\n",m_pSingleWnode));
DEBUGTRACE((THISPROVIDER," OffsetInstanceName....0x%x\n",m_pSingleWnode->OffsetInstanceName));
DEBUGTRACE((THISPROVIDER," InstanceIndex.........0x%x\n",m_pSingleWnode->InstanceIndex));
DEBUGTRACE((THISPROVIDER," DataBlockOffset.......0x%x\n",m_pSingleWnode->DataBlockOffset));
DEBUGTRACE((THISPROVIDER," SizeDataBlock.........0x%x\n",m_pSingleWnode->SizeDataBlock));
DEBUGTRACE((THISPROVIDER,"***************************************\n"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
void CWMIDataBlock::DumpWnodeMsg(char * wcsMsg)
{
ERRORTRACE((THISPROVIDER,"***************************************\n"));
ERRORTRACE((THISPROVIDER,"%s\n",wcsMsg));
ERRORTRACE((THISPROVIDER,"***************************************\n"));
}
////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::DumpWnodeInfo(char * wcsMsg)
{
HRESULT hr = WBEM_E_UNEXPECTED;
//=========================================
// Dump Wnode header info first
//=========================================
// WNODE definition
if( m_pHeaderWnode )
{
if( !IsBadReadPtr( m_pHeaderWnode, m_pHeaderWnode->BufferSize))
{
DumpWnodeMsg(wcsMsg);
if ( LoggingLevelEnabled ( 1 ) )
{
ERRORTRACE((THISPROVIDER,"*******************************************\n"));
ERRORTRACE((THISPROVIDER,"Enable verbose logging for more information\n"));
ERRORTRACE((THISPROVIDER,"*******************************************\n"));
}
DEBUGTRACE((THISPROVIDER,"WNODE_HEADER 0x%x\n",m_pHeaderWnode));
DEBUGTRACE((THISPROVIDER," BufferSize........0x%x\n",m_pHeaderWnode->BufferSize));
DEBUGTRACE((THISPROVIDER," ProviderId........0x%x\n",m_pHeaderWnode->ProviderId));
DEBUGTRACE((THISPROVIDER," Version...........0x%x\n",m_pHeaderWnode->Version));
if( m_pHeaderWnode->Linkage != 0 ){
DEBUGTRACE((THISPROVIDER," Linkage...........%x\n",m_pHeaderWnode->Linkage));
}
DEBUGTRACE((THISPROVIDER," TimeStamp:LowPart.0x%x\n",m_pHeaderWnode->TimeStamp.LowPart));
DEBUGTRACE((THISPROVIDER," TimeStamp:HiPart..0x%x\n",m_pHeaderWnode->TimeStamp.HighPart));
WCHAR * pwcsGuid=NULL;
if( S_OK == StringFromCLSID(m_pHeaderWnode->Guid,&pwcsGuid )){
DEBUGTRACE((THISPROVIDER," Guid.............."));
TranslateAndLog(pwcsGuid, TRUE);
DEBUGTRACE((THISPROVIDER,"\n"));
CoTaskMemFree(pwcsGuid);
}
DEBUGTRACE((THISPROVIDER," Flags.............0x%x\n",m_pHeaderWnode->Flags));
//==================================================================
// Now that we printed the header, we should print out the node
// either single or all
//==================================================================
if( m_pSingleWnode ){
DumpSingleWnode();
}
if( m_pAllWnode ){
DumpAllWnode();
}
//==================================================================
// Now, dump the memory
//==================================================================
DWORD dwCount;
if( IsBadReadPtr( m_pHeaderWnode, m_pHeaderWnode->BufferSize) == 0 )
{
BYTE * pbBuffer = NULL;
BYTE b1,b2,b3,b4,b5,b6,b7,b8,b9,b10;
dwCount = m_pHeaderWnode->BufferSize;
pbBuffer = new BYTE[dwCount+256];
if( pbBuffer )
{
BYTE bDump[12];
DEBUGTRACE((THISPROVIDER,"Writing out buffer, total size to write: %ld\n", dwCount ));
memset(pbBuffer,NULL,dwCount+256);
memcpy(pbBuffer,(BYTE*)m_pHeaderWnode,dwCount);
BYTE * pTmp = pbBuffer;
for( DWORD i = 0; i < dwCount; i +=10)
{
memset(bDump, NULL, 12 );
memcpy(bDump, pTmp, 10);
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]));
pTmp+=10;
}
SAFE_DELETE_ARRAY(pbBuffer);
}
}
}
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::MapReturnCode(ULONG uRc)
{
if( uRc != 0 )
{
ERRORTRACE((THISPROVIDER,"WDM call returned error: %lu\n", uRc));
}
StringCchPrintfW ( m_wcsMsg, MSG_SIZE, L"WDM specific return code: %lu\n",uRc );
switch(uRc){
case ERROR_WMI_GUID_NOT_FOUND:
return WBEM_E_NOT_SUPPORTED;
break;
case S_OK:
return S_OK;
case ERROR_NOT_SUPPORTED:
case ERROR_INVALID_FUNCTION:
return WBEM_E_NOT_SUPPORTED;
case ERROR_WMI_SERVER_UNAVAILABLE:
return WBEM_E_NOT_SUPPORTED;
case NO_DATA_AVAILABLE:
return S_OK;
case ERROR_INVALID_HANDLE:
return WBEM_E_NOT_AVAILABLE;
case ERROR_WMI_DP_FAILED:
StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_DRIVER_ERROR );
DumpWnodeInfo(ANSI_MSG_DRIVER_ERROR);
return WBEM_E_INVALID_OPERATION;
case ERROR_WMI_READ_ONLY:
StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_READONLY_ERROR );
return WBEM_E_READ_ONLY;
case ERROR_INVALID_PARAMETER:
DumpWnodeInfo(ANSI_MSG_INVALID_PARAMETER);
return WBEM_E_INVALID_PARAMETER;
case ERROR_INVALID_DATA:
StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_ARRAY_ERROR );
DumpWnodeInfo(ANSI_MSG_INVALID_DATA);
return WBEM_E_INVALID_PARAMETER;
case ERROR_WMI_GUID_DISCONNECTED:
StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_DATA_NOT_AVAILABLE );
return WBEM_E_NOT_SUPPORTED;
case ERROR_ACCESS_DENIED:
case ERROR_INVALID_PRIMARY_GROUP:
case ERROR_INVALID_OWNER:
DumpWnodeInfo(ANSI_MSG_ACCESS_DENIED);
return WBEM_E_ACCESS_DENIED;
case ERROR_WMI_INSTANCE_NOT_FOUND:
StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_DATA_INSTANCE_NOT_FOUND );
DumpWnodeMsg(ANSI_MSG_DATA_INSTANCE_NOT_FOUND);
return WBEM_E_NOT_SUPPORTED;
}
return WBEM_E_FAILED;
}
//******************************************************************
////////////////////////////////////////////////////////////////////
// CWMIDataBlock
////////////////////////////////////////////////////////////////////
//******************************************************************
////////////////////////////////////////////////////////////////////
//******************************************************************
//
// WMIDataBlock handles the reading and writing of a WMI Data
// block.
//
//******************************************************************
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
CWMIDataBlock::CWMIDataBlock()
{
m_hCurrentWMIHandle = NULL;
InitMemberVars();
memset(m_wcsMsg,NULL,MSG_SIZE);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
CWMIDataBlock::~CWMIDataBlock()
{
if( m_fCloseHandle )
{
if( m_hCurrentWMIHandle )
{
try
{
WmiCloseBlock(m_hCurrentWMIHandle);
}
catch(...){
// don't throw
}
}
}
ResetDataBuffer();
InitMemberVars();
}
////////////////////////////////////////////////////////////////////
void CWMIDataBlock::InitMemberVars()
{
m_fUpdateNamespace = TRUE;
m_fMofHasChanged = FALSE;
m_uDesiredAccess = 0;
m_dwDataBufferSize = 0;
m_pbDataBuffer= NULL;
m_fMore = 0L;
//=======================================
// ptrs
//=======================================
m_pHeaderWnode = NULL;
m_pSingleWnode = NULL;
m_pAllWnode = NULL;
m_dwAccumulativeSizeOfBlock = 0L;
m_dwCurrentAllocSize = 0L;
m_uInstanceSize = 0L;
}
//====================================================================
HRESULT CWMIDataBlock::OpenWMIForBinaryMofGuid()
{
int nRc = 0;
HRESULT hr = WBEM_E_FAILED;
m_fCloseHandle = TRUE;
try
{
hr = m_Class->GetGuid();
if( S_OK == hr )
{
nRc = WmiOpenBlock(m_Class->GuidPtr(),m_uDesiredAccess, &m_hCurrentWMIHandle);
if( nRc == ERROR_SUCCESS )
{
hr = S_OK;
}
}
}
catch(...)
{
hr = WBEM_E_UNEXPECTED;
// don't throw
}
return hr;
}
//====================================================================
int CWMIDataBlock::AssignNewHandleAndKeepItIfWMITellsUsTo()
{
int nRc = 0;
try
{
nRc = WmiOpenBlock(m_Class->GuidPtr(),m_uDesiredAccess, &m_hCurrentWMIHandle);
//===========================================================
// Now that we opened the block successfully, check to see
// if we need to keep this guy open or not, if we do
// then add it to our list, otherwise don't
//===========================================================
if( nRc == ERROR_SUCCESS )
{
//=======================================================
// Call WMI function here to see if we should save or
// not
//=======================================================
WMIGUIDINFORMATION GuidInfo;
GuidInfo.Size = sizeof(WMIGUIDINFORMATION);
if( ERROR_SUCCESS == WmiQueryGuidInformation(m_hCurrentWMIHandle,&GuidInfo))
{
if(GuidInfo.IsExpensive)
{
if( m_fUpdateNamespace )
{
//================================================
// Add it to our list of handles to keep
//================================================
m_fCloseHandle = FALSE;
WMIINTERFACE->HandleMap()->Add(*(m_Class->GuidPtr()),m_hCurrentWMIHandle,m_uDesiredAccess);
}
}
}
}
}
catch(...)
{
nRc = E_UNEXPECTED;
// don't throw
}
return nRc;
}
//====================================================================
HRESULT CWMIDataBlock::OpenWMI()
{
int nRc;
HRESULT hr = WBEM_E_FAILED;
//=======================================================
// Ok, we only want to keep the handles that are flagged
// by WMI to be kept, otherwise, we just open the handle
// and then close it. Because of this, we need to
// check first and see if the Guid we are going after
// already has a handle open, if it does, use it
//=======================================================
if( m_fUpdateNamespace )
{
CAutoBlock(WMIINTERFACE->HandleMap()->GetCriticalSection());
nRc = WMIINTERFACE->HandleMap()->ExistingHandleAlreadyExistsForThisGuidUseIt( *(m_Class->GuidPtr()), m_hCurrentWMIHandle, m_fCloseHandle ,m_uDesiredAccess);
if( nRc != ERROR_SUCCESS)
{
nRc = AssignNewHandleAndKeepItIfWMITellsUsTo();
}
}
else
{
nRc = AssignNewHandleAndKeepItIfWMITellsUsTo();
}
hr = MapReturnCode(nRc);
return hr;
}
////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::ProcessDataBlock()
{
HRESULT hr = S_OK;
//================================================================
// Data blocks can either be of fixed instance size or dynamic
// instance size, call this function so we can determine what
// type of data ptr we are working with
// If there are no more, then break. Otherwise, we know
// we are processing at least one instance
//============================================================
ULONG *pMaxPtrTmp = m_pMaxPtr;
if( NoMore != AdjustDataBlockPtr(hr)){
hr = FillOutProperties();
}
m_pMaxPtr = pMaxPtrTmp;
//====================================================================
// If we didn't succeed in processing these blocks, write it out
// If invalid datablock is from Hi-Perf provider, don't log the data
// to the file as this could be because of Embededclass or array
// properties in the class
//====================================================================
if(hr == WMI_INVALID_HIPERFPROP)
{
hr = WBEM_E_FAILED;
}
else
if( hr != S_OK )
{
DumpWnodeInfo(ANSI_MSG_INVALID_DATA_BLOCK);
}
return hr;
}
////////////////////////////////////////////////////////////////////
int CWMIDataBlock::AdjustDataBlockPtr(HRESULT & hr)
{
int nType = NoMore;
//================================================================
// Get pointer to the data offsets
//================================================================
// INSTANCES ARE ALWAYS ALIGNED ON 8 bytes
if( m_fFixedInstance )
{
//========================================================
// If WNODE_FLAG_FIXED_INSTANCE_SIZE is set in Flags then
// FixedInstanceSize specifies the size of each data block.
//========================================================
// traverse all instances of requested class
//========================================================
if( m_nCurrentInstance == 1 )
{
m_pbWorkingDataPtr = m_pbCurrentDataPtr;
}
else
{
if( m_dwAccumulativeSizeOfBlock < m_pAllWnode->FixedInstanceSize )
{
m_pbWorkingDataPtr += m_pAllWnode->FixedInstanceSize - m_dwAccumulativeSizeOfBlock ;
m_dwAccumulativeSizeOfBlock += m_pAllWnode->FixedInstanceSize - m_dwAccumulativeSizeOfBlock;
}
//=============================================================================
// make sure we adjust for the fixed instance size, then make sure that it is
// on an 8 byte boundary.
// otherwise, we are going to calculate where it should go next
//=============================================================================
DWORD dwBytesToPad = 0 ;
DWORD dwReminder = m_dwAccumulativeSizeOfBlock % 8 ;
if ( 0 < dwReminder )
{
dwBytesToPad = 8 - dwReminder ;
}
if ( 0 < dwBytesToPad )
{
AddPadding ( dwBytesToPad ) ;
m_dwAccumulativeSizeOfBlock += dwBytesToPad ;
}
//
// just get maximum ptr where returned data are
//
m_pMaxPtr = (ULONG *)OffsetToPtr(m_pbWorkingDataPtr, m_pAllWnode->FixedInstanceSize);
}
nType = ProcessOneFixedInstance;
}
else
{
m_dwAccumulativeSizeOfBlock = 0L;
//====================================================
//
// If WMI_FLAG_FIXED_DATA_SIZE is not set then
// OffsetInstanceData data is an array of ULONGS that
// specifies the offsets to the data blocks for each
// instance. In this case there is an array of
// InstanceCount ULONGs followed by the data blocks.
//
// struct {
// ULONG OffsetInstanceData;
// ULONG LengthInstanceData;
// } OffsetInstanceDataAndLength[]; /* [InstanceCount] */
//====================================================
ULONG uOffset;
memcpy( &uOffset, m_pbCurrentDataPtr, sizeof(ULONG) );
if( uOffset == 0 )
{
nType = NoMore;
hr = S_OK;
}
else
{
m_pbCurrentDataPtr += sizeof( ULONG );
memcpy( &m_uInstanceSize, m_pbCurrentDataPtr, sizeof(ULONG) );
m_pbCurrentDataPtr += sizeof( ULONG );
m_pbWorkingDataPtr =(BYTE*) (ULONG *)OffsetToPtr(m_pAllWnode, uOffset);
nType = ProcessUnfixedInstance;
m_pMaxPtr = (ULONG *)OffsetToPtr(m_pbWorkingDataPtr, m_uInstanceSize);
}
}
return nType;
}
/////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::ProcessNameBlock(BOOL fSetName)
{
HRESULT hr = WBEM_E_FAILED;
WCHAR wName[NAME_SIZE+2];
SHORT NameLen = 0;
BYTE *pbData;
ULONG * upNameOffset = NULL;
memset(wName,NULL,NAME_SIZE+2);
//=====================================================
// Either the m_pAllWnode or m_pSingleNode is Null,
// which ever isn't, is the type we are working with
//=====================================================
if( m_pAllWnode ){
if( IsBadReadPtr( m_upNameOffsets, sizeof( ULONG *)) == 0 ){
upNameOffset = ((ULONG *)OffsetToPtr(m_pAllWnode, *m_upNameOffsets));
}
}
else{
upNameOffset = m_upNameOffsets;
}
hr = WBEM_E_INVALID_OBJECT;
if( IsBadReadPtr( upNameOffset, sizeof( ULONG *)) == 0 ){
if((ULONG *) (upNameOffset) < m_pMaxPtr ){
//================================================================
// Get pointer to the name offsets & point to next one
//================================================================
pbData = (LPBYTE)upNameOffset;
if( PtrOk((ULONG*)pbData,(ULONG)0) ){
if( pbData ){
memcpy( &NameLen, pbData, sizeof(USHORT) );
pbData += sizeof(USHORT);
if( NameLen > 0 ){
if( PtrOk((ULONG*)pbData,(ULONG)NameLen) ){
memcpy(wName,pbData,NameLen);
pbData+=NameLen;
hr = m_Class->SetInstanceName(wName,fSetName);
}
}
}
}
}
}
//====================================================================
// If we didn't succeed in processing these blocks, write it out
//====================================================================
if( hr != S_OK ){
DumpWnodeInfo(ANSI_MSG_INVALID_NAME_BLOCK);
}
return hr;
}
////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::ProcessBinaryMofDataBlock( CVARIANT & vResourceName,WCHAR * wcsTmp, int cchSize )
{
HRESULT hr = WBEM_E_FAILED;
ULONG *pMaxPtrTmp = m_pMaxPtr;
AdjustDataBlockPtr(hr);
m_pMaxPtr = pMaxPtrTmp;
CWMIBinMof bMof;
hr = bMof.Initialize(WMIINTERFACE,m_fUpdateNamespace);
if( S_OK == hr )
{
if ( SUCCEEDED ( hr = bMof.SetBinaryMofClassName(vResourceName.GetStr(),wcsTmp, cchSize) ) )
{
hr = bMof.ExtractBinaryMofFromDataBlock(m_pbWorkingDataPtr,m_uInstanceSize,wcsTmp, m_fMofHasChanged);
if( hr != S_OK )
{
DumpWnodeInfo(ANSI_MSG_INVALID_DATA_BLOCK);
}
//===============================================
// Get the next node name and data ptrs ready
//===============================================
if( m_pAllWnode )
{
GetNextNode();
}
m_nCurrentInstance++;
}
}
return hr;
}
////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::AddBinaryMof(CVARIANT & vImagePath,CVARIANT & vResourceName)
{
HRESULT hr = WBEM_E_OUT_OF_MEMORY;
CAutoWChar wcsTmp(MAX_PATH*2);
if( wcsTmp.Valid() )
{
hr = WBEM_E_INVALID_OBJECT;
//=================================================================
// if we have an image path and resource path, then do the normal
// thing
//=================================================================
if((vResourceName.GetType() != VT_NULL ) && ( vImagePath.GetType() != VT_NULL ))
{
//=============================================================
// If this was a mof that was being added, then add it
//=============================================================
CWMIBinMof bMof;
hr = bMof.Initialize(WMIINTERFACE,m_fUpdateNamespace);
if( S_OK == hr )
{
bMof.ExtractBinaryMofFromFile(vImagePath.GetStr(),vResourceName.GetStr(),wcsTmp, MAX_PATH*2, m_fMofHasChanged);
}
}
else if( vResourceName.GetType() != VT_NULL ){
//=================================================================
// if we have a resource to query for
//=================================================================
CProcessStandardDataBlock * pTmp = new CProcessStandardDataBlock();
if( pTmp )
{
try
{
pTmp->UpdateNamespace(m_fUpdateNamespace);
pTmp->SetClassProcessPtr(m_Class);
hr = pTmp->OpenWMIForBinaryMofGuid();
if( hr == S_OK )
{
hr = pTmp->QuerySingleInstance(vResourceName.GetStr());
if( hr == S_OK )
{
hr = pTmp->ProcessBinaryMofDataBlock(vResourceName,wcsTmp, MAX_PATH*2);
m_fMofHasChanged = pTmp->HasMofChanged();
}
else
{
ERRORTRACE((THISPROVIDER,"***************************************\n"));
ERRORTRACE((THISPROVIDER,"Instance failed for: "));
TranslateAndLog(vResourceName.GetStr());
ERRORTRACE((THISPROVIDER,"***************************************\n"));
}
}
SAFE_DELETE_PTR(pTmp);
}
catch(...)
{
SAFE_DELETE_PTR(pTmp);
hr = WBEM_E_UNEXPECTED;
throw;
}
}
}
}
return hr;
}
////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::ProcessBinaryMof()
{
//================================================================
// The binary mof blocks are always going to be two strings,
// 1). Image Path
// 2). Mof resource name
//
// If the image path and resource name are both filled in, then
// we need to go open the file and extract the binary mof as
// usual.
// If the Imagepath is empty, then the mof resource name is going
// to contain the static instance name to query for, we then
// process that.
//================================================================
CVARIANT vImagePath, vResourceName;
CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
m_dwAccumulativeSizeOfBlock = 0;
HRESULT hr = MapWMIData.GetDataFromDataBlock(vImagePath,VT_BSTR,0);
if( SUCCEEDED(hr) )
{
hr = MapWMIData.GetDataFromDataBlock(vResourceName,VT_BSTR,0);
if( hr == S_OK )
{
if( m_Class->GetHardCodedGuidType() == MOF_ADDED )
{
hr = AddBinaryMof( vImagePath, vResourceName);
}
else
{
CWMIBinMof bMof;
hr = bMof.Initialize(WMIINTERFACE,m_fUpdateNamespace);
if( S_OK == hr )
{
hr = bMof.DeleteMofsFromEvent(vImagePath, vResourceName, m_fMofHasChanged);
}
}
}
}
return hr;
}
////////////////////////////////////////////////////////////////////
BOOL CWMIDataBlock::ResetMissingQualifierValue(WCHAR * pwcsProperty, CVARIANT & vToken )
{
BOOL fRc = FALSE;
CVARIANT vQual;
CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
//============================================================
// We are only going to support this for numerical types
//============================================================
HRESULT hr = m_Class->GetQualifierValue(pwcsProperty, L"MissingValue", (CVARIANT*)&vQual);
if( hr == S_OK ){
if( vQual.GetType() != VT_EMPTY ){
if( Map.SetDefaultMissingQualifierValue( vQual, m_Class->PropertyType(), vToken ) ){
fRc = TRUE;
}
}
}
return fRc;
}
////////////////////////////////////////////////////////////////////
BOOL CWMIDataBlock::ResetMissingQualifierValue(WCHAR * pwcsProperty, SAFEARRAY *& pSafe)
{
BOOL fRc = FALSE;
CVARIANT vQual;
CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
//============================================================
// We are only going to support this for numerical types
//============================================================
HRESULT hr = m_Class->GetQualifierValue(pwcsProperty, L"MissingValue", (CVARIANT*)&vQual);
if( hr == S_OK ){
if( vQual.GetType() != VT_EMPTY )
{
SAFEARRAY * psa = V_ARRAY((VARIANT*)vQual);
CSAFEARRAY Safe(psa);
CVARIANT vElement;
DWORD dwCount = Safe.GetNumElements();
//============================================================
// Now, process it
//============================================================
if( dwCount > 0 ){
// Set each element of the array
for (DWORD i = 0; i < dwCount; i++){
if( S_OK == Safe.Get(i,&vElement) ){
long lType = m_Class->PropertyType();
if( Map.SetDefaultMissingQualifierValue( vQual, lType, vElement ) ){
Map.PutInArray(pSafe,(long *)&i,lType,(VARIANT * )vElement);
fRc = TRUE;
}
}
}
}
Safe.Unbind();
}
}
return fRc;
}
////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::RegisterWMIEvent( WCHAR * wcsGuid, ULONG_PTR uContext, CLSID & Guid, BOOL fRegistered)
{
ULONG Status;
HRESULT hr = WBEM_E_UNEXPECTED;
if( SetGuid(wcsGuid, Guid) ){
try
{
if( !fRegistered )
{
Status = WmiNotificationRegistration(&Guid, TRUE, EventCallbackRoutine, uContext, NOTIFICATION_CALLBACK_DIRECT);
}
else
{
Status = WmiNotificationRegistration(&Guid, TRUE, EventCallbackRoutine, uContext, NOTIFICATION_CHECK_ACCESS );
}
hr = MapReturnCode(Status);
}
catch(...)
{
// don't throw
}
}
else
{
Status = GetLastError();
}
if( hr != S_OK )
{
ERRORTRACE((THISPROVIDER,"WmiNotificationRegistration failed ...%ld\n",Status));
}
return hr;
}
//=============================================================
void CWMIDataBlock::GetNextNode()
{
BOOL fRc = FALSE;
//============================================================================================
// If we still have more instances to get, then get them
//============================================================================================
if( m_nCurrentInstance < m_nTotalInstances ){
m_upNameOffsets++;
fRc = TRUE;
}
else{
//========================================================================================
// Otherwise, lets see if we have another NODE to get, if not, then we are done.
//========================================================================================
if (m_pAllWnode->WnodeHeader.Linkage != 0){
m_pAllWnode = (PWNODE_ALL_DATA)OffsetToPtr(m_pAllWnode, m_pAllWnode->WnodeHeader.Linkage);
m_pHeaderWnode = &(m_pAllWnode->WnodeHeader);
m_nTotalInstances = m_pAllWnode->InstanceCount;
m_nCurrentInstance = 0;
m_upNameOffsets = (ULONG *)OffsetToPtr(m_pAllWnode, m_pAllWnode->OffsetInstanceNameOffsets);
if( ParseHeader() ){
fRc = InitializeDataPtr();
}
fRc = TRUE;
}
}
m_fMore = fRc;
}
////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::ReadWMIDataBlockAndPutIntoWbemInstance()
{
//===============================================
// Read the data and name blocks
//===============================================
HRESULT hr = ProcessDataBlock();
if( hr == S_OK ){
//=======================================================
// if this isn't a binary mof to process, then we will
// process the name block, otherwise we will return
// as binary mofs do not have any more useful info in
// them in the name block - we already have what we need
// from the data block ( at this present time anyway...)
//=======================================================
if( !m_Class->GetHardCodedGuidType() ){
hr = ProcessNameBlock(TRUE);
if( hr == S_OK ){
//===============================================
// Get the next node name and data ptrs ready
//===============================================
if( m_pAllWnode ){
GetNextNode();
}
m_nCurrentInstance++;
}
}
}
return hr;
}
//=============================================================
HRESULT CWMIDataBlock::ReAllocateBuffer(DWORD dwAddOn)
{
HRESULT hr = WBEM_E_FAILED;
m_dwCurrentAllocSize += MEMSIZETOALLOCATE * ((dwAddOn / MEMSIZETOALLOCATE) +1);
// save the old buffer ptr
BYTE * pOld = m_pbDataBuffer;
if( pOld ){
// save the location of where we are
ULONG_PTR dwHowmany;
dwHowmany = (ULONG_PTR)m_pbWorkingDataPtr - (ULONG_PTR)m_pbDataBuffer;
// get the new buffer
m_pbDataBuffer = new BYTE[m_dwCurrentAllocSize+1];
if( m_pbDataBuffer )
{
// copy what we have so far
memcpy(m_pbDataBuffer,pOld,dwHowmany);
// Set the working ptr to the current place
m_pbWorkingDataPtr = m_pbDataBuffer;
m_pbWorkingDataPtr += dwHowmany;
// delete the old buffer
SAFE_DELETE_ARRAY(pOld);
hr = S_OK;
}
else
{
m_dwCurrentAllocSize -= MEMSIZETOALLOCATE * ((dwAddOn / MEMSIZETOALLOCATE) +1);
m_pbDataBuffer = pOld;
}
}
return hr;
}
//=============================================================
HRESULT CWMIDataBlock::AllocateBuffer(DWORD dwSize)
{
HRESULT hr = WBEM_E_FAILED;
m_pbDataBuffer = new byte[dwSize+2];
if( m_pbDataBuffer )
{
hr = S_OK;
}
return hr;
}
//=============================================================
void CWMIDataBlock::ResetDataBuffer()
{
if(m_dwCurrentAllocSize)
{
m_dwDataBufferSize = 0;
m_dwCurrentAllocSize = 0;
SAFE_DELETE_ARRAY(m_pbDataBuffer);
}
}
//=============================================================
HRESULT CWMIDataBlock::SetAllInstancePtr( PWNODE_ALL_DATA pwAllNode )
{
m_pbDataBuffer = (BYTE*)pwAllNode;
return(SetAllInstanceInfo());
}
//=============================================================
HRESULT CWMIDataBlock::SetSingleInstancePtr( PWNODE_SINGLE_INSTANCE pwSingleNode )
{
m_pbDataBuffer = (BYTE*)pwSingleNode;
return(SetSingleInstanceInfo());
}
//=============================================================
HRESULT CWMIDataBlock::SetAllInstanceInfo()
{
HRESULT hr = WBEM_E_INVALID_OBJECT;
if( m_pbDataBuffer ){
m_pAllWnode = (PWNODE_ALL_DATA)m_pbDataBuffer;
m_upNameOffsets = (ULONG *)OffsetToPtr(m_pAllWnode, m_pAllWnode->OffsetInstanceNameOffsets);
m_nCurrentInstance = 1;
m_nTotalInstances = m_pAllWnode->InstanceCount;
m_pHeaderWnode = &(m_pAllWnode->WnodeHeader);
m_pSingleWnode = NULL;
if( m_nTotalInstances > 0 ){
if( ParseHeader() ){
if( InitializeDataPtr()){
hr = S_OK;
}
}
}
else{
hr = WBEM_S_NO_MORE_DATA;
}
}
return hr;
}
//=============================================================
HRESULT CWMIDataBlock::SetSingleInstanceInfo()
{
HRESULT hr = WBEM_E_INVALID_OBJECT;
if( m_pbDataBuffer ){
m_pSingleWnode = (PWNODE_SINGLE_INSTANCE)m_pbDataBuffer;
m_upNameOffsets = (ULONG *)OffsetToPtr(m_pSingleWnode, m_pSingleWnode->OffsetInstanceName);
m_nCurrentInstance = 1;
m_nTotalInstances = 1;
m_pAllWnode = NULL;
m_pHeaderWnode = &(m_pSingleWnode->WnodeHeader);
if( ParseHeader() ){
if( InitializeDataPtr()){
hr = S_OK;
}
}
}
return hr;
}
//=============================================================
BOOL CWMIDataBlock::InitializeDataPtr()
{
//=====================================================
// Either the m_pAllWnode or m_pSingleNode is Null,
// which ever isn't, is the type we are working with
//=====================================================
if(m_pAllWnode){
if( m_fFixedInstance ){
m_pbCurrentDataPtr =(BYTE*) (ULONG *)OffsetToPtr(m_pAllWnode, m_pAllWnode->DataBlockOffset);
//==========================================================================================
// for the case of binary mofs, we need to know the size of the instance to calculate the
// crc, so we need to put the whole size of the fixed instance buffer.
//==========================================================================================
m_uInstanceSize = m_pAllWnode->FixedInstanceSize;
}
else{
m_pbCurrentDataPtr =(BYTE*)(ULONG*) m_pAllWnode->OffsetInstanceDataAndLength;
}
m_pMaxPtr = (ULONG *)OffsetToPtr(m_pAllWnode, m_pHeaderWnode->BufferSize);
}
else{
if( m_pSingleWnode ){
m_fFixedInstance = TRUE;
m_pbCurrentDataPtr = (BYTE*)(ULONG *)OffsetToPtr(m_pSingleWnode, m_pSingleWnode->DataBlockOffset);
m_pMaxPtr = (ULONG *)OffsetToPtr(m_pSingleWnode, m_pHeaderWnode->BufferSize);
//==========================================================================================
// for the case of binary mofs, we need to know the size of the instance to calculate the
// crc, so we need to put the whole size of the fixed instance buffer.
//==========================================================================================
m_uInstanceSize = m_pSingleWnode->SizeDataBlock;
}
}
if( (ULONG*)m_pbCurrentDataPtr > (ULONG*) m_pMaxPtr ){
return FALSE;
}
if( (ULONG*) m_pbCurrentDataPtr < (ULONG*) m_pAllWnode ){
return FALSE;
}
return TRUE;
}
//=============================================================
BOOL CWMIDataBlock::ParseHeader()
{
BOOL fRc;
//====================================================
// Check out class to see if it is valid first
//====================================================
if( !m_pHeaderWnode ){
return FALSE;
}
m_ulVersion = m_pHeaderWnode->Version;
if ((m_pHeaderWnode->BufferSize == 0)){
fRc = FALSE;
}
else{
if (m_pHeaderWnode->Flags & WNODE_FLAG_FIXED_INSTANCE_SIZE){
m_fFixedInstance = TRUE;
}
else{
m_fFixedInstance = FALSE;
}
fRc = TRUE;
}
return fRc;
}
////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::WriteArrayTypes(WCHAR * pwcsProperty, CVARIANT & v)
{
LONG lType = 0;
DWORD dwCount = 0;
HRESULT hr = WBEM_E_INVALID_PARAMETER;
CVARIANT vValue;
BOOL fDynamic = FALSE;
m_Class->GetSizeOfArray( lType,dwCount, fDynamic);
if( fDynamic && dwCount == 0 )
{
return WBEM_S_NO_ERROR;
}
//============================================================
// Make sure we get a valid ptr
//============================================================
VARIANT *p = (VARIANT *)v;
SAFEARRAY * psa = V_ARRAY(p);
if( IsBadReadPtr( psa, sizeof(SAFEARRAY) != 0)){
ERRORTRACE((THISPROVIDER,"*****************************************\n"));
ERRORTRACE((THISPROVIDER,"Class ... %S\n", m_Class->GetClassName()));
ERRORTRACE((THISPROVIDER,"Current property ... %S\n", pwcsProperty));
ERRORTRACE((THISPROVIDER,"\n"));
ERRORTRACE((THISPROVIDER,"array ptr ... %x\n", psa));
ERRORTRACE((THISPROVIDER,"*****************************************\n"));
return hr;
}
CSAFEARRAY Safe(psa);
//============================================================
// Make sure there is really what we expect in the array
// NOTE: The MAX represents the fixed size of the array,
// while if it is a dynamic array, the size is determined
// by the property listed in the WMIDATASIZE is property.
// either way, the size returned above is the size the
// array is supposed to be, if it isn't error out.
//============================================================
DWORD dwNumElements = Safe.GetNumElements();
if( dwNumElements != dwCount )
{
Safe.Unbind();
ERRORTRACE((THISPROVIDER,"*****************************************\n"));
ERRORTRACE((THISPROVIDER,"Class ... %S\n", m_Class->GetClassName()));
ERRORTRACE((THISPROVIDER,"Current property ... %S\n", pwcsProperty));
ERRORTRACE((THISPROVIDER,"\n"));
ERRORTRACE((THISPROVIDER,"Expected size ... %d\n", dwCount));
ERRORTRACE((THISPROVIDER,"Current size ... %d\n", dwNumElements));
ERRORTRACE((THISPROVIDER,"*****************************************"));
// Don't need to destroy, it will be destroyed
return WBEM_E_INVALID_PARAMETER;
}
//============================================================
// Set missing qualifier value to the value from the NULL
//============================================================
if( vValue.GetType() == VT_NULL ){
ResetMissingQualifierValue(pwcsProperty,psa);
}
// if the array is not array of embedded instances
// then check if the buffer allocated is enough
if(lType != VT_UNKNOWN)
{
// This function check if enought memory is allocated and if not
// allocates memory
if(S_OK != GetBufferReady ( m_Class->PropertySize() * ( dwCount + 1 ) ) )
{
return WBEM_E_FAILED;
}
}
//============================================================
// Now, process it
//============================================================
if( dwCount > 0 ){
// Set each element of the array
for (DWORD i = 0; i < dwCount; i++){
if( lType == VT_UNKNOWN ){
// embedded object
IUnknown * pUnk = NULL;
hr = Safe.Get(i, &pUnk);
if( pUnk ){
hr = WriteEmbeddedClass(pUnk,vValue);
}
else{
hr = WBEM_E_FAILED;
}
}
else{
CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
if(!MapWMIData.SetDataInDataBlock(&Safe,i,vValue,lType,m_Class->PropertySize()) ){
hr = WBEM_E_FAILED;
break;
}
else{
hr = S_OK;
}
}
if (WBEM_S_NO_ERROR != hr){
break;
}
}
}
Safe.Unbind();
// Don't need to destroy, it will be destroyed
return hr;
}
////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::ProcessArrayTypes(VARIANT & vToken,WCHAR * pwcsProperty)
{
LONG lConvertedType = 0, lType = 0;
DWORD dwCount = 0;
BOOL fDynamic = TRUE;
HRESULT hr = m_Class->GetSizeOfArray( lType,dwCount, fDynamic);
if( hr != S_OK ){
return hr;
}
if( dwCount > 0 )
{
CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
//======================================================
// Allocate array with the converted data type.
// WMI and CIM data types do not match, so use the
// mapping class to get the correct size of the target
// property for CIM
//======================================================
lConvertedType = MapWMIData.ConvertType(lType);
SAFEARRAY * psa = OMSSafeArrayCreate((unsigned short)lConvertedType,dwCount);
if(psa == NULL)
{
return WBEM_E_FAILED;
}
//=======================================================
// Now, get the MissingValue for each element of the
// array
//=======================================================
lConvertedType = lType;
BOOL fMissingValue = FALSE;
CVARIANT vQual;
SAFEARRAY * psaMissingValue = NULL;
long lMax = 0;
CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
hr = m_Class->GetQualifierValue( pwcsProperty, L"MissingValue", (CVARIANT *)&vQual );
if( hr == S_OK )
{
if( vQual.GetType() != VT_EMPTY )
{
if( vQual.GetType() & VT_ARRAY )
{
//============================================================
// Make sure we get a valid ptr
//============================================================
psaMissingValue = V_ARRAY((VARIANT*)&vQual);
fMissingValue = TRUE;
// Don't need to destroy, it will be destroyed in the deconstructor
}
}
}
CSAFEARRAY SafeMissingValue(psaMissingValue);
if( fMissingValue )
{
lMax = SafeMissingValue.GetNumElements();
}
for (long i = 0; i < (long)dwCount; i++)
{
CVARIANT v;
if( lType == VT_UNKNOWN )
{
// embedded object
hr = ProcessEmbeddedClass(v);
if( S_OK == hr )
{
MapWMIData.PutInArray(psa,(long *)&i,lConvertedType,(VARIANT * )v);
}
}
else
{
hr = MapWMIData.GetDataFromDataBlock(v,lType,m_Class->PropertySize());
if( hr != S_OK )
{
StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_INVALID_BLOCK_POINTER );
}
else
{
BOOL fPutProperty = TRUE;
if( fMissingValue )
{
if( i < lMax )
{
CVARIANT vElement;
if( Map.MissingQualifierValueMatches( &SafeMissingValue, i, vElement, v.GetType(), v ) )
{
fPutProperty = FALSE;
}
}
}
if( fPutProperty )
{
MapWMIData.PutInArray(psa,(long *)&i,lConvertedType,(VARIANT * )v);
}
}
}
if (WBEM_S_NO_ERROR != hr)
{
break;
}
}
SafeMissingValue.Unbind();
vToken.vt = (VARTYPE)(lConvertedType | CIM_FLAG_ARRAY);
vToken.parray = psa;
}
else{
hr = WBEM_S_NO_MORE_DATA;
}
return hr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::ProcessEmbeddedClass(CVARIANT & v)
{
HRESULT hr = WBEM_E_FAILED;
CWMIProcessClass EmbeddedClass(0);
hr = EmbeddedClass.Initialize();
if( S_OK == hr )
{
hr = EmbeddedClass.InitializeEmbeddedClass(m_Class);
DWORD dwAccumulativeSize = 0;
CAutoChangePointer p(&m_Class,&EmbeddedClass);
if( hr == S_OK ){
//=============================================
// Align the embedded class properly
//=============================================
int nSize = 0L;
hr = EmbeddedClass.GetLargestDataTypeInClass(nSize);
// NTRaid:136388
// 07/12/00
if( hr == S_OK && nSize > 0){
CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
if( Map.NaturallyAlignData(nSize, READ_IT)){
dwAccumulativeSize = m_dwAccumulativeSizeOfBlock - nSize;
hr = S_OK;
}
else{
hr = WBEM_E_FAILED;
}
}
else
if(nSize <= 0 && hr == S_OK)
{
hr = WBEM_E_FAILED;
}
}
//=============================================
// Get the class
//=============================================
if( hr == S_OK ){
hr = FillOutProperties();
if( hr == S_OK ){
m_dwAccumulativeSizeOfBlock += dwAccumulativeSize;
//=============================================
// Save the object
//=============================================
EmbeddedClass.SaveEmbeddedClass(v);
}
}
}
return hr;
}
//////////////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::WriteEmbeddedClass( IUnknown * pUnknown,CVARIANT & v)
{
HRESULT hr = WBEM_E_FAILED;
CWMIProcessClass EmbeddedClass(0);
hr = EmbeddedClass.Initialize();
if( S_OK == hr )
{
hr = EmbeddedClass.InitializeEmbeddedClass(m_Class);
CAutoChangePointer p(&m_Class,&EmbeddedClass);
//=============================================
hr = EmbeddedClass.ReadEmbeddedClassInstance(pUnknown,v);
if( hr == S_OK ){
//=============================================
// Align the embedded class properly
//=============================================
int nSize = 0L;
hr = EmbeddedClass.GetLargestDataTypeInClass(nSize);
if( hr == S_OK && nSize > 0){
CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
if( Map.NaturallyAlignData(nSize,WRITE_IT)){
m_dwAccumulativeSizeOfBlock -= nSize;
hr = ConstructDataBlock(FALSE);
}
else{
hr = WBEM_E_FAILED;
}
}
else{
hr = WBEM_E_FAILED;
}
}
}
return hr;
}
///////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::SetSingleItem()
{
WCHAR * pwcsInst = NULL;
ULONG uRc = E_UNEXPECTED;
if( SUCCEEDED(m_Class->GetInstanceName(pwcsInst)))
{
try
{
uRc = WmiSetSingleItem( m_hCurrentWMIHandle, pwcsInst, m_Class->WMIDataId(), m_ulVersion, m_dwDataBufferSize, m_pbDataBuffer);
}
catch(...)
{
// don't throw
}
SAFE_DELETE_ARRAY(pwcsInst);
}
return(MapReturnCode(uRc));
}
////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::GetBufferReady(DWORD dwCount)
{
//
// is accumulation passing allocation already?
//
if( ( m_dwAccumulativeSizeOfBlock + dwCount ) >= m_dwCurrentAllocSize )
{
if( FAILED(ReAllocateBuffer(dwCount)))
{
return WBEM_E_FAILED;
}
}
return S_OK;
}
////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::WriteDataToBufferAndIfSinglePropertySubmitToWMI( BOOL fInit, BOOL fPutProperty)
{
HRESULT hr = WBEM_E_FAILED;
CIMTYPE lType;
WCHAR * pwcsProperty;
CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
if( fInit ){
if( !GetDataBlockReady(MEMSIZETOALLOCATE,FALSE) ){
return WBEM_E_FAILED;
}
}
//=============================================================
// get first delimiter in the ordered string
//=============================================================
pwcsProperty = m_Class->FirstProperty();
while (NULL != pwcsProperty){
CVARIANT vValue;
vValue.Clear();
memset(&vValue,0,sizeof(CVARIANT));
//======================================================
// Get a property type and value
//======================================================
hr = m_Class->GetPropertyInInstance(pwcsProperty, vValue, lType);
//======================================================
// We need to put in defaults if there are some
// available
//======================================================
if( hr == S_OK ){
if( ( vValue.GetType() == VT_NULL )&&
( m_Class->PropertyType() != CIM_STRING &&
m_Class->PropertyType() != CIM_DATETIME &&
m_Class->PropertyCategory() != CWMIProcessClass::Array))
{
ERRORTRACE((THISPROVIDER,"*****************************************\n"));
ERRORTRACE((THISPROVIDER,"Class ... %S\n", m_Class->GetClassName()));
ERRORTRACE((THISPROVIDER,"Current property ... %S\n", pwcsProperty));
ERRORTRACE((THISPROVIDER,"\n"));
ERRORTRACE((THISPROVIDER,"value type ... VT_NULL\n"));
ERRORTRACE((THISPROVIDER,"cim type ... %d\n", lType));
ERRORTRACE((THISPROVIDER,"property type ... %d\n", m_Class->PropertyType()));
ERRORTRACE((THISPROVIDER,"*****************************************\n"));
hr = WBEM_E_INVALID_PARAMETER;
break;
}
}
if( SUCCEEDED(hr) ) {
//==================================================
// Check to see if the buffer is big enough
//==================================================
if( S_OK != GetBufferReady(m_Class->PropertySize())) {
return WBEM_E_FAILED;
}
//==================================================
// Add the current buffer size
//==================================================
switch( m_Class->PropertyCategory()) {
case CWMIProcessClass::EmbeddedClass:
hr = WriteEmbeddedClass((IUnknown *)NULL,vValue);
break;
case CWMIProcessClass::Array:
hr = WriteArrayTypes(pwcsProperty,vValue);
break;
case CWMIProcessClass::Data:
//============================================================
// Set missing qualifier value to the value from the NULL
//============================================================
if( vValue.GetType() == VT_NULL ) {
ResetMissingQualifierValue(pwcsProperty,vValue);
}
if( !MapWMIData.SetDataInDataBlock( NULL,0,vValue,m_Class->PropertyType(),m_Class->PropertySize())) {
hr = WBEM_E_FAILED;
}
break;
}
//=================================================
// If we could not set it, then get out
//=================================================
if( hr != S_OK ){
break;
}
//=================================================
// If we are supposed to put the single property
// at this point, then write it, otherwise, keep
// accumulating it. If it is == NULL, we don't
// want it.
//=================================================
if( fPutProperty ){
//=================================================================================
// If we are supposed to set just this property, then do so, otherwise don't
//=================================================================================
m_dwDataBufferSize = m_dwAccumulativeSizeOfBlock;
if( m_Class->GetPutProperty() ){
if( ( vValue.GetType() == VT_NULL )&& ( m_Class->PropertyType() != CIM_STRING && m_Class->PropertyType() != CIM_DATETIME )){
ERRORTRACE((THISPROVIDER,"Datatype does not support NULL values\n"));
hr = WBEM_E_INVALID_PARAMETER;
}
else{
hr = SetSingleItem();
if( hr != S_OK ){
break;
}
if( !GetDataBlockReady(MEMSIZETOALLOCATE,FALSE) ){
return hr;
}
}
}
m_dwAccumulativeSizeOfBlock = 0;
}
//=================================================
}
m_dwDataBufferSize = m_dwAccumulativeSizeOfBlock;
pwcsProperty = m_Class->NextProperty();
}
return hr;
}
////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::ConstructDataBlock(BOOL fInit)
{
return( WriteDataToBufferAndIfSinglePropertySubmitToWMI(fInit,FALSE) );
}
////////////////////////////////////////////////////////////////////////
HRESULT CWMIDataBlock::PutSingleProperties()
{
return( WriteDataToBufferAndIfSinglePropertySubmitToWMI(TRUE,TRUE) );
}
////////////////////////////////////////////////////////////////////////
BOOL CWMIDataBlock::GetListOfPropertiesToPut(int nWhich, CVARIANT & vList)
{
BOOL fRc = FALSE;
//=========================================================
// if nWhich == PUT_PROPERTIES_ONLY, we aren't going to
// do anything special, as, by default, the fPutProperty
// flag on the property is set to TRUE, so, in the
// processing above, we will put the properties that are
// not NULL. The only problem we have now, is if
// __PUT_EXT_PROPERTIES is set to TRUE, then we have to
// loop through all of the properties to see it they
// are in our __PUT_EXT_PROPERTIES list, if they are NOT
// then we are going to set the fPutProperty flag on that
// property to FALSE, so we won't process it above.
//=========================================================
if( nWhich == PUT_PROPERTIES_ONLY ){
fRc = TRUE;
}
else{
//=====================================================
// Make sure we get a valid ptr
//=====================================================
SAFEARRAY * psa = V_ARRAY((VARIANT*)vList);
if( IsBadReadPtr( psa, sizeof(SAFEARRAY) != 0))
{
return FALSE;
}
CSAFEARRAY Safe(psa);
DWORD dwCount = Safe.GetNumElements();
// Set each element of the array
for (DWORD i = 0; i < dwCount; i++){
CBSTR bstrProperty;
WCHAR * pwcsProperty = NULL;
//=================================================
// Loop thru all the properties in the class and
// see which ones are in the list to be PUT
//=================================================
pwcsProperty = m_Class->FirstProperty();
while( pwcsProperty != NULL ){
BOOL fFound = FALSE;
for (DWORD j = 0; j < dwCount; j++)
{
if( S_OK != Safe.Get(j, &bstrProperty))
{
return FALSE;
}
if( wbem_wcsicmp( bstrProperty, pwcsProperty ) == 0 )
{
fFound = TRUE;
break;
}
}
if( !fFound ){
m_Class->SetPutProperty(FALSE);
}
pwcsProperty = m_Class->NextProperty();
}
}
Safe.Unbind();
// Don't need to destroy, it will be destroyed
fRc = TRUE;
}
return fRc;
}
//=============================================================
BOOL CWMIDataBlock::GetDataBlockReady(DWORD dwSize,BOOL fReadingData)
{
BOOL fRc = FALSE;
ResetDataBuffer();
m_dwCurrentAllocSize = dwSize;
if( SUCCEEDED(AllocateBuffer(m_dwCurrentAllocSize)))
{
m_pbCurrentDataPtr = m_pbWorkingDataPtr = m_pbDataBuffer;
//===================================================
// If we are writing data, we will let the size
// remain at 0, otherwise set it to what the max
// is we can read.
//===================================================
if(fReadingData){
m_dwDataBufferSize = dwSize;
}
fRc = TRUE;
}
else
{
m_dwCurrentAllocSize = 0;
}
return fRc;
}
//=============================================================
void CWMIDataBlock::AddPadding(DWORD dwBytesToPad)
{
m_pbWorkingDataPtr += dwBytesToPad ;
}
//=============================================================
inline BOOL CWMIDataBlock::PtrOk(ULONG * pPtr,ULONG uHowMany)
{
ULONG * pNewPtr;
pNewPtr = (ULONG *)OffsetToPtr(pPtr,uHowMany);
if(pNewPtr <= m_pMaxPtr){
return TRUE;
}
return FALSE;
}
//=============================================================
BOOL CWMIDataBlock::CurrentPtrOk(ULONG uHowMany)
{
return(PtrOk((ULONG *)m_pbWorkingDataPtr,uHowMany));
}
//=============================================================
void CWMIDataBlock::GetWord(WORD & wWord)
{
memcpy( &wWord,m_pbWorkingDataPtr,sizeof(WORD));
m_pbWorkingDataPtr += sizeof(WORD);
}
//=============================================================
void CWMIDataBlock::GetDWORD(DWORD & dwWord)
{
memcpy( &dwWord,m_pbWorkingDataPtr,sizeof(DWORD));
m_pbWorkingDataPtr += sizeof(DWORD);
}
//=============================================================
void CWMIDataBlock::GetFloat(float & fFloat)
{
memcpy( &fFloat,m_pbWorkingDataPtr,sizeof(float));
m_pbWorkingDataPtr += sizeof(float);
}
//=============================================================
void CWMIDataBlock::GetDouble(DOUBLE & dDouble)
{
memcpy( &dDouble,m_pbWorkingDataPtr,sizeof(DOUBLE));
m_pbWorkingDataPtr += sizeof(DOUBLE);
}
//=============================================================
HRESULT CWMIDataBlock::GetSInt64( WCHAR * pwcsBuffer, DWORD cchSize )
{
HRESULT hr = WBEM_E_FAILED;
signed __int64 * pInt64;
pInt64 = (__int64 *)m_pbWorkingDataPtr;
if ( SUCCEEDED ( hr = StringCchPrintfW ( pwcsBuffer, cchSize, L"%I64d", *pInt64 ) ) )
{
m_pbWorkingDataPtr += sizeof( signed __int64);
}
return hr;
}
//=============================================================
void CWMIDataBlock::GetQWORD(unsigned __int64 & uInt64)
{
memcpy( &uInt64,m_pbWorkingDataPtr,sizeof(unsigned __int64));
m_pbWorkingDataPtr += sizeof(unsigned __int64);
}
//=============================================================
HRESULT CWMIDataBlock::GetUInt64( WCHAR * pwcsBuffer, DWORD cchSize )
{
HRESULT hr = WBEM_E_FAILED;
unsigned __int64 * puInt64;
puInt64 = (unsigned __int64 *)m_pbWorkingDataPtr;
if ( SUCCEEDED ( hr = StringCchPrintfW ( pwcsBuffer,cchSize, L"%I64u", *puInt64 ) ) )
{
m_pbWorkingDataPtr += sizeof(unsigned __int64);
}
return hr;
}
//=============================================================
void CWMIDataBlock::GetString(WCHAR * pwcsBuffer,WORD wCount,WORD wBufferSize)
{
memset(pwcsBuffer,NULL,wBufferSize);
memcpy(pwcsBuffer,m_pbWorkingDataPtr, wCount);
m_pbWorkingDataPtr += wCount;
}
//=============================================================
void CWMIDataBlock::GetByte(BYTE & bByte)
{
memcpy( &bByte,m_pbWorkingDataPtr,sizeof(BYTE));
m_pbWorkingDataPtr += sizeof(BYTE);
}
//=============================================================
void CWMIDataBlock::SetWord(WORD wWord)
{
memcpy(m_pbWorkingDataPtr,&wWord,sizeof(WORD));
m_pbWorkingDataPtr += sizeof(WORD);
}
//=============================================================
void CWMIDataBlock::SetDWORD(DWORD dwWord)
{
memcpy(m_pbWorkingDataPtr,&dwWord,sizeof(DWORD));
m_pbWorkingDataPtr += sizeof(DWORD);
}
//=============================================================
void CWMIDataBlock::SetFloat(float fFloat)
{
memcpy(m_pbWorkingDataPtr,&fFloat,sizeof(float));
m_pbWorkingDataPtr += sizeof(float);
}
//=============================================================
void CWMIDataBlock::SetDouble(DOUBLE dDouble)
{
memcpy( m_pbWorkingDataPtr,&dDouble,sizeof(DOUBLE));
m_pbWorkingDataPtr += sizeof(DOUBLE);
}
//=============================================================
void CWMIDataBlock::SetSInt64(__int64 Int64)
{
memcpy(m_pbWorkingDataPtr,&Int64,sizeof(__int64));
m_pbWorkingDataPtr += sizeof(__int64);
}
//=============================================================
void CWMIDataBlock::SetUInt64(unsigned __int64 UInt64)
{
memcpy(m_pbWorkingDataPtr,&UInt64,sizeof(unsigned __int64));
m_pbWorkingDataPtr += sizeof(unsigned __int64);
}
//=============================================================
void CWMIDataBlock::SetString(WCHAR * pwcsBuffer,WORD wCount)
{
memcpy(m_pbWorkingDataPtr,pwcsBuffer, wCount);
m_pbWorkingDataPtr += wCount;
}
//=============================================================
void CWMIDataBlock::SetByte(byte bByte)
{
memcpy(m_pbWorkingDataPtr,&bByte,sizeof(byte));
m_pbWorkingDataPtr += sizeof(byte);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//*************************************************************************************************
//
// CProcessStandardDataBlock
//
//*************************************************************************************************
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CProcessStandardDataBlock::CProcessStandardDataBlock()
{
m_Class = NULL;
m_pMethodInput = NULL;
m_pMethodOutput = NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
CProcessStandardDataBlock::~CProcessStandardDataBlock()
{
}
////////////////////////////////////////////////////////////////////
// WMIRaid:2445
HRESULT CProcessStandardDataBlock::FillOutProperties()
{
HRESULT hr = WBEM_E_INVALID_OBJECT;
if( m_Class->GetHardCodedGuidType() )
{
hr = ProcessBinaryMof();
}
else if(m_Class->GetANewInstance()){
//=========================================================
// get the properties from the class and read the WMI Data
//=========================================================
hr = WBEM_S_NO_ERROR;
WCHAR * pwcsProperty=NULL;
CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
m_dwAccumulativeSizeOfBlock = 0L;
pwcsProperty = m_Class->FirstProperty();
while (NULL != pwcsProperty)
{
CVARIANT vToken;
//=========================================================
// See if it is an array or not
//=========================================================
switch( m_Class->PropertyCategory()){
case CWMIProcessClass::EmbeddedClass:
hr = ProcessEmbeddedClass(vToken);
if( hr == S_OK )
{
m_Class->PutPropertyInInstance(&vToken);
}
break;
case CWMIProcessClass::Array:
VARIANT v;
VariantInit(&v);
hr = ProcessArrayTypes(v,pwcsProperty);
if( hr == WBEM_S_NO_MORE_DATA )
{
hr = S_OK;
}
else if( SUCCEEDED(hr) )
{
hr = m_Class->PutPropertyInInstance(&v);
}
VariantClear(&v);
break;
case CWMIProcessClass::Data:
hr = MapWMIData.GetDataFromDataBlock(vToken, m_Class->PropertyType(), m_Class->PropertySize());
if( SUCCEEDED(hr) )
{
CWMIDataTypeMap Map(this,&m_dwAccumulativeSizeOfBlock);
//============================================================
// We are only going to support this for numerical types
//============================================================
CVARIANT vQual;
hr = m_Class->GetQualifierValue( pwcsProperty, L"MissingValue", (CVARIANT *)&vQual);
if( hr == S_OK )
{
if( vQual.GetType() != VT_EMPTY )
{
if( !(Map.MissingQualifierValueMatches( NULL, 0,vQual, vToken.GetType(), vToken ) ))
{
hr = m_Class->PutPropertyInInstance(&vToken);
}
}
else
{
hr = m_Class->PutPropertyInInstance(&vToken);
}
}
else
{
hr = m_Class->PutPropertyInInstance(&vToken);
}
}
else
{
StringCchCopyW ( m_wcsMsg, MSG_SIZE, MSG_INVALID_BLOCK_POINTER );
}
break;
}
pwcsProperty = m_Class->NextProperty();
}
//===============================================
// Set the active value
//===============================================
m_Class->SetActiveProperty();
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CProcessStandardDataBlock::CreateOutParameterBlockForMethods()
{
HRESULT hr = WBEM_E_FAILED;
BOOL fRc = FALSE;
//========================================================
// If we don't have a class, then we don't have to
// worry about creating a block
//========================================================
if( !m_pMethodOutput->ValidClass() ){
ResetDataBuffer();
return S_OK;
}
DWORD dwSize = 0L;
hr = m_pMethodOutput->GetSizeOfClass(dwSize);
if( hr == S_OK ){
// Allocate space for property
m_dwDataBufferSize = dwSize;
if( dwSize > 0 ){
GetDataBlockReady(dwSize,TRUE);
}
}
return hr;
}
//=============================================================
HRESULT CProcessStandardDataBlock::CreateInParameterBlockForMethods( BYTE *& Buffer, ULONG & uBufferSize)
{
HRESULT hr = WBEM_E_FAILED;
BOOL fRc = FALSE;
//========================================================
// If we don't have a class, then we don't have to
// worry about creating a block
//========================================================
if( !m_pMethodInput->ValidClass() ){
Buffer = NULL;
uBufferSize = 0;
return S_OK;
}
//========================================================
// When it goes out of scope, it will reset m_Class back
// to what it was
//========================================================
CAutoChangePointer p(&m_Class,m_pMethodInput);
DEBUGTRACE((THISPROVIDER,"Constructing the data block\n"));
hr = ConstructDataBlock(TRUE);
if( S_OK == hr ){
uBufferSize = (ULONG)m_dwDataBufferSize;
Buffer = new byte[ uBufferSize +1];
if( Buffer )
{
try
{
memcpy( Buffer, m_pbDataBuffer, uBufferSize );
ResetDataBuffer();
hr = S_OK;
}
catch(...)
{
SAFE_DELETE_ARRAY(Buffer);
hr = WBEM_E_UNEXPECTED;
throw;
}
}
}
return hr;
}
//=============================================================
HRESULT CProcessStandardDataBlock::ProcessMethodInstanceParameters()
{
HRESULT hr = WBEM_E_FAILED;
// Create out-param
// ================
m_pMaxPtr = (ULONG *)OffsetToPtr(m_pbDataBuffer, m_dwDataBufferSize);
m_nCurrentInstance = 1;
m_nTotalInstances = 1;
m_pAllWnode = NULL;
m_pHeaderWnode = NULL;
m_pbCurrentDataPtr = m_pbWorkingDataPtr = m_pbDataBuffer;
CAutoChangePointer p(&m_Class,m_pMethodOutput);
hr = FillOutProperties();
if( hr == S_OK )
{
hr = m_pMethodOutput->SendInstanceBack();
}
return hr;
}
//=============================================================
// NTRaid:127832
// 07/12/00
//=============================================================
HRESULT CProcessStandardDataBlock::ExecuteMethod(ULONG MethodId, WCHAR * MethodInstanceName, ULONG InputValueBufferSize,
BYTE * InputValueBuffer )
{
ULONG uRc = E_UNEXPECTED;
try
{
uRc = WmiExecuteMethod(m_hCurrentWMIHandle, MethodInstanceName, MethodId, InputValueBufferSize,
InputValueBuffer,&m_dwDataBufferSize,m_pbDataBuffer);
if( uRc == ERROR_INSUFFICIENT_BUFFER )
{
if( GetDataBlockReady(m_dwDataBufferSize,TRUE))
{
uRc = WmiExecuteMethod(m_hCurrentWMIHandle, MethodInstanceName, MethodId, InputValueBufferSize,
InputValueBuffer,&m_dwDataBufferSize,m_pbDataBuffer);
}
}
}
catch(...)
{
uRc = E_UNEXPECTED;
// don't throw
}
if( uRc == ERROR_SUCCESS ){
//===========================================================
// If we have an out class, process it, otherwise, we are
// done so set hr to success.
//===========================================================g
if( m_pMethodOutput->ValidClass() )
{
if(SUCCEEDED(ProcessMethodInstanceParameters())){
uRc = ERROR_SUCCESS;
}
}
}
return MapReturnCode(uRc);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
ULONG CProcessStandardDataBlock::GetDataBufferAndQueryAllData(DWORD dwSize)
{
ULONG uRc = E_UNEXPECTED;
if(GetDataBlockReady(dwSize,TRUE))
{
try
{
uRc = WmiQueryAllData(m_hCurrentWMIHandle, &m_dwDataBufferSize,m_pbDataBuffer);
}
catch(...)
{
uRc = E_UNEXPECTED;
// don't throw
}
}
return uRc;
}
/////////////////////////////////////////////////////////////////////
HRESULT CProcessStandardDataBlock::QueryAllData()
{
HRESULT hr = WBEM_E_FAILED;
//============================================================
// Get the instances
//============================================================
ULONG uRc = GetDataBufferAndQueryAllData(sizeof(WNODE_ALL_DATA));
if( uRc == ERROR_INSUFFICIENT_BUFFER )
{
//=================================================
// We just want to try one more time to get it,
// if it fails, then bail out. m_dwDataBufferSize
// should now have the correct size needed in it
//=================================================
uRc = GetDataBufferAndQueryAllData(m_dwDataBufferSize);
}
//=====================================================
// Ok, since we are querying for all instances, make
// sure the header node says that all of the instances
// are fine, if not reallocate
//=====================================================
if( uRc == ERROR_SUCCESS )
{
if( S_OK ==(hr = SetAllInstanceInfo()))
{
if (m_pHeaderWnode->Flags & WNODE_FLAG_TOO_SMALL)
{
while( TRUE )
{
//==========================================================
// keep on querying until we get the correct size
// This error may come from the driver
//==========================================================
uRc = GetDataBufferAndQueryAllData(m_dwDataBufferSize);
if( uRc == ERROR_SUCCESS )
{
if( S_OK ==(hr = SetAllInstanceInfo()))
{
if (!(m_pHeaderWnode->Flags & WNODE_FLAG_TOO_SMALL))
{
break;
}
}
} // end GetDataBufferAndQueryAllData
} // end of while
} // end of WNODE_FLAG_TOO_SMALL test
} // end of SetAllInstanceInfo
}
//==========================================================================
// if uRc succeeded, then the return code is already set by SetAllInstance
// otherwise need to map it out
//==========================================================================
if( uRc != ERROR_SUCCESS )
{
hr = MapReturnCode(uRc);
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
ULONG CProcessStandardDataBlock::GetDataBufferAndQuerySingleInstance(DWORD dwSize,WCHAR * wcsInstanceName)
{
ULONG uRc = E_UNEXPECTED;
if(GetDataBlockReady(dwSize,TRUE))
{
try
{
uRc = WmiQuerySingleInstance(m_hCurrentWMIHandle, wcsInstanceName, &m_dwDataBufferSize, m_pbDataBuffer);
}
catch(...)
{
uRc = E_UNEXPECTED;
// don't throw
}
}
return uRc;
}
///////////////////////////////////////////////////////////////////////
HRESULT CProcessStandardDataBlock::QuerySingleInstance(WCHAR * wcsInstanceName)
{
//============================================================
// Get the instances
//============================================================
DWORD dwChar = wcslen(wcsInstanceName);
DWORD dwSize = ROUND_UP_COUNT(sizeof(WNODE_SINGLE_INSTANCE) + dwChar ,8);
ULONG uRc = GetDataBufferAndQuerySingleInstance(dwSize,wcsInstanceName);
if( uRc == ERROR_INSUFFICIENT_BUFFER )
{
uRc = GetDataBufferAndQuerySingleInstance(m_dwDataBufferSize,wcsInstanceName);
}
if( uRc == ERROR_SUCCESS )
{
return(SetSingleInstanceInfo());
}
return(MapReturnCode(uRc));
}
///////////////////////////////////////////////////////////////////////
// NTRaid : 136392
// 07/12/00
HRESULT CProcessStandardDataBlock::SetSingleInstance()
{
ULONG uRc = S_OK;
WCHAR * pwcsInst = NULL;
if( SUCCEEDED(m_Class->GetInstanceName(pwcsInst)))
{
try
{
uRc = WmiSetSingleInstance( m_hCurrentWMIHandle, pwcsInst,1,m_dwDataBufferSize,m_pbDataBuffer);
}
catch(...)
{
uRc = E_UNEXPECTED;
// don't throw
}
SAFE_DELETE_ARRAY(pwcsInst);
}
return(MapReturnCode(uRc));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//*******************************************************************************************************
//
// CProcessHiPerfDataBlock
//
//*******************************************************************************************************
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CProcessHiPerfDataBlock::OpenHiPerfHandle()
{
HRESULT hr = WBEM_E_FAILED;
ULONG uRc = ERROR_SUCCESS;
//========================================================
// Open the handle
//========================================================
try
{
uRc = WmiOpenBlock(m_Class->GuidPtr(),m_uDesiredAccess, &m_hCurrentWMIHandle);
if( uRc == ERROR_SUCCESS )
{
// WMIINTERFACE->HandleMap()->Add(*(m_Class->GuidPtr()),m_hCurrentWMIHandle);
}
}
catch(...)
{
hr = E_UNEXPECTED;
// don't throw
}
return MapReturnCode(uRc);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
ULONG CProcessHiPerfDataBlock::GetDataBufferAndHiPerfQueryAllData(DWORD dwSize,WMIHANDLE * List, long lHandleCount)
{
ULONG uRc = E_UNEXPECTED;
if(GetDataBlockReady(dwSize,TRUE))
{
try
{
uRc = WmiQueryAllDataMultiple(List, lHandleCount, &m_dwDataBufferSize,m_pbDataBuffer);
}
catch(...)
{
uRc = E_UNEXPECTED;
// don't throw
}
}
return uRc;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CProcessHiPerfDataBlock::HiPerfQueryAllData(WMIHANDLE * List,long lHandleCount)
{
HRESULT hr = WBEM_E_FAILED;
//============================================================
// Get the instances
//============================================================
ULONG uRc = GetDataBufferAndHiPerfQueryAllData(sizeof(WNODE_ALL_DATA)*lHandleCount,List,lHandleCount);
if( uRc == ERROR_INSUFFICIENT_BUFFER )
{
//=================================================
// We just want to try one more time to get it,
// if it fails, then bail out. m_dwDataBufferSize
// should now have the correct size needed in it
//=================================================
uRc = GetDataBufferAndHiPerfQueryAllData(m_dwDataBufferSize,List,lHandleCount);
}
//=====================================================
// Ok, since we are querying for all instances, make
// sure the header node says that all of the instances
// are fine, if not reallocate
//=====================================================
if( uRc == ERROR_SUCCESS )
{
if( S_OK ==(hr = SetAllInstanceInfo()))
{
if (m_pHeaderWnode->Flags & WNODE_FLAG_TOO_SMALL)
{
while( TRUE )
{
//==========================================================
// keep on querying until we get the correct size
// This error may come from the driver
//==========================================================
uRc = GetDataBufferAndHiPerfQueryAllData(m_dwDataBufferSize,List,lHandleCount);
if( uRc == ERROR_SUCCESS )
{
if( S_OK ==(hr = SetAllInstanceInfo()))
{
if (!(m_pHeaderWnode->Flags & WNODE_FLAG_TOO_SMALL))
{
break;
}
}
} // end GetDataBufferAndQueryAllData
} // end of while
} // end of WNODE_FLAG_TOO_SMALL test
} // end of SetAllInstanceInfo
}
//==========================================================================
// if uRc succeeded, then the return code is already set by SetAllInstance
// otherwise need to map it out
//==========================================================================
if( uRc != ERROR_SUCCESS )
{
hr = MapReturnCode(uRc);
}
return(hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
ULONG CProcessHiPerfDataBlock::GetDataBufferAndHiPerfQuerySingleInstance( DWORD dwSize,WMIHANDLE *List, PWCHAR * pInstances,long lHandleCount)
{
ULONG uRc = E_UNEXPECTED;
if(GetDataBlockReady(dwSize,TRUE))
{
try
{
uRc = WmiQuerySingleInstanceMultiple( List, pInstances, lHandleCount, &m_dwDataBufferSize, m_pbDataBuffer);
}
catch(...)
{
uRc = E_UNEXPECTED;
// don't throw
}
}
return uRc;
}
///////////////////////////////////////////////////////////////////////
HRESULT CProcessHiPerfDataBlock::HiPerfQuerySingleInstance(WMIHANDLE *List, PWCHAR * pInstances, DWORD dwInstanceNameSize, long lHandleCount)
{
//============================================================
// Get the instances
//============================================================
ULONG uRc = GetDataBufferAndHiPerfQuerySingleInstance((sizeof(WNODE_SINGLE_INSTANCE)*lHandleCount) + dwInstanceNameSize ,List,pInstances,lHandleCount);
if( uRc == ERROR_INSUFFICIENT_BUFFER )
{
uRc = GetDataBufferAndHiPerfQuerySingleInstance(m_dwDataBufferSize,List,pInstances,lHandleCount);
}
if( uRc == ERROR_SUCCESS )
{
return(SetSingleInstanceInfo());
}
return(MapReturnCode(uRc));
}
////////////////////////////////////////////////////////////////////
HRESULT CProcessHiPerfDataBlock::FillOutProperties()
{
HRESULT hr = WBEM_E_INVALID_OBJECT;
//=========================================================
// get the properties from the class and read the WMI Data
//=========================================================
if(m_Class->GetANewInstance()){
WCHAR * pwcsProperty=NULL;
CWMIDataTypeMap MapWMIData(this,&m_dwAccumulativeSizeOfBlock);
m_dwAccumulativeSizeOfBlock = 0L;
pwcsProperty = m_Class->FirstProperty();
while (NULL != pwcsProperty){
//=========================================================
// We do not support arrays or embedded classes
//=========================================================
if( ( CWMIProcessClass::EmbeddedClass == m_Class->PropertyCategory()) ||
( CWMIProcessClass::Array == m_Class->PropertyCategory() ) ){
hr = WMI_INVALID_HIPERFPROP;
ERRORTRACE((THISPROVIDER,"Class %S has embedded class or array property\n",m_Class->GetClassName()));
break;
}
hr = MapWMIData.GetDataFromDataBlock(m_Class->GetAccessInstancePtr(), m_Class->GetPropertyHandle(), m_Class->PropertyType(), m_Class->PropertySize());
if( FAILED(hr) ){
break;
}
pwcsProperty = m_Class->NextProperty();
}
}
//====================================================================
// Now, fill in the specific HI PERF properties
//====================================================================
if( hr == S_OK )
{
hr = m_Class->SetHiPerfProperties(m_pHeaderWnode->TimeStamp);
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This function searches the standard HandleMap for the handle and if it isn't there, it is added.
// The hiperf handles are added/mapped elsewhere.
///////////////////////////////////////////////////////////
HRESULT CProcessHiPerfDataBlock::GetWMIHandle(HANDLE & lWMIHandle)
{
HRESULT hr = WBEM_E_FAILED;
lWMIHandle = 0;
hr = WMIINTERFACE->HandleMap()->GetHandle(*(m_Class->GuidPtr()),lWMIHandle);
if( hr != ERROR_SUCCESS )
{
hr = OpenHiPerfHandle();
if( SUCCEEDED(hr))
{
lWMIHandle = m_hCurrentWMIHandle;
hr = WMIINTERFACE->HandleMap()->Add( *(m_Class->GuidPtr()), lWMIHandle,WMIGUID_QUERY );
}
}
return hr;
}