2796 lines
70 KiB
C
2796 lines
70 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1997-2000 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
resprop.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Implements the management of properties.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Rod Gamache (rodga) 19-Mar-1997
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#define UNICODE 1
|
|||
|
#include "clusres.h"
|
|||
|
#include "clusrtl.h"
|
|||
|
#include "stdio.h"
|
|||
|
#include "stdlib.h"
|
|||
|
|
|||
|
//
|
|||
|
// Cluster Registry API function pointers
|
|||
|
//
|
|||
|
CLUSTER_REG_APIS
|
|||
|
ResUtilClusterRegApis = {
|
|||
|
(PFNCLRTLCREATEKEY) ClusterRegCreateKey,
|
|||
|
(PFNCLRTLOPENKEY) ClusterRegOpenKey,
|
|||
|
(PFNCLRTLCLOSEKEY) ClusterRegCloseKey,
|
|||
|
(PFNCLRTLSETVALUE) ClusterRegSetValue,
|
|||
|
(PFNCLRTLQUERYVALUE) ClusterRegQueryValue,
|
|||
|
(PFNCLRTLENUMVALUE) ClusterRegEnumValue,
|
|||
|
(PFNCLRTLDELETEVALUE) ClusterRegDeleteValue,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
NULL
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilEnumProperties(
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
OUT LPWSTR pszOutProperties,
|
|||
|
IN DWORD cbOutPropertiesSize,
|
|||
|
OUT LPDWORD pcbBytesReturned,
|
|||
|
OUT LPDWORD pcbRequired
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Enumerates the properties for a given object.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
pszOutProperties - Supplies the output buffer.
|
|||
|
|
|||
|
cbOutPropertiesSize - Supplies the size of the output buffer.
|
|||
|
|
|||
|
pcbBytesReturned - The number of bytes returned in pszOutProperties.
|
|||
|
|
|||
|
pcbRequired - The required number of bytes if pszOutProperties is too small.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS - Operation was successful.
|
|||
|
|
|||
|
ERROR_BAD_ARGUMENTS - An argument passed to the function was bad.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlEnumProperties( pPropertyTable,
|
|||
|
pszOutProperties,
|
|||
|
cbOutPropertiesSize,
|
|||
|
pcbBytesReturned,
|
|||
|
pcbRequired ) );
|
|||
|
|
|||
|
|
|||
|
} // ResUtilEnumProperties
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilEnumPrivateProperties(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
OUT LPWSTR pszOutProperties,
|
|||
|
IN DWORD cbOutPropertiesSize,
|
|||
|
OUT LPDWORD pcbBytesReturned,
|
|||
|
OUT LPDWORD pcbRequired
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Enumerates the properties for a given object.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - Supplies the handle to the key in the cluster database
|
|||
|
to read from.
|
|||
|
|
|||
|
pszOutProperties - Supplies the output buffer.
|
|||
|
|
|||
|
cbOutPropertiesSize - Supplies the size of the output buffer.
|
|||
|
|
|||
|
pcbBytesReturned - The number of bytes returned in pszOutProperties.
|
|||
|
|
|||
|
pcbRequired - The required number of bytes if pszOutProperties is too small.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS - Operation was successful.
|
|||
|
|
|||
|
ERROR_BAD_ARGUMENTS - An argument passed to the function was bad.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlEnumPrivateProperties( hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pszOutProperties,
|
|||
|
cbOutPropertiesSize,
|
|||
|
pcbBytesReturned,
|
|||
|
pcbRequired ) );
|
|||
|
|
|||
|
|
|||
|
} // ResUtilEnumProperties
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilGetProperties(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
OUT LPWSTR pPropertyList,
|
|||
|
IN DWORD cbPropertyListSize,
|
|||
|
OUT LPDWORD pcbBytesReturned,
|
|||
|
OUT LPDWORD pcbRequired
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Gets the properties for a given object.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - Supplies the handle to the key in the cluster database
|
|||
|
to read from.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
pPropertyList - Supplies the output buffer.
|
|||
|
|
|||
|
cbPropertyListSize - Supplies the size of the output buffer.
|
|||
|
|
|||
|
pcbBytesReturned - The number of bytes returned in pPropertyList.
|
|||
|
|
|||
|
pcbRequired - The required number of bytes if pPropertyList is too small.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS - Operation was successful.
|
|||
|
|
|||
|
ERROR_BAD_ARGUMENTS - An argument passed to the function was bad.
|
|||
|
|
|||
|
ERROR_NOT_ENOUGH_MEMORY - Error allocating memory.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlGetProperties( hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTable,
|
|||
|
pPropertyList,
|
|||
|
cbPropertyListSize,
|
|||
|
pcbBytesReturned,
|
|||
|
pcbRequired ) );
|
|||
|
|
|||
|
} // ResUtilGetProperties
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilGetAllProperties(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
OUT PVOID pPropertyList,
|
|||
|
IN DWORD cbPropertyListSize,
|
|||
|
OUT LPDWORD pcbBytesReturned,
|
|||
|
OUT LPDWORD pcbRequired
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Gets the default and 'unknown' properties for a given object.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - Supplies the handle to the key in the cluster database
|
|||
|
to read from.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
pPropertyList - Supplies the output buffer.
|
|||
|
|
|||
|
cbPropertyListSize - Supplies the size of the output buffer.
|
|||
|
|
|||
|
pcbBytesReturned - The number of bytes returned in pPropertyList.
|
|||
|
|
|||
|
pcbRequired - The required number of bytes if pPropertyList is too small.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS - Operation was successful.
|
|||
|
|
|||
|
ERROR_BAD_ARGUMENTS - An argument passed to the function was bad.
|
|||
|
|
|||
|
ERROR_NOT_ENOUGH_MEMORY - Error allocating memory.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlGetAllProperties( hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTable,
|
|||
|
pPropertyList,
|
|||
|
cbPropertyListSize,
|
|||
|
pcbBytesReturned,
|
|||
|
pcbRequired ) );
|
|||
|
|
|||
|
} // ResUtilGetAllProperties
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilGetPropertiesToParameterBlock(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
OUT LPBYTE pOutParams,
|
|||
|
IN BOOL bCheckForRequiredProperties,
|
|||
|
OUT OPTIONAL LPWSTR * pszNameOfPropInError
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Gets the default and 'unknown' properties for a given object and stores
|
|||
|
them in a parameter block.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - Supplies the handle to the key in the cluster database
|
|||
|
to read from.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
pOutParams - Supplies the output parameter block.
|
|||
|
|
|||
|
bCheckForRequiredProperties - Boolean value specifying whether missing
|
|||
|
required properties should cause an error.
|
|||
|
|
|||
|
pszNameOfPropInError - String pointer in which to return the name of the
|
|||
|
property in error (optional).
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS - Operation was successful.
|
|||
|
|
|||
|
ERROR_BAD_ARGUMENTS - An argument passed to the function was bad.
|
|||
|
|
|||
|
ERROR_NOT_ENOUGH_MEMORY - Error allocating memory.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD status;
|
|||
|
|
|||
|
status = ClRtlGetPropertiesToParameterBlock( hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTable,
|
|||
|
pOutParams,
|
|||
|
bCheckForRequiredProperties,
|
|||
|
pszNameOfPropInError );
|
|||
|
return(status);
|
|||
|
|
|||
|
} // ResUtilGetPropertiesToParameterBlock
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilPropertyListFromParameterBlock(
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
OUT PVOID pOutPropertyList,
|
|||
|
IN OUT LPDWORD pcbOutPropertyListSize,
|
|||
|
IN const LPBYTE pInParams,
|
|||
|
OUT LPDWORD pcbBytesReturned,
|
|||
|
OUT LPDWORD pcbRequired
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Constructs a property list from a parameter block.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
pOutPropertyList - Supplies the output buffer.
|
|||
|
|
|||
|
pcbOutPropertyListSize - Supplies the size of the output buffer.
|
|||
|
|
|||
|
pInParams - Supplies the input parameter block.
|
|||
|
|
|||
|
pcbBytesReturned - The number of bytes returned in pOutPropertyList.
|
|||
|
|
|||
|
pcbRequired - The required number of bytes if pOutPropertyList is too small.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS - Operation was successful.
|
|||
|
|
|||
|
ERROR_BAD_ARGUMENTS - An argument passed to the function was bad.
|
|||
|
|
|||
|
ERROR_NOT_ENOUGH_MEMORY - Error allocating memory.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD status;
|
|||
|
|
|||
|
status = ClRtlPropertyListFromParameterBlock( pPropertyTable,
|
|||
|
pOutPropertyList,
|
|||
|
pcbOutPropertyListSize,
|
|||
|
pInParams,
|
|||
|
pcbBytesReturned,
|
|||
|
pcbRequired );
|
|||
|
return(status);
|
|||
|
|
|||
|
} // ResUtilPropertyListFromParameterBlock
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilGetPrivateProperties(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
OUT PVOID pOutPropertyList,
|
|||
|
IN DWORD cbOutPropertyListSize,
|
|||
|
OUT LPDWORD pcbBytesReturned,
|
|||
|
OUT LPDWORD pcbRequired
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Gets the private properties for a given object.
|
|||
|
|
|||
|
This routine assumes that it uses the Cluster Registry API's for
|
|||
|
access to registry info.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - Supplies the handle to the key in the cluster database
|
|||
|
to read from.
|
|||
|
|
|||
|
pOutPropertyList - Supplies the output buffer.
|
|||
|
|
|||
|
cbOutPropertyListSize - Supplies the size of the output buffer.
|
|||
|
|
|||
|
pcbBytesReturned - The number of bytes returned in pOutPropertyList.
|
|||
|
|
|||
|
pcbRequired - The required number of bytes if pOutPropertyList is too small.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS - Operation was successful.
|
|||
|
|
|||
|
ERROR_NOT_ENOUGH_MEMORY - Error allocating memory.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlGetPrivateProperties( hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pOutPropertyList,
|
|||
|
cbOutPropertyListSize,
|
|||
|
pcbBytesReturned,
|
|||
|
pcbRequired ) );
|
|||
|
|
|||
|
} // ResUtilGetPrivateProperties
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilGetPropertySize(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTableItem,
|
|||
|
IN OUT LPDWORD pcbOutPropertyListSize,
|
|||
|
IN OUT LPDWORD pnPropertyCount
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get the total number of bytes required for this property.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - Supplies the handle to the key in the cluster database
|
|||
|
to read from.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlGetPropertySize( hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTableItem,
|
|||
|
pcbOutPropertyListSize,
|
|||
|
pnPropertyCount ) );
|
|||
|
|
|||
|
} // ResUtilGetPropertySize
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilGetProperty(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTableItem,
|
|||
|
OUT PVOID * pOutPropertyItem,
|
|||
|
IN OUT LPDWORD pcbOutPropertyItemSize
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
The buffer size has already been determined to be large enough to hold
|
|||
|
the return data.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlGetProperty( hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTableItem,
|
|||
|
pOutPropertyItem,
|
|||
|
pcbOutPropertyItemSize ) );
|
|||
|
|
|||
|
} // ResUtilGetProperty
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilVerifyPropertyTable(
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
IN PVOID Reserved,
|
|||
|
IN BOOL bAllowUnknownProperties,
|
|||
|
IN const PVOID pInPropertyList,
|
|||
|
IN DWORD cbInPropertyListSize,
|
|||
|
OUT OPTIONAL PBYTE pOutParams
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Validate a property list.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
Reserved - Possible pointer to a future ReadOnly property table.
|
|||
|
|
|||
|
bAllowUnknownProperties - TRUE if unknown properties should be accepted.
|
|||
|
|
|||
|
pInPropertyList - The input buffer.
|
|||
|
|
|||
|
cbInPropertyListSize - The input buffer size.
|
|||
|
|
|||
|
pOutParams - Parameters block in which to return the data.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 Error on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlVerifyPropertyTable( pPropertyTable,
|
|||
|
Reserved,
|
|||
|
bAllowUnknownProperties,
|
|||
|
pInPropertyList,
|
|||
|
cbInPropertyListSize,
|
|||
|
pOutParams ) );
|
|||
|
|
|||
|
} // ResUtilVerifyPropertyTable
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilSetPropertyTable(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
IN PVOID Reserved,
|
|||
|
IN BOOL bAllowUnknownProperties,
|
|||
|
IN const PVOID pInPropertyList,
|
|||
|
IN DWORD cbInPropertyListSize,
|
|||
|
OUT OPTIONAL PBYTE pOutParams
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - The opened registry key for this object's parameters.
|
|||
|
If not specified, the property list will only be validated.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
Reserved - Possible pointer to a future ReadOnly property table.
|
|||
|
|
|||
|
bAllowUnknownProperties - TRUE if unknown properties should be accepted.
|
|||
|
|
|||
|
pInPropertyList - The input buffer.
|
|||
|
|
|||
|
cbInPropertyListSize - The input buffer size.
|
|||
|
|
|||
|
pOutParams - Parameters block in which to return the data.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 Error on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlSetPropertyTable( NULL,
|
|||
|
hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTable,
|
|||
|
Reserved,
|
|||
|
bAllowUnknownProperties,
|
|||
|
pInPropertyList,
|
|||
|
cbInPropertyListSize,
|
|||
|
FALSE, // bForceWrite
|
|||
|
pOutParams ) );
|
|||
|
|
|||
|
} // ResUtilSetPropertyTable
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilSetPropertyTableEx(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
IN PVOID Reserved,
|
|||
|
IN BOOL bAllowUnknownProperties,
|
|||
|
IN const PVOID pInPropertyList,
|
|||
|
IN DWORD cbInPropertyListSize,
|
|||
|
IN BOOL bForceWrite,
|
|||
|
OUT OPTIONAL PBYTE pOutParams
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - The opened registry key for this object's parameters.
|
|||
|
If not specified, the property list will only be validated.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
Reserved - Possible pointer to a future ReadOnly property table.
|
|||
|
|
|||
|
bAllowUnknownProperties - TRUE if unknown properties should be accepted.
|
|||
|
|
|||
|
pInPropertyList - The input buffer.
|
|||
|
|
|||
|
cbInPropertyListSize - The input buffer size.
|
|||
|
|
|||
|
bForceWrite - TRUE = always write the properties to the cluster database.
|
|||
|
FALSE = only write the properties if they changed.
|
|||
|
|
|||
|
pOutParams - Parameters block in which to return the data.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 Error on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlSetPropertyTable( NULL,
|
|||
|
hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTable,
|
|||
|
Reserved,
|
|||
|
bAllowUnknownProperties,
|
|||
|
pInPropertyList,
|
|||
|
cbInPropertyListSize,
|
|||
|
bForceWrite,
|
|||
|
pOutParams ) );
|
|||
|
|
|||
|
} // ResUtilSetPropertyTableEx
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilSetPropertyParameterBlock(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
IN PVOID Reserved,
|
|||
|
IN const LPBYTE pInParams,
|
|||
|
IN const PVOID pInPropertyList,
|
|||
|
IN DWORD cbInPropertyListSize,
|
|||
|
OUT OPTIONAL PBYTE pOutParams
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - The opened registry key for this object's parameters.
|
|||
|
If not specified, the property list will only be validated.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
pInParams - Parameters block to set.
|
|||
|
|
|||
|
pInPropertyList - Full Property list.
|
|||
|
|
|||
|
cbInPropertyListSize - Size of the input full property list.
|
|||
|
|
|||
|
pOutParams - Parameters block to copy pInParams to.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 Error on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlSetPropertyParameterBlock( NULL, // IN HANDLE hXsaction,
|
|||
|
hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTable,
|
|||
|
Reserved,
|
|||
|
pInParams,
|
|||
|
pInPropertyList,
|
|||
|
cbInPropertyListSize,
|
|||
|
FALSE, // bForceWrite
|
|||
|
pOutParams ) );
|
|||
|
|
|||
|
} // ResUtilSetPropertyParameterBlock
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilSetPropertyParameterBlockEx(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
IN PVOID Reserved,
|
|||
|
IN const LPBYTE pInParams,
|
|||
|
IN const PVOID pInPropertyList,
|
|||
|
IN DWORD cbInPropertyListSize,
|
|||
|
IN BOOL bForceWrite,
|
|||
|
OUT OPTIONAL PBYTE pOutParams
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - The opened registry key for this object's parameters.
|
|||
|
If not specified, the property list will only be validated.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
pInParams - Parameters block to set.
|
|||
|
|
|||
|
pInPropertyList - Full Property list.
|
|||
|
|
|||
|
cbInPropertyListSize - Size of the input full property list.
|
|||
|
|
|||
|
bForceWrite - TRUE = always write the properties to the cluster database.
|
|||
|
FALSE = only write the properties if they changed.
|
|||
|
|
|||
|
pOutParams - Parameters block to copy pInParams to.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 Error on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlSetPropertyParameterBlock( NULL, // IN HANDLE hXsaction,
|
|||
|
hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTable,
|
|||
|
Reserved,
|
|||
|
pInParams,
|
|||
|
pInPropertyList,
|
|||
|
cbInPropertyListSize,
|
|||
|
bForceWrite,
|
|||
|
pOutParams ) );
|
|||
|
|
|||
|
} // ResUtilSetPropertyParameterBlockEx
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilSetUnknownProperties(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
IN const PVOID pInPropertyList,
|
|||
|
IN DWORD cbInPropertyListSize
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Set items that are not in the property table list.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - The opened registry key for this object's parameters.
|
|||
|
If not specified, the property list will only be validated.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
pInPropertyList - Full Property list.
|
|||
|
|
|||
|
cbInPropertyListSize - Size of the input full property list.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 Error on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlpSetNonPropertyTable( NULL, // IN HANDLE hXsaction
|
|||
|
hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTable,
|
|||
|
NULL,
|
|||
|
pInPropertyList,
|
|||
|
cbInPropertyListSize ) );
|
|||
|
|
|||
|
} // ResUtilSetUnknownProperties
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilVerifyPrivatePropertyList(
|
|||
|
IN const PVOID pInPropertyList,
|
|||
|
IN DWORD cbInPropertyListSize
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Validate a private property list.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pInPropertyList - The input buffer.
|
|||
|
|
|||
|
cbInPropertyListSize - The input buffer size.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 Error on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlVerifyPrivatePropertyList( pInPropertyList, cbInPropertyListSize ) );
|
|||
|
|
|||
|
} // ResUtilVerifyPrivatePropertyList
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilSetPrivatePropertyList(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PVOID pInPropertyList,
|
|||
|
IN DWORD cbInPropertyListSize
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - The opened registry key for this resource's parameters.
|
|||
|
If not specified, the property list will only be validated.
|
|||
|
|
|||
|
pInPropertyList - The input buffer.
|
|||
|
|
|||
|
cbInPropertyListSize - The input buffer size.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 Error on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlSetPrivatePropertyList( NULL, // IN HANDLE hXsaction
|
|||
|
hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pInPropertyList,
|
|||
|
cbInPropertyListSize ) );
|
|||
|
|
|||
|
} // ResUtilSetPrivatePropertyList
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilAddUnknownProperties(
|
|||
|
IN HKEY hkeyClusterKey,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
IN OUT PVOID pOutPropertyList,
|
|||
|
IN DWORD cbOutPropertyListSize,
|
|||
|
IN OUT LPDWORD pcbBytesReturned,
|
|||
|
IN OUT LPDWORD pcbRequired
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Adds the unknown properties for a given object to the end of a property
|
|||
|
list.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hkeyClusterKey - Supplies the handle to the key in the cluster database
|
|||
|
to read from.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
pOutPropertyList - Supplies the output buffer.
|
|||
|
|
|||
|
cbOutPropertyListSize - Supplies the size of the output buffer.
|
|||
|
|
|||
|
pcbBytesReturned - On input, contains the number of bytes in use in the
|
|||
|
output buffer. On output, contains the total number of bytes in
|
|||
|
pOutPropertyList.
|
|||
|
|
|||
|
pcbRequired - The required number of bytes if pOutPropertyList is too small.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS - Operation was successful.
|
|||
|
|
|||
|
ERROR_NOT_ENOUGH_MEMORY - Error allocating memory.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD status;
|
|||
|
|
|||
|
status = ClRtlAddUnknownProperties( hkeyClusterKey,
|
|||
|
&ResUtilClusterRegApis,
|
|||
|
pPropertyTable,
|
|||
|
pOutPropertyList,
|
|||
|
cbOutPropertyListSize,
|
|||
|
pcbBytesReturned,
|
|||
|
pcbRequired );
|
|||
|
|
|||
|
return(status);
|
|||
|
|
|||
|
} // ResUtilAddUnknownProperties
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//***************************************************************************
|
|||
|
//
|
|||
|
// Utility routines to grovel though a Control Function item list buffer
|
|||
|
//
|
|||
|
//***************************************************************************
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilFindSzProperty(
|
|||
|
IN PVOID pPropertyList,
|
|||
|
IN DWORD cbPropertyListSize,
|
|||
|
IN LPCWSTR pszPropertyName,
|
|||
|
OUT LPWSTR * pszPropertyValue
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Finds the specified string property in the Property List buffer pointed at
|
|||
|
by pPropertyList.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyList - a property list.
|
|||
|
|
|||
|
cbPropertyListSize - the size in bytes of the data in pPropertyList.
|
|||
|
|
|||
|
pszPropertyName - the property name to look for in the buffer.
|
|||
|
|
|||
|
pszPropertyValue - the matching string value found.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlFindSzProperty( pPropertyList,
|
|||
|
cbPropertyListSize,
|
|||
|
pszPropertyName,
|
|||
|
pszPropertyValue ) );
|
|||
|
|
|||
|
} // ResUtilFindSzProperty
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilFindExpandSzProperty(
|
|||
|
IN PVOID pPropertyList,
|
|||
|
IN DWORD cbPropertyListSize,
|
|||
|
IN LPCWSTR pszPropertyName,
|
|||
|
OUT LPWSTR * pszPropertyValue
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Finds the specified EXPAND_SZ string property in the Property List buffer
|
|||
|
pointed at by pPropertyList.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyList - a property list.
|
|||
|
|
|||
|
cbPropertyListSize - the size in bytes of the data in pPropertyList.
|
|||
|
|
|||
|
pszPropertyName - the property name to look for in the buffer.
|
|||
|
|
|||
|
pszPropertyValue - the matching string value found.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlFindExpandSzProperty(
|
|||
|
pPropertyList,
|
|||
|
cbPropertyListSize,
|
|||
|
pszPropertyName,
|
|||
|
pszPropertyValue ) );
|
|||
|
|
|||
|
} // ResUtilFindExpandSzProperty
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilFindExpandedSzProperty(
|
|||
|
IN PVOID pPropertyList,
|
|||
|
IN DWORD cbPropertyListSize,
|
|||
|
IN LPCWSTR pszPropertyName,
|
|||
|
OUT LPWSTR * pszPropertyValue
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Finds the specified string property in the Property List buffer pointed at
|
|||
|
by pPropertyList and returns it's expanded value.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyList - a property list.
|
|||
|
|
|||
|
cbPropertyListSize - the size in bytes of the data in pPropertyList.
|
|||
|
|
|||
|
pszPropertyName - the property name to look for in the buffer.
|
|||
|
|
|||
|
pszPropertyValue - the matching string value found.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlFindExpandedSzProperty(
|
|||
|
pPropertyList,
|
|||
|
cbPropertyListSize,
|
|||
|
pszPropertyName,
|
|||
|
pszPropertyValue ) );
|
|||
|
|
|||
|
} // ResUtilFindExpandedSzProperty
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilFindDwordProperty(
|
|||
|
IN PVOID pPropertyList,
|
|||
|
IN DWORD cbPropertyListSize,
|
|||
|
IN LPCWSTR pszPropertyName,
|
|||
|
OUT LPDWORD pdwPropertyValue
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Finds the specified DWORD property in the Property List buffer pointed at
|
|||
|
by pPropertyList.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyList - a property list.
|
|||
|
|
|||
|
cbPropertyListSize - the size in bytes of the data in pPropertyList.
|
|||
|
|
|||
|
pszPropertyName - the property name to look for in the buffer.
|
|||
|
|
|||
|
pdwPropertyValue - the matching DWORD value found.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlFindDwordProperty( pPropertyList,
|
|||
|
cbPropertyListSize,
|
|||
|
pszPropertyName,
|
|||
|
pdwPropertyValue ) );
|
|||
|
|
|||
|
} // ResUtilFindDwordProperty
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilFindLongProperty(
|
|||
|
IN PVOID pPropertyList,
|
|||
|
IN DWORD cbPropertyListSize,
|
|||
|
IN LPCWSTR pszPropertyName,
|
|||
|
OUT LPLONG plPropertyValue
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Finds the specified string in the Value List buffer pointed at by Buffer.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyList - a property list.
|
|||
|
|
|||
|
cbPropertyListSize - the size in bytes of the data in pPropertyList.
|
|||
|
|
|||
|
pszPropertyName - the property name to look for in the buffer.
|
|||
|
|
|||
|
plPropertyValue - the matching long value found.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlFindLongProperty( pPropertyList,
|
|||
|
cbPropertyListSize,
|
|||
|
pszPropertyName,
|
|||
|
plPropertyValue ) );
|
|||
|
} // ResUtilFindLongProperty
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilFindBinaryProperty(
|
|||
|
IN PVOID pPropertyList,
|
|||
|
IN DWORD cbPropertyListSize,
|
|||
|
IN LPCWSTR pszPropertyName,
|
|||
|
OUT LPBYTE * pbPropertyValue,
|
|||
|
OUT LPDWORD pcbPropertyValueSize
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Finds the specified binary property in the Property List buffer pointed at
|
|||
|
by pPropertyList.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyList - a property list.
|
|||
|
|
|||
|
cbPropertyListSize - the size in bytes of the data in pPropertyList.
|
|||
|
|
|||
|
pszPropertyName - the property name to look for in the buffer.
|
|||
|
|
|||
|
pbPropertyValue - the matching binary value found.
|
|||
|
|
|||
|
pcbPropertyValueSize - the length of the matching binary value found.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlFindBinaryProperty( pPropertyList,
|
|||
|
cbPropertyListSize,
|
|||
|
pszPropertyName,
|
|||
|
pbPropertyValue,
|
|||
|
pcbPropertyValueSize ) );
|
|||
|
|
|||
|
} // ResUtilFindBinaryProperty
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilFindMultiSzProperty(
|
|||
|
IN PVOID pPropertyList,
|
|||
|
IN DWORD cbPropertyListSize,
|
|||
|
IN LPCWSTR pszPropertyName,
|
|||
|
OUT LPWSTR * pszPropertyValue,
|
|||
|
OUT LPDWORD pcbPropertyValueSize
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Finds the specified multiple string property in the Proprety List buffer
|
|||
|
pointed at by pPropertyList.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pPropertyList - a property list.
|
|||
|
|
|||
|
cbPropertyListSize - the size in bytes of the data in pPropertyList.
|
|||
|
|
|||
|
pszPropertyName - the property name to look for in the buffer.
|
|||
|
|
|||
|
pszPropertyValue - the matching multiple string value found.
|
|||
|
|
|||
|
pcbPropertyValueSize - the length of the matching multiple string value found.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return( ClRtlFindMultiSzProperty( pPropertyList,
|
|||
|
cbPropertyListSize,
|
|||
|
pszPropertyName,
|
|||
|
pszPropertyValue,
|
|||
|
pcbPropertyValueSize ) );
|
|||
|
|
|||
|
} // ResUtilFindMultiSzProperty
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilDupParameterBlock(
|
|||
|
OUT LPBYTE pOutParams,
|
|||
|
IN const LPBYTE pInParams,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Deallocates any buffers allocated for a parameter block that are
|
|||
|
different than the buffers used for the input parameter block.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pOutParams - Parameter block to return.
|
|||
|
|
|||
|
pInParams - Reference parameter block.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS - Parameter block duplicated successfully.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD status;
|
|||
|
|
|||
|
status = ClRtlDupParameterBlock( pOutParams, pInParams, pPropertyTable );
|
|||
|
|
|||
|
return(status);
|
|||
|
|
|||
|
} // ResUtilDupParameterBlock
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
WINAPI
|
|||
|
ResUtilFreeParameterBlock(
|
|||
|
IN OUT LPBYTE pOutParams,
|
|||
|
IN const LPBYTE pInParams,
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Deallocates any buffers allocated for a parameter block that are
|
|||
|
different than the buffers used for the input parameter block.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pOutParams - Parameter block to free.
|
|||
|
|
|||
|
pInParams - Reference parameter block.
|
|||
|
|
|||
|
pPropertyTable - Pointer to the property table to process.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ClRtlFreeParameterBlock( pOutParams, pInParams, pPropertyTable );
|
|||
|
|
|||
|
} // ResUtilFreeParameterBlock
|
|||
|
|
|||
|
|
|||
|
#define __INITIAL_NAME_LENGTH 256
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
ResUtilResourceTypesEqual(
|
|||
|
IN LPCWSTR lpszResourceTypeName,
|
|||
|
IN HRESOURCE hResource
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
Checks to see if the resource names type matches
|
|||
|
|
|||
|
Arguments:
|
|||
|
lpszResourceTypeName - The type of resource to check for
|
|||
|
|
|||
|
hResource - A handle to the resource to check
|
|||
|
|
|||
|
Return Value:
|
|||
|
TRUE - the resource type matches
|
|||
|
FALSE - the resource types do not match
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BOOL bIsEqual = FALSE;
|
|||
|
DWORD dwError;
|
|||
|
WCHAR szName[ __INITIAL_NAME_LENGTH ];
|
|||
|
LPWSTR pszName = szName;
|
|||
|
DWORD cbNameBufSize = __INITIAL_NAME_LENGTH * sizeof( szName[ 0 ] );
|
|||
|
DWORD cbRetSize;
|
|||
|
|
|||
|
do {
|
|||
|
// Get the resource type name
|
|||
|
dwError = ClusterResourceControl(
|
|||
|
hResource, //Handle to the resource
|
|||
|
NULL, //Don't care about node
|
|||
|
CLUSCTL_RESOURCE_GET_RESOURCE_TYPE, //Get the type
|
|||
|
0, // &InBuffer
|
|||
|
0, // nInBufferSize,
|
|||
|
pszName, // &OutBuffer
|
|||
|
cbNameBufSize, // nOutBufferSize,
|
|||
|
&cbRetSize ); // returned size
|
|||
|
|
|||
|
if ( dwError == ERROR_MORE_DATA ) {
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cbNameBufSize = cbRetSize + sizeof( WCHAR );
|
|||
|
pszName = LocalAlloc( LMEM_FIXED, cbNameBufSize );
|
|||
|
if ( pszName == NULL ) {
|
|||
|
break;
|
|||
|
} // if: error allocating buffer
|
|||
|
dwError = ClusterResourceControl(
|
|||
|
hResource, //Handle to the resource
|
|||
|
NULL, //Don't care about node
|
|||
|
CLUSCTL_RESOURCE_GET_RESOURCE_TYPE, //Get the type
|
|||
|
0, // &InBuffer
|
|||
|
0, // nInBufferSize,
|
|||
|
pszName, // &OutBuffer
|
|||
|
cbNameBufSize, // nOutBufferSize,
|
|||
|
&cbRetSize ); // returned size
|
|||
|
} // if: name buffer too small
|
|||
|
if ( dwError != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// See if it's like US
|
|||
|
if ( lstrcmpiW( lpszResourceTypeName, pszName ) == 0 ) {
|
|||
|
bIsEqual = TRUE;
|
|||
|
}
|
|||
|
} while ( 0 );
|
|||
|
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
} // if: we allocated the output name buffer
|
|||
|
|
|||
|
return bIsEqual;
|
|||
|
|
|||
|
} //*** ResUtilResourceTypesEqual()
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
ResUtilResourcesEqual(
|
|||
|
IN HRESOURCE hSelf,
|
|||
|
IN HRESOURCE hResource
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
Check to See if the resources are the same
|
|||
|
|
|||
|
Arguments:
|
|||
|
IN hSelf - a handle to the callee, or NULL to indicate not equal.
|
|||
|
|
|||
|
IN hResource - a handle to the resource to compare
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE - Resource are equal
|
|||
|
FALSE - otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BOOL bIsEqual = FALSE;
|
|||
|
DWORD dwError;
|
|||
|
WCHAR szSelfName[ __INITIAL_NAME_LENGTH ];
|
|||
|
WCHAR szResName[ __INITIAL_NAME_LENGTH ];
|
|||
|
LPWSTR pszSelfName = szSelfName;
|
|||
|
LPWSTR pszResName = szResName;
|
|||
|
DWORD cbSelfNameBufSize = __INITIAL_NAME_LENGTH * sizeof( szSelfName[ 0 ] );
|
|||
|
DWORD cbResNameBufSize = __INITIAL_NAME_LENGTH * sizeof( szResName[ 0 ] );
|
|||
|
DWORD cbRetSize;
|
|||
|
|
|||
|
do {
|
|||
|
if ( ( hSelf == NULL ) || ( hResource == NULL ) ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// Get the resource type name
|
|||
|
dwError = ClusterResourceControl(
|
|||
|
hSelf, //Handle to the resource
|
|||
|
NULL, //Don't care about node
|
|||
|
CLUSCTL_RESOURCE_GET_NAME, //Get the name
|
|||
|
0, // &InBuffer
|
|||
|
0, // nInBufferSize,
|
|||
|
pszSelfName, // &OutBuffer
|
|||
|
cbSelfNameBufSize, // OutBufferSize,
|
|||
|
&cbRetSize ); // returned size
|
|||
|
|
|||
|
if ( dwError == ERROR_MORE_DATA ) {
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cbSelfNameBufSize = cbRetSize + sizeof( WCHAR );
|
|||
|
pszSelfName = LocalAlloc( LMEM_FIXED, cbSelfNameBufSize );
|
|||
|
if ( pszSelfName == NULL ) {
|
|||
|
break;
|
|||
|
} // if: error allocating buffer
|
|||
|
dwError = ClusterResourceControl(
|
|||
|
hSelf, //Handle to the resource
|
|||
|
NULL, //Don't care about node
|
|||
|
CLUSCTL_RESOURCE_GET_NAME, //Get the name
|
|||
|
0, // &InBuffer
|
|||
|
0, // nInBufferSize,
|
|||
|
pszSelfName, // &OutBuffer
|
|||
|
cbSelfNameBufSize, // OutBufferSize,
|
|||
|
&cbRetSize ); // returned size
|
|||
|
}
|
|||
|
if ( dwError != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// Get the resource type name
|
|||
|
dwError = ClusterResourceControl(
|
|||
|
hResource, //Handle to the resource
|
|||
|
NULL, //Don't care about node
|
|||
|
CLUSCTL_RESOURCE_GET_NAME, //Get the name
|
|||
|
0, // &InBuffer
|
|||
|
0, // nInBufferSize,
|
|||
|
pszResName, // &OutBuffer
|
|||
|
cbResNameBufSize, // OutBufferSize,
|
|||
|
&cbRetSize ); // returned size
|
|||
|
|
|||
|
if ( dwError == ERROR_MORE_DATA ) {
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cbResNameBufSize = cbRetSize + sizeof( WCHAR );
|
|||
|
pszResName = LocalAlloc( LMEM_FIXED, cbResNameBufSize );
|
|||
|
if ( pszResName == NULL ) {
|
|||
|
break;
|
|||
|
} // if: error allocating buffer
|
|||
|
dwError = ClusterResourceControl(
|
|||
|
hResource, //Handle to the resource
|
|||
|
NULL, //Don't care about node
|
|||
|
CLUSCTL_RESOURCE_GET_NAME, //Get the name
|
|||
|
0, // &InBuffer
|
|||
|
0, // nInBufferSize,
|
|||
|
pszResName, // &OutBuffer
|
|||
|
cbResNameBufSize, // OutBufferSize,
|
|||
|
&cbRetSize ); // returned size
|
|||
|
}
|
|||
|
if ( dwError != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// See if were looking in a mirror
|
|||
|
if ( lstrcmpiW( pszResName, pszSelfName ) == 0 ) {
|
|||
|
bIsEqual = TRUE;
|
|||
|
}
|
|||
|
} while ( 0 );
|
|||
|
|
|||
|
if ( pszSelfName != szSelfName ) {
|
|||
|
LocalFree( pszSelfName );
|
|||
|
}
|
|||
|
if ( pszResName != szResName ) {
|
|||
|
LocalFree( pszResName );
|
|||
|
}
|
|||
|
|
|||
|
return bIsEqual;
|
|||
|
|
|||
|
} //*** ResUtilResourcesEqual()
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
WINAPI
|
|||
|
ResUtilIsResourceClassEqual(
|
|||
|
IN PCLUS_RESOURCE_CLASS_INFO prci,
|
|||
|
IN HRESOURCE hResource
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
Checks to see if the resource names type matches
|
|||
|
|
|||
|
Arguments:
|
|||
|
prci - The resource class info to check for.
|
|||
|
|
|||
|
hResource - A handle to the resource to check.
|
|||
|
|
|||
|
Return Value:
|
|||
|
TRUE - the resource type matches
|
|||
|
FALSE - the resource types do not match
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BOOL bIsEqual = FALSE;
|
|||
|
DWORD dwError;
|
|||
|
DWORD cbRetSize;
|
|||
|
CLUS_RESOURCE_CLASS_INFO rci;
|
|||
|
|
|||
|
do {
|
|||
|
// Get the resource class info
|
|||
|
dwError = ClusterResourceControl(
|
|||
|
hResource, // Handle to the resource
|
|||
|
NULL, // Don't care about node
|
|||
|
CLUSCTL_RESOURCE_GET_CLASS_INFO, // Get the class info
|
|||
|
0, // &InBuffer
|
|||
|
0, // nInBufferSize,
|
|||
|
&rci, // &OutBuffer
|
|||
|
sizeof( rci ), // nOutBufferSize,
|
|||
|
&cbRetSize ); // returned size
|
|||
|
|
|||
|
if ( dwError != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// See if it's like US
|
|||
|
if ( rci.rc == prci->rc ) {
|
|||
|
bIsEqual = TRUE;
|
|||
|
}
|
|||
|
} while ( 0 );
|
|||
|
|
|||
|
return bIsEqual;
|
|||
|
|
|||
|
} //*** ResUtilIsResourceClassEqual()
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilEnumResources(
|
|||
|
IN HRESOURCE hSelf,
|
|||
|
IN LPCWSTR lpszResTypeName,
|
|||
|
IN LPRESOURCE_CALLBACK pResCallBack,
|
|||
|
IN PVOID pParameter
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This is a generic resource walking routine. It enumerates all resources in
|
|||
|
the cluster and invokes the callback function for each resource.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
IN [OPTIONAL] hSelf
|
|||
|
- A handle to the resource. When enumerating resources do
|
|||
|
not invoke the callback when the enumerated resource is
|
|||
|
hSelf.
|
|||
|
IF NULL then invoke the callback for all resources
|
|||
|
|
|||
|
IN [OPTIONAL] lpszResTypeName
|
|||
|
- This is an optional resource type name. If specified the
|
|||
|
callback function will only be invoked for resources of
|
|||
|
this type.
|
|||
|
|
|||
|
IN pResCallBack - Pointer to function that gets called for each enumerated
|
|||
|
resource in the cluster
|
|||
|
|
|||
|
IN pParameter - An Opaque callback parameter
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD dwStatus = ERROR_SUCCESS;
|
|||
|
HCLUSTER hCluster = NULL;
|
|||
|
HCLUSENUM hClusEnum = NULL;
|
|||
|
HRESOURCE hResource = NULL;
|
|||
|
BOOL fExecuteCallBack;
|
|||
|
WCHAR szName[ __INITIAL_NAME_LENGTH ];
|
|||
|
LPWSTR lpszName = szName;
|
|||
|
DWORD cchSize = __INITIAL_NAME_LENGTH;
|
|||
|
DWORD cchRetSize;
|
|||
|
DWORD dwIndex;
|
|||
|
DWORD dwType;
|
|||
|
|
|||
|
//
|
|||
|
// Open the cluster
|
|||
|
//
|
|||
|
hCluster = OpenCluster( NULL );
|
|||
|
if( hCluster == NULL )
|
|||
|
{
|
|||
|
dwStatus = GetLastError();
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get a resource enumeration handle
|
|||
|
//
|
|||
|
hClusEnum = ClusterOpenEnum( hCluster, CLUSTER_ENUM_RESOURCE );
|
|||
|
if ( hClusEnum == NULL )
|
|||
|
{
|
|||
|
dwStatus = GetLastError();
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate each resource in the cluster
|
|||
|
//
|
|||
|
dwIndex = 0;
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
cchRetSize = cchSize;
|
|||
|
dwStatus = ClusterEnum(
|
|||
|
hClusEnum, //handle to enum
|
|||
|
dwIndex, //Index
|
|||
|
&dwType, //Type
|
|||
|
lpszName, //Name
|
|||
|
&cchRetSize //Size of name (in characters)
|
|||
|
);
|
|||
|
|
|||
|
if ( dwStatus == ERROR_MORE_DATA )
|
|||
|
{
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cchSize = cchRetSize + 1; // Add room for terminating NULL
|
|||
|
if ( lpszName != szName )
|
|||
|
{
|
|||
|
LocalFree( lpszName );
|
|||
|
}
|
|||
|
lpszName = LocalAlloc( LMEM_FIXED, cchSize * sizeof(WCHAR) );
|
|||
|
if ( lpszName == NULL )
|
|||
|
{
|
|||
|
dwStatus = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
cchRetSize = cchSize;
|
|||
|
dwStatus = ClusterEnum(
|
|||
|
hClusEnum, //handle to enum
|
|||
|
dwIndex, //Index
|
|||
|
&dwType, //Type
|
|||
|
lpszName, //Name
|
|||
|
&cchRetSize //Size of name
|
|||
|
);
|
|||
|
}
|
|||
|
if ( dwStatus == ERROR_SUCCESS )
|
|||
|
{
|
|||
|
//
|
|||
|
// Try to open this resource
|
|||
|
//
|
|||
|
hResource = OpenClusterResource( hCluster, lpszName );
|
|||
|
|
|||
|
if ( hResource == NULL )
|
|||
|
{
|
|||
|
dwStatus = GetLastError();
|
|||
|
if ( dwStatus == ERROR_RESOURCE_NOT_FOUND )
|
|||
|
{
|
|||
|
//
|
|||
|
// If the resource cannot be found, assume it got deleted after
|
|||
|
// you opened the enumeration. So, skip the resource and proceed.
|
|||
|
//
|
|||
|
dwIndex ++;
|
|||
|
dwStatus = ERROR_SUCCESS;
|
|||
|
continue;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Indicate that will invoke the callback
|
|||
|
//
|
|||
|
fExecuteCallBack = TRUE;
|
|||
|
|
|||
|
// Determine if we need to check the type
|
|||
|
//
|
|||
|
if ( lpszResTypeName != NULL )
|
|||
|
{
|
|||
|
fExecuteCallBack = ResUtilResourceTypesEqual( lpszResTypeName, hResource );
|
|||
|
|
|||
|
} //if lpszResTypeName
|
|||
|
|
|||
|
|
|||
|
if ( fExecuteCallBack && ( hSelf != NULL ) )
|
|||
|
{
|
|||
|
// Don't execute callback if hResource is callee (i.e., hSelf)
|
|||
|
fExecuteCallBack = !(ResUtilResourcesEqual( hSelf, hResource ));
|
|||
|
|
|||
|
} //if fExecuteCallBack && hSelf
|
|||
|
|
|||
|
if ( fExecuteCallBack )
|
|||
|
{
|
|||
|
dwStatus = pResCallBack( hSelf, hResource, pParameter );
|
|||
|
|
|||
|
if ( dwStatus != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
} //if fExecuteCallBack
|
|||
|
|
|||
|
CloseClusterResource( hResource );
|
|||
|
hResource = NULL;
|
|||
|
|
|||
|
} // If ERROR_SUCCESS
|
|||
|
|
|||
|
dwIndex++;
|
|||
|
} while ( dwStatus == ERROR_SUCCESS );
|
|||
|
|
|||
|
Cleanup:
|
|||
|
|
|||
|
if ( hClusEnum != NULL )
|
|||
|
{
|
|||
|
ClusterCloseEnum( hClusEnum );
|
|||
|
}
|
|||
|
|
|||
|
if ( hCluster != NULL )
|
|||
|
{
|
|||
|
CloseCluster( hCluster );
|
|||
|
}
|
|||
|
|
|||
|
if ( hResource != NULL )
|
|||
|
{
|
|||
|
CloseClusterResource( hResource );
|
|||
|
}
|
|||
|
|
|||
|
if ( lpszName != szName )
|
|||
|
{
|
|||
|
LocalFree( lpszName );
|
|||
|
}
|
|||
|
|
|||
|
if ( dwStatus == ERROR_NO_MORE_ITEMS )
|
|||
|
{
|
|||
|
dwStatus = ERROR_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
return dwStatus;
|
|||
|
|
|||
|
} //*** ResUtilEnumResources()
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilEnumResourcesEx(
|
|||
|
IN HCLUSTER hCluster,
|
|||
|
IN HRESOURCE hSelf,
|
|||
|
IN LPCWSTR lpszResTypeName,
|
|||
|
IN LPRESOURCE_CALLBACK_EX pResCallBack,
|
|||
|
IN PVOID pParameter
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This is a generic resource walking routine. It enumerates all resources in
|
|||
|
the cluster and invokes the callback function for each resource.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
IN hCluster - A handle to the cluster to enumerate resources on.
|
|||
|
|
|||
|
IN [OPTIONAL] hSelf
|
|||
|
- A handle to the resource. When enumerating resources do
|
|||
|
not invoke the callback when the enumerated resource is
|
|||
|
hSelf.
|
|||
|
IF NULL then invoke the callback for all resources
|
|||
|
|
|||
|
IN [OPTIONAL] lpszResTypeName
|
|||
|
- This is an optional resource type name. If specified the
|
|||
|
callback function will only be invoked for resources of
|
|||
|
this type.
|
|||
|
|
|||
|
IN pResCallBack - Pointer to function that gets called for each enumerated
|
|||
|
resource in the cluster
|
|||
|
|
|||
|
IN pParameter - An Opaque callback parameter
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
|
|||
|
A Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD dwStatus = ERROR_SUCCESS;
|
|||
|
HCLUSENUM hClusEnum = NULL;
|
|||
|
HRESOURCE hResource = NULL;
|
|||
|
BOOL fExecuteCallBack;
|
|||
|
WCHAR szName[ __INITIAL_NAME_LENGTH ];
|
|||
|
LPWSTR lpszName = szName;
|
|||
|
DWORD cchSize = __INITIAL_NAME_LENGTH;
|
|||
|
DWORD cchRetSize;
|
|||
|
DWORD dwIndex;
|
|||
|
DWORD dwType;
|
|||
|
|
|||
|
//
|
|||
|
// Get a resource enumeration handle
|
|||
|
//
|
|||
|
hClusEnum = ClusterOpenEnum( hCluster, CLUSTER_ENUM_RESOURCE );
|
|||
|
if ( hClusEnum == NULL )
|
|||
|
{
|
|||
|
dwStatus = GetLastError();
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate each resource in the cluster
|
|||
|
//
|
|||
|
dwIndex = 0;
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
cchRetSize = cchSize;
|
|||
|
dwStatus = ClusterEnum(
|
|||
|
hClusEnum, //handle to enum
|
|||
|
dwIndex, //Index
|
|||
|
&dwType, //Type
|
|||
|
lpszName, //Name
|
|||
|
&cchRetSize //Size of name
|
|||
|
);
|
|||
|
|
|||
|
if ( dwStatus == ERROR_MORE_DATA )
|
|||
|
{
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cchSize = cchRetSize + 1; // Add room for terminating null
|
|||
|
if ( lpszName != szName )
|
|||
|
{
|
|||
|
LocalFree( lpszName );
|
|||
|
}
|
|||
|
lpszName = LocalAlloc( LMEM_FIXED, cchSize * sizeof(WCHAR) );
|
|||
|
if ( lpszName == NULL )
|
|||
|
{
|
|||
|
dwStatus = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
cchRetSize = cchSize;
|
|||
|
dwStatus = ClusterEnum(
|
|||
|
hClusEnum, //handle to enum
|
|||
|
dwIndex, //Index
|
|||
|
&dwType, //Type
|
|||
|
lpszName, //Name
|
|||
|
&cchRetSize //Size of name
|
|||
|
);
|
|||
|
}
|
|||
|
if ( dwStatus == ERROR_SUCCESS )
|
|||
|
{
|
|||
|
//
|
|||
|
// Try to open this resource
|
|||
|
//
|
|||
|
hResource = OpenClusterResource( hCluster, lpszName );
|
|||
|
|
|||
|
if ( hResource == NULL )
|
|||
|
{
|
|||
|
dwStatus = GetLastError();
|
|||
|
if ( dwStatus == ERROR_RESOURCE_NOT_FOUND )
|
|||
|
{
|
|||
|
//
|
|||
|
// If the resource cannot be found, assume it got deleted after
|
|||
|
// you opened the enumeration. So, skip the resource and proceed.
|
|||
|
//
|
|||
|
dwIndex ++;
|
|||
|
dwStatus = ERROR_SUCCESS;
|
|||
|
continue;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Indicate that will invoke the callback
|
|||
|
//
|
|||
|
fExecuteCallBack = TRUE;
|
|||
|
|
|||
|
// Determine if we need to check the type
|
|||
|
//
|
|||
|
if ( lpszResTypeName != NULL )
|
|||
|
{
|
|||
|
fExecuteCallBack = ResUtilResourceTypesEqual( lpszResTypeName, hResource );
|
|||
|
|
|||
|
} //if lpszResTypeName
|
|||
|
|
|||
|
|
|||
|
if ( fExecuteCallBack && ( hSelf != NULL ) )
|
|||
|
{
|
|||
|
// Don't execute callback if hResource is callee (i.e., hSelf)
|
|||
|
fExecuteCallBack = !(ResUtilResourcesEqual( hSelf, hResource ));
|
|||
|
|
|||
|
} //if fExecuteCallBack && hSelf
|
|||
|
|
|||
|
if ( fExecuteCallBack )
|
|||
|
{
|
|||
|
dwStatus = pResCallBack( hCluster, hSelf, hResource, pParameter );
|
|||
|
|
|||
|
if ( dwStatus != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
} //if fExecuteCallBack
|
|||
|
|
|||
|
CloseClusterResource( hResource );
|
|||
|
hResource = NULL;
|
|||
|
|
|||
|
} // If ERROR_SUCCESS
|
|||
|
|
|||
|
dwIndex++;
|
|||
|
} while ( dwStatus == ERROR_SUCCESS );
|
|||
|
|
|||
|
Cleanup:
|
|||
|
|
|||
|
if ( hClusEnum != NULL )
|
|||
|
{
|
|||
|
ClusterCloseEnum( hClusEnum );
|
|||
|
}
|
|||
|
|
|||
|
if ( hResource != NULL )
|
|||
|
{
|
|||
|
CloseClusterResource( hResource );
|
|||
|
}
|
|||
|
|
|||
|
if ( lpszName != szName )
|
|||
|
{
|
|||
|
LocalFree( lpszName );
|
|||
|
}
|
|||
|
|
|||
|
if ( dwStatus == ERROR_NO_MORE_ITEMS )
|
|||
|
{
|
|||
|
dwStatus = ERROR_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
return dwStatus;
|
|||
|
|
|||
|
} //*** ResUtilEnumResourcesEx()
|
|||
|
|
|||
|
|
|||
|
|
|||
|
HRESOURCE
|
|||
|
WINAPI
|
|||
|
ResUtilGetResourceDependency(
|
|||
|
IN HANDLE hSelf,
|
|||
|
IN LPCWSTR lpszResourceType
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Returns a dependent resource for the local cluster.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hSelf - A handle to the original resource.
|
|||
|
|
|||
|
lpszResourceType - the type of resource that it depends on
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NULL - error (use GetLastError() to get further info)
|
|||
|
|
|||
|
NON-NULL - Handle to a resource of type ResourceType
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESOURCE hResDepends = NULL;
|
|||
|
HCLUSTER hCluster = NULL;
|
|||
|
HRESENUM hResEnum = NULL;
|
|||
|
WCHAR szName[ __INITIAL_NAME_LENGTH ];
|
|||
|
LPWSTR pszName = szName;
|
|||
|
DWORD cchSize = __INITIAL_NAME_LENGTH;
|
|||
|
DWORD cchRetSize;
|
|||
|
DWORD dwType = 0;
|
|||
|
DWORD dwIndex = 0;
|
|||
|
DWORD status = ERROR_SUCCESS;
|
|||
|
|
|||
|
|
|||
|
hCluster = OpenCluster( NULL );
|
|||
|
if ( hCluster == NULL ) {
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Open the depends on enum (get resource dependencies)
|
|||
|
//
|
|||
|
hResEnum = ClusterResourceOpenEnum( hSelf, CLUSTER_RESOURCE_ENUM_DEPENDS );
|
|||
|
|
|||
|
if ( hResEnum == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate all the depends on keys
|
|||
|
//
|
|||
|
do {
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
if ( status == ERROR_MORE_DATA ) {
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cchSize = cchRetSize + 1; // Add room for terminating null
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
pszName = LocalAlloc( LMEM_FIXED, cchSize * sizeof(WCHAR) );
|
|||
|
if ( pszName == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
} // if: error allocating memory
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
}
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Determine the type of resource found
|
|||
|
//
|
|||
|
hResDepends = OpenClusterResource( hCluster, pszName );
|
|||
|
if ( hResDepends == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ( hResDepends != NULL ) {
|
|||
|
//
|
|||
|
// Valid resource now open the reg and get it's type
|
|||
|
//
|
|||
|
if ( ResUtilResourceTypesEqual( lpszResourceType, hResDepends ) ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
} //if !hResDepends
|
|||
|
|
|||
|
//
|
|||
|
// Close all handles, key's
|
|||
|
//
|
|||
|
if ( hResDepends != NULL ) {
|
|||
|
CloseClusterResource( hResDepends );
|
|||
|
hResDepends = NULL;
|
|||
|
}
|
|||
|
|
|||
|
dwIndex++;
|
|||
|
} while ( status == ERROR_SUCCESS );
|
|||
|
|
|||
|
error_exit:
|
|||
|
//
|
|||
|
// At this point hResDepends is NULL if no match or non-null (success)
|
|||
|
//
|
|||
|
if ( hCluster != NULL ) {
|
|||
|
CloseCluster( hCluster );
|
|||
|
}
|
|||
|
|
|||
|
if ( hResEnum != NULL ) {
|
|||
|
ClusterResourceCloseEnum( hResEnum );
|
|||
|
}
|
|||
|
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
SetLastError( status );
|
|||
|
}
|
|||
|
return(hResDepends);
|
|||
|
|
|||
|
} //*** ResUtilGetResourceDependency()
|
|||
|
|
|||
|
|
|||
|
HRESOURCE
|
|||
|
WINAPI
|
|||
|
ResUtilGetResourceDependencyByName(
|
|||
|
IN HCLUSTER hCluster,
|
|||
|
IN HANDLE hSelf,
|
|||
|
IN LPCWSTR lpszResourceType,
|
|||
|
IN BOOL bRecurse
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Returns a dependent resource for a specified cluster based on the resource
|
|||
|
type name.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hCluster - Cluster to query.
|
|||
|
|
|||
|
hSelf - A handle to the original resource.
|
|||
|
|
|||
|
lpszResourceType - The name of the resource type of the resource that the
|
|||
|
specified resource depends on.
|
|||
|
|
|||
|
bRecurse - TRUE = check dependents of dependents. An immediate dependency
|
|||
|
will be returned if there is one.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NULL - error (use GetLastError() to get further info)
|
|||
|
|
|||
|
NON-NULL - Handle to a resource of type lpszResourceType
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESOURCE hResDepends = NULL;
|
|||
|
HRESOURCE hResDepends2 = NULL;
|
|||
|
HRESENUM hResEnum = NULL;
|
|||
|
WCHAR szName[ __INITIAL_NAME_LENGTH ];
|
|||
|
LPWSTR pszName = szName;
|
|||
|
DWORD cchSize = __INITIAL_NAME_LENGTH;
|
|||
|
DWORD cchRetSize;
|
|||
|
DWORD dwType = 0;
|
|||
|
DWORD dwIndex = 0;
|
|||
|
DWORD status = ERROR_SUCCESS;
|
|||
|
|
|||
|
if ( ( hCluster == NULL ) || ( lpszResourceType == NULL ) )
|
|||
|
{
|
|||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|||
|
return NULL;
|
|||
|
} // if: no cluster handle or resource type name specified
|
|||
|
|
|||
|
//
|
|||
|
// Open the depends on enum (get resource dependencies)
|
|||
|
//
|
|||
|
hResEnum = ClusterResourceOpenEnum( hSelf, CLUSTER_RESOURCE_ENUM_DEPENDS );
|
|||
|
|
|||
|
if ( hResEnum == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate all the depends on keys
|
|||
|
//
|
|||
|
do {
|
|||
|
//
|
|||
|
// Get the next dependent resource.
|
|||
|
//
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
if ( status == ERROR_MORE_DATA ) {
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cchSize = cchRetSize + 1; // Add room for terminating null
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
pszName = LocalAlloc( LMEM_FIXED, cchSize * sizeof(WCHAR) );
|
|||
|
if ( pszName == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
} // if: error allocating memory
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
}
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Open the resource.
|
|||
|
//
|
|||
|
hResDepends = OpenClusterResource( hCluster, pszName );
|
|||
|
if ( hResDepends == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Resource is valid. Now see if it is the right type.
|
|||
|
//
|
|||
|
if ( ResUtilResourceTypesEqual( lpszResourceType, hResDepends ) ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Close all handles, key's
|
|||
|
//
|
|||
|
if ( hResDepends != NULL ) {
|
|||
|
CloseClusterResource( hResDepends );
|
|||
|
hResDepends = NULL;
|
|||
|
}
|
|||
|
|
|||
|
dwIndex++;
|
|||
|
} while ( status == ERROR_SUCCESS );
|
|||
|
|
|||
|
//
|
|||
|
// If a match was not found, recurse the dependencies again looking for a
|
|||
|
// dependency of the dependencies if the bDeep argument was specified.
|
|||
|
//
|
|||
|
if ( ( status == ERROR_SUCCESS ) && ( hResDepends == NULL ) && bRecurse ) {
|
|||
|
|
|||
|
//
|
|||
|
// Open the depends on enum (get resource dependencies)
|
|||
|
//
|
|||
|
ClusterResourceCloseEnum( hResEnum );
|
|||
|
hResEnum = ClusterResourceOpenEnum( hSelf, CLUSTER_RESOURCE_ENUM_DEPENDS );
|
|||
|
|
|||
|
if ( hResEnum == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate all the depends on keys
|
|||
|
//
|
|||
|
dwIndex = 0;
|
|||
|
do {
|
|||
|
//
|
|||
|
// Get the next dependent resource.
|
|||
|
//
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
if ( status == ERROR_MORE_DATA ) {
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cchSize = cchRetSize + 1; // Add room for terminating null
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
pszName = LocalAlloc( LMEM_FIXED, cchSize * sizeof(WCHAR) );
|
|||
|
if ( pszName == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
} // if: error allocating memory
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
}
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Open the resource.
|
|||
|
//
|
|||
|
hResDepends2 = OpenClusterResource( hCluster, pszName );
|
|||
|
if ( hResDepends2 == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Recursively call ourselves with this resource.
|
|||
|
//
|
|||
|
hResDepends = ResUtilGetResourceDependencyByName(
|
|||
|
hCluster,
|
|||
|
hResDepends2,
|
|||
|
lpszResourceType,
|
|||
|
bRecurse
|
|||
|
);
|
|||
|
if ( hResDepends != NULL ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_RESOURCE_NOT_FOUND ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
status = ERROR_SUCCESS;
|
|||
|
|
|||
|
//
|
|||
|
// Close all handles, key's
|
|||
|
//
|
|||
|
if ( hResDepends2 != NULL ) {
|
|||
|
CloseClusterResource( hResDepends2 );
|
|||
|
hResDepends2 = NULL;
|
|||
|
}
|
|||
|
|
|||
|
dwIndex++;
|
|||
|
} while ( status == ERROR_SUCCESS );
|
|||
|
}
|
|||
|
|
|||
|
error_exit:
|
|||
|
if ( hResEnum != NULL ) {
|
|||
|
ClusterResourceCloseEnum( hResEnum );
|
|||
|
}
|
|||
|
|
|||
|
if ( hResDepends2 != NULL ) {
|
|||
|
CloseClusterResource( hResDepends2 );
|
|||
|
}
|
|||
|
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
|
|||
|
if ( ( status == ERROR_SUCCESS ) && ( hResDepends == NULL ) ) {
|
|||
|
status = ERROR_RESOURCE_NOT_FOUND;
|
|||
|
}
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
SetLastError( status );
|
|||
|
}
|
|||
|
|
|||
|
return hResDepends;
|
|||
|
|
|||
|
} //*** ResUtilGetResourceDependencyByName()
|
|||
|
|
|||
|
|
|||
|
HRESOURCE
|
|||
|
WINAPI
|
|||
|
ResUtilGetResourceDependencyByClass(
|
|||
|
IN HCLUSTER hCluster,
|
|||
|
IN HANDLE hSelf,
|
|||
|
IN PCLUS_RESOURCE_CLASS_INFO prci,
|
|||
|
IN BOOL bRecurse
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Returns a dependent resource for a specified cluster based on the resource
|
|||
|
type class information.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hCluster - Cluster to query.
|
|||
|
|
|||
|
hSelf - A handle to the original resource.
|
|||
|
|
|||
|
prci - The resource class info of the resource type of the resource that
|
|||
|
the specified resource depends on.
|
|||
|
|
|||
|
bRecurse - TRUE = check dependents of dependents. An immediate dependency
|
|||
|
will be returned if there is one.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NULL - error (use GetLastError() to get further info)
|
|||
|
|
|||
|
NON-NULL - Handle to a resource whose class is specified by prci.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESOURCE hResDepends = NULL;
|
|||
|
HRESOURCE hResDepends2 = NULL;
|
|||
|
HRESENUM hResEnum = NULL;
|
|||
|
WCHAR szName[ __INITIAL_NAME_LENGTH ];
|
|||
|
LPWSTR pszName = szName;
|
|||
|
DWORD cchSize = __INITIAL_NAME_LENGTH;
|
|||
|
DWORD cchRetSize;
|
|||
|
DWORD dwType = 0;
|
|||
|
DWORD dwIndex = 0;
|
|||
|
DWORD status = ERROR_SUCCESS;
|
|||
|
|
|||
|
if ( ( hCluster == NULL ) || ( prci == NULL ) )
|
|||
|
{
|
|||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|||
|
return NULL;
|
|||
|
} // if: no cluster handle or class info specified
|
|||
|
|
|||
|
//
|
|||
|
// Open the depends on enum (get resource dependencies)
|
|||
|
//
|
|||
|
hResEnum = ClusterResourceOpenEnum( hSelf, CLUSTER_RESOURCE_ENUM_DEPENDS );
|
|||
|
|
|||
|
if ( hResEnum == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate all the depends on keys
|
|||
|
//
|
|||
|
do {
|
|||
|
//
|
|||
|
// Get the next dependent resource.
|
|||
|
//
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
if ( status == ERROR_MORE_DATA ) {
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cchSize = cchRetSize + 1; // Add room for terminating null
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
pszName = LocalAlloc( LMEM_FIXED, cchSize * sizeof(WCHAR) );
|
|||
|
if ( pszName == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
} // if: error allocating memory
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
}
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Determine the type of resource found
|
|||
|
//
|
|||
|
hResDepends = OpenClusterResource( hCluster, pszName );
|
|||
|
if ( hResDepends == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Resource is valid. Now see if it is the right class.
|
|||
|
//
|
|||
|
if ( ResUtilIsResourceClassEqual( prci, hResDepends ) ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Close all handles, key's
|
|||
|
//
|
|||
|
if ( hResDepends != NULL ) {
|
|||
|
CloseClusterResource( hResDepends );
|
|||
|
hResDepends = NULL;
|
|||
|
}
|
|||
|
|
|||
|
dwIndex++;
|
|||
|
} while ( status == ERROR_SUCCESS );
|
|||
|
|
|||
|
//
|
|||
|
// If a match was not found, recurse the dependencies again looking for a
|
|||
|
// dependency of the dependencies if the bDeep argument was specified.
|
|||
|
//
|
|||
|
if ( ( status == ERROR_SUCCESS ) && ( hResDepends == NULL ) && bRecurse ) {
|
|||
|
|
|||
|
//
|
|||
|
// Open the depends on enum (get resource dependencies)
|
|||
|
//
|
|||
|
ClusterResourceCloseEnum( hResEnum );
|
|||
|
hResEnum = ClusterResourceOpenEnum( hSelf, CLUSTER_RESOURCE_ENUM_DEPENDS );
|
|||
|
|
|||
|
if ( hResEnum == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate all the depends on keys
|
|||
|
//
|
|||
|
dwIndex = 0;
|
|||
|
do {
|
|||
|
//
|
|||
|
// Get the next dependent resource.
|
|||
|
//
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
if ( status == ERROR_MORE_DATA ) {
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cchSize = cchRetSize + 1; // Add room for terminating null
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
pszName = LocalAlloc( LMEM_FIXED, cchSize * sizeof(WCHAR) );
|
|||
|
if ( pszName == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
} // if: error allocating memory
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
}
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Open the resource.
|
|||
|
//
|
|||
|
hResDepends2 = OpenClusterResource( hCluster, pszName );
|
|||
|
if ( hResDepends2 == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Recursively call ourselves with this resource.
|
|||
|
//
|
|||
|
hResDepends = ResUtilGetResourceDependencyByClass(
|
|||
|
hCluster,
|
|||
|
hResDepends2,
|
|||
|
prci,
|
|||
|
bRecurse
|
|||
|
);
|
|||
|
if ( hResDepends != NULL ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_RESOURCE_NOT_FOUND ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
status = ERROR_SUCCESS;
|
|||
|
|
|||
|
//
|
|||
|
// Close all handles, key's
|
|||
|
//
|
|||
|
if ( hResDepends2 != NULL ) {
|
|||
|
CloseClusterResource( hResDepends2 );
|
|||
|
hResDepends2 = NULL;
|
|||
|
}
|
|||
|
|
|||
|
dwIndex++;
|
|||
|
} while ( status == ERROR_SUCCESS );
|
|||
|
}
|
|||
|
|
|||
|
error_exit:
|
|||
|
if ( hResEnum != NULL ) {
|
|||
|
ClusterResourceCloseEnum( hResEnum );
|
|||
|
}
|
|||
|
|
|||
|
if ( hResDepends2 != NULL ) {
|
|||
|
CloseClusterResource( hResDepends2 );
|
|||
|
}
|
|||
|
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
|
|||
|
if ( ( status == ERROR_SUCCESS ) && ( hResDepends == NULL ) ) {
|
|||
|
status = ERROR_RESOURCE_NOT_FOUND;
|
|||
|
}
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
SetLastError( status );
|
|||
|
}
|
|||
|
|
|||
|
return hResDepends;
|
|||
|
|
|||
|
} //*** ResUtilGetResourceDependencyByClass()
|
|||
|
|
|||
|
|
|||
|
HRESOURCE
|
|||
|
WINAPI
|
|||
|
ResUtilGetResourceNameDependency(
|
|||
|
IN LPCWSTR lpszResourceName,
|
|||
|
IN LPCWSTR lpszResourceType
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Returns a dependent resource
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
lpszResourceName - the name of the resource
|
|||
|
|
|||
|
lpszResourceType - the type of the resource that it depends on
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NULL - error (use GetLastError() to get further info)
|
|||
|
|
|||
|
NON-NULL - Handle to a resource of type ResourceType
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HRESOURCE hResDepends = NULL;
|
|||
|
HCLUSTER hCluster = NULL;
|
|||
|
HRESOURCE hSelf = NULL;
|
|||
|
HRESENUM hResEnum = NULL;
|
|||
|
WCHAR szName[ __INITIAL_NAME_LENGTH ];
|
|||
|
LPWSTR pszName = szName;
|
|||
|
DWORD cchSize = __INITIAL_NAME_LENGTH;
|
|||
|
DWORD cchRetSize;
|
|||
|
DWORD dwType = 0;
|
|||
|
DWORD dwIndex = 0;
|
|||
|
DWORD status = ERROR_SUCCESS;
|
|||
|
|
|||
|
if ( lpszResourceName == NULL ) {
|
|||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
hCluster = OpenCluster( NULL );
|
|||
|
if ( hCluster == NULL ) {
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Open a handle to the passed in resource name.
|
|||
|
//
|
|||
|
hSelf = OpenClusterResource( hCluster, lpszResourceName );
|
|||
|
if ( hSelf == NULL ) {
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Open the depends on enum (get resource dependencies)
|
|||
|
//
|
|||
|
hResEnum = ClusterResourceOpenEnum( hSelf, CLUSTER_RESOURCE_ENUM_DEPENDS );
|
|||
|
if ( hResEnum == NULL ) {
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enumerate all the depends on keys
|
|||
|
//
|
|||
|
do {
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
if ( status == ERROR_MORE_DATA ) {
|
|||
|
//
|
|||
|
// Output name buffer is too small. Allocate a new one.
|
|||
|
//
|
|||
|
cchSize = cchRetSize + 1; // Add room for terminating NULL
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
pszName = LocalAlloc( LMEM_FIXED, cchSize * sizeof(WCHAR) );
|
|||
|
if ( pszName == NULL ) {
|
|||
|
status = GetLastError();
|
|||
|
break;
|
|||
|
} // if: error allocating memory
|
|||
|
cchRetSize = cchSize;
|
|||
|
status = ClusterResourceEnum( hResEnum, dwIndex, &dwType, pszName, &cchRetSize );
|
|||
|
}
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Determine the type of resource found
|
|||
|
//
|
|||
|
hResDepends = OpenClusterResource( hCluster, pszName );
|
|||
|
if ( hResDepends == NULL ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Valid resource now open the reg and get it's type
|
|||
|
//
|
|||
|
if ( ResUtilResourceTypesEqual( lpszResourceType, hResDepends ) ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Close all handles, key's
|
|||
|
//
|
|||
|
if ( hResDepends != NULL ) {
|
|||
|
CloseClusterResource( hResDepends );
|
|||
|
hResDepends = NULL;
|
|||
|
}
|
|||
|
|
|||
|
dwIndex++;
|
|||
|
} while (status == ERROR_SUCCESS);
|
|||
|
|
|||
|
error_exit:
|
|||
|
//
|
|||
|
// At this point hResDepends is NULL if no match or non-null (success)
|
|||
|
//
|
|||
|
if ( hCluster != NULL ) {
|
|||
|
CloseCluster( hCluster );
|
|||
|
}
|
|||
|
|
|||
|
if ( hSelf != NULL ) {
|
|||
|
CloseClusterResource( hSelf );
|
|||
|
}
|
|||
|
|
|||
|
if ( hResEnum != NULL ) {
|
|||
|
ClusterResourceCloseEnum( hResEnum );
|
|||
|
}
|
|||
|
|
|||
|
if ( pszName != szName ) {
|
|||
|
LocalFree( pszName );
|
|||
|
}
|
|||
|
|
|||
|
if ( status != ERROR_SUCCESS ) {
|
|||
|
SetLastError( status );
|
|||
|
}
|
|||
|
|
|||
|
return hResDepends;
|
|||
|
|
|||
|
} //*** ResUtilGetResourceNameDependency()
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
WINAPI
|
|||
|
ResUtilGetPropertyFormats(
|
|||
|
IN const PRESUTIL_PROPERTY_ITEM pPropertyTable,
|
|||
|
OUT PVOID pOutPropertyFormatList,
|
|||
|
IN DWORD cbPropertyFormatListSize,
|
|||
|
OUT LPDWORD pcbBytesReturned,
|
|||
|
OUT LPDWORD pcbRequired
|
|||
|
)
|
|||
|
{
|
|||
|
return( ClRtlGetPropertyFormats( pPropertyTable,
|
|||
|
pOutPropertyFormatList,
|
|||
|
cbPropertyFormatListSize,
|
|||
|
pcbBytesReturned,
|
|||
|
pcbRequired ) );
|
|||
|
|
|||
|
} // ResUtilGetPropertyFormats()
|
|||
|
|