OledbConnectionStringbuilder.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. //------------------------------------------------------------------------------
  2. // <copyright file="OleDbConnectionStringBuilder.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">[....]</owner>
  6. // <owner current="true" primary="false">[....]</owner>
  7. //------------------------------------------------------------------------------
  8. using System;
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. using System.ComponentModel;
  12. using System.Data;
  13. using System.Data.Common;
  14. using System.Diagnostics;
  15. using System.Globalization;
  16. using System.Runtime.Serialization;
  17. using System.Security.Permissions;
  18. using System.Text;
  19. namespace System.Data.OleDb {
  20. [DefaultProperty("Provider")]
  21. [RefreshPropertiesAttribute(RefreshProperties.All)]
  22. [System.ComponentModel.TypeConverterAttribute(typeof(OleDbConnectionStringBuilder.OleDbConnectionStringBuilderConverter))]
  23. public sealed class OleDbConnectionStringBuilder : DbConnectionStringBuilder {
  24. private enum Keywords { // specific ordering for ConnectionString output construction
  25. // NamedConnection,
  26. FileName,
  27. Provider,
  28. DataSource,
  29. PersistSecurityInfo,
  30. OleDbServices,
  31. }
  32. private static readonly string[] _validKeywords;
  33. private static readonly Dictionary<string,Keywords> _keywords;
  34. private string[] _knownKeywords;
  35. private Dictionary<string,OleDbPropertyInfo> _propertyInfo;
  36. // private string _namedConnection = DbConnectionStringDefaults.NamedConnection;
  37. private string _fileName = DbConnectionStringDefaults.FileName;
  38. private string _dataSource = DbConnectionStringDefaults.DataSource;
  39. private string _provider = DbConnectionStringDefaults.Provider;
  40. private int _oleDbServices = DbConnectionStringDefaults.OleDbServices;
  41. private bool _persistSecurityInfo = DbConnectionStringDefaults.PersistSecurityInfo;
  42. static OleDbConnectionStringBuilder() {
  43. string[] validKeywords = new string[5];
  44. validKeywords[(int)Keywords.DataSource] = DbConnectionStringKeywords.DataSource;
  45. validKeywords[(int)Keywords.FileName] = DbConnectionStringKeywords.FileName;
  46. // validKeywords[(int)Keywords.NamedConnection] = DbConnectionStringKeywords.NamedConnection;
  47. validKeywords[(int)Keywords.OleDbServices] = DbConnectionStringKeywords.OleDbServices;
  48. validKeywords[(int)Keywords.PersistSecurityInfo] = DbConnectionStringKeywords.PersistSecurityInfo;
  49. validKeywords[(int)Keywords.Provider] = DbConnectionStringKeywords.Provider;
  50. _validKeywords = validKeywords;
  51. Dictionary<string,Keywords> hash = new Dictionary<string,Keywords>(9, StringComparer.OrdinalIgnoreCase);
  52. hash.Add(DbConnectionStringKeywords.DataSource, Keywords.DataSource);
  53. hash.Add(DbConnectionStringKeywords.FileName, Keywords.FileName);
  54. // hash.Add(DbConnectionStringKeywords.NamedConnection, Keywords.NamedConnection);
  55. hash.Add(DbConnectionStringKeywords.OleDbServices, Keywords.OleDbServices);
  56. hash.Add(DbConnectionStringKeywords.PersistSecurityInfo, Keywords.PersistSecurityInfo);
  57. hash.Add(DbConnectionStringKeywords.Provider, Keywords.Provider);
  58. Debug.Assert(5 == hash.Count, "initial expected size is incorrect");
  59. _keywords = hash;
  60. }
  61. public OleDbConnectionStringBuilder() : this(null) {
  62. _knownKeywords = _validKeywords;
  63. }
  64. public OleDbConnectionStringBuilder(string connectionString) : base() {
  65. if (!ADP.IsEmpty(connectionString)) {
  66. ConnectionString = connectionString;
  67. }
  68. }
  69. public override object this[string keyword] {
  70. get {
  71. ADP.CheckArgumentNull(keyword, "keyword");
  72. object value;
  73. Keywords index;
  74. if (_keywords.TryGetValue(keyword, out index)) {
  75. value = GetAt(index);
  76. }
  77. else if (!base.TryGetValue(keyword, out value)) {
  78. Dictionary<string,OleDbPropertyInfo> dynamic = GetProviderInfo(Provider);
  79. OleDbPropertyInfo info = dynamic[keyword];
  80. value = info._defaultValue;
  81. }
  82. return value;
  83. }
  84. set {
  85. if (null != value) {
  86. ADP.CheckArgumentNull(keyword, "keyword");
  87. Keywords index;
  88. if (_keywords.TryGetValue(keyword, out index)) {
  89. switch(index) {
  90. case Keywords.DataSource: DataSource = ConvertToString(value); break;
  91. case Keywords.FileName: FileName = ConvertToString(value); break;
  92. // case Keywords.NamedConnection: NamedConnection = ConvertToString(value); break;
  93. case Keywords.Provider: Provider = ConvertToString(value); break;
  94. case Keywords.OleDbServices: OleDbServices = ConvertToInt32(value); break;
  95. case Keywords.PersistSecurityInfo: PersistSecurityInfo = ConvertToBoolean(value); break;
  96. default:
  97. Debug.Assert(false, "unexpected keyword");
  98. throw ADP.KeywordNotSupported(keyword);
  99. }
  100. }
  101. else {
  102. base[keyword] = value;
  103. ClearPropertyDescriptors();
  104. }
  105. }
  106. else {
  107. Remove(keyword);
  108. }
  109. }
  110. }
  111. [DisplayName(DbConnectionStringKeywords.DataSource)]
  112. [ResCategoryAttribute(Res.DataCategory_Source)]
  113. [ResDescriptionAttribute(Res.DbConnectionString_DataSource)]
  114. [RefreshPropertiesAttribute(RefreshProperties.All)]
  115. //
  116. public string DataSource {
  117. get { return _dataSource; }
  118. set {
  119. SetValue(DbConnectionStringKeywords.DataSource, value);
  120. _dataSource = value;
  121. }
  122. }
  123. [DisplayName(DbConnectionStringKeywords.FileName)]
  124. [ResCategoryAttribute(Res.DataCategory_NamedConnectionString)]
  125. [ResDescriptionAttribute(Res.DbConnectionString_FileName)]
  126. [RefreshPropertiesAttribute(RefreshProperties.All)]
  127. //
  128. [Editor("System.Windows.Forms.Design.FileNameEditor, " + AssemblyRef.SystemDesign, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing)]
  129. public string FileName {
  130. get { return _fileName; }
  131. set {
  132. SetValue(DbConnectionStringKeywords.FileName, value);
  133. _fileName = value;
  134. }
  135. }
  136. /*
  137. [DisplayName(DbConnectionStringKeywords.NamedConnection)]
  138. [ResCategoryAttribute(Res.DataCategory_NamedConnectionString)]
  139. [ResDescriptionAttribute(Res.DbConnectionString_NamedConnection)]
  140. [RefreshPropertiesAttribute(RefreshProperties.All)]
  141. [TypeConverter(typeof(NamedConnectionStringConverter))]
  142. public string NamedConnection {
  143. get { return _namedConnection; }
  144. set {
  145. SetValue(DbConnectionStringKeywords.NamedConnection, value);
  146. _namedConnection = value;
  147. }
  148. }
  149. */
  150. [DisplayName(DbConnectionStringKeywords.OleDbServices)]
  151. [ResCategoryAttribute(Res.DataCategory_Pooling)]
  152. [ResDescriptionAttribute(Res.DbConnectionString_OleDbServices)]
  153. [RefreshPropertiesAttribute(RefreshProperties.All)]
  154. [TypeConverter(typeof(OleDbConnectionStringBuilder.OleDbServicesConverter))]
  155. public int OleDbServices {
  156. get { return _oleDbServices; }
  157. set {
  158. SetValue(DbConnectionStringKeywords.OleDbServices, value);
  159. _oleDbServices = value;
  160. }
  161. }
  162. [DisplayName(DbConnectionStringKeywords.PersistSecurityInfo)]
  163. [ResCategoryAttribute(Res.DataCategory_Security)]
  164. [ResDescriptionAttribute(Res.DbConnectionString_PersistSecurityInfo)]
  165. [RefreshPropertiesAttribute(RefreshProperties.All)]
  166. public bool PersistSecurityInfo {
  167. get { return _persistSecurityInfo; }
  168. set {
  169. SetValue(DbConnectionStringKeywords.PersistSecurityInfo, value);
  170. _persistSecurityInfo = value;
  171. }
  172. }
  173. [DisplayName(DbConnectionStringKeywords.Provider)]
  174. [ResCategoryAttribute(Res.DataCategory_Source)]
  175. [ResDescriptionAttribute(Res.DbConnectionString_Provider)]
  176. [RefreshPropertiesAttribute(RefreshProperties.All)]
  177. [TypeConverter(typeof(OleDbConnectionStringBuilder.OleDbProviderConverter))]
  178. public string Provider {
  179. get { return _provider; }
  180. set {
  181. SetValue(DbConnectionStringKeywords.Provider, value);
  182. _provider = value;
  183. RestartProvider();
  184. }
  185. }
  186. public override ICollection Keys {
  187. get {
  188. string[] knownKeywords = _knownKeywords;
  189. if (null == knownKeywords) {
  190. Dictionary<string,OleDbPropertyInfo> dynamic = GetProviderInfo(Provider);
  191. if (0 < dynamic.Count) {
  192. knownKeywords = new string[_validKeywords.Length + dynamic.Count];
  193. _validKeywords.CopyTo(knownKeywords, 0);
  194. dynamic.Keys.CopyTo(knownKeywords, _validKeywords.Length);
  195. }
  196. else {
  197. knownKeywords = _validKeywords;
  198. }
  199. int count = 0;
  200. foreach(string keyword in base.Keys) {
  201. bool flag = true;
  202. foreach(string s in knownKeywords) {
  203. if (StringComparer.OrdinalIgnoreCase.Equals(s, keyword)) {
  204. flag = false;
  205. break;
  206. }
  207. }
  208. if (flag) {
  209. count++;
  210. }
  211. }
  212. if (0 < count) {
  213. string[] tmp = new string[knownKeywords.Length + count];
  214. knownKeywords.CopyTo(tmp, 0);
  215. int index = knownKeywords.Length;
  216. foreach(string keyword in base.Keys) {
  217. bool flag = true;
  218. foreach(string s in knownKeywords) {
  219. if (StringComparer.OrdinalIgnoreCase.Equals(s, keyword)) {
  220. flag = false;
  221. break;
  222. }
  223. }
  224. if (flag) {
  225. tmp[index++] = keyword;
  226. }
  227. }
  228. knownKeywords = tmp;
  229. }
  230. _knownKeywords = knownKeywords;
  231. }
  232. return new System.Data.Common.ReadOnlyCollection<string>(knownKeywords);
  233. }
  234. }
  235. public override bool ContainsKey(string keyword) {
  236. ADP.CheckArgumentNull(keyword, "keyword");
  237. return _keywords.ContainsKey(keyword) || base.ContainsKey(keyword);
  238. }
  239. private static bool ConvertToBoolean(object value) {
  240. return DbConnectionStringBuilderUtil.ConvertToBoolean(value);
  241. }
  242. private static int ConvertToInt32(object value) {
  243. return DbConnectionStringBuilderUtil.ConvertToInt32(value);
  244. }
  245. private static string ConvertToString(object value) {
  246. return DbConnectionStringBuilderUtil.ConvertToString(value);
  247. }
  248. public override void Clear() {
  249. base.Clear();
  250. for(int i = 0; i < _validKeywords.Length; ++i) {
  251. Reset((Keywords)i);
  252. }
  253. base.ClearPropertyDescriptors();
  254. _knownKeywords = _validKeywords;
  255. }
  256. private object GetAt(Keywords index) {
  257. switch(index) {
  258. case Keywords.DataSource: return DataSource;
  259. case Keywords.FileName: return FileName;
  260. // case Keywords.NamedConnection: return NamedConnection;
  261. case Keywords.OleDbServices: return OleDbServices;
  262. case Keywords.PersistSecurityInfo: return PersistSecurityInfo;
  263. case Keywords.Provider: return Provider;
  264. default:
  265. Debug.Assert(false, "unexpected keyword");
  266. throw ADP.KeywordNotSupported(_validKeywords[(int)index]);
  267. }
  268. }
  269. public override bool Remove(string keyword) {
  270. ADP.CheckArgumentNull(keyword, "keyword");
  271. bool value = base.Remove(keyword);
  272. Keywords index;
  273. if (_keywords.TryGetValue(keyword, out index)) {
  274. Reset(index);
  275. }
  276. else if (value) {
  277. ClearPropertyDescriptors();
  278. }
  279. return value;
  280. }
  281. private void Reset(Keywords index) {
  282. switch(index) {
  283. case Keywords.DataSource:
  284. _dataSource = DbConnectionStringDefaults.DataSource;
  285. break;
  286. case Keywords.FileName:
  287. _fileName = DbConnectionStringDefaults.FileName;
  288. RestartProvider();
  289. break;
  290. // case Keywords.NamedConnection:
  291. // _namedConnection = DbConnectionStringDefaults.NamedConnection;
  292. // break;
  293. case Keywords.OleDbServices:
  294. _oleDbServices = DbConnectionStringDefaults.OleDbServices;
  295. break;
  296. case Keywords.PersistSecurityInfo:
  297. _persistSecurityInfo = DbConnectionStringDefaults.PersistSecurityInfo;
  298. break;
  299. case Keywords.Provider:
  300. _provider = DbConnectionStringDefaults.Provider;
  301. RestartProvider();
  302. break;
  303. default:
  304. Debug.Assert(false, "unexpected keyword");
  305. throw ADP.KeywordNotSupported(_validKeywords[(int)index]);
  306. }
  307. }
  308. private new void ClearPropertyDescriptors() {
  309. base.ClearPropertyDescriptors();
  310. _knownKeywords = null;
  311. }
  312. private void RestartProvider() {
  313. ClearPropertyDescriptors();
  314. _propertyInfo = null;
  315. }
  316. private void SetValue(string keyword, bool value) {
  317. base[keyword] = value.ToString((System.IFormatProvider)null);
  318. }
  319. private void SetValue(string keyword, int value) {
  320. base[keyword] = value.ToString((System.IFormatProvider)null);
  321. }
  322. private void SetValue(string keyword, string value) {
  323. ADP.CheckArgumentNull(value, keyword);
  324. base[keyword] = value;
  325. }
  326. public override bool TryGetValue(string keyword, out object value) {
  327. ADP.CheckArgumentNull(keyword, "keyword");
  328. Keywords index;
  329. if (_keywords.TryGetValue(keyword, out index)) {
  330. value = GetAt(index);
  331. return true;
  332. }
  333. else if (!base.TryGetValue(keyword, out value)) {
  334. Dictionary<string,OleDbPropertyInfo> dynamic = GetProviderInfo(Provider);
  335. OleDbPropertyInfo info;
  336. if (dynamic.TryGetValue(keyword, out info)) {
  337. value = info._defaultValue;
  338. return true;
  339. }
  340. return false;
  341. }
  342. return true;
  343. }
  344. private Dictionary<string,OleDbPropertyInfo> GetProviderInfo(string provider) {
  345. Dictionary<string,OleDbPropertyInfo> providerInfo = _propertyInfo;
  346. if (null == providerInfo) {
  347. providerInfo = new Dictionary<string,OleDbPropertyInfo>(StringComparer.OrdinalIgnoreCase);
  348. if (!ADP.IsEmpty(provider)) {
  349. Dictionary<string,OleDbPropertyInfo> hash = null;
  350. try {
  351. StringBuilder builder = new StringBuilder();
  352. AppendKeyValuePair(builder, DbConnectionStringKeywords.Provider, provider);
  353. OleDbConnectionString constr = new OleDbConnectionString(builder.ToString(), true);
  354. constr.CreatePermissionSet().Demand();
  355. // load provider without calling Initialize or CreateDataSource
  356. using(OleDbConnectionInternal connection = new OleDbConnectionInternal(constr, (OleDbConnection)null)) {
  357. // get all the init property information for the provider
  358. hash = connection.GetPropertyInfo(new Guid[] { OleDbPropertySetGuid.DBInitAll });
  359. foreach(KeyValuePair<string,OleDbPropertyInfo> entry in hash) {
  360. Keywords index;
  361. OleDbPropertyInfo info = entry.Value;
  362. if (!_keywords.TryGetValue(info._description, out index)) {
  363. if ((OleDbPropertySetGuid.DBInit == info._propertySet) &&
  364. ((ODB.DBPROP_INIT_ASYNCH == info._propertyID) ||
  365. (ODB.DBPROP_INIT_HWND == info._propertyID) ||
  366. (ODB.DBPROP_INIT_PROMPT == info._propertyID))) {
  367. continue; // skip this keyword
  368. }
  369. providerInfo[info._description] = info;
  370. }
  371. }
  372. // what are the unique propertysets?
  373. List<Guid> listPropertySets= new List<Guid>();
  374. foreach(KeyValuePair<string,OleDbPropertyInfo> entry in hash) {
  375. OleDbPropertyInfo info = entry.Value;
  376. if (!listPropertySets.Contains(info._propertySet)) {
  377. listPropertySets.Add(info._propertySet);
  378. }
  379. }
  380. Guid[] arrayPropertySets = new Guid[listPropertySets.Count];
  381. listPropertySets.CopyTo(arrayPropertySets, 0);
  382. // get all the init property values for the provider
  383. using(PropertyIDSet propidset = new PropertyIDSet(arrayPropertySets)) {
  384. using(IDBPropertiesWrapper idbProperties = connection.IDBProperties()) {
  385. OleDbHResult hr;
  386. using(DBPropSet propset = new DBPropSet(idbProperties.Value, propidset, out hr)) {
  387. // VSDD 671375: OleDbConnectionStringBuilder is ignoring/hiding potential errors of OLEDB provider when reading its properties information
  388. if (0 <= (int)hr) {
  389. int count = propset.PropertySetCount;
  390. for(int i = 0; i < count; ++i) {
  391. Guid propertyset;
  392. tagDBPROP[] props = propset.GetPropertySet(i, out propertyset);
  393. // attach the default property value to the property info
  394. foreach(tagDBPROP prop in props) {
  395. foreach(KeyValuePair<string,OleDbPropertyInfo> entry in hash) {
  396. OleDbPropertyInfo info = entry.Value;
  397. if ((info._propertyID == prop.dwPropertyID) && (info._propertySet == propertyset)) {
  398. info._defaultValue = prop.vValue;
  399. if (null == info._defaultValue) {
  400. if (typeof(string) == info._type) {
  401. info._defaultValue = "";
  402. }
  403. else if (typeof(Int32) == info._type) {
  404. info._defaultValue = 0;
  405. }
  406. else if (typeof(Boolean) == info._type) {
  407. info._defaultValue = false;
  408. }
  409. }
  410. }
  411. }
  412. }
  413. }
  414. }
  415. }
  416. }
  417. }
  418. }
  419. }
  420. catch(System.InvalidOperationException e) {
  421. ADP.TraceExceptionWithoutRethrow(e);
  422. }
  423. catch(System.Data.OleDb.OleDbException e) {
  424. ADP.TraceExceptionWithoutRethrow(e);
  425. }
  426. catch(System.Security.SecurityException e) {
  427. ADP.TraceExceptionWithoutRethrow(e);
  428. }
  429. }
  430. _propertyInfo = providerInfo;
  431. }
  432. return providerInfo;
  433. }
  434. protected override void GetProperties(Hashtable propertyDescriptors) {
  435. Dictionary<string,OleDbPropertyInfo> providerInfo = GetProviderInfo(Provider);
  436. if (0 < providerInfo.Count) {
  437. foreach(OleDbPropertyInfo info in providerInfo.Values) {
  438. Keywords index;
  439. if (!_keywords.TryGetValue(info._description, out index)) { // not a strongly typed property
  440. bool isReadOnly = false;
  441. bool refreshOnChange = false;
  442. Attribute[] attributes;
  443. if (OleDbPropertySetGuid.DBInit == info._propertySet) {
  444. switch(info._propertyID) {
  445. #if DEBUG
  446. case ODB.DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO:
  447. case ODB.DBPROP_INIT_ASYNCH:
  448. case ODB.DBPROP_INIT_DATASOURCE:
  449. case ODB.DBPROP_INIT_HWND:
  450. case ODB.DBPROP_INIT_OLEDBSERVICES:
  451. Debug.Assert(false, "should be handled via strongly typed property");
  452. goto default;
  453. #endif
  454. case ODB.DBPROP_INIT_CATALOG:
  455. case ODB.DBPROP_INIT_LOCATION:
  456. attributes = new Attribute[] {
  457. BrowsableAttribute.Yes,
  458. new ResCategoryAttribute(Res.DataCategory_Source),
  459. RefreshPropertiesAttribute.All,
  460. };
  461. break;
  462. case ODB.DBPROP_INIT_TIMEOUT:
  463. case ODB.DBPROP_INIT_GENERALTIMEOUT:
  464. attributes = new Attribute[] {
  465. BrowsableAttribute.Yes,
  466. new ResCategoryAttribute(Res.DataCategory_Initialization),
  467. RefreshPropertiesAttribute.All,
  468. };
  469. break;
  470. // 'Password' & 'User ID' will be readonly if 'Integrated Security' exists
  471. case ODB.DBPROP_AUTH_PASSWORD:
  472. attributes = new Attribute[] {
  473. BrowsableAttribute.Yes,
  474. PasswordPropertyTextAttribute.Yes,
  475. new ResCategoryAttribute(Res.DataCategory_Security),
  476. RefreshPropertiesAttribute.All,
  477. };
  478. isReadOnly = ContainsKey(DbConnectionStringKeywords.IntegratedSecurity);
  479. refreshOnChange = true;
  480. break;
  481. case ODB.DBPROP_AUTH_USERID:
  482. attributes = new Attribute[] {
  483. BrowsableAttribute.Yes,
  484. new ResCategoryAttribute(Res.DataCategory_Security),
  485. RefreshPropertiesAttribute.All,
  486. };
  487. isReadOnly = ContainsKey(DbConnectionStringKeywords.IntegratedSecurity);
  488. refreshOnChange = true;
  489. break;
  490. case ODB.DBPROP_AUTH_CACHE_AUTHINFO:
  491. case ODB.DBPROP_AUTH_ENCRYPT_PASSWORD:
  492. case ODB.DBPROP_AUTH_INTEGRATED:
  493. case ODB.DBPROP_AUTH_MASK_PASSWORD:
  494. case ODB.DBPROP_AUTH_PERSIST_ENCRYPTED:
  495. attributes = new Attribute[] {
  496. BrowsableAttribute.Yes,
  497. new ResCategoryAttribute(Res.DataCategory_Security),
  498. RefreshPropertiesAttribute.All,
  499. };
  500. refreshOnChange = (ODB.DBPROP_AUTH_INTEGRATED == info._propertyID);
  501. break;
  502. case ODB.DBPROP_INIT_BINDFLAGS:
  503. case ODB.DBPROP_INIT_IMPERSONATION_LEVEL:
  504. case ODB.DBPROP_INIT_LCID:
  505. case ODB.DBPROP_INIT_MODE:
  506. case ODB.DBPROP_INIT_PROTECTION_LEVEL:
  507. case ODB.DBPROP_INIT_PROVIDERSTRING:
  508. case ODB.DBPROP_INIT_LOCKOWNER:
  509. attributes = new Attribute[] {
  510. BrowsableAttribute.Yes,
  511. new ResCategoryAttribute(Res.DataCategory_Advanced),
  512. RefreshPropertiesAttribute.All,
  513. };
  514. break;
  515. default:
  516. Debug.Assert(false, "new standard propertyid");
  517. attributes = new Attribute[] {
  518. BrowsableAttribute.Yes,
  519. RefreshPropertiesAttribute.All,
  520. };
  521. break;
  522. }
  523. }
  524. else if (info._description.EndsWith(" Provider", StringComparison.OrdinalIgnoreCase)) {
  525. attributes = new Attribute[] {
  526. BrowsableAttribute.Yes,
  527. RefreshPropertiesAttribute.All,
  528. new ResCategoryAttribute(Res.DataCategory_Source),
  529. new TypeConverterAttribute(typeof(OleDbConnectionStringBuilder.OleDbProviderConverter)),
  530. };
  531. refreshOnChange = true;
  532. }
  533. else {
  534. attributes = new Attribute[] {
  535. BrowsableAttribute.Yes,
  536. RefreshPropertiesAttribute.All,
  537. new CategoryAttribute(Provider),
  538. };
  539. }
  540. DbConnectionStringBuilderDescriptor descriptor = new DbConnectionStringBuilderDescriptor(info._description,
  541. typeof(OleDbConnectionStringBuilder), info._type, isReadOnly, attributes);
  542. descriptor.RefreshOnChange = refreshOnChange;
  543. propertyDescriptors[info._description] = descriptor;
  544. }
  545. // else strongly typed property already exists, i.e. DataSource
  546. }
  547. }
  548. base.GetProperties(propertyDescriptors);
  549. }
  550. private sealed class OleDbProviderConverter : StringConverter {
  551. private const int DBSOURCETYPE_DATASOURCE_TDP = 1;
  552. private const int DBSOURCETYPE_DATASOURCE_MDP = 3;
  553. private StandardValuesCollection _standardValues;
  554. // converter classes should have public ctor
  555. public OleDbProviderConverter() {
  556. }
  557. public override bool GetStandardValuesSupported(ITypeDescriptorContext context) {
  558. return true;
  559. }
  560. public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) {
  561. return false;
  562. }
  563. public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) {
  564. StandardValuesCollection dataSourceNames = _standardValues;
  565. if (null == _standardValues) {
  566. // Get the sources rowset for the SQLOLEDB enumerator
  567. DataTable table = (new OleDbEnumerator()).GetElements();
  568. DataColumn column2 = table.Columns["SOURCES_NAME"];
  569. DataColumn column5 = table.Columns["SOURCES_TYPE"];
  570. //DataColumn column4 = table.Columns["SOURCES_DESCRIPTION"];
  571. System.Collections.Generic.List<string> providerNames = new System.Collections.Generic.List<string>(table.Rows.Count);
  572. foreach(DataRow row in table.Rows) {
  573. int sourceType = (int)row[column5];
  574. if (DBSOURCETYPE_DATASOURCE_TDP == sourceType || DBSOURCETYPE_DATASOURCE_MDP == sourceType) {
  575. string progid = (string)row[column2];
  576. if (!OleDbConnectionString.IsMSDASQL(progid.ToLower(CultureInfo.InvariantCulture))) {
  577. if (0 > providerNames.IndexOf(progid)) {
  578. providerNames.Add(progid);
  579. }
  580. }
  581. }
  582. }
  583. // Create the standard values collection that contains the sources
  584. dataSourceNames = new StandardValuesCollection(providerNames);
  585. _standardValues = dataSourceNames;
  586. }
  587. return dataSourceNames;
  588. }
  589. }
  590. [Flags()] internal enum OleDbServiceValues : int {
  591. DisableAll = unchecked((int)0x00000000),
  592. ResourcePooling = unchecked((int)0x00000001),
  593. TransactionEnlistment = unchecked((int)0x00000002),
  594. ClientCursor = unchecked((int)0x00000004),
  595. AggregationAfterSession = unchecked((int)0x00000008),
  596. EnableAll = unchecked((int)0xffffffff),
  597. Default = ~(ClientCursor | AggregationAfterSession),
  598. };
  599. internal sealed class OleDbServicesConverter : TypeConverter {
  600. private StandardValuesCollection _standardValues;
  601. // converter classes should have public ctor
  602. public OleDbServicesConverter() : base() {
  603. }
  604. public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
  605. // Only know how to convert from a string
  606. return ((typeof(string) == sourceType) || base.CanConvertFrom(context, sourceType));
  607. }
  608. public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
  609. string svalue = (value as string);
  610. if (null != svalue) {
  611. Int32 services;
  612. if(Int32.TryParse(svalue, out services)) {
  613. return services;
  614. }
  615. else {
  616. if (svalue.IndexOf(',') != -1) {
  617. int convertedValue = 0;
  618. string[] values = svalue.Split(new char[] {','});
  619. foreach(string v in values) {
  620. convertedValue |= (int)(OleDbServiceValues)Enum.Parse(typeof(OleDbServiceValues), v, true);
  621. }
  622. return (int)convertedValue;;
  623. }
  624. else {
  625. return (int)(OleDbServiceValues)Enum.Parse(typeof(OleDbServiceValues), svalue, true);
  626. }
  627. }
  628. }
  629. return base.ConvertFrom(context, culture, value);
  630. }
  631. public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
  632. // Only know how to convert to the NetworkLibrary enumeration
  633. return ((typeof(string) == destinationType) || base.CanConvertTo(context, destinationType));
  634. }
  635. public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) {
  636. if ((typeof(string) == destinationType) && (null != value) && (typeof(Int32) == value.GetType())) {
  637. return Enum.Format(typeof(OleDbServiceValues), ((OleDbServiceValues)(int)value), "G");
  638. }
  639. return base.ConvertTo(context, culture, value, destinationType);
  640. }
  641. public override bool GetStandardValuesSupported(ITypeDescriptorContext context) {
  642. return true;
  643. }
  644. public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) {
  645. return false;
  646. }
  647. public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) {
  648. StandardValuesCollection standardValues = _standardValues;
  649. if (null == standardValues) {
  650. Array objValues = Enum.GetValues(typeof(OleDbServiceValues));
  651. Array.Sort(objValues, 0, objValues.Length);
  652. standardValues = new StandardValuesCollection(objValues);
  653. _standardValues = standardValues;
  654. }
  655. return standardValues;
  656. }
  657. public override bool IsValid(ITypeDescriptorContext context, object value) {
  658. return true;
  659. //return Enum.IsDefined(type, value);
  660. }
  661. }
  662. sealed internal class OleDbConnectionStringBuilderConverter : ExpandableObjectConverter {
  663. // converter classes should have public ctor
  664. public OleDbConnectionStringBuilderConverter() {
  665. }
  666. override public bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
  667. if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) {
  668. return true;
  669. }
  670. return base.CanConvertTo(context, destinationType);
  671. }
  672. override public object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
  673. if (destinationType == null) {
  674. throw ADP.ArgumentNull("destinationType");
  675. }
  676. if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) {
  677. OleDbConnectionStringBuilder obj = (value as OleDbConnectionStringBuilder);
  678. if (null != obj) {
  679. return ConvertToInstanceDescriptor(obj);
  680. }
  681. }
  682. return base.ConvertTo(context, culture, value, destinationType);
  683. }
  684. private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToInstanceDescriptor(OleDbConnectionStringBuilder options) {
  685. Type[] ctorParams = new Type[] { typeof(string) };
  686. object[] ctorValues = new object[] { options.ConnectionString };
  687. System.Reflection.ConstructorInfo ctor = typeof(OleDbConnectionStringBuilder).GetConstructor(ctorParams);
  688. return new System.ComponentModel.Design.Serialization.InstanceDescriptor(ctor, ctorValues);
  689. }
  690. }
  691. }
  692. }