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.
465 lines
11 KiB
465 lines
11 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: dpvcpi.cpp
|
|
* Content: Base class for providing compression DLL implementation
|
|
*
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 10/27/99 rodtoll Created
|
|
* 01/21/00 rodtoll Moved error level debug to info
|
|
* 08/23/2000 rodtoll DllCanUnloadNow always returning TRUE!
|
|
* 06/27/2001 rodtoll RC2: DPVOICE: DPVACM's DllMain calls into acm -- potential hang
|
|
* Move global initialization to first object creation
|
|
***************************************************************************/
|
|
|
|
|
|
#include <windows.h>
|
|
#include <tchar.h>
|
|
#include "osind.h"
|
|
#include "dndbg.h"
|
|
#include "dpvcp.h"
|
|
#include "dpvcpi.h"
|
|
|
|
LONG IncrementObjectCount();
|
|
LONG DecrementObjectCount();
|
|
extern "C" LONG g_lNumLocks;
|
|
|
|
CDPVCPI::CompressionNode *CDPVCPI::s_pcnList = NULL;
|
|
BOOL CDPVCPI::s_fIsLoaded = FALSE;
|
|
DWORD CDPVCPI::s_dwNumCompressionTypes = 0;
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::CDPVCPI"
|
|
CDPVCPI::CDPVCPI(): m_lRefCount(0), m_fCritSecInited(FALSE)
|
|
{
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::InitClass"
|
|
BOOL CDPVCPI::InitClass()
|
|
{
|
|
if (DNInitializeCriticalSection( &m_csLock ))
|
|
{
|
|
m_fCritSecInited = TRUE;
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::I_CreateCompressor"
|
|
HRESULT CDPVCPI::I_CreateCompressor( DPVCPIOBJECT *This, LPWAVEFORMATEX lpwfxSrcFormat, GUID guidTargetCT, PDPVCOMPRESSOR *ppCompressor, DWORD dwFlags )
|
|
{
|
|
return This->pObject->CreateCompressor( This, lpwfxSrcFormat, guidTargetCT, ppCompressor, dwFlags );
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::I_CreateDeCompressor"
|
|
HRESULT CDPVCPI::I_CreateDeCompressor( DPVCPIOBJECT *This, GUID guidTargetCT, LPWAVEFORMATEX lpwfxSrcFormat, PDPVCOMPRESSOR *ppCompressor, DWORD dwFlags )
|
|
{
|
|
return This->pObject->CreateDeCompressor( This, guidTargetCT, lpwfxSrcFormat, ppCompressor, dwFlags );
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::~CDPVCPI"
|
|
CDPVCPI::~CDPVCPI()
|
|
{
|
|
if (m_fCritSecInited)
|
|
{
|
|
DNDeleteCriticalSection( &m_csLock );
|
|
}
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::DeInitCompressionList"
|
|
HRESULT CDPVCPI::DeInitCompressionList()
|
|
{
|
|
return CN_FreeList();
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::QueryInterface"
|
|
HRESULT CDPVCPI::QueryInterface( DPVCPIOBJECT *This, REFIID riid, PVOID *ppvObj )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if( ppvObj == NULL ||
|
|
!DNVALID_WRITEPTR( ppvObj, sizeof(LPVOID) ) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer passed for object" );
|
|
return DVERR_INVALIDPOINTER;
|
|
}
|
|
|
|
*ppvObj=NULL;
|
|
|
|
DNEnterCriticalSection( &This->pObject->m_csLock );
|
|
|
|
// hmmm, switch would be cleaner...
|
|
if( IsEqualIID(riid, IID_IUnknown) ||
|
|
IsEqualIID(riid, IID_IDPVCompressionProvider ) )
|
|
{
|
|
*ppvObj = This;
|
|
This->pObject->AddRef( This );
|
|
}
|
|
else
|
|
{
|
|
hr = E_NOINTERFACE;
|
|
}
|
|
|
|
DNLeaveCriticalSection( &This->pObject->m_csLock );
|
|
|
|
return hr;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::AddRef"
|
|
HRESULT CDPVCPI::AddRef( DPVCPIOBJECT *This )
|
|
{
|
|
LONG rc;
|
|
|
|
rc = InterlockedIncrement( &This->pObject->m_lRefCount );
|
|
|
|
return rc;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::Release"
|
|
HRESULT CDPVCPI::Release( DPVCPIOBJECT *This )
|
|
{
|
|
LONG rc;
|
|
|
|
if( ( rc = InterlockedDecrement( &This->pObject->m_lRefCount ) ) == 0 )
|
|
{
|
|
DPFX(DPFPREP, DVF_INFOLEVEL, "Destroying object" );
|
|
|
|
delete This->pObject;
|
|
delete This;
|
|
|
|
DecrementObjectCount();
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::EnumCompressionTypes"
|
|
HRESULT CDPVCPI::EnumCompressionTypes( DPVCPIOBJECT *This, PVOID pBuffer, PDWORD pdwSize, PDWORD pdwNumElements, DWORD dwFlags )
|
|
{
|
|
if( pdwSize == NULL ||
|
|
!DNVALID_WRITEPTR( pdwSize, sizeof( DWORD ) ) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer specified for pdwSize" );
|
|
return DVERR_INVALIDPOINTER;
|
|
}
|
|
|
|
if( *pdwSize > 0 &&
|
|
!DNVALID_WRITEPTR( pBuffer, *pdwSize ) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer specified for buffer" );
|
|
return DVERR_INVALIDPOINTER;
|
|
}
|
|
|
|
CompressionNode *pcnWalker = s_pcnList;
|
|
|
|
DWORD dwRequiredSize = 0,
|
|
dwTmp = 0,
|
|
dwNumElements = 0,
|
|
dwStringSize = 0;
|
|
LPBYTE pbDataPtr;
|
|
|
|
DVFULLCOMPRESSIONINFO *pbStructPtr;
|
|
|
|
HRESULT hr;
|
|
|
|
// Walk the list and determine how much space we need
|
|
while( pcnWalker != NULL )
|
|
{
|
|
hr = CI_GetSize( pcnWalker->pdvfci, &dwTmp );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get size" );
|
|
return hr;
|
|
}
|
|
|
|
dwRequiredSize += dwTmp;
|
|
|
|
pcnWalker = pcnWalker->pcnNext;
|
|
dwNumElements++;
|
|
}
|
|
|
|
if( dwRequiredSize > *pdwSize )
|
|
{
|
|
*pdwSize = dwRequiredSize;
|
|
return DVERR_BUFFERTOOSMALL;
|
|
}
|
|
|
|
*pdwNumElements = dwNumElements;
|
|
|
|
*pdwSize = dwRequiredSize;
|
|
pbDataPtr = (LPBYTE) pBuffer;
|
|
pbStructPtr = (DVFULLCOMPRESSIONINFO *) pBuffer;
|
|
|
|
// Move data pointer to be right after location of
|
|
pbDataPtr += (dwNumElements*sizeof(DVFULLCOMPRESSIONINFO));
|
|
|
|
pcnWalker = s_pcnList;
|
|
|
|
while( pcnWalker != NULL )
|
|
{
|
|
memcpy( pbStructPtr, pcnWalker->pdvfci, sizeof( DVFULLCOMPRESSIONINFO ) );
|
|
|
|
// If there is a name, copy it at the end
|
|
if( pcnWalker->pdvfci->lpszName != NULL && wcslen( pcnWalker->pdvfci->lpszName ) > 0 )
|
|
{
|
|
dwStringSize = (wcslen( pcnWalker->pdvfci->lpszName )+1)*2;
|
|
memcpy( pbDataPtr, pcnWalker->pdvfci->lpszName, dwStringSize );
|
|
pbStructPtr->lpszName = (wchar_t *) pbDataPtr;
|
|
pbDataPtr += dwStringSize;
|
|
}
|
|
|
|
// If there's a description, copy it at the end
|
|
if( pcnWalker->pdvfci->lpszDescription != NULL && wcslen( pcnWalker->pdvfci->lpszDescription ) > 0 )
|
|
{
|
|
dwStringSize = (wcslen( pcnWalker->pdvfci->lpszDescription)+1)*2;
|
|
memcpy( pbDataPtr, pcnWalker->pdvfci->lpszDescription, dwStringSize );
|
|
pbStructPtr->lpszDescription = (wchar_t *) pbDataPtr;
|
|
pbDataPtr += dwStringSize;
|
|
}
|
|
|
|
// If there's a format, copy it at the end
|
|
if( pcnWalker->pdvfci->lpwfxFormat != NULL )
|
|
{
|
|
dwStringSize = sizeof( WAVEFORMATEX ) + pcnWalker->pdvfci->lpwfxFormat->cbSize;
|
|
memcpy( pbDataPtr, pcnWalker->pdvfci->lpwfxFormat, dwStringSize );
|
|
pbStructPtr->lpwfxFormat = (LPWAVEFORMATEX) pbDataPtr;
|
|
pbDataPtr += dwStringSize;
|
|
}
|
|
|
|
pbStructPtr ++;
|
|
|
|
pcnWalker = pcnWalker->pcnNext;
|
|
}
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::IsCompressionSupported"
|
|
HRESULT CDPVCPI::IsCompressionSupported( DPVCPIOBJECT *This, GUID guidCT )
|
|
{
|
|
DVFULLCOMPRESSIONINFO *pdvfci;
|
|
|
|
if( !FAILED( CN_Get( guidCT, &pdvfci ) ) )
|
|
{
|
|
return DV_OK;
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid CT specified" );
|
|
return DVERR_COMPRESSIONNOTSUPPORTED;
|
|
}
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::GetCompressionInfo"
|
|
HRESULT CDPVCPI::GetCompressionInfo( DPVCPIOBJECT *This, GUID guidCT, PVOID pBuffer, PDWORD pdwSize )
|
|
{
|
|
DVFULLCOMPRESSIONINFO *pdvfci;
|
|
|
|
if( pdwSize == NULL ||
|
|
!DNVALID_WRITEPTR( pdwSize, sizeof( DWORD ) ) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer specified for pdwSize" );
|
|
return DVERR_INVALIDPOINTER;
|
|
}
|
|
|
|
if( *pdwSize > 0 &&
|
|
!DNVALID_WRITEPTR( pBuffer, *pdwSize ) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer specified for buffer" );
|
|
return DVERR_INVALIDPOINTER;
|
|
}
|
|
|
|
if( FAILED( CN_Get( guidCT, &pdvfci ) ) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid CT specified" );
|
|
return DVERR_COMPRESSIONNOTSUPPORTED;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwSize;
|
|
HRESULT hr;
|
|
LPBYTE pbTmp;
|
|
DWORD dwStringSize;
|
|
DVFULLCOMPRESSIONINFO *pTmpInfo;
|
|
|
|
hr = CI_GetSize( pdvfci, &dwSize );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get size of ci" );
|
|
return hr;
|
|
}
|
|
|
|
if( dwSize > *pdwSize )
|
|
{
|
|
*pdwSize = dwSize;
|
|
DPFX(DPFPREP, DVF_WARNINGLEVEL, "Buffer too small" );
|
|
return DVERR_BUFFERTOOSMALL;
|
|
}
|
|
|
|
*pdwSize = dwSize;
|
|
|
|
memcpy( pBuffer, pdvfci, sizeof( DVFULLCOMPRESSIONINFO ) );
|
|
|
|
pbTmp = (LPBYTE) pBuffer;
|
|
pTmpInfo = (DVFULLCOMPRESSIONINFO *) pBuffer;
|
|
|
|
pbTmp += sizeof( DVFULLCOMPRESSIONINFO );
|
|
|
|
// If there is a name
|
|
if( pdvfci->lpszName != NULL && wcslen( pdvfci->lpszName ) > 0 )
|
|
{
|
|
dwStringSize = (wcslen( pdvfci->lpszName )+1)*2;
|
|
memcpy( pbTmp, pdvfci->lpszName, dwStringSize );
|
|
pTmpInfo->lpszName = (wchar_t *) pbTmp;
|
|
pbTmp += dwStringSize;
|
|
}
|
|
|
|
if( pdvfci->lpszDescription != NULL && wcslen( pdvfci->lpszDescription ) > 0 )
|
|
{
|
|
dwStringSize = (wcslen( pdvfci->lpszDescription)+1)*2;
|
|
memcpy( pbTmp, pdvfci->lpszDescription, dwStringSize );
|
|
pTmpInfo->lpszDescription = (wchar_t *) pbTmp;
|
|
pbTmp += dwStringSize;
|
|
}
|
|
|
|
if( pdvfci->lpwfxFormat != NULL )
|
|
{
|
|
memcpy( pbTmp, pdvfci->lpwfxFormat, sizeof( WAVEFORMATEX ) + pdvfci->lpwfxFormat->cbSize );
|
|
pTmpInfo->lpwfxFormat = (LPWAVEFORMATEX) pbTmp;
|
|
}
|
|
|
|
return DV_OK;
|
|
}
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::CN_Add"
|
|
HRESULT CDPVCPI::CN_Add( DVFULLCOMPRESSIONINFO *pdvfci )
|
|
{
|
|
CompressionNode *pcnNewNode = new CompressionNode;
|
|
|
|
if( pcnNewNode == NULL )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc failure" );
|
|
return DVERR_OUTOFMEMORY;
|
|
}
|
|
|
|
pcnNewNode->pcnNext = s_pcnList;
|
|
pcnNewNode->pdvfci = pdvfci;
|
|
s_pcnList = pcnNewNode;
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::CN_Get"
|
|
HRESULT CDPVCPI::CN_Get( GUID guidCT, DVFULLCOMPRESSIONINFO **pdvfci )
|
|
{
|
|
CompressionNode *pcnWalker = s_pcnList;
|
|
|
|
*pdvfci = NULL;
|
|
|
|
while( pcnWalker != NULL )
|
|
{
|
|
if( pcnWalker->pdvfci->guidType == guidCT )
|
|
{
|
|
*pdvfci = pcnWalker->pdvfci;
|
|
return DV_OK;
|
|
}
|
|
|
|
pcnWalker = pcnWalker->pcnNext;
|
|
}
|
|
|
|
return DVERR_COMPRESSIONNOTSUPPORTED;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::CN_FreeList"
|
|
void CDPVCPI::CN_FreeItem( CompressionNode *pcNode )
|
|
{
|
|
if( pcNode->pdvfci->lpwfxFormat != NULL )
|
|
{
|
|
delete [] pcNode->pdvfci->lpwfxFormat;
|
|
}
|
|
|
|
if( pcNode->pdvfci->lpszName != NULL )
|
|
{
|
|
delete [] pcNode->pdvfci->lpszName;
|
|
}
|
|
|
|
if( pcNode->pdvfci->lpszDescription != NULL )
|
|
{
|
|
delete [] pcNode->pdvfci->lpszDescription;
|
|
}
|
|
|
|
delete pcNode->pdvfci;
|
|
|
|
delete pcNode;
|
|
}
|
|
|
|
// Free up the list, deallocating memory.
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::CN_FreeList"
|
|
HRESULT CDPVCPI::CN_FreeList()
|
|
{
|
|
CompressionNode *pcnWalker = s_pcnList;
|
|
CompressionNode *pcnTmp;
|
|
|
|
while( pcnWalker != NULL )
|
|
{
|
|
pcnTmp = pcnWalker;
|
|
pcnWalker = pcnWalker->pcnNext;
|
|
|
|
CN_FreeItem( pcnTmp );
|
|
}
|
|
|
|
s_pcnList = NULL;
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDPVCPI::CI_GetSize"
|
|
HRESULT CDPVCPI::CI_GetSize( DVFULLCOMPRESSIONINFO *pdvfci, LPDWORD lpdwSize )
|
|
{
|
|
DWORD dwSize = sizeof( DVFULLCOMPRESSIONINFO );
|
|
|
|
if( pdvfci->lpwfxFormat != NULL )
|
|
{
|
|
dwSize += sizeof( WAVEFORMATEX ) + pdvfci->lpwfxFormat->cbSize;
|
|
}
|
|
|
|
if( pdvfci->lpszName != NULL )
|
|
{
|
|
dwSize += ((wcslen( pdvfci->lpszName )+1)*2);
|
|
}
|
|
|
|
if( pdvfci->lpszDescription != NULL )
|
|
{
|
|
dwSize += ((wcslen( pdvfci->lpszDescription )+1)*2);
|
|
}
|
|
|
|
*lpdwSize = dwSize;
|
|
|
|
return DV_OK;
|
|
}
|
|
|