470 lines
12 KiB
C++
470 lines
12 KiB
C++
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORPORATION, 1998
|
|
*
|
|
* TITLE: PROPARRY.CPP
|
|
*
|
|
* VERSION: 1.0
|
|
*
|
|
* AUTHOR: ShaunIv
|
|
*
|
|
* DATE: 5/4/1999
|
|
*
|
|
* DESCRIPTION: IWiaPropertyStorage cache definitions
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
CPropertyStorageArray::CPropertyStorageArray( const CPropertyStorageArray &other )
|
|
: m_nCount(0),
|
|
m_ppvPropVariants(NULL),
|
|
m_ppsPropSpecs(NULL),
|
|
m_pstrPropNames(NULL)
|
|
{
|
|
Copy(other);
|
|
}
|
|
|
|
|
|
CPropertyStorageArray::CPropertyStorageArray(IUnknown *pIUnknown)
|
|
: m_nCount(0),
|
|
m_ppvPropVariants(NULL),
|
|
m_ppsPropSpecs(NULL),
|
|
m_pstrPropNames(NULL)
|
|
{
|
|
Initialize(pIUnknown);
|
|
}
|
|
|
|
|
|
CPropertyStorageArray::~CPropertyStorageArray(void)
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
|
|
bool CPropertyStorageArray::IsValid(void) const
|
|
{
|
|
// It's OK to have an empty list, but it isn't considered valid
|
|
return (m_nCount && m_ppvPropVariants && m_ppsPropSpecs && m_pstrPropNames);
|
|
}
|
|
|
|
|
|
HRESULT CPropertyStorageArray::Copy( const CPropertyStorageArray &other )
|
|
{
|
|
Destroy();
|
|
HRESULT hr = S_OK;
|
|
if (this != &other)
|
|
{
|
|
if (other.IsValid())
|
|
{
|
|
m_nCount = other.Count();
|
|
if (m_nCount)
|
|
{
|
|
if (AllocateData())
|
|
{
|
|
for (int i=0;i<m_nCount && SUCCEEDED(hr);i++)
|
|
{
|
|
// Copy propvariant
|
|
if (!SUCCEEDED(PropVariantCopy( &m_ppvPropVariants[i], &other.PropVariants()[i])))
|
|
{
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
// Copy property name
|
|
if (other.PropNames() && other.PropNames()[i])
|
|
{
|
|
m_pstrPropNames[i] = new WCHAR[lstrlenW(other.PropNames()[i])+1];
|
|
if (!m_pstrPropNames[i])
|
|
{
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
lstrcpyW( m_pstrPropNames[i], other.PropNames()[i] );
|
|
}
|
|
|
|
// Copy propspec (propid)
|
|
m_ppsPropSpecs[i].propid = other.PropSpecs()[i].propid;
|
|
m_ppsPropSpecs[i].ulKind = PRSPEC_PROPID;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
if (!SUCCEEDED(hr))
|
|
Destroy();
|
|
return hr;
|
|
}
|
|
|
|
|
|
void CPropertyStorageArray::ClearPropVariantArray(void)
|
|
{
|
|
if (!m_ppvPropVariants || !m_nCount)
|
|
return;
|
|
for (int i=0;i<m_nCount;i++)
|
|
{
|
|
PropVariantClear(m_ppvPropVariants+i);
|
|
m_ppvPropVariants[i].vt = VT_EMPTY;
|
|
}
|
|
}
|
|
|
|
|
|
void CPropertyStorageArray::Destroy(void)
|
|
{
|
|
ClearPropVariantArray();
|
|
for (int i=0;i<m_nCount;i++)
|
|
{
|
|
if (m_pstrPropNames && m_pstrPropNames[i])
|
|
delete[] m_pstrPropNames[i];
|
|
}
|
|
if (m_ppvPropVariants)
|
|
delete[] m_ppvPropVariants;
|
|
if (m_ppsPropSpecs)
|
|
delete[] m_ppsPropSpecs;
|
|
if (m_pstrPropNames)
|
|
delete[] m_pstrPropNames;
|
|
m_ppvPropVariants = NULL;
|
|
m_ppsPropSpecs = NULL;
|
|
m_pstrPropNames = NULL;
|
|
m_nCount = 0;
|
|
}
|
|
|
|
|
|
bool CPropertyStorageArray::AllocateData(void)
|
|
{
|
|
m_ppsPropSpecs = new PROPSPEC[m_nCount];
|
|
if (m_ppsPropSpecs)
|
|
{
|
|
ZeroMemory(m_ppsPropSpecs,m_nCount*sizeof(m_ppsPropSpecs[0]));
|
|
}
|
|
m_ppvPropVariants = new PROPVARIANT[m_nCount];
|
|
if (m_ppvPropVariants)
|
|
{
|
|
ZeroMemory(m_ppvPropVariants,m_nCount*sizeof(m_ppvPropVariants[0]));
|
|
}
|
|
m_pstrPropNames = new LPWSTR[m_nCount];
|
|
if (m_pstrPropNames)
|
|
{
|
|
ZeroMemory(m_pstrPropNames,m_nCount*sizeof(m_pstrPropNames[0]));
|
|
}
|
|
return(m_ppsPropSpecs && m_ppvPropVariants && m_pstrPropNames);
|
|
}
|
|
|
|
|
|
CPropertyStorageArray &CPropertyStorageArray::operator=( const CPropertyStorageArray &other )
|
|
{
|
|
Copy(other);
|
|
return(*this);
|
|
}
|
|
|
|
|
|
int CPropertyStorageArray::GetPropertyCount( IWiaPropertyStorage *pIWiaPropertyStorage )
|
|
{
|
|
IEnumSTATPROPSTG *pIEnum = NULL;
|
|
HRESULT hr;
|
|
int nCount=0;
|
|
|
|
hr = pIWiaPropertyStorage->Enum(&pIEnum);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
STATPROPSTG StatPropStg;
|
|
ZeroMemory(&StatPropStg,sizeof(StatPropStg));
|
|
while ((hr = pIEnum->Next(1,&StatPropStg, NULL)) == S_OK)
|
|
{
|
|
nCount++;
|
|
if (StatPropStg.lpwstrName)
|
|
{
|
|
CoTaskMemFree(StatPropStg.lpwstrName);
|
|
}
|
|
ZeroMemory(&StatPropStg,sizeof(StatPropStg));
|
|
}
|
|
}
|
|
return(nCount);
|
|
}
|
|
|
|
|
|
HRESULT CPropertyStorageArray::GetPropertyNames( IWiaPropertyStorage *pIWiaPropertyStorage )
|
|
{
|
|
IEnumSTATPROPSTG *pIEnum = NULL;
|
|
HRESULT hr;
|
|
int nCurrentIndex=0;
|
|
|
|
hr = pIWiaPropertyStorage->Enum(&pIEnum);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
STATPROPSTG StatPropStg;
|
|
ZeroMemory(&StatPropStg,sizeof(StatPropStg));
|
|
while ((hr = pIEnum->Next(1,&StatPropStg, NULL)) == S_OK)
|
|
{
|
|
m_ppsPropSpecs[nCurrentIndex].propid = StatPropStg.propid;
|
|
m_ppsPropSpecs[nCurrentIndex].ulKind = PRSPEC_PROPID;
|
|
if (StatPropStg.lpwstrName)
|
|
{
|
|
m_pstrPropNames[nCurrentIndex] = new WCHAR[lstrlenW(StatPropStg.lpwstrName)+1];
|
|
if (m_pstrPropNames[nCurrentIndex])
|
|
{
|
|
lstrcpyW( m_pstrPropNames[nCurrentIndex], StatPropStg.lpwstrName );
|
|
CoTaskMemFree(StatPropStg.lpwstrName);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
CoTaskMemFree(StatPropStg.lpwstrName);
|
|
break;
|
|
}
|
|
}
|
|
nCurrentIndex++;
|
|
}
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT CPropertyStorageArray::Initialize( IUnknown *pIUnknown )
|
|
{
|
|
Destroy();
|
|
HRESULT hr = E_INVALIDARG;
|
|
if (pIUnknown)
|
|
{
|
|
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
|
|
hr = pIUnknown->QueryInterface(IID_IWiaPropertyStorage, (void**)&pIWiaPropertyStorage);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_nCount = GetPropertyCount( pIWiaPropertyStorage );
|
|
if (m_nCount)
|
|
{
|
|
if (AllocateData())
|
|
{
|
|
hr = GetPropertyNames( pIWiaPropertyStorage );
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pIWiaPropertyStorage->ReadMultiple( m_nCount, m_ppsPropSpecs, m_ppvPropVariants );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
Destroy();
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT CPropertyStorageArray::Read( IUnknown *pIUnknown )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
if (IsValid())
|
|
{
|
|
ClearPropVariantArray();
|
|
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
|
|
hr = pIUnknown->QueryInterface(IID_IWiaPropertyStorage, (void**)&pIWiaPropertyStorage);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pIWiaPropertyStorage->ReadMultiple( m_nCount, m_ppsPropSpecs, m_ppvPropVariants );
|
|
}
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT CPropertyStorageArray::Write( IUnknown *pIUnknown )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
if (IsValid())
|
|
{
|
|
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
|
|
hr = pIUnknown->QueryInterface(IID_IWiaPropertyStorage, (void**)&pIWiaPropertyStorage);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pIWiaPropertyStorage->WriteMultiple( m_nCount, m_ppsPropSpecs, m_ppvPropVariants, WIA_IPA_FIRST);
|
|
}
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT CPropertyStorageArray::Write( IUnknown *pIUnknown, PROPID propId )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
if (IsValid())
|
|
{
|
|
int nIndex = GetIndexFromPropId( propId );
|
|
if (nIndex >= 0)
|
|
{
|
|
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
|
|
hr = pIUnknown->QueryInterface(IID_IWiaPropertyStorage, (void**)&pIWiaPropertyStorage);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pIWiaPropertyStorage->WriteMultiple( 1, m_ppsPropSpecs+nIndex, m_ppvPropVariants+nIndex, WIA_IPA_FIRST );
|
|
}
|
|
}
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
int CPropertyStorageArray::GetIndexFromPropId( PROPID propId )
|
|
{
|
|
if (!IsValid())
|
|
return -1;
|
|
for (int i=0;i<m_nCount;i++)
|
|
{
|
|
if (m_ppsPropSpecs[i].propid == propId)
|
|
return(i);
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
|
|
PROPVARIANT *CPropertyStorageArray::GetProperty( PROPID propId )
|
|
{
|
|
int nIndex = GetIndexFromPropId( propId );
|
|
if (nIndex < 0)
|
|
return(NULL);
|
|
return(m_ppvPropVariants+nIndex);
|
|
}
|
|
|
|
|
|
bool CPropertyStorageArray::GetProperty( PROPID propId, LONG &nProp )
|
|
{
|
|
PROPVARIANT *ppvPropValue = GetProperty( propId );
|
|
if (!ppvPropValue)
|
|
return(false);
|
|
if (VT_I4 != ppvPropValue->vt)
|
|
return(false);
|
|
nProp = ppvPropValue->lVal;
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
bool CPropertyStorageArray::GetProperty( PROPID propId, CSimpleStringWide &strProp )
|
|
{
|
|
PROPVARIANT *ppvPropValue = GetProperty( propId );
|
|
if (!ppvPropValue)
|
|
return(false);
|
|
if (VT_LPWSTR != ppvPropValue->vt && VT_BSTR != ppvPropValue->vt)
|
|
return(false);
|
|
strProp = ppvPropValue->pwszVal;
|
|
return(true);
|
|
}
|
|
|
|
|
|
|
|
bool CPropertyStorageArray::SetProperty( PROPID propId, PROPVARIANT *pPropVar )
|
|
{
|
|
PROPVARIANT *ppvPropValue = GetProperty( propId );
|
|
if (ppvPropValue)
|
|
{
|
|
PropVariantClear(ppvPropValue);
|
|
return(SUCCEEDED(PropVariantCopy(ppvPropValue,pPropVar)));
|
|
}
|
|
return(false);
|
|
}
|
|
|
|
bool CPropertyStorageArray::SetProperty( PROPID propId, LONG nProp )
|
|
{
|
|
PROPVARIANT *ppvPropValue = GetProperty( propId );
|
|
if (ppvPropValue)
|
|
{
|
|
ppvPropValue->vt = VT_I4;
|
|
ppvPropValue->lVal = nProp;
|
|
return(true);
|
|
}
|
|
return(false);
|
|
}
|
|
|
|
|
|
int CPropertyStorageArray::Count(void) const
|
|
{
|
|
return(m_nCount);
|
|
}
|
|
|
|
|
|
PROPVARIANT *CPropertyStorageArray::PropVariants(void) const
|
|
{
|
|
return(m_ppvPropVariants);
|
|
}
|
|
|
|
|
|
PROPSPEC *CPropertyStorageArray::PropSpecs(void) const
|
|
{
|
|
return(m_ppsPropSpecs);
|
|
}
|
|
|
|
|
|
LPWSTR *CPropertyStorageArray::PropNames(void) const
|
|
{
|
|
return(m_pstrPropNames);
|
|
}
|
|
|
|
|
|
void CPropertyStorageArray::Dump( int nIndex )
|
|
{
|
|
#if defined(WIA_DEBUG)
|
|
WIA_TRACE((TEXT("Dumping IWiaPropertyStorage:")));
|
|
int nStart = nIndex < 0 ? 0 : nIndex;
|
|
int nCount = nIndex < 0 ? Count() : 1;
|
|
for (int i=nStart;i<nCount;i++)
|
|
{
|
|
PROPVARIANT *pPropVar = GetProperty( m_ppsPropSpecs[i].propid );
|
|
if (pPropVar)
|
|
{
|
|
TCHAR szValue[512] = TEXT("");
|
|
switch (m_ppvPropVariants[i].vt)
|
|
{
|
|
case VT_I4:
|
|
wsprintf(szValue,TEXT("%d"),(LONG)m_ppvPropVariants[i].lVal);
|
|
break;
|
|
|
|
case VT_BSTR:
|
|
wsprintf(szValue,TEXT("%ws"),m_ppvPropVariants[i].bstrVal);
|
|
break;
|
|
|
|
case VT_VECTOR|VT_I4:
|
|
{
|
|
for (int j=0;j<(int)m_ppvPropVariants[i].cal.cElems;j++)
|
|
{
|
|
wsprintf(szValue+lstrlen(szValue),TEXT("%08X"),(LONG)m_ppvPropVariants[i].cal.pElems[j]);
|
|
if (j < (int)m_ppvPropVariants[i].cal.cElems-1)
|
|
wsprintf(szValue+lstrlen(szValue),TEXT(" "));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case VT_VECTOR|VT_UI1:
|
|
{
|
|
for (int j=0;j<(int)m_ppvPropVariants[i].cal.cElems;j++)
|
|
{
|
|
wsprintf(szValue+lstrlen(szValue),TEXT("%02X"),(LONG)m_ppvPropVariants[i].caub.pElems[j]);
|
|
if (j < (int)m_ppvPropVariants[i].cal.cElems-1 && j % 4 == 3)
|
|
wsprintf(szValue+lstrlen(szValue),TEXT(" "));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case VT_LPWSTR:
|
|
wsprintf(szValue,TEXT("%ws"),m_ppvPropVariants[i].pwszVal );
|
|
break;
|
|
|
|
default:
|
|
wsprintf(szValue,TEXT("Unknown Type %d (08X)"),m_ppvPropVariants[i].vt);
|
|
}
|
|
WIA_TRACE((TEXT(" [%-3d %ws] = [%s]"), m_ppsPropSpecs[i].propid, m_pstrPropNames[i], szValue));
|
|
}
|
|
}
|
|
#endif // defined(II_DEBUG)
|
|
}
|
|
|