|
|
/*==========================================================================
* * Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved. * * File: private.c * Content: DirectDraw Private Client Data support * History: * Date By Reason * ==== == ====== * 10/08/97 jeffno Initial Implementation * 24/11/97 t-craigs Added support for palettes, flags, et al * ***************************************************************************/ #include "ddrawpr.h"
void FreePrivateDataNode(LPPRIVATEDATANODE pData) { /*
* Check to see whether we should release the * memory our data pointer might be pointing to. */ if (pData->dwFlags & DDSPD_IUNKNOWNPOINTER) { IUnknown *pUnk = (IUnknown *) pData->pData; /*
* Better try-except, or Gershon will get on my back */ TRY { pUnk->lpVtbl->Release(pUnk); } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered releasing private IUnknown pointer" ); } } else { MemFree(pData->pData); } MemFree(pData); }
void FreeAllPrivateData(LPPRIVATEDATANODE * ppListHead) { LPPRIVATEDATANODE pData = (*ppListHead);
while(pData) { LPPRIVATEDATANODE pPrevious = pData; pData=pData->pNext; FreePrivateDataNode(pPrevious); } (*ppListHead) = NULL; }
/*
* Helpers called from API entry points */ HRESULT InternalFreePrivateData(LPPRIVATEDATANODE * ppListHead, REFGUID rGuid) { LPPRIVATEDATANODE pData = * ppListHead; LPPRIVATEDATANODE pPrevious = NULL;
while (pData) { if ( IsEqualGUID(&pData->guid, rGuid)) { /*
* Check to see whether we should release the * memory our data pointer might be pointing to. */ if (pPrevious) pPrevious->pNext = pData->pNext; else *ppListHead = pData->pNext;
FreePrivateDataNode(pData);
return DD_OK; } pPrevious = pData; pData=pData->pNext; }
return DDERR_NOTFOUND; }
HRESULT InternalSetPrivateData( LPPRIVATEDATANODE *ppListHead, REFGUID rGuid, LPVOID pData, DWORD cbData, DWORD dwFlags, DWORD dwContentsStamp) { HRESULT hr = DD_OK; LPPRIVATEDATANODE pDataNode = NULL; BOOL bPtr;
if( 0UL == cbData ) { DPF_ERR( "Zero is invalid size of private data"); return DDERR_INVALIDPARAMS; }
if( !VALID_IID_PTR( rGuid ) ) { DPF_ERR( "GUID reference is invalid" ); return DDERR_INVALIDPARAMS; }
if( !VALID_PTR( pData, cbData ) ) { DPF_ERR( "Private data pointer is invalid" ); return DDERR_INVALIDPARAMS; }
if( dwFlags & ~DDSPD_VALID ) { DPF_ERR( "Invalid flags" ); return DDERR_INVALIDPARAMS; }
bPtr = dwFlags & DDSPD_IUNKNOWNPOINTER; /*
* First check if GUID already exists, squish it if so. * Don't care about return value. */ InternalFreePrivateData(ppListHead, rGuid);
/*
* Now we can add the guid and know it's unique */ pDataNode = MemAlloc(sizeof(PRIVATEDATANODE));
if (!pDataNode) return DDERR_OUTOFMEMORY;
/*
* If we have a "special" pointer, as indicated by one of the flags, * then we copy that pointer. * Otherwise we copy a certain number of bytes from * the location pointed to. */ if (bPtr) { IUnknown * pUnk;
if (sizeof(IUnknown*) != cbData) { MemFree(pDataNode); DPF_ERR("cbData must be set to sizeof(IUnknown *) when DDSPD_IUNKNOWNPOINTER is used"); return DDERR_INVALIDPARAMS; } pDataNode->pData = pData;
/*
* Now addref the pointer. We'll release it again when the data are freed */ pUnk = (IUnknown*) pData;
TRY { pUnk->lpVtbl->AddRef(pUnk); } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { MemFree(pDataNode); DPF_ERR( "Exception encountered releasing private IUnknown pointer" ); return DDERR_INVALIDPARAMS; } } else { pDataNode->pData = MemAlloc(cbData);
if (!pDataNode->pData) { MemFree(pDataNode); return DDERR_OUTOFMEMORY; }
memcpy(pDataNode->pData,pData,cbData); } memcpy(&pDataNode->guid,rGuid,sizeof(*rGuid)); pDataNode->cbData = cbData; pDataNode->dwFlags = dwFlags; pDataNode->dwContentsStamp = dwContentsStamp;
/*
* Insert the node at the head of the list */ pDataNode->pNext = *ppListHead; *ppListHead = pDataNode;
return DD_OK; }
HRESULT InternalGetPrivateData( LPPRIVATEDATANODE *ppListHead, REFGUID rGuid, LPVOID pData, LPDWORD pcbData, DWORD dwCurrentStamp) { HRESULT hr = DD_OK; LPPRIVATEDATANODE pDataNode = *ppListHead;
if( !VALID_PTR( pcbData, sizeof(DWORD) ) ) { DPF_ERR( "Private data count pointer is invalid" ); return DDERR_INVALIDPARAMS; }
if( !VALID_IID_PTR( rGuid ) ) { *pcbData = 0; DPF_ERR( "GUID reference is invalid" ); return DDERR_INVALIDPARAMS; }
if (*pcbData) { if( !VALID_PTR( pData, *pcbData ) ) { *pcbData = 0; DPF_ERR( "Private data pointer is invalid" ); return DDERR_INVALIDPARAMS; } }
while (pDataNode) { if ( IsEqualGUID(&pDataNode->guid, rGuid)) { /*
* Check if possibly volatile contents are still valid. */ if (pDataNode->dwFlags & DDSPD_VOLATILE) { if ((dwCurrentStamp == 0) || (pDataNode->dwContentsStamp != dwCurrentStamp)) { DPF_ERR("Private data is volatile and state has changed"); *pcbData = 0; return DDERR_EXPIRED; } }
if (*pcbData < pDataNode->cbData) { *pcbData = pDataNode->cbData; return DDERR_MOREDATA; }
if (pDataNode->dwFlags & DDSPD_IUNKNOWNPOINTER) { memcpy(pData,&(pDataNode->pData),pDataNode->cbData); } else { memcpy(pData,pDataNode->pData,pDataNode->cbData); } *pcbData = pDataNode->cbData; return DD_OK; } pDataNode=pDataNode->pNext; }
return DDERR_NOTFOUND; }
/*
* API entry points */
/*
* SetPrivateData - Surface */ HRESULT DDAPI DD_Surface_SetPrivateData( LPDIRECTDRAWSURFACE lpDDSurface, REFGUID rGuid, LPVOID pData, DWORD cbData, DWORD dwFlags) { LPDDRAWI_DDRAWSURFACE_INT this_int; LPDDRAWI_DDRAWSURFACE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Surface_SetPrivateData");
TRY { this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) ) { DPF_ERR( "Invalid surface description passed" ); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; }
this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl );
hr = InternalSetPrivateData( &this_lcl->lpSurfMore->pPrivateDataHead, rGuid, pData, cbData, dwFlags, GET_LPDDRAWSURFACE_GBL_MORE( this_lcl->lpGbl )->dwContentsStamp );
LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { LEAVE_DDRAW(); DPF_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
}
/*
* GetPrivateData - Surface */ HRESULT DDAPI DD_Surface_GetPrivateData( LPDIRECTDRAWSURFACE lpDDSurface, REFGUID rGuid, LPVOID pData, LPDWORD pcbData) { LPDDRAWI_DDRAWSURFACE_INT this_int; LPDDRAWI_DDRAWSURFACE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Surface_GetPrivateData");
TRY { this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) ) { *pcbData = 0; DPF_ERR( "Invalid surface description passed" ); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl );
hr = InternalGetPrivateData( &this_lcl->lpSurfMore->pPrivateDataHead, rGuid, pData, pcbData, GET_LPDDRAWSURFACE_GBL_MORE( this_lcl->lpGbl )->dwContentsStamp );
LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } }
/*
* FreePrivateData - Surface */ HRESULT DDAPI DD_Surface_FreePrivateData( LPDIRECTDRAWSURFACE lpDDSurface, REFGUID rGuid) { LPDDRAWI_DDRAWSURFACE_INT this_int; LPDDRAWI_DDRAWSURFACE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Surface_FreePrivateData");
TRY { this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) ) { DPF_ERR( "Invalid surface description passed" ); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl );
if( !VALID_IID_PTR( rGuid ) ) { DPF_ERR( "GUID reference is invalid" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } hr = InternalFreePrivateData( &this_lcl->lpSurfMore->pPrivateDataHead, rGuid);
LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } }
/*
* SetPrivateData - Palette */ HRESULT DDAPI DD_Palette_SetPrivateData( LPDIRECTDRAWPALETTE lpDDPalette, REFGUID rGuid, LPVOID pData, DWORD cbData, DWORD dwFlags) { LPDDRAWI_DDRAWPALETTE_INT this_int; LPDDRAWI_DDRAWPALETTE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Palette_SetPrivateData");
TRY { this_int = (LPDDRAWI_DDRAWPALETTE_INT) lpDDPalette; if( !VALID_DIRECTDRAWPALETTE_PTR( this_int ) ) { DPF_ERR( "Invalid palette pointer passed" ); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; }
this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl );
hr = InternalSetPrivateData( &this_lcl->pPrivateDataHead, rGuid, pData, cbData, dwFlags, this_lcl->lpGbl->dwContentsStamp );
LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { LEAVE_DDRAW(); DPF_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
}
/*
* GetPrivateData - Palette */ HRESULT DDAPI DD_Palette_GetPrivateData( LPDIRECTDRAWPALETTE lpDDPalette, REFGUID rGuid, LPVOID pData, LPDWORD pcbData) { LPDDRAWI_DDRAWPALETTE_INT this_int; LPDDRAWI_DDRAWPALETTE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Palette_GetPrivateData");
TRY { this_int = (LPDDRAWI_DDRAWPALETTE_INT) lpDDPalette; if( !VALID_DIRECTDRAWPALETTE_PTR( this_int ) ) { *pcbData = 0; DPF_ERR( "Invalid palette pointer passed" ); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl );
hr = InternalGetPrivateData( &this_lcl->pPrivateDataHead, rGuid, pData, pcbData, this_lcl->lpGbl->dwContentsStamp );
LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } }
/*
* FreePrivateData - Palette */ HRESULT DDAPI DD_Palette_FreePrivateData( LPDIRECTDRAWPALETTE lpDDPalette, REFGUID rGuid) { LPDDRAWI_DDRAWPALETTE_INT this_int; LPDDRAWI_DDRAWPALETTE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Palette_FreePrivateData");
TRY { this_int = (LPDDRAWI_DDRAWPALETTE_INT) lpDDPalette; if( !VALID_DIRECTDRAWPALETTE_PTR( this_int ) ) { DPF_ERR( "Invalid palette pointer passed"); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl );
if( !VALID_IID_PTR( rGuid ) ) { DPF_ERR( "GUID reference is invalid" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } hr = InternalFreePrivateData( & this_lcl->pPrivateDataHead, rGuid);
LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } }
/*
* GetUniquenessValue - Surface */ HRESULT EXTERN_DDAPI DD_Surface_GetUniquenessValue( LPDIRECTDRAWSURFACE lpDDSurface, LPDWORD lpValue ) { LPDDRAWI_DDRAWSURFACE_INT this_int; LPDDRAWI_DDRAWSURFACE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Surface_GetUniquenessValue");
TRY { this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) ) { DPF_ERR( "Invalid surface pointer passed"); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl ); if (!VALID_PTR(lpValue, sizeof(LPVOID))) { DPF_ERR("lpValue may not be NULL"); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } (*lpValue) = GET_LPDDRAWSURFACE_GBL_MORE( this_lcl->lpGbl )->dwContentsStamp; LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } }
/*
* GetUniquenessValue - Palette */ HRESULT EXTERN_DDAPI DD_Palette_GetUniquenessValue( LPDIRECTDRAWPALETTE lpDDPalette, LPDWORD lpValue ) { LPDDRAWI_DDRAWPALETTE_INT this_int; LPDDRAWI_DDRAWPALETTE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Palette_GetUniquenessValue");
TRY { this_int = (LPDDRAWI_DDRAWPALETTE_INT) lpDDPalette; if( !VALID_DIRECTDRAWPALETTE_PTR( this_int ) ) { DPF_ERR( "Invalid palette pointer passed"); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl ); if (!VALID_PTR(lpValue, sizeof(LPVOID))) { DPF_ERR("lpValue may not be NULL"); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } (*lpValue) = this_lcl->lpGbl->dwContentsStamp; LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } }
/*
* ChangeUniquenessValue - Surface */ HRESULT EXTERN_DDAPI DD_Surface_ChangeUniquenessValue( LPDIRECTDRAWSURFACE lpDDSurface ) { LPDDRAWI_DDRAWSURFACE_INT this_int; LPDDRAWI_DDRAWSURFACE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Surface_ChangeUniquenessValue");
TRY { this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) ) { DPF_ERR( "Invalid surface pointer passed"); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl ); BUMP_SURFACE_STAMP(this_lcl->lpGbl); LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } }
/*
* ChangeUniquenessValue - Palette */ HRESULT EXTERN_DDAPI DD_Palette_ChangeUniquenessValue( LPDIRECTDRAWPALETTE lpDDPalette ) { LPDDRAWI_DDRAWPALETTE_INT this_int; LPDDRAWI_DDRAWPALETTE_LCL this_lcl; HRESULT hr = DD_OK;
ENTER_DDRAW();
DPF(2,A,"ENTERAPI: DD_Palette_ChangeUniquenessValue");
TRY { this_int = (LPDDRAWI_DDRAWPALETTE_INT) lpDDPalette; if( !VALID_DIRECTDRAWPALETTE_PTR( this_int ) ) { DPF_ERR( "Invalid palette pointer passed"); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_lcl = this_int->lpLcl; DDASSERT( NULL != this_lcl ); BUMP_PALETTE_STAMP(this_lcl->lpGbl); LEAVE_DDRAW(); return hr; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } }
|