2025-04-27 07:49:33 -04:00

167 lines
5.0 KiB
C++

// BlobDecoder.cpp : Implementation of CBlobDecoder
#include "stdafx.h"
#include "BlobDcod.h"
#include "BlobDecoder.h"
struct TEST_BLOB
{
WCHAR szName[25];
DWORD dwIndex;
BYTE cData[10];
WCHAR szStrings[3][25];
};
#define DWORD_ALIGNED(x) ((DWORD)((((x) * 8) + 31) & (~31)) / 8)
/////////////////////////////////////////////////////////////////////////////
// CBlobDecoder
HRESULT STDMETHODCALLTYPE CBlobDecoder::DecodeProperty(
/* [in] */ VARIANT __RPC_FAR *pPropertyHandle,
/* [unique][in][out] */ CIMTYPE __RPC_FAR *pType,
/* [in] */ BYTE __RPC_FAR *pBlob,
/* [in] */ DWORD dwBlobSize,
/* [unique][in][out] */ BYTE __RPC_FAR *pOutBuffer,
/* [in] */ DWORD dwOutBufferSize,
/* [unique][in][out] */ DWORD __RPC_FAR *dwBytesRead)
{
HRESULT hr = E_FAIL;
TEST_BLOB *pTestBlob = (TEST_BLOB*) pBlob;
// Make sure the size is right and that the property handle is
// an integer.
if (dwBlobSize == sizeof(*pTestBlob) && pPropertyHandle->vt == VT_I4)
{
switch(pPropertyHandle->iVal)
{
// Name
case 0:
{
DWORD dwLength =
(wcslen(pTestBlob->szName) + 1) * sizeof(WCHAR),
dwTotal = dwLength + sizeof(DWORD);
if (pType)
*pType = CIM_STRING;
if (dwTotal <= dwOutBufferSize)
{
memcpy(pOutBuffer + sizeof(DWORD), pTestBlob->szName,
dwLength);
*(DWORD*) pOutBuffer = dwLength;
*dwBytesRead = dwTotal;
hr = S_OK;
}
else
hr = WBEM_E_BUFFER_TOO_SMALL;
break;
}
// Index
case 1:
{
DWORD dwLength = sizeof(DWORD);
if (pType)
*pType = CIM_UINT32;
if (dwLength <= dwOutBufferSize)
{
*(DWORD*) pOutBuffer = pTestBlob->dwIndex;
*dwBytesRead = dwLength;
hr = S_OK;
}
else
hr = WBEM_E_BUFFER_TOO_SMALL;
break;
}
// ByteArray
case 2:
{
DWORD dwLength = sizeof(pTestBlob->cData) + sizeof(DWORD);
if (pType)
*pType = CIM_UINT8 | CIM_FLAG_ARRAY;
if (dwLength <= dwOutBufferSize)
{
// For arrays the first 4 bytes indicates the number of
// elements in the array.
*(DWORD*) pOutBuffer = sizeof(pTestBlob->cData);
// Copy in the array data.
memcpy(
pOutBuffer + sizeof(DWORD),
pTestBlob->cData,
sizeof(pTestBlob->cData));
*dwBytesRead = dwLength;
hr = S_OK;
}
else
hr = WBEM_E_BUFFER_TOO_SMALL;
break;
}
// StringArray
case 3:
{
DWORD dwLength =
(wcslen(pTestBlob->szStrings[0]) + 1 +
wcslen(pTestBlob->szStrings[1]) + 1 +
wcslen(pTestBlob->szStrings[2]) + 1) * sizeof(WCHAR) +
sizeof(DWORD);
if (pType)
*pType = CIM_STRING | CIM_FLAG_ARRAY;
if (dwLength <= dwOutBufferSize)
{
LPBYTE pCurrent;
// For arrays the first 4 bytes indicates the number of
// elements in the array.
*(DWORD*) pOutBuffer = 3;
// Get past the first 4 bytes.
pCurrent = pOutBuffer + sizeof(DWORD);
for (int i = 0; i < 3; i++)
{
DWORD dwStrLen =
(wcslen(pTestBlob->szStrings[i]) + 1) *
sizeof(WCHAR);
*(DWORD*) pCurrent = dwStrLen;
memcpy(
pCurrent + sizeof(DWORD),
pTestBlob->szStrings[i],
dwStrLen);
pCurrent += sizeof(DWORD) + DWORD_ALIGNED(dwStrLen);
}
*dwBytesRead = dwLength;
hr = S_OK;
}
else
hr = WBEM_E_BUFFER_TOO_SMALL;
break;
}
}
}
return hr;
}