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.
 
 
 
 
 
 

421 lines
11 KiB

#include <fusenetincludes.h>
#include <manifestinfo.h>
// Must be in the same order as the MAN_INFO enumeration in fusenet.idl
DWORD CPropertyArray::max_params[MAN_INFO_MAX] = {
MAN_INFO_ASM_FILE_MAX,
MAN_INFO_APPLICATION_MAX,
MAN_INFO_SUBSCRIPTION_MAX,
MAN_INFO_DEPENDANT_ASM_MAX,
MAN_INFO_SOURCE_ASM_MAX,
MAN_INFO_PATCH_INFO_MAX,
};
// ---------------------------------------------------------------------------
// CreatePropertyArray
// ---------------------------------------------------------------------------
STDAPI CreatePropertyArray(DWORD dwType, CPropertyArray** ppPropertyArray)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
CPropertyArray *pPropArray = NULL;
*ppPropertyArray = NULL;
IF_ALLOC_FAILED_EXIT(pPropArray = new (CPropertyArray));
IF_FAILED_EXIT(pPropArray->Init(dwType));
*ppPropertyArray = pPropArray;
pPropArray = NULL;
exit:
SAFEDELETE(pPropArray);
return hr;
}
// ---------------------------------------------------------------------------
// CPropertyArray ctor
// ---------------------------------------------------------------------------
CPropertyArray::CPropertyArray()
: _dwType(0), _rProp(NULL)
{
_dwSig = 'PORP';
}
// ---------------------------------------------------------------------------
// CPropertyArray dtor
// ---------------------------------------------------------------------------
CPropertyArray::~CPropertyArray()
{
for (DWORD i = 0; i < max_params[_dwType]; i++)
{
if (_rProp[i].flag == MAN_INFO_FLAG_IUNKNOWN_PTR)
{
IUnknown *pUnk = ((IUnknown*) _rProp[i].pv);
SAFERELEASE(pUnk);
}
if (_rProp[i].cb > sizeof(DWORD))
SAFEDELETEARRAY(_rProp[i].pv);
}
SAFEDELETEARRAY(_rProp);
}
// ---------------------------------------------------------------------------
// CPropertyArray::Init
// ---------------------------------------------------------------------------
HRESULT CPropertyArray::Init(DWORD dwType)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
_dwType = dwType;
IF_ALLOC_FAILED_EXIT(_rProp = new Property[max_params[dwType]]);
memset(_rProp, 0, max_params[dwType]* sizeof(Property));
exit:
return hr;
}
// ---------------------------------------------------------------------------
// CPropertyArray::Set
// ---------------------------------------------------------------------------
HRESULT CPropertyArray::Set(DWORD PropertyId,
LPVOID pvProperty, DWORD cbProperty, DWORD flag)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
Property *pItem ;
if (PropertyId > max_params[_dwType])
{
hr = E_INVALIDARG;
goto exit;
}
pItem = &(_rProp[PropertyId]);
if (!cbProperty && !pvProperty)
{
if (pItem->cb > sizeof(DWORD))
SAFEDELETEARRAY(pItem->pv);
pItem->pv = NULL;
}
else if (cbProperty > sizeof(DWORD))
{
LPBYTE ptr = NULL;
IF_ALLOC_FAILED_EXIT(ptr = new (BYTE[cbProperty]));
if (pItem->cb > sizeof(DWORD))
SAFEDELETEARRAY(pItem->pv);
memcpy(ptr, pvProperty, cbProperty);
pItem->pv = ptr;
}
else
{
if (pItem->cb > sizeof(DWORD))
SAFEDELETEARRAY(pItem->pv);
memcpy(&(pItem->pv), pvProperty, cbProperty);
}
pItem->cb = cbProperty;
pItem->flag = flag;
exit:
return hr;
}
// ---------------------------------------------------------------------------
// CPropertyArray::Get
// ---------------------------------------------------------------------------
HRESULT CPropertyArray::Get(DWORD PropertyId,
LPVOID pvProperty, LPDWORD pcbProperty, DWORD *flag)
{
HRESULT hr = S_OK;
Property *pItem;
if ((!pvProperty && *pcbProperty) || (PropertyId > max_params[_dwType]))
{
hr = E_INVALIDARG;
goto exit;
}
pItem = &(_rProp[PropertyId]);
if (pItem->cb > *pcbProperty)
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
else if (pItem->cb)
{
memcpy(pvProperty, (pItem->cb > sizeof(DWORD) ?
pItem->pv : (LPBYTE) &(pItem->pv)), pItem->cb);
}
*pcbProperty = pItem->cb;
*flag = pItem->flag;
exit:
return hr;
}
// ---------------------------------------------------------------------------
// GetType
// ---------------------------------------------------------------------------
HRESULT CPropertyArray::GetType(DWORD *pdwType)
{
*pdwType = _dwType;
return S_OK;
}
// ---------------------------------------------------------------------------
// CPropertyArray::operator []
// Wraps DWORD optimization test.
// ---------------------------------------------------------------------------
Property CPropertyArray::operator [] (DWORD PropertyId)
{
Property Prop;
Prop.pv = _rProp[PropertyId].cb > sizeof(DWORD) ?
_rProp[PropertyId].pv : &(_rProp[PropertyId].pv);
Prop.cb = _rProp[PropertyId].cb;
return Prop;
}
// ---------------------------------------------------------------------------
// CreateManifestInfo
// ---------------------------------------------------------------------------
STDAPI CreateManifestInfo(DWORD dwType, LPMANIFEST_INFO* ppManifestInfo)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
CManifestInfo *pManifestInfo = NULL;
IF_ALLOC_FAILED_EXIT(pManifestInfo = new(CManifestInfo));
IF_FAILED_EXIT(pManifestInfo->Init(dwType));
*ppManifestInfo = static_cast<IManifestInfo*> (pManifestInfo);
pManifestInfo = NULL;
exit:
SAFERELEASE(pManifestInfo);
return hr;
}
// ---------------------------------------------------------------------------
// ctor
// ---------------------------------------------------------------------------
CManifestInfo::CManifestInfo()
: _dwSig('INAM'), _cRef(1), _hr(S_OK)
{
}
// ---------------------------------------------------------------------------
// dtor
// ---------------------------------------------------------------------------
CManifestInfo::~CManifestInfo()
{
SAFEDELETE(_properties);
}
// ---------------------------------------------------------------------------
// Set
// ---------------------------------------------------------------------------
HRESULT CManifestInfo::Set(DWORD PropertyId, LPVOID pvProperty, DWORD cbProperty, DWORD flag)
{
IF_FAILED_EXIT( (*_properties).Set(PropertyId, pvProperty, cbProperty, flag));
if (flag == MAN_INFO_FLAG_IUNKNOWN_PTR)
(*(IUnknown**) pvProperty)->AddRef();
exit:
return _hr;
}
// ---------------------------------------------------------------------------
// Get
// ---------------------------------------------------------------------------
HRESULT CManifestInfo::Get(DWORD PropertyId, LPVOID *ppvProperty, DWORD *pcbProperty, DWORD *pflag)
{
DWORD flag;
LPBYTE pbAlloc;
DWORD cbAlloc;
*ppvProperty = NULL;
*pcbProperty = 0;
// Get property size
_hr = (*_properties).Get(PropertyId, NULL, &(cbAlloc = 0), &flag);
if (_hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
{
// Property is set; alloc buf
IF_ALLOC_FAILED_EXIT(pbAlloc = new(BYTE[cbAlloc]));
// Get the property
IF_FAILED_EXIT( (*_properties).Get(PropertyId, pbAlloc, &cbAlloc, &flag));
if (flag == MAN_INFO_FLAG_IUNKNOWN_PTR)
{
memcpy(ppvProperty, pbAlloc, cbAlloc);
((IUnknown *)(*ppvProperty))-> AddRef();
SAFEDELETEARRAY(pbAlloc);
}
else
*ppvProperty = pbAlloc;
*pcbProperty = cbAlloc;
*pflag = flag;
}
else
{
// If property unset, hr should be S_OK
if (_hr != S_OK)
goto exit;
// Success, returning 0 bytes, ensure buf is null.
*pflag = MAN_INFO_FLAG_UNDEF;
}
exit:
return _hr;
}
// ---------------------------------------------------------------------------
// IsEqual
// As of now, only valid to check equality of MAN_INFO_FILE property bags
// ---------------------------------------------------------------------------
HRESULT CManifestInfo::IsEqual(IManifestInfo *pManifestInfo)
{
_hr = S_OK;
DWORD dwType1, dwType2, cbBuf, dwFlag;
LPWSTR pwzBuf1=NULL, pwzBuf2=NULL;
GetType(&dwType1);
pManifestInfo->GetType(&dwType2);
if (dwType1 != MAN_INFO_FILE && dwType2 != MAN_INFO_FILE)
{
_hr = E_INVALIDARG;
goto exit;
}
for (DWORD i = MAN_INFO_ASM_FILE_NAME; i < MAN_INFO_ASM_FILE_MAX; i++)
{
// BUGBUG?: case sensitivity and issues?
// BUGBUG?: locale?
Get(i, (LPVOID *)&pwzBuf1, &cbBuf, &dwFlag);
pManifestInfo->Get(i, (LPVOID *)&pwzBuf2, &cbBuf, &dwFlag);
if ((pwzBuf1 && !pwzBuf2) || (!pwzBuf1 && pwzBuf2))
_hr= S_FALSE;
if(pwzBuf1 && pwzBuf2)
IF_FAILED_EXIT(FusionCompareString(pwzBuf1, pwzBuf2, 0));
SAFEDELETEARRAY(pwzBuf1);
SAFEDELETEARRAY(pwzBuf2);
// if one entry is false, no need to check the rest
if (_hr == S_FALSE)
break;
}
goto exit;
exit:
return _hr;
}
// ---------------------------------------------------------------------------
// GetType
// ---------------------------------------------------------------------------
HRESULT CManifestInfo::GetType(DWORD *pdwType)
{
DWORD dwType;
_hr = _properties->GetType(&dwType);
*pdwType = dwType;
return _hr;
}
// ---------------------------------------------------------------------------
// Init
// ---------------------------------------------------------------------------
HRESULT CManifestInfo::Init(DWORD dwType)
{
_hr = S_OK;
if (dwType >= MAN_INFO_MAX)
{
_hr = E_INVALIDARG;
goto exit;
}
_hr = CreatePropertyArray(dwType, &_properties);
exit:
return _hr;
}
// IUnknown Boilerplate
// ---------------------------------------------------------------------------
// CManifestInfo::QI
// ---------------------------------------------------------------------------
STDMETHODIMP
CManifestInfo::QueryInterface(REFIID riid, void** ppvObj)
{
if ( IsEqualIID(riid, IID_IUnknown)
|| IsEqualIID(riid, IID_IManifestInfo)
)
{
*ppvObj = static_cast<IManifestInfo*> (this);
AddRef();
return S_OK;
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
}
// ---------------------------------------------------------------------------
// CManifestInfo::AddRef
// ---------------------------------------------------------------------------
STDMETHODIMP_(ULONG)
CManifestInfo::AddRef()
{
return InterlockedIncrement ((LONG*) &_cRef);
}
// ---------------------------------------------------------------------------
// CManifestInfo::Release
// ---------------------------------------------------------------------------
STDMETHODIMP_(ULONG)
CManifestInfo::Release()
{
ULONG lRet = InterlockedDecrement ((LONG*) &_cRef);
if (!lRet)
delete this;
return lRet;
}