269 lines
6.6 KiB
C++
269 lines
6.6 KiB
C++
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
|
||
|
//
|
||
|
// File: DplayBufHelp.cpp
|
||
|
// Content: Helper functions for DPlay Buffers (Byte arrays)
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
#include "stdafx.h"
|
||
|
#include "Direct.h"
|
||
|
|
||
|
#define SAFE_FREE(p) { if(p) { free (p); p=NULL; } }
|
||
|
#define SAFE_DELETE(p) { if(p) { delete (p); p=NULL; } }
|
||
|
|
||
|
#define INITIAL_BUFFER_SIZE 20
|
||
|
|
||
|
HRESULT WINAPI VB_GrowBuffer(SAFEARRAY **Buffer, DWORD dwGrowSize);
|
||
|
HRESULT WINAPI VB_NewBuffer(SAFEARRAY **Buffer, long *lOffSet);
|
||
|
HRESULT WINAPI VB_AddDataToBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet);
|
||
|
HRESULT WINAPI VB_AddStringToBuffer(SAFEARRAY **Buffer, BSTR StringData, long *lOffSet);
|
||
|
HRESULT WINAPI VB_GetDataFromBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet);
|
||
|
HRESULT WINAPI VB_GetStringFromBuffer(SAFEARRAY **Buffer, long *lOffSet, BSTR *sData);
|
||
|
|
||
|
// Functions for writing a buffer
|
||
|
HRESULT WINAPI VB_AddStringToBuffer(SAFEARRAY **Buffer, BSTR StringData, long *lOffSet)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
// For strings we will first write out a DWORD
|
||
|
// containging the length of the string. Then we
|
||
|
// will write the actual data to the string.
|
||
|
|
||
|
DWORD dwStrLen= (((DWORD*)StringData)[-1]);
|
||
|
DWORD dwDataSize = sizeof(DWORD) + dwStrLen;
|
||
|
|
||
|
if (!StringData)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (!((SAFEARRAY*)*Buffer))
|
||
|
{
|
||
|
// We need to create this buffer, it doesn't exist
|
||
|
SAFEARRAY *lpData = NULL;
|
||
|
SAFEARRAYBOUND rgsabound[1];
|
||
|
|
||
|
// Let's create our SafeArray
|
||
|
rgsabound[0].lLbound = 0; // A single dimension array that is zero based
|
||
|
rgsabound[0].cElements = dwDataSize; //Set the initial size
|
||
|
// Create this data
|
||
|
lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
|
||
|
|
||
|
if (!lpData)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
(SAFEARRAY*)*Buffer = lpData;
|
||
|
}
|
||
|
|
||
|
if (!((SAFEARRAY*)*Buffer)->pvData)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
// Do we have enough memory for this string right now?
|
||
|
if (*lOffSet + dwDataSize > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
|
||
|
if (FAILED( hr = VB_GrowBuffer(Buffer, dwDataSize) ) )
|
||
|
return hr;
|
||
|
|
||
|
// Ok, now we' ve got our memory, copy it over
|
||
|
// First the length
|
||
|
BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
|
||
|
__try {
|
||
|
|
||
|
memcpy(lPtr + *lOffSet, &dwStrLen, sizeof(DWORD));
|
||
|
*lOffSet += sizeof(DWORD);
|
||
|
// Now the actual string
|
||
|
memcpy(lPtr + *lOffSet, StringData, dwStrLen);
|
||
|
*lOffSet += dwStrLen;
|
||
|
}
|
||
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT WINAPI VB_AddDataToBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
if (!lData)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (!lSize)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (!((SAFEARRAY*)*Buffer))
|
||
|
{
|
||
|
// We need to create this buffer, it doesn't exist
|
||
|
SAFEARRAY *lpData = NULL;
|
||
|
SAFEARRAYBOUND rgsabound[1];
|
||
|
|
||
|
// Let's create our SafeArray
|
||
|
rgsabound[0].lLbound = 0; // A single dimension array that is zero based
|
||
|
rgsabound[0].cElements = lSize; //Set the initial size
|
||
|
// Create this data
|
||
|
lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
|
||
|
|
||
|
if (!lpData)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
(SAFEARRAY*)*Buffer = lpData;
|
||
|
}
|
||
|
|
||
|
if (!((SAFEARRAY*)*Buffer)->pvData)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
// Do we have enough memory for this string right now?
|
||
|
if (*lOffSet + lSize > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
|
||
|
if (FAILED( hr = VB_GrowBuffer(Buffer, lSize) ) )
|
||
|
return hr;
|
||
|
|
||
|
BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
|
||
|
|
||
|
__try {
|
||
|
memcpy(lPtr + *lOffSet, lData, lSize);
|
||
|
*lOffSet += lSize;
|
||
|
}
|
||
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT WINAPI VB_NewBuffer(SAFEARRAY **Buffer, long *lOffSet)
|
||
|
{
|
||
|
// Set up with a 20 byte msg at first
|
||
|
SAFEARRAY *lpData = NULL;
|
||
|
SAFEARRAYBOUND rgsabound[1];
|
||
|
|
||
|
// Let's create our SafeArray
|
||
|
rgsabound[0].lLbound = 0; // A single dimension array that is zero based
|
||
|
rgsabound[0].cElements = INITIAL_BUFFER_SIZE; //Set the initial size
|
||
|
// Create this data
|
||
|
lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
|
||
|
|
||
|
if (!lpData)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
(SAFEARRAY*)*Buffer = lpData;
|
||
|
|
||
|
*lOffSet = 0;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT WINAPI VB_GrowBuffer(SAFEARRAY **Buffer, DWORD dwGrowSize)
|
||
|
{
|
||
|
SAFEARRAY *lpData = NULL;
|
||
|
SAFEARRAYBOUND rgsabound[1];
|
||
|
DWORD dwCurSize = 0;
|
||
|
|
||
|
if (!dwGrowSize)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (!((SAFEARRAY*)*Buffer))
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (!((SAFEARRAY*)*Buffer)->pvData)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
dwCurSize = ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements;
|
||
|
|
||
|
// Let's create a new SafeArray
|
||
|
rgsabound[0].lLbound = 0; // A single dimension array that is zero based
|
||
|
rgsabound[0].cElements = dwCurSize + dwGrowSize; //Set the size
|
||
|
// Create this data
|
||
|
lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
|
||
|
|
||
|
if (!lpData)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
__try {
|
||
|
memcpy(lpData->pvData, ((SAFEARRAY*)*Buffer)->pvData, dwCurSize);
|
||
|
SafeArrayDestroy((SAFEARRAY*)*Buffer);
|
||
|
|
||
|
(SAFEARRAY*)*Buffer = lpData;
|
||
|
}
|
||
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT WINAPI VB_GetDataFromBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet)
|
||
|
{
|
||
|
// Simply copy the memory from the offset to the new data
|
||
|
|
||
|
if (!lData)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (!lSize)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (!(SAFEARRAY*)*Buffer)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (!((SAFEARRAY*)*Buffer)->pvData)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (*lOffSet + lSize > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
|
||
|
|
||
|
__try {
|
||
|
memcpy(lData, lPtr + *lOffSet, lSize);
|
||
|
*lOffSet += lSize;
|
||
|
}
|
||
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT WINAPI VB_GetStringFromBuffer(SAFEARRAY **Buffer, long *lOffSet, BSTR *sData)
|
||
|
{
|
||
|
DWORD dwStrLen = 0;
|
||
|
WCHAR *sNewString = NULL;
|
||
|
|
||
|
// Simply copy the memory from the offset to the new data
|
||
|
if (!(SAFEARRAY*)*Buffer)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (!((SAFEARRAY*)*Buffer)->pvData)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (*lOffSet + sizeof(DWORD) > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
|
||
|
|
||
|
__try {
|
||
|
// First read the size of the string
|
||
|
dwStrLen = *(DWORD*)(lPtr + *lOffSet);
|
||
|
*lOffSet += sizeof(DWORD);
|
||
|
|
||
|
if (*lOffSet + dwStrLen > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
sNewString = (WCHAR*)new BYTE[dwStrLen+2];
|
||
|
if (!sNewString)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
ZeroMemory(sNewString, dwStrLen+2);
|
||
|
memcpy(sNewString, lPtr + *lOffSet, dwStrLen);
|
||
|
*sData = SysAllocString(sNewString);
|
||
|
|
||
|
*lOffSet += (dwStrLen);
|
||
|
}
|
||
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|