672 lines
15 KiB
C++
672 lines
15 KiB
C++
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name :
|
|
mb.hxx
|
|
|
|
Abstract:
|
|
This module defines the USER-level wrapper class for access to the
|
|
metabase
|
|
|
|
Author:
|
|
|
|
JohnL 09-Oct-1996
|
|
|
|
Environment:
|
|
Win32 - User Mode
|
|
|
|
Project:
|
|
|
|
Internet Server DLL
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#ifndef _MB_HXX_
|
|
#define _MB_HXX_
|
|
|
|
#if !defined( dllexp)
|
|
#define dllexp __declspec( dllexport)
|
|
#endif // !defined( dllexp)
|
|
|
|
//
|
|
// Default timeout
|
|
//
|
|
|
|
#define MB_TIMEOUT 5000
|
|
|
|
//
|
|
// IIS Service pointer
|
|
//
|
|
|
|
#define PINETSVC g_pInetSvc
|
|
|
|
/************************************************************
|
|
* Type Definitions
|
|
************************************************************/
|
|
|
|
|
|
//
|
|
// Simple wrapper class around the metabase APIs
|
|
//
|
|
// The Metabase Interface pointer is assumed to remain valid for the lifetime
|
|
// of this object.
|
|
//
|
|
// The character counts for paths should include the terminating '\0'.
|
|
//
|
|
//
|
|
|
|
class MB
|
|
{
|
|
public:
|
|
|
|
MB( IMSAdminBase * pMBCom )
|
|
: _pMBCom( pMBCom ),
|
|
_hMB ( NULL )
|
|
{
|
|
}
|
|
|
|
~MB( VOID )
|
|
{
|
|
Close();
|
|
_pMBCom = NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline
|
|
BOOL Open( const TCHAR * pszPath,
|
|
DWORD dwFlags = METADATA_PERMISSION_READ )
|
|
{
|
|
return Open( METADATA_MASTER_ROOT_HANDLE,
|
|
pszPath,
|
|
dwFlags );
|
|
}
|
|
|
|
inline
|
|
BOOL Open( METADATA_HANDLE hOpenRoot,
|
|
const TCHAR * pszPath,
|
|
DWORD dwFlags = METADATA_PERMISSION_READ );
|
|
|
|
/*
|
|
inline
|
|
BOOL GetAll( const TCHAR * pszPath,
|
|
DWORD dwFlags,
|
|
DWORD dwUserType,
|
|
BUFFER * pBuff,
|
|
DWORD * pcRecords,
|
|
DWORD * pdwDataSetNumber );
|
|
*/
|
|
|
|
inline
|
|
BOOL GetDataSetNumber( const TCHAR * pszPath,
|
|
DWORD * pdwDataSetNumber );
|
|
|
|
|
|
inline
|
|
BOOL EnumObjects( const TCHAR * pszPath,
|
|
TCHAR * Name,
|
|
DWORD Index )
|
|
{
|
|
HRESULT hRes = _pMBCom->EnumKeys( _hMB,pszPath, Name, Index );
|
|
|
|
if ( SUCCEEDED( hRes ))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
SetLastError( HRESULTTOWIN32( hRes ));
|
|
return FALSE;
|
|
}
|
|
|
|
inline
|
|
BOOL AddObject( const TCHAR * pszPath )
|
|
{
|
|
HRESULT hRes = _pMBCom->AddKey( _hMB, pszPath );
|
|
if ( SUCCEEDED( hRes ))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
SetLastError( HRESULTTOWIN32( hRes ));
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------- boydm
|
|
inline
|
|
BOOL RenameKey( const TCHAR* pszPath, const TCHAR* pszNewName )
|
|
{
|
|
HRESULT hRes = _pMBCom->RenameKey( _hMB, pszPath, pszNewName );
|
|
if ( SUCCEEDED( hRes ))
|
|
{
|
|
return TRUE;
|
|
}
|
|
SetLastError( HRESULTTOWIN32( hRes ));
|
|
return FALSE;
|
|
}
|
|
|
|
inline
|
|
BOOL DeleteObject( const TCHAR * pszPath )
|
|
{
|
|
HRESULT hRes = _pMBCom->DeleteKey( _hMB, pszPath );
|
|
|
|
if ( SUCCEEDED( hRes ))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
SetLastError( HRESULTTOWIN32( hRes ));
|
|
return FALSE;
|
|
}
|
|
|
|
inline
|
|
BOOL Save( VOID )
|
|
{
|
|
HRESULT hRes = _pMBCom->SaveData();
|
|
|
|
if ( SUCCEEDED( hRes ))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
SetLastError( HRESULTTOWIN32( hRes ));
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL SetDword( const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
DWORD dwValue,
|
|
DWORD dwFlags = METADATA_INHERIT )
|
|
{
|
|
return SetData( pszPath,
|
|
dwPropID,
|
|
dwUserType,
|
|
DWORD_METADATA,
|
|
(PVOID) &dwValue,
|
|
sizeof( DWORD ),
|
|
dwFlags );
|
|
}
|
|
|
|
BOOL SetString( const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
TCHAR * pszValue,
|
|
DWORD dwFlags = METADATA_INHERIT )
|
|
{
|
|
#ifdef _UNICODE
|
|
return SetData( pszPath,
|
|
dwPropID,
|
|
dwUserType,
|
|
STRING_METADATA,
|
|
pszValue,
|
|
(wcslen(pszValue)+1) * 2, // byte count, not character count
|
|
dwFlags );
|
|
#else
|
|
return SetData( pszPath,
|
|
dwPropID,
|
|
dwUserType,
|
|
STRING_METADATA,
|
|
pszValue,
|
|
strlen(pszValue)+1, // string length ignored for inprocess clients
|
|
dwFlags );
|
|
#endif
|
|
}
|
|
|
|
BOOL GetDword( const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
DWORD * pdwValue,
|
|
DWORD dwFlags = METADATA_INHERIT )
|
|
{
|
|
DWORD cb = sizeof(DWORD);
|
|
|
|
return GetData( pszPath,
|
|
dwPropID,
|
|
dwUserType,
|
|
DWORD_METADATA,
|
|
pdwValue,
|
|
&cb,
|
|
dwFlags );
|
|
}
|
|
|
|
BOOL GetString( const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
TCHAR * pszValue,
|
|
DWORD * pcbValue,
|
|
DWORD dwFlags = METADATA_INHERIT )
|
|
{
|
|
return GetData( pszPath,
|
|
dwPropID,
|
|
dwUserType,
|
|
STRING_METADATA,
|
|
pszValue,
|
|
pcbValue,
|
|
dwFlags );
|
|
}
|
|
|
|
/*
|
|
inline
|
|
BOOL GetStr( const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
STR * strValue,
|
|
DWORD dwFlags = METADATA_INHERIT,
|
|
const TCHAR * pszDefault = NULL );
|
|
*/
|
|
|
|
inline
|
|
BOOL SetData( const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
DWORD dwDataType,
|
|
VOID * pvData,
|
|
DWORD cbData,
|
|
DWORD dwFlags = METADATA_INHERIT );
|
|
|
|
inline
|
|
BOOL GetData( const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
DWORD dwDataType,
|
|
VOID * pvData,
|
|
DWORD * cbData,
|
|
DWORD dwFlags = METADATA_INHERIT );
|
|
|
|
inline
|
|
BOOL DeleteData(const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
DWORD dwDataType )
|
|
{
|
|
HRESULT hRes = _pMBCom->DeleteData( _hMB, pszPath,
|
|
dwPropID,
|
|
dwDataType );
|
|
|
|
if ( SUCCEEDED( hRes ))
|
|
{
|
|
return TRUE;
|
|
}
|
|
SetLastError( HRESULTTOWIN32( hRes ));
|
|
return(FALSE);
|
|
}
|
|
|
|
BOOL Close( VOID )
|
|
{
|
|
if ( _hMB )
|
|
{
|
|
_pMBCom->CloseKey( _hMB );
|
|
_hMB = NULL;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
METADATA_HANDLE QueryHandle( VOID ) const
|
|
{ return _hMB; }
|
|
|
|
private:
|
|
|
|
IMSAdminBase * _pMBCom;
|
|
METADATA_HANDLE _hMB;
|
|
|
|
};
|
|
|
|
|
|
inline
|
|
BOOL
|
|
MB::Open(
|
|
METADATA_HANDLE hOpenRoot,
|
|
const TCHAR * pszPath,
|
|
DWORD dwFlags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Opens the metabase
|
|
|
|
Arguments:
|
|
|
|
hOpenRoot - Relative root or METADATA_MASTER_ROOT_HANDLE
|
|
pszPath - Path to open
|
|
dwFlags - Open flags
|
|
|
|
Return:
|
|
|
|
TRUE if success, FALSE on error, (call GetLastError())
|
|
|
|
--*/
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = _pMBCom->OpenKey( hOpenRoot, pszPath,
|
|
dwFlags,
|
|
MB_TIMEOUT,
|
|
&_hMB );
|
|
|
|
if ( SUCCEEDED( hRes ))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
SetLastError( HRESULTTOWIN32( hRes ) );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
inline
|
|
BOOL
|
|
MB::SetData(
|
|
const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
DWORD dwDataType,
|
|
VOID * pvData,
|
|
DWORD cbData,
|
|
DWORD dwFlags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets a metadata property on an openned metabase
|
|
|
|
Arguments:
|
|
|
|
pszPath - Path to set data on
|
|
dwPropID - Metabase property ID
|
|
dwUserType - User type for this property
|
|
dwDataType - Type of data being set (dword, string etc)
|
|
pvData - Pointer to data
|
|
cbData - Size of data
|
|
dwFlags - Inheritance flags
|
|
|
|
Return:
|
|
|
|
TRUE if success, FALSE on error, (call GetLastError())
|
|
|
|
--*/
|
|
{
|
|
METADATA_RECORD mdRecord;
|
|
HRESULT hRes;
|
|
|
|
|
|
mdRecord.dwMDIdentifier = dwPropID;
|
|
mdRecord.dwMDAttributes = dwFlags;
|
|
mdRecord.dwMDUserType = dwUserType;
|
|
mdRecord.dwMDDataType = dwDataType;
|
|
mdRecord.dwMDDataLen = cbData;
|
|
mdRecord.pbMDData = (PBYTE) pvData;
|
|
|
|
hRes = _pMBCom->SetData( _hMB, pszPath,
|
|
&mdRecord );
|
|
|
|
if ( SUCCEEDED( hRes ))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
SetLastError( HRESULTTOWIN32( hRes ) );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
inline
|
|
BOOL
|
|
MB::GetData(
|
|
const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
DWORD dwDataType,
|
|
VOID * pvData,
|
|
DWORD * pcbData,
|
|
DWORD dwFlags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieves a metadata property on an openned metabase
|
|
|
|
Arguments:
|
|
|
|
pszPath - Path to set data on
|
|
dwPropID - Metabase property ID
|
|
dwUserType - User type for this property
|
|
dwDataType - Type of data being set (dword, string etc)
|
|
pvData - Pointer to data
|
|
pcbData - Size of pvData, receives size of object
|
|
dwFlags - Inheritance flags
|
|
|
|
Return:
|
|
|
|
TRUE if success, FALSE on error, (call GetLastError())
|
|
|
|
--*/
|
|
{
|
|
METADATA_RECORD mdRecord;
|
|
HRESULT hRes;
|
|
DWORD dwRequiredLen;
|
|
|
|
mdRecord.dwMDIdentifier = dwPropID;
|
|
mdRecord.dwMDAttributes = dwFlags;
|
|
mdRecord.dwMDUserType = dwUserType;
|
|
mdRecord.dwMDDataType = dwDataType;
|
|
mdRecord.dwMDDataLen = *pcbData;
|
|
mdRecord.pbMDData = (PBYTE) pvData;
|
|
|
|
hRes = _pMBCom->GetData( _hMB, pszPath,
|
|
&mdRecord,
|
|
&dwRequiredLen );
|
|
|
|
if ( SUCCEEDED( hRes ))
|
|
{
|
|
*pcbData = mdRecord.dwMDDataLen;
|
|
return TRUE;
|
|
}
|
|
|
|
*pcbData = dwRequiredLen;
|
|
|
|
SetLastError( HRESULTTOWIN32( hRes ) );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef O
|
|
inline
|
|
BOOL MB::GetAll(
|
|
const TCHAR * pszPath,
|
|
DWORD dwFlags,
|
|
DWORD dwUserType,
|
|
BUFFER * pBuff,
|
|
DWORD * pcRecords,
|
|
DWORD * pdwDataSetNumber
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieves all the metabase properties on this path of the request type
|
|
|
|
Arguments:
|
|
|
|
pszPath - Path to set data on
|
|
dwFlags - Inerhitance flags
|
|
dwPropID - Metabase property ID
|
|
dwUserType - User type for this property
|
|
dwDataType - Type of data being set (dword, string etc)
|
|
pvData - Pointer to data
|
|
pcbData - Size of pvData, receives size of object
|
|
dwFlags - Inheritance flags
|
|
|
|
Return:
|
|
|
|
TRUE if success, FALSE on error, (call GetLastError())
|
|
|
|
--*/
|
|
{
|
|
DWORD RequiredSize;
|
|
HRESULT hRes;
|
|
|
|
TryAgain:
|
|
|
|
hRes = _pMBCom->GetAllData( _hMB,
|
|
(unsigned TCHAR *)pszPath,
|
|
dwFlags,
|
|
dwUserType,
|
|
ALL_METADATA,
|
|
pcRecords,
|
|
pdwDataSetNumber,
|
|
pBuff->QuerySize(),
|
|
(PBYTE)pBuff->QueryPtr(),
|
|
&RequiredSize
|
|
);
|
|
|
|
// See if we got it, and if we failed because of lack of buffer space
|
|
// try again.
|
|
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// Some sort of error, most likely not enough buffer space. Keep
|
|
// trying until we get a non-fatal error.
|
|
|
|
if (HRESULT_FACILITY(hRes) == FACILITY_WIN32 &&
|
|
HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER) {
|
|
|
|
// Not enough buffer space. RequiredSize contains the amount
|
|
// the metabase thinks we need.
|
|
|
|
if ( !pBuff->Resize(RequiredSize) ) {
|
|
|
|
// Not enough memory to resize.
|
|
return FALSE;
|
|
}
|
|
|
|
goto TryAgain;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
inline
|
|
BOOL MB::GetDataSetNumber(
|
|
const TCHAR * pszPath,
|
|
DWORD * pdwDataSetNumber
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieves the data set number and size of the data from the
|
|
metabase.
|
|
|
|
Arguments:
|
|
|
|
pszPath - Path to set data on
|
|
pdwDataSetNumber - Where to return the data set number.
|
|
|
|
Return:
|
|
|
|
TRUE if success, FALSE on error, (call GetLastError())
|
|
|
|
--*/
|
|
{
|
|
HRESULT hRes;
|
|
|
|
//
|
|
// We allow _hMB to be null (root handle) for this API (though technically
|
|
// all the APIs allow the metabase handle to be null)
|
|
//
|
|
|
|
hRes = _pMBCom->GetDataSetNumber( _hMB, pszPath, pdwDataSetNumber );
|
|
|
|
return SUCCEEDED(hRes);
|
|
}
|
|
|
|
#ifdef O
|
|
inline
|
|
BOOL
|
|
MB::GetStr(
|
|
const TCHAR * pszPath,
|
|
DWORD dwPropID,
|
|
DWORD dwUserType,
|
|
STR * pstrValue,
|
|
DWORD dwFlags,
|
|
const TCHAR * pszDefault
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieves the string from the metabase. If the value wasn't found and
|
|
a default is supplied, then the default value is copied to the string.
|
|
|
|
Arguments:
|
|
|
|
pszPath - Path to get data on
|
|
dwPropID - property id to retrieve
|
|
dwUserType - User type for this property
|
|
pstrValue - string that receives the value
|
|
dwFlags - Metabase flags
|
|
pszDefault - Default value to use if the string isn't found, NULL
|
|
for no default value (i.e., will return an error).
|
|
|
|
Return:
|
|
|
|
TRUE if success, FALSE on error, (call GetLastError())
|
|
|
|
--*/
|
|
{
|
|
DWORD cbSize = pstrValue->QuerySize();
|
|
|
|
TryAgain:
|
|
|
|
if ( !GetData( pszPath,
|
|
dwPropID,
|
|
dwUserType,
|
|
STRING_METADATA,
|
|
pstrValue->QueryStr(),
|
|
&cbSize,
|
|
dwFlags ))
|
|
{
|
|
if ( GetLastError() == MD_ERROR_DATA_NOT_FOUND )
|
|
{
|
|
if ( pszDefault != NULL )
|
|
{
|
|
return pstrValue->Copy( pszDefault );
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
else if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
|
|
pstrValue->Resize( cbSize ) )
|
|
{
|
|
goto TryAgain;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
pstrValue->SetLen( cbSize );
|
|
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
|
|
#endif // _MB_HXX_
|