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
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;
|
|
}
|