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.

401 lines
9.2 KiB

  1. //-----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: ccolinfo.cxx
  7. //
  8. // Contents: IColumnsInfo implementation for LDAP rowsets
  9. //
  10. //
  11. // History: 07/10/96 RenatoB Created, lifted from EricJ code
  12. //
  13. //------------------------------------------------------------------------------
  14. // Includes
  15. #include "oleds.hxx"
  16. //-----------------------------------------------------------------------------
  17. // CLdap_ColumnsInfo object
  18. //
  19. // This object is just a wrapper for the CColInfo object.
  20. // It is separate because of refcount usage.
  21. // (It is also shared by Command and Rowset objects.)
  22. //
  23. // - Delegate QI, AddRef, Release to CLdap_RowProvider.
  24. // - Delegate IColumnsInfo functions to CColInfo.
  25. //-----------------------------------------------------------------------------
  26. //+---------------------------------------------------------------------------
  27. //
  28. // Function: CLdap_ColumnsInfo::CLdap_ColumnsInfo
  29. //
  30. // Synopsis: @mfunc Ctor
  31. //
  32. // Arguments:
  33. //
  34. //
  35. // Returns: @rdesc NONE
  36. //
  37. // Modifies:
  38. //
  39. // History: 07/10/96 RenatoB Created
  40. //
  41. //----------------------------------------------------------------------------
  42. PUBLIC
  43. CLdap_ColumnsInfo::CLdap_ColumnsInfo(
  44. CLdap_RowProvider * pObj) // @parm IN |
  45. {
  46. m_pObj = pObj;
  47. };
  48. //+---------------------------------------------------------------------------
  49. //
  50. // Function: CLdap_ColumnsInfo::FInit
  51. //
  52. // Synopsis:
  53. //
  54. // Arguments:
  55. //
  56. // Returns:
  57. //
  58. // Modifies:
  59. //
  60. // History: 07/10/96 RenatoB Created
  61. //
  62. //----------------------------------------------------------------------------
  63. PUBLIC STDMETHODIMP
  64. CLdap_ColumnsInfo::FInit(
  65. ULONG cColumns,
  66. DBCOLUMNINFO *rgInfo,
  67. OLECHAR *pStringsBuffer
  68. )
  69. {
  70. ULONG cChars;
  71. ULONG cCharDispl;
  72. ULONG i;
  73. HRESULT hr;
  74. void* Null1 = NULL;
  75. void* Null2 = NULL;
  76. m_ColInfo = NULL;
  77. m_pwchBuf = NULL;
  78. hr = CoGetMalloc(
  79. MEMCTX_TASK,
  80. &m_pMalloc);
  81. if (! SUCCEEDED(hr)) {
  82. goto error;
  83. }
  84. m_cColumns= cColumns;
  85. Null1 = m_pMalloc->Alloc(
  86. cColumns*sizeof(DBCOLUMNINFO)
  87. );
  88. if (Null1 == NULL)
  89. goto error;
  90. memset(Null1, 0, cColumns*sizeof(DBCOLUMNINFO));
  91. memcpy( (void*) Null1, (void*) rgInfo, cColumns*sizeof(DBCOLUMNINFO));
  92. m_ColInfo = (DBCOLUMNINFO*) Null1;
  93. cChars= m_pMalloc->GetSize(pStringsBuffer);
  94. Null2 = m_pMalloc->Alloc(cChars);
  95. if (Null2 == NULL)
  96. goto error;
  97. memset(Null2, 0, cChars);
  98. memcpy( (void*) Null2, (void*)pStringsBuffer , cChars);
  99. m_pwchBuf= (OLECHAR*) Null2;
  100. for (i=0; i<m_cColumns; i++) {
  101. cCharDispl = rgInfo[i].pwszName - pStringsBuffer;
  102. m_ColInfo[i].pwszName = m_pwchBuf+ cCharDispl;
  103. };
  104. RRETURN(S_OK);
  105. error:
  106. if (m_ColInfo != NULL)
  107. m_pMalloc->Free(m_ColInfo);
  108. if (m_pwchBuf != NULL)
  109. m_pMalloc->Free(m_pwchBuf);
  110. m_ColInfo = NULL;
  111. m_pwchBuf = NULL;
  112. m_cColumns = 0;
  113. m_pMalloc->Release();
  114. RRETURN(E_FAIL);
  115. }
  116. //+---------------------------------------------------------------------------
  117. //
  118. // Function: CLdap_ColumnsInfo::~CLdap_ColumnsInfo
  119. //
  120. // Synopsis: @mfunc Dtor
  121. //
  122. // Arguments:
  123. //
  124. // Returns: @rdesc NONE
  125. //
  126. // Modifies:
  127. //
  128. // History: 07/10/96 RenatoB Created
  129. //
  130. //----------------------------------------------------------------------------
  131. PUBLIC CLdap_ColumnsInfo::~CLdap_ColumnsInfo()
  132. {
  133. //
  134. // Assume we are only being called by CLdap_RowProvider
  135. // (i.e. backpointer) therefore we don't delete.
  136. // Delete m_ColInfo, m_CharBuf, and release the memory allocator
  137. //
  138. if (m_pMalloc != NULL) {
  139. if (m_ColInfo != NULL)
  140. m_pMalloc->Free(m_ColInfo);
  141. if (m_pwchBuf != NULL)
  142. m_pMalloc->Free(m_pwchBuf);
  143. m_pMalloc->Release();
  144. }
  145. }
  146. //+---------------------------------------------------------------------------
  147. //
  148. // Function: CLdap_ColumnsInfo::QueryInterface
  149. //
  150. // Synopsis: @mfunc QueryInterface.
  151. // We delegate to the CLdap_RowProvider.
  152. //
  153. // Called by: Client.
  154. // Called when: Any time.
  155. //
  156. // Arguments:
  157. //
  158. // Returns: @rdesc HRESULT
  159. //
  160. // Modifies:
  161. //
  162. // History: 07/10/96 RenatoB Created
  163. //
  164. //----------------------------------------------------------------------------
  165. PUBLIC STDMETHODIMP
  166. CLdap_ColumnsInfo::QueryInterface(
  167. REFIID riid, // IN | Interface ID of the interface being queried for
  168. LPVOID * ppv // OUT | Pointer to interface that was instantiated
  169. )
  170. {
  171. return m_pObj->QueryInterface(riid, ppv);
  172. }
  173. //+---------------------------------------------------------------------------
  174. //
  175. // Function: CLdap_ColumnsInfo::AddRef
  176. //
  177. // Synopsis: @mfunc AddRef.
  178. // We delegate to the CLdap_RowProvider.
  179. //
  180. // Called by: Client.
  181. // Called when: Any time.
  182. //
  183. // Arguments:
  184. //
  185. // Returns: @rdesc Refcount
  186. //
  187. // Modifies:
  188. //
  189. // History: 07/10/96 RenatoB Created
  190. //
  191. //----------------------------------------------------------------------------
  192. PUBLIC STDMETHODIMP_(ULONG) CLdap_ColumnsInfo::AddRef()
  193. {
  194. return m_pObj->AddRef();
  195. }
  196. //+---------------------------------------------------------------------------
  197. //
  198. // Function: CLdap_ColumnsInfo::Release
  199. //
  200. // Synopsis: @mfunc Release.
  201. // We delegate to the CLdap_RowProvider.
  202. //
  203. // Called by: Client.
  204. // Called when: Any time.
  205. //
  206. // Arguments:
  207. //
  208. // Returns: @rdesc Refcount
  209. //
  210. // Modifies:
  211. //
  212. // History: 07/10/96 RenatoB Created
  213. //
  214. //----------------------------------------------------------------------------
  215. PUBLIC STDMETHODIMP_(ULONG) CLdap_ColumnsInfo::Release()
  216. {
  217. return m_pObj->Release();
  218. }
  219. //+---------------------------------------------------------------------------
  220. //
  221. // Function: CLdap_ColumnsInfo::GetColumnInfo
  222. //
  223. // Synopsis: @mfunc Get Column Info.
  224. // Delegate.
  225. //
  226. // @rdesc See CColInfo::GetColumnInfo.
  227. //
  228. // Arguments:
  229. //
  230. // Returns: @rdesc See CColInfo::GetColumnInfo.
  231. //
  232. // Modifies:
  233. //
  234. // History: 07/10/96 RenatoB Created
  235. //
  236. //----------------------------------------------------------------------------
  237. PUBLIC STDMETHODIMP
  238. CLdap_ColumnsInfo::GetColumnInfo(
  239. DBORDINAL *pcColumns, //@parm OUT | .
  240. DBCOLUMNINFO **prgInfo, //@parm OUT | .
  241. WCHAR **ppStringsBuffer //@parm OUT | .
  242. )
  243. {
  244. ULONG i, cChars, cCharDispl;
  245. HRESULT hr= S_OK;
  246. void* Null1 = NULL;
  247. void* Null2 = NULL;
  248. if ((pcColumns == NULL ) || (prgInfo == NULL) || (ppStringsBuffer == NULL))
  249. BAIL_ON_FAILURE(hr=E_INVALIDARG);
  250. *pcColumns= m_cColumns;
  251. Null1 = m_pMalloc->Alloc(m_cColumns*sizeof(DBCOLUMNINFO));
  252. if (Null1 == NULL) {
  253. hr = E_OUTOFMEMORY;
  254. goto error;
  255. };
  256. memset(Null1, 0, m_cColumns*sizeof(DBCOLUMNINFO));
  257. memcpy( (void*) Null1, (void*) m_ColInfo,m_cColumns*sizeof(DBCOLUMNINFO));
  258. *prgInfo = (DBCOLUMNINFO*) Null1;
  259. cChars= m_pMalloc->GetSize(m_pwchBuf);
  260. Null2 = m_pMalloc->Alloc(cChars);
  261. if (Null2 == NULL) {
  262. hr = E_OUTOFMEMORY;
  263. goto error;
  264. };
  265. memset(Null2, 0, cChars);
  266. memcpy( (void*) Null2, (void*)m_pwchBuf , cChars);
  267. *ppStringsBuffer= (OLECHAR*) Null2;
  268. for (i=0; i<m_cColumns; i++) {
  269. cCharDispl = m_ColInfo[i].pwszName - m_pwchBuf;
  270. (*prgInfo)[i].pwszName =(*ppStringsBuffer) + cCharDispl;
  271. };
  272. RRETURN(hr);
  273. error:
  274. if (Null1 != NULL)
  275. m_pMalloc->Free(Null1);
  276. if (Null2 != NULL)
  277. m_pMalloc->Free(Null2);
  278. *prgInfo = NULL;
  279. *ppStringsBuffer = NULL;
  280. *pcColumns= 0;
  281. RRETURN(hr);
  282. };
  283. //+---------------------------------------------------------------------------
  284. //
  285. // Function: CLdap_ColumnsInfo::MapColumnIDs
  286. //
  287. // Synopsis: @mfunc Map Column IDs.
  288. // Just delegate to the CColInfo object we have.
  289. //
  290. // @rdesc See CColInfo::MapColumnIDs.
  291. //
  292. // Arguments:
  293. //
  294. // Returns: @rdesc See CColInfo::MapColumnIDs
  295. //
  296. // Modifies:
  297. //
  298. // History: 07/10/96 RenatoB Created
  299. //
  300. //----------------------------------------------------------------------------
  301. PUBLIC STDMETHODIMP
  302. CLdap_ColumnsInfo::MapColumnIDs(
  303. DBORDINAL cColumnIDs, //@parm IN | .
  304. const DBID rgColumnIDs[], //@parm IN | .
  305. DBORDINAL rgColumns[] //@parm INOUT | .
  306. )
  307. {
  308. // It is a logical (programming) error to fail here.
  309. // this data must have already been established.
  310. // Delegate the actual work.
  311. ULONG found = 0;
  312. DBORDINAL i;
  313. if (cColumnIDs == 0)
  314. RRETURN(S_OK);
  315. if (rgColumnIDs == NULL || rgColumns == NULL)
  316. RRETURN(E_INVALIDARG);
  317. for (i=0; i<cColumnIDs; i++) {
  318. if (rgColumnIDs[i].eKind!= DBKIND_PROPID) {
  319. found = 1;
  320. rgColumns[i]= DB_INVALIDCOLUMN;
  321. }
  322. else {
  323. if ((rgColumnIDs[i].uName.ulPropid > 3) ||
  324. (rgColumnIDs[i].uName.ulPropid<2)) {
  325. found = 1;
  326. rgColumns[i]= DB_INVALIDCOLUMN;
  327. }
  328. else rgColumns[i] = rgColumnIDs[i].uName.ulPropid -2;
  329. }
  330. }
  331. if (found == 1)
  332. RRETURN(DB_S_ERRORSOCCURRED);
  333. else
  334. return S_OK;
  335. }