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