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.

408 lines
9.6 KiB

  1. //------------------------------------------------------------------------------
  2. //
  3. // Microsoft Sidewalk
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: oledbhelp.cpp
  7. //
  8. // Contents: OLE DB helper methods
  9. //
  10. // Owner: BassamT
  11. //
  12. // History: 11/30/97 BassamT Created.
  13. //
  14. //------------------------------------------------------------------------------
  15. #include "oleds.hxx"
  16. #if (!defined(BUILD_FOR_NT40))
  17. #define dimensionof(x) sizeof(x)/sizeof(x[0])
  18. HRESULT IsValidDBID
  19. //------------------------------------------------------------------------------
  20. // checks if we have a valid DBID
  21. (
  22. const DBID * pdbid1
  23. // [in] the DBID to check
  24. )
  25. {
  26. Assert(pdbid1 != NULL);
  27. if (pdbid1 &&
  28. ((pdbid1->eKind == DBKIND_GUID_NAME) ||
  29. (pdbid1->eKind == DBKIND_GUID_PROPID) ||
  30. (pdbid1->eKind == DBKIND_NAME) ||
  31. (pdbid1->eKind == DBKIND_PGUID_NAME) ||
  32. (pdbid1->eKind == DBKIND_PGUID_PROPID) ||
  33. (pdbid1->eKind == DBKIND_PROPID) ||
  34. (pdbid1->eKind == DBKIND_GUID)))
  35. {
  36. return S_OK;
  37. }
  38. else
  39. {
  40. return S_FALSE;
  41. }
  42. }
  43. BOOL CompareDBIDs
  44. //------------------------------------------------------------------------------
  45. // Compares two DBIDs. Given two DBIDS to determine if they are the same.
  46. // Returns TRUE if they are the same DBIDs or FALSE if different
  47. (
  48. const DBID * pdbid1,
  49. // [in] pointer to DBID 1; can be badly formed eKind
  50. const DBID * pdbid2
  51. // [in] pointer to DBID 2; assumed valid eKind
  52. )
  53. {
  54. // Array of valid eKind matches, in addition to matching exactly.
  55. static BYTE abKind[] =
  56. {
  57. DBKIND_PGUID_NAME, // DBKIND_GUID_NAME
  58. DBKIND_PGUID_PROPID, // DBKIND_GUID_PROPID
  59. DBKIND_NAME, // DBKIND_NAME
  60. DBKIND_GUID_NAME, // DBKIND_PGUID_NAME
  61. DBKIND_GUID_PROPID, // DBKIND_PGUID_PROPID
  62. DBKIND_PROPID, // DBKIND_PROPID
  63. DBKIND_GUID // DBKIND_GUID
  64. };
  65. // Verify that offsets are correct (header file might change).
  66. Assert( 0 == DBKIND_GUID_NAME &&
  67. 1 == DBKIND_GUID_PROPID &&
  68. 2 == DBKIND_NAME &&
  69. 3 == DBKIND_PGUID_NAME &&
  70. 4 == DBKIND_PGUID_PROPID &&
  71. 5 == DBKIND_PROPID &&
  72. 6 == DBKIND_GUID);
  73. if (pdbid1 == NULL || pdbid2 == NULL)
  74. {
  75. return FALSE;
  76. }
  77. // Assume a match, and discard early if we can.
  78. // Don't assert for 1, since might be badly-formed.
  79. // 2 is assumed to be well-formed.
  80. Assert(inrange(((SHORT)pdbid2->eKind), 0, dimensionof(abKind)));
  81. if (pdbid1->eKind != pdbid2->eKind &&
  82. pdbid1->eKind != abKind[pdbid2->eKind])
  83. {
  84. return FALSE;
  85. }
  86. if (DBID_USE_GUID_OR_PGUID(pdbid1->eKind))
  87. {
  88. if (!DBID_USE_GUID_OR_PGUID(pdbid2->eKind))
  89. {
  90. return FALSE;
  91. }
  92. // Compare GUIDs.
  93. // Note that _GUID_ is equivalent to _PGUID_.
  94. if (!IsEqualGUID(
  95. DBID_USE_PGUID(pdbid1->eKind) ? *(pdbid1->uGuid.pguid) : pdbid1->uGuid.guid,
  96. DBID_USE_PGUID(pdbid2->eKind) ? *(pdbid2->uGuid.pguid) : pdbid2->uGuid.guid))
  97. {
  98. return FALSE;
  99. }
  100. }
  101. if (DBID_USE_NAME(pdbid1->eKind))
  102. {
  103. if (!DBID_USE_NAME(pdbid2->eKind))
  104. {
  105. return FALSE;
  106. }
  107. // Compare names.
  108. // Need to check if 1 is null and the other is not.
  109. if (((pdbid1->uName.pwszName == NULL) && (pdbid2->uName.pwszName != NULL)) ||
  110. ((pdbid1->uName.pwszName != NULL) && (pdbid2->uName.pwszName == NULL)))
  111. {
  112. return FALSE;
  113. }
  114. // Since the above check does not rule out both being null, which is
  115. // a valid comparison, and wcscmp will GPF if they were, we need
  116. // to check for valid pointers
  117. if(pdbid1->uName.pwszName != NULL && pdbid2->uName.pwszName != NULL)
  118. {
  119. // Assume null-terminated.
  120. if (_wcsicmp(pdbid1->uName.pwszName, pdbid2->uName.pwszName) != 0)
  121. {
  122. return FALSE;
  123. }
  124. }
  125. }
  126. if (DBID_USE_PROPID(pdbid1->eKind))
  127. {
  128. if (!DBID_USE_PROPID(pdbid2->eKind))
  129. {
  130. return FALSE;
  131. }
  132. // Compare PROPID.
  133. if (pdbid1->uName.ulPropid != pdbid2->uName.ulPropid)
  134. {
  135. return FALSE;
  136. }
  137. }
  138. // a match
  139. return TRUE;
  140. }
  141. void FreeDBID
  142. //------------------------------------------------------------------------------
  143. // FreeDBID
  144. // Given a DBID free an allocated buffers
  145. (
  146. DBID *pdbidSrc
  147. //[in] Pointer to DBID
  148. )
  149. {
  150. Assert(pdbidSrc);
  151. switch (pdbidSrc->eKind)
  152. {
  153. case DBKIND_GUID_NAME:
  154. CLIENT_FREE(pdbidSrc->uName.pwszName);
  155. break;
  156. case DBKIND_NAME:
  157. CLIENT_FREE(pdbidSrc->uName.pwszName);
  158. break;
  159. case DBKIND_PGUID_NAME:
  160. CLIENT_FREE(pdbidSrc->uGuid.pguid);
  161. CLIENT_FREE(pdbidSrc->uName.pwszName);
  162. break;
  163. case DBKIND_PGUID_PROPID:
  164. CLIENT_FREE(pdbidSrc->uGuid.pguid);
  165. break;
  166. case DBKIND_GUID_PROPID:
  167. case DBKIND_PROPID:
  168. case DBKIND_GUID:
  169. break;
  170. default:
  171. Assert(NULL && L"Unhandled dbid1.ekind");
  172. break;
  173. }
  174. }
  175. HRESULT CopyDBIDs
  176. //------------------------------------------------------------------------------
  177. // Given a DBID to copy, put it in the new buffer
  178. //
  179. // Need to use IMalloc->Alloc and IMalloc->Free since this routine
  180. // is used to copy the DBIDs from storage back into the memory handed to
  181. // the consumer.
  182. //
  183. // HRESULT indicating the status of the copy
  184. // S_OK = Copied
  185. // S_FALSE = Problems copying
  186. // E_OUTOFMEMORY = Could not allocate resources
  187. //
  188. (
  189. DBID * pdbidDest,
  190. // [in,out] Pointer to Destination DBID
  191. const DBID *pdbidSrc
  192. // [in] Pointer to Source DBID
  193. )
  194. {
  195. Assert(pdbidDest);
  196. Assert(pdbidSrc);
  197. size_t cwchBuffer;
  198. HRESULT hr;
  199. memset(pdbidDest, 0, sizeof(*pdbidDest));
  200. // Save eKind
  201. pdbidDest->eKind = pdbidSrc->eKind;
  202. switch (pdbidSrc->eKind)
  203. {
  204. case DBKIND_GUID_NAME:
  205. pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid;
  206. cwchBuffer = wcslen(pdbidSrc->uName.pwszName) + 1;
  207. if (pdbidDest->uName.pwszName = (PWSTR)CLIENT_MALLOC(cwchBuffer * sizeof(WCHAR)))
  208. {
  209. wcsncpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer);
  210. }
  211. else
  212. {
  213. hr = E_OUTOFMEMORY;
  214. //ErrorTrace(hr);
  215. goto Error;
  216. }
  217. break;
  218. case DBKIND_GUID_PROPID:
  219. pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid;
  220. pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid;
  221. break;
  222. case DBKIND_NAME:
  223. cwchBuffer = wcslen(pdbidSrc->uName.pwszName) + 1;
  224. if (pdbidDest->uName.pwszName = (PWSTR)CLIENT_MALLOC(cwchBuffer * sizeof(WCHAR)))
  225. {
  226. wcsncpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer);
  227. }
  228. else
  229. {
  230. hr = E_OUTOFMEMORY;
  231. //ErrorTrace(hr);
  232. goto Error;
  233. }
  234. break;
  235. case DBKIND_PGUID_NAME:
  236. // convert the pguid into a guid so that we don't have to do an extra malloc
  237. pdbidDest->eKind = DBKIND_GUID_NAME;
  238. pdbidDest->uGuid.guid = *pdbidSrc->uGuid.pguid;
  239. cwchBuffer = wcslen(pdbidSrc->uName.pwszName) + 1;
  240. if (pdbidDest->uName.pwszName = (PWSTR)CLIENT_MALLOC(cwchBuffer * sizeof(WCHAR)))
  241. {
  242. wcsncpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer);
  243. }
  244. else
  245. {
  246. hr = E_OUTOFMEMORY;
  247. //ErrorTrace(hr);
  248. goto Error;
  249. }
  250. break;
  251. case DBKIND_PGUID_PROPID:
  252. // convert the pguid into a guid so that we don't have to do an extra malloc
  253. pdbidDest->eKind = DBKIND_GUID_PROPID;
  254. pdbidDest->uGuid.guid = *pdbidSrc->uGuid.pguid;
  255. pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid;
  256. break;
  257. case DBKIND_PROPID:
  258. pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid;
  259. break;
  260. case DBKIND_GUID:
  261. pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid;
  262. break;
  263. default:
  264. Assert(NULL && L"Unhandled dbid ekind");
  265. hr = E_FAIL;
  266. //ErrorTrace(hr);
  267. goto Error;
  268. }
  269. return NOERROR;
  270. Error:
  271. Assert(FAILED(hr));
  272. return hr;
  273. }
  274. INT CompareOLEDBTypes
  275. //------------------------------------------------------------------------------
  276. // Compares two value of the same DBTYPE.
  277. //
  278. // Returns :
  279. //
  280. // 0 if both values are equal
  281. // >0 if pvValue1 is greater than pvValue2
  282. // <0 if pvValue1 is less than pvValue2
  283. //
  284. (
  285. DBTYPE wType,
  286. // [in] the OLE DB type of both values
  287. void * pvValue1,
  288. // [in] a pointer to Value1
  289. void * pvValue2
  290. // [in] a pointer to Value2
  291. )
  292. {
  293. Assert (pvValue1 != NULL);
  294. Assert (pvValue2 != NULL);
  295. // TODO : Is this right ?
  296. INT comp = -1;
  297. /*
  298. // TODO : how do we handle these ?
  299. case DBTYPE_ARRAY:
  300. case DBTYPE_BYREF:
  301. case DBTYPE_VECTOR:
  302. */
  303. // TODO : support the other DB_TYPES and check that all types work
  304. // TODO : What about NULL values ?
  305. // TODO : WE could generalize this function and let it handle values
  306. // of different types.
  307. switch (wType)
  308. {
  309. case DBTYPE_I2:
  310. comp = (*(SHORT*)pvValue1) - (*(SHORT*)pvValue2);
  311. break;
  312. case DBTYPE_I4:
  313. comp = (*(LONG*)pvValue1) - (*(LONG*)pvValue2);
  314. break;
  315. case DBTYPE_UI1:
  316. comp = (*(UCHAR*)pvValue1) - (*(UCHAR*)pvValue2);
  317. break;
  318. case DBTYPE_I1:
  319. comp = (*(CHAR*)pvValue1) - (*(CHAR*)pvValue2);
  320. break;
  321. case DBTYPE_UI2:
  322. comp = (*(USHORT*)pvValue1) - (*(USHORT*)pvValue2);
  323. break;
  324. case DBTYPE_UI4:
  325. comp = (*(ULONG*)pvValue1) - (*(ULONG*)pvValue2);
  326. break;
  327. case DBTYPE_STR:
  328. comp = strcmp((CHAR*)(pvValue1), (CHAR*)pvValue2);
  329. break;
  330. case DBTYPE_WSTR:
  331. comp = wcscmp((WCHAR*)(pvValue1), (WCHAR*)pvValue2);
  332. break;
  333. case DBTYPE_GUID:
  334. case DBTYPE_I8:
  335. case DBTYPE_UI8:
  336. case DBTYPE_R4:
  337. case DBTYPE_R8:
  338. case DBTYPE_CY:
  339. case DBTYPE_DATE:
  340. case DBTYPE_BSTR:
  341. case DBTYPE_IDISPATCH:
  342. case DBTYPE_ERROR:
  343. case DBTYPE_BOOL:
  344. case DBTYPE_VARIANT:
  345. case DBTYPE_IUNKNOWN:
  346. case DBTYPE_DECIMAL:
  347. case DBTYPE_RESERVED:
  348. case DBTYPE_BYTES:
  349. case DBTYPE_NUMERIC:
  350. case DBTYPE_UDT:
  351. case DBTYPE_DBDATE:
  352. case DBTYPE_DBTIME:
  353. case DBTYPE_DBTIMESTAMP:
  354. default:
  355. Assert(FALSE && "CIndex : Data type not supported");
  356. return -1;
  357. }
  358. return comp;
  359. }
  360. #endif