Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

297 lines
7.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: bnreg.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // BNREG.CPP: Use Registry to store persistent BN properties, etc.
  12. //
  13. #include <windows.h>
  14. #include "bnreg.h"
  15. #include "gmobj.h"
  16. //
  17. // String constants for Registry handling
  18. //
  19. static const SZC szcBn = "Software\\Microsoft\\DTAS\\BeliefNetworks";
  20. static const SZC szcPropertyTypes = "PropertyTypes";
  21. static const SZC szcFlags = "Flags";
  22. static const SZC szcComment = "Comment";
  23. static const SZC szcChoices = "Choices";
  24. static const SZC szcCount = "Count";
  25. BNREG :: BNREG ()
  26. {
  27. OpenOrCreate( HKEY_LOCAL_MACHINE, _rkBn, szcBn );
  28. }
  29. BNREG :: ~ BNREG ()
  30. {
  31. }
  32. void BNREG :: OpenOrCreate ( HKEY hk, REGKEY & rk, SZC szcKeyName )
  33. {
  34. LONG ec;
  35. ec = rk.Open( hk, szcKeyName );
  36. if ( ec != ERROR_SUCCESS )
  37. ec = rk.Create( hk, szcKeyName );
  38. if ( ec != ERROR_SUCCESS )
  39. throw GMException( EC_REGISTRY_ACCESS, "unable to open or create key" );
  40. }
  41. //
  42. // Store the property types from this network into the Registry.
  43. // If 'bStandard', force property types to be marked as "standard".
  44. //
  45. void BNREG :: StorePropertyTypes ( MBNET & mbnet, bool bStandard )
  46. {
  47. REGKEY rkPtype;
  48. assert( _rkBn.HKey() != NULL );
  49. OpenOrCreate( _rkBn, rkPtype, szcPropertyTypes );
  50. MBNET::ITER mbnit( mbnet, GOBJMBN::EBNO_PROP_TYPE );
  51. GOBJMBN * pgmobj;
  52. SZC szcName;
  53. for ( ; pgmobj = *mbnit ; ++mbnit )
  54. {
  55. ZSREF zsrName = mbnit.ZsrCurrent();
  56. GOBJPROPTYPE * pbnpt;
  57. DynCastThrow( pgmobj, pbnpt );
  58. // Get the name of the property type
  59. szcName = pbnpt->ZsrefName();
  60. // See if it already exists
  61. LONG fPropType = FPropType( szcName );
  62. if ( fPropType >= 0 )
  63. {
  64. // Property type already exists; guarantee that its "standard"
  65. // flag is consistent
  66. bool bOldStandard = (fPropType & fPropStandard) > 0;
  67. // It's standard if it was already or is now being forced to be
  68. bool bNewStandard = (pbnpt->FPropType() & fPropStandard) > 0 || bStandard;
  69. if ( bNewStandard ^ bOldStandard )
  70. throw GMException( EC_REGISTRY_ACCESS,
  71. "conflict between standard and non-standard property types" );
  72. // Delete any older version of this property type
  73. rkPtype.RecurseDeleteKey( szcName );
  74. }
  75. CreatePropType( rkPtype, szcName, *pbnpt, bStandard );
  76. }
  77. }
  78. //
  79. // Load the property types from the Registry into this network. If
  80. // 'bStandard', load only the types marked "standard" if !bStandard,
  81. // load only the types NOT so marked.
  82. //
  83. void BNREG :: LoadPropertyTypes ( MBNET & mbnet, bool bStandard )
  84. {
  85. REGKEY rkPtype;
  86. assert( _rkBn.HKey() != NULL );
  87. OpenOrCreate( _rkBn, rkPtype, szcPropertyTypes );
  88. FILETIME time;
  89. TCHAR szBuffer[256];
  90. DWORD dwSize = 256;
  91. ZSTR zsPt;
  92. DWORD dwKey = 0;
  93. for (;;)
  94. {
  95. dwSize = 256;
  96. if ( RegEnumKeyEx(rkPtype,
  97. dwKey++,
  98. szBuffer,
  99. & dwSize,
  100. NULL,
  101. NULL,
  102. NULL,
  103. & time ) != ERROR_SUCCESS )
  104. break;
  105. zsPt = szBuffer;
  106. LONG fPropType = FPropType( zsPt );
  107. ASSERT_THROW( fPropType >= 0,
  108. EC_REGISTRY_ACCESS,
  109. "registry property type load enumeration failure" );
  110. // Load this type if appropriate
  111. if ( ((fPropType & fPropStandard) > 0) == bStandard )
  112. LoadPropertyType( mbnet, zsPt );
  113. }
  114. }
  115. // Load a single property type from the Registry into the network
  116. void BNREG :: LoadPropertyType ( MBNET & mbnet, SZC szcPropTypeName )
  117. {
  118. REGKEY rkPtype;
  119. assert( _rkBn.HKey() != NULL );
  120. OpenOrCreate( _rkBn, rkPtype, szcPropertyTypes );
  121. TCHAR szValue [2000];
  122. DWORD dwCount;
  123. SZC szcError = NULL;
  124. GOBJPROPTYPE * pgobjPt = NULL;
  125. do // false loop for error checking
  126. {
  127. // Check that the belief network doesn't already have such a beast
  128. if ( mbnet.PgobjFind( szcPropTypeName ) != NULL )
  129. {
  130. szcError = "duplicate property type addition attempt";
  131. break;
  132. }
  133. REGKEY rkPt;
  134. if ( rkPt.Open( rkPtype, szcPropTypeName ) != ERROR_SUCCESS )
  135. {
  136. szcError = "property type key open failure";
  137. break;
  138. }
  139. LONG fPropType = FPropType( szcPropTypeName );
  140. if ( fPropType < 0 )
  141. throw GMException( EC_REGISTRY_ACCESS,
  142. "property type flag query failure" );
  143. // Create the new property type object
  144. GOBJPROPTYPE * pgobjPt = new GOBJPROPTYPE;
  145. // Set its flags and mark it as "persistent" (imported)
  146. pgobjPt->_fType = fPropType | fPropPersist;
  147. // Get the comment string
  148. dwCount = sizeof szValue;
  149. if ( rkPt.QueryValue( szValue, szcComment, & dwCount ) != ERROR_SUCCESS )
  150. {
  151. szcError = "property type key value query failure";
  152. break;
  153. }
  154. szValue[dwCount] = 0;
  155. pgobjPt->_zsrComment = mbnet.Mpsymtbl().intern( szValue );
  156. // Is this a "choice" property type?
  157. if ( fPropType & fPropChoice )
  158. {
  159. REGKEY rkChoices;
  160. if ( rkChoices.Open( rkPt, szcChoices ) != ERROR_SUCCESS )
  161. {
  162. szcError = "choices key missing for property type";
  163. break;
  164. }
  165. // Get the "Count" value
  166. if ( rkChoices.QueryValue( dwCount, szcCount ) != ERROR_SUCCESS )
  167. {
  168. szcError = "failure to create choice count value";
  169. break;
  170. }
  171. ZSTR zs;
  172. int cChoice = dwCount;
  173. for ( int i = 0; i < cChoice; i++ )
  174. {
  175. zs.Format("%d",i);
  176. dwCount = sizeof szValue;
  177. if ( rkChoices.QueryValue( szValue, zs, & dwCount ) != ERROR_SUCCESS )
  178. {
  179. szcError = "failure to query choice string";
  180. break;
  181. }
  182. szValue[dwCount] = 0;
  183. pgobjPt->_vzsrChoice.push_back( mbnet.Mpsymtbl().intern( szValue ) );
  184. }
  185. assert( i == cChoice );
  186. }
  187. if ( szcError )
  188. break;
  189. mbnet.AddElem( szcPropTypeName, pgobjPt );
  190. } while ( false );
  191. if ( szcError )
  192. {
  193. delete pgobjPt;
  194. throw GMException( EC_REGISTRY_ACCESS, szcError );
  195. }
  196. }
  197. // Remove all property types from the Registry
  198. void BNREG :: DeleteAllPropertyTypes ()
  199. {
  200. assert( _rkBn.HKey() != NULL );
  201. _rkBn.RecurseDeleteKey( szcPropertyTypes );
  202. }
  203. // Return the value of the property type flags or -1 if open failure
  204. LONG BNREG :: FPropType ( SZC szcPropType )
  205. {
  206. REGKEY rkPtype;
  207. assert( _rkBn.HKey() != NULL );
  208. if ( rkPtype.Open( _rkBn, szcPropertyTypes ) != ERROR_SUCCESS )
  209. return -1;
  210. REGKEY rkPt;
  211. if ( rkPt.Open( rkPtype, szcPropType ) != ERROR_SUCCESS )
  212. return -1;
  213. DWORD dwValue;
  214. if ( rkPt.QueryValue( dwValue, szcFlags ) != ERROR_SUCCESS )
  215. return -1;
  216. return dwValue;
  217. }
  218. void BNREG :: CreatePropType (
  219. REGKEY & rkParent,
  220. SZC szcPropType,
  221. GOBJPROPTYPE & bnpt,
  222. bool bStandard )
  223. {
  224. REGKEY rkPt;
  225. LONG ec = rkPt.Create( rkParent, szcPropType );
  226. if ( ec != ERROR_SUCCESS )
  227. throw GMException( EC_REGISTRY_ACCESS,
  228. "property type key creation failure" );
  229. bool bOK = true;
  230. // Add the "flags" value, clearing the "persistent" flag
  231. DWORD dwFlags = bnpt.FPropType();
  232. dwFlags &= ~ fPropPersist;
  233. if ( bStandard )
  234. dwFlags |= fPropStandard;
  235. bOK &= (rkPt.SetValue( dwFlags, szcFlags ) == ERROR_SUCCESS);
  236. // Add the "comment" string
  237. bOK &= (rkPt.SetValue( bnpt.ZsrComment(), szcComment ) == ERROR_SUCCESS);
  238. // Add the choices, if applicable
  239. if ( bnpt.VzsrChoice().size() > 0 )
  240. {
  241. // Add the "Choices" subkey
  242. REGKEY rkChoice;
  243. ZSTR zs;
  244. int cChoice = bnpt.VzsrChoice().size();
  245. ec = rkChoice.Create( rkPt, szcChoices );
  246. if ( ec != ERROR_SUCCESS )
  247. throw GMException( EC_REGISTRY_ACCESS,
  248. "property type choices key creation failure" );
  249. bOK &= (rkChoice.SetValue( cChoice, szcCount ) == ERROR_SUCCESS);
  250. for ( int i = 0; i < cChoice; i++ )
  251. {
  252. zs.Format("%d",i);
  253. bOK &= (rkChoice.SetValue( bnpt.VzsrChoice()[i], zs ) == ERROR_SUCCESS);
  254. }
  255. }
  256. if ( ! bOK )
  257. throw GMException( EC_REGISTRY_ACCESS,
  258. "property type value addition failure" );
  259. }