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.
978 lines
28 KiB
978 lines
28 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2000-2003 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// GenScript.cpp
|
|
//
|
|
// Description:
|
|
// DLL services/entry points for the generic script resource.
|
|
//
|
|
// Maintained By:
|
|
// Ozan Ozhan (OzanO) 04-APR-2002
|
|
// Geoff Pease (GPease) 08-FEB-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Pch.h"
|
|
#include "ActiveScriptSite.h"
|
|
#include "ScriptResource.h"
|
|
#include "SpinLock.h"
|
|
|
|
//
|
|
// Debugging Module Name
|
|
//
|
|
DEFINE_MODULE("SCRIPTRES")
|
|
|
|
//
|
|
// DLL Globals
|
|
//
|
|
HINSTANCE g_hInstance = NULL;
|
|
LONG g_cObjects = 0;
|
|
LONG g_cLock = 0;
|
|
WCHAR g_szDllFilename[ MAX_PATH ] = { 0 };
|
|
|
|
#if defined(DEBUG)
|
|
LPVOID g_GlobalMemoryList = NULL; // Global memory tracking list
|
|
#endif
|
|
|
|
PSET_RESOURCE_STATUS_ROUTINE g_prsrCallback = NULL;
|
|
|
|
extern "C"
|
|
{
|
|
|
|
extern CLRES_FUNCTION_TABLE GenScriptFunctionTable;
|
|
|
|
//
|
|
// GenScript resource read-write private properties
|
|
//
|
|
RESUTIL_PROPERTY_ITEM
|
|
GenScriptResourcePrivateProperties[] = {
|
|
{ CLUSREG_NAME_GENSCRIPT_SCRIPT_FILEPATH, NULL, CLUSPROP_FORMAT_SZ, 0, 0, 0, RESUTIL_PROPITEM_REQUIRED, FIELD_OFFSET( GENSCRIPT_PROPS, pszScriptFilePath ) },
|
|
{ 0 }
|
|
};
|
|
|
|
DWORD
|
|
ScriptValidateResourcePrivateProperties(
|
|
CScriptResource * pres
|
|
, PVOID pvBufferIn
|
|
, DWORD dwBufferInSizeIn
|
|
, PGENSCRIPT_PROPS pPropsCurrent
|
|
, PGENSCRIPT_PROPS pPropsNew
|
|
);
|
|
|
|
//****************************************************************************
|
|
//
|
|
// DLL Entry Points
|
|
//
|
|
//****************************************************************************
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// BOOL
|
|
// WINAPI
|
|
// GenScriptDllEntryPoint(
|
|
// HANDLE hInstIn,
|
|
// ULONG ulReasonIn,
|
|
// LPVOID lpReservedIn
|
|
// )
|
|
//
|
|
// Description:
|
|
// Dll entry point.
|
|
//
|
|
// Arguments:
|
|
// hInstIn - DLL instance handle.
|
|
// ulReasonIn - DLL reason code for entrance.
|
|
// lpReservedIn - Not used.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
WINAPI
|
|
GenScriptDllEntryPoint(
|
|
HINSTANCE hInstIn,
|
|
ULONG ulReasonIn,
|
|
LPVOID // lpReservedIn
|
|
)
|
|
{
|
|
//
|
|
// KB: THREAD_OPTIMIZATIONS gpease 19-OCT-1999
|
|
//
|
|
// By defining this you can prevent the linker
|
|
// from calling your DllEntry for every new thread.
|
|
// This makes creating new threads significantly
|
|
// faster if every DLL in a process does it.
|
|
// Unfortunately, not all DLLs do this.
|
|
//
|
|
// In CHKed/DEBUG, we keep this on for memory
|
|
// tracking.
|
|
//
|
|
#if ! defined( DEBUG )
|
|
#define THREAD_OPTIMIZATIONS
|
|
#endif // DEBUG
|
|
|
|
switch( ulReasonIn )
|
|
{
|
|
//////////////////////////////////////////////////////////////////////
|
|
// DLL_PROCESS_ATTACH
|
|
//////////////////////////////////////////////////////////////////////
|
|
case DLL_PROCESS_ATTACH:
|
|
{
|
|
#if defined( DEBUG_SW_TRACING_ENABLED )
|
|
TraceInitializeProcess( g_rgTraceControlGuidList, ARRAYSIZE( g_rgTraceControlGuidList ), TRUE );
|
|
#else // ! DEBUG_SW_TRACING_ENABLED
|
|
TraceInitializeProcess( TRUE );
|
|
#endif // DEBUG_SW_TRACING_ENABLED
|
|
|
|
TraceFunc( "" );
|
|
TraceMessage( TEXT(__FILE__),
|
|
__LINE__,
|
|
__MODULE__,
|
|
mtfDLL,
|
|
TEXT("DLL: DLL_PROCESS_ATTACH - ThreadID = %#x"),
|
|
GetCurrentThreadId()
|
|
);
|
|
|
|
g_hInstance = hInstIn;
|
|
|
|
#if defined( ENTRY_PREFIX )
|
|
hProxyDll = g_hInstance;
|
|
#endif // ENTRY_PREFIX
|
|
|
|
GetModuleFileNameW( g_hInstance, g_szDllFilename, ARRAYSIZE( g_szDllFilename ) );
|
|
|
|
//
|
|
// Create a global memory list so that memory allocated by one
|
|
// thread and handed to another can be tracked without causing
|
|
// unnecessary trace messages.
|
|
//
|
|
TraceCreateMemoryList( g_GlobalMemoryList );
|
|
|
|
#if defined( THREAD_OPTIMIZATIONS )
|
|
{
|
|
//
|
|
// Disable thread library calls so that we don't get called
|
|
// on thread attach and detach.
|
|
//
|
|
BOOL fResult = DisableThreadLibraryCalls( g_hInstance );
|
|
if ( ! fResult )
|
|
{
|
|
TW32MSG( GetLastError(), "DisableThreadLibraryCalls()" );
|
|
}
|
|
}
|
|
#endif // THREAD_OPTIMIZATIONS
|
|
|
|
#if defined( USE_FUSION )
|
|
//
|
|
// Initialize Fusion.
|
|
//
|
|
// The value of IDR_MANIFEST in the call to
|
|
// SHFusionInitializeFromModuleID() must match the value specified in the
|
|
// sources file for SXS_MANIFEST_RESOURCE_ID.
|
|
//
|
|
BOOL fResult = SHFusionInitializeFromModuleID( hInstIn, IDR_MANIFEST );
|
|
if ( ! fResult )
|
|
{
|
|
TW32MSG( GetLastError(), "SHFusionInitializeFromModuleID()" );
|
|
}
|
|
#endif // USE_FUSION
|
|
|
|
#if defined( DO_MODULE_INIT )
|
|
THR( HrLocalProcessInit() );
|
|
#endif
|
|
|
|
//
|
|
// This is necessary here because TraceFunc() defines a variable
|
|
// on the stack which isn't available outside the scope of this
|
|
// block.
|
|
// This function doesn't do anything but clean up after
|
|
// TraceFunc().
|
|
//
|
|
FRETURN( TRUE );
|
|
|
|
break;
|
|
} // case: DLL_PROCESS_ATTACH
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// DLL_PROCESS_DETACH
|
|
//////////////////////////////////////////////////////////////////////
|
|
case DLL_PROCESS_DETACH:
|
|
{
|
|
TraceFunc( "" );
|
|
TraceMessage( TEXT(__FILE__),
|
|
__LINE__,
|
|
__MODULE__,
|
|
mtfDLL,
|
|
TEXT("DLL: DLL_PROCESS_DETACH - ThreadID = %#x [ g_cLock=%u, g_cObjects=%u ]"),
|
|
GetCurrentThreadId(),
|
|
g_cLock,
|
|
g_cObjects
|
|
);
|
|
|
|
#if defined( DO_MODULE_UNINIT )
|
|
THR( HrLocalProcessUninit() );
|
|
#endif
|
|
|
|
//
|
|
// Cleanup the global memory list used to track memory allocated
|
|
// in one thread and then handed to another.
|
|
//
|
|
TraceTerminateMemoryList( g_GlobalMemoryList );
|
|
|
|
//
|
|
// This is necessary here because TraceFunc() defines a variable
|
|
// on the stack which isn't available outside the scope of this
|
|
// block.
|
|
// This function doesn't do anything but clean up after
|
|
// TraceFunc().
|
|
//
|
|
FRETURN( TRUE );
|
|
|
|
#if defined( DEBUG_SW_TRACING_ENABLED )
|
|
TraceTerminateProcess( g_rgTraceControlGuidList, ARRAYSIZE( g_rgTraceControlGuidList )
|
|
);
|
|
#else // ! DEBUG_SW_TRACING_ENABLED
|
|
TraceTerminateProcess();
|
|
#endif // DEBUG_SW_TRACING_ENABLED
|
|
|
|
#if defined( USE_FUSION )
|
|
SHFusionUninitialize();
|
|
#endif // USE_FUSION
|
|
|
|
break;
|
|
} // case: DLL_PROCESS_DETACH
|
|
|
|
#if ! defined( THREAD_OPTIMIZATIONS )
|
|
//////////////////////////////////////////////////////////////////////
|
|
// DLL_THREAD_ATTACH
|
|
//////////////////////////////////////////////////////////////////////
|
|
case DLL_THREAD_ATTACH:
|
|
{
|
|
TraceInitializeThread( NULL );
|
|
TraceMessage( TEXT(__FILE__),
|
|
__LINE__,
|
|
__MODULE__,
|
|
mtfDLL,
|
|
TEXT("Thread %#x has started."),
|
|
GetCurrentThreadId()
|
|
);
|
|
TraceFunc( "" );
|
|
TraceMessage( TEXT(__FILE__),
|
|
__LINE__,
|
|
__MODULE__,
|
|
mtfDLL,
|
|
TEXT("DLL: DLL_THREAD_ATTACH - ThreadID = %#x [ g_cLock=%u, g_cObjects=%u ]"),
|
|
GetCurrentThreadId(),
|
|
g_cLock,
|
|
g_cObjects
|
|
);
|
|
|
|
//
|
|
// This is necessary here because TraceFunc() defines a variable
|
|
// on the stack which isn't available outside the scope of this
|
|
// block.
|
|
// This function doesn't do anything but clean up after
|
|
// TraceFunc().
|
|
//
|
|
FRETURN( TRUE );
|
|
|
|
break;
|
|
} // case: DLL_THREAD_ATTACH
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// DLL_THREAD_DETACH
|
|
//////////////////////////////////////////////////////////////////////
|
|
case DLL_THREAD_DETACH:
|
|
{
|
|
TraceFunc( "" );
|
|
TraceMessage( TEXT(__FILE__),
|
|
__LINE__,
|
|
__MODULE__,
|
|
mtfDLL,
|
|
TEXT("DLL: DLL_THREAD_DETACH - ThreadID = %#x [ g_cLock=%u, g_cObjects=%u ]"),
|
|
GetCurrentThreadId(),
|
|
g_cLock,
|
|
g_cObjects
|
|
);
|
|
|
|
//
|
|
// This is necessary here because TraceFunc() defines a variable
|
|
// on the stack which isn't available outside the scope of this
|
|
// block.
|
|
// This function doesn't do anything but clean up after
|
|
// TraceFunc().
|
|
//
|
|
FRETURN( TRUE );
|
|
|
|
TraceThreadRundown();
|
|
|
|
break;
|
|
} // case: DLL_THREAD_DETACH
|
|
#endif // ! THREAD_OPTIMIZATIONS
|
|
|
|
default:
|
|
{
|
|
TraceFunc( "" );
|
|
TraceMessage( TEXT(__FILE__),
|
|
__LINE__,
|
|
__MODULE__,
|
|
mtfDLL,
|
|
TEXT("DLL: UNKNOWN ENTRANCE REASON - ThreadID = %#x [ g_cLock=%u, g_cObjects=%u ]"),
|
|
GetCurrentThreadId(),
|
|
g_cLock,
|
|
g_cObjects
|
|
);
|
|
|
|
#if defined( THREAD_OPTIMIZATIONS )
|
|
Assert( ( ulReasonIn != DLL_THREAD_ATTACH )
|
|
&& ( ulReasonIn != DLL_THREAD_DETACH ) );
|
|
#endif // THREAD_OPTIMIZATIONS
|
|
|
|
//
|
|
// This is necessary here because TraceFunc defines a variable
|
|
// on the stack which isn't available outside the scope of this
|
|
// block.
|
|
// This function doesn't do anything but clean up after TraceFunc.
|
|
//
|
|
FRETURN( TRUE );
|
|
|
|
break;
|
|
} // default case
|
|
} // switch on reason code
|
|
|
|
return TRUE;
|
|
|
|
} //*** GenScriptDllEntryPoint()
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// Cluster Resource Entry Points
|
|
//
|
|
//****************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// void
|
|
// WINAPI
|
|
// ScriptResClose(
|
|
// RESID residIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
WINAPI
|
|
ScriptResClose(
|
|
RESID residIn
|
|
)
|
|
{
|
|
TraceFunc1( "ScriptResClose( residIn = 0x%08x )\n", residIn );
|
|
|
|
HRESULT hr;
|
|
|
|
CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
|
|
|
|
if ( pres == NULL )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( pres->Close( ) );
|
|
hr = STATUS_TO_RETURN( hr );
|
|
|
|
//
|
|
// Matching Release() for object creation in ScriptResOpen( ).
|
|
//
|
|
|
|
pres->Release( );
|
|
|
|
Cleanup:
|
|
|
|
TraceFuncExit( );
|
|
|
|
} //*** ScriptResClose( )
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RESID
|
|
// WINAPI
|
|
// ScriptResOpen(
|
|
// LPCWSTR pszNameIn,
|
|
// HKEY hkeyIn,
|
|
// RESOURCE_HANDLE hResourceIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
RESID
|
|
WINAPI
|
|
ScriptResOpen(
|
|
LPCWSTR pszNameIn,
|
|
HKEY hkeyIn,
|
|
RESOURCE_HANDLE hResourceIn
|
|
)
|
|
{
|
|
TraceFunc1( "ScriptResOpen( pszNameIn = '%s', hkeyIn, hResourceIn )\n", pszNameIn );
|
|
|
|
HRESULT hr;
|
|
CScriptResource * pres;
|
|
|
|
pres = CScriptResource_CreateInstance( pszNameIn, hkeyIn, hResourceIn );
|
|
if ( pres == NULL )
|
|
{
|
|
hr = TW32( ERROR_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( pres->Open( ) );
|
|
hr = STATUS_TO_RETURN( hr );
|
|
|
|
Cleanup:
|
|
|
|
//
|
|
// KB: Don't pres->Release( ) as we are handing it out as out RESID.
|
|
//
|
|
RETURN( pres );
|
|
|
|
} //*** ScriptResOpen( )
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DWORD
|
|
// WINAPI
|
|
// ScriptResOnline(
|
|
// RESID residIn,
|
|
// PHANDLE hEventInout
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
WINAPI
|
|
ScriptResOnline(
|
|
RESID residIn,
|
|
PHANDLE hEventInout
|
|
)
|
|
{
|
|
TraceFunc2( "ScriptResOnline( residIn = 0x%08x, hEventInout = 0x%08x )\n",
|
|
residIn, hEventInout );
|
|
|
|
HRESULT hr;
|
|
|
|
CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
|
|
|
|
if ( pres == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( pres->Online( ) );
|
|
hr = STATUS_TO_RETURN( hr );
|
|
|
|
Cleanup:
|
|
|
|
RETURN( hr );
|
|
|
|
} //*** ScriptResOnline( )
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DWORD
|
|
// WINAPI
|
|
// ScriptResOffline(
|
|
// RESID residIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
WINAPI
|
|
ScriptResOffline(
|
|
RESID residIn
|
|
)
|
|
{
|
|
TraceFunc1( "ScriptResOffline( residIn = 0x%08x )\n", residIn );
|
|
|
|
HRESULT hr;
|
|
|
|
CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
|
|
|
|
if ( pres == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = THR( pres->Offline( ) );
|
|
hr = STATUS_TO_RETURN( hr );
|
|
|
|
Cleanup:
|
|
|
|
RETURN( hr );
|
|
|
|
} //*** ScriptResOffline( )
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// void
|
|
// WINAPI
|
|
// ScriptResTerminate(
|
|
// RESID residIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
WINAPI
|
|
ScriptResTerminate(
|
|
RESID residIn
|
|
)
|
|
{
|
|
TraceFunc1( "ScriptResTerminate( residIn = 0x%08x )\n", residIn );
|
|
|
|
CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
|
|
|
|
if ( pres == NULL )
|
|
{
|
|
THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
|
|
goto Cleanup;
|
|
}
|
|
|
|
THR( pres->Terminate( ) );
|
|
|
|
Cleanup:
|
|
|
|
TraceFuncExit( );
|
|
|
|
} // ScriptResTerminate( )
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// BOOL
|
|
// WINAPI
|
|
// ScriptResLooksAlive(
|
|
// RESID residIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
WINAPI
|
|
ScriptResLooksAlive(
|
|
RESID residIn
|
|
)
|
|
{
|
|
TraceFunc1( "ScriptResLooksAlive( residIn = 0x%08x )\n", residIn );
|
|
|
|
HRESULT hr;
|
|
BOOL fLooksAlive = FALSE;
|
|
|
|
CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
|
|
|
|
if ( pres == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = STHR( pres->LooksAlive( ) );
|
|
if ( hr == S_OK )
|
|
{
|
|
fLooksAlive = TRUE;
|
|
} // if: S_OK
|
|
hr = STATUS_TO_RETURN( hr );
|
|
|
|
Cleanup:
|
|
|
|
RETURN( fLooksAlive );
|
|
|
|
} //*** ScriptResLooksAlive( )
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// BOOL
|
|
// WINAPI
|
|
// ScriptResIsAlive(
|
|
// RESID residIn
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
WINAPI
|
|
ScriptResIsAlive(
|
|
RESID residIn
|
|
)
|
|
{
|
|
TraceFunc1( "ScriptResIsAlive( residIn = 0x%08x )\n", residIn );
|
|
|
|
HRESULT hr;
|
|
BOOL fIsAlive = FALSE;
|
|
|
|
CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
|
|
|
|
if ( pres == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG ); // TODO: Replace with Win32 error code
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = STHR( pres->IsAlive( ) );
|
|
if ( hr == S_OK )
|
|
{
|
|
fIsAlive = TRUE;
|
|
} // if: S_OK
|
|
hr = STATUS_TO_RETURN( hr );
|
|
|
|
Cleanup:
|
|
|
|
RETURN( fIsAlive );
|
|
|
|
} //*** ScriptResIsAlive( )
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DWORD
|
|
// ScriptResResourceControl(
|
|
// RESID residIn,
|
|
// DWORD dwControlCodeIn,
|
|
// PVOID pvBufferIn,
|
|
// DWORD dwBufferInSizeIn,
|
|
// PVOID pvBufferOut,
|
|
// DWORD dwBufferOutSizeIn,
|
|
// LPDWORD pdwBytesReturnedOut
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
ScriptResResourceControl(
|
|
RESID residIn,
|
|
DWORD dwControlCodeIn,
|
|
PVOID pvBufferIn,
|
|
DWORD dwBufferInSizeIn,
|
|
PVOID pvBufferOut,
|
|
DWORD dwBufferOutSizeIn,
|
|
LPDWORD pdwBytesReturnedOut
|
|
)
|
|
{
|
|
TraceFunc( "ScriptResResourceControl( ... )\n " );
|
|
|
|
DWORD scErr = ERROR_SUCCESS;
|
|
DWORD dwBytesRequired = 0;
|
|
DWORD dwPendingTimeout = 0;
|
|
GENSCRIPT_PROPS propsNew;
|
|
GENSCRIPT_PROPS propsCurrent;
|
|
|
|
*pdwBytesReturnedOut = 0;
|
|
|
|
CScriptResource * pres = reinterpret_cast< CScriptResource * >( residIn );
|
|
if ( pres == NULL )
|
|
{
|
|
scErr = (DWORD) THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
}
|
|
|
|
switch ( dwControlCodeIn )
|
|
{
|
|
case CLUSCTL_RESOURCE_UNKNOWN:
|
|
break;
|
|
|
|
case CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTY_FMTS:
|
|
scErr = TW32( ResUtilGetPropertyFormats(
|
|
GenScriptResourcePrivateProperties
|
|
, pvBufferOut
|
|
, dwBufferOutSizeIn
|
|
, pdwBytesReturnedOut
|
|
, &dwBytesRequired
|
|
) );
|
|
if ( scErr == ERROR_MORE_DATA )
|
|
{
|
|
*pdwBytesReturnedOut = dwBytesRequired;
|
|
}
|
|
break;
|
|
|
|
case CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES:
|
|
scErr = TW32( ResUtilGetAllProperties(
|
|
pres->GetRegistryParametersKey()
|
|
, GenScriptResourcePrivateProperties
|
|
, pvBufferOut
|
|
, dwBufferOutSizeIn
|
|
, pdwBytesReturnedOut
|
|
, &dwBytesRequired
|
|
) );
|
|
if ( scErr == ERROR_MORE_DATA )
|
|
{
|
|
*pdwBytesReturnedOut = dwBytesRequired;
|
|
}
|
|
break;
|
|
|
|
case CLUSCTL_RESOURCE_VALIDATE_PRIVATE_PROPERTIES:
|
|
scErr= TW32( ScriptValidateResourcePrivateProperties(
|
|
pres
|
|
, pvBufferIn
|
|
, dwBufferInSizeIn
|
|
, &propsCurrent
|
|
, &propsNew
|
|
) );
|
|
break;
|
|
|
|
case CLUSCTL_RESOURCE_SET_PRIVATE_PROPERTIES:
|
|
scErr= TW32( ScriptValidateResourcePrivateProperties(
|
|
pres
|
|
, pvBufferIn
|
|
, dwBufferInSizeIn
|
|
, &propsCurrent
|
|
, &propsNew
|
|
) );
|
|
if ( scErr != ERROR_SUCCESS )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
scErr = pres->SetPrivateProperties( &propsNew );
|
|
break;
|
|
|
|
case CLUSCTL_RESOURCE_SET_COMMON_PROPERTIES:
|
|
//
|
|
// Find the resource pending timeout in the property list.
|
|
//
|
|
scErr = ResUtilFindDwordProperty(
|
|
pvBufferIn
|
|
, dwBufferInSizeIn
|
|
, CLUSREG_NAME_RES_PENDING_TIMEOUT
|
|
, &dwPendingTimeout
|
|
);
|
|
if ( scErr == ERROR_SUCCESS )
|
|
{
|
|
//
|
|
// Pending timeout period was changed.
|
|
//
|
|
pres->SetResourcePendingTimeoutChanged( TRUE );
|
|
}
|
|
scErr = ERROR_INVALID_FUNCTION;
|
|
break;
|
|
|
|
default:
|
|
scErr = ERROR_INVALID_FUNCTION;
|
|
break;
|
|
} // switch: on control code
|
|
|
|
Cleanup:
|
|
|
|
RETURN( scErr );
|
|
|
|
} //*** ScriptResResourceControl
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DWORD
|
|
// ScriptResTypeControl(
|
|
// LPCWSTR ResourceTypeName,
|
|
// DWORD dwControlCodeIn,
|
|
// PVOID pvBufferIn,
|
|
// DWORD dwBufferInSizeIn,
|
|
// PVOID pvBufferOut,
|
|
// DWORD dwBufferOutSizeIn,
|
|
// LPDWORD pdwBytesReturnedOut
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
ScriptResTypeControl(
|
|
LPCWSTR ResourceTypeName,
|
|
DWORD dwControlCodeIn,
|
|
PVOID pvBufferIn,
|
|
DWORD dwBufferInSizeIn,
|
|
PVOID pvBufferOut,
|
|
DWORD dwBufferOutSizeIn,
|
|
LPDWORD pdwBytesReturnedOut
|
|
)
|
|
{
|
|
TraceFunc( "ScriptResTypeControl( ... )\n " );
|
|
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
DWORD dwBytesRequired;
|
|
|
|
*pdwBytesReturnedOut = 0;
|
|
|
|
switch ( dwControlCodeIn )
|
|
{
|
|
case CLUSCTL_RESOURCE_TYPE_UNKNOWN:
|
|
break;
|
|
|
|
case CLUSCTL_RESOURCE_TYPE_GET_PRIVATE_RESOURCE_PROPERTY_FMTS:
|
|
dwErr = ResUtilGetPropertyFormats( GenScriptResourcePrivateProperties,
|
|
pvBufferOut,
|
|
dwBufferOutSizeIn,
|
|
pdwBytesReturnedOut,
|
|
&dwBytesRequired );
|
|
if ( dwErr == ERROR_MORE_DATA ) {
|
|
*pdwBytesReturnedOut = dwBytesRequired;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
dwErr = ERROR_INVALID_FUNCTION;
|
|
break;
|
|
}
|
|
|
|
RETURN( dwErr );
|
|
|
|
} //*** ScriptResTypeControl( )
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DWORD
|
|
// ScriptValidateResourcePrivateProperties(
|
|
// CScriptResource * pres
|
|
// , PVOID pvBufferIn
|
|
// , DWORD dwBufferInSizeIn
|
|
// , PGENSCRIPT_PROPS pPropsCurrent
|
|
// , PGENSCRIPT_PROPS pPropsNew
|
|
// )
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
ScriptValidateResourcePrivateProperties(
|
|
CScriptResource * pres
|
|
, PVOID pvBufferIn
|
|
, DWORD dwBufferInSizeIn
|
|
, PGENSCRIPT_PROPS pPropsCurrent
|
|
, PGENSCRIPT_PROPS pPropsNew
|
|
)
|
|
{
|
|
DWORD scErr = ERROR_SUCCESS;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
LPWSTR pszNameOfPropInError;
|
|
LPWSTR pszFilePath = NULL;
|
|
|
|
//
|
|
// Check if there is input data.
|
|
//
|
|
if ( ( pvBufferIn == NULL ) || ( dwBufferInSizeIn < sizeof( DWORD ) ) )
|
|
{
|
|
scErr = ERROR_INVALID_DATA;
|
|
goto Cleanup;
|
|
} // if: no input buffer or input buffer not big enough to contain property list
|
|
|
|
//
|
|
// Retrieve the current set of private properties from the
|
|
// cluster database.
|
|
//
|
|
ZeroMemory( pPropsCurrent, sizeof( *pPropsCurrent ) );
|
|
scErr = TW32( ResUtilGetPropertiesToParameterBlock(
|
|
pres->GetRegistryParametersKey()
|
|
, GenScriptResourcePrivateProperties
|
|
, reinterpret_cast< LPBYTE >( pPropsCurrent )
|
|
, FALSE // CheckForRequiredProperties
|
|
, &pszNameOfPropInError
|
|
) );
|
|
if ( scErr != ERROR_SUCCESS )
|
|
{
|
|
(ClusResLogEvent)(
|
|
pres->GetResourceHandle()
|
|
, LOG_ERROR
|
|
, L"ValidatePrivateProperties: Unable to read the '%1!ws!' property. Error: %2!u! (%2!#08x!).\n"
|
|
, (pszNameOfPropInError == NULL ? L"" : pszNameOfPropInError)
|
|
, scErr
|
|
);
|
|
goto Cleanup;
|
|
} // if: error getting properties
|
|
|
|
ZeroMemory( pPropsNew, sizeof( *pPropsNew ) );
|
|
scErr = TW32( ResUtilDupParameterBlock(
|
|
reinterpret_cast< LPBYTE >( pPropsNew )
|
|
, reinterpret_cast< LPBYTE >( pPropsCurrent )
|
|
, GenScriptResourcePrivateProperties
|
|
) );
|
|
if ( scErr != ERROR_SUCCESS )
|
|
{
|
|
goto Cleanup;
|
|
} // if: error duplicating the parameter block
|
|
|
|
//
|
|
// Parse and validate the properties.
|
|
//
|
|
scErr = TW32( ResUtilVerifyPropertyTable(
|
|
GenScriptResourcePrivateProperties
|
|
, NULL
|
|
, TRUE // AllowUnknownProperties
|
|
, pvBufferIn
|
|
, dwBufferInSizeIn
|
|
, reinterpret_cast< LPBYTE >( pPropsNew )
|
|
) );
|
|
if ( scErr != ERROR_SUCCESS )
|
|
{
|
|
goto Cleanup;
|
|
} // if: error parsing the property table.
|
|
|
|
//
|
|
// If the new script file path is NULL: i.e. the case where /usedefault
|
|
// switch is used to set ScriptFilePath property using cluster.exe.
|
|
// Or if an empty string specified for the ScriptFilePath property.
|
|
//
|
|
if ( ( pPropsNew->pszScriptFilePath == NULL ) || ( *pPropsNew->pszScriptFilePath == L'\0' ) )
|
|
{
|
|
scErr = TW32( ERROR_INVALID_PARAMETER );
|
|
goto Cleanup;
|
|
} // if: the new ScriptFilePath is NULL, or it is an empty string.
|
|
|
|
//
|
|
// Expand the new script file path.
|
|
//
|
|
pszFilePath = ClRtlExpandEnvironmentStrings( pPropsNew->pszScriptFilePath );
|
|
if ( pszFilePath == NULL )
|
|
{
|
|
scErr = TW32( ERROR_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
} // if: ( pszFilePath == NULL )
|
|
|
|
//
|
|
// Open the script file.
|
|
//
|
|
hFile = CreateFile(
|
|
pszFilePath
|
|
, GENERIC_READ
|
|
, FILE_SHARE_READ
|
|
, NULL
|
|
, OPEN_EXISTING
|
|
, 0
|
|
, NULL
|
|
);
|
|
if ( hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
scErr = TW32( GetLastError() );
|
|
(ClusResLogEvent)(
|
|
pres->GetResourceHandle()
|
|
, LOG_ERROR
|
|
, L"Error opening script '%1!ws!'. SCODE: 0x%2!08x!\n"
|
|
, pPropsNew->pszScriptFilePath
|
|
, scErr
|
|
);
|
|
goto Cleanup;
|
|
} // if: failed to open
|
|
|
|
Cleanup:
|
|
|
|
LocalFree( pszFilePath );
|
|
if ( hFile != INVALID_HANDLE_VALUE )
|
|
{
|
|
CloseHandle( hFile );
|
|
} // if: hFile
|
|
|
|
return scErr;
|
|
|
|
} //*** ScriptValidateResourcePrivateProperties
|
|
|
|
//***********************************************************
|
|
//
|
|
// Define Function Table
|
|
//
|
|
//***********************************************************
|
|
|
|
CLRES_V1_FUNCTION_TABLE( GenScriptFunctionTable, // Name
|
|
CLRES_VERSION_V1_00, // Version
|
|
ScriptRes, // Prefix
|
|
NULL, // Arbitrate
|
|
NULL, // Release
|
|
ScriptResResourceControl, // ResControl
|
|
ScriptResTypeControl // ResTypeControl
|
|
);
|
|
|
|
} // extern "C"
|