Postby bill585 » 18 Apr 2006 19:02
I have tried with .84 but it’s the same.
I have looked at source code "vlccontrol.cpp: ActiveX control for VLC".
There seem to be bugs in the function createTargetOptions.
I have marked the code where the bug are.
static HRESULT createTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount)
{
HRESULT hr = E_INVALIDARG;
if( VT_ERROR == V_VT(options) )
{
if( DISP_E_PARAMNOTFOUND == V_ERROR(options) )
{
// optional parameter not set
*cOptions = NULL;
*cOptionCount = 0;
return NOERROR;
}
}
else if( (VT_EMPTY == V_VT(options)) || (VT_NULL == V_VT(options)) )
{
// null parameter
*cOptions = NULL;
*cOptionCount = 0;
return NOERROR;
}
else if( VT_DISPATCH == V_VT(options) )
{
// collection parameter
VARIANT colEnum;
V_VT(&colEnum) = VT_UNKNOWN;
hr = GetObjectProperty(V_DISPATCH(options), DISPID_NEWENUM, colEnum);
if( SUCCEEDED(hr) )
{
IEnumVARIANT *enumVar;
hr = V_UNKNOWN(&colEnum)->QueryInterface(IID_IEnumVARIANT, (LPVOID *)&enumVar);
if( SUCCEEDED(hr) )
{
long pos = 0;
long capacity = 16;
VARIANT option;
*cOptions = (char **)malloc(capacity*sizeof(char *));
if( NULL != *cOptions )
{
ZeroMemory(*cOptions, sizeof(char *)*capacity);
while( SUCCEEDED(hr) && (S_OK == enumVar->Next(1, &option, NULL)) )
{
if( VT_BSTR == V_VT(&option) )
{
char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
(*cOptions)[pos] = cOption;
if( NULL != cOption )
{
++pos;
if( pos == capacity )
{
char **moreOptions = (char **)realloc(*cOptions, (capacity+16)*sizeof(char *));
if( NULL != moreOptions )
{
ZeroMemory(moreOptions+capacity, sizeof(char *)*16);
capacity += 16;
*cOptions = moreOptions;
}
else
hr = E_OUTOFMEMORY;
}
}
else
hr = E_OUTOFMEMORY;
}
else
hr = E_INVALIDARG;
VariantClear(&option);
}
*cOptionCount = pos;
if( FAILED(hr) )
{
// free already processed elements
freeTargetOptions(*cOptions, *cOptionCount);
}
}
else
hr = E_OUTOFMEMORY;
enumVar->Release();
}
}
}
else if( V_ISARRAY(options) )
{
// array parameter
SAFEARRAY *array = V_ISBYREF(options) ? *V_ARRAYREF(options) : V_ARRAY(options);
if( SafeArrayGetDim(array) != 1 )
return E_INVALIDARG;
long lBound = 0;
long uBound = 0;
SafeArrayGetLBound(array, 1, &lBound);
SafeArrayGetUBound(array, 1, &uBound);
// have we got any options
if( uBound > lBound )
{
VARTYPE vType;
HRESULT hr = SafeArrayGetVartype(array, &vType);
if( FAILED(hr) )
return hr;
long pos;
// marshall options into an array of C strings
if( VT_VARIANT == vType )
{
*cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
if( NULL != options )
return E_OUTOFMEMORY;
for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
{
VARIANT option;
hr = SafeArrayGetElement(array, &pos, &option);
if( SUCCEEDED(hr) )
{
if( VT_BSTR == V_VT(&option) )
{
char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
(*cOptions)[pos-lBound] = cOption;
if( NULL == cOption )
hr = E_OUTOFMEMORY;
}
else
hr = E_INVALIDARG;
VariantClear(&option);
}
}
}
else if( VT_BSTR == vType )
{
*cOptions = (char **)malloc(sizeof(char *)*(uBound-lBound));
if( NULL != options )
return E_OUTOFMEMORY;
ZeroMemory(cOptions, sizeof(char *)*(uBound-lBound));
for(pos=lBound; SUCCEEDED(hr) && (pos<uBound); ++pos )
{
BSTR option;
hr = SafeArrayGetElement(array, &pos, &option);
if( SUCCEEDED(hr) )
{
char *cOption = CStrFromBSTR(codePage, option);
(*cOptions)[pos-lBound] = cOption;
if( NULL == cOption )
hr = E_OUTOFMEMORY;
SysFreeString(option);
}
}
}
else
// unsupported type
return E_INVALIDARG;
*cOptionCount = pos-lBound;
if( FAILED(hr) )
{
// free already processed elements
freeTargetOptions(*cOptions, *cOptionCount);
}
}
else
{
// empty array
*cOptions = NULL;
*cOptionCount = 0;
return NOERROR;
}
}
return hr;
};