234 lines
5.1 KiB
C
234 lines
5.1 KiB
C
|
//
|
||
|
// utils.h
|
||
|
//
|
||
|
|
||
|
inline BOOL IsNumericVariant(VARIANT * pVar)
|
||
|
{
|
||
|
while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
|
||
|
pVar = V_VARIANTREF(pVar);
|
||
|
}
|
||
|
if((V_VT(pVar) & ~(VT_TYPEMASK|VT_BYREF)) != 0) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
switch(V_VT(pVar) & VT_TYPEMASK) {
|
||
|
case VT_I1:
|
||
|
case VT_I2:
|
||
|
case VT_I4:
|
||
|
case VT_I8:
|
||
|
case VT_INT:
|
||
|
case VT_UI1:
|
||
|
case VT_UI2:
|
||
|
case VT_UI4:
|
||
|
case VT_UI8:
|
||
|
case VT_UINT:
|
||
|
case VT_R4:
|
||
|
case VT_R8:
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
inline BOOL IsArrayVariant(VARIANT * pVar,SAFEARRAY **pArray,VARTYPE *pType)
|
||
|
{
|
||
|
while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
|
||
|
pVar = V_VARIANTREF(pVar);
|
||
|
}
|
||
|
if(!V_ISARRAY(pVar)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
if(pArray) {
|
||
|
if(V_ISBYREF(pVar)) {
|
||
|
*pArray = *V_ARRAYREF(pVar);
|
||
|
} else {
|
||
|
*pArray = V_ARRAY(pVar);
|
||
|
}
|
||
|
}
|
||
|
if(pType) {
|
||
|
*pType = V_VT(pVar) & VT_TYPEMASK;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
inline BOOL IsCollectionVariant(VARIANT * pVar,IEnumVARIANT ** pCollection)
|
||
|
{
|
||
|
while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
|
||
|
pVar = V_VARIANTREF(pVar);
|
||
|
}
|
||
|
CComVariant v;
|
||
|
HRESULT hr = v.ChangeType(VT_DISPATCH,pVar);
|
||
|
if(FAILED(hr)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
//
|
||
|
// look for an enumerator
|
||
|
//
|
||
|
DISPPARAMS params;
|
||
|
LPDISPATCH pDisp = V_DISPATCH(&v);
|
||
|
if(!pDisp) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
CComVariant result;
|
||
|
params.cArgs = 0;
|
||
|
params.cNamedArgs = 0;
|
||
|
hr = pDisp->Invoke(DISPID_NEWENUM,
|
||
|
IID_NULL,
|
||
|
0,
|
||
|
DISPATCH_PROPERTYGET,
|
||
|
¶ms,
|
||
|
&result,
|
||
|
NULL,
|
||
|
NULL);
|
||
|
|
||
|
if(FAILED(hr)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
hr = result.ChangeType(VT_UNKNOWN);
|
||
|
if(FAILED(hr)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
IEnumVARIANT *pEnum;
|
||
|
hr = V_UNKNOWN(&result)->QueryInterface(IID_IEnumVARIANT,(LPVOID*)&pEnum);
|
||
|
if(FAILED(hr)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
if(pCollection) {
|
||
|
*pCollection = pEnum;
|
||
|
} else {
|
||
|
pEnum->Release();
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
inline BOOL IsMultiValueVariant(VARIANT * pVar)
|
||
|
{
|
||
|
while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
|
||
|
pVar = V_VARIANTREF(pVar);
|
||
|
}
|
||
|
if(IsArrayVariant(pVar,NULL,NULL)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
if(IsCollectionVariant(pVar,NULL)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
inline BOOL IsNoArg(LPVARIANT pVar)
|
||
|
{
|
||
|
//
|
||
|
// explicit "no parameter"
|
||
|
//
|
||
|
if((V_VT(pVar) == VT_ERROR) && (V_ERROR(pVar) == (DISP_E_PARAMNOTFOUND))) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
inline BOOL IsBlank(LPVARIANT pVar)
|
||
|
{
|
||
|
//
|
||
|
// flexable "no parameter" allow 'null' 'nothing'
|
||
|
//
|
||
|
if(IsNoArg(pVar)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
|
||
|
pVar = V_VARIANTREF(pVar);
|
||
|
}
|
||
|
if(V_ISBYREF(pVar) && !V_BYREF(pVar)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
if((V_VT(pVar) == VT_EMPTY) || (V_VT(pVar) == VT_NULL)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
if(((V_VT(pVar) == VT_UNKNOWN) || (V_VT(pVar) == VT_DISPATCH)) && !V_UNKNOWN(pVar)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
if(((V_VT(pVar) == (VT_BYREF|VT_UNKNOWN)) || (V_VT(pVar) == (VT_BYREF|VT_DISPATCH)))
|
||
|
&& !(V_UNKNOWNREF(pVar) && *V_UNKNOWNREF(pVar))) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
//
|
||
|
// consider everything else as a parameter
|
||
|
//
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
inline BOOL IsBlankString(LPVARIANT pVar)
|
||
|
{
|
||
|
//
|
||
|
// even more flexable, allow "" too
|
||
|
//
|
||
|
if(IsBlank(pVar)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
while(V_VT(pVar) == (VT_BYREF|VT_VARIANT)) {
|
||
|
pVar = V_VARIANTREF(pVar);
|
||
|
}
|
||
|
if(V_VT(pVar) == VT_BSTR) {
|
||
|
return SysStringLen(V_BSTR(pVar)) ? FALSE : TRUE;
|
||
|
}
|
||
|
if(V_VT(pVar) == (VT_BYREF|VT_BSTR)) {
|
||
|
return (V_BSTRREF(pVar) && SysStringLen(*V_BSTRREF(pVar))) ? FALSE : TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
#define DEVFLAGS_HIDDEN 0x00000001
|
||
|
#define DEVFLAGS_SINGLEPROFILE 0x00000002
|
||
|
#define DEVFLAGS_ALL 0x00000003
|
||
|
|
||
|
inline HRESULT TranslateDeviceFlags(LPVARIANT flags,DWORD * di_flags)
|
||
|
{
|
||
|
long fl_final = 0;
|
||
|
CComVariant v;
|
||
|
HRESULT hr;
|
||
|
|
||
|
if(flags) {
|
||
|
if(IsNoArg(flags)) {
|
||
|
fl_final = 0;
|
||
|
} else if(IsNumericVariant(flags)) {
|
||
|
hr = v.ChangeType(VT_I4,flags);
|
||
|
if(FAILED(hr)) {
|
||
|
return hr;
|
||
|
}
|
||
|
fl_final = V_I4(&v);
|
||
|
} else {
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*di_flags = 0;
|
||
|
if(fl_final & ~(DEVFLAGS_ALL)) {
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
if(!(fl_final & DEVFLAGS_HIDDEN)) {
|
||
|
*di_flags |= DIGCF_PRESENT;
|
||
|
}
|
||
|
if(fl_final & DEVFLAGS_SINGLEPROFILE) {
|
||
|
*di_flags |= DIGCF_PROFILE;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
inline HRESULT GetOptionalString(LPVARIANT param,CComVariant &store,LPCWSTR *pString)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
*pString = NULL;
|
||
|
if(param) {
|
||
|
if(IsBlank(param)) {
|
||
|
return S_OK;
|
||
|
}
|
||
|
hr = store.ChangeType(VT_BSTR,param);
|
||
|
if(FAILED(hr)) {
|
||
|
return hr;
|
||
|
}
|
||
|
*pString = V_BSTR(&store);
|
||
|
return S_OK;
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|