Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1932 lines
72 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. //
  597. // Zero out the password before freeing it
  598. //
  599. SecureZeroMemory(pszPassword, wcslen(pszPassword) * sizeof(WCHAR));
  600. FreeADsMem(pszPassword);
  601. if( V_BSTR(&pPropSupport->vValue) == NULL ) {
  602. VariantClear( &pPropSupport->vValue );
  603. return DB_S_ERRORSOCCURRED;
  604. }
  605. }
  606. }
  607. else if( pProp->pwstrVal ) {
  608. V_VT(&pPropSupport->vValue) = VT_BSTR;
  609. V_BSTR(&pPropSupport->vValue)= SysAllocString(pProp->pwstrVal);
  610. if( V_BSTR(&pPropSupport->vValue) == NULL ) {
  611. VariantClear( &pPropSupport->vValue );
  612. return DB_S_ERRORSOCCURRED;
  613. }
  614. }
  615. break;
  616. default:
  617. ADsAssert( !"LoadDBPROP unknown variant type!\n\r" );
  618. pPropSupport->dwStatus = DBPROPSTATUS_BADVALUE;
  619. RRETURN (DB_S_ERRORSOCCURRED);
  620. break;
  621. }
  622. //
  623. // all went well
  624. //
  625. pPropSupport->dwStatus = DBPROPSTATUS_OK;
  626. RRETURN(S_OK);
  627. }
  628. //+---------------------------------------------------------------------------
  629. //
  630. // Function: CUtilProp::StoreDBProp
  631. //
  632. // Synopsis: Helper for SetProperties. Loads field of DBPROP structure.
  633. //
  634. // Arguments:
  635. //
  636. // Returns:
  637. //
  638. //
  639. // Modifies:
  640. //
  641. // History: 09-28-96 ShankSh Created.
  642. //
  643. //----------------------------------------------------------------------------
  644. STDMETHODIMP
  645. CUtilProp::StoreDBPROP (
  646. PROPSTRUCT* pPropStruct,
  647. PROPSTRUCT* pStaticPropStruct,
  648. ULONG cProperties,
  649. DBPROP* pPropSupport,
  650. DWORD dwPropIndex
  651. )
  652. {
  653. // asserts
  654. ADsAssert( pPropStruct );
  655. ADsAssert( pPropSupport );
  656. ULONG i;
  657. HRESULT hr=S_OK;
  658. // Initialize the status to DBPROPSTATUS_OK
  659. pPropSupport->dwStatus = DBPROPSTATUS_OK;
  660. for (i=0; i < cProperties; i++) {
  661. if(pPropStruct[i].dwPropertyID == pPropSupport->dwPropertyID) {
  662. // arg checking for the prop
  663. if( pPropSupport->dwOptions != DBPROPOPTIONS_OPTIONAL &&
  664. pPropSupport->dwOptions != DBPROPOPTIONS_REQUIRED ) {
  665. pPropSupport->dwStatus = DBPROPSTATUS_BADOPTION;
  666. hr = DB_S_ERRORSOCCURRED;
  667. goto error;
  668. }
  669. if( (pPropStruct[i].vtType != V_VT(&pPropSupport->vValue) &&
  670. V_VT(&pPropSupport->vValue) != VT_EMPTY) ||
  671. (IsValidValue(pPropSupport, dwPropIndex) == S_FALSE) ) {
  672. pPropSupport->dwStatus = DBPROPSTATUS_BADVALUE;
  673. hr = DB_S_ERRORSOCCURRED;
  674. goto error;
  675. }
  676. //
  677. // If property being set is password, we get out here.
  678. // Reason is we have already stored it in the Credentials structure
  679. // in encrypted form in the function IsVaidValue above.
  680. // We should not store it in plain text in pPropStruct[i].
  681. //
  682. if (dwPropIndex == INDEX_INIT &&
  683. pPropSupport->dwPropertyID == DBPROP_AUTH_PASSWORD)
  684. {
  685. pPropSupport->dwStatus = DBPROPSTATUS_OK;
  686. pPropStruct[i].dwOptions = pPropSupport->dwOptions;
  687. goto error;
  688. }
  689. if( !(pPropStruct[i].dwFlags & DBPROPFLAGS_WRITE) ) {
  690. // Check the value - if they are the same, do nothing
  691. if ( (V_VT(&pPropSupport->vValue) == VT_EMPTY) ||
  692. ((V_VT(&pPropSupport->vValue) == VT_BOOL) &&
  693. (pPropStruct[i].boolVal == V_BOOL(&pPropSupport->vValue))) ||
  694. ((V_VT(&pPropSupport->vValue) == VT_I4) &&
  695. (pPropStruct[i].longVal == V_I4(&pPropSupport->vValue))) ||
  696. ((V_VT(&pPropSupport->vValue) == VT_I2) &&
  697. ((short)pPropStruct[i].longVal == V_I2(&pPropSupport->vValue))) ||
  698. ((V_VT(&pPropSupport->vValue) == VT_BSTR) && pPropStruct[i].pwstrVal &&
  699. (NULL != V_BSTR(&pPropSupport->vValue)) &&
  700. (wcscmp(pPropStruct[i].pwstrVal,V_BSTR(&pPropSupport->vValue)) == 0)) )
  701. goto error;
  702. if( pPropSupport->dwOptions != DBPROPOPTIONS_OPTIONAL )
  703. pPropSupport->dwStatus = DBPROPSTATUS_NOTSETTABLE;
  704. else
  705. pPropSupport->dwStatus = DBPROPSTATUS_NOTSET;
  706. hr = DB_S_ERRORSOCCURRED;
  707. goto error;
  708. }
  709. switch (pPropStruct[i].vtType) {
  710. case VT_BOOL:
  711. if( V_VT(&pPropSupport->vValue) != VT_EMPTY )
  712. pPropStruct[i].boolVal = V_BOOL( &pPropSupport->vValue );
  713. else
  714. pPropStruct[i].boolVal = pStaticPropStruct[i].boolVal;
  715. break;
  716. case VT_I4:
  717. if( V_VT(&pPropSupport->vValue) != VT_EMPTY )
  718. pPropStruct[i].longVal = V_I4( &pPropSupport->vValue );
  719. else
  720. pPropStruct[i].longVal = pStaticPropStruct[i].longVal;
  721. break;
  722. case VT_I2:
  723. if( V_VT(&pPropSupport->vValue) != VT_EMPTY )
  724. pPropStruct[i].longVal = V_I2( &pPropSupport->vValue );
  725. else
  726. pPropStruct[i].longVal = pStaticPropStruct[i].longVal;
  727. break;
  728. case VT_BSTR:
  729. if(pPropStruct[i].pwstrVal) {
  730. FreeADsStr(pPropStruct[i].pwstrVal);
  731. pPropStruct[i].pwstrVal = NULL;
  732. }
  733. if( V_VT(&pPropSupport->vValue) == VT_EMPTY )
  734. pPropStruct[i].pwstrVal = AllocADsStr(( pStaticPropStruct[i].pwstrVal ));
  735. else
  736. {
  737. if (V_BSTR( &pPropSupport->vValue) == NULL &&
  738. pPropSupport->dwPropertyID == DBPROP_AUTH_INTEGRATED)
  739. {
  740. //
  741. // For integrated security, NULL bstrVal implies 'use default
  742. // provider', which is "SSPI" for us. The reason we don't set
  743. // the defult value to SSPI in the static structure is
  744. // because this property is special. Unless set, it should
  745. // not be used.
  746. //
  747. pPropStruct[i].pwstrVal = AllocADsStr(L"SSPI");
  748. }
  749. else
  750. pPropStruct[i].pwstrVal = AllocADsStr(V_BSTR( &pPropSupport->vValue ));
  751. }
  752. if( !pPropStruct[i].pwstrVal &&
  753. V_VT(&pPropSupport->vValue) == VT_BSTR ) {
  754. hr = E_FAIL;
  755. goto error;
  756. }
  757. break;
  758. default:
  759. pPropSupport->dwStatus = DBPROPSTATUS_BADVALUE;
  760. hr = DB_S_ERRORSOCCURRED;
  761. goto error;
  762. }
  763. pPropSupport->dwStatus = DBPROPSTATUS_OK;
  764. pPropStruct[i].dwOptions = pPropSupport->dwOptions;
  765. break;
  766. }
  767. }
  768. if (i == cProperties) {
  769. pPropSupport->dwStatus = DBPROPSTATUS_NOTSUPPORTED;
  770. hr = DB_E_ERRORSOCCURRED;
  771. goto error;
  772. }
  773. error:
  774. RRETURN(hr);
  775. }
  776. //+---------------------------------------------------------------------------
  777. //
  778. // Function: CUtilProp::IsValidValue
  779. //
  780. // Synopsis: Helper for SetProperties. Check the valid values for the Property.
  781. //
  782. // Arguments:
  783. //
  784. // Returns:
  785. //
  786. //
  787. // Modifies:
  788. //
  789. // History: 09-28-96 ShankSh Created.
  790. //
  791. //----------------------------------------------------------------------------
  792. HRESULT
  793. CUtilProp::IsValidValue
  794. (
  795. DBPROP* pDBProp,
  796. DWORD dwPropIndex
  797. )
  798. {
  799. // Check BOOLEAN values
  800. if( (pDBProp->vValue.vt == VT_BOOL) &&
  801. !((V_BOOL(&(pDBProp->vValue)) == VARIANT_TRUE) ||
  802. (V_BOOL(&(pDBProp->vValue)) == VARIANT_FALSE)) )
  803. return S_FALSE;
  804. if( pDBProp->vValue.vt != VT_EMPTY &&
  805. dwPropIndex == INDEX_INIT )
  806. {
  807. switch( pDBProp->dwPropertyID )
  808. {
  809. case DBPROP_INIT_PROMPT:
  810. // These are the only values we support (from spec).
  811. if (!(V_I2(&pDBProp->vValue) == DBPROMPT_PROMPT ||
  812. V_I2(&pDBProp->vValue) == DBPROMPT_COMPLETE ||
  813. V_I2(&pDBProp->vValue) == DBPROMPT_COMPLETEREQUIRED ||
  814. V_I2(&pDBProp->vValue) == DBPROMPT_NOPROMPT))
  815. return S_FALSE;
  816. break;
  817. case DBPROP_INIT_TIMEOUT:
  818. if( (pDBProp->vValue.vt != VT_I4) ||
  819. (V_I4(&pDBProp->vValue) < 0) )
  820. return S_FALSE;
  821. break;
  822. case DBPROP_AUTH_USERID:
  823. if( (!_pCredentials) ||
  824. (S_OK != _pCredentials->SetUserName(V_BSTR(&pDBProp->vValue))) )
  825. return S_FALSE;
  826. break;
  827. case DBPROP_AUTH_PASSWORD:
  828. if( (!_pCredentials) ||
  829. (S_OK != _pCredentials->SetPassword(V_BSTR(&pDBProp->vValue))) )
  830. return S_FALSE;
  831. break;
  832. case DBPROP_AUTH_INTEGRATED:
  833. //
  834. // For integrated security, NULL bstrVal implies 'use default
  835. // provider', which is "SSPI" for us.
  836. //
  837. if( ((pDBProp->vValue.vt != VT_BSTR) &&
  838. (pDBProp->vValue.vt != VT_NULL)) ||
  839. ((V_BSTR(&pDBProp->vValue) != NULL) &&
  840. (wcscmp(V_BSTR(&pDBProp->vValue), L"SSPI") != 0)))
  841. return S_FALSE;
  842. break;
  843. case DBPROP_INIT_MODE:
  844. if( (pDBProp->vValue.vt != VT_I4) ||
  845. (S_FALSE == IsValidInitMode(V_I4(&pDBProp->vValue))) )
  846. return S_FALSE;
  847. break;
  848. #if (!defined(BUILD_FOR_NT40))
  849. case DBPROP_INIT_BINDFLAGS:
  850. if( (pDBProp->vValue.vt != VT_I4) ||
  851. (S_FALSE == IsValidBindFlag(V_I4(&pDBProp->vValue))) )
  852. return S_FALSE;
  853. break;
  854. #endif
  855. case DBPROP_AUTH_ENCRYPT_PASSWORD:
  856. if( !_pCredentials )
  857. return S_FALSE;
  858. if( IsADSIFlagSet() )
  859. // override this property if the user set the authentication
  860. break;
  861. BOOL fAuthFlags = _pCredentials->GetAuthFlags();
  862. if( V_BOOL(&pDBProp->vValue) )
  863. _pCredentials->SetAuthFlags(fAuthFlags | ADS_SECURE_AUTHENTICATION);
  864. else
  865. _pCredentials->SetAuthFlags(fAuthFlags & ~ADS_SECURE_AUTHENTICATION);
  866. break;
  867. }
  868. }
  869. else if( pDBProp->vValue.vt != VT_EMPTY &&
  870. dwPropIndex == INDEX_ADSIBIND )
  871. {
  872. switch( pDBProp->dwPropertyID )
  873. {
  874. case ADSIPROP_ADSIFLAG:
  875. if( !_pCredentials )
  876. // don't think this will ever happen
  877. return S_FALSE;
  878. // prevent default initialization by VB from setting the
  879. // AUTH flags. The client should not specify ADS_AUTH_RESERVED
  880. // for this property (this might happen if the client behaves
  881. // like VB i.e, does GetProperties and then SetProperties
  882. // without ORing in any flags. In this case, ENCRYPT_PASSWORD
  883. // will not be overwritten by this property due to this check).
  884. if( ADS_AUTH_RESERVED == (V_I4(&pDBProp->vValue)) )
  885. break;
  886. // the following call might overwrite ENCRYPT_PASSWORD
  887. _pCredentials->SetAuthFlags((V_I4(&pDBProp->vValue)) &
  888. (~ADS_AUTH_RESERVED) );
  889. break;
  890. }
  891. }
  892. else if( pDBProp->vValue.vt != VT_EMPTY &&
  893. dwPropIndex == INDEX_SESSION )
  894. {
  895. switch( pDBProp->dwPropertyID )
  896. {
  897. case DBPROP_SESS_AUTOCOMMITISOLEVELS:
  898. // These are the only values we support (from spec).
  899. if( (pDBProp->vValue.vt != VT_I4) ||
  900. (V_I4(&pDBProp->vValue) != 0 &&
  901. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_CHAOS &&
  902. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_READUNCOMMITTED &&
  903. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_READCOMMITTED &&
  904. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_REPEATABLEREAD &&
  905. V_I4(&pDBProp->vValue) != DBPROPVAL_TI_SERIALIZABLE) )
  906. return S_FALSE;
  907. break;
  908. }
  909. }
  910. else if( pDBProp->vValue.vt != VT_EMPTY &&
  911. dwPropIndex == INDEX_ROWSET )
  912. {
  913. switch( pDBProp->dwPropertyID )
  914. {
  915. case DBPROP_MAXOPENROWS:
  916. if( (pDBProp->vValue.vt != VT_I4) ||
  917. (V_I4(&pDBProp->vValue) < 0) )
  918. return S_FALSE;
  919. break;
  920. }
  921. }
  922. return S_OK; // Is valid
  923. }
  924. //----------------------------------------------------------------------------
  925. // IsValidInitMode
  926. //
  927. // Checks if a given value is a valid value for DBPROP_INIT_MODE
  928. //
  929. //----------------------------------------------------------------------------
  930. HRESULT
  931. CUtilProp::IsValidInitMode(
  932. long lVal
  933. )
  934. {
  935. // check if any bit that shouldn't be set is actually set
  936. if( lVal & (~(DB_MODE_READWRITE |
  937. DB_MODE_SHARE_EXCLUSIVE | DB_MODE_SHARE_DENY_NONE)) )
  938. return S_FALSE;
  939. return S_OK;
  940. }
  941. //---------------------------------------------------------------------------
  942. // IsValidInitBindFlag
  943. //
  944. // Checks if a given value is a valid value for DBPROP_INIT_BINDFLAGS
  945. //
  946. //---------------------------------------------------------------------------
  947. HRESULT
  948. CUtilProp::IsValidBindFlag(
  949. long lVal
  950. )
  951. {
  952. #if (!defined(BUILD_FOR_NT40))
  953. // check if any bit that shouldn't be set is actually set
  954. if( lVal & (~(DB_BINDFLAGS_DELAYFETCHCOLUMNS |
  955. DB_BINDFLAGS_DELAYFETCHSTREAM | DB_BINDFLAGS_RECURSIVE |
  956. DB_BINDFLAGS_OUTPUT | DB_BINDFLAGS_COLLECTION |
  957. DB_BINDFLAGS_OPENIFEXISTS | DB_BINDFLAGS_OVERWRITE |
  958. DB_BINDFLAGS_ISSTRUCTUREDDOCUMENT)) )
  959. return S_FALSE;
  960. // check for mutually exclusive flags
  961. if( (lVal & DB_BINDFLAGS_OPENIFEXISTS) &&
  962. (lVal & DB_BINDFLAGS_OVERWRITE) )
  963. return S_FALSE;
  964. return S_OK;
  965. #else
  966. return E_FAIL;
  967. #endif
  968. }
  969. //+---------------------------------------------------------------------------
  970. //
  971. // Function: CUtilProp::GetPropertiesArgChk
  972. //
  973. // Synopsis: Initialize the buffers and check for E_INVALIDARG
  974. //
  975. // Arguments:
  976. // cPropertyIDSets # of restiction property IDs
  977. // rgPropertyIDSets[] restriction guids
  978. // pcPropertySets count of properties returned
  979. // prgPropertySets property information returned
  980. // dwBitMask which property group
  981. //
  982. // Returns:
  983. // S_OK | The method succeeded
  984. // E_INVALIDARG | pcPropertyIDSets or prgPropertyInfo was NULL
  985. //
  986. // Modifies:
  987. //
  988. // History: 08-28-96 ShankSh Created.
  989. //
  990. //----------------------------------------------------------------------------
  991. HRESULT
  992. CUtilProp::GetPropertiesArgChk(
  993. ULONG cPropertySets,
  994. const DBPROPIDSET rgPropertySets[],
  995. ULONG* pcProperties,
  996. DBPROPSET** prgProperties,
  997. DWORD dwBitMask
  998. )
  999. {
  1000. // Initialize values
  1001. if( pcProperties )
  1002. *pcProperties = 0;
  1003. if( prgProperties )
  1004. *prgProperties = NULL;
  1005. // Check Arguments
  1006. if( ((cPropertySets > 0) && !rgPropertySets) ||
  1007. !pcProperties || !prgProperties )
  1008. RRETURN ( E_INVALIDARG );
  1009. // New argument check for > 1 cPropertyIDs and NULL pointer for
  1010. // array of property ids.
  1011. for(ULONG ul=0; ul<cPropertySets; ul++)
  1012. {
  1013. if( rgPropertySets[ul].cPropertyIDs && !(rgPropertySets[ul].rgPropertyIDs) )
  1014. RRETURN ( E_INVALIDARG );
  1015. // Check for propper formation of DBPROPSET_PROPERTIESINERROR
  1016. if( ((dwBitMask & PROPSET_DSO) || (dwBitMask & PROPSET_COMMAND)) &&
  1017. (rgPropertySets[ul].guidPropertySet == DBPROPSET_PROPERTIESINERROR) )
  1018. {
  1019. if( (cPropertySets > 1) ||
  1020. (rgPropertySets[ul].cPropertyIDs != 0) ||
  1021. (rgPropertySets[ul].rgPropertyIDs != NULL) )
  1022. RRETURN ( E_INVALIDARG );
  1023. }
  1024. }
  1025. RRETURN ( S_OK );
  1026. }
  1027. //+---------------------------------------------------------------------------
  1028. //
  1029. // Function: CUtilProp::GetPropertyInfo
  1030. //
  1031. // Synopsis: Returns information about rowset and data source properties
  1032. // supported by the provider
  1033. //
  1034. // Arguments:
  1035. // cPropertyIDSets # properties
  1036. // rgPropertyIDSets[] Array of property sets
  1037. // pcPropertyInfoSets # DBPROPSET structures
  1038. // prgPropertyInfoSets DBPROPSET structures property
  1039. // information returned
  1040. // ppDescBuffer Property descriptions
  1041. //
  1042. // Returns:
  1043. // S_OK | The method succeeded
  1044. // E_INVALIDARG | pcPropertyIDSets or prgPropertyInfo was NULL
  1045. // E_OUTOFMEMORY | Out of memory
  1046. //
  1047. // Modifies:
  1048. //
  1049. // History: 08-28-96 ShankSh Created.
  1050. //
  1051. //----------------------------------------------------------------------------
  1052. STDMETHODIMP CUtilProp::GetPropertyInfo
  1053. (
  1054. ULONG cPropertyIDSets,
  1055. const DBPROPIDSET rgPropertyIDSets[],
  1056. ULONG* pcPropertyInfoSets,
  1057. DBPROPINFOSET** pprgPropertyInfoSets,
  1058. WCHAR** ppDescBuffer,
  1059. BOOL fDSOInitialized
  1060. )
  1061. {
  1062. DBPROPINFO* pPropInfo = NULL;
  1063. DBPROPINFOSET* pPropInfoSet = NULL;
  1064. BOOL fNoPropInfoGot = TRUE;
  1065. BOOL fWarning=FALSE;
  1066. HRESULT hr;
  1067. LPWSTR pwszDescBuffer=NULL;
  1068. ULONG cPropertySets=0, cProperties=0;
  1069. ULONG cCount, j, i;
  1070. ULONG cNewPropIDSets = 0;
  1071. BOOL fIsSpecialGUID = FALSE;
  1072. BOOL fIsNotSpecialGUID = FALSE;
  1073. ULONG ul;
  1074. BOOL fNewDescription = TRUE;
  1075. // asserts
  1076. ADsAssert( _pIMalloc );
  1077. // init out params
  1078. if( pcPropertyInfoSets )
  1079. *pcPropertyInfoSets = 0;
  1080. if( pprgPropertyInfoSets )
  1081. *pprgPropertyInfoSets = NULL;
  1082. if( ppDescBuffer )
  1083. *ppDescBuffer = NULL;
  1084. // Check Arguments, on failure post HRESULT to error queue
  1085. if( (cPropertyIDSets > 0 && !rgPropertyIDSets) ||
  1086. !pcPropertyInfoSets || !pprgPropertyInfoSets )
  1087. RRETURN( E_INVALIDARG );
  1088. // New argument check for > 1 cPropertyIDs and NULL pointer for
  1089. // array of property ids.
  1090. for(ul=0; ul<cPropertyIDSets; ul++)
  1091. {
  1092. if( rgPropertyIDSets[ul].cPropertyIDs &&
  1093. !rgPropertyIDSets[ul].rgPropertyIDs )
  1094. RRETURN( E_INVALIDARG );
  1095. // Add 1 for the Provider Specific Rowset Properties
  1096. if( (rgPropertyIDSets[ul].guidPropertySet == DBPROPSET_DBINITALL) ||
  1097. (fDSOInitialized &&
  1098. rgPropertyIDSets[ul].guidPropertySet == DBPROPSET_ROWSETALL) )
  1099. cNewPropIDSets++;
  1100. //
  1101. // Special Guids for Property Sets can not be mixed with ordinary
  1102. // Property Set Guids. Either one or the other, not both
  1103. //
  1104. if (IsSpecialGuid(rgPropertyIDSets[ul].guidPropertySet))
  1105. fIsSpecialGUID = TRUE;
  1106. else
  1107. fIsNotSpecialGUID = TRUE;
  1108. if( fIsSpecialGUID && fIsNotSpecialGUID )
  1109. RRETURN( E_INVALIDARG );
  1110. }
  1111. // save the count of PropertyIDSets
  1112. cNewPropIDSets += cPropertyIDSets;
  1113. // If the consumer does not restrict the property sets
  1114. // by specify an array of property sets and a cPropertySets
  1115. // greater than 0, then we need to make sure we
  1116. // have some to return
  1117. if( cPropertyIDSets == 0 )
  1118. {
  1119. if( fDSOInitialized )
  1120. cNewPropIDSets = NUMBER_OF_SUPPORTED_PROPERTY_SETS;
  1121. else
  1122. // we have 2 property sets in the DBINIT property group
  1123. cNewPropIDSets = 2;
  1124. }
  1125. // use task memory allocater to alloc a DBPROPINFOSET struct
  1126. pPropInfoSet = (DBPROPINFOSET*) _pIMalloc->Alloc(cNewPropIDSets *
  1127. sizeof( DBPROPINFOSET ));
  1128. if( !pPropInfoSet )
  1129. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1130. memset( pPropInfoSet, 0, (cNewPropIDSets * sizeof( DBPROPINFOSET )));
  1131. if( ppDescBuffer )
  1132. {
  1133. // Allocating more memory than actually required, since
  1134. // _dwDescBufferLen is th etotal for all property sets together, not
  1135. // just for one property set
  1136. pwszDescBuffer = (LPWSTR) _pIMalloc->Alloc(_dwDescBufferLen * cNewPropIDSets);
  1137. if( !pwszDescBuffer )
  1138. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1139. memset( pwszDescBuffer, 0, _dwDescBufferLen * cNewPropIDSets);
  1140. *ppDescBuffer = pwszDescBuffer;
  1141. }
  1142. // If no restrictions return all properties from the three supported property sets
  1143. if( cPropertyIDSets == 0 )
  1144. {
  1145. // Fill in all of the Providers Properties
  1146. for (j=0; j< cNewPropIDSets; j++)
  1147. pPropInfoSet[j].guidPropertySet = *s_rgPropertySets[j].guidPropertySet;
  1148. }
  1149. else
  1150. {
  1151. cCount = 0;
  1152. //
  1153. // Deal with the Special GUID's
  1154. //
  1155. for (j=0; j< cPropertyIDSets; j++)
  1156. {
  1157. if( rgPropertyIDSets[j].guidPropertySet == DBPROPSET_DBINITALL )
  1158. {
  1159. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_DBINIT;
  1160. // Adjust for ADSI_BIND (provider specific) property set
  1161. cCount++;
  1162. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_ADSIBIND;
  1163. }
  1164. else if( fDSOInitialized &&
  1165. rgPropertyIDSets[j].guidPropertySet == DBPROPSET_DATASOURCEINFOALL )
  1166. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_DATASOURCEINFO;
  1167. else if( fDSOInitialized &&
  1168. rgPropertyIDSets[j].guidPropertySet == DBPROPSET_SESSIONALL )
  1169. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_SESSION;
  1170. else if( fDSOInitialized &&
  1171. rgPropertyIDSets[j].guidPropertySet == DBPROPSET_ROWSETALL )
  1172. {
  1173. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_ROWSET;
  1174. // Adjust for the Provider Specific
  1175. cCount++;
  1176. pPropInfoSet[cCount].guidPropertySet = DBPROPSET_ADSISEARCH;
  1177. }
  1178. else
  1179. {
  1180. pPropInfoSet[cCount].guidPropertySet = rgPropertyIDSets[j].guidPropertySet;
  1181. pPropInfoSet[cCount].cPropertyInfos = rgPropertyIDSets[j].cPropertyIDs;
  1182. }
  1183. cCount++;
  1184. }
  1185. }
  1186. //
  1187. // For each supported Property Set
  1188. //
  1189. for (cPropertySets=0;
  1190. cPropertySets < cNewPropIDSets;
  1191. cPropertySets++)
  1192. {
  1193. // Set cProperties to the numerber passed in
  1194. cProperties = pPropInfoSet[cPropertySets].cPropertyInfos;
  1195. pPropInfo = NULL;
  1196. // Get the correct Static data. We have 2 property sets in the
  1197. // INIT property group. Note that we assume that both these property
  1198. // sets occur successively in s_rgPropertySets.
  1199. for (j=0; j< (fDSOInitialized ? NUMELEM(s_rgPropertySets) : 2); j++) {
  1200. if( IsEqualGUID(pPropInfoSet[cPropertySets].guidPropertySet,
  1201. *(s_rgPropertySets[j].guidPropertySet)) ) {
  1202. if( pPropInfoSet[cPropertySets].cPropertyInfos == 0 )
  1203. cProperties = s_rgPropertySets[j].cProperties;
  1204. break;
  1205. }
  1206. }
  1207. if( cProperties )
  1208. {
  1209. //
  1210. // use task memory allocater to alloc array of DBPROPINFO structs
  1211. //
  1212. pPropInfo = (DBPROPINFO*) _pIMalloc->Alloc(cProperties * sizeof( DBPROPINFO ));
  1213. if( !pPropInfo ) {
  1214. for (i=0; i<cNewPropIDSets; i++)
  1215. _pIMalloc->Free(pPropInfoSet[i].rgPropertyInfos);
  1216. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1217. }
  1218. memset(pPropInfo, 0, cProperties * sizeof(DBPROPINFO));
  1219. for (cCount=0; cCount < cProperties; cCount++)
  1220. {
  1221. if( pPropInfoSet[cPropertySets].cPropertyInfos == 0 )
  1222. pPropInfo[cCount].dwPropertyID =
  1223. s_rgPropertySets[j].pUPropInfo[cCount].dwPropertyID;
  1224. else
  1225. pPropInfo[cCount].dwPropertyID =
  1226. rgPropertyIDSets[cPropertySets].rgPropertyIDs[cCount];
  1227. // set the description pointer. If this property was already
  1228. // requested in this call, then we reuse the same description
  1229. // pointer.
  1230. DWORD dwTmp;
  1231. for(dwTmp = 0; dwTmp < cCount; dwTmp++)
  1232. if(pPropInfo[dwTmp].dwPropertyID ==
  1233. pPropInfo[cCount].dwPropertyID)
  1234. // same property requested more than once
  1235. break;
  1236. if(dwTmp == cCount)
  1237. {
  1238. fNewDescription = TRUE;
  1239. pPropInfo[cCount].pwszDescription = pwszDescBuffer;
  1240. }
  1241. else
  1242. {
  1243. fNewDescription = FALSE;
  1244. pPropInfo[cCount].pwszDescription =
  1245. pPropInfo[dwTmp].pwszDescription;
  1246. }
  1247. hr = LoadDBPROPINFO(
  1248. ((j < (fDSOInitialized ? NUMELEM(s_rgPropertySets) : 2)) ?
  1249. s_rgPropertySets[j].pUPropInfo : NULL),
  1250. ((j < (fDSOInitialized ? NUMELEM(s_rgPropertySets) : 2)) ?
  1251. s_rgPropertySets[j].cProperties : 0),
  1252. &pPropInfo[cCount]
  1253. );
  1254. if( FAILED(hr) ) {
  1255. ULONG ulFor;
  1256. //
  1257. // something went wrong
  1258. // clear all variants used so far..
  1259. //
  1260. for (ulFor = 0; ulFor < cCount; ulFor++)
  1261. VariantClear( &pPropInfo[ulFor].vValues );
  1262. //
  1263. // .. delete the pPropInfo array, return failure
  1264. //
  1265. for (i=0; i<cNewPropIDSets; i++)
  1266. _pIMalloc->Free(pPropInfoSet[i].rgPropertyInfos);
  1267. _pIMalloc->Free(pPropInfo);
  1268. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1269. }
  1270. if( hr != S_OK )
  1271. fWarning = TRUE;
  1272. else
  1273. fNoPropInfoGot = FALSE;
  1274. // move the description pointer to the next, if required
  1275. if( pPropInfo[cCount].pwszDescription && fNewDescription)
  1276. pwszDescBuffer += (wcslen(pPropInfo[cCount].pwszDescription) + 1);
  1277. }
  1278. }
  1279. else
  1280. fWarning = TRUE;
  1281. pPropInfoSet[cPropertySets].rgPropertyInfos = pPropInfo;
  1282. pPropInfoSet[cPropertySets].cPropertyInfos = cProperties;
  1283. } // for each property set
  1284. //
  1285. // set count of properties and property information
  1286. //
  1287. *pcPropertyInfoSets= cNewPropIDSets;
  1288. *pprgPropertyInfoSets = pPropInfoSet;
  1289. if( fNoPropInfoGot ) {
  1290. if( ppDescBuffer )
  1291. *ppDescBuffer = NULL;
  1292. if( pwszDescBuffer )
  1293. _pIMalloc->Free(pwszDescBuffer);
  1294. RRETURN ( DB_E_ERRORSOCCURRED );
  1295. }
  1296. else if( fWarning )
  1297. RRETURN ( DB_S_ERRORSOCCURRED );
  1298. else
  1299. RRETURN ( S_OK );
  1300. error:
  1301. if( pPropInfoSet )
  1302. _pIMalloc->Free(pPropInfoSet);
  1303. if( pwszDescBuffer )
  1304. _pIMalloc->Free(pwszDescBuffer);
  1305. RRETURN ( hr );
  1306. }
  1307. //----------------------------------------------------------------------------
  1308. // IsSpecialGuid
  1309. //
  1310. // Check if the the property set GUID is one of the special GUIDs
  1311. //
  1312. //----------------------------------------------------------------------------
  1313. BOOL CUtilProp::IsSpecialGuid(
  1314. GUID guidPropSet
  1315. )
  1316. {
  1317. if( (DBPROPSET_ROWSETALL == guidPropSet) ||
  1318. (DBPROPSET_DATASOURCEALL == guidPropSet) ||
  1319. (DBPROPSET_DATASOURCEINFOALL == guidPropSet) ||
  1320. (DBPROPSET_SESSIONALL == guidPropSet) ||
  1321. (DBPROPSET_DBINITALL == guidPropSet)
  1322. #if (!defined(BUILD_FOR_NT40))
  1323. ||
  1324. (DBPROPSET_COLUMNALL == guidPropSet) ||
  1325. (DBPROPSET_CONSTRAINTALL == guidPropSet) ||
  1326. (DBPROPSET_INDEXALL == guidPropSet) ||
  1327. (DBPROPSET_TABLEALL == guidPropSet) ||
  1328. (DBPROPSET_TRUSTEEALL == guidPropSet) ||
  1329. (DBPROPSET_VIEWALL == guidPropSet)
  1330. #endif
  1331. )
  1332. return TRUE;
  1333. else
  1334. return FALSE;
  1335. }
  1336. //+---------------------------------------------------------------------------
  1337. //
  1338. // Function: CUtilProp::GetProperties
  1339. //
  1340. // Synopsis: Returns current settings of all properties supported
  1341. // by the DSO/rowset
  1342. //
  1343. // Arguments:
  1344. //
  1345. // cPropertyIDSets # of restiction property IDs
  1346. // rgPropertyIDSets[] restriction guids
  1347. // pcPropertySets count of properties returned
  1348. // prgPropertySets property information returned
  1349. //
  1350. //
  1351. // Returns:
  1352. // S_OK | The method succeeded
  1353. // E_INVALIDARG | pcPropertyIDSets or prgPropertyInfo was NULL
  1354. // E_OUTOFMEMORY | Out of memory
  1355. //
  1356. // Modifies:
  1357. //
  1358. // History: 08-28-96 ShankSh Created.
  1359. //
  1360. //----------------------------------------------------------------------------
  1361. STDMETHODIMP CUtilProp::GetProperties
  1362. (
  1363. ULONG cPropertyIDSets,
  1364. const DBPROPIDSET rgPropertyIDSets[],
  1365. ULONG* pcPropertySets,
  1366. DBPROPSET** pprgPropertySets,
  1367. DWORD dwBitMask
  1368. )
  1369. {
  1370. ULONG cPropertySets, cProperties;
  1371. ULONG cNewPropIDSets = 0;
  1372. ULONG cCount, j, i;
  1373. DBPROP* pProp = NULL;
  1374. DBPROPSET* pPropSet = NULL;
  1375. HRESULT hr = E_FAIL;
  1376. BOOL fNoPropertyGot = TRUE;
  1377. BOOL fWarning = FALSE;
  1378. BOOL fFound = FALSE;
  1379. ULONG cOffset = 0;
  1380. // asserts
  1381. ADsAssert(_pIMalloc);
  1382. // Assign in the count
  1383. cNewPropIDSets = cPropertyIDSets;
  1384. // If the consumer does not restrict the property sets
  1385. // by specify an array of property sets and a cPropertySets
  1386. // greater than 0, then we need to make sure we
  1387. // have some to return
  1388. if( cPropertyIDSets == 0 )
  1389. {
  1390. // Set the count of properties
  1391. cNewPropIDSets = 1;
  1392. if(dwBitMask & PROPSET_DSO)
  1393. {
  1394. if(dwBitMask & PROPSET_INIT)
  1395. // if the data src object has been initialized, return
  1396. // properties in the DBInit, DSInfo and ADSIBind property sets.
  1397. cNewPropIDSets = 3;
  1398. else
  1399. // Return DBInit and ADSIBind property sets only. Note that we
  1400. // are counting on ADSIBind being the second property set in
  1401. // s_rgPropertySets, since we are leaving cOffset as 0
  1402. cNewPropIDSets = 2;
  1403. }
  1404. if(dwBitMask & PROPSET_COMMAND)
  1405. cNewPropIDSets = 2;
  1406. }
  1407. // Figure out the Offset
  1408. if( dwBitMask & PROPSET_SESSION )
  1409. cOffset = INDEX_SESSION;
  1410. else if( dwBitMask & PROPSET_COMMAND )
  1411. cOffset = INDEX_ROWSET;
  1412. //
  1413. // use task memory allocater to alloc a DBPROPSET struct
  1414. //
  1415. pPropSet = (DBPROPSET*) _pIMalloc->Alloc(cNewPropIDSets * sizeof( DBPROPSET ));
  1416. if( !pPropSet )
  1417. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1418. memset( pPropSet, 0, (cNewPropIDSets * sizeof( DBPROPSET )));
  1419. //
  1420. // For each supported Property Set
  1421. //
  1422. for (cPropertySets=0; cPropertySets < cNewPropIDSets; cPropertySets++) {
  1423. // Initialize variable
  1424. ULONG cPropOffset = 0;
  1425. int cNumDSOProps = 0;
  1426. cProperties = 0;
  1427. pProp = NULL;
  1428. fFound = FALSE;
  1429. // Setup the PropSet GUID
  1430. if( cPropertyIDSets == 0 ) {
  1431. pPropSet[cPropertySets].guidPropertySet =
  1432. *s_rgPropertySets[cPropertySets+cOffset].guidPropertySet;
  1433. }
  1434. else {
  1435. cProperties = rgPropertyIDSets[cPropertySets].cPropertyIDs;
  1436. pPropSet[cPropertySets].guidPropertySet =
  1437. rgPropertyIDSets[cPropertySets].guidPropertySet;
  1438. }
  1439. if(dwBitMask & PROPSET_DSO)
  1440. // we have 2 property sets whose properties can be set before
  1441. // initialization and one whose properties can be set only after
  1442. // init. Set the count of properties accordingly.
  1443. cNumDSOProps = 1 + !!(dwBitMask & PROPSET_INIT);
  1444. // Setup the count of Properties for that PropSet
  1445. for (j=0;
  1446. j <= cOffset+ cNumDSOProps + !!(dwBitMask & PROPSET_COMMAND);
  1447. j++) {
  1448. if( j >= cOffset &&
  1449. IsEqualGUID(pPropSet[cPropertySets].guidPropertySet,
  1450. *(s_rgPropertySets[j].guidPropertySet)) ) {
  1451. if (rgPropertyIDSets == NULL ||
  1452. rgPropertyIDSets[cPropertySets].cPropertyIDs == 0)
  1453. cProperties = s_rgPropertySets[j].cProperties;
  1454. fFound = TRUE;
  1455. break;
  1456. }
  1457. // Move to the next PropSet
  1458. cPropOffset += s_rgPropertySets[j].cProperties;
  1459. }
  1460. if( cProperties != 0 ) {
  1461. // use task memory allocator to alloc array of DBPROP struct
  1462. pProp = (DBPROP*) _pIMalloc->Alloc(cProperties * sizeof( DBPROP ));
  1463. if( pProp == NULL ) {
  1464. for (i=0; i < cPropertySets; i++)
  1465. _pIMalloc->Free(pPropSet[i].rgProperties);
  1466. BAIL_ON_FAILURE ( hr=E_OUTOFMEMORY );
  1467. }
  1468. memset( pProp, 0, (cProperties * sizeof( DBPROP )));
  1469. if( rgPropertyIDSets == NULL ||
  1470. rgPropertyIDSets[cPropertySets].cPropertyIDs == 0 ) {
  1471. for (cCount=0; cCount < cProperties; cCount++)
  1472. pProp[cCount].dwPropertyID =
  1473. s_rgPropertySets[j-!fFound].pUPropInfo[cCount].dwPropertyID;
  1474. }
  1475. else {
  1476. for (cCount=0; cCount < cProperties; cCount++)
  1477. pProp[cCount].dwPropertyID =
  1478. rgPropertyIDSets[cPropertySets].rgPropertyIDs[cCount];
  1479. }
  1480. }
  1481. else
  1482. fWarning = TRUE;
  1483. //
  1484. // for each prop in our table..
  1485. //
  1486. for (cCount = 0; cCount < cProperties; cCount++) {
  1487. hr = LoadDBPROP((fFound ? &(_prgProperties[cPropOffset]) : NULL),
  1488. (fFound ? s_rgPropertySets[j-!fFound].cProperties : 0),
  1489. &pProp[cCount],
  1490. pPropSet[cPropertySets].guidPropertySet == DBPROPSET_DBINIT
  1491. );
  1492. if( FAILED(hr) ) {
  1493. // something went wrong
  1494. // clear all variants used so far..
  1495. for (i=0; i < cCount; i++)
  1496. VariantClear( &pProp[i].vValue );
  1497. for (i=0; i < cPropertySets; i++)
  1498. _pIMalloc->Free(pPropSet[i].rgProperties);
  1499. _pIMalloc->Free(pProp);
  1500. BAIL_ON_FAILURE( hr );
  1501. }
  1502. if( hr != S_OK )
  1503. fWarning = TRUE;
  1504. else
  1505. fNoPropertyGot = FALSE;
  1506. } // for each property
  1507. pPropSet[cPropertySets].rgProperties = pProp;
  1508. pPropSet[cPropertySets].cProperties = cProperties;
  1509. } // for each property set
  1510. // set count of properties and property informatio
  1511. *pcPropertySets = cNewPropIDSets;
  1512. *pprgPropertySets = pPropSet;
  1513. if( fNoPropertyGot )
  1514. RRETURN( DB_E_ERRORSOCCURRED );
  1515. else if( fWarning )
  1516. RRETURN( DB_S_ERRORSOCCURRED );
  1517. else
  1518. RRETURN( S_OK );
  1519. error:
  1520. if( pPropSet )
  1521. _pIMalloc->Free(pPropSet);
  1522. RRETURN( hr );
  1523. }
  1524. //+---------------------------------------------------------------------------
  1525. //
  1526. // Function: CUtilProp::SetProperties
  1527. //
  1528. // Synopsis: Set current settings of properties supported by the DSO/rowset
  1529. //
  1530. // Arguments:
  1531. //
  1532. // cPropertyIDSets, # of DBPROPSET
  1533. // rgPropertyIDSets[] Array of property sets
  1534. //
  1535. // Returns:
  1536. // S_OK | The method succeeded
  1537. // E_INVALIDARG | pcPropertyIDSets or prgPropertyInfo was NULL
  1538. // E_OUTOFMEMORY | Out of memory
  1539. //
  1540. // Modifies:
  1541. //
  1542. // History: 08-28-96 ShankSh Created.
  1543. //
  1544. //----------------------------------------------------------------------------
  1545. STDMETHODIMP
  1546. CUtilProp::SetProperties(
  1547. ULONG cPropertySets,
  1548. DBPROPSET rgPropertySets[],
  1549. DWORD dwBitMask
  1550. )
  1551. {
  1552. ULONG cCount, j, k;
  1553. HRESULT hr;
  1554. BOOL fNoPropertySet = TRUE;
  1555. BOOL fWarning = FALSE;
  1556. // check params
  1557. if( cPropertySets > 0 && !rgPropertySets )
  1558. RRETURN ( E_INVALIDARG );
  1559. // New argument check for > 1 cPropertyIDs and NULL pointer for
  1560. // array of property ids.
  1561. for(ULONG ul=0; ul<cPropertySets; ul++)
  1562. {
  1563. if( rgPropertySets[ul].cProperties &&
  1564. !(rgPropertySets[ul].rgProperties) )
  1565. RRETURN ( E_INVALIDARG );
  1566. }
  1567. for (cCount=0; cCount < cPropertySets; cCount++) {
  1568. // Not legal to Set INIT or DATASOURCE properties after Initializing
  1569. if( (dwBitMask & PROPSET_INIT) &&
  1570. (rgPropertySets[cCount].guidPropertySet == DBPROPSET_DBINIT) ) {
  1571. //
  1572. // Wrong time to set these Properties
  1573. //
  1574. for (k=0; k < rgPropertySets[cCount].cProperties; k++) {
  1575. rgPropertySets[cCount].rgProperties[k].dwStatus = DBPROPSTATUS_NOTSETTABLE;
  1576. fWarning = TRUE;
  1577. }
  1578. continue;
  1579. }
  1580. // Trying to set the wrong Property Set
  1581. if( ((dwBitMask & PROPSET_DSO) && !(dwBitMask & PROPSET_INIT) &&
  1582. (rgPropertySets[cCount].guidPropertySet != DBPROPSET_DBINIT &&
  1583. rgPropertySets[cCount].guidPropertySet != DBPROPSET_ADSIBIND)) ||
  1584. ((dwBitMask & PROPSET_DSO) && (dwBitMask & PROPSET_INIT) &&
  1585. rgPropertySets[cCount].guidPropertySet != DBPROPSET_DATASOURCEINFO) ||
  1586. ((dwBitMask & PROPSET_SESSION) &&
  1587. rgPropertySets[cCount].guidPropertySet != DBPROPSET_SESSION) ||
  1588. ((dwBitMask & PROPSET_COMMAND) &&
  1589. rgPropertySets[cCount].guidPropertySet != DBPROPSET_ROWSET &&
  1590. rgPropertySets[cCount].guidPropertySet != DBPROPSET_ADSISEARCH) ) {
  1591. //
  1592. // Wrong Property Set
  1593. //
  1594. for (k=0; k < rgPropertySets[cCount].cProperties; k++) {
  1595. rgPropertySets[cCount].rgProperties[k].dwStatus = DBPROPSTATUS_NOTSUPPORTED;
  1596. fWarning = TRUE;
  1597. }
  1598. continue;
  1599. }
  1600. ULONG cPropOffset = 0;
  1601. for (j=0; j< NUMELEM(s_rgPropertySets); j++) {
  1602. if (IsEqualGUID(rgPropertySets[cCount].guidPropertySet,
  1603. *(s_rgPropertySets[j].guidPropertySet))) {
  1604. for (k=0; k < rgPropertySets[cCount].cProperties; k++) {
  1605. hr = StoreDBPROP(&(_prgProperties[cPropOffset]),
  1606. s_rgPropertySets[j].pUPropInfo,
  1607. s_rgPropertySets[j].cProperties,
  1608. &(rgPropertySets[cCount].rgProperties[k]),
  1609. j );
  1610. if( hr != S_OK )
  1611. fWarning = TRUE;
  1612. else
  1613. fNoPropertySet = FALSE;
  1614. }
  1615. break;
  1616. }
  1617. // Move to the next PropSet
  1618. cPropOffset += s_rgPropertySets[j].cProperties;
  1619. }
  1620. }
  1621. if ( fNoPropertySet && fWarning )
  1622. RRETURN ( DB_E_ERRORSOCCURRED );
  1623. else if (fWarning)
  1624. RRETURN ( DB_S_ERRORSOCCURRED );
  1625. else
  1626. RRETURN ( S_OK );
  1627. }
  1628. BOOL
  1629. CUtilProp::IsIntegratedSecurity(
  1630. void
  1631. )
  1632. {
  1633. // Check to see if SSPI is set
  1634. for (ULONG i=0; i< s_rgPropertySets[INDEX_INIT].cProperties; i++) {
  1635. if( _prgProperties[i].dwPropertyID == DBPROP_AUTH_INTEGRATED)
  1636. {
  1637. if (_prgProperties[i].pwstrVal )
  1638. return( wcscmp(_prgProperties[i].pwstrVal, L"SSPI") == 0 );
  1639. break;
  1640. }
  1641. }
  1642. return FALSE;
  1643. }
  1644. BOOL
  1645. CUtilProp::IsADSIFlagSet()
  1646. {
  1647. ULONG PropSetOffset = 0, i;
  1648. for(i = 0; i < INDEX_ADSIBIND; i++)
  1649. PropSetOffset += s_rgPropertySets[i].cProperties;
  1650. // Check if "ADSI Flag" is set to something other than ADS_AUTH_RESERVED
  1651. for (i=0; i < s_rgPropertySets[INDEX_ADSIBIND].cProperties; i++)
  1652. if(_prgProperties[i+PropSetOffset].dwPropertyID == ADSIPROP_ADSIFLAG)
  1653. return (_prgProperties[i+PropSetOffset].longVal !=
  1654. ADS_AUTH_RESERVED);
  1655. // we should never get here
  1656. return FALSE;
  1657. }