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.

422 lines
10 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: umisrch.cxx
  7. //
  8. // Contents: This file contains the query object for the LDAP provider.
  9. // IUmiQuery is the interface supported by this object. The
  10. // properties on the interface property list of this object are
  11. // mapped to the preferences you can set for IDirectorySearch.
  12. //
  13. // History: 03-27-00 AjayR Created.
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "ldap.hxx"
  17. //+---------------------------------------------------------------------------
  18. // Function: CUmiLDAPQuery::CUmiLDAPQuery --- Constructor.
  19. //
  20. // Synopsis: Standard constructor.
  21. //
  22. // Arguments: N/A.
  23. //
  24. // Returns: N/A.
  25. //
  26. // Modifies: N/A.
  27. //
  28. //----------------------------------------------------------------------------
  29. CUmiLDAPQuery::CUmiLDAPQuery():
  30. _pIntfPropMgr(NULL),
  31. _pszQueryText(NULL),
  32. _pszLanguage(NULL),
  33. _ulStatus(0)
  34. {
  35. }
  36. //+---------------------------------------------------------------------------
  37. // Function: CUmiLDAPQuery::~CUmiLDAPQuery --- Destructor.
  38. //
  39. // Synopsis: Standard destructor.
  40. //
  41. // Arguments: N/A.
  42. //
  43. // Returns: N/A.
  44. //
  45. // Modifies: N/A.
  46. //
  47. //----------------------------------------------------------------------------
  48. CUmiLDAPQuery::~CUmiLDAPQuery()
  49. {
  50. if (_pIntfPropMgr) {
  51. delete _pIntfPropMgr;
  52. }
  53. if (_pszQueryText) {
  54. FreeADsStr(_pszQueryText);
  55. }
  56. if (_pszLanguage) {
  57. FreeADsStr(_pszLanguage);
  58. }
  59. }
  60. //+---------------------------------------------------------------------------
  61. // Function: CUmiLDAPQuery::CreateUmiLDAPQuery --- STATIC constructor.
  62. //
  63. // Synopsis: Static constructor.
  64. //
  65. // Arguments: riid - Interface needed on new object.
  66. // ppObj - Return ptr for newly created object.
  67. //
  68. // Returns: S_OK on success or any suitable error code.
  69. //
  70. // Modifies: N/A.
  71. //
  72. //----------------------------------------------------------------------------
  73. HRESULT
  74. CUmiLDAPQuery::CreateUmiLDAPQuery(
  75. IID riid,
  76. void FAR* FAR* ppObj
  77. )
  78. {
  79. HRESULT hr = S_OK;
  80. CUmiLDAPQuery *pQuery;
  81. CPropertyManager *pIntfPropMgr = NULL;
  82. if (!ppObj) {
  83. RRETURN(E_INVALIDARG);
  84. }
  85. pQuery = new CUmiLDAPQuery();
  86. if (!pQuery) {
  87. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  88. }
  89. hr = CPropertyManager::CreatePropertyManager(
  90. (IUmiQuery *) pQuery,
  91. NULL, // IADs ptr
  92. NULL, // pCreds
  93. IntfPropsQuery,
  94. &pIntfPropMgr
  95. );
  96. BAIL_ON_FAILURE(hr);
  97. hr = pQuery->QueryInterface(riid, ppObj);
  98. BAIL_ON_FAILURE(hr)
  99. pQuery->Release();
  100. pQuery->_pIntfPropMgr = pIntfPropMgr;
  101. RRETURN(hr);
  102. error :
  103. if (pQuery) {
  104. delete pQuery;
  105. }
  106. if (pIntfPropMgr) {
  107. delete pIntfPropMgr;
  108. }
  109. RRETURN(hr);
  110. }
  111. //
  112. // IUnknown support - standard query interface method.
  113. //
  114. STDMETHODIMP
  115. CUmiLDAPQuery::QueryInterface(REFIID iid, LPVOID FAR* ppv)
  116. {
  117. HRESULT hr = S_OK;
  118. if (ppv == NULL) {
  119. RRETURN(E_POINTER);
  120. }
  121. if (IsEqualIID(iid, IID_IUnknown)){
  122. *ppv = (IUnknown FAR *) this;
  123. }
  124. else if (IsEqualIID(iid, IID_IUmiPropList)) {
  125. *ppv = (IUmiConnection FAR *) this;
  126. }
  127. else if (IsEqualIID(iid, IID_IUmiBaseObject)) {
  128. *ppv = (IUmiConnection FAR *) this;
  129. }
  130. else if (IsEqualIID(iid, IID_IUmiQuery)) {
  131. *ppv = (IUmiQuery FAR *) this;
  132. }
  133. else {
  134. *ppv = NULL;
  135. return E_NOINTERFACE;
  136. }
  137. AddRef();
  138. return NOERROR;
  139. }
  140. //
  141. // IUmiQuery methods.
  142. //
  143. //+---------------------------------------------------------------------------
  144. // Function: CUmiLDAPQuery::Set --- IUmiQuery support.
  145. //
  146. // Synopsis: Sets the query string and language.
  147. //
  148. // Arguments: pszLanguage - Language used to specify the query,
  149. // only LDAP and SQL/WQL are supported.
  150. // uFlags - Flags, only 0 is allowed now.
  151. // pszText - Query text.
  152. //
  153. // Returns: N/A.
  154. //
  155. // Modifies: Internal query and language strings.
  156. //
  157. //----------------------------------------------------------------------------
  158. STDMETHODIMP
  159. CUmiLDAPQuery::Set(
  160. IN LPCWSTR pszLanguage,
  161. IN ULONG uFlags,
  162. IN LPCWSTR pszText
  163. )
  164. {
  165. HRESULT hr = S_OK;
  166. SetLastStatus(0);
  167. //
  168. // Validate params
  169. //
  170. if (!pszLanguage || !pszText) {
  171. BAIL_ON_FAILURE(hr = E_INVALIDARG);
  172. }
  173. if (uFlags != 0) {
  174. BAIL_ON_FAILURE(hr = UMI_E_INVALID_FLAGS);
  175. }
  176. if (_wcsicmp(pszLanguage, L"LDAP")
  177. && _wcsicmp(pszLanguage, L"SQL")
  178. && _wcsicmp(pszLanguage, L"WQL")
  179. ) {
  180. //
  181. // We do not support this language.
  182. //
  183. BAIL_ON_FAILURE(hr = E_INVALIDARG);
  184. }
  185. //
  186. // Free exisitng stuff if needed.
  187. //
  188. if (_pszLanguage) {
  189. FreeADsStr(_pszLanguage);
  190. _pszLanguage = NULL;
  191. }
  192. if (_pszQueryText) {
  193. FreeADsStr(_pszQueryText);
  194. }
  195. _pszLanguage = AllocADsStr(pszLanguage);
  196. if (!_pszLanguage) {
  197. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  198. }
  199. _pszQueryText = AllocADsStr(pszText);
  200. if (!_pszQueryText) {
  201. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  202. }
  203. error:
  204. if (FAILED(hr)) {
  205. SetLastStatus(hr);
  206. hr = MapHrToUmiError(hr);
  207. }
  208. RRETURN(hr);
  209. }
  210. //+---------------------------------------------------------------------------
  211. // Function: CUmiLDAPQuery::GetQuery --- IUmiQuery support.
  212. //
  213. // Synopsis: Returns the query language and text in the user allocated
  214. // buffers provided.
  215. //
  216. // Arguments: puLangBufSize - Size of buffer for language string.
  217. // pszLangBuf - The actual buffer.
  218. // puQyeryTextBufSiz - Size of buffer for queyr text.
  219. // pszQueryTextBuf - Buffer for query text.
  220. //
  221. // Returns: S_OK on success or any appropriate error code.
  222. //
  223. // Modifies: pszLangBuf and pszQueryText on success. On failure,
  224. // * puLangBufSize and *puQueryTextBufSize are updated with
  225. // the length of the buffers needed (length in bytes).
  226. //
  227. //----------------------------------------------------------------------------
  228. STDMETHODIMP
  229. CUmiLDAPQuery::GetQuery(
  230. IN OUT ULONG * puLangBufSize,
  231. IN OUT LPWSTR pszLangBuf,
  232. IN OUT ULONG * puQueryTextBufSize,
  233. IN OUT LPWSTR pszQueryTextBuf
  234. )
  235. {
  236. HRESULT hr = S_OK;
  237. SetLastStatus(0);
  238. if (!_pszLanguage || !_pszQueryText) {
  239. BAIL_ON_FAILURE(hr = UMI_E_NOT_FOUND);
  240. }
  241. if (!puLangBufSize || !puQueryTextBufSize) {
  242. BAIL_ON_FAILURE(hr = E_INVALIDARG);
  243. }
  244. if ((*puLangBufSize < ((wcslen(_pszLanguage) + 1) * sizeof(WCHAR)))
  245. || *puQueryTextBufSize < ((wcslen(_pszQueryText) + 1) * sizeof(WCHAR))
  246. ) {
  247. //
  248. // We really need an insufficient buffer error for this.
  249. //
  250. *puLangBufSize = (wcslen(_pszLanguage) + 1) * sizeof(WCHAR);
  251. *puQueryTextBufSize = (wcslen(_pszQueryText) + 1) * sizeof(WCHAR);
  252. BAIL_ON_FAILURE( hr = E_OUTOFMEMORY);
  253. }
  254. //
  255. // We have enough space in the provided buffers.
  256. //
  257. wcscpy(pszLangBuf, _pszLanguage);
  258. wcscpy(pszQueryTextBuf, _pszQueryText);
  259. error:
  260. if (FAILED(hr)) {
  261. SetLastStatus(hr);
  262. hr = MapHrToUmiError(hr);
  263. }
  264. RRETURN(hr);
  265. }
  266. //
  267. // IUmiBaseObject methods.
  268. //
  269. //+---------------------------------------------------------------------------
  270. // Function: CUmiLDAPQuery::GetLastStatus (IUmiBaseObject method).
  271. //
  272. // Synopsis: Returns only numeric status code from the last operation.
  273. //
  274. // Arguments: uFlags - Only 0 is supported for now.
  275. // puSpecificStatus - Returns status/error code.
  276. // riid - Not used.
  277. // pStatusObj - NULL, not used currently.
  278. //
  279. // Returns: UMI_S_NO_ERROR on success. Error code otherwise.
  280. //
  281. // Modifies: *puSpecificStatus to return appropriate status code.
  282. //
  283. //----------------------------------------------------------------------------
  284. STDMETHODIMP
  285. CUmiLDAPQuery::GetLastStatus(
  286. IN ULONG uFlags,
  287. OUT ULONG *puSpecificStatus,
  288. IN REFIID riid,
  289. OUT LPVOID *pStatusObj
  290. )
  291. {
  292. if (uFlags != 0) {
  293. RRETURN(UMI_E_INVALID_FLAGS);
  294. }
  295. if (!puSpecificStatus) {
  296. RRETURN(E_INVALIDARG);
  297. }
  298. if (pStatusObj) {
  299. //
  300. // Should we error out ?
  301. //
  302. *pStatusObj = NULL;
  303. }
  304. *puSpecificStatus = _ulStatus;
  305. RRETURN(UMI_S_NO_ERROR);
  306. }
  307. //+---------------------------------------------------------------------------
  308. // Function: CUmiLDAPQuery::GetInterfacePropList (IUmiBaseObject method).
  309. //
  310. // Synopsis: Returns a pointer to the interface property list for
  311. // cursor object.
  312. //
  313. // Arguments: uFlags - Flags, only 0 is supported.
  314. // ppPropList - Return value.
  315. //
  316. // Returns: UMI_S_NO_ERROR on success. Error code otherwise.
  317. //
  318. // Modifies: *pPropList changed to IUmiPropList pointer
  319. //
  320. //----------------------------------------------------------------------------
  321. STDMETHODIMP
  322. CUmiLDAPQuery::GetInterfacePropList(
  323. IN ULONG uFlags,
  324. OUT IUmiPropList **pPropList
  325. )
  326. {
  327. HRESULT hr = UMI_S_NO_ERROR;
  328. SetLastStatus(0);
  329. if (uFlags != 0) {
  330. SetLastStatus(hr);
  331. RRETURN(UMI_E_INVALID_FLAGS);
  332. }
  333. //
  334. // QI will check for bad pointer so no need to check here.
  335. //
  336. hr = _pIntfPropMgr->QueryInterface(IID_IUmiPropList, (void **)pPropList);
  337. if (FAILED(hr)) {
  338. SetLastStatus(hr);
  339. }
  340. RRETURN(hr);
  341. }
  342. //
  343. // Private/Protected Methods.
  344. //
  345. //+---------------------------------------------------------------------------
  346. // Function: CUmiCursor::SetLastStatus (internal private helper routine).
  347. //
  348. // Synopsis: Sets the status of the last operation. If the status is one
  349. // of the pre-defined error codes, then the status is just set to
  350. // 0 since we are not adding any value by returning the same
  351. // status as the error code.
  352. //
  353. // Arguments: ulStatus - Status to be set.
  354. //
  355. // Returns: Nothing
  356. //
  357. // Modifies: Internal member status variable.
  358. //
  359. //----------------------------------------------------------------------------
  360. void
  361. CUmiLDAPQuery::SetLastStatus(ULONG ulStatus)
  362. {
  363. this->_ulStatus = ulStatus;
  364. return;
  365. }