1237 lines
30 KiB
C++
1237 lines
30 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2000 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// ResourceObject.cpp
|
|
//
|
|
// Description:
|
|
// CResourceObject automation class implementation.
|
|
//
|
|
// Maintained By:
|
|
// gpease 08-FEB-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pch.h"
|
|
#include "ResourceObject.h"
|
|
|
|
DEFINE_THISCLASS( "CResourceObject" );
|
|
#define STATIC_AUTOMATION_METHODS 4
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Constructor
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CResourceObject::CResourceObject(
|
|
RESOURCE_HANDLE hResourceIn,
|
|
PLOG_EVENT_ROUTINE plerIn,
|
|
HKEY hkeyIn,
|
|
LPCWSTR pszNameIn
|
|
) :
|
|
m_hResource( hResourceIn ),
|
|
m_pler( plerIn ),
|
|
m_hkey( hkeyIn ),
|
|
m_pszName( pszNameIn )
|
|
{
|
|
TraceClsFunc( "CResourceObject\n" );
|
|
Assert( m_cRef == 0 );
|
|
AddRef( );
|
|
|
|
TraceFuncExit( );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Destructor
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CResourceObject::~CResourceObject()
|
|
{
|
|
TraceClsFunc( "~CResourceObject\n" );
|
|
|
|
// Don't free m_pszName.
|
|
// Don't close m_hkey.
|
|
|
|
TraceFuncExit( );
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// IUnknown
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CScriptResource::[IUnknown] QueryInterface(
|
|
// REFIID riid,
|
|
// LPVOID * ppv
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::QueryInterface(
|
|
REFIID riid,
|
|
void** ppUnk
|
|
)
|
|
{
|
|
TraceClsFunc( "[IUnknown] QueryInterface( )\n" );
|
|
|
|
HRESULT hr = E_NOINTERFACE;
|
|
|
|
*ppUnk = NULL;
|
|
|
|
if ( riid == IID_IUnknown )
|
|
{
|
|
*ppUnk = TraceInterface( __THISCLASS__, IUnknown, (IDispatchEx*) this, 0 );
|
|
hr = S_OK;
|
|
}
|
|
else if ( riid == IID_IDispatchEx )
|
|
{
|
|
*ppUnk = TraceInterface( __THISCLASS__, IDispatchEx, (IDispatchEx*) this, 0 );
|
|
hr = S_OK;
|
|
}
|
|
else if ( riid == IID_IDispatch )
|
|
{
|
|
*ppUnk = TraceInterface( __THISCLASS__, IDispatch, (IDispatchEx*) this, 0 );
|
|
hr = S_OK;
|
|
}
|
|
|
|
if ( hr == S_OK )
|
|
{
|
|
((IUnknown *) *ppUnk)->AddRef( );
|
|
}
|
|
|
|
QIRETURN( hr, riid );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP_( ULONG )
|
|
// CScriptResource::[IUnknown] AddRef( void )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG)
|
|
CResourceObject::AddRef( )
|
|
{
|
|
TraceClsFunc( "[IUnknown] AddRef( )\n" );
|
|
InterlockedIncrement( &m_cRef );
|
|
RETURN( m_cRef );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP_( ULONG )
|
|
// CScriptResource::[IUnknown] Release( void )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG)
|
|
CResourceObject::Release( )
|
|
{
|
|
TraceClsFunc( "[IUnknown] Release( )\n" );
|
|
InterlockedDecrement( &m_cRef );
|
|
if ( m_cRef )
|
|
RETURN( m_cRef );
|
|
|
|
delete this;
|
|
|
|
RETURN( 0 );
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// IDispatch
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::GetTypeInfoCount (
|
|
// UINT * pctinfo // out
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::GetTypeInfoCount (
|
|
UINT * pctinfo // out
|
|
)
|
|
{
|
|
TraceClsFunc( "[IDispatch] GetTypeInfoCount( )\n" );
|
|
|
|
*pctinfo = 0;
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::GetTypeInfo (
|
|
// UINT iTInfo, // in
|
|
// LCID lcid, // in
|
|
// ITypeInfo * * ppTInfo // out
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::GetTypeInfo (
|
|
UINT iTInfo, // in
|
|
LCID lcid, // in
|
|
ITypeInfo * * ppTInfo // out
|
|
)
|
|
{
|
|
TraceClsFunc( "[IDispatch] GetTypeInfo( )\n" );
|
|
|
|
if ( !ppTInfo )
|
|
HRETURN( E_POINTER );
|
|
|
|
*ppTInfo = NULL;
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::GetIDsOfNames (
|
|
// REFIID riid, // in
|
|
// LPOLESTR * rgszNames, // in
|
|
// UINT cNames, // in
|
|
// LCID lcid, // in
|
|
// DISPID * rgDispId // out
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::GetIDsOfNames (
|
|
REFIID riid, // in
|
|
LPOLESTR * rgszNames, // in
|
|
UINT cNames, // in
|
|
LCID lcid, // in
|
|
DISPID * rgDispId // out
|
|
)
|
|
{
|
|
TraceClsFunc( "[IDispatch] GetIDsOfName( )\n" );
|
|
|
|
ZeroMemory( rgDispId, cNames * sizeof(DISPID) );
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::Invoke (
|
|
// DISPID dispIdMember, // in
|
|
// REFIID riid, // in
|
|
// LCID lcid, // in
|
|
// WORD wFlags, // in
|
|
// DISPPARAMS *pDispParams, // out in
|
|
// VARIANT *pVarResult, // out
|
|
// EXCEPINFO *pExcepInfo, // out
|
|
// UINT *puArgErr // out
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::Invoke (
|
|
DISPID dispIdMember, // in
|
|
REFIID riid, // in
|
|
LCID lcid, // in
|
|
WORD wFlags, // in
|
|
DISPPARAMS *pDispParams, // out in
|
|
VARIANT *pVarResult, // out
|
|
EXCEPINFO *pExcepInfo, // out
|
|
UINT *puArgErr // out
|
|
)
|
|
{
|
|
TraceClsFunc( "[IDispatch] Invoke( )\n" );
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// IDispatchEx
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::GetDispID (
|
|
// BSTR bstrName, // in
|
|
// DWORD grfdex, //in
|
|
// DISPID *pid //out
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::GetDispID (
|
|
BSTR bstrName, // in
|
|
DWORD grfdex, //in
|
|
DISPID *pid //out
|
|
)
|
|
{
|
|
TraceClsFunc( "[IDispatchEx] GetDispID( )\n" );
|
|
|
|
if ( pid == NULL
|
|
|| bstrName == NULL
|
|
)
|
|
{
|
|
HRETURN( E_POINTER );
|
|
}
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceMsg( mtfCALLS, "Looking for: %s\n", bstrName );
|
|
|
|
if ( StrCmpI( bstrName, L"Name" ) == 0 )
|
|
{
|
|
*pid = 0;
|
|
}
|
|
else if ( StrCmpI( bstrName, L"LogInformation" ) == 0 )
|
|
{
|
|
*pid = 1;
|
|
}
|
|
else if ( StrCmpI( bstrName, L"AddProperty" ) == 0 )
|
|
{
|
|
*pid = 2;
|
|
}
|
|
else if ( StrCmpI( bstrName, L"RemoveProperty" ) == 0 )
|
|
{
|
|
*pid = 3;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// See if it is a private property.
|
|
//
|
|
|
|
DWORD dwIndex;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
hr = DISP_E_UNKNOWNNAME;
|
|
|
|
//
|
|
// Enum all the value under the \Cluster\Resources\{Resource}\Parameters.
|
|
//
|
|
for( dwIndex = 0; dwErr == ERROR_SUCCESS; dwIndex ++ )
|
|
{
|
|
WCHAR szName[ 1024 ]; // randomly large
|
|
DWORD cbName = sizeof(szName)/sizeof(szName[0]);
|
|
|
|
dwErr = ClusterRegEnumValue( m_hkey,
|
|
dwIndex,
|
|
szName,
|
|
&cbName,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
if ( dwErr == ERROR_NO_MORE_ITEMS )
|
|
break; // done!
|
|
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
hr = THR( HRESULT_FROM_WIN32( dwErr ) );
|
|
goto Error;
|
|
}
|
|
|
|
if ( StrCmpI( bstrName, szName ) == 0 )
|
|
{
|
|
//
|
|
// Found a match.
|
|
//
|
|
*pid = STATIC_AUTOMATION_METHODS + dwIndex;
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// ...else keep going.
|
|
//
|
|
}
|
|
}
|
|
|
|
Cleanup:
|
|
HRETURN( hr );
|
|
|
|
Error:
|
|
LogError( hr );
|
|
goto Cleanup;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::InvokeEx (
|
|
// DISPID idIn,
|
|
// LCID lcidIn,
|
|
// WORD wFlagsIn,
|
|
// DISPPARAMS * pdpIn,
|
|
// VARIANT * pvarResOut,
|
|
// EXCEPINFO * peiOut,
|
|
// IServiceProvider * pspCallerIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::InvokeEx (
|
|
DISPID idIn,
|
|
LCID lcidIn,
|
|
WORD wFlagsIn,
|
|
DISPPARAMS * pdpIn,
|
|
VARIANT * pvarResOut,
|
|
EXCEPINFO * peiOut,
|
|
IServiceProvider * pspCallerIn
|
|
)
|
|
{
|
|
TraceClsFunc2( "[IDispatchEx] InvokeEx( idIn = %u, ..., wFlagsIn = 0x%08x, ... )\n", idIn, wFlagsIn );
|
|
|
|
HRESULT hr = DISP_E_MEMBERNOTFOUND;
|
|
|
|
switch ( idIn )
|
|
{
|
|
case 0: // Name
|
|
if ( wFlagsIn & DISPATCH_PROPERTYGET )
|
|
{
|
|
pvarResOut->vt = VT_BSTR;
|
|
pvarResOut->bstrVal = SysAllocString( m_pszName );
|
|
if ( pvarResOut->bstrVal == NULL )
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 1: // Log
|
|
if ( wFlagsIn & DISPATCH_METHOD )
|
|
{
|
|
hr = THR( LogInformation( pdpIn->rgvarg->bstrVal ) );
|
|
}
|
|
break;
|
|
|
|
case 2: // AddProperty
|
|
if ( wFlagsIn & DISPATCH_METHOD )
|
|
{
|
|
hr = THR( AddPrivateProperty( pdpIn ) );
|
|
}
|
|
break;
|
|
|
|
case 3: // AddProperty
|
|
if ( wFlagsIn & DISPATCH_METHOD )
|
|
{
|
|
hr = THR( RemovePrivateProperty( pdpIn ) );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// See if it is a private property.
|
|
//
|
|
if ( wFlagsIn & DISPATCH_PROPERTYGET )
|
|
{
|
|
hr = THR( ReadPrivateProperty( idIn - STATIC_AUTOMATION_METHODS, pvarResOut ) );
|
|
}
|
|
else if ( wFlagsIn & DISPATCH_PROPERTYPUT )
|
|
{
|
|
hr = THR( WritePrivateProperty( idIn - STATIC_AUTOMATION_METHODS, pdpIn ) );
|
|
}
|
|
break;
|
|
|
|
} // switch: id
|
|
|
|
HRETURN( hr );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::DeleteMemberByName (
|
|
// BSTR bstr, // in
|
|
// DWORD grfdex // in
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::DeleteMemberByName (
|
|
BSTR bstr, // in
|
|
DWORD grfdex // in
|
|
)
|
|
{
|
|
TraceClsFunc( "[IDispatchEx] DeleteMemberByName( )\n" );
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::DeleteMemberByDispID (
|
|
// DISPID id // in
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::DeleteMemberByDispID (
|
|
DISPID id // in
|
|
)
|
|
{
|
|
TraceClsFunc1( "[IDispatchEx] DeleteMemberByDispID( id = %u )\n", id );
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::GetMemberProperties (
|
|
// DISPID id, // in
|
|
// DWORD grfdexFetch, // in
|
|
// DWORD * pgrfdex // out
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::GetMemberProperties (
|
|
DISPID id, // in
|
|
DWORD grfdexFetch, // in
|
|
DWORD * pgrfdex // out
|
|
)
|
|
{
|
|
TraceClsFunc2( "[IDispatchEx] GetMemberProperties( id = %u, grfdexFetch = 0x%08x )\n",
|
|
id, grfdexFetch );
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::GetMemberName (
|
|
// DISPID id, // in
|
|
// BSTR * pbstrName // out
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::GetMemberName (
|
|
DISPID id, // in
|
|
BSTR * pbstrName // out
|
|
)
|
|
{
|
|
TraceClsFunc1( "[IDispatchEx] GetMemberName( id = %u, ... )\n", id );
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::GetNextDispID (
|
|
// DWORD grfdex, // in
|
|
// DISPID id, // in
|
|
// DISPID * pid // out
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::GetNextDispID (
|
|
DWORD grfdex, // in
|
|
DISPID id, // in
|
|
DISPID * pid // out
|
|
)
|
|
{
|
|
TraceClsFunc2( "[IDispatchEx] GetNextDispId( grfdex = 0x%08x, id = %u, ... )\n",
|
|
grfdex, id );
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::GetNameSpaceParent (
|
|
// IUnknown * * ppunk // out
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::GetNameSpaceParent (
|
|
IUnknown * * ppunk // out
|
|
)
|
|
{
|
|
TraceClsFunc( "[IDispatchEx] GetNameSpaceParent( ... )\n" );
|
|
|
|
if ( !ppunk )
|
|
HRETURN( E_POINTER );
|
|
|
|
*ppunk = NULL;
|
|
|
|
HRETURN( E_NOTIMPL );
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Private Methods
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::LogError(
|
|
// HRESULT hrIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::LogError(
|
|
HRESULT hrIn
|
|
)
|
|
{
|
|
TraceClsFunc1( "LogError( hrIn = 0x%08x )\n", hrIn );
|
|
|
|
TraceMsg( mtfCALLS, "HRESULT: 0x%08x\n", hrIn );
|
|
(ClusResLogEvent)( m_hResource, LOG_ERROR, L"HRESULT: 0x%1!08x!.\n", hrIn );
|
|
|
|
HRETURN( S_OK );
|
|
|
|
} //*** LogError( )
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::ReadPrivateProperty(
|
|
// DISPID idIn,
|
|
// VARIANT * pvarResOut
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::ReadPrivateProperty(
|
|
DISPID idIn,
|
|
VARIANT * pvarResOut
|
|
)
|
|
{
|
|
TraceClsFunc( "ReadPrivateProperty( ... )\n" );
|
|
|
|
BSTR * pbstrList;
|
|
|
|
BYTE rgbData[ 1024 ]; // randomly large
|
|
WCHAR szName[ 1024 ]; // randomly large
|
|
DWORD dwType;
|
|
DWORD dwIndex;
|
|
DWORD dwErr;
|
|
|
|
DWORD cbName = sizeof(szName)/sizeof(szName[0]);
|
|
DWORD cbData = sizeof(rgbData);
|
|
BOOL fFreepData = FALSE;
|
|
LPBYTE pData = NULL;
|
|
|
|
HRESULT hr = DISP_E_UNKNOWNNAME;
|
|
|
|
//
|
|
// We can jump to the exact entry because the script called
|
|
// GetDispID() before calling this method.
|
|
//
|
|
for ( ;; )
|
|
{
|
|
dwErr = ClusterRegEnumValue( m_hkey,
|
|
idIn,
|
|
szName,
|
|
&cbName,
|
|
&dwType,
|
|
rgbData,
|
|
&cbData
|
|
);
|
|
if ( dwErr == ERROR_MORE_DATA )
|
|
{
|
|
//
|
|
// Make some space if our stack buffer is too small.
|
|
//
|
|
pData = (LPBYTE) TraceAlloc( LMEM_FIXED, cbData );
|
|
if ( pData == NULL )
|
|
goto OutOfMemory;
|
|
|
|
fFreepData = TRUE;
|
|
|
|
continue; // try again
|
|
}
|
|
|
|
if ( dwErr == ERROR_NO_MORE_ITEMS )
|
|
goto Cleanup; // item must have dissappeared
|
|
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
hr = THR( HRESULT_FROM_WIN32( dwErr ) );
|
|
goto Error;
|
|
}
|
|
|
|
Assert( dwErr == ERROR_SUCCESS );
|
|
break; // exit loop
|
|
}
|
|
|
|
//
|
|
// It's a private property. Convert the data into the appropriate
|
|
// VARIANT.
|
|
//
|
|
|
|
switch ( dwType )
|
|
{
|
|
case REG_DWORD:
|
|
{
|
|
DWORD * pdw = (DWORD *) rgbData;
|
|
pvarResOut->vt = VT_I4;
|
|
pvarResOut->intVal = *pdw;
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
case REG_EXPAND_SZ:
|
|
{
|
|
DWORD cbNeeded;
|
|
WCHAR szExpandedString[ 2 * MAX_PATH ]; // randomly large
|
|
DWORD cbSize = sizeof(szExpandedString)/sizeof(szExpandedString[0]);
|
|
LPCWSTR pszData = (LPCWSTR) rgbData;
|
|
|
|
cbNeeded = ExpandEnvironmentStrings( pszData, szExpandedString, cbSize );
|
|
if ( cbSize == 0 )
|
|
goto Win32Error;
|
|
|
|
if ( cbNeeded > cbSize )
|
|
goto OutOfMemory;
|
|
|
|
pvarResOut->vt = VT_BSTR;
|
|
pvarResOut->bstrVal = SysAllocString( szExpandedString );
|
|
if ( pvarResOut->bstrVal == NULL )
|
|
goto OutOfMemory;
|
|
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
case REG_MULTI_SZ:
|
|
{
|
|
//
|
|
// KB: gpease 08-FEB-2000
|
|
// Currently VBScript doesn't support SAFEARRAYs. So someone
|
|
// trying to access a multi-sz will get the following error:
|
|
//
|
|
// Error: 2148139466
|
|
// Source: Microsoft VBScript runtime error
|
|
// Description: Variable uses an Automation type not supported in VBScript
|
|
//
|
|
// The code is correct as far as I can tell, so I am just
|
|
// going to leave it in (it doesn't AV or cause bad things
|
|
// to happen).
|
|
//
|
|
VARIANT var;
|
|
LPWSTR psz;
|
|
DWORD nCount;
|
|
DWORD cbCount;
|
|
DWORD cbBiggestOne;
|
|
|
|
LPWSTR pszData = (LPWSTR) rgbData;
|
|
LPWSTR pszEnd = (LPWSTR) &rgbData[ cbData ];
|
|
|
|
SAFEARRAYBOUND rgsabound[ 1 ];
|
|
|
|
//
|
|
// Figure out how many item there are in the list.
|
|
//
|
|
cbBiggestOne = cbCount = nCount = 0;
|
|
psz = pszData;
|
|
while ( *psz != 0 )
|
|
{
|
|
psz++;
|
|
cbCount ++;
|
|
if ( *psz == 0 )
|
|
{
|
|
if ( cbCount > cbBiggestOne )
|
|
{
|
|
cbBiggestOne = cbCount;
|
|
}
|
|
cbCount = 0;
|
|
nCount++;
|
|
psz++;
|
|
}
|
|
}
|
|
|
|
Assert( psz <= pszEnd );
|
|
|
|
//
|
|
// Create a safe array to package the string into.
|
|
//
|
|
rgsabound[0].lLbound = 0;
|
|
rgsabound[0].cElements = nCount;
|
|
pvarResOut->vt = VT_SAFEARRAY;
|
|
pvarResOut->parray = SafeArrayCreate( VT_BSTR, 1, rgsabound );
|
|
if ( pvarResOut->parray == NULL )
|
|
goto OutOfMemory;
|
|
|
|
//
|
|
// Fix the memory location of the array so it can be accessed
|
|
// thru an array pointer.
|
|
//
|
|
hr = THR( SafeArrayAccessData( pvarResOut->parray, (void**) &pbstrList ) );
|
|
if ( FAILED( hr ) )
|
|
goto Error;
|
|
|
|
//
|
|
// Convert the multi-string into BSTRs
|
|
//
|
|
psz = pszData;
|
|
for( nCount = 0; *psz != 0 ; nCount ++ )
|
|
{
|
|
pbstrList[ nCount ] = SysAllocString( psz );
|
|
if ( pbstrList[ nCount ] == NULL )
|
|
goto OutOfMemory;
|
|
|
|
//
|
|
// Skip the next entry.
|
|
//
|
|
while ( *psz != 0 )
|
|
{
|
|
psz++;
|
|
}
|
|
psz++;
|
|
}
|
|
|
|
Assert( psz <= pszEnd );
|
|
|
|
//
|
|
// Release the array.
|
|
//
|
|
hr = THR( SafeArrayUnaccessData( pvarResOut->parray ) );
|
|
if ( FAILED( hr ) )
|
|
goto Error;
|
|
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
case REG_SZ:
|
|
{
|
|
LPCWSTR pszData = (LPCWSTR) rgbData;
|
|
pvarResOut->bstrVal = SysAllocString( pszData );
|
|
if ( pvarResOut->bstrVal == NULL )
|
|
goto OutOfMemory;
|
|
|
|
pvarResOut->vt = VT_BSTR;
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
case REG_BINARY:
|
|
default:
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATATYPE );
|
|
goto Error;
|
|
} // switch: dwType
|
|
|
|
Cleanup:
|
|
if ( fFreepData
|
|
&& pData != NULL
|
|
)
|
|
{
|
|
TraceFree( pData );
|
|
}
|
|
|
|
//
|
|
// Make sure this has been wiped if there is a problem.
|
|
//
|
|
if ( FAILED( hr ) )
|
|
{
|
|
VariantClear( pvarResOut );
|
|
}
|
|
|
|
HRETURN( hr );
|
|
|
|
Error:
|
|
LogError( hr );
|
|
goto Cleanup;
|
|
|
|
Win32Error:
|
|
hr = HRESULT_FROM_WIN32( GetLastError( ) );
|
|
goto Error;
|
|
|
|
OutOfMemory:
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::WritePrivateProperty(
|
|
// DISPID idIn,
|
|
// DISPPARAMS * pdpIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::WritePrivateProperty(
|
|
DISPID idIn,
|
|
DISPPARAMS * pdpIn
|
|
)
|
|
{
|
|
TraceClsFunc( "WritePrivateProperty( ... )\n" );
|
|
|
|
DWORD dwType;
|
|
DWORD dwErr;
|
|
DWORD cbData;
|
|
UINT uiArg;
|
|
|
|
WCHAR szName [ 1024 ]; // randomly large
|
|
|
|
DWORD cbName = sizeof(szName)/sizeof(szName[0]);
|
|
|
|
HRESULT hr = DISP_E_UNKNOWNNAME;
|
|
|
|
//
|
|
// Do some parameter validation.
|
|
//
|
|
if ( pdpIn->cArgs != 1 || pdpIn->cNamedArgs > 1 )
|
|
goto BadParamCount;
|
|
|
|
//
|
|
// We can jump to the exact entry because the script called
|
|
// GetDispID() before calling this method. Here we are only
|
|
// going to validate that the value exists and what type
|
|
// the value is.
|
|
//
|
|
dwErr = ClusterRegEnumValue( m_hkey,
|
|
idIn,
|
|
szName,
|
|
&cbName,
|
|
&dwType,
|
|
NULL,
|
|
NULL
|
|
);
|
|
if ( dwErr == ERROR_NO_MORE_ITEMS )
|
|
goto Cleanup; // item must have dissappeared
|
|
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
hr = THR( HRESULT_FROM_WIN32( dwErr ) );
|
|
goto Error;
|
|
}
|
|
|
|
//
|
|
// It's a private property. Convert the script data into the
|
|
// appropriate VARIANT and then write it into the hive.
|
|
//
|
|
switch ( dwType )
|
|
{
|
|
case REG_DWORD:
|
|
{
|
|
VARIANT var;
|
|
|
|
VariantInit( &var );
|
|
|
|
hr = THR( DispGetParam( pdpIn, DISPID_PROPERTYPUT, VT_I4, &var, &uiArg ) );
|
|
if ( FAILED( hr ) )
|
|
goto Error;
|
|
|
|
cbData = sizeof( var.intVal );
|
|
dwErr = TW32( ClusterRegSetValue( m_hkey, szName, dwType, (LPBYTE) &var.intVal, cbData ) );
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( dwErr );
|
|
goto Error;
|
|
}
|
|
|
|
VariantClear( &var );
|
|
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
case REG_EXPAND_SZ:
|
|
case REG_SZ:
|
|
{
|
|
VARIANT var;
|
|
|
|
VariantInit( &var );
|
|
|
|
hr = THR( DispGetParam( pdpIn, DISPID_PROPERTYPUT, VT_BSTR, &var, &uiArg ) );
|
|
if ( FAILED( hr ) )
|
|
goto Error;
|
|
|
|
cbData = sizeof(WCHAR) * ( SysStringLen( var.bstrVal ) + 1 );
|
|
|
|
dwErr = TW32( ClusterRegSetValue( m_hkey, szName, dwType, (LPBYTE) var.bstrVal, cbData ) );
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( dwErr );
|
|
goto Error;
|
|
}
|
|
|
|
VariantClear( &var );
|
|
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
case REG_MULTI_SZ:
|
|
case REG_BINARY:
|
|
//
|
|
// Can't handle these since VBScript can't generate them.
|
|
//
|
|
default:
|
|
hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATATYPE );
|
|
goto Error;
|
|
} // switch: dwType
|
|
|
|
Cleanup:
|
|
HRETURN( hr );
|
|
|
|
Error:
|
|
LogError( hr );
|
|
goto Cleanup;
|
|
|
|
BadParamCount:
|
|
hr = THR( DISP_E_BADPARAMCOUNT );
|
|
goto Error;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::RemovePrivateProperty(
|
|
// DISPPARAMS * pdpIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::RemovePrivateProperty(
|
|
DISPPARAMS * pdpIn
|
|
)
|
|
{
|
|
TraceClsFunc( "RemovePrivateProperty( ... )\n" );
|
|
|
|
HRESULT hr;
|
|
DWORD dwErr;
|
|
UINT uiArg;
|
|
VARIANT var;
|
|
|
|
VariantInit( &var );
|
|
|
|
//
|
|
// Do some parameter validation.
|
|
//
|
|
if ( pdpIn->cArgs != 1 || pdpIn->cNamedArgs > 1 )
|
|
goto BadParamCount;
|
|
|
|
//
|
|
// Retrieve the name of the property to remove.
|
|
//
|
|
hr = THR( DispGetParam( pdpIn, 0, VT_BSTR, &var, &uiArg ) );
|
|
if ( FAILED( hr ) )
|
|
goto Error;
|
|
|
|
//
|
|
// Delete the value from the hive.
|
|
//
|
|
dwErr = TW32( ClusterRegDeleteValue( m_hkey, var.bstrVal ) );
|
|
if ( dwErr == ERROR_FILE_NOT_FOUND )
|
|
{
|
|
hr = THR( DISP_E_UNKNOWNNAME );
|
|
goto Error;
|
|
}
|
|
else if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( dwErr );
|
|
goto Error;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
VariantClear( &var );
|
|
|
|
HRETURN( hr );
|
|
|
|
Error:
|
|
LogError( hr );
|
|
goto Cleanup;
|
|
|
|
BadParamCount:
|
|
hr = THR( DISP_E_BADPARAMCOUNT );
|
|
goto Error;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::AddPrivateProperty(
|
|
// DISPPARAMS * pdpIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::AddPrivateProperty(
|
|
DISPPARAMS * pdpIn
|
|
)
|
|
{
|
|
TraceClsFunc( "AddPrivateProperty( ... )\n" );
|
|
|
|
DWORD dwType;
|
|
DWORD dwErr;
|
|
DWORD cbName;
|
|
DWORD cbData;
|
|
UINT uiArg;
|
|
|
|
LPBYTE pData;
|
|
|
|
VARIANT varProperty;
|
|
VARIANT varValue;
|
|
|
|
HRESULT hr;
|
|
|
|
WCHAR szNULL [] = L"";
|
|
|
|
VariantInit( &varProperty );
|
|
VariantInit( &varValue );
|
|
|
|
//
|
|
// Do some parameter validation.
|
|
//
|
|
if ( pdpIn->cArgs == 0
|
|
|| pdpIn->cArgs > 2
|
|
|| pdpIn->cNamedArgs > 2
|
|
)
|
|
goto BadParamCount;
|
|
|
|
//
|
|
// Retrieve the name of the property.
|
|
//
|
|
hr = THR( DispGetParam( pdpIn, 0, VT_BSTR, &varProperty, &uiArg ) );
|
|
if ( FAILED( hr ) )
|
|
goto Error;
|
|
|
|
//
|
|
// If there are 2 args, the second one indicates the default value.
|
|
//
|
|
if ( pdpIn->cArgs == 2 )
|
|
{
|
|
//
|
|
// DISPPARAMS are parsed in reverse order so "1" is actually the name
|
|
// and "0" is the default value.
|
|
//
|
|
switch ( pdpIn->rgvarg[0].vt )
|
|
{
|
|
case VT_I4:
|
|
case VT_I2:
|
|
case VT_BOOL:
|
|
case VT_UI1:
|
|
case VT_UI2:
|
|
case VT_UI4:
|
|
case VT_INT:
|
|
case VT_UINT:
|
|
hr = THR( DispGetParam( pdpIn, 1, VT_I4, &varValue, &uiArg ) );
|
|
if ( FAILED( hr ) )
|
|
goto Error;
|
|
|
|
dwType = REG_DWORD;
|
|
pData = (LPBYTE) &varValue.intVal;
|
|
cbData = sizeof(DWORD);
|
|
break;
|
|
|
|
case VT_BSTR:
|
|
hr = THR( DispGetParam( pdpIn, 1, VT_BSTR, &varValue, &uiArg ) );
|
|
if ( FAILED( hr ) )
|
|
goto Error;
|
|
|
|
dwType = REG_SZ;
|
|
pData = (LPBYTE) varValue.bstrVal;
|
|
cbData = sizeof(WCHAR) * ( SysStringLen( varValue.bstrVal ) + 1 );
|
|
break;
|
|
|
|
default:
|
|
hr = THR( E_INVALIDARG );
|
|
goto Error;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Provide a default of a NULL string.
|
|
//
|
|
dwType = REG_SZ;
|
|
pData = (LPBYTE) &szNULL[0];
|
|
cbData = sizeof(szNULL);
|
|
}
|
|
|
|
//
|
|
// Create the value in the hive.
|
|
//
|
|
dwErr = TW32( ClusterRegSetValue( m_hkey, varProperty.bstrVal, dwType, pData, cbData ) );
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
hr = HRESULT_FROM_WIN32( dwErr );
|
|
goto Error;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
VariantClear( &varProperty );
|
|
VariantClear( &varValue );
|
|
HRETURN( hr );
|
|
|
|
Error:
|
|
LogError( hr );
|
|
goto Cleanup;
|
|
|
|
BadParamCount:
|
|
hr = THR( DISP_E_BADPARAMCOUNT );
|
|
goto Error;
|
|
}
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Automation Methods
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// STDMETHODIMP
|
|
// CResourceObject::LogInformation(
|
|
// BSTR bstrString
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CResourceObject::LogInformation(
|
|
BSTR bstrString
|
|
)
|
|
{
|
|
TraceClsFunc1( "LogInformation( %ws )\n", bstrString );
|
|
|
|
TraceMsg( mtfCALLS, "LOG_INFORMATION: %s\n", bstrString );
|
|
|
|
m_pler( m_hResource, LOG_INFORMATION, L"%1\n", bstrString );
|
|
|
|
HRETURN( S_OK );
|
|
}
|