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.

746 lines
17 KiB

  1. /***********************************************************************
  2. *
  3. * ABSEARCH.C
  4. *
  5. * Sample AB directory container Search object
  6. *
  7. * This file contains the code for implementing the Sample AB
  8. * directory container search object. Also known as advanced
  9. * search.
  10. *
  11. * This search object was retrieved by OpenProperty on PR_SEARCH on the
  12. * AB directory found in ABCONT.C.
  13. *
  14. * The following routines are implemented in this file:
  15. *
  16. * HrNewSearch
  17. * ABSRCH_Release
  18. * ABSRCH_SaveChanges
  19. * ABSRCH_OpenProperty
  20. * ABSRCH_GetSearchCriteria
  21. *
  22. * HrGetSearchDialog
  23. *
  24. * Copyright 1992, 1993, 1994 Microsoft Corporation. All Rights Reserved.
  25. *
  26. ***********************************************************************/
  27. #include "faxab.h"
  28. /*
  29. * Proptags used only in this module
  30. */
  31. #define PR_ANR_STRING_A PROP_TAG(PT_STRING8,0x6602)
  32. /* Display table control structures for the Search property sheet. */
  33. /*
  34. * The Sample AB exposes an 'advanced' search dialog. The following
  35. * structures define it's layout.
  36. */
  37. /*
  38. * The edit control that will have the name to be search for on it.
  39. */
  40. #define MAX_SEARCH_NAME 50
  41. DTBLEDIT editSearchName =
  42. {
  43. SIZEOF(DTBLEDIT),
  44. 0,
  45. MAX_SEARCH_NAME,
  46. PR_ANR_STRING_A
  47. };
  48. /*
  49. * Display table pages for Search property sheet
  50. */
  51. DTCTL rgdtctlSearchGeneral[] =
  52. {
  53. /*
  54. * Defines the name of this Pane.
  55. */
  56. {DTCT_PAGE, 0, NULL, 0, NULL, 0, &dtblpage},
  57. /* group box control */
  58. {DTCT_GROUPBOX, 0, NULL, 0, NULL, IDC_STATIC_CONTROL, &dtblgroupbox},
  59. /* control and edit control */
  60. {DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL, &dtbllabel},
  61. {DTCT_EDIT, DT_EDITABLE, NULL, 0, (LPTSTR)szNoFilter, IDC_SEARCH_NAME, &editSearchName},
  62. };
  63. /*
  64. * Actual definition of the set of pages that make up this advanced search
  65. * dialog.
  66. */
  67. DTPAGE rgdtpageSearch[] =
  68. {
  69. {
  70. ARRAYSIZE(rgdtctlSearchGeneral),
  71. (LPTSTR) MAKEINTRESOURCE(SearchGeneralPage),
  72. TEXT(""),
  73. rgdtctlSearchGeneral
  74. }
  75. };
  76. /*
  77. * ABSearch vtbl is filled in here.
  78. */
  79. ABSRCH_Vtbl vtblABSRCH =
  80. {
  81. (ABSRCH_QueryInterface_METHOD *) ROOT_QueryInterface,
  82. (ABSRCH_AddRef_METHOD *) ROOT_AddRef,
  83. ABSRCH_Release,
  84. (ABSRCH_GetLastError_METHOD *) ROOT_GetLastError,
  85. ABSRCH_SaveChanges,
  86. (ABSRCH_GetProps_METHOD *) WRAP_GetProps,
  87. (ABSRCH_GetPropList_METHOD *) WRAP_GetPropList,
  88. ABSRCH_OpenProperty,
  89. (ABSRCH_SetProps_METHOD *) WRAP_SetProps,
  90. (ABSRCH_DeleteProps_METHOD *) WRAP_DeleteProps,
  91. (ABSRCH_CopyTo_METHOD *) WRAP_CopyTo,
  92. (ABSRCH_CopyProps_METHOD *) WRAP_CopyProps,
  93. (ABSRCH_GetNamesFromIDs_METHOD *) WRAP_GetNamesFromIDs,
  94. (ABSRCH_GetIDsFromNames_METHOD *) WRAP_GetIDsFromNames,
  95. (ABSRCH_GetContentsTable_METHOD *) ROOT_GetContentsTable,
  96. (ABSRCH_GetHierarchyTable_METHOD *) ABC_GetHierarchyTable,
  97. (ABSRCH_OpenEntry_METHOD *) ROOT_OpenEntry,
  98. (ABSRCH_SetSearchCriteria_METHOD *) ROOT_SetSearchCriteria,
  99. ABSRCH_GetSearchCriteria,
  100. };
  101. HRESULT HrGetSearchDialog(LPABSRCH lpABSearch, LPMAPITABLE * lppSearchTable);
  102. /*
  103. - HrNewSearch
  104. -
  105. * Creates an advanced search object
  106. *
  107. *
  108. */
  109. /*
  110. * Properties that are initially set on this object
  111. */
  112. enum { ivalabsrchPR_ANR_STRING = 0,
  113. cvalabsrchMax };
  114. HRESULT
  115. HrNewSearch( LPMAPICONTAINER * lppABSearch,
  116. LPABLOGON lpABLogon,
  117. LPCIID lpInterface,
  118. HINSTANCE hLibrary,
  119. LPALLOCATEBUFFER lpAllocBuff,
  120. LPALLOCATEMORE lpAllocMore,
  121. LPFREEBUFFER lpFreeBuff,
  122. LPMALLOC lpMalloc
  123. )
  124. {
  125. HRESULT hResult = hrSuccess;
  126. LPABSRCH lpABSearch = NULL;
  127. SCODE sc;
  128. LPPROPDATA lpPropData = NULL;
  129. SPropValue spv[cvalabsrchMax];
  130. /* Do I support this interface?? */
  131. if (lpInterface)
  132. {
  133. if ( memcmp(lpInterface, &IID_IMAPIContainer, SIZEOF(IID)) &&
  134. memcmp(lpInterface, &IID_IMAPIProp, SIZEOF(IID)) &&
  135. memcmp(lpInterface, &IID_IUnknown, SIZEOF(IID))
  136. )
  137. {
  138. DebugTraceSc(HrNewSearch, MAPI_E_INTERFACE_NOT_SUPPORTED);
  139. return ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
  140. }
  141. }
  142. /*
  143. * Allocate space for the directory container structure
  144. */
  145. sc = lpAllocBuff( SIZEOF(ABSRCH), (LPVOID *) &lpABSearch );
  146. if (FAILED(sc))
  147. {
  148. hResult = ResultFromScode(sc);
  149. goto err;
  150. }
  151. lpABSearch->lpVtbl = &vtblABSRCH;
  152. lpABSearch->lcInit = 1;
  153. lpABSearch->hResult = hrSuccess;
  154. lpABSearch->idsLastError = 0;
  155. lpABSearch->hLibrary = hLibrary;
  156. lpABSearch->lpAllocBuff = lpAllocBuff;
  157. lpABSearch->lpAllocMore = lpAllocMore;
  158. lpABSearch->lpFreeBuff = lpFreeBuff;
  159. lpABSearch->lpMalloc = lpMalloc;
  160. lpABSearch->lpABLogon = lpABLogon;
  161. lpABSearch->lpRestrictData = NULL;
  162. /*
  163. * Create property storage object
  164. */
  165. sc = CreateIProp((LPIID) &IID_IMAPIPropData,
  166. lpAllocBuff,
  167. lpAllocMore,
  168. lpFreeBuff,
  169. lpMalloc,
  170. &lpPropData);
  171. if (FAILED(sc))
  172. {
  173. hResult = ResultFromScode(sc);
  174. goto err;
  175. }
  176. spv[ivalabsrchPR_ANR_STRING].ulPropTag = PR_ANR_STRING_A;
  177. spv[ivalabsrchPR_ANR_STRING].Value.lpszA = "";
  178. /*
  179. * Set the default properties
  180. */
  181. hResult = lpPropData->lpVtbl->SetProps(lpPropData,
  182. cvalabsrchMax,
  183. spv,
  184. NULL);
  185. InitializeCriticalSection(&lpABSearch->cs);
  186. lpABSearch->lpPropData = (LPMAPIPROP) lpPropData;
  187. *lppABSearch = (LPMAPICONTAINER) lpABSearch;
  188. out:
  189. DebugTraceResult(HrNewSearch, hResult);
  190. return hResult;
  191. err:
  192. /*
  193. * free the ABContainer object
  194. */
  195. lpFreeBuff( lpABSearch );
  196. /*
  197. * free the property storage object
  198. */
  199. if (lpPropData)
  200. lpPropData->lpVtbl->Release(lpPropData);
  201. goto out;
  202. }
  203. /*
  204. - ABSRCH_Release
  205. -
  206. * Decrement lcInit.
  207. * When lcInit == 0, free up the lpABSearch structure
  208. *
  209. */
  210. STDMETHODIMP_(ULONG)
  211. ABSRCH_Release(LPABSRCH lpABSearch)
  212. {
  213. long lcInit;
  214. /*
  215. * Check to see if it has a jump table
  216. */
  217. if (IsBadReadPtr(lpABSearch, SIZEOF(ABSRCH)))
  218. {
  219. /*
  220. * No jump table found
  221. */
  222. return 1;
  223. }
  224. /*
  225. * Check to see that it's the correct jump table
  226. */
  227. if (lpABSearch->lpVtbl != &vtblABSRCH)
  228. {
  229. /*
  230. * Not my jump table
  231. */
  232. return 1;
  233. }
  234. EnterCriticalSection(&lpABSearch->cs);
  235. lcInit = --lpABSearch->lcInit;
  236. LeaveCriticalSection(&lpABSearch->cs);
  237. if (lcInit == 0)
  238. {
  239. /*
  240. * Get rid of the lpPropData
  241. */
  242. if (lpABSearch->lpPropData)
  243. lpABSearch->lpPropData->lpVtbl->Release(lpABSearch->lpPropData);
  244. /*
  245. * Free up the restriction data
  246. */
  247. lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
  248. /*
  249. * Destroy the critical section for this object
  250. */
  251. DeleteCriticalSection(&lpABSearch->cs);
  252. /*
  253. * Set the Jump table to NULL. This way the client will find out
  254. * real fast if it's calling a method on a released object. That is,
  255. * the client will crash. Hopefully, this will happen during the
  256. * development stage of the client.
  257. */
  258. lpABSearch->lpVtbl = NULL;
  259. /*
  260. * Need to free the object
  261. */
  262. lpABSearch->lpFreeBuff(lpABSearch);
  263. return 0;
  264. }
  265. return lpABSearch->lcInit;
  266. }
  267. /*
  268. - ABSRCH_SaveChanges
  269. -
  270. * This is used to save changes associated with the search dialog
  271. * in order to get the advanced search restriction and to save changes
  272. * associated with the container details dialog.
  273. *
  274. */
  275. SPropTagArray tagaANR_INT =
  276. {
  277. 1,
  278. {
  279. PR_ANR_STRING_A
  280. }
  281. };
  282. STDMETHODIMP
  283. ABSRCH_SaveChanges(LPABSRCH lpABSearch, ULONG ulFlags)
  284. {
  285. HRESULT hResult;
  286. ULONG ulCount;
  287. LPSPropValue lpspv = NULL;
  288. LPPROPDATA lpPropData = (LPPROPDATA) lpABSearch->lpPropData;
  289. /*
  290. * Check to see if it has a jump table
  291. */
  292. if (IsBadReadPtr(lpABSearch, SIZEOF(ABSRCH)))
  293. {
  294. /*
  295. * No jump table found
  296. */
  297. hResult = ResultFromScode(E_INVALIDARG);
  298. return hResult;
  299. }
  300. /*
  301. * Check to see that it's the correct jump table
  302. */
  303. if (lpABSearch->lpVtbl != &vtblABSRCH)
  304. {
  305. /*
  306. * Not my jump table
  307. */
  308. hResult = ResultFromScode(E_INVALIDARG);
  309. return hResult;
  310. }
  311. EnterCriticalSection(&lpABSearch->cs);
  312. /*
  313. * Is there a PR_ANR_STRING??
  314. */
  315. hResult = lpPropData->lpVtbl->GetProps(lpPropData,
  316. &tagaANR_INT,
  317. 0, /* ansi */
  318. &ulCount,
  319. &lpspv);
  320. if (HR_FAILED(hResult))
  321. {
  322. goto ret;
  323. }
  324. if ((lpspv->ulPropTag == PR_ANR_STRING_A) && (lpspv->Value.lpszA != '\0'))
  325. {
  326. /*
  327. * save away the information to build up the new restriction
  328. */
  329. /* Free any existing data */
  330. if (lpABSearch->lpRestrictData)
  331. {
  332. lpABSearch->lpFreeBuff(lpABSearch->lpRestrictData);
  333. }
  334. lpABSearch->lpRestrictData = lpspv;
  335. lpspv = NULL;
  336. }
  337. ret:
  338. LeaveCriticalSection(&lpABSearch->cs);
  339. lpABSearch->lpFreeBuff(lpspv);
  340. DebugTraceResult(ABSRCH_SaveChanges, hResult);
  341. return hResult;
  342. }
  343. /*************************************************************************
  344. *
  345. - ABSRCH_OpenProperty
  346. -
  347. *
  348. * This method allows the opening of the following object:
  349. *
  350. * PR_DETAILS_TABLE :- Gets the display table associated with
  351. * the advanced search dialog.
  352. */
  353. STDMETHODIMP
  354. ABSRCH_OpenProperty( LPABSRCH lpABSearch,
  355. ULONG ulPropTag,
  356. LPCIID lpiid,
  357. ULONG ulInterfaceOptions,
  358. ULONG ulFlags,
  359. LPUNKNOWN * lppUnk
  360. )
  361. {
  362. HRESULT hResult;
  363. /*
  364. * Check to see if it's big enough to be this object
  365. */
  366. if (IsBadReadPtr(lpABSearch, SIZEOF(ABSRCH)))
  367. {
  368. /*
  369. * Not big enough to be this object
  370. */
  371. hResult = ResultFromScode(E_INVALIDARG);
  372. goto out;
  373. }
  374. /*
  375. * Check to see that it's the correct vtbl
  376. */
  377. if (lpABSearch->lpVtbl != &vtblABSRCH)
  378. {
  379. /*
  380. * Not my vtbl
  381. */
  382. hResult = ResultFromScode(E_INVALIDARG);
  383. goto out;
  384. }
  385. if (IsBadWritePtr(lppUnk, SIZEOF(LPUNKNOWN)))
  386. {
  387. /*
  388. * Got to be able to return an object
  389. */
  390. hResult = ResultFromScode(E_INVALIDARG);
  391. goto out;
  392. }
  393. if (IsBadReadPtr(lpiid, (UINT) SIZEOF(IID)))
  394. {
  395. /*
  396. * An interface ID is required for this call.
  397. */
  398. hResult = ResultFromScode(E_INVALIDARG);
  399. goto out;
  400. }
  401. /*
  402. * check for unknown flags
  403. */
  404. if (ulFlags & ~(MAPI_DEFERRED_ERRORS | MAPI_CREATE | MAPI_MODIFY))
  405. {
  406. hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  407. goto out;
  408. }
  409. /*
  410. * Check for flags we can't support
  411. */
  412. if (ulFlags & (MAPI_CREATE|MAPI_MODIFY))
  413. {
  414. hResult = ResultFromScode(E_ACCESSDENIED);
  415. goto out;
  416. }
  417. if (ulInterfaceOptions & ~MAPI_UNICODE)
  418. {
  419. /*
  420. * Only UNICODE flag should be set for any of the objects that might
  421. * be returned from this object.
  422. */
  423. hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  424. goto out;
  425. }
  426. if ( ulInterfaceOptions & MAPI_UNICODE )
  427. {
  428. hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
  429. DebugTraceArg( ABSRCH_OpenProperty, "bad character width" );
  430. goto out;
  431. }
  432. /*
  433. * Details for this Search object
  434. */
  435. if (ulPropTag == PR_DETAILS_TABLE)
  436. {
  437. if (!memcmp(lpiid, &IID_IMAPITable, SIZEOF(IID)))
  438. {
  439. hResult = HrGetSearchDialog(lpABSearch, (LPMAPITABLE *) lppUnk);
  440. goto out;
  441. }
  442. }
  443. hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  444. out:
  445. DebugTraceResult(ABSRCH_OpenProperty, hResult);
  446. return hResult;
  447. }
  448. /*
  449. - ABSRCH_GetSearchCriteria
  450. -
  451. * Generates the restriction associated with the data from
  452. * the advanced search dialog. This restriction is subsequently
  453. * applied to the contents table retrieved from this container.
  454. */
  455. STDMETHODIMP
  456. ABSRCH_GetSearchCriteria( LPABSRCH lpABSearch,
  457. ULONG ulFlags,
  458. LPSRestriction FAR * lppRestriction,
  459. LPENTRYLIST FAR * lppContainerList,
  460. ULONG FAR * lpulSearchState
  461. )
  462. {
  463. HRESULT hResult = hrSuccess;
  464. SCODE sc;
  465. LPSRestriction lpRestriction = NULL;
  466. LPSPropValue lpPropANR = NULL;
  467. LPSTR lpszPartNameA;
  468. LPSTR lpszRestrNameA;
  469. /*
  470. * Check to see if it's large enough to be my object
  471. */
  472. if (IsBadReadPtr(lpABSearch, SIZEOF(ABSRCH)))
  473. {
  474. /*
  475. * Not large enough
  476. */
  477. hResult = ResultFromScode(E_INVALIDARG);
  478. DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  479. return hResult;
  480. }
  481. /*
  482. * Check to see that it's the correct vtbl
  483. */
  484. if (lpABSearch->lpVtbl != &vtblABSRCH)
  485. {
  486. /*
  487. * Not my vtbl
  488. */
  489. hResult = ResultFromScode(E_INVALIDARG);
  490. DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  491. return hResult;
  492. }
  493. /*
  494. * Check out parameters
  495. */
  496. if ( ulFlags & ~(MAPI_UNICODE) )
  497. {
  498. hResult = ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
  499. DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  500. return hResult;
  501. }
  502. if ( ulFlags & MAPI_UNICODE )
  503. {
  504. DebugTraceArg( ABSRCH_GetSearchCriteria, "bad character width" );
  505. return ResultFromScode( MAPI_E_BAD_CHARWIDTH );
  506. }
  507. if (IsBadWritePtr(lppRestriction, SIZEOF(LPSRestriction)))
  508. {
  509. hResult = ResultFromScode(E_INVALIDARG);
  510. DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  511. return hResult;
  512. }
  513. if (lpulSearchState && IsBadWritePtr(lpulSearchState, SIZEOF(ULONG)))
  514. {
  515. hResult = ResultFromScode(E_INVALIDARG);
  516. DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  517. return hResult;
  518. }
  519. if (lppContainerList && IsBadWritePtr(lppContainerList, SIZEOF(LPENTRYLIST)))
  520. {
  521. hResult = ResultFromScode(E_INVALIDARG);
  522. DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  523. return hResult;
  524. }
  525. if (!lpABSearch->lpRestrictData)
  526. {
  527. hResult = ResultFromScode(MAPI_E_NOT_INITIALIZED);
  528. if (lppRestriction)
  529. *lppRestriction = NULL;
  530. if (lppContainerList)
  531. *lppContainerList = NULL;
  532. if (lpulSearchState)
  533. *lpulSearchState = 0L;
  534. DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  535. return hResult;
  536. }
  537. /*
  538. * Entering state dependant section
  539. */
  540. EnterCriticalSection(&lpABSearch->cs);
  541. /*
  542. * Ok, now build up a restriction using lpRestrictData (an LPSPropValue)
  543. */
  544. sc = lpABSearch->lpAllocBuff(SIZEOF(SRestriction), &lpRestriction);
  545. if (FAILED(sc))
  546. {
  547. hResult = ResultFromScode(sc);
  548. goto err;
  549. }
  550. sc = lpABSearch->lpAllocMore(SIZEOF(SPropValue), lpRestriction, &lpPropANR);
  551. if (FAILED(sc))
  552. {
  553. hResult = ResultFromScode(sc);
  554. goto err;
  555. }
  556. lpszRestrNameA = lpABSearch->lpRestrictData->Value.lpszA;
  557. sc = lpABSearch->lpAllocMore( lstrlenA(lpszRestrNameA)+1,
  558. lpRestriction,
  559. &lpszPartNameA
  560. );
  561. if (FAILED(sc))
  562. {
  563. hResult = ResultFromScode(sc);
  564. goto err;
  565. }
  566. lstrcpyA(lpszPartNameA, lpszRestrNameA);
  567. lpPropANR->ulPropTag = PR_ANR_A;
  568. lpPropANR->Value.lpszA = lpszPartNameA;
  569. lpRestriction->rt = RES_PROPERTY;
  570. lpRestriction->res.resProperty.relop = RELOP_EQ;
  571. lpRestriction->res.resProperty.ulPropTag = PR_ANR_A;
  572. lpRestriction->res.resProperty.lpProp = lpPropANR;
  573. *lppRestriction = lpRestriction;
  574. /*
  575. * The returned SearchState is set to 0 because none
  576. * of the defined states match what's going on.
  577. */
  578. if (lpulSearchState)
  579. *lpulSearchState = 0;
  580. out:
  581. LeaveCriticalSection(&lpABSearch->cs);
  582. DebugTraceResult(ABSRCH_GetSearchCriteria, hResult);
  583. return hResult;
  584. err:
  585. lpABSearch->lpFreeBuff(lpRestriction);
  586. goto out;
  587. }
  588. /*
  589. - HrGetSearchDialog
  590. -
  591. *
  592. * Builds a display table for the search dialog.
  593. */
  594. HRESULT
  595. HrGetSearchDialog(LPABSRCH lpABSearch, LPMAPITABLE * lppSearchTable)
  596. {
  597. HRESULT hResult;
  598. /* Create a display table */
  599. hResult = BuildDisplayTable(
  600. lpABSearch->lpAllocBuff,
  601. lpABSearch->lpAllocMore,
  602. lpABSearch->lpFreeBuff,
  603. lpABSearch->lpMalloc,
  604. lpABSearch->hLibrary,
  605. ARRAYSIZE(rgdtpageSearch),
  606. rgdtpageSearch,
  607. 0,
  608. lppSearchTable,
  609. NULL);
  610. DebugTraceResult(ABSRCH_GetSearchDialog, hResult);
  611. return hResult;
  612. }