Leaked source code of windows server 2003
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.

1590 lines
47 KiB

  1. using System;
  2. using System.Collections;
  3. using System.Data;
  4. using System.Data.SqlClient;
  5. using System.Diagnostics;
  6. using System.Runtime.InteropServices;
  7. using System.Security.Principal;
  8. using System.Threading;
  9. using Microsoft.Win32;
  10. namespace UDDI
  11. {
  12. /// ****************************************************************
  13. /// public class Config
  14. /// ----------------------------------------------------------------
  15. /// <summary>
  16. /// Manages configuration settings for UDDI.
  17. /// </summary>
  18. /// ----------------------------------------------------------------
  19. /// <remarks>
  20. /// The configuration table is of very high importance, so if
  21. /// we fail to retrieve the configuration settings we'll mark
  22. /// the table as being invalid by setting it to NULL. Any
  23. /// attempt to retrieve a setting while the table is in this
  24. /// invalid state will result in an exception.
  25. /// </remarks>
  26. /// ****************************************************************
  27. ///
  28. //
  29. // TODO: Get and Set static methods should check the IsValid property through a
  30. // common piece of code method. This would avoid a significant
  31. // amount of code bload in the try/catch blocks.
  32. //
  33. public class Config
  34. {
  35. private const string registryRoot = @"SOFTWARE\Microsoft\UDDI";
  36. private static Hashtable settings = null;
  37. private static ReaderWriterLock readWriteLock = new ReaderWriterLock();
  38. private static Thread monitor = null;
  39. private static WindowsIdentity identity = null;
  40. public static Exception LastError = null;
  41. public delegate void ConfigChangeHandler();
  42. public static event ConfigChangeHandler ConfigChange;
  43. /// ****************************************************************
  44. /// private Config
  45. /// ----------------------------------------------------------------
  46. /// <summary>
  47. /// Constructor.
  48. /// </summary>
  49. /// ****************************************************************
  50. ///
  51. static Config()
  52. {
  53. //
  54. // 730294 - Never throw exceptions out of this static initializer
  55. //
  56. try
  57. {
  58. System.Diagnostics.Debug.Write( "INFO CONF Configuration manager starting (thread="
  59. + Thread.CurrentThread.GetHashCode().ToString()
  60. + ", user='" + WindowsIdentity.GetCurrent().Name + "')\r\n" );
  61. //
  62. // Initialize the settings collection.
  63. //
  64. Refresh();
  65. //
  66. // Verify that the version of the database that we are using is compatible.
  67. //
  68. string versionRegKeyName = "Setup.WebServer.DBSchemaVersion";
  69. //
  70. // This key will not exist if only the DB was installed on this machine. In that case,
  71. // default to the DbServer.DBSchemaVersion setting.
  72. //
  73. if( false == Config.SettingExists( versionRegKeyName ) )
  74. {
  75. versionRegKeyName = "Setup.DbServer.DBSchemaVersion";
  76. }
  77. UDDI.Diagnostics.Debug.VerifySetting( versionRegKeyName );
  78. UDDI.Diagnostics.Debug.VerifySetting( "Database.Version" );
  79. Version webServerVersion = new Version( Config.GetString( versionRegKeyName ) );
  80. Version dataBaseVersion = new Version( Config.GetString( "Database.Version" ) );
  81. //
  82. // The major and minor versions must be equal.
  83. //
  84. if( ( dataBaseVersion.Major != webServerVersion.Major ) ||
  85. ( dataBaseVersion.Minor != webServerVersion.Minor ) )
  86. {
  87. UDDIText errorMessage = new UDDIText( "UDDI_ERROR_SCHEMA_MISMATCH", webServerVersion.ToString(), dataBaseVersion.ToString() );
  88. throw new UDDIException( ErrorType.E_fatalError, errorMessage );
  89. }
  90. //
  91. // Install the registry change notification event handler. By
  92. // marking this thread as a background thread, the runtime will
  93. // automatically terminate it when all foreground threads have
  94. // finished processing. This eliminates the need for a separate
  95. // shutdown mechanism.
  96. //
  97. identity = WindowsIdentity.GetCurrent();
  98. monitor = new Thread( new ThreadStart( Registry_OnChange ) );
  99. monitor.IsBackground = true;
  100. monitor.Start();
  101. }
  102. catch( UDDIException uddiException )
  103. {
  104. //
  105. // Something has thrown a UDDIException; in this case, just make this exception the last error.
  106. //
  107. LastError = uddiException;
  108. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.ConfigError, uddiException.Message );
  109. //
  110. // If any exception occurs, invalidate ourselves.
  111. //
  112. InvalidateSelf();
  113. }
  114. catch( Exception )
  115. {
  116. //
  117. // Something has thrown a generic Exception; in this case, just create a generic UDDIException, and make
  118. // that the last error.
  119. //
  120. UDDIText errorMessage = new UDDIText( "UDDI_ERROR_CONFIG_COMMUNICATION_ERROR" );
  121. LastError = new UDDIException( ErrorType.E_fatalError, errorMessage );
  122. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.CannotReadSettings, errorMessage.GetText() );
  123. //
  124. // If any exception occurs, invalidate ourselves.
  125. //
  126. InvalidateSelf();
  127. }
  128. }
  129. /// ****************************************************************
  130. /// public CheckForUpdate [static]
  131. /// ----------------------------------------------------------------
  132. /// <summary>
  133. /// </summary>
  134. /// ****************************************************************
  135. ///
  136. public static void CheckForUpdate()
  137. {
  138. //
  139. // Throw an exception if we are not in a valid state.
  140. //
  141. CheckIsValid();
  142. SqlConnection conn = new SqlConnection( Config.GetString( "Database.WriterConnectionString" ) );
  143. SqlCommand cmd = new SqlCommand( "net_config_getLastChangeDate", conn );
  144. conn.Open();
  145. try
  146. {
  147. cmd.CommandType = CommandType.StoredProcedure;
  148. string lastChange = (string)cmd.ExecuteScalar();
  149. string lastRefresh = Config.GetString( "LastChange", "Jan 01 0001 12:00AM" );
  150. //
  151. // Compare the database last change configuration with our latest
  152. // config. If it differs, the database has changed and we need
  153. // to refresh. Use the minimum SQL date value if the config value
  154. // isn't available.
  155. //
  156. if( 0 != String.Compare( lastChange, lastRefresh ) )
  157. Config.Refresh();
  158. }
  159. finally
  160. {
  161. conn.Close();
  162. }
  163. }
  164. /// ****************************************************************
  165. /// public IsValid [static]
  166. /// ----------------------------------------------------------------
  167. /// <summary>
  168. /// Returns true if the config table is valid (i.e. has been
  169. /// properly initialized).
  170. /// </summary>
  171. /// ----------------------------------------------------------------
  172. /// <returns>
  173. /// True if the table is valid, false otherwise.
  174. /// </returns>
  175. /// ****************************************************************
  176. ///
  177. public static bool IsValid
  178. {
  179. get
  180. {
  181. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  182. try
  183. {
  184. return ( null != settings );
  185. }
  186. finally
  187. {
  188. readWriteLock.ReleaseReaderLock();
  189. }
  190. }
  191. }
  192. /// ****************************************************************
  193. /// private OperatorMessage [static]
  194. /// ----------------------------------------------------------------
  195. /// <summary>
  196. /// Writes a message to the event log.
  197. /// </summary>
  198. /// ----------------------------------------------------------------
  199. /// <param name="source">
  200. /// </param>
  201. ///
  202. /// <param name="message">
  203. /// </param>
  204. ///
  205. /// <param name="type">
  206. /// </param>
  207. ///
  208. /// <param name="eventID">
  209. /// </param>
  210. ///
  211. /// <param name="category">
  212. /// </param>
  213. /// ----------------------------------------------------------------
  214. /// <remarks>
  215. /// This is a safe version of the Debug.WriteEventLog method
  216. /// that prevents re-entrancy issues with the config.
  217. /// </remarks>
  218. /// ****************************************************************
  219. ///
  220. private static void OperatorMessage( UDDI.Diagnostics.OperatorMessageType messageType, string message )
  221. {
  222. try
  223. {
  224. EventLog.WriteEntry(
  225. "UDDIRuntime",
  226. message,
  227. EventLogEntryType.Error,
  228. (int)messageType,
  229. (int)UDDI.Diagnostics.CategoryType.Config );
  230. }
  231. catch( Exception )
  232. {
  233. Debug.Write(
  234. "ERRO CONF Error writing message to event log.\r\n\r\n"
  235. + "Message:\r\n" + message );
  236. }
  237. }
  238. /// ****************************************************************
  239. /// private AddSetting [static]
  240. /// ----------------------------------------------------------------
  241. /// <summary>
  242. /// Adds a configuration setting.
  243. /// </summary>
  244. /// ----------------------------------------------------------------
  245. /// <param name="key">
  246. /// The setting key.
  247. /// </param>
  248. ///
  249. /// <param name="data">
  250. /// The configuration setting data.
  251. /// </param>
  252. /// ----------------------------------------------------------------
  253. /// <remarks>
  254. /// This function assumes that the writer lock has already been
  255. /// obtained.
  256. /// </remarks>
  257. /// ****************************************************************
  258. ///
  259. private static void AddSetting( string key, object data )
  260. {
  261. //
  262. // Throw an exception if we are not in a valid state.
  263. //
  264. CheckIsValid();
  265. if( true == settings.ContainsKey( key ) )
  266. {
  267. Debug.Write( "INFO CONF Updating setting '" + key + "' value '" + data.ToString() + "'\r\n" );
  268. settings[ key ] = data;
  269. }
  270. else
  271. {
  272. Debug.Write( "INFO CONF Adding setting '" + key + "' value '" + data.ToString() + "'\r\n" );
  273. settings.Add( key, data );
  274. }
  275. }
  276. /// ****************************************************************
  277. /// private SetString [static]
  278. /// ----------------------------------------------------------------
  279. /// <summary>
  280. /// Adds a configuration setting to the database configuration table.
  281. /// </summary>
  282. /// ----------------------------------------------------------------
  283. /// <param name="name">
  284. /// The configuration setting name.
  285. /// </param>
  286. ///
  287. /// <param name="value">
  288. /// The value to store in the configuration.
  289. /// </param>
  290. /// ----------------------------------------------------------------
  291. /// <remarks>
  292. /// This function does not update the in memory cache.
  293. /// </remarks>
  294. /// ****************************************************************
  295. ///
  296. public static void SetString( string name, string value )
  297. {
  298. //
  299. // Throw an exception if we are not in a valid state.
  300. //
  301. CheckIsValid();
  302. //
  303. // Connect to the database and get the configuration settings.
  304. //
  305. SqlConnection conn = new SqlConnection( Config.GetString( "Database.WriterConnectionString" ) );
  306. SqlCommand cmd = new SqlCommand( "net_config_save", conn );
  307. conn.Open();
  308. try
  309. {
  310. cmd.CommandType = CommandType.StoredProcedure;
  311. cmd.Parameters.Add( new SqlParameter( "@configName", SqlDbType.NVarChar, UDDI.Constants.Lengths.ConfigName ) ).Direction = ParameterDirection.Input;
  312. cmd.Parameters.Add( new SqlParameter( "@configValue", SqlDbType.NVarChar, UDDI.Constants.Lengths.ConfigValue ) ).Direction = ParameterDirection.Input;
  313. cmd.Parameters[ "@configName" ].Value = name;
  314. cmd.Parameters[ "@configValue" ].Value = value;
  315. cmd.ExecuteNonQuery();
  316. }
  317. finally
  318. {
  319. conn.Close();
  320. }
  321. }
  322. public static int GetCount()
  323. {
  324. //
  325. // Throw an exception if we are not in a valid state.
  326. //
  327. CheckIsValid();
  328. int n = 0;
  329. //
  330. // Acquire the reader lock and read the setting.
  331. //
  332. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  333. try
  334. {
  335. n = settings.Count;
  336. }
  337. finally
  338. {
  339. readWriteLock.ReleaseReaderLock();
  340. }
  341. return n;
  342. }
  343. /// ****************************************************************
  344. /// private CopyTo [static]
  345. /// ----------------------------------------------------------------
  346. /// <summary>
  347. /// Adds a configuration setting.
  348. /// </summary>
  349. /// ----------------------------------------------------------------
  350. /// <param name="array">
  351. /// The array to copy the stuff into.
  352. /// </param>
  353. ///
  354. /// <param name="arrayIndex">
  355. /// The location in the array to start copying the stuff into.
  356. /// </param>
  357. /// ----------------------------------------------------------------
  358. /// <remarks>
  359. /// This function assumes that the writer lock has already been
  360. /// obtained.
  361. /// </remarks>
  362. /// ****************************************************************
  363. ///
  364. public static void CopyTo( Array array, int arrayIndex )
  365. {
  366. //
  367. // Throw an exception if we are not in a valid state.
  368. //
  369. CheckIsValid();
  370. //
  371. // Acquire the reader lock and read the setting.
  372. //
  373. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  374. try
  375. {
  376. settings.CopyTo( array, arrayIndex );
  377. }
  378. finally
  379. {
  380. readWriteLock.ReleaseReaderLock();
  381. }
  382. }
  383. /// ****************************************************************
  384. /// public GetObject [static]
  385. /// ----------------------------------------------------------------
  386. /// <summary>
  387. /// Retrieves the setting with the given key.
  388. /// </summary>
  389. /// ----------------------------------------------------------------
  390. /// <param name="key">
  391. /// The setting key.
  392. /// </param>
  393. /// ----------------------------------------------------------------
  394. /// <returns>
  395. /// The value of the key, if it exists. An exception is raised
  396. /// if it does not.
  397. /// </returns>
  398. /// ****************************************************************
  399. ///
  400. public static object GetObject( string key )
  401. {
  402. //
  403. // Throw an exception if we are not in a valid state.
  404. //
  405. CheckIsValid();
  406. object setting = null;
  407. try
  408. {
  409. //
  410. // Acquire the reader lock and read the setting.
  411. //
  412. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  413. setting = settings[ key ];
  414. }
  415. catch( NullReferenceException )
  416. {
  417. //
  418. // Null reference exceptions are generated when the settings
  419. // table could not be read.
  420. //
  421. #if never
  422. OperatorMessage(
  423. UDDI.Diagnostics.OperatorMessageType.ConfigInvalid,
  424. "Configuration table is in an invalid state.\r\n\r\n" + LastError.ToString() );
  425. #endif
  426. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_CONFIG_INVALID_STATE", LastError.ToString() );
  427. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.ConfigInvalid, operatorMessage.GetText() );
  428. #if never
  429. throw new UDDIException(
  430. ErrorType.E_fatalError,
  431. "Server configuration error.\r\n\r\n" + LastError.ToString() );
  432. #endif
  433. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_COMMUNICATION_ERROR" );
  434. }
  435. finally
  436. {
  437. //
  438. // Release the reader lock.
  439. //
  440. readWriteLock.ReleaseReaderLock();
  441. }
  442. return setting;
  443. }
  444. /// ****************************************************************
  445. /// public GetObject [static]
  446. /// ----------------------------------------------------------------
  447. /// <summary>
  448. /// Retrieves the setting with the given key.
  449. /// </summary>
  450. /// ----------------------------------------------------------------
  451. /// <param name="key">
  452. /// The setting key.
  453. /// </param>
  454. ///
  455. /// <param name="defaultValue">
  456. /// Default value to use if the key does not exist.
  457. /// </param>
  458. /// ----------------------------------------------------------------
  459. /// <returns>
  460. /// The value of the key, if it exists, or the specified default
  461. /// value if it does not.
  462. /// </returns>
  463. /// ****************************************************************
  464. ///
  465. public static object GetObject( string key, object defaultValue )
  466. {
  467. //
  468. // Throw an exception if we are not in a valid state.
  469. //
  470. CheckIsValid();
  471. object setting = defaultValue;
  472. try
  473. {
  474. //
  475. // Acquire the reader lock and read the setting.
  476. //
  477. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  478. if( settings.ContainsKey( key ) )
  479. setting = settings[ key ];
  480. }
  481. catch( NullReferenceException )
  482. {
  483. //
  484. // Null reference exceptions are generated when the settings
  485. // table could not be read.
  486. //
  487. #if never
  488. OperatorMessage(
  489. UDDI.Diagnostics.OperatorMessageType.ConfigInvalid,
  490. "Configuration table is in an invalid state.\r\n\r\n" + LastError.ToString() );
  491. #endif
  492. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_CONFIG_INVALID_STATE", LastError.ToString() );
  493. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.ConfigInvalid, operatorMessage.GetText() );
  494. #if never
  495. throw new UDDIException(
  496. ErrorType.E_fatalError,
  497. "Server configuration error.\r\n\r\n" + LastError.ToString() );
  498. #endif
  499. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_COMMUNICATION_ERROR" );
  500. }
  501. finally
  502. {
  503. //
  504. // Release the reader lock.
  505. //
  506. readWriteLock.ReleaseReaderLock();
  507. }
  508. return setting;
  509. }
  510. /// ****************************************************************
  511. /// public GetInt [static]
  512. /// ----------------------------------------------------------------
  513. /// <summary>
  514. /// Retrieves the setting with the given key.
  515. /// </summary>
  516. /// ----------------------------------------------------------------
  517. /// <param name="key">
  518. /// The setting key.
  519. /// </param>
  520. /// ----------------------------------------------------------------
  521. /// <returns>
  522. /// The value of the key, if it exists. An exception is raised
  523. /// if it does not.
  524. /// </returns>
  525. /// ****************************************************************
  526. ///
  527. public static string GetString( string key )
  528. {
  529. //
  530. // Throw an exception if we are not in a valid state.
  531. //
  532. CheckIsValid();
  533. string setting = null;
  534. try
  535. {
  536. //
  537. // Acquire the reader lock and read the setting.
  538. //
  539. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  540. object data = settings[ key ];
  541. if( data is System.String )
  542. setting = (string)data;
  543. else
  544. setting = Convert.ToString( data );
  545. }
  546. catch( NullReferenceException )
  547. {
  548. //
  549. // Null reference exceptions are generated when the settings
  550. // table could not be read.
  551. //
  552. #if never
  553. OperatorMessage(
  554. UDDI.Diagnostics.OperatorMessageType.ConfigInvalid,
  555. "Configuration table is in an invalid state.\r\n\r\n" + LastError.ToString() );
  556. #endif
  557. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_CONFIG_INVALID_STATE", LastError.ToString() );
  558. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.ConfigInvalid, operatorMessage.GetText() );
  559. #if never
  560. throw new UDDIException(
  561. ErrorType.E_fatalError,
  562. "Server configuration error.\r\n\r\n" + LastError.ToString() );
  563. #endif
  564. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_COMMUNICATION_ERROR" );
  565. }
  566. finally
  567. {
  568. //
  569. // Release the reader lock.
  570. //
  571. readWriteLock.ReleaseReaderLock();
  572. }
  573. return setting;
  574. }
  575. /// ****************************************************************
  576. /// public GetString [static]
  577. /// ----------------------------------------------------------------
  578. /// <summary>
  579. /// Retrieves the setting with the given key.
  580. /// </summary>
  581. /// ----------------------------------------------------------------
  582. /// <param name="key">
  583. /// The setting key.
  584. /// </param>
  585. ///
  586. /// <param name="defaultValue">
  587. /// Default value to use if the key does not exist.
  588. /// </param>
  589. /// ----------------------------------------------------------------
  590. /// <returns>
  591. /// The value of the key, if it exists. Otherwise returns the
  592. /// default value.
  593. /// </returns>
  594. /// ****************************************************************
  595. ///
  596. public static string GetString( string key, string defaultValue )
  597. {
  598. //
  599. // Throw an exception if we are not in a valid state.
  600. //
  601. CheckIsValid();
  602. string setting = defaultValue;
  603. try
  604. {
  605. //
  606. // Acquire the reader lock and read the setting.
  607. //
  608. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  609. if( settings.ContainsKey( key ) )
  610. {
  611. object data = settings[ key ];
  612. if( data is System.String )
  613. setting = (string)data;
  614. else
  615. setting = Convert.ToString( data );
  616. }
  617. }
  618. catch( NullReferenceException )
  619. {
  620. //
  621. // Null reference exceptions are generated when the settings
  622. // table could not be read.
  623. //
  624. #if never
  625. OperatorMessage(
  626. UDDI.Diagnostics.OperatorMessageType.ConfigInvalid,
  627. "Configuration table is in an invalid state.\r\n\r\n" + LastError.ToString() );
  628. #endif
  629. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_CONFIG_INVALID_STATE", LastError.ToString() );
  630. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.ConfigInvalid, operatorMessage.GetText() );
  631. #if never
  632. throw new UDDIException(
  633. ErrorType.E_fatalError,
  634. "Server configuration error.\r\n\r\n" + LastError.ToString() );
  635. #endif
  636. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_COMMUNICATION_ERROR" );
  637. }
  638. finally
  639. {
  640. //
  641. // Release the reader lock.
  642. //
  643. readWriteLock.ReleaseReaderLock();
  644. }
  645. return setting;
  646. }
  647. /// ****************************************************************
  648. /// public GetInt [static]
  649. /// ----------------------------------------------------------------
  650. /// <summary>
  651. /// Retrieves the setting with the given key.
  652. /// </summary>
  653. /// ----------------------------------------------------------------
  654. /// <param name="key">
  655. /// The setting key.
  656. /// </param>
  657. /// ----------------------------------------------------------------
  658. /// <returns>
  659. /// The value of the key.
  660. /// </returns>
  661. /// ****************************************************************
  662. ///
  663. public static int GetInt( string key )
  664. {
  665. //
  666. // Throw an exception if we are not in a valid state.
  667. //
  668. CheckIsValid();
  669. int setting = 0;
  670. try
  671. {
  672. //
  673. // Acquire the reader lock and read the setting.
  674. //
  675. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  676. object data = settings[ key ];
  677. if( data is System.Int32 )
  678. setting = (int)data;
  679. else
  680. setting = Convert.ToInt32( data );
  681. }
  682. catch( NullReferenceException )
  683. {
  684. //
  685. // Null reference exceptions are generated when the settings
  686. // table could not be read.
  687. //
  688. #if never
  689. OperatorMessage(
  690. UDDI.Diagnostics.OperatorMessageType.ConfigInvalid,
  691. "Configuration table is in an invalid state.\r\n\r\n" + LastError.ToString() );
  692. #endif
  693. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_CONFIG_INVALID_STATE", LastError.ToString() );
  694. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.ConfigInvalid, operatorMessage.GetText() );
  695. #if never
  696. throw new UDDIException(
  697. ErrorType.E_fatalError,
  698. "Server configuration error.\r\n\r\n" + LastError.ToString() );
  699. #endif
  700. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_COMMUNICATION_ERROR" );
  701. }
  702. finally
  703. {
  704. //
  705. // Release the reader lock.
  706. //
  707. readWriteLock.ReleaseReaderLock();
  708. }
  709. return setting;
  710. }
  711. /// ****************************************************************
  712. /// public GetInt [static]
  713. /// ----------------------------------------------------------------
  714. /// <summary>
  715. /// Retrieves the setting with the given key.
  716. /// </summary>
  717. /// ----------------------------------------------------------------
  718. /// <param name="key">
  719. /// The setting key.
  720. /// </param>
  721. ///
  722. /// <param name="defaultValue">
  723. /// Default value to use if the key does not exist.
  724. /// </param>
  725. /// ----------------------------------------------------------------
  726. /// <returns>
  727. /// The value of the key, if it exists. Otherwise returns the
  728. /// default value.
  729. /// </returns>
  730. /// ****************************************************************
  731. ///
  732. public static int GetInt( string key, int defaultValue )
  733. {
  734. //
  735. // Throw an exception if we are not in a valid state.
  736. //
  737. CheckIsValid();
  738. int setting = defaultValue;
  739. try
  740. {
  741. //
  742. // Acquire the reader lock and read the setting.
  743. //
  744. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  745. if( settings.ContainsKey( key ) )
  746. {
  747. object data = settings[ key ];
  748. if( data is System.Int32 )
  749. setting = (int)data;
  750. else
  751. setting = Convert.ToInt32( data );
  752. }
  753. }
  754. catch( NullReferenceException )
  755. {
  756. //
  757. // Null reference exceptions are generated when the settings
  758. // table could not be read.
  759. //
  760. #if never
  761. OperatorMessage(
  762. UDDI.Diagnostics.OperatorMessageType.ConfigInvalid,
  763. "Configuration table is in an invalid state.\r\n\r\n" + LastError.ToString() );
  764. #endif
  765. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_CONFIG_INVALID_STATE", LastError.ToString() );
  766. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.ConfigInvalid, operatorMessage.GetText() );
  767. #if never
  768. throw new UDDIException(
  769. ErrorType.E_fatalError,
  770. "Server configuration error.\r\n\r\n" + LastError.ToString() );
  771. #endif
  772. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_COMMUNICATION_ERROR" );
  773. }
  774. finally
  775. {
  776. //
  777. // Release the reader lock.
  778. //
  779. readWriteLock.ReleaseReaderLock();
  780. }
  781. return setting;
  782. }
  783. /// ****************************************************************
  784. /// public SettingExists [static]
  785. /// ----------------------------------------------------------------
  786. /// <summary>
  787. /// Determines whether the given setting exists in the
  788. /// collection.
  789. /// </summary>
  790. /// ----------------------------------------------------------------
  791. /// <param name="key">
  792. /// The setting key.
  793. /// </param>
  794. /// ----------------------------------------------------------------
  795. /// <returns>
  796. /// Returns true if the setting exists.
  797. /// </returns>
  798. /// ****************************************************************
  799. ///
  800. public static bool SettingExists( string key )
  801. {
  802. //
  803. // Throw an exception if we are not in a valid state.
  804. //
  805. CheckIsValid();
  806. bool exists = false;
  807. try
  808. {
  809. //
  810. // Acquire the reader lock and read the setting.
  811. //
  812. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  813. exists = settings.ContainsKey( key );
  814. }
  815. catch( NullReferenceException )
  816. {
  817. //
  818. // Null reference exceptions are generated when the settings
  819. // table could not be read.
  820. //
  821. #if never
  822. OperatorMessage(
  823. UDDI.Diagnostics.OperatorMessageType.ConfigInvalid,
  824. "Configuration table is in an invalid state.\r\n\r\n" + LastError.ToString() );
  825. #endif
  826. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_CONFIG_INVALID_STATE", LastError.ToString() );
  827. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.ConfigInvalid, operatorMessage.GetText() );
  828. #if never
  829. throw new UDDIException(
  830. ErrorType.E_fatalError,
  831. "Server configuration error.\r\n\r\n" + LastError.ToString() );
  832. #endif
  833. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_COMMUNICATION_ERROR" );
  834. }
  835. finally
  836. {
  837. //
  838. // Release the reader lock.
  839. //
  840. readWriteLock.ReleaseReaderLock();
  841. }
  842. return exists;
  843. }
  844. /// ****************************************************************
  845. /// public Refresh [static]
  846. /// ----------------------------------------------------------------
  847. /// <summary>
  848. /// Refreshes setting information.
  849. /// </summary>
  850. /// ****************************************************************
  851. ///
  852. public static void Refresh()
  853. {
  854. try
  855. {
  856. Debug.Write(
  857. "INFO CONF Refreshing configuration settings (thread="
  858. + Thread.CurrentThread.GetHashCode().ToString()
  859. + ", user='" + WindowsIdentity.GetCurrent().Name + "')\r\n" );
  860. //
  861. // Obtain the writer lock.
  862. //
  863. readWriteLock.AcquireWriterLock( Timeout.Infinite );
  864. //
  865. // Clear the existing setting table.
  866. //
  867. settings = new Hashtable( CaseInsensitiveHashCodeProvider.Default,
  868. CaseInsensitiveComparer.Default );
  869. //
  870. // Attempt to get the database connection string.
  871. //
  872. RegistryKey databaseKey = Registry.LocalMachine.OpenSubKey( registryRoot + @"\Database" );
  873. string writerConnectionString = null;
  874. if( null != databaseKey )
  875. {
  876. try
  877. {
  878. writerConnectionString = (string)databaseKey.GetValue( "WriterConnectionString" );
  879. }
  880. catch( Exception )
  881. {
  882. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_DB_WRITER_CONNECTION_STRING" );
  883. }
  884. }
  885. //
  886. // 730294 - The MMC will set this value to "", so use StringEmtpy, not just check for null.
  887. //
  888. if( true == Utility.StringEmpty( writerConnectionString ) )
  889. {
  890. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_DB_WRITER_CONNECTION_STRING" );
  891. }
  892. //
  893. // Connect to the database and get the configuration settings.
  894. //
  895. SqlConnection conn = new SqlConnection( writerConnectionString );
  896. SqlCommand cmd = new SqlCommand( "net_config_get", conn );
  897. conn.Open();
  898. try
  899. {
  900. cmd.CommandType = CommandType.StoredProcedure;
  901. SqlDataReader reader = cmd.ExecuteReader();
  902. while( reader.Read() )
  903. {
  904. //
  905. // We'll treat all database settings as strings, except for those
  906. // with special prefixes.
  907. //
  908. string keyName = reader.GetString( 0 );
  909. string keyPrefix = "";
  910. int separator = keyName.IndexOf( "." );
  911. if( -1 != separator )
  912. keyPrefix = keyName.Substring( 0, separator );
  913. if( "Length" == keyPrefix )
  914. {
  915. AddSetting( keyName, Convert.ToInt32( reader.GetString( 1 ) ) );
  916. }
  917. else
  918. {
  919. AddSetting( keyName, reader.GetString( 1 ) );
  920. }
  921. }
  922. }
  923. finally
  924. {
  925. conn.Close();
  926. }
  927. //
  928. // Read configuration data from the registry.
  929. //
  930. RegistryKey root = Registry.LocalMachine.OpenSubKey( registryRoot );
  931. if( null != root )
  932. RefreshRegistrySettings( root, "", true );
  933. }
  934. catch( SqlException e )
  935. {
  936. LastError = e;
  937. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_ERROR_READING_CONFIG_SETTINGS", e.ToString() );
  938. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.CannotReadSettings, operatorMessage.GetText() );
  939. //
  940. // Mark the table as being invalid.
  941. //
  942. settings = null;
  943. }
  944. catch( Exception e )
  945. {
  946. LastError = e;
  947. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_ERROR_READING_CONFIG_SETTINGS", e.ToString() );
  948. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.CannotReadSettings, operatorMessage.GetText() );
  949. //
  950. // Mark the table as being invalid.
  951. //
  952. settings = null;
  953. }
  954. finally
  955. {
  956. //
  957. // Release the writer lock.
  958. //
  959. readWriteLock.ReleaseWriterLock();
  960. if( null != ConfigChange )
  961. {
  962. try
  963. {
  964. ConfigChange();
  965. }
  966. catch( Exception )
  967. {
  968. }
  969. }
  970. }
  971. }
  972. /// ****************************************************************
  973. /// private RefreshRegistrySettings [static]
  974. /// ----------------------------------------------------------------
  975. /// <summary>
  976. /// Refreshes configuration settings from the registry,
  977. /// starting at the specified root.
  978. /// </summary>
  979. /// ----------------------------------------------------------------
  980. /// <param name="root">
  981. /// Registry key that contains the settings.
  982. /// </param>
  983. ///
  984. /// <param name="prefix">
  985. /// Optional. Prefix to add to the beginning of setting names
  986. /// in the collection.
  987. /// </param>
  988. ///
  989. /// <param name="recurse">
  990. /// True if subkeys of the root should be searched.
  991. /// </param>
  992. /// ----------------------------------------------------------------
  993. /// <remarks>
  994. /// If recursion is enabled, values in subkeys of the root are
  995. /// also enumerated. When enumerating subkeys, the value names
  996. /// are prefixed with the name of the subkey.
  997. /// </remarks>
  998. /// ****************************************************************
  999. ///
  1000. private static void RefreshRegistrySettings( RegistryKey root, string prefix, bool recurse )
  1001. {
  1002. //
  1003. // Add the values in the given root.
  1004. //
  1005. foreach( string name in root.GetValueNames() )
  1006. AddSetting( prefix + name, root.GetValue( name ) );
  1007. //
  1008. // If recursion is enabled, search through the subkeys under the given root. The
  1009. // key will be prefixed with the subkey name.
  1010. //
  1011. if( true == recurse )
  1012. {
  1013. foreach( string name in root.GetSubKeyNames() )
  1014. RefreshRegistrySettings( root.OpenSubKey( name ), prefix + name + ".", true );
  1015. }
  1016. }
  1017. /// ****************************************************************
  1018. /// private Registry_OnChange [static]
  1019. /// ----------------------------------------------------------------
  1020. /// <summary>
  1021. /// Event handler for setting change events in the registry.
  1022. /// </summary>
  1023. /// ****************************************************************
  1024. ///
  1025. private static void Registry_OnChange()
  1026. {
  1027. //
  1028. // Impersonate the identity of the main thread.
  1029. //
  1030. if( WindowsIdentity.GetCurrent().Name != identity.Name )
  1031. {
  1032. try
  1033. {
  1034. identity.Impersonate();
  1035. }
  1036. catch( Exception e )
  1037. {
  1038. #if never
  1039. OperatorMessage(
  1040. UDDI.Diagnostics.OperatorMessageType.CannotReadSettings,
  1041. "Configuration refresh thread was unable take on the identity " +
  1042. "of the creating thread (thread=" + Thread.CurrentThread.GetHashCode().ToString() +
  1043. ").\r\n\r\nDetails:\r\n" + e.ToString() );
  1044. #endif
  1045. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_CANNOT_IMPERSONATE", Thread.CurrentThread.GetHashCode().ToString(), e.ToString() );
  1046. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.CannotReadSettings, operatorMessage.GetText() );
  1047. return;
  1048. }
  1049. }
  1050. Debug.Write(
  1051. "INFO CONF Configuration registry change handler starting (thread=" +
  1052. Thread.CurrentThread.GetHashCode().ToString() +
  1053. ", user='" + WindowsIdentity.GetCurrent().Name + "')\r\n" );
  1054. //
  1055. // Obtain a handle to the registry key we want to monitor.
  1056. //
  1057. uint hkey;
  1058. int hr = Win32.RegOpenKeyEx( Win32.HKEY_LOCAL_MACHINE, registryRoot, 0, Win32.KEY_READ, out hkey );
  1059. if( 0 != hr )
  1060. {
  1061. #if never
  1062. OperatorMessage(
  1063. UDDI.Diagnostics.OperatorMessageType.CannotReadSettings,
  1064. "Unable to access registry root '" + registryRoot + "'" );
  1065. #endif
  1066. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_UNABLE_TO_ACCESS_REGISTRY", registryRoot );
  1067. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.CannotReadSettings, operatorMessage.GetText() );
  1068. }
  1069. //
  1070. // Monitor changes to the registry key.
  1071. //
  1072. AutoResetEvent changeEvent = new AutoResetEvent( false );
  1073. while( true )
  1074. {
  1075. //
  1076. // Wait for a change notification event.
  1077. //
  1078. Win32.RegNotifyChangeKeyValue( hkey, true,
  1079. Win32.REG_NOTIFY_CHANGE_LAST_SET, (uint)changeEvent.Handle.ToInt32(), true );
  1080. changeEvent.WaitOne();
  1081. //
  1082. // Refresh the settings. We trap all errors since we never
  1083. // want to kill the refresh thread, otherwise who would read
  1084. // the settings when they finally become available?
  1085. //
  1086. try
  1087. {
  1088. Refresh();
  1089. }
  1090. catch( Exception e )
  1091. {
  1092. #if never
  1093. OperatorMessage(
  1094. UDDI.Diagnostics.OperatorMessageType.CannotReadSettings,
  1095. "Unable to refresh configuration settings from registry monitor thread.\r\n\r\nDetails:\r\n" + e.ToString() );
  1096. #endif
  1097. UDDIText operatorMessage = new UDDIText( "UDDI_ERROR_OPERATOR_MESSAGE_UNABLE_TO_REFRESH", e.ToString() );
  1098. OperatorMessage( UDDI.Diagnostics.OperatorMessageType.CannotReadSettings, operatorMessage.GetText() );
  1099. }
  1100. }
  1101. }
  1102. //
  1103. // 730294 - Centralize what exceptions we throw.
  1104. //
  1105. private static void CheckIsValid()
  1106. {
  1107. if( !IsValid )
  1108. {
  1109. //
  1110. // Make sure we are always throwing a nice UDDIException; construct a generic one if you have to.
  1111. //
  1112. UDDIException uddiException = LastError as UDDIException;
  1113. if( null == uddiException )
  1114. {
  1115. uddiException = new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_COMMUNICATION_ERROR" );
  1116. }
  1117. throw uddiException;
  1118. }
  1119. }
  1120. //
  1121. // 730294 - Clean up the way we do exceptions.
  1122. //
  1123. private static void InvalidateSelf()
  1124. {
  1125. //
  1126. // Make ourself invalid by nulling out the setting table. Make sure to keep this in sync with
  1127. // what the IsValid property is doing.
  1128. //
  1129. try
  1130. {
  1131. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  1132. settings = null;
  1133. }
  1134. finally
  1135. {
  1136. readWriteLock.ReleaseReaderLock();
  1137. }
  1138. }
  1139. }
  1140. /// ********************************************************************
  1141. /// public class CachedSetting
  1142. /// --------------------------------------------------------------------
  1143. /// <summary>
  1144. /// </summary>
  1145. /// ********************************************************************
  1146. ///
  1147. public class CachedSetting
  1148. {
  1149. private ReaderWriterLock readWriteLock = new ReaderWriterLock();
  1150. //
  1151. // 730294 - Keep the state of a CachedSetting in sync with the Config by just using the Config.IsValid property instead
  1152. // of keeping a valid member. Remove the valid member.
  1153. //
  1154. private string key;
  1155. private object setting;
  1156. private object defaultValue;
  1157. private bool exists;
  1158. private bool defaultSpecified;
  1159. public event Config.ConfigChangeHandler ConfigChange;
  1160. /// ****************************************************************
  1161. /// public CachedSetting [constructor]
  1162. /// ----------------------------------------------------------------
  1163. /// <summary>
  1164. /// </summary>
  1165. /// ----------------------------------------------------------------
  1166. /// <param name="key">
  1167. /// </param>
  1168. /// ****************************************************************
  1169. ///
  1170. public CachedSetting( string key )
  1171. {
  1172. this.key = key;
  1173. this.defaultSpecified = false;
  1174. this.defaultValue = null;
  1175. Config_OnChange();
  1176. Config.ConfigChange += new Config.ConfigChangeHandler( Config_OnChange );
  1177. }
  1178. /// ****************************************************************
  1179. /// public CachedSetting [constructor]
  1180. /// ----------------------------------------------------------------
  1181. /// <summary>
  1182. /// </summary>
  1183. /// ----------------------------------------------------------------
  1184. /// <param name="key">
  1185. /// </param>
  1186. ///
  1187. /// <param name="defaultValue">
  1188. /// </param>
  1189. /// ****************************************************************
  1190. ///
  1191. public CachedSetting( string key, object defaultValue )
  1192. {
  1193. this.key = key;
  1194. this.defaultSpecified = true;
  1195. this.defaultValue = defaultValue;
  1196. Config_OnChange();
  1197. Config.ConfigChange += new Config.ConfigChangeHandler( Config_OnChange );
  1198. }
  1199. /// ****************************************************************
  1200. /// private Config_OnChange [event handler]
  1201. /// ----------------------------------------------------------------
  1202. /// <summary>
  1203. /// </summary>
  1204. /// ----------------------------------------------------------------
  1205. /// <remarks>
  1206. /// We don't have to worry about acquiring a reader lock in
  1207. /// this method because the configuration update only executes
  1208. /// on a single background thread.
  1209. /// </remarks>
  1210. /// ****************************************************************
  1211. ///
  1212. private void Config_OnChange()
  1213. {
  1214. //
  1215. // Make sure the config is valid. If not, just return.
  1216. //
  1217. if( !Config.IsValid )
  1218. {
  1219. return;
  1220. }
  1221. object setting = null;
  1222. //
  1223. // Retrieve the new setting.
  1224. //
  1225. bool exists = Config.SettingExists( key );
  1226. if( exists )
  1227. setting = Config.GetObject( key );
  1228. //
  1229. // Check to see if we need to do anything. First of all, if the
  1230. // existance of the setting has changed, we need to update that
  1231. // information. If that has not changed, then the only other way
  1232. // we do not have to update is if the setting itself hasn't
  1233. // changed.
  1234. //
  1235. if( exists == this.exists &&
  1236. null != setting && setting.Equals( this.setting ) )
  1237. return;
  1238. //
  1239. // Store the new setting details.
  1240. //
  1241. System.Diagnostics.Debug.Write(
  1242. "INFO CONF Refreshing cached setting '" + key + "' (thread="
  1243. + Thread.CurrentThread.GetHashCode().ToString()
  1244. + ", user='" + WindowsIdentity.GetCurrent().Name + "')\r\n" );
  1245. readWriteLock.AcquireWriterLock( Timeout.Infinite );
  1246. try
  1247. {
  1248. this.exists = exists;
  1249. this.setting = setting;
  1250. }
  1251. finally
  1252. {
  1253. readWriteLock.ReleaseWriterLock();
  1254. if( null != ConfigChange )
  1255. ConfigChange();
  1256. }
  1257. }
  1258. /// ****************************************************************
  1259. /// public Exists
  1260. /// ----------------------------------------------------------------
  1261. /// <summary>
  1262. /// </summary>
  1263. /// ****************************************************************
  1264. ///
  1265. public bool Exists
  1266. {
  1267. get
  1268. {
  1269. //
  1270. // Don't call CheckSetting() here because we don't want to throw an exception if the setting
  1271. // does not exist.
  1272. //
  1273. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  1274. try
  1275. {
  1276. //
  1277. // Make sure that our configuration is still valid.
  1278. //
  1279. CheckIsConfigValid();
  1280. return exists;
  1281. }
  1282. finally
  1283. {
  1284. readWriteLock.ReleaseReaderLock();
  1285. }
  1286. }
  1287. }
  1288. /// ****************************************************************
  1289. /// public HasDefaultValue
  1290. /// ----------------------------------------------------------------
  1291. /// <summary>
  1292. /// </summary>
  1293. /// ****************************************************************
  1294. ///
  1295. public bool HasDefaultValue
  1296. {
  1297. get { return defaultSpecified; }
  1298. }
  1299. /// ****************************************************************
  1300. /// public DefaultValue
  1301. /// ----------------------------------------------------------------
  1302. /// <summary>
  1303. /// </summary>
  1304. /// ****************************************************************
  1305. ///
  1306. public object DefaultValue
  1307. {
  1308. get { return defaultValue; }
  1309. }
  1310. /// ****************************************************************
  1311. /// public GetString
  1312. /// ----------------------------------------------------------------
  1313. /// <summary>
  1314. /// </summary>
  1315. /// ****************************************************************
  1316. ///
  1317. public string GetString()
  1318. {
  1319. //
  1320. // 730294 - Centralize checking of setting state and validity.
  1321. //
  1322. CheckSetting();
  1323. //
  1324. // Return the setting as a string.
  1325. //
  1326. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  1327. try
  1328. {
  1329. if( exists )
  1330. return Convert.ToString( setting );
  1331. else
  1332. return Convert.ToString( defaultValue );
  1333. }
  1334. finally
  1335. {
  1336. readWriteLock.ReleaseReaderLock();
  1337. }
  1338. }
  1339. /// ****************************************************************
  1340. /// public GetInt
  1341. /// ----------------------------------------------------------------
  1342. /// <summary>
  1343. /// </summary>
  1344. /// ****************************************************************
  1345. ///
  1346. public int GetInt()
  1347. {
  1348. //
  1349. // 730294 - Centralize checking of setting state and validity.
  1350. //
  1351. CheckSetting();
  1352. //
  1353. // Return the setting as an integer.
  1354. //
  1355. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  1356. try
  1357. {
  1358. if( exists )
  1359. return Convert.ToInt32( setting );
  1360. else
  1361. return Convert.ToInt32( defaultValue );
  1362. }
  1363. finally
  1364. {
  1365. readWriteLock.ReleaseReaderLock();
  1366. }
  1367. }
  1368. /// ****************************************************************
  1369. /// public GetObject
  1370. /// ----------------------------------------------------------------
  1371. /// <summary>
  1372. /// </summary>
  1373. /// ****************************************************************
  1374. ///
  1375. public object GetObject()
  1376. {
  1377. //
  1378. // 730294 - Centralize checking of setting state and validity.
  1379. //
  1380. CheckSetting();
  1381. //
  1382. // Return the setting as an object.
  1383. //
  1384. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  1385. try
  1386. {
  1387. if( exists )
  1388. return setting;
  1389. else
  1390. return defaultValue;
  1391. }
  1392. finally
  1393. {
  1394. readWriteLock.ReleaseReaderLock();
  1395. }
  1396. }
  1397. //
  1398. // 730294 - Keep the state of a CachedSetting in sync with the Config by just using the Config.IsValid property instead
  1399. // of keeping a valid member.
  1400. //
  1401. private void CheckSetting()
  1402. {
  1403. //
  1404. // First, make sure that we still exist.
  1405. //
  1406. if( !exists && !defaultSpecified )
  1407. {
  1408. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_CONFIG_SETTING_MISSING", key );
  1409. }
  1410. //
  1411. // Make sure that our configuration is still valid.
  1412. //
  1413. CheckIsConfigValid();
  1414. }
  1415. private void CheckIsConfigValid()
  1416. {
  1417. if( false == Config.IsValid )
  1418. {
  1419. throw new UDDIException( ErrorType.E_fatalError, "UDDI_ERROR_SERVER_CONFIGURATION_ERROR", Config.LastError.Message );
  1420. }
  1421. }
  1422. public void AcquireReaderLock( int millisecondsTimeout )
  1423. {
  1424. readWriteLock.AcquireReaderLock( millisecondsTimeout );
  1425. }
  1426. public void AcquireReaderLock( TimeSpan timeout )
  1427. {
  1428. readWriteLock.AcquireReaderLock( timeout );
  1429. }
  1430. public void ReleaseReaderLock()
  1431. {
  1432. readWriteLock.ReleaseReaderLock();
  1433. }
  1434. }
  1435. }