|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: bnreg.cpp
//
//--------------------------------------------------------------------------
//
// BNREG.CPP: Use Registry to store persistent BN properties, etc.
//
#include <windows.h>
#include "bnreg.h"
#include "gmobj.h"
//
// String constants for Registry handling
//
static const SZC szcBn = "Software\\Microsoft\\DTAS\\BeliefNetworks"; static const SZC szcPropertyTypes = "PropertyTypes"; static const SZC szcFlags = "Flags"; static const SZC szcComment = "Comment"; static const SZC szcChoices = "Choices"; static const SZC szcCount = "Count";
BNREG :: BNREG () { OpenOrCreate( HKEY_LOCAL_MACHINE, _rkBn, szcBn ); }
BNREG :: ~ BNREG () { }
void BNREG :: OpenOrCreate ( HKEY hk, REGKEY & rk, SZC szcKeyName ) { LONG ec; ec = rk.Open( hk, szcKeyName ); if ( ec != ERROR_SUCCESS ) ec = rk.Create( hk, szcKeyName ); if ( ec != ERROR_SUCCESS ) throw GMException( EC_REGISTRY_ACCESS, "unable to open or create key" ); }
//
// Store the property types from this network into the Registry.
// If 'bStandard', force property types to be marked as "standard".
//
void BNREG :: StorePropertyTypes ( MBNET & mbnet, bool bStandard ) { REGKEY rkPtype; assert( _rkBn.HKey() != NULL ); OpenOrCreate( _rkBn, rkPtype, szcPropertyTypes );
MBNET::ITER mbnit( mbnet, GOBJMBN::EBNO_PROP_TYPE ); GOBJMBN * pgmobj; SZC szcName; for ( ; pgmobj = *mbnit ; ++mbnit ) { ZSREF zsrName = mbnit.ZsrCurrent(); GOBJPROPTYPE * pbnpt; DynCastThrow( pgmobj, pbnpt ); // Get the name of the property type
szcName = pbnpt->ZsrefName(); // See if it already exists
LONG fPropType = FPropType( szcName ); if ( fPropType >= 0 ) { // Property type already exists; guarantee that its "standard"
// flag is consistent
bool bOldStandard = (fPropType & fPropStandard) > 0; // It's standard if it was already or is now being forced to be
bool bNewStandard = (pbnpt->FPropType() & fPropStandard) > 0 || bStandard; if ( bNewStandard ^ bOldStandard ) throw GMException( EC_REGISTRY_ACCESS, "conflict between standard and non-standard property types" );
// Delete any older version of this property type
rkPtype.RecurseDeleteKey( szcName ); } CreatePropType( rkPtype, szcName, *pbnpt, bStandard ); } }
//
// Load the property types from the Registry into this network. If
// 'bStandard', load only the types marked "standard" if !bStandard,
// load only the types NOT so marked.
//
void BNREG :: LoadPropertyTypes ( MBNET & mbnet, bool bStandard ) { REGKEY rkPtype; assert( _rkBn.HKey() != NULL ); OpenOrCreate( _rkBn, rkPtype, szcPropertyTypes );
FILETIME time; TCHAR szBuffer[256]; DWORD dwSize = 256; ZSTR zsPt; DWORD dwKey = 0;
for (;;) { dwSize = 256; if ( RegEnumKeyEx(rkPtype, dwKey++, szBuffer, & dwSize, NULL, NULL, NULL, & time ) != ERROR_SUCCESS ) break;
zsPt = szBuffer; LONG fPropType = FPropType( zsPt ); ASSERT_THROW( fPropType >= 0, EC_REGISTRY_ACCESS, "registry property type load enumeration failure" );
// Load this type if appropriate
if ( ((fPropType & fPropStandard) > 0) == bStandard ) LoadPropertyType( mbnet, zsPt ); } }
// Load a single property type from the Registry into the network
void BNREG :: LoadPropertyType ( MBNET & mbnet, SZC szcPropTypeName ) { REGKEY rkPtype; assert( _rkBn.HKey() != NULL ); OpenOrCreate( _rkBn, rkPtype, szcPropertyTypes );
TCHAR szValue [2000]; DWORD dwCount; SZC szcError = NULL; GOBJPROPTYPE * pgobjPt = NULL;
do // false loop for error checking
{ // Check that the belief network doesn't already have such a beast
if ( mbnet.PgobjFind( szcPropTypeName ) != NULL ) { szcError = "duplicate property type addition attempt"; break; } REGKEY rkPt; if ( rkPt.Open( rkPtype, szcPropTypeName ) != ERROR_SUCCESS ) { szcError = "property type key open failure"; break; }
LONG fPropType = FPropType( szcPropTypeName ); if ( fPropType < 0 ) throw GMException( EC_REGISTRY_ACCESS, "property type flag query failure" );
// Create the new property type object
GOBJPROPTYPE * pgobjPt = new GOBJPROPTYPE; // Set its flags and mark it as "persistent" (imported)
pgobjPt->_fType = fPropType | fPropPersist;
// Get the comment string
dwCount = sizeof szValue; if ( rkPt.QueryValue( szValue, szcComment, & dwCount ) != ERROR_SUCCESS ) { szcError = "property type key value query failure"; break; } szValue[dwCount] = 0; pgobjPt->_zsrComment = mbnet.Mpsymtbl().intern( szValue );
// Is this a "choice" property type?
if ( fPropType & fPropChoice ) { REGKEY rkChoices; if ( rkChoices.Open( rkPt, szcChoices ) != ERROR_SUCCESS ) { szcError = "choices key missing for property type"; break; } // Get the "Count" value
if ( rkChoices.QueryValue( dwCount, szcCount ) != ERROR_SUCCESS ) { szcError = "failure to create choice count value"; break; } ZSTR zs; int cChoice = dwCount; for ( int i = 0; i < cChoice; i++ ) { zs.Format("%d",i); dwCount = sizeof szValue; if ( rkChoices.QueryValue( szValue, zs, & dwCount ) != ERROR_SUCCESS ) { szcError = "failure to query choice string"; break; } szValue[dwCount] = 0; pgobjPt->_vzsrChoice.push_back( mbnet.Mpsymtbl().intern( szValue ) ); } assert( i == cChoice ); }
if ( szcError ) break;
mbnet.AddElem( szcPropTypeName, pgobjPt );
} while ( false );
if ( szcError ) { delete pgobjPt; throw GMException( EC_REGISTRY_ACCESS, szcError ); } }
// Remove all property types from the Registry
void BNREG :: DeleteAllPropertyTypes () { assert( _rkBn.HKey() != NULL ); _rkBn.RecurseDeleteKey( szcPropertyTypes ); }
// Return the value of the property type flags or -1 if open failure
LONG BNREG :: FPropType ( SZC szcPropType ) { REGKEY rkPtype; assert( _rkBn.HKey() != NULL ); if ( rkPtype.Open( _rkBn, szcPropertyTypes ) != ERROR_SUCCESS ) return -1; REGKEY rkPt; if ( rkPt.Open( rkPtype, szcPropType ) != ERROR_SUCCESS ) return -1;
DWORD dwValue; if ( rkPt.QueryValue( dwValue, szcFlags ) != ERROR_SUCCESS ) return -1; return dwValue; }
void BNREG :: CreatePropType ( REGKEY & rkParent, SZC szcPropType, GOBJPROPTYPE & bnpt, bool bStandard ) { REGKEY rkPt; LONG ec = rkPt.Create( rkParent, szcPropType ); if ( ec != ERROR_SUCCESS ) throw GMException( EC_REGISTRY_ACCESS, "property type key creation failure" );
bool bOK = true;
// Add the "flags" value, clearing the "persistent" flag
DWORD dwFlags = bnpt.FPropType(); dwFlags &= ~ fPropPersist; if ( bStandard ) dwFlags |= fPropStandard; bOK &= (rkPt.SetValue( dwFlags, szcFlags ) == ERROR_SUCCESS);
// Add the "comment" string
bOK &= (rkPt.SetValue( bnpt.ZsrComment(), szcComment ) == ERROR_SUCCESS);
// Add the choices, if applicable
if ( bnpt.VzsrChoice().size() > 0 ) { // Add the "Choices" subkey
REGKEY rkChoice; ZSTR zs; int cChoice = bnpt.VzsrChoice().size(); ec = rkChoice.Create( rkPt, szcChoices ); if ( ec != ERROR_SUCCESS ) throw GMException( EC_REGISTRY_ACCESS, "property type choices key creation failure" );
bOK &= (rkChoice.SetValue( cChoice, szcCount ) == ERROR_SUCCESS); for ( int i = 0; i < cChoice; i++ ) { zs.Format("%d",i); bOK &= (rkChoice.SetValue( bnpt.VzsrChoice()[i], zs ) == ERROR_SUCCESS); } }
if ( ! bOK ) throw GMException( EC_REGISTRY_ACCESS, "property type value addition failure" ); }
|