|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
metautil.cpp
Abstract:
Useful functions for dealing with the metabase
Author:
Magnus Hedlund (MagnusH) --
Revision History:
--*/
#include "stdafx.h"
#include "smtpcmn.h"
#include "cmultisz.h"
#include "oleutil.h"
#include "metautil.h"
#include "metakey.h"
// Metabase property manipulation:
BOOL StdGetMetabaseProp ( CMetabaseKey * pMB, DWORD dwID, BOOL fDefault, BOOL * pfOut, LPCWSTR wszPath, DWORD dwUserType, DWORD dwFlags ) { TraceQuietEnter ( "StdGetMetabaseProp<BOOL>" );
HRESULT hr; DWORD dwTemp;
hr = pMB->GetDword ( wszPath, dwID, &dwTemp, dwFlags, dwUserType ); if ( hr == MD_ERROR_DATA_NOT_FOUND ) { // Couldn't find property, use defaults.
DebugTraceX ( 0, "Using default for ID: %d", dwID ); dwTemp = fDefault; hr = NOERROR; } BAIL_ON_FAILURE(hr);
*pfOut = dwTemp;
Exit: if ( FAILED(hr) ) { ErrorTraceX ( 0, "Failed to get metabase property ID: %d, Error: %x", dwID, hr ); SetLastError ( HRESULTTOWIN32 ( hr ) ); }
return SUCCEEDED(hr); }
BOOL StdGetMetabaseProp ( CMetabaseKey * pMB, DWORD dwID, DWORD dwDefault, DWORD * pdwOut, LPCWSTR wszPath, DWORD dwUserType, DWORD dwFlags ) { TraceQuietEnter ( "StdGetMetabaseProp<DWORD>" );
DWORD dwTemp; HRESULT hr;
hr = pMB->GetDword ( wszPath, dwID, &dwTemp, dwFlags, dwUserType ); if ( hr == MD_ERROR_DATA_NOT_FOUND ) { // Couldn't find property, use defaults.
DebugTraceX ( 0, "Using default for ID: %d", dwID ); dwTemp = dwDefault; hr = NOERROR; } BAIL_ON_FAILURE(hr);
*pdwOut = dwTemp;
Exit: if ( FAILED(hr) ) { ErrorTraceX ( 0, "Failed to get metabase property ID: %d, Error: %x", dwID, hr ); SetLastError ( HRESULTTOWIN32 ( hr ) ); }
return SUCCEEDED(hr); }
BOOL StdGetMetabaseProp ( CMetabaseKey * pMB, DWORD dwID, LPCWSTR wszDefault, BSTR * pstrOut, LPCWSTR wszPath, DWORD dwUserType, DWORD dwFlags ) { TraceQuietEnter ( "StdGetMetabaseProp <BSTR>" );
HRESULT hr = NOERROR; BSTR strNew = NULL; DWORD cbRequired = 0; DWORD cchRequired = 0; BOOL fUseDefault = FALSE;
// Get the length of the string to retrieve:
hr = pMB->GetDataSize ( wszPath, dwID, STRING_METADATA, &cbRequired, dwFlags, dwUserType ); cchRequired = cbRequired / sizeof ( WCHAR );
// Is the value there?
if ( hr == MD_ERROR_DATA_NOT_FOUND ) {
// No, so use the default that was passed in.
DebugTraceX ( 0, "Using default for ID: %d", dwID );
fUseDefault = TRUE; hr = NOERROR; } BAIL_ON_FAILURE(hr);
if ( !fUseDefault ) {
strNew = ::SysAllocStringLen ( NULL, cbRequired ); if ( !strNew ) { FatalTrace ( 0, "Out of memory" ); BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY); }
// Get the metabase string:
hr = pMB->GetString ( wszPath, dwID, strNew, cbRequired, dwFlags, dwUserType ); BAIL_ON_FAILURE(hr); }
if ( fUseDefault ) { // Use the default:
DebugTraceX ( 0, "Using default for ID: %d", dwID );
strNew = ::SysAllocString ( wszDefault ); if ( !strNew ) { FatalTrace ( 0, "Out of memory" ); BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY); } }
SAFE_FREE_BSTR ( *pstrOut ); *pstrOut = strNew;
Exit: if ( FAILED(hr) ) { ErrorTraceX ( 0, "Failed to get metabase property ID: %d, Error: %x", dwID, hr ); SetLastError ( HRESULTTOWIN32 ( hr ) ); } return SUCCEEDED(hr); }
BOOL StdGetMetabaseProp ( CMetabaseKey * pMB, DWORD dwID, LPCWSTR mszDefault, CMultiSz * pmszOut, LPCWSTR wszPath, DWORD dwUserType, DWORD dwFlags ) { TraceQuietEnter ( "StdGetMetabaseProp <CMultiSz>" );
HRESULT hr = NOERROR; BSTR strNew = NULL; DWORD cbRequired = 0; DWORD cchRequired = 0; BOOL fUseDefault = FALSE; LPWSTR msz = NULL;
// Get the length of the string to retrieve:
hr = pMB->GetDataSize ( wszPath, dwID, MULTISZ_METADATA, &cbRequired, dwFlags, dwUserType ); cchRequired = cbRequired / sizeof ( WCHAR );
// Is the value there?
if ( hr == MD_ERROR_DATA_NOT_FOUND ) {
// No, so use the default that was passed in.
DebugTraceX ( 0, "Using default for ID: %d", dwID );
fUseDefault = TRUE; hr = NOERROR; } BAIL_ON_FAILURE(hr);
if ( !fUseDefault ) {
msz = new WCHAR [ cchRequired ]; if ( !msz ) { FatalTrace ( 0, "Out of memory" ); BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY); }
// Get the metabase string:
hr = pMB->GetData ( wszPath, dwID, dwUserType, MULTISZ_METADATA, msz, &cbRequired, dwFlags ); BAIL_ON_FAILURE(hr);
*pmszOut = msz; }
if ( fUseDefault ) { // Use the default:
DebugTraceX ( 0, "Using default for ID: %d", dwID );
*pmszOut = mszDefault; }
if ( !*pmszOut ) { BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY); }
Exit: delete msz;
if ( FAILED(hr) ) { ErrorTraceX ( 0, "Failed to get metabase property ID: %d, Error: %x", dwID, hr ); SetLastError ( HRESULTTOWIN32 ( hr ) ); } return SUCCEEDED(hr); }
BOOL StdPutMetabaseProp ( CMetabaseKey * pMB, DWORD dwID, BOOL fValue, LPCWSTR wszPath, DWORD dwUserType, DWORD dwFlags ) { TraceQuietEnter ( "StdPutMetabaseProp <BOOL>" );
HRESULT hr;
hr = pMB->SetDword ( wszPath, dwID, fValue, dwFlags, dwUserType );
if ( FAILED(hr) ) { ErrorTraceX ( 0, "Failed to put metabase property ID: %d, Error: %x", dwID, hr ); SetLastError ( HRESULTTOWIN32 ( hr ) ); }
return SUCCEEDED(hr); }
BOOL StdPutMetabaseProp ( CMetabaseKey * pMB, DWORD dwID, DWORD dwValue, LPCWSTR wszPath, DWORD dwUserType, DWORD dwFlags ) { TraceQuietEnter ( "StdPutMetabaseProp <DWORD>" );
HRESULT hr;
hr = pMB->SetDword ( wszPath, dwID, dwValue, dwFlags, dwUserType );
if ( FAILED(hr) ) { ErrorTraceX ( 0, "Failed to put metabase property ID: %d, Error: %x", dwID, hr ); SetLastError ( HRESULTTOWIN32 ( hr ) ); }
return SUCCEEDED(hr); }
BOOL StdPutMetabaseProp ( CMetabaseKey * pMB, DWORD dwID, BSTR strValue, LPCWSTR wszPath, DWORD dwUserType, DWORD dwFlags ) { TraceQuietEnter ( "StdPutMetabaseProp <BSTR>" );
_ASSERT ( strValue );
HRESULT hr;
if ( !strValue ) { // Just skip it, but log the trace.
FatalTrace ( 0, "strValue should not be NULL here" ); return TRUE; }
hr = pMB->SetString ( wszPath, dwID, strValue, dwFlags, dwUserType ); BAIL_ON_FAILURE (hr);
Exit: if ( FAILED(hr) ) { ErrorTraceX ( 0, "Failed to put metabase property ID: %d, Error: %x", dwID, hr ); SetLastError ( HRESULTTOWIN32 ( hr ) ); }
return SUCCEEDED(hr); }
BOOL StdPutMetabaseProp ( CMetabaseKey * pMB, DWORD dwID, CMultiSz * pmszValue, LPCWSTR wszPath, DWORD dwUserType, DWORD dwFlags ) { TraceQuietEnter ( "StdPutMetabaseProp <BSTR>" );
_ASSERT ( pmszValue );
if ( !*pmszValue ) { // Just skip it, but log the trace.
FatalTrace ( 0, "strValue should not be NULL here" ); return TRUE; }
HRESULT hr; DWORD cbMultiSz; LPCWSTR wszValue;
cbMultiSz = pmszValue->SizeInBytes (); wszValue = *pmszValue;
hr = pMB->SetData ( wszPath, dwID, dwUserType, MULTISZ_METADATA, (void *) wszValue, cbMultiSz, dwFlags ); BAIL_ON_FAILURE (hr);
Exit: if ( FAILED(hr) ) { ErrorTraceX ( 0, "Failed to put metabase property ID: %d, Error: %x", dwID, hr ); SetLastError ( HRESULTTOWIN32 ( hr ) ); }
return SUCCEEDED(hr); }
BOOL HasKeyChanged ( IMSAdminBase * pMetabase, METADATA_HANDLE hKey, const FILETIME * pftLastChanged, LPCWSTR wszSubKey ) { TraceFunctEnter ( "HasKeyChanged" );
FILETIME ftNew; HRESULT hr = NOERROR; BOOL fResult = FALSE;
if ( pftLastChanged->dwHighDateTime == 0 && pftLastChanged->dwLowDateTime == 0 ) { ErrorTrace ( 0, "Last changed time is NULL" );
// No setting, so say it hasn't changed:
goto Exit; }
hr = pMetabase->GetLastChangeTime ( hKey, wszSubKey, &ftNew, FALSE ); if ( FAILED (hr) ) { ErrorTrace ( 0, "Failed to get last change time: %x", hr );
// This is an unexpected error. Ignore it.
goto Exit; }
// Has the metabase been changed since last time?
// Time can't go backwards:
_ASSERT ( ftNew.dwHighDateTime >= pftLastChanged->dwHighDateTime ); _ASSERT ( ftNew.dwLowDateTime >= pftLastChanged->dwLowDateTime || ftNew.dwHighDateTime > pftLastChanged->dwHighDateTime );
if ( ftNew.dwHighDateTime != pftLastChanged->dwHighDateTime || ftNew.dwLowDateTime != pftLastChanged->dwLowDateTime ) {
fResult = TRUE; }
Exit: TraceFunctLeave (); return FALSE; }
BOOL IsValidIntegerSubKey ( LPCWSTR wszSubKey ) { TraceQuietEnter ( "IsValidIntegerSubKey" );
WCHAR wszIntegerKey [ METADATA_MAX_NAME_LEN ]; DWORD dwItemValue;
dwItemValue = _wtoi ( wszSubKey ); wsprintf ( wszIntegerKey, _T("%d"), dwItemValue );
// If the key is nonzero AND
// The key is just the itoa value of the number:
if ( dwItemValue != 0 && lstrcmp ( wszIntegerKey, wszSubKey ) == 0 ) {
return TRUE; } else { return FALSE; } }
|