765 lines
20 KiB
C++
765 lines
20 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1997 - 2000.
|
||
|
//
|
||
|
// File: ixsutil.cxx
|
||
|
//
|
||
|
// Contents: Utility SSO class
|
||
|
//
|
||
|
// History: 04 Apr 1997 Alanw Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include "pch.cxx"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Include Files
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
// debugging macros
|
||
|
#include "ssodebug.hxx"
|
||
|
|
||
|
// class declaration
|
||
|
#include "stdcf.hxx"
|
||
|
#include "ixsso.hxx"
|
||
|
#include "ixsutil.hxx"
|
||
|
|
||
|
#include <string.hxx>
|
||
|
#include <htmlchar.hxx>
|
||
|
|
||
|
extern WCHAR * g_pwszProgIdUtil;
|
||
|
|
||
|
#if CIDBG
|
||
|
extern ULONG g_ulObjCount;
|
||
|
extern LONG g_lUtlCount;
|
||
|
#endif // CIDBG
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoUtil::CixssoUtil - public
|
||
|
//
|
||
|
// Synopsis: Constructor of CixssoUtil
|
||
|
//
|
||
|
// Arguments: [pitlb] - pointer to ITypeLib for ixsso
|
||
|
//
|
||
|
// History: 04 Apr 1997 Alanw Created
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
CixssoUtil::CixssoUtil( ITypeLib * pitlb ) :
|
||
|
_ptinfo( 0 ),
|
||
|
_err( IID_IixssoUtil )
|
||
|
{
|
||
|
_cRef = 1;
|
||
|
|
||
|
SCODE sc = pitlb->GetTypeInfoOfGuid( IID_IixssoUtil, &_ptinfo );
|
||
|
if (FAILED(sc))
|
||
|
{
|
||
|
ixssoDebugOut(( DEB_ERROR, "Util - GetTypeInfoOfGuid failed (%x)\n", sc ));
|
||
|
Win4Assert(SUCCEEDED(sc));
|
||
|
|
||
|
THROW( CException(sc) );
|
||
|
}
|
||
|
|
||
|
INC_OBJECT_COUNT();
|
||
|
|
||
|
ixssoDebugOut((DEB_REFCOUNTS, "[DLL]: Create util: refcounts: glob %d util %d\n",
|
||
|
g_ulObjCount,
|
||
|
g_lUtlCount ));
|
||
|
} //CixssoUtil
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoUtil::~CixssoUtil - public
|
||
|
//
|
||
|
// Synopsis: Destructor of CixssoUtil
|
||
|
//
|
||
|
// History: 04 Apr 1997 Alanw Created
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
CixssoUtil::~CixssoUtil( )
|
||
|
{
|
||
|
if (_ptinfo)
|
||
|
_ptinfo->Release();
|
||
|
DEC_OBJECT_COUNT();
|
||
|
#if CIDBG
|
||
|
extern LONG g_lUtlCount;
|
||
|
LONG l = InterlockedDecrement( &g_lUtlCount );
|
||
|
Win4Assert( l >= 0 );
|
||
|
#endif //CIDBG
|
||
|
|
||
|
ixssoDebugOut((DEB_REFCOUNTS, "[DLL]: Delete util: refcounts: glob %d util %d\n",
|
||
|
g_ulObjCount,
|
||
|
g_lUtlCount ));
|
||
|
} //~CixssoUtl
|
||
|
|
||
|
|
||
|
#if 0 // NOTE: OnStartPage and OnEndPage are unneeded
|
||
|
//
|
||
|
// ASP Methods
|
||
|
//
|
||
|
|
||
|
#include <asp/asptlb.h>
|
||
|
|
||
|
STDMETHODIMP CixssoUtil::OnStartPage (IUnknown* pUnk)
|
||
|
{
|
||
|
// reset the error structure
|
||
|
_err.Reset();
|
||
|
|
||
|
SCODE sc;
|
||
|
IScriptingContext *piContext;
|
||
|
|
||
|
//Get IScriptingContext Interface
|
||
|
sc = pUnk->QueryInterface(IID_IScriptingContext, (void**)&piContext);
|
||
|
if (FAILED(sc))
|
||
|
return E_FAIL;
|
||
|
|
||
|
//Get Request Object Pointer
|
||
|
IRequest* piRequest = NULL;
|
||
|
sc = piContext->get_Request(&piRequest);
|
||
|
|
||
|
//Get ServerVariables Pointer
|
||
|
IRequestDictionary *piRequestDict = NULL;
|
||
|
sc = piRequest->get_ServerVariables(&piRequestDict);
|
||
|
|
||
|
VARIANT vtOut;
|
||
|
VariantInit(&vtOut);
|
||
|
|
||
|
//Get the HTTP_ACCEPT_LANGUAGE Item
|
||
|
sc = piRequestDict->get_Item(g_vtAcceptLanguageHeader, &vtOut);
|
||
|
|
||
|
//vtOut Contains an IDispatch Pointer. To fetch the value
|
||
|
//for HTTP_ACCEPT_LANGUAGE you must get the Default Value for the
|
||
|
//Object stored in vtOut using VariantChangeType.
|
||
|
if (V_VT(&vtOut) != VT_BSTR)
|
||
|
VariantChangeType(&vtOut, &vtOut, 0, VT_BSTR);
|
||
|
|
||
|
if (V_VT(&vtOut) == VT_BSTR)
|
||
|
{
|
||
|
ixssoDebugOut((DEB_TRACE, "OnStartPage: HTTP_ACCEPT_LANGUAGE = %ws\n",
|
||
|
V_BSTR(&vtOut) ));
|
||
|
SetLocaleString(V_BSTR(&vtOut));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ixssoDebugOut(( DEB_TRACE,
|
||
|
"OnStart: HTTP_ACCEPT_LANGAUGE was not set is ServerVariables; using lcid=0x%x\n",
|
||
|
GetSystemDefaultLCID() ));
|
||
|
|
||
|
put_LocaleID( GetSystemDefaultLCID() );
|
||
|
}
|
||
|
|
||
|
VariantClear(&vtOut);
|
||
|
|
||
|
piRequestDict->Release();
|
||
|
piRequest->Release();
|
||
|
piContext->Release();
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CixssoUtil::OnEndPage(void)
|
||
|
{
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
#endif // 0 NOTE: OnStartPage and OnEndPage are unneeded
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// CixssoUtil IUnknown Methods
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::QueryInterface(REFIID iid, void * * ppv)
|
||
|
{
|
||
|
*ppv = 0;
|
||
|
|
||
|
if (iid == IID_IUnknown || iid == IID_IDispatch)
|
||
|
*ppv = (IDispatch *)this;
|
||
|
else if (iid == IID_ISupportErrorInfo )
|
||
|
*ppv = (ISupportErrorInfo *) this;
|
||
|
else if (iid == IID_IixssoUtil )
|
||
|
*ppv = (IixssoUtil *) this;
|
||
|
else
|
||
|
return E_NOINTERFACE;
|
||
|
|
||
|
AddRef();
|
||
|
return S_OK;
|
||
|
} //QueryInterface
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CixssoUtil::AddRef(void)
|
||
|
{
|
||
|
return InterlockedIncrement((long *)&_cRef);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
CixssoUtil::Release(void)
|
||
|
{
|
||
|
ULONG uTmp = InterlockedDecrement((long *)&_cRef);
|
||
|
if (uTmp == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
return uTmp;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// CixssoUtil IDispatch Methods
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::GetTypeInfoCount(UINT * pctinfo)
|
||
|
{
|
||
|
*pctinfo = 1;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::GetTypeInfo(
|
||
|
UINT itinfo,
|
||
|
LCID lcid,
|
||
|
ITypeInfo * * pptinfo)
|
||
|
{
|
||
|
_ptinfo->AddRef();
|
||
|
*pptinfo = _ptinfo;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::GetIDsOfNames(
|
||
|
REFIID riid,
|
||
|
OLECHAR * * rgszNames,
|
||
|
UINT cNames,
|
||
|
LCID lcid,
|
||
|
DISPID * rgdispid)
|
||
|
{
|
||
|
return DispGetIDsOfNames(_ptinfo, rgszNames, cNames, rgdispid);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::Invoke(
|
||
|
DISPID dispidMember,
|
||
|
REFIID riid,
|
||
|
LCID lcid,
|
||
|
WORD wFlags,
|
||
|
DISPPARAMS * pParams,
|
||
|
VARIANT * pvarResult,
|
||
|
EXCEPINFO * pexcepinfo,
|
||
|
UINT * puArgErr)
|
||
|
{
|
||
|
ixssoDebugOut((DEB_IDISPATCH, "Util - Invoking method dispid=%d wFlags=%d\n",
|
||
|
dispidMember, wFlags ));
|
||
|
|
||
|
|
||
|
_err.Reset();
|
||
|
|
||
|
SCODE sc = DispInvoke( this, _ptinfo,
|
||
|
dispidMember, wFlags, pParams,
|
||
|
pvarResult, pexcepinfo, puArgErr );
|
||
|
|
||
|
if ( _err.IsError() )
|
||
|
sc = DISP_E_EXCEPTION;
|
||
|
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::InterfaceSupportsErrorInfo(
|
||
|
REFIID riid)
|
||
|
{
|
||
|
if (riid == IID_IixssoUtil)
|
||
|
return S_OK;
|
||
|
else
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoQuery::CopyWstrToBstr - private inline
|
||
|
//
|
||
|
// Synopsis: Copies a Unicode string to a BSTR
|
||
|
//
|
||
|
// Arguments: [pbstr] - destination BSTR
|
||
|
// [pwstr] - string to be copied
|
||
|
//
|
||
|
// Returns: SCODE - status return
|
||
|
//
|
||
|
// History: 25 Oct 1996 Alanw Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline
|
||
|
SCODE CixssoUtil::CopyWstrToBstr( BSTR * pbstr, WCHAR const * pwstr )
|
||
|
{
|
||
|
*pbstr = 0;
|
||
|
if (pwstr)
|
||
|
{
|
||
|
*pbstr = SysAllocString( pwstr );
|
||
|
if (0 == *pbstr)
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// CixssoUtil Methods
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoUtil::ISOToLocaleID - public
|
||
|
//
|
||
|
// Synopsis: Parse the input string for a recognizable locale name
|
||
|
//
|
||
|
// Arguments: [bstrLocale] - input string
|
||
|
// [pLcid] - pointer where corresponding LCID is returned
|
||
|
//
|
||
|
// Returns: SCODE - status return
|
||
|
//
|
||
|
// History: 04 Apr 1997 Alanw Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::ISOToLocaleID(BSTR bstrLocale, LONG *pLcid)
|
||
|
{
|
||
|
_err.Reset();
|
||
|
|
||
|
if ( 0 == pLcid )
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
*pLcid = GetLCIDFromString( bstrLocale );
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoUtil::LocaleIDToISO - public
|
||
|
//
|
||
|
// Synopsis: Return the ISO locale name for an LCID
|
||
|
//
|
||
|
// Arguments: [Lcid] - input LCID
|
||
|
// [pstr] - pointer where output string is returned
|
||
|
//
|
||
|
// Returns: SCODE - status return
|
||
|
//
|
||
|
// History: 04 Apr 1997 Alanw Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::LocaleIDToISO(LONG lcid, BSTR * pstr)
|
||
|
{
|
||
|
_err.Reset();
|
||
|
|
||
|
if ( 0 == pstr )
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
WCHAR awc[100];
|
||
|
|
||
|
GetStringFromLCID( lcid, awc );
|
||
|
|
||
|
return CopyWstrToBstr( pstr, awc );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoUtil::AddScopeToQuery - public
|
||
|
//
|
||
|
// Synopsis: Parse the input string for a recognizable locale name
|
||
|
//
|
||
|
// Arguments: [pDisp] - an IDispatch for the query object
|
||
|
// [bstrScope] - input scope
|
||
|
// [bstrDepth] - input depth (optional)
|
||
|
//
|
||
|
// Returns: SCODE - status return
|
||
|
//
|
||
|
// Notes: In the future, this will operate by modifying the query
|
||
|
// property to include a scope restriction.
|
||
|
// For now, it just adds the scope and depth via a private
|
||
|
// interface.
|
||
|
//
|
||
|
// History: 04 Apr 1997 Alanw Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::AddScopeToQuery( IDispatch * pDisp,
|
||
|
BSTR bstrScope,
|
||
|
BSTR bstrDepth)
|
||
|
{
|
||
|
_err.Reset();
|
||
|
|
||
|
SCODE sc = S_OK;
|
||
|
CTranslateSystemExceptions translate;
|
||
|
TRY
|
||
|
{
|
||
|
if ( 0 == pDisp )
|
||
|
THROW( CException( E_INVALIDARG ) );
|
||
|
|
||
|
IixssoQueryPrivate * pIQueryPvt = 0;
|
||
|
sc = pDisp->QueryInterface( IID_IixssoQueryPrivate, (void **)&pIQueryPvt );
|
||
|
|
||
|
if (FAILED(sc))
|
||
|
{
|
||
|
THROW(CException(sc));
|
||
|
}
|
||
|
|
||
|
XInterface<IixssoQueryPrivate> pQry(pIQueryPvt);
|
||
|
pQry->AddScopeToQuery( bstrScope, bstrDepth );
|
||
|
}
|
||
|
CATCH( CIxssoException, e )
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
SetError( sc, OLESTR("AddScopeToQuery"), eIxssoError );
|
||
|
}
|
||
|
AND_CATCH( CException, e )
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
SetError( sc, OLESTR("AddScopeToQuery") );
|
||
|
}
|
||
|
END_CATCH
|
||
|
|
||
|
return sc;
|
||
|
} //AddScopeToQuery
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoUtil::TruncateToWhitespace - public
|
||
|
//
|
||
|
// Synopsis: Truncate a string, preferably at a white space character.
|
||
|
//
|
||
|
// Arguments: [bstrIn] - input string
|
||
|
// [maxLen] - maximum number of characters in output string
|
||
|
// [pbstrOut] - pointer where output string is returned
|
||
|
//
|
||
|
// Returns: SCODE - status return
|
||
|
//
|
||
|
// Notes: The implementation does not take into account real word breaks.
|
||
|
// This may not work too well on far eastern languages.
|
||
|
//
|
||
|
// History: 04 Apr 1997 Alanw Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::TruncateToWhitespace(BSTR bstrIn, LONG maxLen, BSTR * pbstrOut)
|
||
|
{
|
||
|
_err.Reset();
|
||
|
|
||
|
ULONG cchString = 0;
|
||
|
if (maxLen <= 0)
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if (0 != bstrIn)
|
||
|
cchString = SysStringLen(bstrIn);
|
||
|
|
||
|
if (cchString > (unsigned)maxLen)
|
||
|
{
|
||
|
cchString = maxLen;
|
||
|
for (unsigned i=0; i <= (unsigned)maxLen; i++)
|
||
|
{
|
||
|
if (iswspace(bstrIn[i]))
|
||
|
cchString = i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*pbstrOut = SysAllocStringLen( bstrIn, cchString );
|
||
|
|
||
|
if (0 == *pbstrOut)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
return S_OK;
|
||
|
} //TruncateToWhitespace
|
||
|
|
||
|
class XVariant
|
||
|
{
|
||
|
public:
|
||
|
XVariant() : _pVar( 0 ) {}
|
||
|
XVariant( VARIANT & var ) : _pVar( &var ) {}
|
||
|
~XVariant() { if ( 0 != _pVar ) VariantClear( _pVar ); }
|
||
|
void Set( VARIANT & var ) { Win4Assert( 0 == _pVar ); _pVar = &var; }
|
||
|
private:
|
||
|
VARIANT * _pVar;
|
||
|
};
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoUtil::GetArrayElement - public
|
||
|
//
|
||
|
// Synopsis: Returns an element in an array as a variant
|
||
|
//
|
||
|
// Arguments: [pVarIn] - The input array (IDispatch or VT_ARRAY)
|
||
|
// [iElement] - The element to retrieve
|
||
|
// [pVarOut] - Where the array element result is written
|
||
|
//
|
||
|
// Returns: SCODE - status return
|
||
|
//
|
||
|
// History: 10 Sep 1997 dlee Created
|
||
|
// 18 Jan 2000 KLam DECIMAL needs to fit into a VARIANT
|
||
|
// on Win64 VARIANT is bigger than DECIMAL
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CixssoUtil::GetArrayElement(
|
||
|
VARIANT * pVarIn,
|
||
|
LONG iElement,
|
||
|
VARIANT * pVarOut )
|
||
|
{
|
||
|
_err.Reset();
|
||
|
|
||
|
//
|
||
|
// Validate the variant arguments.
|
||
|
//
|
||
|
|
||
|
if ( ( 0 == pVarIn ) || ( 0 == pVarOut ) )
|
||
|
return SetError( E_INVALIDARG, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
//
|
||
|
// Get the source array, either from the IDispatch or just copy it.
|
||
|
//
|
||
|
|
||
|
XVariant xvar;
|
||
|
VARIANT varArray;
|
||
|
VariantInit( &varArray );
|
||
|
|
||
|
if ( VT_DISPATCH == pVarIn->vt )
|
||
|
{
|
||
|
//
|
||
|
// The first argument is an IDispatch, not the array value, so we
|
||
|
// have to invoke it to get the value out.
|
||
|
//
|
||
|
|
||
|
if ( 0 == pVarIn->pdispVal )
|
||
|
return SetError( E_INVALIDARG, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
|
||
|
|
||
|
SCODE sc = pVarIn->pdispVal->Invoke( DISPID_VALUE,
|
||
|
IID_NULL,
|
||
|
GetSystemDefaultLCID(),
|
||
|
DISPATCH_PROPERTYGET,
|
||
|
&dispparamsNoArgs,
|
||
|
&varArray,
|
||
|
0,
|
||
|
0 );
|
||
|
ixssoDebugOut(( DEB_ITRACE, "result of invoke: 0x%x\n", sc ));
|
||
|
if ( FAILED( sc ) )
|
||
|
return SetError( sc, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
xvar.Set( varArray );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
varArray = *pVarIn;
|
||
|
}
|
||
|
|
||
|
ixssoDebugOut(( DEB_ITRACE, "value vt: 0x%x\n", varArray.vt ));
|
||
|
|
||
|
//
|
||
|
// Check for a valid variant array argument.
|
||
|
//
|
||
|
|
||
|
if ( ( 0 == ( VT_ARRAY & varArray.vt ) ) ||
|
||
|
( 0 == varArray.parray ) )
|
||
|
return SetError( E_INVALIDARG, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
SAFEARRAY *psa = varArray.parray;
|
||
|
|
||
|
//
|
||
|
// This function only deals with 1-dimensional safearrays.
|
||
|
//
|
||
|
|
||
|
if ( 1 != SafeArrayGetDim( psa ) )
|
||
|
return SetError( E_INVALIDARG, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
//
|
||
|
// Make sure iElement is in the bounds of the array.
|
||
|
//
|
||
|
|
||
|
long lLowBound;
|
||
|
SCODE sc = SafeArrayGetLBound( psa, 1, &lLowBound );
|
||
|
if ( FAILED( sc ) )
|
||
|
return SetError( sc, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
long lUpBound;
|
||
|
sc = SafeArrayGetUBound( psa, 1, &lUpBound );
|
||
|
if ( FAILED( sc ) )
|
||
|
return SetError( sc, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
if ( ( iElement < lLowBound ) || ( iElement > lUpBound ) )
|
||
|
return SetError( E_INVALIDARG, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
//
|
||
|
// Get a pointer to the element.
|
||
|
//
|
||
|
|
||
|
void * pvData;
|
||
|
sc = SafeArrayPtrOfIndex( psa, &iElement, &pvData );
|
||
|
if ( FAILED( sc ) )
|
||
|
return SetError( sc, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
//
|
||
|
// Put the element in a local variant so it can be copied.
|
||
|
//
|
||
|
|
||
|
VARIANT var;
|
||
|
VariantInit( &var );
|
||
|
var.vt = varArray.vt & (~VT_ARRAY);
|
||
|
unsigned cbElem = SafeArrayGetElemsize( psa );
|
||
|
|
||
|
if ( VT_VARIANT == var.vt )
|
||
|
{
|
||
|
Win4Assert( sizeof( VARIANT ) == cbElem );
|
||
|
RtlCopyMemory( &var, pvData, cbElem );
|
||
|
}
|
||
|
else if ( VT_DECIMAL == var.vt )
|
||
|
{
|
||
|
Win4Assert( sizeof( VARIANT ) >= cbElem &&
|
||
|
sizeof( DECIMAL ) == cbElem );
|
||
|
RtlCopyMemory( &var, pvData, cbElem );
|
||
|
var.vt = VT_DECIMAL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Win4Assert( cbElem <= 8 );
|
||
|
RtlCopyMemory( &var.lVal, pvData, cbElem );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Make a copy of the value into another local variant.
|
||
|
//
|
||
|
|
||
|
VARIANT varCopy;
|
||
|
VariantInit( &varCopy );
|
||
|
sc = VariantCopy( &varCopy, &var );
|
||
|
if ( FAILED( sc ) )
|
||
|
return SetError( sc, OLESTR( "GetArrayElement" ) );
|
||
|
|
||
|
//
|
||
|
// Free anything still allocated in the output variant, and transfer
|
||
|
// the value to the output variant.
|
||
|
//
|
||
|
|
||
|
VariantClear( pVarOut );
|
||
|
*pVarOut = varCopy;
|
||
|
|
||
|
return S_OK;
|
||
|
} //GetArrayElement
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoUtil::HTMLEncode - public
|
||
|
//
|
||
|
// Synopsis: Encode a string for use in HTML. Take the output code page
|
||
|
// into account so that unicode characters not representable in
|
||
|
// the code page are output as HTML numeric entities.
|
||
|
//
|
||
|
// Arguments: [bstrIn] - input string
|
||
|
// [codepage] - code page for output string
|
||
|
// [pbstrOut] - pointer where output string is returned
|
||
|
//
|
||
|
// Returns: SCODE - status return
|
||
|
//
|
||
|
// History: 04 Apr 1997 Alanw Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::HTMLEncode(BSTR bstrIn, LONG codepage, BSTR * pbstrOut)
|
||
|
{
|
||
|
_err.Reset();
|
||
|
|
||
|
SCODE sc = S_OK;
|
||
|
CTranslateSystemExceptions translate;
|
||
|
TRY
|
||
|
{
|
||
|
if ( ( codepage < 0 ) || ( 0 == pbstrOut ) )
|
||
|
THROW( CException( E_INVALIDARG ) );
|
||
|
|
||
|
CVirtualString vString( 512 );
|
||
|
|
||
|
if ( 0 != bstrIn )
|
||
|
HTMLEscapeW( bstrIn, vString, codepage );
|
||
|
|
||
|
BSTR bstr = SysAllocStringLen( vString.GetPointer(), vString.StrLen() );
|
||
|
if ( 0 == bstr )
|
||
|
THROW( CException( E_OUTOFMEMORY ) );
|
||
|
|
||
|
*pbstrOut = bstr;
|
||
|
}
|
||
|
CATCH( CException, e )
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
SetError( sc, OLESTR("HTMLEncode"), eIxssoError );
|
||
|
}
|
||
|
END_CATCH;
|
||
|
|
||
|
return sc;
|
||
|
} //HTMLEncode
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CixssoUtil::URLEncode - public
|
||
|
//
|
||
|
// Synopsis: Encode a string for use in a URL. Take the output code page
|
||
|
// into account so that unicode characters not representable in
|
||
|
// the code page are output as %uxxxx escapes.
|
||
|
//
|
||
|
// Arguments: [bstrIn] - input string
|
||
|
// [codepage] - code page for output string
|
||
|
// [pbstrOut] - pointer where output string is returned
|
||
|
//
|
||
|
// Returns: SCODE - status return
|
||
|
//
|
||
|
// History: 04 Apr 1997 Alanw Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CixssoUtil::URLEncode(BSTR bstrIn, LONG codepage, BSTR * pbstrOut)
|
||
|
{
|
||
|
_err.Reset();
|
||
|
|
||
|
SCODE sc = S_OK;
|
||
|
CTranslateSystemExceptions translate;
|
||
|
TRY
|
||
|
{
|
||
|
if ( ( codepage < 0 ) || ( 0 == pbstrOut ) )
|
||
|
THROW( CException( E_INVALIDARG ) );
|
||
|
|
||
|
CVirtualString vString( 512 );
|
||
|
|
||
|
if ( 0 != bstrIn )
|
||
|
URLEscapeW( bstrIn, vString, codepage, FALSE );
|
||
|
|
||
|
BSTR bstr = SysAllocStringLen( vString.GetPointer(), vString.StrLen() );
|
||
|
if ( 0 == bstr )
|
||
|
THROW( CException( E_OUTOFMEMORY ) );
|
||
|
|
||
|
*pbstrOut = bstr;
|
||
|
}
|
||
|
CATCH( CException, e )
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
SetError( sc, OLESTR("URLEncode"), eIxssoError );
|
||
|
}
|
||
|
END_CATCH;
|
||
|
|
||
|
return sc;
|
||
|
} //URLEncode
|
||
|
|
||
|
|