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.

1927 lines
70 KiB

  1. //-- == 0-------------------------------------------------------------------------
  2. //
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 1992 - 1995
  6. //
  7. // File: utilprop.cxx
  8. //
  9. // Contents:
  10. //
  11. //
  12. // History: 08-28-96 shanksh Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. // Notes - there are two main methods in this module:
  16. // - CUtilProps::GetPropertyInfo, a helper function for
  17. // GetProperty method on Data Source
  18. // - CUtilProps::GetProperties, a helper function for
  19. // GetProperties method on Data Source, Session and Command objects
  20. // - CUtilProps::SetProperties, a helper function for
  21. // SetProperties method on Data Source, Session and Command objects
  22. //
  23. //
  24. // The implementation is very simple - we keep a global table of the
  25. // properties we support in s_rgprop. We search this table sequentially.
  26. //
  27. #include "oleds.hxx"
  28. #pragma hdrstop
  29. PROPSTRUCT s_rgDBInitProp[] =
  30. {
  31. {DBPROP_AUTH_PASSWORD, F_DBINITRW, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Password"},
  32. {DBPROP_AUTH_USERID, F_DBINITRW, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"User ID"},
  33. {DBPROP_AUTH_ENCRYPT_PASSWORD, F_DBINITRW, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Encrypt Password"},
  34. {DBPROP_AUTH_INTEGRATED, F_DBINITRW, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Integrated Security"},
  35. {DBPROP_INIT_DATASOURCE, F_DBINITRW, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Data Source"},
  36. {DBPROP_INIT_LOCATION, F_DBINITRW, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Location"},
  37. {DBPROP_INIT_PROVIDERSTRING, F_DBINITRW, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Extended Properties"},
  38. {DBPROP_INIT_TIMEOUT, F_DBINITRW, VT_I4, VARIANT_FALSE, 90, OPT_REQ, NULL, L"Connect Timeout"},
  39. {DBPROP_INIT_PROMPT, F_DBINITRW, VT_I2, VARIANT_FALSE, DBPROMPT_NOPROMPT, OPT_REQ, NULL, L"Prompt"},
  40. {DBPROP_INIT_HWND, F_DBINITRW, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Window Handle"},
  41. {DBPROP_INIT_MODE, F_DBINITRW, VT_I4, VARIANT_FALSE, DB_MODE_READ, OPT_REQ, NULL, L"Mode"}
  42. #if (!defined(BUILD_FOR_NT40))
  43. ,
  44. {DBPROP_INIT_BINDFLAGS, F_DBINITRW, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Bind Flags"}
  45. #endif
  46. };
  47. PROPSTRUCT s_rgADSIBindProp[] =
  48. {
  49. // initialize this property to a reserved value. The client is not supposed
  50. // to set this property to the reserved value. This reserved value prevents
  51. // ADSIFLAG from overriding ENCRYPT_PASSWORD when VB initializes this
  52. // property to its default value. See IsValidValue().
  53. {ADSIPROP_ADSIFLAG, F_DBINITRW, VT_I4, VARIANT_FALSE,
  54. ADS_AUTH_RESERVED, OPT_REQ, NULL, L"ADSI Flag"}
  55. };
  56. PROPSTRUCT s_rgDSInfoProp[] =
  57. {
  58. {DBPROP_ACTIVESESSIONS, F_DSRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Active Sessions"},
  59. {DBPROP_BYREFACCESSORS, F_DSRO, VT_BOOL, VARIANT_FALSE, 1, OPT_REQ, NULL, L"Pass By Ref Accessors"},
  60. {DBPROP_CATALOGLOCATION, F_DSRO, VT_I4, VARIANT_FALSE, DBPROPVAL_CL_START, OPT_REQ, NULL, L"Catalog Location"},
  61. {DBPROP_CATALOGTERM, F_DSRO, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Catalog Term"},
  62. {DBPROP_CATALOGUSAGE, F_DSRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Catalog Usage"},
  63. {DBPROP_DATASOURCENAME, F_DSRO, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, L"Active Directory Service Interfaces", L"Data Source Name"},
  64. {DBPROP_DATASOURCEREADONLY, F_DSRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"Read-Only Data Source"},
  65. // {DBPROP_DBMSNAME, F_DSRO, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"DBMS Name"},
  66. // {DBPROP_DBMSVER, F_DSRO, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"DBMS Version"},
  67. {DBPROP_DSOTHREADMODEL, F_DSRO, VT_I4, VARIANT_FALSE, DBPROPVAL_RT_FREETHREAD, OPT_REQ, NULL, L"Data Source Object Threading Model"},
  68. {DBPROP_MAXROWSIZE, F_DSRO, VT_I4, VARIANT_FALSE, 0, OPT_SIC, NULL, L"Maximum Row Size"},
  69. #if (!defined(BUILD_FOR_NT40))
  70. {DBPROP_OLEOBJECTS, F_DSRO, VT_I4, VARIANT_FALSE, DBPROPVAL_OO_ROWOBJECT | DBPROPVAL_OO_DIRECTBIND | DBPROPVAL_OO_SINGLETON, OPT_REQ, NULL, L"OLE Object Support"},
  71. #endif
  72. {DBPROP_PERSISTENTIDTYPE, F_DSRO, VT_I4, VARIANT_FALSE, DBPROPVAL_PT_NAME, OPT_SIC, NULL, L"Persistent ID Type"},
  73. {DBPROP_PROVIDERFRIENDLYNAME, F_DSRO, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, L"Microsoft OLE DB Provider for ADSI", L"Provider Friendly Name"},
  74. {DBPROP_PROVIDERNAME, F_DSRO, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, L"ACTIVEDS.DLL", L"Provider Name"},
  75. {DBPROP_PROVIDEROLEDBVER, F_DSRO, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, L"02.50", L"OLE DB Version"},
  76. {DBPROP_PROVIDERVER, F_DSRO, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, L"02.50.0000", L"Provider Version"},
  77. {DBPROP_SQLSUPPORT, F_DSRO, VT_I4, VARIANT_FALSE, DBPROPVAL_SQL_ODBC_MINIMUM, OPT_REQ, NULL, L"SQL Support"},
  78. {DBPROP_ROWSETCONVERSIONSONCOMMAND, F_DSRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"Rowset Conversions on Command"},
  79. {DBPROP_USERNAME, F_DSRO, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"User Name"}
  80. };
  81. PROPSTRUCT s_rgRowsetProp[] =
  82. {
  83. {DBPROP_IAccessor, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IAccessor"},
  84. {DBPROP_IColumnsInfo, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IColumnsInfo"},
  85. #if (!defined(BUILD_FOR_NT40))
  86. {DBPROP_IColumnsInfo2, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IColumnsInfo2"},
  87. #endif
  88. {DBPROP_IConvertType, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IConvertType"},
  89. #if (!defined(BUILD_FOR_NT40))
  90. {DBPROP_IGetSession, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IGetSession"},
  91. {DBPROP_IRow, F_ROWSETRW, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"IRow"},
  92. {DBPROP_IGetRow, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IGetRow"},
  93. #endif
  94. {DBPROP_IRowset, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IRowset"},
  95. {DBPROP_IRowsetIdentity, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_SIC, NULL, L"IRowsetIdentity"},
  96. {DBPROP_IRowsetInfo, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IRowsetInfo"},
  97. {DBPROP_IRowsetLocate, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IRowsetLocate"},
  98. {DBPROP_IRowsetScroll, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"IRowsetScroll"},
  99. {DBPROP_ABORTPRESERVE, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Preserve on Abort"},
  100. {DBPROP_BLOCKINGSTORAGEOBJECTS, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"Blocking Storage Objects"},
  101. {DBPROP_BOOKMARKS, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"Use Bookmarks"},
  102. {DBPROP_BOOKMARKSKIPPED, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Skip Deleted Bookmarks"},
  103. {DBPROP_BOOKMARKTYPE, F_ROWSETRO, VT_I4, VARIANT_FALSE, DBPROPVAL_BMK_NUMERIC, OPT_REQ, NULL, L"Bookmark Type"},
  104. {DBPROP_CANFETCHBACKWARDS, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_SIC, NULL, L"Fetch Backwards"},
  105. {DBPROP_CANHOLDROWS, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_SIC, NULL, L"Hold Rows"},
  106. {DBPROP_CANSCROLLBACKWARDS, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_SIC, NULL, L"Scroll Backwards"},
  107. {DBPROP_COLUMNRESTRICT, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_SIC, NULL, L"Column Privileges"},
  108. {DBPROP_COMMITPRESERVE, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Preserve on Commit"},
  109. {DBPROP_IMMOBILEROWS, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_SIC, NULL, L"Immobile Rows"},
  110. {DBPROP_LITERALBOOKMARKS, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_SIC, NULL, L"Literal Bookmarks"},
  111. {DBPROP_LITERALIDENTITY, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"Literal Row Identity"},
  112. {DBPROP_MAXOPENROWS, F_ROWSETRW, VT_I4, VARIANT_FALSE, 0, OPT_SIC, NULL, L"Maximum Open Rows"},
  113. {DBPROP_MAXPENDINGROWS, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_SIC, NULL, L"Maximum Pending Rows"},
  114. {DBPROP_MAXROWS, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_SIC, NULL, L"Maximum Rows"},
  115. {DBPROP_NOTIFICATIONPHASES, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Notification Phases"},
  116. // {DBPROP_NOTIFYCOLUMNRECALCULATED, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"NotifyColumnRecalculated"},
  117. {DBPROP_NOTIFYCOLUMNSET, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Column Set Notification"},
  118. // {DBPROP_NOTIFYROWACTIVATE, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"NotifyRowActivate"},
  119. {DBPROP_NOTIFYROWDELETE, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Row Delete Notification"},
  120. {DBPROP_NOTIFYROWFIRSTCHANGE, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Row First Change Notification"},
  121. {DBPROP_NOTIFYROWINSERT, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Row Insert Notification"},
  122. // {DBPROP_NOTIFYROWRELEASE, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"NotifyRowRelease"},
  123. {DBPROP_NOTIFYROWRESYNCH, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Row Resynchronization Notification"},
  124. {DBPROP_NOTIFYROWSETRELEASE, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Rowset Release Notification"},
  125. {DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Rowset Fetch Position Change Notification"},
  126. {DBPROP_NOTIFYROWUNDOCHANGE, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Row Undo Change Notification"},
  127. {DBPROP_NOTIFYROWUNDODELETE, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Row Undo Delete Notification"},
  128. {DBPROP_NOTIFYROWUNDOINSERT, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Row Undo Insert Notification"},
  129. {DBPROP_NOTIFYROWUPDATE, F_ROWSETRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Row Update Notification"},
  130. {DBPROP_ORDEREDBOOKMARKS, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_SIC, NULL, L"Bookmarks Ordered"},
  131. {DBPROP_OWNINSERT, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_SIC, NULL, L"Own Inserts Visible"},
  132. {DBPROP_OWNUPDATEDELETE, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_SIC, NULL, L"Own Changes Visible"},
  133. {DBPROP_QUICKRESTART, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_SIC, NULL, L"Quick Restart"},
  134. {DBPROP_REENTRANTEVENTS, F_ROWSETRO, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"Reentrant Events"},
  135. {DBPROP_REMOVEDELETED, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_SIC, NULL, L"Remove Deleted Rows"},
  136. {DBPROP_REPORTMULTIPLECHANGES, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Report Multiple Changes"},
  137. {DBPROP_ROWRESTRICT, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Row Privileges"},
  138. {DBPROP_ROWTHREADMODEL, F_ROWSETRO, VT_I4, VARIANT_FALSE, DBPROPVAL_RT_FREETHREAD, OPT_REQ, NULL, L"Row Threading Model"},
  139. {DBPROP_STRONGIDENTITY, F_ROWSETRO, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Strong Row Identity"},
  140. };
  141. PROPSTRUCT s_rgDBSessProp[] =
  142. {
  143. {DBPROP_SESS_AUTOCOMMITISOLEVELS, F_SESSRO, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Autocommit Isolation Levels"},
  144. };
  145. PROPSTRUCT s_rgADSISearchProp[12] =
  146. {
  147. {ADSIPROP_ASYNCHRONOUS, F_ADSIRW, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Asynchronous"},
  148. {ADSIPROP_DEREF_ALIASES, F_ADSIRW, VT_I4, VARIANT_FALSE, ADS_DEREF_NEVER, OPT_REQ, NULL, L"Deref Aliases"},
  149. {ADSIPROP_SIZE_LIMIT, F_ADSIRW, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Size Limit"},
  150. {ADSIPROP_TIME_LIMIT, F_ADSIRW, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Server Time Limit"},
  151. {ADSIPROP_ATTRIBTYPES_ONLY, F_ADSIRW, VT_BOOL, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Column Names only"},
  152. {ADSIPROP_SEARCH_SCOPE, F_ADSIRW, VT_I4, VARIANT_FALSE, ADS_SCOPE_SUBTREE, OPT_REQ, NULL, L"SearchScope"},
  153. {ADSIPROP_TIMEOUT, F_ADSIRW, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Timeout"},
  154. {ADSIPROP_PAGESIZE, F_ADSIRW, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Page size"},
  155. {ADSIPROP_PAGED_TIME_LIMIT, F_ADSIRW, VT_I4, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Time limit"},
  156. {ADSIPROP_CHASE_REFERRALS, F_ADSIRW, VT_I4, VARIANT_FALSE, ADS_CHASE_REFERRALS_NEVER, OPT_REQ, NULL, L"Chase referrals"},
  157. {ADSIPROP_SORT_ON, F_ADSIRW, VT_BSTR, VARIANT_FALSE, 0, OPT_REQ, NULL, L"Sort On"},
  158. {ADSIPROP_CACHE_RESULTS, F_ADSIRW, VT_BOOL, VARIANT_TRUE, 0, OPT_REQ, NULL, L"Cache Results"}
  159. };
  160. // Number of supported properties per property set
  161. #define NUMBER_OF_SUPPORTED_PROPERTY_SETS 6
  162. static PROPSET s_rgPropertySets[NUMBER_OF_SUPPORTED_PROPERTY_SETS] =
  163. {
  164. {&DBPROPSET_DBINIT, NUMELEM(s_rgDBInitProp), s_rgDBInitProp},
  165. {&DBPROPSET_ADSIBIND, NUMELEM(s_rgADSIBindProp), s_rgADSIBindProp},
  166. {&DBPROPSET_DATASOURCEINFO, NUMELEM(s_rgDSInfoProp), s_rgDSInfoProp},
  167. {&DBPROPSET_SESSION, NUMELEM(s_rgDBSessProp), s_rgDBSessProp},
  168. {&DBPROPSET_ROWSET, NUMELEM(s_rgRowsetProp), s_rgRowsetProp},
  169. {&DBPROPSET_ADSISEARCH, NUMELEM(s_rgADSISearchProp),s_rgADSISearchProp}
  170. };
  171. //
  172. // WARNING: Don't change the order. Add new property sets at the end
  173. //
  174. // Update: New property sets should not always be added at the end.
  175. // Property sets which have properties in the Initialization property group
  176. // have to be added before DATASOURCEINFO and prop. sets with properties
  177. // in the data source information property groups have to be added
  178. // before INDEX_SESSION and so on. This is for GetProperties to work correctly.
  179. //
  180. #define INDEX_INIT 0
  181. #define INDEX_ADSIBIND 1
  182. #define INDEX_DATASOURCEINFO 2
  183. #define INDEX_SESSION 3
  184. #define INDEX_ROWSET 4
  185. #define INDEX_ADSISEARCH 5
  186. //+---------------------------------------------------------------------------
  187. //
  188. // Function: CUtilProp::CUtilProp
  189. //
  190. // Synopsis: Constructor for this class
  191. //
  192. // Arguments:
  193. //
  194. // Returns:
  195. //
  196. // Modifies:
  197. //
  198. // History: 08-28-96 ShankSh Created.
  199. //
  200. //----------------------------------------------------------------------------
  201. CUtilProp::CUtilProp(
  202. void
  203. )
  204. {
  205. _pIMalloc = NULL;
  206. _pCredentials = NULL;
  207. _prgProperties = NULL;
  208. _dwDescBufferLen = 0;
  209. }
  210. //+---------------------------------------------------------------------------
  211. //
  212. // Function: CUtilProp::FInit
  213. //
  214. // Synopsis:
  215. //
  216. // Arguments:
  217. //
  218. // Returns:
  219. //
  220. // Modifies:
  221. //
  222. // History: 09-20-96 ShankSh Created.
  223. //
  224. // Update: pCredentials may be NULL if called from CRowset.
  225. //
  226. //----------------------------------------------------------------------------
  227. STDMETHODIMP
  228. CUtilProp::FInit(
  229. CCredentials *pCredentials
  230. )
  231. {
  232. HRESULT hr=S_OK;
  233. ULONG i, j;
  234. ULONG c = 0;
  235. //
  236. // Get the IMalloc interface pointer
  237. //
  238. hr = CoGetMalloc(MEMCTX_TASK, &_pIMalloc);
  239. BAIL_ON_FAILURE( hr );
  240. _pCredentials = pCredentials;
  241. _prgProperties = (PROPSTRUCT*) AllocADsMem(sizeof(PROPSTRUCT) *
  242. (NUMELEM(s_rgDBInitProp) +
  243. NUMELEM(s_rgADSIBindProp) +
  244. NUMELEM(s_rgDSInfoProp) +
  245. NUMELEM(s_rgDBSessProp) +
  246. NUMELEM(s_rgRowsetProp) +
  247. NUMELEM(s_rgADSISearchProp)) );
  248. if( !_prgProperties )
  249. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  250. for (i=c=0; i< NUMBER_OF_SUPPORTED_PROPERTY_SETS; i++) {
  251. for (j=0; j < s_rgPropertySets[i].cProperties; j++) {
  252. // Copy static structure
  253. memcpy( &_prgProperties[c],
  254. &s_rgPropertySets[i].pUPropInfo[j], sizeof(PROPSTRUCT) );
  255. // Allocate new BSTR value
  256. _prgProperties[c].pwstrVal =
  257. AllocADsStr(s_rgPropertySets[i].pUPropInfo[j].pwstrVal);
  258. // Add description length
  259. if( s_rgPropertySets[i].pUPropInfo[j].pwszDescription ) {
  260. _dwDescBufferLen += wcslen(s_rgPropertySets[i].pUPropInfo[j].pwszDescription) + 1;
  261. }
  262. c++;
  263. }
  264. }
  265. _dwDescBufferLen *= sizeof(WCHAR);
  266. ADsAssert( c == NUMELEM(s_rgDBInitProp) +
  267. NUMELEM(s_rgADSIBindProp) +
  268. NUMELEM(s_rgDSInfoProp) +
  269. NUMELEM(s_rgDBSessProp) +
  270. NUMELEM(s_rgRowsetProp) +
  271. NUMELEM(s_rgADSISearchProp) );
  272. error:
  273. RRETURN( hr );
  274. }
  275. //+---------------------------------------------------------------------------
  276. //
  277. // Function: CUtilProp::~CUtilProp
  278. //
  279. // Synopsis: Destructor for this class
  280. //
  281. // Arguments:
  282. //
  283. // Returns:
  284. //
  285. // Modifies:
  286. //
  287. // History: 08-28-96 ShankSh Created.
  288. //
  289. //----------------------------------------------------------------------------
  290. CUtilProp:: ~CUtilProp
  291. (
  292. void
  293. )
  294. {
  295. ULONG c = 0;
  296. if( _prgProperties )
  297. {
  298. // Clear all of the String values
  299. for (ULONG i=c=0; i< NUMBER_OF_SUPPORTED_PROPERTY_SETS; i++) {
  300. for (ULONG j=0; j < s_rgPropertySets[i].cProperties; j++) {
  301. if( _prgProperties[c].pwstrVal )
  302. FreeADsStr(_prgProperties[c].pwstrVal);
  303. c++;
  304. }
  305. }
  306. FreeADsMem(_prgProperties);
  307. }
  308. if( _pIMalloc )
  309. _pIMalloc->Release();
  310. return;
  311. }
  312. PROPSET *
  313. CUtilProp::GetPropSetFromGuid (
  314. GUID guidPropSet
  315. )
  316. {
  317. for (int j=0; j< NUMELEM(s_rgPropertySets); j++) {
  318. if (IsEqualGUID(guidPropSet,
  319. *(s_rgPropertySets[j].guidPropertySet)))
  320. return &(s_rgPropertySets[j]);
  321. }
  322. return NULL;
  323. }
  324. HRESULT
  325. CUtilProp::GetSearchPrefInfo(
  326. DBPROPID dwPropId,
  327. PADS_SEARCHPREF_INFO pSearchPrefInfo
  328. )
  329. {
  330. PADS_SORTKEY pSortKey = NULL;
  331. LPWSTR pszAttrs = NULL;
  332. LPWSTR pszFirstAttr = NULL;
  333. LPWSTR pszCurrentAttr = NULL, pszNextAttr = NULL, pszOrder = NULL;
  334. DWORD cAttrs = 0;
  335. HRESULT hr = S_OK;
  336. DWORD index;
  337. if (!pSearchPrefInfo) {
  338. RRETURN (E_INVALIDARG);
  339. }
  340. if (dwPropId >= g_cMapDBPropToSearchPref)
  341. RRETURN(E_FAIL);
  342. pSearchPrefInfo->dwSearchPref = g_MapDBPropIdToSearchPref[dwPropId];
  343. //
  344. // Get index of where ADSI search properties begin
  345. //
  346. index = NUMELEM(s_rgDBInitProp) +
  347. NUMELEM(s_rgADSIBindProp) +
  348. NUMELEM(s_rgDSInfoProp) +
  349. NUMELEM(s_rgDBSessProp) +
  350. NUMELEM(s_rgRowsetProp);
  351. switch (_prgProperties[index + dwPropId].vtType) {
  352. case VT_BOOL:
  353. pSearchPrefInfo->vValue.dwType = ADSTYPE_BOOLEAN;
  354. pSearchPrefInfo->vValue.Boolean =
  355. _prgProperties[index + dwPropId].boolVal == VARIANT_TRUE ? TRUE : FALSE;
  356. break;
  357. case VT_I4:
  358. case VT_I2:
  359. pSearchPrefInfo->vValue.dwType = ADSTYPE_INTEGER;
  360. pSearchPrefInfo->vValue.Integer = _prgProperties[index + dwPropId].longVal;
  361. break;
  362. case VT_BSTR: {
  363. if (pSearchPrefInfo->dwSearchPref != ADS_SEARCHPREF_SORT_ON) {
  364. //
  365. // right now, this is the only string preference supported
  366. //
  367. RRETURN (E_FAIL);
  368. }
  369. //
  370. // The preference is a list of atributes to be sorted on (in that order
  371. // and an optional indication of whether it has to be sorted ascending
  372. // or not.
  373. // eg., "name ASC, usnchanged DESC, cn"
  374. //
  375. pSearchPrefInfo->vValue.dwType = ADSTYPE_PROV_SPECIFIC;
  376. if (!_prgProperties[index + dwPropId].pwstrVal ||
  377. !_wcsicmp(_prgProperties[index + dwPropId].pwstrVal, L"")) {
  378. pSearchPrefInfo->vValue.ProviderSpecific.dwLength = 0;
  379. pSearchPrefInfo->vValue.ProviderSpecific.lpValue = NULL;
  380. break;
  381. }
  382. // make a copy
  383. pszAttrs = AllocADsStr(_prgProperties[index + dwPropId].pwstrVal);
  384. pszCurrentAttr = pszFirstAttr = wcstok(pszAttrs, L",");
  385. for(cAttrs=0; pszCurrentAttr != NULL; cAttrs++ ) {
  386. pszCurrentAttr = wcstok(NULL, L",");
  387. }
  388. if(cAttrs == 0) {
  389. BAIL_ON_FAILURE ( hr = E_ADS_BAD_PARAMETER );
  390. }
  391. pSortKey = (PADS_SORTKEY) AllocADsMem(sizeof(ADS_SORTKEY) * cAttrs);
  392. if (!pSortKey) {
  393. BAIL_ON_FAILURE ( E_OUTOFMEMORY );
  394. }
  395. pszCurrentAttr = pszFirstAttr;
  396. for (DWORD i=0 ; i < cAttrs; i++) {
  397. pszNextAttr = pszCurrentAttr + wcslen(pszCurrentAttr) + 1;
  398. pszCurrentAttr = RemoveWhiteSpaces(pszCurrentAttr);
  399. pszOrder = wcstok(pszCurrentAttr, L" ");
  400. pszOrder = pszOrder ? wcstok(NULL, L" ") : NULL;
  401. if (pszOrder && !_wcsicmp(pszOrder, L"DESC"))
  402. pSortKey[i].fReverseorder = 1;
  403. else
  404. pSortKey[i].fReverseorder = 0; // This is the default
  405. pSortKey[i].pszAttrType = AllocADsStr(pszCurrentAttr);
  406. pSortKey[i].pszReserved = NULL;
  407. pszCurrentAttr = pszNextAttr;
  408. }
  409. pSearchPrefInfo->vValue.ProviderSpecific.dwLength = sizeof(ADS_SORTKEY) * cAttrs;
  410. pSearchPrefInfo->vValue.ProviderSpecific.lpValue = (LPBYTE) pSortKey;
  411. break;
  412. }
  413. default:
  414. RRETURN (E_FAIL);
  415. }
  416. error:
  417. if (pszAttrs) {
  418. FreeADsStr(pszAttrs);
  419. }
  420. RRETURN(hr);
  421. }
  422. HRESULT
  423. CUtilProp::FreeSearchPrefInfo(
  424. PADS_SEARCHPREF_INFO pSearchPrefInfo,
  425. DWORD dwNumSearchPrefs
  426. )
  427. {
  428. PADS_SORTKEY pSortKey = NULL;
  429. DWORD nSortKeys = 0;
  430. if (!pSearchPrefInfo || !dwNumSearchPrefs) {
  431. RRETURN (S_OK);
  432. }
  433. for (DWORD i=0; i<dwNumSearchPrefs; i++) {
  434. switch(pSearchPrefInfo[i].vValue.dwType) {
  435. case ADSTYPE_BOOLEAN:
  436. case ADSTYPE_INTEGER:
  437. // do nothing
  438. break;
  439. case ADSTYPE_PROV_SPECIFIC:
  440. if (pSearchPrefInfo[i].dwSearchPref == ADS_SEARCHPREF_SORT_ON) {
  441. //
  442. // delete the strings allocated for each of the attributes
  443. // to be sorted
  444. nSortKeys = pSearchPrefInfo[i].vValue.ProviderSpecific.dwLength / sizeof(ADS_SORTKEY);
  445. pSortKey = (PADS_SORTKEY) pSearchPrefInfo[i].vValue.ProviderSpecific.lpValue;
  446. for (DWORD j=0; pSortKey && j<nSortKeys; j++) {
  447. FreeADsStr(pSortKey[j].pszAttrType);
  448. }
  449. if (pSortKey) {
  450. FreeADsMem(pSortKey);
  451. }
  452. }
  453. break;
  454. }
  455. }
  456. RRETURN (S_OK);
  457. }
  458. //+---------------------------------------------------------------------------
  459. //
  460. // Function: CUtilProp::LoadDBPROPINFO
  461. //
  462. // Synopsis: Helper for GetPropertyInfo. Loads field of DBPROPINFO
  463. // structure.
  464. //
  465. // Arguments:
  466. //
  467. // Returns: TRUE : Method succeeded
  468. // FALSE : Method failed (couldn't allocate memory)
  469. //
  470. // Modifies:
  471. //
  472. // History: 08-28-96 ShankSh Created.
  473. //
  474. //----------------------------------------------------------------------------
  475. STDMETHODIMP
  476. CUtilProp::LoadDBPROPINFO (
  477. PROPSTRUCT* pPropStruct,
  478. ULONG cProperties,
  479. DBPROPINFO* pPropInfo
  480. )
  481. {
  482. ULONG cCount;
  483. PROPSTRUCT* pProp=NULL;
  484. // asserts
  485. ADsAssert( pPropInfo );
  486. if( cProperties ) {
  487. ADsAssert( pPropStruct );
  488. }
  489. //
  490. // init the variant
  491. //
  492. VariantInit( &pPropInfo->vValues );
  493. for (cCount=0; cCount < cProperties; cCount++) {
  494. if(pPropInfo->dwPropertyID == pPropStruct[cCount].dwPropertyID)
  495. break;
  496. }
  497. if(cCount == cProperties) {
  498. pPropInfo->dwFlags = DBPROPFLAGS_NOTSUPPORTED;
  499. pPropInfo->pwszDescription = NULL;
  500. RRETURN (DB_S_ERRORSOCCURRED);
  501. }
  502. pProp = &(pPropStruct[cCount]);
  503. //
  504. // set the easy fields..
  505. //
  506. pPropInfo->dwPropertyID = pProp->dwPropertyID;
  507. pPropInfo->dwFlags = pProp->dwFlags;
  508. pPropInfo->vtType = pProp->vtType;
  509. // fill in the description
  510. if (pPropInfo->pwszDescription)
  511. wcscpy(pPropInfo->pwszDescription, pProp->pwszDescription);
  512. RRETURN(S_OK);
  513. }
  514. //+---------------------------------------------------------------------------
  515. //
  516. // Function: CUtilProp::LoadDBPROP
  517. //
  518. // Synopsis: Helper for GetProperties. Loads field of DBPROP structure.
  519. //
  520. // Arguments:
  521. //
  522. // Returns: TRUE : Method succeeded
  523. // FALSE : Method failed (couldn't allocate memory)
  524. //
  525. // Modifies:
  526. //
  527. // History: 08-28-96 ShankSh Created.
  528. //
  529. //----------------------------------------------------------------------------
  530. STDMETHODIMP
  531. CUtilProp::LoadDBPROP (
  532. PROPSTRUCT* pPropStruct,
  533. ULONG cProperties,
  534. DBPROP* pPropSupport,
  535. BOOL IsDBInitPropSet
  536. )
  537. {
  538. ULONG cCount;
  539. PROPSTRUCT* pProp=NULL;
  540. LPWSTR szUserName=NULL, szPassword=NULL;
  541. BOOL fAuthFlags=0;
  542. // asserts
  543. ADsAssert( pPropSupport );
  544. if( cProperties ) {
  545. ADsAssert( pPropStruct );
  546. }
  547. //
  548. // init the variant
  549. //
  550. VariantInit( &pPropSupport->vValue );
  551. for (cCount=0; cCount < cProperties; cCount++) {
  552. if( pPropSupport->dwPropertyID == pPropStruct[cCount].dwPropertyID )
  553. break;
  554. }
  555. if( cCount == cProperties ) {
  556. pPropSupport->dwStatus = DBPROPSTATUS_NOTSUPPORTED;
  557. RRETURN ( DB_S_ERRORSOCCURRED );
  558. }
  559. pProp = &(pPropStruct[cCount]);
  560. pPropSupport->colid = DB_NULLID;
  561. pPropSupport->dwOptions = pProp->dwOptions;
  562. //
  563. // set pPropSupport->vValue based on Variant type
  564. //
  565. switch (pProp->vtType) {
  566. case VT_BOOL:
  567. V_VT( &pPropSupport->vValue ) = VT_BOOL;
  568. V_BOOL( &pPropSupport->vValue ) = (SHORT)pProp->boolVal;
  569. break;
  570. case VT_I4:
  571. V_VT( &pPropSupport->vValue ) = VT_I4;
  572. V_I4( &pPropSupport->vValue ) = pProp->longVal;
  573. break;
  574. case VT_I2:
  575. V_VT( &pPropSupport->vValue ) = VT_I2;
  576. V_I2( &pPropSupport->vValue ) = (short)pProp->longVal;
  577. break;
  578. case VT_BSTR:
  579. //
  580. // If requesting password, get it from the credentials structure
  581. // as it is not stored anywhere else
  582. //
  583. if (IsDBInitPropSet &&
  584. pPropSupport->dwPropertyID == DBPROP_AUTH_PASSWORD)
  585. {
  586. PWSTR pszPassword = NULL;
  587. if (FAILED(_pCredentials->GetPassword(&pszPassword)))
  588. {
  589. VariantClear( &pPropSupport->vValue );
  590. return DB_S_ERRORSOCCURRED;
  591. }
  592. if (pszPassword)
  593. {
  594. V_VT(&pPropSupport->vValue) = VT_BSTR;
  595. V_BSTR(&pPropSupport->vValue)= SysAllocString(pszPassword);
  596. FreeADsMem(pszPassword);
  597. if( V_BSTR(&pPropSupport->vValue) == NULL ) {
  598. VariantClear( &pPropSupport->vValue );
  599. return DB_S_ERRORSOCCURRED;
  600. }
  601. }
  602. }
  603. else if( pProp->pwstrVal ) {
  604. V_VT(&pPropSupport->vValue) = VT_BSTR;
  605. V_BSTR(&pPropSupport->vValue)= SysAllocString(pProp->pwstrVal);
  606. if( V_BSTR(&pPropSupport->vValue) == NULL ) {
  607. VariantClear( &pPropSupport->vValue );
  608. return DB_S_ERRORSOCCURRED;
  609. }
  610. }
  611. break;
  612. default:
  613. ADsAssert( !"LoadDBPROP unknown variant type!\n\r" );
  614. pPropSupport->dwStatus = DBPROPSTATUS_BADVALUE;
  615. RRETURN (DB_S_ERRORSOCCURRED);
  616. break;
  617. }
  618. //
  619. // all went well
  620. //
  621. pPropSupport->dwStatus = DBPROPSTATUS_OK;
  622. RRETURN(S_OK);
  623. }
  624. //+---------------------------------------------------------------------------
  625. //
  626. // Function: CUtilProp::StoreDBProp
  627. //
  628. // Synopsis: Helper for SetProperties. Loads field of DBPROP structure.
  629. //
  630. // Arguments:
  631. //
  632. // Returns:
  633. //
  634. //
  635. // Modifies:
  636. //
  637. // History: 09-28-96 ShankSh Created.
  638. //
  639. //----------------------------------------------------------------------------
  640. STDMETHODIMP
  641. CUtilProp::StoreDBPROP (
  642. PROPSTRUCT* pPropStruct,
  643. PROPSTRUCT* pStaticPropStruct,
  644. ULONG cProperties,
  645. DBPROP* pPropSupport,
  646. DWORD dwPropIndex
  647. )
  648. {
  649. // asserts
  650. ADsAssert( pPropStruct );
  651. ADsAssert( pPropSupport );
  652. ULONG i;
  653. HRESULT hr=S_OK;
  654. // Initialize the status to DBPROPSTATUS_OK
  655. pPropSupport->dwStatus = DBPROPSTATUS_OK;
  656. for (i=0; i < cProperties; i++) {
  657. if(pPropStruct[i].dwPropertyID == pPropSupport->dwPropertyID) {
  658. // arg checking for the prop
  659. if( pPropSupport->dwOptions != DBPROPOPTIONS_OPTIONAL &&
  660. pPropSupport->dwOptions != DBPROPOPTIONS_REQUIRED ) {
  661. pPropSupport->dwStatus = DBPROPSTATUS_BADOPTION;
  662. hr = DB_S_ERRORSOCCURRED;
  663. goto error;
  664. }
  665. if( (pPropStruct[i].vtType != V_VT(&pPropSupport->vValue) &&
  666. V_VT(&pPropSupport->vValue) != VT_EMPTY) ||
  667. (IsValidValue(pPropSupport, dwPropIndex) == S_FALSE) ) {
  668. pPropSupport->dwStatus = DBPROPSTATUS_BADVALUE;
  669. hr = DB_S_ERRORSOCCURRED;
  670. goto error;
  671. }
  672. //
  673. // If property being set is password, we get out here.
  674. // Reason is we have already stored it in the Credentials structure
  675. // in encrypted form in the function IsVaidValue above.
  676. // We should not store it in plain text in pPropStruct[i].
  677. //
  678. if (dwPropIndex == INDEX_INIT &&
  679. pPropSupport->dwPropertyID == DBPROP_AUTH_PASSWORD)
  680. {
  681. pPropSupport->dwStatus = DBPROPSTATUS_OK;
  682. pPropStruct[i].dwOptions = pPropSupport->dwOptions;
  683. goto error;
  684. }
  685. if( !(pPropStruct[i].dwFlags & DBPROPFLAGS_WRITE) ) {
  686. // Check the value - if they are the same, do nothing
  687. if ( (V_VT(&pPropSupport->vValue) == VT_EMPTY) ||
  688. ((V_VT(&pPropSupport->vValue) == VT_BOOL) &&
  689. (pPropStruct[i].boolVal == V_BOOL(&pPropSupport->vValue))) ||
  690. ((V_VT(&pPropSupport->vValue) == VT_I4) &&
  691. (pPropStruct[i].longVal == V_I4(&pPropSupport->vValue))) ||
  692. ((V_VT(&pPropSupport->vValue) == VT_I2) &&
  693. ((short)pPropStruct[i].longVal == V_I2(&pPropSupport->vValue))) ||
  694. ((V_VT(&pPropSupport->vValue) == VT_BSTR) && pPropStruct[i].pwstrVal &&
  695. (wcscmp(pPropStruct[i].pwstrVal,V_BSTR(&pPropSupport->vValue)) == 0)) )
  696. goto error;
  697. if( pPropSupport->dwOptions != DBPROPOPTIONS_OPTIONAL )
  698. pPropSupport->dwStatus = DBPROPSTATUS_NOTSETTABLE;
  699. else
  700. pPropSupport->dwStatus = DBPROPSTATUS_NOTSET;
  701. hr = DB_S_ERRORSOCCURRED;
  702. goto error;
  703. }
  704. switch (pPropStruct[i].vtType) {
  705. case VT_BOOL:
  706. if( V_VT(&pPropSupport->vValue) != VT_EMPTY )
  707. pPropStruct[i].boolVal = V_BOOL( &pPropSupport->vValue );
  708. else
  709. pPropStruct[i].boolVal = pStaticPropStruct[i].boolVal;
  710. break;
  711. case VT_I4:
  712. if( V_VT(&pPropSupport->vValue) != VT_EMPTY )
  713. pPropStruct[i].longVal = V_I4( &pPropSupport->vValue );
  714. else
  715. pPropStruct[i].longVal = pStaticPropStruct[i].longVal;
  716. break;
  717. case VT_I2:
  718. if( V_VT(&pPropSupport->vValue) != VT_EMPTY )
  719. pPropStruct[i].longVal = V_I2( &pPropSupport->vValue );
  720. else
  721. pPropStruct[i].longVal = pStaticPropStruct[i].longVal;
  722. break;
  723. case VT_BSTR:
  724. if(pPropStruct[i].pwstrVal) {
  725. FreeADsStr(pPropStruct[i].pwstrVal);
  726. pPropStruct[i].pwstrVal = NULL;
  727. }
  728. if( V_VT(&pPropSupport->vValue) == VT_EMPTY )
  729. pPropStruct[i].pwstrVal = AllocADsStr(( pStaticPropStruct[i].pwstrVal ));
  730. else
  731. {
  732. if (V_BSTR( &pPropSupport->vValue) == NULL &&
  733. pPropSupport->dwPropertyID == DBPROP_AUTH_INTEGRATED)
  734. {
  735. //
  736. // For integrated security, NULL bstrVal implies 'use default
  737. // provider', which is "SSPI" for us. The reason we don't set
  738. // the defult value to SSPI in the static structure is
  739. // because this property is special. Unless set, it should
  740. // not be used.
  741. //
  742. pPropStruct[i].pwstrVal = AllocADsStr(L"SSPI");
  743. }
  744. else
  745. pPropStruct[i].pwstrVal = AllocADsStr(V_BSTR( &pPropSupport->vValue ));
  746. }
  747. if( !pPropStruct[i].pwstrVal &&
  748. V_VT(&pPropSupport->vValue) == VT_BSTR ) {
  749. hr = E_FAIL;
  750. goto error;
  751. }
  752. break;
  753. default:
  754. pPropSupport->dwStatus = DBPROPSTATUS_BADVALUE;
  755. hr = DB_S_ERRORSOCCURRED;
  756. goto error;
  757. }
  758. pPropSupport->dwStatus = DBPROPSTATUS_OK;
  759. pPropStruct[i].dwOptions = pPropSupport->dwOptions;
  760. break;
  761. }
  762. }
  763. if (i == cProperties) {
  764. pPropSupport->dwStatus = DBPROPSTATUS_NOTSUPPORTED;
  765. hr = DB_E_ERRORSOCCURRED;
  766. goto error;
  767. }
  768. error:
  769. RRETURN(hr);
  770. }
  771. //+---------------------------------------------------------------------------
  772. //
  773. // Function: CUtilProp::IsValidValue
  774. //
  775. // Synopsis: Helper for SetProperties. Check the valid values for the Property.
  776. //
  777. // Arguments:
  778. //
  779. // Returns:
  780. //
  781. //
  782. // Modifies:
  783. //
  784. // History: 09-28-96 ShankSh Created.
  785. //
  786. //----------------------------------------------------------------------------
  787. HRESULT
  788. CUtilProp::IsValidValue
  789. (
  790. DBPROP* pDBProp,
  791. DWORD dwPropIndex
  792. )
  793. {
  794. // Check BOOLEAN values
  795. if( (pDBProp->vValue.vt == VT_BOOL) &&
  796. !((V_BOOL(&(pDBProp->vValue)) == VARIANT_TRUE) ||
  797. (V_BOOL(&(pDBProp->vValue)) == VARIANT_FALSE)) )
  798. return S_FALSE;
  799. if( pDBProp->vValue.vt != VT_EMPTY &&
  800. dwPropIndex == INDEX_INIT )
  801. {
  802. switch( pDBProp->dwPropertyID )
  803. {
  804. case DBPROP_INIT_PROMPT:
  805. // These are the only values we support (from spec).
  806. if (!(V_I2(&pDBProp->vValue) == DBPROMPT_PROMPT ||
  807. V_I2(&pDBProp->vValue) == DBPROMPT_COMPLETE ||
  808. V_I2(&pDBProp->vValue) == DBPROMPT_COMPLETEREQUIRED ||
  809. V_I2(&pDBProp->vValue) == DBPROMPT_NOPROMPT))
  810. return S_FALSE;
  811. break;
  812. case DBPROP_INIT_TIMEOUT:
  813. if( (pDBProp->vValue.vt == VT_I4) &&
  814. (V_I4(&pDBProp->vValue) < 0) )
  815. return S_FALSE;
  816. break;
  817. case DBPROP_AUTH_USERID:
  818. if( (!_pCredentials) ||
  819. (S_OK != _pCredentials->SetUserName(V_BSTR(&pDBProp->vValue))) )
  820. return S_FALSE;
  821. break;
  822. case DBPROP_AUTH_PASSWORD:
  823. if( (!_pCredentials) ||
  824. (S_OK != _pCredentials->SetPassword(V_BSTR(&pDBProp->vValue))) )
  825. return S_FALSE;
  826. break;
  827. case DBPROP_AUTH_INTEGRATED:
  828. //
  829. // For integrated security, NULL bstrVal implies 'use default
  830. // provider', which is "SSPI" for us.
  831. //
  832. if( ((pDBProp->vValue.vt != VT_BSTR) &&
  833. (pDBProp->vValue.vt != VT_NULL)) ||
  834. ((V_BSTR(&pDBProp->vValue) != NULL) &&
  835. (wcscmp(V_BSTR(&pDBProp->vValue), L"SSPI") != 0)))
  836. return S_FALSE;
  837. break;
  838. case DBPROP_INIT_MODE:
  839. if( (pDBProp->vValue.vt != VT_I4) ||
  840. (S_FALSE == IsValidInitMode(V_I4(&pDBProp->vValue))) )
  841. return S_FALSE;
  842. break;
  843. #if (!defined(BUILD_FOR_NT40))
  844. case DBPROP_INIT_BINDFLAGS:
  845. if( (pDBProp->vValue.vt != VT_I4) ||
  846. (S_FALSE == IsValidBindFlag(V_I4(&pDBProp->vValue))) )
  847. return S_FALSE;
  848. break;
  849. #endif
  850. case DBPROP_AUTH_ENCRYPT_PASSWORD:
  851. if( !_pCredentials )
  852. return S_FALSE;
  853. if( IsADSIFlagSet() )
  854. // override this property if the user set the authentication
  855. break;
  856. BOOL fAuthFlags = _pCredentials->GetAuthFlags();
  857. if( V_BOOL(&pDBProp->vValue) )
  858. _pCredentials->SetAuthFlags(fAuthFlags | ADS_SECURE_AUTHENTICATION);
  859. else
  860. _pCredentials->SetAuthFlags(fAuthFlags & ~ADS_SECURE_AUTHENTICATION);
  861. break;
  862. }
  863. }
  864. else if( pDBProp->vValue.vt != VT_EMPTY &&
  865. dwPropIndex == INDEX_ADSIBIND )
  866. {
  867. switch( pDBProp->dwPropertyID )
  868. {
  869. case ADSIPROP_ADSIFLAG:
  870. if( !_pCredentials )
  871. // don't think this will ever happen
  872. return S_FALSE;
  873. // prevent default initialization by VB from setting the
  874. // AUTH flags. The client should not specify ADS_AUTH_RESERVED
  875. // for this property (this might happen if the client behaves
  876. // like VB i.e, does GetProperties and then SetProperties
  877. // without ORing in any flags. In this case, ENCRYPT_PASSWORD
  878. // will not be overwritten by this property due to this check).
  879. if( ADS_AUTH_RESERVED == (V_I4(&pDBProp->vValue)) )
  880. break;
  881. // the following call might overwrite ENCRYPT_PASSWORD
  882. _pCredentials->SetAuthFlags((V_I4(&pDBProp->vValue)) &
  883. (~ADS_AUTH_RESERVED) );
  884. break;
  885. }
  886. }
  887. else if( pDBProp->vValue.vt != VT_EMPTY &&
  888. dwPropIndex == INDEX_SESSION )
  889. {
  890. switch( pDBProp->dwPropertyID )
  891. {
  892. case DBPROP_SESS_AUTOCOMMITISOLEVELS:
  893. // These are the only values we support (from spec).
  894. if( (pDBProp->vValue.vt == VT_I4) &&
  895. (V_I4(&pDBProp->vValue) != 0 &&
  896. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_CHAOS &&
  897. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_READUNCOMMITTED &&
  898. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_READCOMMITTED &&
  899. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_REPEATABLEREAD &&
  900. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_SERIALIZABLE) )
  901. return S_FALSE;
  902. break;
  903. }
  904. }
  905. else if( pDBProp->vValue.vt != VT_EMPTY &&
  906. dwPropIndex == INDEX_ROWSET )
  907. {
  908. switch( pDBProp->dwPropertyID )
  909. {
  910. case DBPROP_MAXOPENROWS:
  911. if( (pDBProp->vValue.vt != VT_I4) ||
  912. (V_I4(&pDBProp->vValue) < 0) )
  913. return S_FALSE;
  914. break;
  915. }
  916. }
  917. return S_OK; // Is valid
  918. }
  919. //----------------------------------------------------------------------------
  920. // IsValidInitMode
  921. //
  922. // Checks if a given value is a valid value for DBPROP_INIT_MODE
  923. //
  924. //----------------------------------------------------------------------------
  925. HRESULT
  926. CUtilProp::IsValidInitMode(
  927. long lVal
  928. )
  929. {
  930. // check if any bit that shouldn't be set is actually set
  931. if( lVal & (~(DB_MODE_READWRITE |
  932. DB_MODE_SHARE_EXCLUSIVE | DB_MODE_SHARE_DENY_NONE)) )
  933. return S_FALSE;
  934. return S_OK;
  935. }
  936. //---------------------------------------------------------------------------
  937. // IsValidInitBindFlag
  938. //
  939. // Checks if a given value is a valid value for DBPROP_INIT_BINDFLAGS
  940. //
  941. //---------------------------------------------------------------------------
  942. HRESULT
  943. CUtilProp::IsValidBindFlag(
  944. long lVal
  945. )
  946. {
  947. #if (!defined(BUILD_FOR_NT40))
  948. // check if any bit that shouldn't be set is actually set
  949. if( lVal & (~(DB_BINDFLAGS_DELAYFETCHCOLUMNS |
  950. DB_BINDFLAGS_DELAYFETCHSTREAM | DB_BINDFLAGS_RECURSIVE |
  951. DB_BINDFLAGS_OUTPUT | DB_BINDFLAGS_COLLECTION |
  952. DB_BINDFLAGS_OPENIFEXISTS | DB_BINDFLAGS_OVERWRITE |
  953. DB_BINDFLAGS_ISSTRUCTUREDDOCUMENT)) )
  954. return S_FALSE;
  955. // check for mutually exclusive flags
  956. if( (lVal & DB_BINDFLAGS_OPENIFEXISTS) &&
  957. (lVal & DB_BINDFLAGS_OVERWRITE) )
  958. return S_FALSE;
  959. return S_OK;
  960. #else
  961. return E_FAIL;
  962. #endif
  963. }
  964. //+---------------------------------------------------------------------------
  965. //
  966. // Function: CUtilProp::GetPropertiesArgChk
  967. //
  968. // Synopsis: Initialize the buffers and check for E_INVALIDARG
  969. //
  970. // Arguments:
  971. // cPropertyIDSets # of restiction property IDs
  972. // rgPropertyIDSets[] restriction guids
  973. // pcPropertySets count of properties returned
  974. // prgPropertySets property information returned
  975. // dwBitMask which property group
  976. //
  977. // Returns:
  978. // S_OK | The method succeeded
  979. // E_INVALIDARG | pcPropertyIDSets or prgPropertyInfo was NULL
  980. //
  981. // Modifies:
  982. //
  983. // History: 08-28-96 ShankSh Created.
  984. //
  985. //----------------------------------------------------------------------------
  986. HRESULT
  987. CUtilProp::GetPropertiesArgChk(
  988. ULONG cPropertySets,
  989. const DBPROPIDSET rgPropertySets[],
  990. ULONG* pcProperties,
  991. DBPROPSET** prgProperties,
  992. DWORD dwBitMask
  993. )
  994. {
  995. // Initialize values
  996. if( pcProperties )
  997. *pcProperties = 0;
  998. if( prgProperties )
  999. *prgProperties = NULL;
  1000. // Check Arguments
  1001. if( ((cPropertySets > 0) && !rgPropertySets) ||
  1002. !pcProperties || !prgProperties )
  1003. RRETURN ( E_INVALIDARG );
  1004. // New argument check for > 1 cPropertyIDs and NULL pointer for
  1005. // array of property ids.
  1006. for(ULONG ul=0; ul<cPropertySets; ul++)
  1007. {
  1008. if( rgPropertySets[ul].cPropertyIDs && !(rgPropertySets[ul].rgPropertyIDs) )
  1009. RRETURN ( E_INVALIDARG );
  1010. // Check for propper formation of DBPROPSET_PROPERTIESINERROR
  1011. if( ((dwBitMask & PROPSET_DSO) || (dwBitMask & PROPSET_COMMAND)) &&
  1012. (rgPropertySets[ul].guidPropertySet == DBPROPSET_PROPERTIESINERROR) )
  1013. {
  1014. if( (cPropertySets > 1) ||
  1015. (rgPropertySets[ul].cPropertyIDs != 0) ||
  1016. (rgPropertySets[ul].rgPropertyIDs != NULL) )
  1017. RRETURN ( E_INVALIDARG );
  1018. }
  1019. }
  1020. RRETURN ( S_OK );
  1021. }
  1022. //+---------------------------------------------------------------------------
  1023. //
  1024. // Function: CUtilProp::GetPropertyInfo
  1025. //
  1026. // Synopsis: Returns information about rowset and data source properties
  1027. // supported by the provider
  1028. //
  1029. // Arguments:
  1030. // cPropertyIDSets # properties
  1031. // rgPropertyIDSets[] Array of property sets
  1032. // pcPropertyInfoSets # DBPROPSET structures
  1033. // prgPropertyInfoSets DBPROPSET structures property
  1034. // information returned
  1035. // ppDescBuffer Property descriptions
  1036. //
  1037. // Returns:
  1038. // S_OK | The method succeeded
  1039. // E_INVALIDARG | pcPropertyIDSets or prgPropertyInfo was NULL
  1040. // E_OUTOFMEMORY | Out of memory
  1041. //
  1042. // Modifies:
  1043. //
  1044. // History: 08-28-96 ShankSh Created.
  1045. //
  1046. //----------------------------------------------------------------------------
  1047. STDMETHODIMP CUtilProp::GetPropertyInfo
  1048. (
  1049. ULONG cPropertyIDSets,
  1050. const DBPROPIDSET rgPropertyIDSets[],
  1051. ULONG* pcPropertyInfoSets,
  1052. DBPROPINFOSET** pprgPropertyInfoSets,
  1053. WCHAR** ppDescBuffer,
  1054. BOOL fDSOInitialized
  1055. )
  1056. {
  1057. DBPROPINFO* pPropInfo = NULL;
  1058. DBPROPINFOSET* pPropInfoSet = NULL;
  1059. BOOL fNoPropInfoGot = TRUE;
  1060. BOOL fWarning=FALSE;
  1061. HRESULT hr;
  1062. LPWSTR pwszDescBuffer=NULL;
  1063. ULONG cPropertySets=0, cProperties=0;
  1064. ULONG cCount, j, i;
  1065. ULONG cNewPropIDSets = 0;
  1066. BOOL fIsSpecialGUID = FALSE;
  1067. BOOL fIsNotSpecialGUID = FALSE;
  1068. ULONG ul;
  1069. BOOL fNewDescription = TRUE;
  1070. // asserts
  1071. ADsAssert( _pIMalloc );
  1072. // init out params
  1073. if( pcPropertyInfoSets )
  1074. *pcPropertyInfoSets = 0;
  1075. if( pprgPropertyInfoSets )
  1076. *pprgPropertyInfoSets = NULL;
  1077. if( ppDescBuffer )
  1078. *ppDescBuffer = NULL;
  1079. // Check Arguments, on failure post HRESULT to error queue
  1080. if( (cPropertyIDSets > 0 && !rgPropertyIDSets) ||
  1081. !pcPropertyInfoSets || !pprgPropertyInfoSets )
  1082. RRETURN( E_INVALIDARG );
  1083. // New argument check for > 1 cPropertyIDs and NULL pointer for
  1084. // array of property ids.
  1085. for(ul=0; ul<cPropertyIDSets; ul++)
  1086. {
  1087. if( rgPropertyIDSets[ul].cPropertyIDs &&
  1088. !rgPropertyIDSets[ul].rgPropertyIDs )
  1089. RRETURN( E_INVALIDARG );
  1090. // Add 1 for the Provider Specific Rowset Properties
  1091. if( (rgPropertyIDSets[ul].guidPropertySet == DBPROPSET_DBINITALL) ||
  1092. (fDSOInitialized &&
  1093. rgPropertyIDSets[ul].guidPropertySet == DBPROPSET_ROWSETALL) )
  1094. cNewPropIDSets++;
  1095. //
  1096. // Special Guids for Property Sets can not be mixed with ordinary
  1097. // Property Set Guids. Either one or the other, not both
  1098. //
  1099. if (IsSpecialGuid(rgPropertyIDSets[ul].guidPropertySet))
  1100. fIsSpecialGUID = TRUE;
  1101. else
  1102. fIsNotSpecialGUID = TRUE;
  1103. if( fIsSpecialGUID && fIsNotSpecialGUID )
  1104. RRETURN( E_INVALIDARG );
  1105. }
  1106. // save the count of PropertyIDSets
  1107. cNewPropIDSets += cPropertyIDSets;
  1108. // If the consumer does not restrict the property sets
  1109. // by specify an array of property sets and a cPropertySets
  1110. // greater than 0, then we need to make sure we
  1111. // have some to return
  1112. if( cPropertyIDSets == 0 )
  1113. {
  1114. if( fDSOInitialized )
  1115. cNewPropIDSets = NUMBER_OF_SUPPORTED_PROPERTY_SETS;
  1116. else
  1117. // we have 2 property sets in the DBINIT property group
  1118. cNewPropIDSets = 2;
  1119. }
  1120. // use task memory allocater to alloc a DBPROPINFOSET struct
  1121. pPropInfoSet = (DBPROPINFOSET*) _pIMalloc->Alloc(cNewPropIDSets *
  1122. sizeof( DBPROPINFOSET ));
  1123. if( !pPropInfoSet )
  1124. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1125. memset( pPropInfoSet, 0, (cNewPropIDSets * sizeof( DBPROPINFOSET )));
  1126. if( ppDescBuffer )
  1127. {
  1128. // Allocating more memory than actually required, since
  1129. // _dwDescBufferLen is th etotal for all property sets together, not
  1130. // just for one property set
  1131. pwszDescBuffer = (LPWSTR) _pIMalloc->Alloc(_dwDescBufferLen * cNewPropIDSets);
  1132. if( !pwszDescBuffer )
  1133. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1134. memset( pwszDescBuffer, 0, _dwDescBufferLen * cNewPropIDSets);
  1135. *ppDescBuffer = pwszDescBuffer;
  1136. }
  1137. // If no restrictions return all properties from the three supported property sets
  1138. if( cPropertyIDSets == 0 )
  1139. {
  1140. // Fill in all of the Providers Properties
  1141. for (j=0; j< cNewPropIDSets; j++)
  1142. pPropInfoSet[j].guidPropertySet = *s_rgPropertySets[j].guidPropertySet;
  1143. }
  1144. else
  1145. {
  1146. cCount = 0;
  1147. //
  1148. // Deal with the Special GUID's
  1149. //
  1150. for (j=0; j< cPropertyIDSets; j++)
  1151. {
  1152. if( rgPropertyIDSets[j].guidPropertySet == DBPROPSET_DBINITALL )
  1153. {
  1154. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_DBINIT;
  1155. // Adjust for ADSI_BIND (provider specific) property set
  1156. cCount++;
  1157. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_ADSIBIND;
  1158. }
  1159. else if( fDSOInitialized &&
  1160. rgPropertyIDSets[j].guidPropertySet == DBPROPSET_DATASOURCEINFOALL )
  1161. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_DATASOURCEINFO;
  1162. else if( fDSOInitialized &&
  1163. rgPropertyIDSets[j].guidPropertySet == DBPROPSET_SESSIONALL )
  1164. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_SESSION;
  1165. else if( fDSOInitialized &&
  1166. rgPropertyIDSets[j].guidPropertySet == DBPROPSET_ROWSETALL )
  1167. {
  1168. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_ROWSET;
  1169. // Adjust for the Provider Specific
  1170. cCount++;
  1171. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_ADSISEARCH;
  1172. }
  1173. else
  1174. {
  1175. pPropInfoSet[cCount].guidPropertySet = rgPropertyIDSets[j].guidPropertySet;
  1176. pPropInfoSet[cCount].cPropertyInfos = rgPropertyIDSets[j].cPropertyIDs;
  1177. }
  1178. cCount++;
  1179. }
  1180. }
  1181. //
  1182. // For each supported Property Set
  1183. //
  1184. for (cPropertySets=0;
  1185. cPropertySets < cNewPropIDSets;
  1186. cPropertySets++)
  1187. {
  1188. // Set cProperties to the numerber passed in
  1189. cProperties = pPropInfoSet[cPropertySets].cPropertyInfos;
  1190. pPropInfo = NULL;
  1191. // Get the correct Static data. We have 2 property sets in the
  1192. // INIT property group. Note that we assume that both these property
  1193. // sets occur successively in s_rgPropertySets.
  1194. for (j=0; j< (fDSOInitialized ? NUMELEM(s_rgPropertySets) : 2); j++) {
  1195. if( IsEqualGUID(pPropInfoSet[cPropertySets].guidPropertySet,
  1196. *(s_rgPropertySets[j].guidPropertySet)) ) {
  1197. if( pPropInfoSet[cPropertySets].cPropertyInfos == 0 )
  1198. cProperties = s_rgPropertySets[j].cProperties;
  1199. break;
  1200. }
  1201. }
  1202. if( cProperties )
  1203. {
  1204. //
  1205. // use task memory allocater to alloc array of DBPROPINFO structs
  1206. //
  1207. pPropInfo = (DBPROPINFO*) _pIMalloc->Alloc(cProperties * sizeof( DBPROPINFO ));
  1208. if( !pPropInfo ) {
  1209. for (i=0; i<cNewPropIDSets; i++)
  1210. _pIMalloc->Free(pPropInfoSet[i].rgPropertyInfos);
  1211. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1212. }
  1213. memset(pPropInfo, 0, cProperties * sizeof(DBPROPINFO));
  1214. for (cCount=0; cCount < cProperties; cCount++)
  1215. {
  1216. if( pPropInfoSet[cPropertySets].cPropertyInfos == 0 )
  1217. pPropInfo[cCount].dwPropertyID =
  1218. s_rgPropertySets[j].pUPropInfo[cCount].dwPropertyID;
  1219. else
  1220. pPropInfo[cCount].dwPropertyID =
  1221. rgPropertyIDSets[cPropertySets].rgPropertyIDs[cCount];
  1222. // set the description pointer. If this property was already
  1223. // requested in this call, then we reuse the same description
  1224. // pointer.
  1225. DWORD dwTmp;
  1226. for(dwTmp = 0; dwTmp < cCount; dwTmp++)
  1227. if(pPropInfo[dwTmp].dwPropertyID ==
  1228. pPropInfo[cCount].dwPropertyID)
  1229. // same property requested more than once
  1230. break;
  1231. if(dwTmp == cCount)
  1232. {
  1233. fNewDescription = TRUE;
  1234. pPropInfo[cCount].pwszDescription = pwszDescBuffer;
  1235. }
  1236. else
  1237. {
  1238. fNewDescription = FALSE;
  1239. pPropInfo[cCount].pwszDescription =
  1240. pPropInfo[dwTmp].pwszDescription;
  1241. }
  1242. hr = LoadDBPROPINFO(
  1243. ((j < (fDSOInitialized ? NUMELEM(s_rgPropertySets) : 2)) ?
  1244. s_rgPropertySets[j].pUPropInfo : NULL),
  1245. ((j < (fDSOInitialized ? NUMELEM(s_rgPropertySets) : 2)) ?
  1246. s_rgPropertySets[j].cProperties : 0),
  1247. &pPropInfo[cCount]
  1248. );
  1249. if( FAILED(hr) ) {
  1250. ULONG ulFor;
  1251. //
  1252. // something went wrong
  1253. // clear all variants used so far..
  1254. //
  1255. for (ulFor = 0; ulFor < cCount; ulFor++)
  1256. VariantClear( &pPropInfo[ulFor].vValues );
  1257. //
  1258. // .. delete the pPropInfo array, return failure
  1259. //
  1260. for (i=0; i<cNewPropIDSets; i++)
  1261. _pIMalloc->Free(pPropInfoSet[i].rgPropertyInfos);
  1262. _pIMalloc->Free(pPropInfo);
  1263. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1264. }
  1265. if( hr != S_OK )
  1266. fWarning = TRUE;
  1267. else
  1268. fNoPropInfoGot = FALSE;
  1269. // move the description pointer to the next, if required
  1270. if( pPropInfo[cCount].pwszDescription && fNewDescription)
  1271. pwszDescBuffer += (wcslen(pPropInfo[cCount].pwszDescription) + 1);
  1272. }
  1273. }
  1274. else
  1275. fWarning = TRUE;
  1276. pPropInfoSet[cPropertySets].rgPropertyInfos = pPropInfo;
  1277. pPropInfoSet[cPropertySets].cPropertyInfos = cProperties;
  1278. } // for each property set
  1279. //
  1280. // set count of properties and property information
  1281. //
  1282. *pcPropertyInfoSets= cNewPropIDSets;
  1283. *pprgPropertyInfoSets = pPropInfoSet;
  1284. if( fNoPropInfoGot ) {
  1285. if( ppDescBuffer )
  1286. *ppDescBuffer = NULL;
  1287. if( pwszDescBuffer )
  1288. _pIMalloc->Free(pwszDescBuffer);
  1289. RRETURN ( DB_E_ERRORSOCCURRED );
  1290. }
  1291. else if( fWarning )
  1292. RRETURN ( DB_S_ERRORSOCCURRED );
  1293. else
  1294. RRETURN ( S_OK );
  1295. error:
  1296. if( pPropInfoSet )
  1297. _pIMalloc->Free(pPropInfoSet);
  1298. if( pwszDescBuffer )
  1299. _pIMalloc->Free(pwszDescBuffer);
  1300. RRETURN ( hr );
  1301. }
  1302. //----------------------------------------------------------------------------
  1303. // IsSpecialGuid
  1304. //
  1305. // Check if the the property set GUID is one of the special GUIDs
  1306. //
  1307. //----------------------------------------------------------------------------
  1308. BOOL CUtilProp::IsSpecialGuid(
  1309. GUID guidPropSet
  1310. )
  1311. {
  1312. if( (DBPROPSET_ROWSETALL == guidPropSet) ||
  1313. (DBPROPSET_DATASOURCEALL == guidPropSet) ||
  1314. (DBPROPSET_DATASOURCEINFOALL == guidPropSet) ||
  1315. (DBPROPSET_SESSIONALL == guidPropSet) ||
  1316. (DBPROPSET_DBINITALL == guidPropSet)
  1317. #if (!defined(BUILD_FOR_NT40))
  1318. ||
  1319. (DBPROPSET_COLUMNALL == guidPropSet) ||
  1320. (DBPROPSET_CONSTRAINTALL == guidPropSet) ||
  1321. (DBPROPSET_INDEXALL == guidPropSet) ||
  1322. (DBPROPSET_TABLEALL == guidPropSet) ||
  1323. (DBPROPSET_TRUSTEEALL == guidPropSet) ||
  1324. (DBPROPSET_VIEWALL == guidPropSet)
  1325. #endif
  1326. )
  1327. return TRUE;
  1328. else
  1329. return FALSE;
  1330. }
  1331. //+---------------------------------------------------------------------------
  1332. //
  1333. // Function: CUtilProp::GetProperties
  1334. //
  1335. // Synopsis: Returns current settings of all properties supported
  1336. // by the DSO/rowset
  1337. //
  1338. // Arguments:
  1339. //
  1340. // cPropertyIDSets # of restiction property IDs
  1341. // rgPropertyIDSets[] restriction guids
  1342. // pcPropertySets count of properties returned
  1343. // prgPropertySets property information returned
  1344. //
  1345. //
  1346. // Returns:
  1347. // S_OK | The method succeeded
  1348. // E_INVALIDARG | pcPropertyIDSets or prgPropertyInfo was NULL
  1349. // E_OUTOFMEMORY | Out of memory
  1350. //
  1351. // Modifies:
  1352. //
  1353. // History: 08-28-96 ShankSh Created.
  1354. //
  1355. //----------------------------------------------------------------------------
  1356. STDMETHODIMP CUtilProp::GetProperties
  1357. (
  1358. ULONG cPropertyIDSets,
  1359. const DBPROPIDSET rgPropertyIDSets[],
  1360. ULONG* pcPropertySets,
  1361. DBPROPSET** pprgPropertySets,
  1362. DWORD dwBitMask
  1363. )
  1364. {
  1365. ULONG cPropertySets, cProperties;
  1366. ULONG cNewPropIDSets = 0;
  1367. ULONG cCount, j, i;
  1368. DBPROP* pProp = NULL;
  1369. DBPROPSET* pPropSet = NULL;
  1370. HRESULT hr = E_FAIL;
  1371. BOOL fNoPropertyGot = TRUE;
  1372. BOOL fWarning = FALSE;
  1373. BOOL fFound = FALSE;
  1374. ULONG cOffset = 0;
  1375. // asserts
  1376. ADsAssert(_pIMalloc);
  1377. // Assign in the count
  1378. cNewPropIDSets = cPropertyIDSets;
  1379. // If the consumer does not restrict the property sets
  1380. // by specify an array of property sets and a cPropertySets
  1381. // greater than 0, then we need to make sure we
  1382. // have some to return
  1383. if( cPropertyIDSets == 0 )
  1384. {
  1385. // Set the count of properties
  1386. cNewPropIDSets = 1;
  1387. if(dwBitMask & PROPSET_DSO)
  1388. {
  1389. if(dwBitMask & PROPSET_INIT)
  1390. // if the data src object has been initialized, return
  1391. // properties in the DBInit, DSInfo and ADSIBind property sets.
  1392. cNewPropIDSets = 3;
  1393. else
  1394. // Return DBInit and ADSIBind property sets only. Note that we
  1395. // are counting on ADSIBind being the second property set in
  1396. // s_rgPropertySets, since we are leaving cOffset as 0
  1397. cNewPropIDSets = 2;
  1398. }
  1399. if(dwBitMask & PROPSET_COMMAND)
  1400. cNewPropIDSets = 2;
  1401. }
  1402. // Figure out the Offset
  1403. if( dwBitMask & PROPSET_SESSION )
  1404. cOffset = INDEX_SESSION;
  1405. else if( dwBitMask & PROPSET_COMMAND )
  1406. cOffset = INDEX_ROWSET;
  1407. //
  1408. // use task memory allocater to alloc a DBPROPSET struct
  1409. //
  1410. pPropSet = (DBPROPSET*) _pIMalloc->Alloc(cNewPropIDSets * sizeof( DBPROPSET ));
  1411. if( !pPropSet )
  1412. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1413. memset( pPropSet, 0, (cNewPropIDSets * sizeof( DBPROPSET )));
  1414. //
  1415. // For each supported Property Set
  1416. //
  1417. for (cPropertySets=0; cPropertySets < cNewPropIDSets; cPropertySets++) {
  1418. // Initialize variable
  1419. ULONG cPropOffset = 0;
  1420. int cNumDSOProps = 0;
  1421. cProperties = 0;
  1422. pProp = NULL;
  1423. fFound = FALSE;
  1424. // Setup the PropSet GUID
  1425. if( cPropertyIDSets == 0 ) {
  1426. pPropSet[cPropertySets].guidPropertySet =
  1427. *s_rgPropertySets[cPropertySets+cOffset].guidPropertySet;
  1428. }
  1429. else {
  1430. cProperties = rgPropertyIDSets[cPropertySets].cPropertyIDs;
  1431. pPropSet[cPropertySets].guidPropertySet =
  1432. rgPropertyIDSets[cPropertySets].guidPropertySet;
  1433. }
  1434. if(dwBitMask & PROPSET_DSO)
  1435. // we have 2 property sets whose properties can be set before
  1436. // initialization and one whose properties can be set only after
  1437. // init. Set the count of properties accordingly.
  1438. cNumDSOProps = 1 + !!(dwBitMask & PROPSET_INIT);
  1439. // Setup the count of Properties for that PropSet
  1440. for (j=0;
  1441. j <= cOffset+ cNumDSOProps + !!(dwBitMask & PROPSET_COMMAND);
  1442. j++) {
  1443. if( j >= cOffset &&
  1444. IsEqualGUID(pPropSet[cPropertySets].guidPropertySet,
  1445. *(s_rgPropertySets[j].guidPropertySet)) ) {
  1446. if (rgPropertyIDSets == NULL ||
  1447. rgPropertyIDSets[cPropertySets].cPropertyIDs == 0)
  1448. cProperties = s_rgPropertySets[j].cProperties;
  1449. fFound = TRUE;
  1450. break;
  1451. }
  1452. // Move to the next PropSet
  1453. cPropOffset += s_rgPropertySets[j].cProperties;
  1454. }
  1455. if( cProperties != 0 ) {
  1456. // use task memory allocator to alloc array of DBPROP struct
  1457. pProp = (DBPROP*) _pIMalloc->Alloc(cProperties * sizeof( DBPROP ));
  1458. if( pProp == NULL ) {
  1459. for (i=0; i < cPropertySets; i++)
  1460. _pIMalloc->Free(pPropSet[i].rgProperties);
  1461. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1462. }
  1463. memset( pProp, 0, (cProperties * sizeof( DBPROP )));
  1464. if( rgPropertyIDSets == NULL ||
  1465. rgPropertyIDSets[cPropertySets].cPropertyIDs == 0 ) {
  1466. for (cCount=0; cCount < cProperties; cCount++)
  1467. pProp[cCount].dwPropertyID =
  1468. s_rgPropertySets[j-!fFound].pUPropInfo[cCount].dwPropertyID;
  1469. }
  1470. else {
  1471. for (cCount=0; cCount < cProperties; cCount++)
  1472. pProp[cCount].dwPropertyID =
  1473. rgPropertyIDSets[cPropertySets].rgPropertyIDs[cCount];
  1474. }
  1475. }
  1476. else
  1477. fWarning = TRUE;
  1478. //
  1479. // for each prop in our table..
  1480. //
  1481. for (cCount = 0; cCount < cProperties; cCount++) {
  1482. hr = LoadDBPROP((fFound ? &(_prgProperties[cPropOffset]) : NULL),
  1483. (fFound ? s_rgPropertySets[j-!fFound].cProperties : 0),
  1484. &pProp[cCount],
  1485. pPropSet[cPropertySets].guidPropertySet == DBPROPSET_DBINIT
  1486. );
  1487. if( FAILED(hr) ) {
  1488. // something went wrong
  1489. // clear all variants used so far..
  1490. for (i=0; i < cCount; i++)
  1491. VariantClear( &pProp[i].vValue );
  1492. for (i=0; i < cPropertySets; i++)
  1493. _pIMalloc->Free(pPropSet[i].rgProperties);
  1494. _pIMalloc->Free(pProp);
  1495. BAIL_ON_FAILURE( hr );
  1496. }
  1497. if( hr != S_OK )
  1498. fWarning = TRUE;
  1499. else
  1500. fNoPropertyGot = FALSE;
  1501. } // for each property
  1502. pPropSet[cPropertySets].rgProperties = pProp;
  1503. pPropSet[cPropertySets].cProperties = cProperties;
  1504. } // for each property set
  1505. // set count of properties and property informatio
  1506. *pcPropertySets = cNewPropIDSets;
  1507. *pprgPropertySets = pPropSet;
  1508. if( fNoPropertyGot )
  1509. RRETURN( DB_E_ERRORSOCCURRED );
  1510. else if( fWarning )
  1511. RRETURN( DB_S_ERRORSOCCURRED );
  1512. else
  1513. RRETURN( S_OK );
  1514. error:
  1515. if( pPropSet )
  1516. _pIMalloc->Free(pPropSet);
  1517. RRETURN( hr );
  1518. }
  1519. //+---------------------------------------------------------------------------
  1520. //
  1521. // Function: CUtilProp::SetProperties
  1522. //
  1523. // Synopsis: Set current settings of properties supported by the DSO/rowset
  1524. //
  1525. // Arguments:
  1526. //
  1527. // cPropertyIDSets, # of DBPROPSET
  1528. // rgPropertyIDSets[] Array of property sets
  1529. //
  1530. // Returns:
  1531. // S_OK | The method succeeded
  1532. // E_INVALIDARG | pcPropertyIDSets or prgPropertyInfo was NULL
  1533. // E_OUTOFMEMORY | Out of memory
  1534. //
  1535. // Modifies:
  1536. //
  1537. // History: 08-28-96 ShankSh Created.
  1538. //
  1539. //----------------------------------------------------------------------------
  1540. STDMETHODIMP
  1541. CUtilProp::SetProperties(
  1542. ULONG cPropertySets,
  1543. DBPROPSET rgPropertySets[],
  1544. DWORD dwBitMask
  1545. )
  1546. {
  1547. ULONG cCount, j, k;
  1548. HRESULT hr;
  1549. BOOL fNoPropertySet = TRUE;
  1550. BOOL fWarning = FALSE;
  1551. // check params
  1552. if( cPropertySets > 0 && !rgPropertySets )
  1553. RRETURN ( E_INVALIDARG );
  1554. // New argument check for > 1 cPropertyIDs and NULL pointer for
  1555. // array of property ids.
  1556. for(ULONG ul=0; ul<cPropertySets; ul++)
  1557. {
  1558. if( rgPropertySets[ul].cProperties &&
  1559. !(rgPropertySets[ul].rgProperties) )
  1560. RRETURN ( E_INVALIDARG );
  1561. }
  1562. for (cCount=0; cCount < cPropertySets; cCount++) {
  1563. // Not legal to Set INIT or DATASOURCE properties after Initializing
  1564. if( (dwBitMask & PROPSET_INIT) &&
  1565. (rgPropertySets[cCount].guidPropertySet == DBPROPSET_DBINIT) ) {
  1566. //
  1567. // Wrong time to set these Properties
  1568. //
  1569. for (k=0; k < rgPropertySets[cCount].cProperties; k++) {
  1570. rgPropertySets[cCount].rgProperties[k].dwStatus = DBPROPSTATUS_NOTSETTABLE;
  1571. fWarning = TRUE;
  1572. }
  1573. continue;
  1574. }
  1575. // Trying to set the wrong Property Set
  1576. if( ((dwBitMask & PROPSET_DSO) && !(dwBitMask & PROPSET_INIT) &&
  1577. (rgPropertySets[cCount].guidPropertySet != DBPROPSET_DBINIT &&
  1578. rgPropertySets[cCount].guidPropertySet != DBPROPSET_ADSIBIND)) ||
  1579. ((dwBitMask & PROPSET_DSO) && (dwBitMask & PROPSET_INIT) &&
  1580. rgPropertySets[cCount].guidPropertySet != DBPROPSET_DATASOURCEINFO) ||
  1581. ((dwBitMask & PROPSET_SESSION) &&
  1582. rgPropertySets[cCount].guidPropertySet != DBPROPSET_SESSION) ||
  1583. ((dwBitMask & PROPSET_COMMAND) &&
  1584. rgPropertySets[cCount].guidPropertySet != DBPROPSET_ROWSET &&
  1585. rgPropertySets[cCount].guidPropertySet != DBPROPSET_ADSISEARCH) ) {
  1586. //
  1587. // Wrong Property Set
  1588. //
  1589. for (k=0; k < rgPropertySets[cCount].cProperties; k++) {
  1590. rgPropertySets[cCount].rgProperties[k].dwStatus = DBPROPSTATUS_NOTSUPPORTED;
  1591. fWarning = TRUE;
  1592. }
  1593. continue;
  1594. }
  1595. ULONG cPropOffset = 0;
  1596. for (j=0; j< NUMELEM(s_rgPropertySets); j++) {
  1597. if (IsEqualGUID(rgPropertySets[cCount].guidPropertySet,
  1598. *(s_rgPropertySets[j].guidPropertySet))) {
  1599. for (k=0; k < rgPropertySets[cCount].cProperties; k++) {
  1600. hr = StoreDBPROP(&(_prgProperties[cPropOffset]),
  1601. s_rgPropertySets[j].pUPropInfo,
  1602. s_rgPropertySets[j].cProperties,
  1603. &(rgPropertySets[cCount].rgProperties[k]),
  1604. j );
  1605. if( hr != S_OK )
  1606. fWarning = TRUE;
  1607. else
  1608. fNoPropertySet = FALSE;
  1609. }
  1610. break;
  1611. }
  1612. // Move to the next PropSet
  1613. cPropOffset += s_rgPropertySets[j].cProperties;
  1614. }
  1615. }
  1616. if ( fNoPropertySet && fWarning )
  1617. RRETURN ( DB_E_ERRORSOCCURRED );
  1618. else if (fWarning)
  1619. RRETURN ( DB_S_ERRORSOCCURRED );
  1620. else
  1621. RRETURN ( S_OK );
  1622. }
  1623. BOOL
  1624. CUtilProp::IsIntegratedSecurity(
  1625. void
  1626. )
  1627. {
  1628. // Check to see if SSPI is set
  1629. for (ULONG i=0; i< s_rgPropertySets[INDEX_INIT].cProperties; i++) {
  1630. if( _prgProperties[i].dwPropertyID == DBPROP_AUTH_INTEGRATED)
  1631. {
  1632. if (_prgProperties[i].pwstrVal )
  1633. return( wcscmp(_prgProperties[i].pwstrVal, L"SSPI") == 0 );
  1634. break;
  1635. }
  1636. }
  1637. return FALSE;
  1638. }
  1639. BOOL
  1640. CUtilProp::IsADSIFlagSet()
  1641. {
  1642. ULONG PropSetOffset = 0, i;
  1643. for(i = 0; i < INDEX_ADSIBIND; i++)
  1644. PropSetOffset += s_rgPropertySets[i].cProperties;
  1645. // Check if "ADSI Flag" is set to something other than ADS_AUTH_RESERVED
  1646. for (i=0; i < s_rgPropertySets[INDEX_ADSIBIND].cProperties; i++)
  1647. if(_prgProperties[i+PropSetOffset].dwPropertyID == ADSIPROP_ADSIFLAG)
  1648. return (_prgProperties[i+PropSetOffset].longVal !=
  1649. ADS_AUTH_RESERVED);
  1650. // we should never get here
  1651. return FALSE;
  1652. }