Leaked source code of windows server 2003
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.
 
 
 
 
 
 

314 lines
9.2 KiB

/////////////////////////////////////////////////////////////////////////////////////
// ComponentTypes.cpp : Implementation of CComponentTypes
// Copyright (c) Microsoft Corporation 1999.
#include "stdafx.h"
#include "Tuner.h"
#include "ComponentTypes.h"
#include "ComponentType.h"
#include "LanguageComponentType.h"
#include "MPEG2ComponentType.h"
#include "ATSCComponentType.h"
DEFINE_EXTERN_OBJECT_ENTRY(CLSID_ComponentTypes, CComponentTypes)
DEFINE_EXTERN_OBJECT_ENTRY(CLSID_ComponentType, CComponentType)
DEFINE_EXTERN_OBJECT_ENTRY(CLSID_LanguageComponentType, CLanguageComponentType)
DEFINE_EXTERN_OBJECT_ENTRY(CLSID_MPEG2ComponentType, CMPEG2ComponentType)
DEFINE_EXTERN_OBJECT_ENTRY(CLSID_ATSCComponentType, CATSCComponentType)
/////////////////////////////////////////////////////////////////////////////
// CComponentTypes
STDMETHODIMP CComponentTypes::Load(IPropertyBag2 *pBag2, IErrorLog *pErrLog) {
try {
ULONG count;
HRESULT hr = pBag2->CountProperties(&count);
if (FAILED(hr)) {
return hr;
}
// undone: should this be on the heap not the stack?
PROPBAG2 *props = reinterpret_cast<PROPBAG2 *>(_alloca(sizeof(PROPBAG2) * count));
if (!props) {
return E_OUTOFMEMORY;
}
ULONG readcount = 0;
hr = pBag2->GetPropertyInfo(0, count, props, &readcount);
if (FAILED(hr)) {
return hr;
}
if (count != readcount) {
return E_UNEXPECTED;
}
HRESULT *phr = reinterpret_cast<HRESULT *>(_alloca(sizeof(HRESULT) * readcount));
if (!phr) {
return E_OUTOFMEMORY;
}
VARIANT *pv = new VARIANT[readcount];
if (!pv) {
return E_OUTOFMEMORY;
}
// readcount is set from GetPropertyInfo
// pv is an array of variants readcount in length
memset(pv, 0, sizeof(VARIANT) * readcount);
hr = pBag2->Read(readcount, props, pErrLog, pv, phr);
if (FAILED(hr)) {
delete[] pv;
return hr;
}
ATL_LOCK();
for (count = 0; count < readcount; ++count) {
int idx = _wtoi(props[count].pstrName);
switch(props[count].vt) {
case VT_UNKNOWN:
if (idx >= m_ComponentTypes.size()) {
m_ComponentTypes.reserve(idx + 1);
m_ComponentTypes.insert(m_ComponentTypes.end(), (idx - m_ComponentTypes.size()) + 1, PQComponentType());
}
m_ComponentTypes[idx] = pv[count].punkVal;
break;
case VT_DISPATCH:
if (idx >= m_ComponentTypes.size()) {
m_ComponentTypes.reserve(idx + 1);
m_ComponentTypes.insert(m_ComponentTypes.end(), (idx - m_ComponentTypes.size()) + 1, PQComponentType());
}
m_ComponentTypes[idx] = pv[count].pdispVal;
break;
case VT_CLSID:
case VT_BSTR:
break; // ignore clsids
default:
_ASSERT(FALSE);
}
VariantClear(&pv[count]);
}
delete[] pv;
return NOERROR;
} catch (...) {
return E_UNEXPECTED;
}
}
STDMETHODIMP CComponentTypes::Save(IPropertyBag2 *pBag2, BOOL fClearDirty, BOOL fSaveAllProperties) {
try {
if (!m_bRequiresSave) {
return NOERROR;
}
int propsize = sizeof(PROPBAG2) * m_ComponentTypes.size();
PROPBAG2 *props = new PROPBAG2[m_ComponentTypes.size()];
if (!props) {
return E_OUTOFMEMORY;
}
// props points to memory _alloca'd propsize in length
memset(props, 0, propsize);
VARIANT *pv = new VARIANT[m_ComponentTypes.size()];
if (!pv) {
delete[] props;
return E_OUTOFMEMORY;
}
int ctidx = 0;
int propidx = 0;
for (int i = 0; i < m_ComponentTypes.size(); ++i) {
PQPersist pct(m_ComponentTypes[ctidx++]);
if (!pct) continue;
pv[i].vt = VT_UNKNOWN;
pv[i].punkVal = pct; // guaranteed nested lifetime(m_components isn't going away) thus no addref needed
props[i].dwType = PROPBAG2_TYPE_OBJECT;
props[i].vt = VT_UNKNOWN;
HRESULT hr = pct->GetClassID(&(props[i].clsid));
if (FAILED(hr)) {
_ASSERT(false);
--i; // reuse this slot and keep going
continue;
}
USES_CONVERSION;
const long idlen = sizeof(long) * 3 /* max digits per byte*/ + 1;
props[i].pstrName = new OLECHAR[idlen + 1];
_itow(i, props[i].pstrName, 10);
++propidx;
}
HRESULT hr = NOERROR;
hr = pBag2->Write(propidx, props, pv);
if (SUCCEEDED(hr)) {
m_bRequiresSave = false;
}
for (i = 0; i < propidx; ++i) {
delete props[i].pstrName;
}
delete[] props;
delete[] pv;
return hr;
} catch (...) {
return E_UNEXPECTED;
}
}
STDMETHODIMP CComponentTypes::get_Count(long *pVal)
{
try {
if (!pVal) {
return E_POINTER;
}
*pVal = m_ComponentTypes.size();
} catch (...) {
return E_POINTER;
}
return NOERROR;
}
STDMETHODIMP CComponentTypes::get__NewEnum(IEnumVARIANT** ppVal)
{
try {
if (ppVal == NULL)
return E_POINTER;
ComponentTypeScriptEnumerator_t* p;
*ppVal = NULL;
HRESULT hr = ComponentTypeScriptEnumerator_t::CreateInstance(&p);
if (FAILED(hr) || !p) {
return E_OUTOFMEMORY;
}
hr = p->Init(GetUnknown(), m_ComponentTypes);
if (FAILED(hr)) {
delete p;
return hr;
}
hr = p->QueryInterface(__uuidof(IEnumVARIANT), (void**)ppVal);
if (FAILED(hr)) {
delete p;
return hr;
}
return NOERROR;
} catch(...) {
return E_POINTER;
}
}
STDMETHODIMP CComponentTypes::EnumComponentTypes(IEnumComponentTypes** pVal)
{
ComponentTypeBaseEnumerator_t *pe = NULL;
ComponentTypeBaseEnumerator_t::CreateInstance(&pe);
pe->Init(static_cast<IComponentTypes*>(this), m_ComponentTypes);
HRESULT hr = pe->QueryInterface(pVal);
if (FAILED(hr)) {
delete pe;
}
return hr;
}
STDMETHODIMP CComponentTypes::get_Item(VARIANT varIndex, IComponentType **ppComponentType)
{
try {
if (!ppComponentType) {
return E_POINTER;
}
int idx;
CComVariant vidx;
if (FAILED(vidx.ChangeType(VT_I4, &varIndex))) {
return E_INVALIDARG;
}
idx = vidx.lVal;
if (idx >= m_ComponentTypes.size()) {
return E_INVALIDARG;
}
(*(m_ComponentTypes.begin() + idx)).CopyTo(ppComponentType);
} catch (...) {
return E_POINTER;
}
return NOERROR;
}
STDMETHODIMP CComponentTypes::put_Item(VARIANT varIndex, IComponentType *pComponentType) {
try {
int idx;
CComVariant vidx;
if (FAILED(vidx.ChangeType(VT_I4, &varIndex))) {
return E_INVALIDARG;
}
idx = vidx.lVal;
PQComponentType p(pComponentType);
if (idx >= m_ComponentTypes.size() || !p) {
return E_INVALIDARG;
}
m_ComponentTypes[idx] = p;
return NOERROR;
} catch(...) {
return E_UNEXPECTED;
}
}
STDMETHODIMP CComponentTypes::Add(IComponentType *pComponentType, VARIANT *pNewIndex)
{
try {
if (!pComponentType) {
return E_POINTER;
}
PQComponentType p(pComponentType);
m_ComponentTypes.push_back(p);
if (pNewIndex) {
VariantClear(pNewIndex);
pNewIndex->vt = VT_UI4;
pNewIndex->ulVal = m_ComponentTypes.end() - m_ComponentTypes.begin() - 1;
}
m_bRequiresSave = true;
} catch (...) {
return E_POINTER;
}
return NOERROR;
}
STDMETHODIMP CComponentTypes::Remove(VARIANT varIndex)
{
try {
int idx;
CComVariant vidx;
if (FAILED(vidx.ChangeType(VT_I4, &varIndex))) {
return E_INVALIDARG;
}
idx = vidx.lVal;
if (idx >= m_ComponentTypes.size()) {
return E_INVALIDARG;
}
m_ComponentTypes.erase(m_ComponentTypes.begin() + idx);
m_bRequiresSave = true;
} catch (...) {
return E_UNEXPECTED;
}
return NOERROR;
}
STDMETHODIMP CComponentTypes::Clone(IComponentTypes **ppNewList)
{
try {
if (!ppNewList) {
return E_POINTER;
}
CComponentTypes* pCs = new CComObject<CComponentTypes>;
if (!pCs) {
return E_OUTOFMEMORY;
}
ComponentTypeList::iterator i;
for (i = m_ComponentTypes.begin(); i != m_ComponentTypes.end(); ++i) {
PQComponentType p;
HRESULT hr = (*i)->Clone(&p);
if (FAILED(hr)) {
pCs->Release();
return hr;
}
pCs->m_ComponentTypes.push_back(p);
}
pCs->AddRef();
pCs->m_bRequiresSave = true;
*ppNewList = pCs;
return NOERROR;
} catch (...) {
return E_UNEXPECTED;
}
return NOERROR;
}