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.

2775 lines
90 KiB

  1. /*-----------------------------------------
  2. APITEST.C -- Function Test of WABAPI.DLL
  3. -----------------------------------------*/
  4. #include <windows.h>
  5. #include <wab.h>
  6. #include <wabguid.h>
  7. #include "apitest.h"
  8. #include "instring.h"
  9. #include "dbgutil.h"
  10. #define WinMainT WinMain
  11. long FAR PASCAL WndProc (HWND, UINT, UINT, LONG) ;
  12. #define MAX_INPUT_STRING 200
  13. char szAppName [] = "APITest" ;
  14. HINSTANCE hInst;
  15. enum _AddressTestFlags
  16. {
  17. ADDRESS_CONTENTS = 0,
  18. ADDRESS_CONTENTS_BROWSE,
  19. ADDRESS_CONTENTS_BROWSE_MODAL,
  20. ADDRESS_WELLS,
  21. ADDRESS_WELLS_DEFAULT,
  22. };
  23. void AllocTest(void);
  24. void IPropTest(void);
  25. void WABOpenTest(void);
  26. void CreateEntryTest(HWND hwnd, BOOL fDL);
  27. void GetContentsTableTest(void);
  28. void GetSearchPathTest(void);
  29. void ResolveNameTest(HWND hwnd);
  30. void ResolveNamesTest(HWND hwnd);
  31. void DeleteEntriesTest(HWND hwnd);
  32. void WABAddressTest(HWND hWnd, int iFlag, int cDestWells);
  33. void AddrBookDetailsTest(HWND hwnd);
  34. void AddrBookDetailsOneOffTest(HWND hwnd);
  35. void RootContainerTest(void);
  36. void NotificationsTest(HWND hwnd);
  37. void GetMeTest(HWND hWnd);
  38. #define DATABASE_KEY HKEY_CURRENT_USER
  39. #define CCH_MAX_REGISTRY_DATA 256
  40. const TCHAR szMainSectionName[] = TEXT("APITest"); // Test settings in here
  41. const TCHAR szIniSectionName[] = TEXT("Software\\Microsoft\\WAB\\Test"); // Look here for settings
  42. const TCHAR szContactNumberKey[] = TEXT("Next Contact Number");
  43. const TCHAR szContainerNumberKey[] = TEXT("Container Number");
  44. //
  45. // Global WAB Allocator access functions
  46. //
  47. typedef struct _WAB_ALLOCATORS {
  48. LPWABOBJECT lpWABObject;
  49. LPWABALLOCATEBUFFER lpAllocateBuffer;
  50. LPWABALLOCATEMORE lpAllocateMore;
  51. LPWABFREEBUFFER lpFreeBuffer;
  52. } WAB_ALLOCATORS, *LPWAB_ALLOCATORS;
  53. ULONG ulContainerNumber = 0;
  54. WAB_ALLOCATORS WABAllocators = {0};
  55. /***************************************************************************
  56. Name : SetGlobalBufferFunctions
  57. Purpose : Set the global buffer functions based on methods from
  58. the WAB object.
  59. Parameters: lpWABObject = the open wab object
  60. Returns : none
  61. Comment :
  62. ***************************************************************************/
  63. void SetGlobalBufferFunctions(LPWABOBJECT lpWABObject) {
  64. if (lpWABObject && WABAllocators.lpWABObject != lpWABObject) {
  65. WABAllocators.lpAllocateBuffer = lpWABObject->lpVtbl->AllocateBuffer;
  66. WABAllocators.lpAllocateMore = lpWABObject->lpVtbl->AllocateMore;
  67. WABAllocators.lpFreeBuffer = lpWABObject->lpVtbl->FreeBuffer;
  68. WABAllocators.lpWABObject = lpWABObject;
  69. }
  70. }
  71. /***************************************************************************
  72. Name : WABAllocateBuffer
  73. Purpose : Use the WAB Allocator
  74. Parameters: cbSize = size to allocate
  75. lppBuffer = returned buffer
  76. Returns : SCODE
  77. Comment :
  78. ***************************************************************************/
  79. SCODE WABAllocateBuffer(ULONG cbSize, LPVOID FAR * lppBuffer) {
  80. if (WABAllocators.lpWABObject && WABAllocators.lpAllocateBuffer) {
  81. return(WABAllocators.lpAllocateBuffer(WABAllocators.lpWABObject, cbSize, lppBuffer));
  82. } else {
  83. return(MAPI_E_INVALID_OBJECT);
  84. }
  85. }
  86. /***************************************************************************
  87. Name : WABAllocateMore
  88. Purpose : Use the WAB Allocator
  89. Parameters: cbSize = size to allocate
  90. lpObject = existing allocation
  91. lppBuffer = returned buffer
  92. Returns : SCODE
  93. Comment :
  94. ***************************************************************************/
  95. SCODE WABAllocateMore(ULONG cbSize, LPVOID lpObject, LPVOID FAR * lppBuffer) {
  96. if (WABAllocators.lpWABObject && WABAllocators.lpAllocateMore) {
  97. return(WABAllocators.lpAllocateMore(WABAllocators.lpWABObject, cbSize, lpObject, lppBuffer));
  98. } else {
  99. return(MAPI_E_INVALID_OBJECT);
  100. }
  101. }
  102. /***************************************************************************
  103. Name : WABFreeBuffer
  104. Purpose : Use the WAB Allocator
  105. Parameters: lpBuffer = buffer to free
  106. Returns : SCODE
  107. Comment :
  108. ***************************************************************************/
  109. SCODE WABFreeBuffer(LPVOID lpBuffer) {
  110. if (WABAllocators.lpWABObject && WABAllocators.lpFreeBuffer) {
  111. return(WABAllocators.lpFreeBuffer(WABAllocators.lpWABObject, lpBuffer));
  112. } else {
  113. return(MAPI_E_INVALID_OBJECT);
  114. }
  115. }
  116. /***************************************************************************
  117. Name : WABFreePadrlist
  118. Purpose : Free an adrlist and it's property arrays
  119. Parameters: lpBuffer = buffer to free
  120. Returns : SCODE
  121. Comment :
  122. ***************************************************************************/
  123. void WABFreePadrlist(LPADRLIST lpAdrList) {
  124. ULONG iEntry;
  125. if (lpAdrList) {
  126. for (iEntry = 0; iEntry < lpAdrList->cEntries; ++iEntry) {
  127. if (lpAdrList->aEntries[iEntry].rgPropVals) {
  128. WABFreeBuffer(lpAdrList->aEntries[iEntry].rgPropVals);
  129. }
  130. }
  131. WABFreeBuffer(lpAdrList);
  132. }
  133. }
  134. /***************************************************************************
  135. Name : StrInteger
  136. Purpose : Replace atoi(). Base 10 string to integer.
  137. Parameters: lpszString = string pointer (null terminated)
  138. Returns : integer value found in lpszString
  139. Comment : Reads characters from lpszString until a non-digit is found.
  140. ***************************************************************************/
  141. int __fastcall StrInteger(LPCTSTR lpszString) {
  142. register DWORD dwInt = 0;
  143. register LPTSTR lpsz = (LPTSTR)lpszString;
  144. if (lpsz) {
  145. while (*lpsz > '0' && *lpsz < '9') {
  146. dwInt = dwInt * 10 + (*lpsz - '0');
  147. lpsz++;
  148. }
  149. }
  150. return(dwInt);
  151. }
  152. /***************************************************************************
  153. Name : GetInitializerInt
  154. Purpose : Gets an integer value from the initializer data
  155. Parameters: lpszSection = section name
  156. lpszKey = key name
  157. dwDefault = default value if key not found
  158. lpszFile = inifile/keyname
  159. Returns : UINT value from the initializer database (registry)
  160. Comment : Same interface as GetPrivateProfileInt: If the key is not
  161. found, the return value is the specified default value.
  162. If value of the key is less than zero, the return value
  163. is zero.
  164. The registry key to get here is:
  165. lpszFile\lpszSection
  166. The value name is lpszKey.
  167. ***************************************************************************/
  168. UINT GetInitializerInt(LPCTSTR lpszSection, LPCTSTR lpszKey, INT dwDefault,
  169. LPCTSTR lpszFile) {
  170. LPTSTR lpszKeyName = NULL;
  171. HKEY hKey = NULL;
  172. INT iReturn = 0;
  173. DWORD dwType;
  174. DWORD cbData = CCH_MAX_REGISTRY_DATA;
  175. BYTE lpData[CCH_MAX_REGISTRY_DATA];
  176. DWORD cchKey;
  177. DWORD dwErr;
  178. if (lpszFile == NULL || lpszSection == NULL || lpszKey == NULL) {
  179. return(dwDefault);
  180. }
  181. cchKey = lstrlen(lpszFile) + lstrlen(lpszSection) + 2;
  182. if ((lpszKeyName = LocalAlloc(LPTR, cchKey)) == NULL) {
  183. DebugTrace("GetInitializerInt: LocalAlloc(%u) failed\n", cchKey);
  184. return(0);
  185. }
  186. // Create keyname string
  187. lstrcpy(lpszKeyName, lpszFile);
  188. lstrcat(lpszKeyName, "\\");
  189. lstrcat(lpszKeyName, lpszSection);
  190. if (dwErr = RegOpenKeyEx(DATABASE_KEY, lpszKeyName, 0, KEY_READ, &hKey)) {
  191. DebugTrace("GetInitializerInt: RegOpenKeyEx(%s) --> %u, using default.\n",
  192. lpszKeyName, dwErr);
  193. iReturn = dwDefault; // default
  194. goto Exit;
  195. }
  196. if (dwErr = RegQueryValueEx(hKey, (LPTSTR)lpszKey, 0, &dwType, lpData, &cbData)) {
  197. iReturn = dwDefault;
  198. goto Exit;
  199. }
  200. switch (dwType) {
  201. case REG_SZ:
  202. iReturn = StrInteger((char *)lpData);
  203. if (iReturn < 0) {
  204. iReturn = 0; // match spec of GetPrivateProfileInt.
  205. }
  206. break;
  207. case REG_DWORD:
  208. if ((iReturn = (INT)(*(DWORD *)lpData)) < 0) {
  209. iReturn = 0; // match spec of GetPrivateProfileInt.
  210. }
  211. break;
  212. default:
  213. DebugTrace("GetInitializerInt: RegQueryValueEx(%s) -> UNKNOWN dwType = %u\n",
  214. lpszKey, dwType);
  215. iReturn = dwDefault;
  216. break;
  217. }
  218. Exit:
  219. if (hKey) {
  220. RegCloseKey(hKey);
  221. }
  222. LocalFree(lpszKeyName);
  223. return(iReturn);
  224. }
  225. /***************************************************************************
  226. Name : WriteRegistryString
  227. Purpose : Sets the string value in the registry
  228. Parameters: hKeyRoot = root key
  229. lpszSection = section name
  230. lpszKey = key name
  231. lpszString = string value to add
  232. lpszFile = inifile/keyname
  233. Returns : TRUE on success
  234. ***************************************************************************/
  235. BOOL WriteRegistryString(HKEY hKeyRoot, LPCTSTR lpszSection, LPCTSTR lpszKey,
  236. LPCTSTR lpszString, LPCTSTR lpszFile) {
  237. DWORD cchKey;
  238. LPTSTR lpszKeyName = NULL;
  239. HKEY hKey = NULL;
  240. BOOL fReturn = FALSE;
  241. DWORD dwDisposition;
  242. DWORD dwErr;
  243. if (lpszFile == NULL || lpszSection == NULL || lpszKey == NULL) {
  244. return(FALSE);
  245. }
  246. cchKey = lstrlen(lpszFile) + lstrlen(lpszSection) + 2;
  247. if ((lpszKeyName = LocalAlloc(LPTR, cchKey)) == NULL) {
  248. DebugTrace("WriteInitializerString: LocalAlloc(%u) failed\n", cchKey);
  249. return(0);
  250. }
  251. // Create keyname string
  252. lstrcpy(lpszKeyName, lpszFile);
  253. lstrcat(lpszKeyName, "\\");
  254. lstrcat(lpszKeyName, lpszSection);
  255. if (dwErr = RegCreateKeyEx(hKeyRoot, lpszKeyName, 0, NULL,
  256. REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hKey, &dwDisposition)) {
  257. DebugTrace("WriteInitializerString: RegCreateKeyEx(%s) --> %u.\n",
  258. lpszKeyName, dwErr);
  259. goto Exit;
  260. }
  261. if (dwErr = RegSetValueEx(hKey, lpszKey, 0, REG_SZ,
  262. (CONST LPBYTE)lpszString, lstrlen(lpszString) + 1)) {
  263. DebugTrace("WriteInitializerString: RegSetValueEx(%s) --> %u.\n",
  264. lpszKey, dwErr);
  265. goto Exit;
  266. }
  267. fReturn = TRUE; // must have succeeded
  268. Exit:
  269. if (hKey) {
  270. RegCloseKey(hKey);
  271. }
  272. LocalFree(lpszKeyName);
  273. return(fReturn);
  274. }
  275. /***************************************************************************
  276. Name : WriteInitializerString
  277. Purpose : Sets the string value in the initializer data
  278. Parameters: lpszSection = section name
  279. lpszKey = key name
  280. lpszString = string value to add
  281. lpszFile = inifile/keyname
  282. Returns : TRUE on success
  283. Comment : Same interface as WritePrivateProfileString.
  284. The registry key to get here is:
  285. lpszFile\lpszSection
  286. The value name is lpszKey.
  287. ***************************************************************************/
  288. BOOL WriteInitializerString(LPCTSTR lpszSection, LPCTSTR lpszKey,
  289. LPCTSTR lpszString, LPCTSTR lpszFile) {
  290. return(WriteRegistryString(DATABASE_KEY, lpszSection, lpszKey,
  291. lpszString, lpszFile));
  292. }
  293. /***************************************************************************
  294. Name : WriteInitializerInt
  295. Purpose : Sets the integer value in the initializer data
  296. Parameters: lpszSection = section name
  297. lpszKey = key name
  298. i = int value to add
  299. lpszFile = inifile/keyname
  300. Returns : TRUE on success
  301. Comment : Same interface as WritePrivateProfileInt would be if
  302. there were one.
  303. The registry key to get here is:
  304. lpszFile\lpszSection
  305. The value name is lpszKey.
  306. ***************************************************************************/
  307. BOOL WriteInitializerInt(LPCTSTR lpszSection, LPCTSTR lpszKey,
  308. DWORD i, LPCTSTR lpszFile) {
  309. TCHAR szIntString[12]; // put string representation of int here.
  310. wsprintf(szIntString, "%u", i);
  311. return(WriteInitializerString(lpszSection, lpszKey,
  312. szIntString, lpszFile));
  313. }
  314. /***************************************************************************
  315. Name : GetNewMessageReference
  316. Purpose : Generate a unique messag reference value
  317. Parameters: none
  318. Returns : return ULONG message reference value.
  319. Comment : Look in registry for the next available message reference
  320. value and update the registry. We will increment the number
  321. to keep track of the number of faxes sent or received. Since
  322. the number is a DWORD, it should be sufficient for the life
  323. of the product. ie, if we could send 1 fax every second,
  324. it would last over 137 years.
  325. We will maintain the number as a count of messages handled,
  326. and will use the current number before incrementing as the
  327. ulMessageRef.
  328. This number will increment for all attempts to send and
  329. receive, not just successes.
  330. WARNING: This code is not reentrant!
  331. ***************************************************************************/
  332. ULONG GetNewMessageReference(void) {
  333. ULONG ulNum;
  334. if ((ulNum = GetInitializerInt(szMainSectionName, szContactNumberKey,
  335. 0xFFFFFFFF, szIniSectionName)) == 0xFFFFFFFF) {
  336. // Start with a one.
  337. ulNum = 1;
  338. }
  339. WriteInitializerInt(szMainSectionName, szContactNumberKey, ulNum + 1,
  340. szIniSectionName);
  341. return(ulNum);
  342. }
  343. /***************************************************************************
  344. Name : FindProperty
  345. Purpose : Finds a property in a proparray
  346. Parameters: cProps = number of props in the array
  347. lpProps = proparray
  348. ulPropTag = property tag to look for
  349. Returns : array index of property or NOT_FOUND
  350. Comment :
  351. ***************************************************************************/
  352. ULONG FindProperty(ULONG cProps, LPSPropValue lpProps, ULONG ulPropTag) {
  353. register ULONG i;
  354. for (i = 0; i < cProps; i++) {
  355. if (lpProps[i].ulPropTag == ulPropTag) {
  356. return(i);
  357. }
  358. }
  359. return((ULONG)-1);
  360. }
  361. /***************************************************************************
  362. Name : FindAdrEntryID
  363. Purpose : Find the PR_ENTRYID in the Nth ADRENTRY of an ADRLIST
  364. Parameters: lpAdrList -> AdrList
  365. index = which ADRENTRY to look at
  366. Returns : return pointer to the SBinary structure of the ENTRYID value
  367. Comment :
  368. ***************************************************************************/
  369. LPSBinary FindAdrEntryID(LPADRLIST lpAdrList, ULONG index) {
  370. LPADRENTRY lpAdrEntry;
  371. ULONG i;
  372. if (lpAdrList && index < lpAdrList->cEntries) {
  373. lpAdrEntry = &(lpAdrList->aEntries[index]);
  374. for (i = 0; i < lpAdrEntry->cValues; i++) {
  375. if (lpAdrEntry->rgPropVals[i].ulPropTag == PR_ENTRYID) {
  376. return((LPSBinary)&lpAdrEntry->rgPropVals[i].Value);
  377. }
  378. }
  379. }
  380. return(NULL);
  381. }
  382. //
  383. // Properties to get from the contents table
  384. //
  385. enum {
  386. ircPR_OBJECT_TYPE = 0,
  387. ircPR_ENTRYID,
  388. ircPR_DISPLAY_NAME,
  389. ircMax
  390. };
  391. static const SizedSPropTagArray(ircMax, ptaRoot) =
  392. {
  393. ircMax,
  394. {
  395. PR_OBJECT_TYPE,
  396. PR_ENTRYID,
  397. PR_DISPLAY_NAME,
  398. }
  399. };
  400. HRESULT GetContainerEID(LPADRBOOK lpAdrBook, LPULONG lpcbEID, LPENTRYID * lppEID) {
  401. HRESULT hResult;
  402. ULONG ulObjType;
  403. LPABCONT lpRoot = NULL;
  404. LPMAPITABLE lpRootTable = NULL;
  405. LPSRowSet lpRow = NULL;
  406. if (ulContainerNumber) {
  407. // Get the root contents table
  408. if (! (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  409. 0,
  410. NULL,
  411. NULL,
  412. 0,
  413. &ulObjType,
  414. (LPUNKNOWN *)&lpRoot))) {
  415. if (! (hResult = lpRoot->lpVtbl->GetContentsTable(lpRoot,
  416. 0,
  417. &lpRootTable))) {
  418. // Set the columns
  419. lpRootTable->lpVtbl->SetColumns(lpRootTable,
  420. (LPSPropTagArray)&ptaRoot,
  421. 0);
  422. lpRootTable->lpVtbl->SeekRow(lpRootTable,
  423. BOOKMARK_BEGINNING,
  424. ulContainerNumber,
  425. NULL);
  426. if (hResult = lpRootTable->lpVtbl->QueryRows(lpRootTable,
  427. 1, // one row at a time
  428. 0, // ulFlags
  429. &lpRow)) {
  430. DebugTrace("GetContainerEID: QueryRows -> %x\n", GetScode(hResult));
  431. } else {
  432. // Found it, copy entryid to new allocation
  433. if (lpRow->cRows) {
  434. *lpcbEID = lpRow->aRow[0].lpProps[ircPR_ENTRYID].Value.bin.cb;
  435. WABAllocateBuffer(*lpcbEID, lppEID);
  436. memcpy(*lppEID, lpRow->aRow[0].lpProps[ircPR_ENTRYID].Value.bin.lpb, *lpcbEID);
  437. } else {
  438. hResult = ResultFromScode(MAPI_E_NOT_FOUND);
  439. DebugTrace("GetContainerEID couldn't find -> container %u\n", ulContainerNumber);
  440. }
  441. FreeProws(lpRow);
  442. }
  443. lpRootTable->lpVtbl->Release(lpRootTable);
  444. }
  445. lpRoot->lpVtbl->Release(lpRoot);
  446. }
  447. } else {
  448. hResult = lpAdrBook->lpVtbl->GetPAB(lpAdrBook,
  449. lpcbEID,
  450. lppEID);
  451. }
  452. return(hResult);
  453. }
  454. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) {
  455. HWND hwnd ;
  456. MSG msg ;
  457. WNDCLASS wndclass ;
  458. if (!hPrevInstance) {
  459. hInst = hInstance;
  460. wndclass.style = CS_HREDRAW | CS_VREDRAW ;
  461. wndclass.lpfnWndProc = WndProc ;
  462. wndclass.cbClsExtra = 0 ;
  463. wndclass.cbWndExtra = 0 ;
  464. wndclass.hInstance = hInstance ;
  465. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION) ;
  466. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW) ;
  467. wndclass.hbrBackground = GetStockObject(WHITE_BRUSH) ;
  468. wndclass.lpszMenuName = szAppName ;
  469. wndclass.lpszClassName = szAppName ;
  470. RegisterClass (&wndclass) ;
  471. }
  472. hwnd = CreateWindow (szAppName, "WAB API Test",
  473. WS_OVERLAPPEDWINDOW,
  474. 0, // CW_USEDEFAULT,
  475. 0, // CW_USEDEFAULT,
  476. 300, // CW_USEDEFAULT,
  477. 200, // CW_USEDEFAULT,
  478. NULL,
  479. NULL,
  480. hInstance,
  481. NULL) ;
  482. ShowWindow (hwnd, nCmdShow) ;
  483. UpdateWindow (hwnd) ;
  484. while (GetMessage(&msg, NULL, 0, 0)) {
  485. TranslateMessage (&msg) ;
  486. DispatchMessage (&msg) ;
  487. }
  488. return msg.wParam ;
  489. }
  490. long FAR PASCAL WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam) {
  491. switch (message) {
  492. case WM_CREATE:
  493. if ((ulContainerNumber = GetInitializerInt(szMainSectionName, szContainerNumberKey,
  494. 0xFFFFFFFF, szIniSectionName)) == 0xFFFFFFFF) {
  495. // None
  496. ulContainerNumber = 0;
  497. }
  498. break;
  499. case WM_COMMAND :
  500. switch (wParam) {
  501. case IDM_EXIT :
  502. SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
  503. return 0 ;
  504. case IDM_GETME:
  505. GetMeTest(hwnd);
  506. return(0);
  507. case IDM_ALLOCATE:
  508. AllocTest();
  509. return(0);
  510. case IDM_IPROP:
  511. IPropTest();
  512. return(0);
  513. case IDM_GETSEARCHPATH:
  514. GetSearchPathTest();
  515. return(0);
  516. case IDM_CONTENTS_TABLE:
  517. GetContentsTableTest();
  518. return(0);
  519. case IDM_WABOPEN:
  520. WABOpenTest();
  521. return(0);
  522. case IDM_CREATE_ENTRY:
  523. CreateEntryTest(hwnd, FALSE);
  524. return(0);
  525. case IDM_CREATE_DL:
  526. CreateEntryTest(hwnd, TRUE);
  527. break;
  528. case IDM_RESOLVE_NAME:
  529. ResolveNameTest(hwnd);
  530. return(0);
  531. case IDM_DETAILS:
  532. AddrBookDetailsTest(hwnd);
  533. return(0);
  534. case IDM_DETAILS_ONE_OFF:
  535. AddrBookDetailsOneOffTest(hwnd);
  536. return(0);
  537. case IDM_RESOLVE_NAMES:
  538. ResolveNamesTest(hwnd);
  539. return(0);
  540. case IDM_DELETE_ENTRIES:
  541. DeleteEntriesTest(hwnd);
  542. return(0);
  543. case IDM_ADDRESS_WELLS0:
  544. WABAddressTest(hwnd,ADDRESS_WELLS,0);
  545. return(0);
  546. case IDM_ADDRESS_WELLS1:
  547. WABAddressTest(hwnd,ADDRESS_WELLS,1);
  548. return(0);
  549. case IDM_ADDRESS_WELLS2:
  550. WABAddressTest(hwnd,ADDRESS_WELLS,2);
  551. return(0);
  552. case IDM_ADDRESS_DEFAULT:
  553. WABAddressTest(hwnd,ADDRESS_WELLS_DEFAULT,3);
  554. return(0);
  555. case IDM_ADDRESS_WELLS3:
  556. WABAddressTest(hwnd,ADDRESS_WELLS,3);
  557. return(0);
  558. case IDM_ADDRESS_PICK_USER:
  559. WABAddressTest(hwnd,ADDRESS_CONTENTS,0);
  560. return(0);
  561. case IDM_ADDRESS_BROWSE_ONLY:
  562. WABAddressTest(hwnd,ADDRESS_CONTENTS_BROWSE,0);
  563. return(0);
  564. case IDM_ADDRESS_BROWSE_MODAL_ONLY:
  565. WABAddressTest(hwnd,ADDRESS_CONTENTS_BROWSE_MODAL,0);
  566. return(0);
  567. case IDM_ROOT_CONTAINER:
  568. RootContainerTest();
  569. return(0);
  570. case IDM_NOTIFICATIONS:
  571. NotificationsTest(hwnd);
  572. return(0);
  573. case IDM_ABOUT:
  574. MessageBox (hwnd, "WAB API Function Test.",
  575. szAppName, MB_ICONINFORMATION | MB_OK);
  576. return(0);
  577. }
  578. break ;
  579. case WM_DESTROY:
  580. PostQuitMessage(0);
  581. return(0);
  582. }
  583. return(DefWindowProc (hwnd, message, wParam, lParam));
  584. }
  585. #define MAX_INPUT_STRING 200
  586. void AllocTest(void) {
  587. LPTSTR lpBuffer = NULL;
  588. LPWABOBJECT lpWABObject = NULL;
  589. LPADRBOOK lpAdrBook = NULL;
  590. WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  591. SetGlobalBufferFunctions(lpWABObject);
  592. WABAllocateBuffer(1234, &lpBuffer);
  593. WABFreeBuffer(lpBuffer);
  594. lpAdrBook->lpVtbl->Release(lpAdrBook);
  595. lpWABObject->lpVtbl->Release(lpWABObject);
  596. }
  597. // enum for setting the created properties
  598. enum {
  599. imuPR_DISPLAY_NAME = 0, // must be first so DL's can use same enum
  600. imuPR_SURNAME,
  601. imuPR_GIVEN_NAME,
  602. imuPR_EMAIL_ADDRESS,
  603. imuPR_ADDRTYPE,
  604. imuMax
  605. };
  606. static const SizedSPropTagArray(imuMax, ptag)=
  607. {
  608. imuMax,
  609. {
  610. PR_DISPLAY_NAME,
  611. PR_SURNAME,
  612. PR_GIVEN_NAME,
  613. PR_EMAIL_ADDRESS,
  614. PR_ADDRTYPE,
  615. }
  616. };
  617. void IPropTest(void) {
  618. LPPROPDATA lpPropData = NULL;
  619. SPropValue spv[imuMax];
  620. LPTSTR lpszDisplayName = "Bruce Kelley xxxxx";
  621. LPTSTR lpszEmailName = "[email protected]";
  622. HRESULT hResult = hrSuccess;
  623. LPWABOBJECT lpWABObject = NULL;
  624. LPADRBOOK lpAdrBook = NULL;
  625. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  626. SetGlobalBufferFunctions(lpWABObject);
  627. WABCreateIProp(NULL,
  628. (LPALLOCATEBUFFER)WABAllocateBuffer,
  629. (LPALLOCATEMORE)WABAllocateMore,
  630. (LPFREEBUFFER)WABFreeBuffer,
  631. NULL,
  632. &lpPropData);
  633. if (lpPropData) {
  634. spv[imuPR_EMAIL_ADDRESS].ulPropTag = PR_EMAIL_ADDRESS;
  635. spv[imuPR_EMAIL_ADDRESS].Value.lpszA = lpszEmailName;
  636. spv[imuPR_ADDRTYPE].ulPropTag = PR_ADDRTYPE;
  637. spv[imuPR_ADDRTYPE].Value.lpszA = "SMTP";
  638. spv[imuPR_DISPLAY_NAME].ulPropTag = PR_DISPLAY_NAME;
  639. spv[imuPR_DISPLAY_NAME].Value.lpszA = lpszDisplayName;
  640. spv[imuPR_SURNAME].ulPropTag = PR_SURNAME;
  641. spv[imuPR_SURNAME].Value.lpszA = "Kelley";
  642. spv[imuPR_GIVEN_NAME].ulPropTag = PR_GIVEN_NAME;
  643. spv[imuPR_GIVEN_NAME].Value.lpszA = "Bruce";
  644. if (HR_FAILED(hResult = lpPropData->lpVtbl->SetProps(lpPropData, // this
  645. imuMax, // cValues
  646. spv, // property array
  647. NULL))) { // problems array
  648. }
  649. hResult = lpPropData->lpVtbl->SaveChanges(lpPropData, // this
  650. 0); // ulFlags
  651. lpPropData->lpVtbl->Release(lpPropData);
  652. }
  653. lpAdrBook->lpVtbl->Release(lpAdrBook);
  654. lpWABObject->lpVtbl->Release(lpWABObject);
  655. }
  656. #define WORKS_STUFF TRUE
  657. #ifdef WORKS_STUFF
  658. #define PR_WKS_CONTACT_CHECKED PROP_TAG( PT_LONG, 0x8020)
  659. const SizedSPropTagArray(4 , ipta) = {
  660. 4, // count of entries
  661. {
  662. PR_DISPLAY_NAME,
  663. PR_ENTRYID,
  664. PR_OBJECT_TYPE,
  665. PR_WKS_CONTACT_CHECKED,
  666. }
  667. };
  668. #else
  669. const SizedSPropTagArray(3 , ipta) = {
  670. 3,
  671. {
  672. PR_DISPLAY_NAME,
  673. PR_ENTRYID,
  674. PR_OBJECT_TYPE,
  675. }
  676. };
  677. #endif
  678. #ifdef WORKS_STUFF
  679. #define nStatusCheck 1
  680. HRESULT RestrictToContactAndCheck(LPMAPITABLE pWabTable)
  681. {
  682. SRestriction resAnd[2];
  683. SRestriction resResolve;
  684. SPropValue propRestrict0, propRestrict1;
  685. HRESULT hr;
  686. // Restrict to get checked status
  687. resAnd[0].rt = RES_PROPERTY; // Restriction type Property
  688. resAnd[0].res.resProperty.relop = RELOP_EQ;
  689. resAnd[0].res.resProperty.ulPropTag = PR_WKS_CONTACT_CHECKED;
  690. resAnd[0].res.resProperty.lpProp = &propRestrict0;
  691. propRestrict0.ulPropTag = PR_WKS_CONTACT_CHECKED;
  692. propRestrict0.Value.ul = nStatusCheck; // this is actually a #define with value of 1
  693. // Restrict to get contact (MailUsers)
  694. resAnd[1].rt = RES_PROPERTY; // Restriction type Property
  695. resAnd[1].res.resProperty.relop = RELOP_EQ;
  696. resAnd[1].res.resProperty.ulPropTag = PR_OBJECT_TYPE;
  697. resAnd[1].res.resProperty.lpProp = &propRestrict1;
  698. propRestrict1.ulPropTag = PR_OBJECT_TYPE;
  699. propRestrict1.Value.ul = MAPI_MAILUSER;
  700. resResolve.rt = RES_AND;
  701. resResolve.res.resAnd.cRes = 2;
  702. resResolve.res.resAnd.lpRes = resAnd;
  703. hr = pWabTable->lpVtbl->Restrict(pWabTable, &resResolve, 0);
  704. return(hr);
  705. }
  706. #endif
  707. #ifdef PHONE_STUFF
  708. #define WAB_PHONE_TYPE_COUNT 2
  709. ULONG WABPHONEPROPLIST[WAB_PHONE_TYPE_COUNT] = {
  710. PR_BUSINESS_TELEPHONE_NUMBER,
  711. PR_HOME_TELEPHONE_NUMBER
  712. };
  713. /*----------------------------------------------------------------------------
  714. Purpose: Given a phone number returns the Name in the WAB if exists.
  715. Paramaters:
  716. LPCTSTR lpcstrInputNumber: Input Number string
  717. #ifdef OLD_STUFF
  718. LPTSTR lptstrOutputName: Output Name string
  719. #endif // OLD_STUFF
  720. History
  721. 02/10/97 a-ericwa Created
  722. ----------------------------------------------------------------------------*/
  723. HRESULT WABNumberToName(LPADRBOOK m_pAdrBook, LPCTSTR lpcstrInputNumber) {
  724. HRESULT hRes = NOERROR;
  725. LPENTRYID lpEntryID = NULL;
  726. LPABCONT lpContainer = NULL;
  727. LPMAPITABLE lpMapiTable = NULL;
  728. UINT cColumn = 0;
  729. LPSPropValue lpPropValue = NULL;
  730. LPSRowSet lpRow = NULL;
  731. ULONG ulObjType = 0;
  732. ULONG ulCounter = 0;
  733. ULONG ulRowCount = 0;
  734. ULONG ulEntryIDSize = 0;
  735. LPSTR lpszTempOutput = NULL;
  736. BOOL bFound = FALSE;
  737. SRestriction srOr, srPhoneNumType[WAB_PHONE_TYPE_COUNT]; //for the restriction
  738. SPropValue spvPhoneNumType[WAB_PHONE_TYPE_COUNT]; // d dd ddd ditto
  739. SizedSPropTagArray(21, OUR_PROPTAG_ARRAY) = {
  740. 21, {
  741. PR_OBJECT_TYPE,
  742. PR_ENTRYID,
  743. PR_DISPLAY_NAME,
  744. PR_CALLBACK_TELEPHONE_NUMBER,
  745. PR_BUSINESS_TELEPHONE_NUMBER,
  746. PR_OFFICE_TELEPHONE_NUMBER,
  747. PR_HOME_TELEPHONE_NUMBER,
  748. PR_PRIMARY_TELEPHONE_NUMBER,
  749. PR_BUSINESS2_TELEPHONE_NUMBER,
  750. PR_OFFICE2_TELEPHONE_NUMBER,
  751. PR_MOBILE_TELEPHONE_NUMBER,
  752. PR_CELLULAR_TELEPHONE_NUMBER,
  753. PR_RADIO_TELEPHONE_NUMBER,
  754. PR_CAR_TELEPHONE_NUMBER,
  755. PR_OTHER_TELEPHONE_NUMBER,
  756. PR_PAGER_TELEPHONE_NUMBER,
  757. PR_BEEPER_TELEPHONE_NUMBER,
  758. PR_ASSISTANT_TELEPHONE_NUMBER,
  759. PR_HOME2_TELEPHONE_NUMBER,
  760. PR_PRIMARY_FAX_NUMBER,
  761. PR_HOME_FAX_NUMBER,
  762. }
  763. };
  764. //validate input
  765. if (!lpcstrInputNumber) {
  766. goto WABNTN_Exit;
  767. }
  768. //Get the PAB
  769. hRes = m_pAdrBook->lpVtbl->GetPAB(m_pAdrBook,
  770. &ulEntryIDSize, //size
  771. &lpEntryID); //EntryId
  772. if (FAILED(hRes)) {
  773. goto WABNTN_Exit;
  774. }
  775. //Open the root container
  776. hRes = m_pAdrBook->lpVtbl->OpenEntry(m_pAdrBook,
  777. ulEntryIDSize, // size of EntryID to open
  778. lpEntryID, // EntryID to open
  779. NULL, // interface
  780. 0, // flags (default is Read Only)
  781. &ulObjType, //object type
  782. (LPUNKNOWN *)&lpContainer); //returned object
  783. if (FAILED(hRes) || (ulObjType != MAPI_ABCONT)) {
  784. goto WABNTN_Exit;
  785. }
  786. //Get the contents
  787. hRes = lpContainer->lpVtbl->GetContentsTable(lpContainer,
  788. 0, //FLAGS
  789. &lpMapiTable); //returned Table Object
  790. if (FAILED(hRes)) {
  791. goto WABNTN_Exit;
  792. }
  793. // Set desired columns
  794. hRes = lpMapiTable->lpVtbl->SetColumns(lpMapiTable,
  795. (LPSPropTagArray)&OUR_PROPTAG_ARRAY, // SPropTagArray of desired rows
  796. 0); // reserved Must be zero for the WAB
  797. if (FAILED(hRes)) {
  798. goto WABNTN_Exit;
  799. }
  800. //Seek to the beginning
  801. hRes = lpMapiTable->lpVtbl->SeekRow(lpMapiTable, BOOKMARK_BEGINNING, 0, NULL);
  802. if (FAILED(hRes)) {
  803. goto WABNTN_Exit;
  804. }
  805. //Create the restriction
  806. srOr.rt = RES_OR;
  807. srOr.res.resOr.cRes = WAB_PHONE_TYPE_COUNT;
  808. srOr.res.resOr.lpRes = srPhoneNumType;
  809. for (ulCounter = 0; ulCounter < WAB_PHONE_TYPE_COUNT; ulCounter++) {
  810. spvPhoneNumType[ulCounter].ulPropTag = WABPHONEPROPLIST[ulCounter];
  811. spvPhoneNumType[ulCounter].Value.lpszA = (LPSTR) lpcstrInputNumber;
  812. spvPhoneNumType[ulCounter].dwAlignPad = 0;
  813. srPhoneNumType[ulCounter].rt = RES_CONTENT;
  814. srPhoneNumType[ulCounter].res.resContent.ulFuzzyLevel = FL_SUBSTRING; //Fuzzy level
  815. srPhoneNumType[ulCounter].res.resContent.ulPropTag = WABPHONEPROPLIST[ulCounter];
  816. srPhoneNumType[ulCounter].res.resContent.lpProp = &(spvPhoneNumType[ulCounter]);
  817. }
  818. //Set the restriction
  819. if (hRes = lpMapiTable->lpVtbl->Restrict(lpMapiTable, &srOr, 0)) {
  820. DebugTrace("Restrict -> %x\n", GetScode(hRes));
  821. }
  822. DebugMapiTable(lpMapiTable);
  823. //Did any match?
  824. hRes = lpMapiTable->lpVtbl->GetRowCount(lpMapiTable, 0, &ulRowCount);
  825. if (FAILED(hRes) || (!ulRowCount)) {
  826. goto WABNTN_Exit;
  827. }
  828. //Get the name of the first match
  829. for (ulCounter = 0; ulCounter < ulRowCount; ulCounter++) {
  830. //Found at least one row
  831. hRes = lpMapiTable->lpVtbl->QueryRows(lpMapiTable, 1, // one row at a time
  832. 0, // ulFlags
  833. &lpRow);
  834. if (FAILED(hRes) || (!lpRow->cRows)) {
  835. goto WABNTN_Exit;
  836. }
  837. //Get the Dispay Name Data
  838. lpPropValue = lpRow->aRow[0].lpProps;
  839. for(cColumn = 0; cColumn < lpRow->aRow[0].cValues; cColumn++) {
  840. if (lpPropValue->ulPropTag == PR_DISPLAY_NAME) {
  841. bFound = TRUE;
  842. break;
  843. }
  844. lpPropValue++;
  845. } // cColumn loop
  846. if (lpRow) {
  847. WABFreeBuffer(lpRow); lpRow = NULL;
  848. }
  849. if (bFound) {
  850. break;
  851. }
  852. } //ulCounter loop
  853. WABNTN_Exit:
  854. if (lpMapiTable) {
  855. lpMapiTable->lpVtbl->Release(lpMapiTable);
  856. }
  857. if (lpContainer) {
  858. lpContainer->lpVtbl->Release(lpContainer);
  859. }
  860. if (lpEntryID) {
  861. WABFreeBuffer(lpEntryID);
  862. }
  863. return(hRes);
  864. }
  865. #endif
  866. void GetSearchPathTest(void)
  867. {
  868. HRESULT hResult = hrSuccess;
  869. LPWABOBJECT lpWABObject = NULL;
  870. LPADRBOOK lpAdrBook = NULL;
  871. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  872. SetGlobalBufferFunctions(lpWABObject);
  873. if (lpAdrBook)
  874. {
  875. ULONG i = 0, j=0;
  876. LPTSTR lpsz = NULL;
  877. LPSRowSet lpsrs = NULL;
  878. hResult = lpAdrBook->lpVtbl->GetSearchPath( lpAdrBook,
  879. 0,
  880. &lpsrs);
  881. if(lpsrs && lpsrs->cRows)
  882. {
  883. ULONG nLen = 0;
  884. for(i=0;i<lpsrs->cRows;i++)
  885. {
  886. for(j=0;j<lpsrs->aRow[i].cValues;j++)
  887. {
  888. if(lpsrs->aRow[i].lpProps[j].ulPropTag == PR_DISPLAY_NAME)
  889. {
  890. nLen += lstrlen(lpsrs->aRow[i].lpProps[j].Value.LPSZ) + lstrlen("\r\n") + 1;
  891. break;
  892. }
  893. }
  894. }
  895. lpsz = LocalAlloc(LMEM_ZEROINIT, nLen);
  896. if(lpsz)
  897. {
  898. *lpsz = '\0';
  899. for(i=0;i<lpsrs->cRows;i++)
  900. {
  901. for(j=0;j<lpsrs->aRow[i].cValues;j++)
  902. {
  903. if(lpsrs->aRow[i].lpProps[j].ulPropTag == PR_DISPLAY_NAME)
  904. {
  905. lstrcat(lpsz,lpsrs->aRow[i].lpProps[j].Value.LPSZ);
  906. lstrcat(lpsz,"\r\n");
  907. break;
  908. }
  909. }
  910. }
  911. MessageBox(NULL, lpsz, "List of ResolveName containers", MB_OK);
  912. }
  913. if(lpsz)
  914. LocalFree(lpsz);
  915. for(i=0;i<lpsrs->cRows;i++)
  916. WABFreeBuffer(lpsrs->aRow[i].lpProps);
  917. WABFreeBuffer(lpsrs);
  918. }
  919. lpAdrBook->lpVtbl->Release(lpAdrBook);
  920. }
  921. if (lpWABObject)
  922. {
  923. lpWABObject->lpVtbl->Release(lpWABObject);
  924. }
  925. }
  926. void GetContentsTableTest(void) {
  927. HRESULT hResult = hrSuccess;
  928. LPWABOBJECT lpWABObject = NULL;
  929. LPADRBOOK lpAdrBook = NULL;
  930. LPABCONT lpContainer = NULL;
  931. LPMAPITABLE lpContentsTable = NULL;
  932. ULONG ulObjType;
  933. SCODE sc = SUCCESS_SUCCESS;
  934. ULONG cbWABEID;
  935. LPENTRYID lpWABEID = NULL;
  936. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  937. SetGlobalBufferFunctions(lpWABObject);
  938. if (lpAdrBook) {
  939. #ifdef PHONE_STUFF
  940. WABNumberToName(lpAdrBook, "869-8347");
  941. #endif
  942. if (! (hResult = GetContainerEID(lpAdrBook, &cbWABEID, &lpWABEID))) {
  943. if (! (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  944. cbWABEID, // size of EntryID to open
  945. lpWABEID, // EntryID to open
  946. NULL, // interface
  947. 0, // flags
  948. &ulObjType, (LPUNKNOWN *)&lpContainer))) {
  949. // Opened PAB container OK
  950. // Call GetContentsTable on it.
  951. if (! (hResult = lpContainer->lpVtbl->GetContentsTable(lpContainer,
  952. 0, // ulFlags
  953. &lpContentsTable))) {
  954. SRestriction res;
  955. SPropValue propRestrict;
  956. SizedSSortOrderSet(1, sos) = {
  957. 1,
  958. 0,
  959. 0,
  960. {
  961. PR_DISPLAY_NAME,
  962. TABLE_SORT_DESCEND
  963. }
  964. };
  965. res.rt = RES_PROPERTY;
  966. res.res.resProperty.relop = RELOP_EQ;
  967. res.res.resProperty.ulPropTag = PR_OBJECT_TYPE;
  968. res.res.resProperty.lpProp = &propRestrict;
  969. propRestrict.ulPropTag = PR_OBJECT_TYPE;
  970. propRestrict.Value.ul = MAPI_DISTLIST; // MAPI_MAILUSER for Contact
  971. hResult = lpContentsTable->lpVtbl->Restrict(lpContentsTable, &res, 0);
  972. lpContentsTable->lpVtbl->SetColumns(lpContentsTable,
  973. (LPSPropTagArray)&ipta, 0);
  974. DebugMapiTable(lpContentsTable);
  975. hResult = lpContentsTable->lpVtbl->SortTable(lpContentsTable,
  976. (LPSSortOrderSet)&sos, 0);
  977. // RestrictToContactAndCheck(lpContentsTable);
  978. DebugMapiTable(lpContentsTable);
  979. lpContentsTable->lpVtbl->Release(lpContentsTable);
  980. }
  981. lpContainer->lpVtbl->Release(lpContainer);
  982. }
  983. WABFreeBuffer(lpWABEID);
  984. }
  985. lpAdrBook->lpVtbl->Release(lpAdrBook);
  986. }
  987. if (lpWABObject) {
  988. lpWABObject->lpVtbl->Release(lpWABObject);
  989. }
  990. }
  991. extern LPALLOCATEBUFFER lpfnMAPIAllocateBuffer;
  992. extern LPALLOCATEMORE lpfnMAPIAllocateMore;
  993. extern LPFREEBUFFER lpfnMAPIFreeBuffer;
  994. extern HRESULT MAPIInitialize(LPVOID lpMapiInit);
  995. void WABOpenTest(void) {
  996. LPWABOBJECT lpWABObject1 = NULL, lpWABObject2 = NULL;
  997. LPADRBOOK lpAdrBook1 = NULL, lpAdrBook2 = NULL;
  998. LPABCONT lpContainer = NULL;
  999. HRESULT hResult = hrSuccess;
  1000. LPTSTR lpBuffer1 = NULL;
  1001. LPTSTR lpBuffer2 = NULL;
  1002. ULONG ulObjType;
  1003. ULONG cbWABEID;
  1004. LPENTRYID lpWABEID = NULL;
  1005. hResult = WABOpen(&lpAdrBook1, &lpWABObject1, NULL, 0);
  1006. SetGlobalBufferFunctions(lpWABObject1);
  1007. if (!hResult) {
  1008. if (! (hResult = WABOpen(&lpAdrBook2, &lpWABObject2, NULL, 0))) {
  1009. lpWABObject2->lpVtbl->Release(lpWABObject2);
  1010. lpAdrBook2->lpVtbl->Release(lpAdrBook2);
  1011. lpAdrBook2 = NULL;
  1012. }
  1013. }
  1014. if (lpAdrBook1) {
  1015. if (! (hResult = GetContainerEID(lpAdrBook1, &cbWABEID, &lpWABEID))) {
  1016. if (! (hResult = lpAdrBook1->lpVtbl->OpenEntry(lpAdrBook1,
  1017. cbWABEID, // size of EntryID to open
  1018. lpWABEID, // EntryID to open
  1019. NULL, // interface
  1020. 0, // flags
  1021. &ulObjType, (LPUNKNOWN *)&lpContainer))) {
  1022. // Opened container OK
  1023. lpContainer->lpVtbl->Release(lpContainer);
  1024. }
  1025. WABFreeBuffer(lpWABEID);
  1026. }
  1027. lpAdrBook1->lpVtbl->Release(lpAdrBook1);
  1028. lpAdrBook1 = NULL;
  1029. }
  1030. if (lpWABObject1) {
  1031. lpWABObject1->lpVtbl->AllocateBuffer(lpWABObject1, 1234, &lpBuffer1);
  1032. lpWABObject1->lpVtbl->AllocateMore(lpWABObject1, 4321, lpBuffer1, &lpBuffer2);
  1033. lpWABObject1->lpVtbl->FreeBuffer(lpWABObject1, lpBuffer1);
  1034. lpWABObject1->lpVtbl->Release(lpWABObject1);
  1035. lpWABObject1 = NULL;
  1036. }
  1037. // Try WABOpenEx
  1038. MAPIInitialize(NULL);
  1039. WABOpenEx(&lpAdrBook1, &lpWABObject1, NULL, 0,
  1040. lpfnMAPIAllocateBuffer,
  1041. lpfnMAPIAllocateMore,
  1042. lpfnMAPIFreeBuffer);
  1043. SetGlobalBufferFunctions(lpWABObject1);
  1044. if (lpAdrBook1) {
  1045. if (! (hResult = GetContainerEID(lpAdrBook1, &cbWABEID, &lpWABEID))) {
  1046. if (! (hResult = lpAdrBook1->lpVtbl->OpenEntry(lpAdrBook1,
  1047. cbWABEID, // size of EntryID to open
  1048. lpWABEID, // EntryID to open
  1049. NULL, // interface
  1050. 0, // flags
  1051. &ulObjType, (LPUNKNOWN *)&lpContainer))) {
  1052. // Opened container OK
  1053. LPMAPITABLE lpContentsTable = NULL;
  1054. if (! (hResult = lpContainer->lpVtbl->GetContentsTable(lpContainer,
  1055. 0, // ulFlags
  1056. &lpContentsTable))) {
  1057. SRestriction res;
  1058. SPropValue propRestrict;
  1059. SizedSSortOrderSet(1, sos) = {
  1060. 1,
  1061. 0,
  1062. 0,
  1063. {
  1064. PR_DISPLAY_NAME,
  1065. TABLE_SORT_DESCEND
  1066. }
  1067. };
  1068. res.rt = RES_PROPERTY;
  1069. res.res.resProperty.relop = RELOP_EQ;
  1070. res.res.resProperty.ulPropTag = PR_OBJECT_TYPE;
  1071. res.res.resProperty.lpProp = &propRestrict;
  1072. propRestrict.ulPropTag = PR_OBJECT_TYPE;
  1073. propRestrict.Value.ul = MAPI_DISTLIST; // MAPI_MAILUSER for Contact
  1074. hResult = lpContentsTable->lpVtbl->Restrict(lpContentsTable, &res, 0);
  1075. lpContentsTable->lpVtbl->SetColumns(lpContentsTable,
  1076. (LPSPropTagArray)&ipta, 0);
  1077. DebugMapiTable(lpContentsTable);
  1078. hResult = lpContentsTable->lpVtbl->SortTable(lpContentsTable,
  1079. (LPSSortOrderSet)&sos, 0);
  1080. // RestrictToContactAndCheck(lpContentsTable);
  1081. DebugMapiTable(lpContentsTable);
  1082. lpContentsTable->lpVtbl->Release(lpContentsTable);
  1083. }
  1084. lpContainer->lpVtbl->Release(lpContainer);
  1085. }
  1086. WABFreeBuffer(lpWABEID);
  1087. }
  1088. lpAdrBook1->lpVtbl->Release(lpAdrBook1);
  1089. lpAdrBook1 = NULL;
  1090. }
  1091. if (lpWABObject1) {
  1092. lpWABObject1->lpVtbl->AllocateBuffer(lpWABObject1, 1234, &lpBuffer1);
  1093. lpWABObject1->lpVtbl->AllocateMore(lpWABObject1, 4321, lpBuffer1, &lpBuffer2);
  1094. lpWABObject1->lpVtbl->FreeBuffer(lpWABObject1, lpBuffer1);
  1095. lpWABObject1->lpVtbl->Release(lpWABObject1);
  1096. lpWABObject1 = NULL;
  1097. }
  1098. }
  1099. //
  1100. // BUGBUG: Notifications are NOT YET IMPLEMENTED in WAB!
  1101. //
  1102. #undef INTERFACE
  1103. #define INTERFACE struct _ADVS
  1104. #undef MAPIMETHOD_
  1105. #define MAPIMETHOD_(type, method) MAPIMETHOD_DECLARE(type, method, ADVS_)
  1106. MAPI_IUNKNOWN_METHODS(IMPL)
  1107. MAPI_IMAPIADVISESINK_METHODS(IMPL)
  1108. #undef MAPIMETHOD_
  1109. #define MAPIMETHOD_(type, method) STDMETHOD_(type, method)
  1110. DECLARE_MAPI_INTERFACE(ADVS_)
  1111. {
  1112. BEGIN_INTERFACE
  1113. MAPI_IUNKNOWN_METHODS(IMPL)
  1114. MAPI_IMAPIADVISESINK_METHODS(IMPL)
  1115. };
  1116. typedef struct _ADVS FAR *LPADVS;
  1117. typedef struct _ADVS
  1118. {
  1119. ADVS_Vtbl * lpVtbl;
  1120. UINT cRef;
  1121. LPMALLOC pmalloc;
  1122. LPVOID lpvContext;
  1123. LPNOTIFCALLBACK lpfnCallback;
  1124. } ADVS;
  1125. ADVS_Vtbl vtblADVS =
  1126. {
  1127. ADVS_QueryInterface,
  1128. ADVS_AddRef,
  1129. ADVS_Release,
  1130. ADVS_OnNotify
  1131. };
  1132. STDMETHODIMP
  1133. ADVS_QueryInterface(LPADVS padvs, REFIID lpiid, LPVOID *ppvObj)
  1134. {
  1135. HRESULT hr;
  1136. if (IsEqualMAPIUID((LPMAPIUID)lpiid, (LPMAPIUID)&IID_IUnknown) ||
  1137. IsEqualMAPIUID((LPMAPIUID)lpiid, (LPMAPIUID)&IID_IMAPIAdviseSink))
  1138. {
  1139. ++padvs->cRef;
  1140. *ppvObj = padvs;
  1141. hr = hrSuccess;
  1142. } else {
  1143. *ppvObj = NULL;
  1144. hr = ResultFromScode(E_NOINTERFACE);
  1145. }
  1146. return hr;
  1147. }
  1148. STDMETHODIMP_(ULONG)
  1149. ADVS_AddRef(LPADVS padvs)
  1150. {
  1151. return((ULONG)(++padvs->cRef));
  1152. }
  1153. STDMETHODIMP_(ULONG)
  1154. ADVS_Release(LPADVS padvs)
  1155. {
  1156. if (--(padvs->cRef) == 0)
  1157. {
  1158. WABFreeBuffer(padvs);
  1159. return 0L;
  1160. }
  1161. return (ULONG)padvs->cRef;
  1162. }
  1163. STDMETHODIMP_(ULONG)
  1164. ADVS_OnNotify(LPADVS padvs, ULONG cNotif, LPNOTIFICATION lpNotif)
  1165. {
  1166. return (*(padvs->lpfnCallback))(padvs->lpvContext, cNotif, lpNotif);
  1167. }
  1168. void NotificationsTest(HWND hwnd) {
  1169. LPWABOBJECT lpWABObject = NULL;
  1170. LPADRBOOK lpAdrBook = NULL;
  1171. LPABCONT lpContainer = NULL;
  1172. HRESULT hResult = hrSuccess;
  1173. ULONG ulObjType;
  1174. ULONG cbWABEID;
  1175. LPENTRYID lpWABEID = NULL;
  1176. ULONG ulConnection = 0;
  1177. LPMAPIADVISESINK lpAdvs = NULL;
  1178. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  1179. SetGlobalBufferFunctions(lpWABObject);
  1180. if (lpAdrBook) {
  1181. if (! (hResult = GetContainerEID(lpAdrBook, &cbWABEID, &lpWABEID))) {
  1182. if (! (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  1183. cbWABEID, // size of EntryID to open
  1184. lpWABEID, // EntryID to open
  1185. NULL, // interface
  1186. 0, // flags
  1187. &ulObjType, (LPUNKNOWN *)&lpContainer))) {
  1188. // Opened container OK
  1189. // Create the Advise Sink Object
  1190. WABAllocateBuffer(sizeof(ADVS), &lpAdvs);
  1191. ZeroMemory(lpAdvs, sizeof(ADVS));
  1192. lpAdvs->lpVtbl = (struct IMAPIAdviseSinkVtbl *)&vtblADVS;
  1193. lpAdvs->lpVtbl->AddRef(lpAdvs);
  1194. // Call Advise on address book object
  1195. if (! (hResult = lpAdrBook->lpVtbl->Advise(lpAdrBook,
  1196. cbWABEID,
  1197. lpWABEID,
  1198. fnevObjectCreated | fnevObjectDeleted | fnevObjectModified,
  1199. lpAdvs,
  1200. &ulConnection))) {
  1201. // Advise succeeded.
  1202. // Do something to fire a notification
  1203. WABAddressTest(hwnd, ADDRESS_CONTENTS_BROWSE_MODAL, 0);
  1204. if (! (hResult = lpAdrBook->lpVtbl->Unadvise(lpAdrBook,
  1205. ulConnection))) {
  1206. }
  1207. }
  1208. lpAdvs->lpVtbl->Release(lpAdvs);
  1209. lpContainer->lpVtbl->Release(lpContainer);
  1210. }
  1211. WABFreeBuffer(lpWABEID);
  1212. }
  1213. lpAdrBook->lpVtbl->Release(lpAdrBook);
  1214. }
  1215. if (lpWABObject) {
  1216. lpWABObject->lpVtbl->Release(lpWABObject);
  1217. }
  1218. }
  1219. void ResolveNamesTest(HWND hwnd) {
  1220. #define MAX_INPUT_STRING 200
  1221. TCHAR lpszInput[MAX_INPUT_STRING + 1] = "";
  1222. LPADRLIST lpAdrList = NULL;
  1223. ULONG rgFlagList[2];
  1224. LPFlagList lpFlagList = (LPFlagList)rgFlagList;
  1225. HRESULT hResult = hrSuccess;
  1226. LPWABOBJECT lpWABObject = NULL;
  1227. LPADRBOOK lpAdrBook = NULL;
  1228. LPABCONT lpContainer = NULL;
  1229. ULONG ulObjType;
  1230. SCODE sc = SUCCESS_SUCCESS;
  1231. ULONG cbWABEID;
  1232. LPENTRYID lpWABEID = NULL;
  1233. if (InputString(hInst, hwnd, szAppName, "Resolve Name", lpszInput, MAX_INPUT_STRING)) {
  1234. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  1235. SetGlobalBufferFunctions(lpWABObject);
  1236. if (lpAdrBook) {
  1237. if (! (hResult = GetContainerEID(lpAdrBook, &cbWABEID, &lpWABEID))) {
  1238. if (! (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  1239. cbWABEID, // size of EntryID to open
  1240. lpWABEID, // EntryID to open
  1241. NULL, // interface
  1242. 0, // flags
  1243. &ulObjType, (LPUNKNOWN *)&lpContainer))) {
  1244. // Opened container OK
  1245. // Call ResolveNames on it.
  1246. if (! (sc = WABAllocateBuffer(sizeof(ADRLIST) + sizeof(ADRENTRY), &lpAdrList))) {
  1247. lpAdrList->cEntries = 1;
  1248. lpAdrList->aEntries[0].ulReserved1 = 0;
  1249. lpAdrList->aEntries[0].cValues = 1;
  1250. if (! (sc = WABAllocateBuffer(sizeof(SPropValue), &lpAdrList->aEntries[0].rgPropVals))) {
  1251. lpAdrList->aEntries[0].rgPropVals[0].ulPropTag = PR_DISPLAY_NAME;
  1252. lpAdrList->aEntries[0].rgPropVals[0].Value.LPSZ = lpszInput;
  1253. lpFlagList->cFlags = 1;
  1254. lpFlagList->ulFlag[0] = MAPI_UNRESOLVED;
  1255. if (! (hResult = lpContainer->lpVtbl->ResolveNames(lpContainer,
  1256. NULL, // tag set
  1257. 0, // ulFlags
  1258. lpAdrList,
  1259. lpFlagList))) {
  1260. DebugADRLIST(lpAdrList, "Resolved ADRLIST");
  1261. }
  1262. }
  1263. WABFreePadrlist(lpAdrList);
  1264. }
  1265. lpContainer->lpVtbl->Release(lpContainer);
  1266. }
  1267. WABFreeBuffer(lpWABEID);
  1268. }
  1269. lpAdrBook->lpVtbl->Release(lpAdrBook);
  1270. }
  1271. if (lpWABObject) {
  1272. lpWABObject->lpVtbl->Release(lpWABObject);
  1273. }
  1274. }
  1275. }
  1276. // enum for setting the created properties
  1277. enum {
  1278. irnPR_DISPLAY_NAME = 0,
  1279. irnPR_RECIPIENT_TYPE,
  1280. irnPR_ENTRYID,
  1281. irnPR_EMAIL_ADDRESS,
  1282. irnMax
  1283. };
  1284. void ResolveNameTest(HWND hwnd) {
  1285. TCHAR lpszInput1[MAX_INPUT_STRING + 1] = "";
  1286. TCHAR lpszInput2[MAX_INPUT_STRING + 1] = "";
  1287. LPADRLIST lpAdrList = NULL;
  1288. HRESULT hResult = hrSuccess;
  1289. LPWABOBJECT lpWABObject = NULL;
  1290. LPADRBOOK lpAdrBook = NULL;
  1291. SCODE sc = SUCCESS_SUCCESS;
  1292. ULONG ulObjectType;
  1293. LPMAILUSER lpMailUser = NULL;
  1294. ULONG i = 0;
  1295. if (InputString(hInst, hwnd, szAppName, "Resolve Name", lpszInput1, MAX_INPUT_STRING)) {
  1296. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  1297. SetGlobalBufferFunctions(lpWABObject);
  1298. if (lpAdrBook) {
  1299. if (! (sc = WABAllocateBuffer(sizeof(ADRLIST) + 5 * sizeof(ADRENTRY), &lpAdrList))) {
  1300. lpAdrList->cEntries = 5;
  1301. for (i = 0; i < lpAdrList->cEntries; i++) {
  1302. lpAdrList->aEntries[i].cValues = 0;
  1303. lpAdrList->aEntries[i].rgPropVals = NULL;
  1304. }
  1305. lpAdrList->aEntries[0].ulReserved1 = 0;
  1306. lpAdrList->aEntries[0].cValues = irnMax - 1; // No PR_EMAIL_ADDRESS;
  1307. if (! (sc = WABAllocateBuffer(lpAdrList->aEntries[0].cValues * sizeof(SPropValue),
  1308. &lpAdrList->aEntries[0].rgPropVals))) {
  1309. lpAdrList->aEntries[0].rgPropVals[irnPR_DISPLAY_NAME].ulPropTag = PR_DISPLAY_NAME;
  1310. lpAdrList->aEntries[0].rgPropVals[irnPR_DISPLAY_NAME].Value.LPSZ = lpszInput1;
  1311. lpAdrList->aEntries[0].rgPropVals[irnPR_RECIPIENT_TYPE].ulPropTag = PR_RECIPIENT_TYPE;
  1312. lpAdrList->aEntries[0].rgPropVals[irnPR_RECIPIENT_TYPE].Value.l = MAPI_TO;
  1313. lpAdrList->aEntries[0].rgPropVals[irnPR_ENTRYID].ulPropTag = PR_ENTRYID;
  1314. lpAdrList->aEntries[0].rgPropVals[irnPR_ENTRYID].Value.bin.cb = 0;
  1315. lpAdrList->aEntries[0].rgPropVals[irnPR_ENTRYID].Value.bin.lpb = NULL;
  1316. hResult = lpAdrBook->lpVtbl->ResolveName(lpAdrBook,
  1317. (ULONG)hwnd, // ulUIParam
  1318. MAPI_DIALOG, // ulFlags
  1319. "APITest ResolveName", // lpszNewEntryTitle
  1320. lpAdrList);
  1321. DebugTrace("ResolveName [%s] -> %x\n", lpszInput1, GetScode(hResult));
  1322. if (! HR_FAILED(hResult)) {
  1323. // Open the entry and dump it's properties
  1324. // Should have PR_ENTRYID in rgPropVals[2]
  1325. if (lpAdrList->aEntries[0].rgPropVals[2].ulPropTag == PR_ENTRYID) {
  1326. if (! (HR_FAILED(hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  1327. lpAdrList->aEntries[0].rgPropVals[2].Value.bin.cb,
  1328. (LPENTRYID)lpAdrList->aEntries[0].rgPropVals[2].Value.bin.lpb,
  1329. NULL,
  1330. 0,
  1331. &ulObjectType,
  1332. (LPUNKNOWN *)&(lpMailUser))))) {
  1333. DebugObjectProps((LPMAPIPROP)lpMailUser, "Resolved Entry Properties");
  1334. lpMailUser->lpVtbl->Release(lpMailUser);
  1335. }
  1336. } else {
  1337. DebugTrace("Hey! What happened to my PR_ENTRYID?\n");
  1338. }
  1339. }
  1340. }
  1341. }
  1342. WABFreePadrlist(lpAdrList);
  1343. lpAdrBook->lpVtbl->Release(lpAdrBook);
  1344. }
  1345. if (lpWABObject) {
  1346. lpWABObject->lpVtbl->Release(lpWABObject);
  1347. }
  1348. }
  1349. }
  1350. // enum for getting the entryid of an entry
  1351. enum {
  1352. ieidPR_DISPLAY_NAME = 0,
  1353. ieidPR_ENTRYID,
  1354. ieidMax
  1355. };
  1356. static const SizedSPropTagArray(ieidMax, ptaEid)=
  1357. {
  1358. ieidMax,
  1359. {
  1360. PR_DISPLAY_NAME,
  1361. PR_ENTRYID,
  1362. }
  1363. };
  1364. enum {
  1365. iconPR_DEF_CREATE_MAILUSER = 0,
  1366. iconPR_DEF_CREATE_DL,
  1367. iconMax
  1368. };
  1369. static const SizedSPropTagArray(iconMax, ptaCon)=
  1370. {
  1371. iconMax,
  1372. {
  1373. PR_DEF_CREATE_MAILUSER,
  1374. PR_DEF_CREATE_DL,
  1375. }
  1376. };
  1377. void DeleteEntriesTest(HWND hwnd) {
  1378. TCHAR lpszInput[MAX_INPUT_STRING + 1] = "";
  1379. LPADRLIST lpAdrList = NULL;
  1380. ULONG rgFlagList[2];
  1381. LPFlagList lpFlagList = (LPFlagList)rgFlagList;
  1382. HRESULT hResult = hrSuccess;
  1383. LPWABOBJECT lpWABObject = NULL;
  1384. LPADRBOOK lpAdrBook = NULL;
  1385. LPABCONT lpContainer = NULL;
  1386. ULONG ulObjType;
  1387. SCODE sc = SUCCESS_SUCCESS;
  1388. ULONG cbWABEID;
  1389. LPENTRYID lpWABEID = NULL;
  1390. ENTRYLIST EntryList;
  1391. if (InputString(hInst, hwnd, szAppName, "Resolve Name", lpszInput, MAX_INPUT_STRING)) {
  1392. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  1393. SetGlobalBufferFunctions(lpWABObject);
  1394. if (lpAdrBook) {
  1395. if (! (hResult = GetContainerEID(lpAdrBook, &cbWABEID, &lpWABEID))) {
  1396. if (! (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  1397. cbWABEID, // size of EntryID to open
  1398. lpWABEID, // EntryID to open
  1399. NULL, // interface
  1400. 0, // flags
  1401. &ulObjType, (LPUNKNOWN *)&lpContainer))) {
  1402. // Opened container OK
  1403. // Call ResolveNames on it.
  1404. if (! (sc = WABAllocateBuffer(sizeof(ADRLIST) + sizeof(ADRENTRY), &lpAdrList))) {
  1405. lpAdrList->cEntries = 1;
  1406. lpAdrList->aEntries[0].ulReserved1 = 0;
  1407. lpAdrList->aEntries[0].cValues = 1;
  1408. if (! (sc = WABAllocateBuffer(ieidMax * sizeof(SPropValue),
  1409. &lpAdrList->aEntries[0].rgPropVals))) {
  1410. lpAdrList->aEntries[0].rgPropVals[ieidPR_DISPLAY_NAME].ulPropTag = PR_DISPLAY_NAME;
  1411. lpAdrList->aEntries[0].rgPropVals[ieidPR_DISPLAY_NAME].Value.LPSZ = lpszInput;
  1412. lpAdrList->aEntries[0].rgPropVals[ieidPR_ENTRYID].ulPropTag = PR_ENTRYID;
  1413. lpAdrList->aEntries[0].rgPropVals[ieidPR_ENTRYID].Value.bin.cb = 0;
  1414. lpAdrList->aEntries[0].rgPropVals[ieidPR_ENTRYID].Value.bin.lpb = NULL;
  1415. lpFlagList->cFlags = 1;
  1416. lpFlagList->ulFlag[0] = MAPI_UNRESOLVED;
  1417. lpContainer->lpVtbl->ResolveNames(lpContainer,
  1418. (LPSPropTagArray)&ptaEid, // tag set
  1419. 0, // ulFlags
  1420. lpAdrList,
  1421. lpFlagList);
  1422. if (lpFlagList->ulFlag[0] != MAPI_RESOLVED) {
  1423. DebugTrace("Couldn't resolve name %s\n", lpszInput);
  1424. } else {
  1425. // Create a list of entryid's to delete
  1426. EntryList.cValues = 1;
  1427. EntryList.lpbin = &(lpAdrList->aEntries[0].rgPropVals[ieidPR_ENTRYID].Value.bin);
  1428. // Now, delete the entry found.
  1429. if (hResult = lpContainer->lpVtbl->DeleteEntries(lpContainer,
  1430. &EntryList,
  1431. 0)) {
  1432. DebugTrace("DeleteEntries -> %x", hResult);
  1433. }
  1434. }
  1435. }
  1436. WABFreePadrlist(lpAdrList);
  1437. }
  1438. lpContainer->lpVtbl->Release(lpContainer);
  1439. }
  1440. WABFreeBuffer(lpWABEID);
  1441. }
  1442. lpAdrBook->lpVtbl->Release(lpAdrBook);
  1443. }
  1444. if (lpWABObject) {
  1445. lpWABObject->lpVtbl->Release(lpWABObject);
  1446. }
  1447. }
  1448. }
  1449. void TestNamedProps(LPMAILUSER lpEntry) {
  1450. MAPINAMEID mnidT1;
  1451. LPMAPINAMEID lpmnidT1;
  1452. HRESULT hr;
  1453. GUID guidT1 = { /* 13fbb976-15a2-11d0-9b9f-00c04fd90294 */
  1454. 0x13fbb976,
  1455. 0x15a2,
  1456. 0x11d0,
  1457. {0x9b, 0x9f, 0x00, 0xc0, 0x4f, 0xd9, 0x02, 0x94}
  1458. };
  1459. LPSPropTagArray lptaga = NULL;
  1460. SPropValue spv;
  1461. MAPINAMEID mnidT2;
  1462. LPMAPINAMEID lpmnidT2;
  1463. GUID guidT2 = { /* 39f110d8-15a2-11d0-9b9f-00c04fd90294 */
  1464. 0x39f110d8,
  1465. 0x15a2,
  1466. 0x11d0,
  1467. {0x9b, 0x9f, 0x00, 0xc0, 0x4f, 0xd9, 0x02, 0x94}
  1468. };
  1469. //
  1470. // We just made up that GUID. On NT try uuidgen -s to get your own
  1471. //
  1472. mnidT1.lpguid = &guidT1;
  1473. mnidT1.ulKind = MNID_ID; // This means union will contain a long...
  1474. mnidT1.Kind.lID = 0x00000001; // numeric property 1
  1475. lpmnidT1 = &mnidT1;
  1476. hr = lpEntry->lpVtbl->GetIDsFromNames(lpEntry,
  1477. 1, // Just one name
  1478. &lpmnidT1, // &-of because this is an array
  1479. MAPI_CREATE, // This is where MAPI_CREATE might go
  1480. &lptaga);
  1481. if (hr) {
  1482. //
  1483. // I'd really be suprised if I got S_OK for this...
  1484. //
  1485. if (GetScode(hr) != MAPI_W_ERRORS_RETURNED) {
  1486. // Real error here
  1487. goto out;
  1488. }
  1489. // Basically, this means you don't have anything by this name and you
  1490. // didn't ask the object to create it.
  1491. //$ no biggie
  1492. }
  1493. // Free the lptaga, as it was allocated by the object and returned to the calling
  1494. // app.
  1495. WABFreeBuffer(lptaga);
  1496. //
  1497. // And here's how to successfully add a named property to an object. In this case
  1498. // we'll slap on in and I'll demonstrate how to use this new property.
  1499. //
  1500. //
  1501. // We just made up that GUID. On NT try uuidgen -s to get your own
  1502. //
  1503. mnidT2.lpguid = &guidT2;
  1504. mnidT2.ulKind = MNID_STRING; // This means union will contain a UNICODE string...
  1505. mnidT2.Kind.lpwstrName = L"Check out this cool property!";
  1506. lpmnidT2 = &mnidT2;
  1507. hr = lpEntry->lpVtbl->GetIDsFromNames(lpEntry,
  1508. 1, // Just one name
  1509. &lpmnidT2, // &-of because this is an array
  1510. MAPI_CREATE,
  1511. &lptaga);
  1512. if (hr) {
  1513. //
  1514. // I'd really be suprised if I got S_OK for this...
  1515. //
  1516. if (GetScode(hr) != MAPI_W_ERRORS_RETURNED) {
  1517. // Real error here
  1518. goto out;
  1519. }
  1520. // Basically, this means you don't have anything by this name and you
  1521. // didn't ask the object to create it.
  1522. //$ no biggie
  1523. }
  1524. //
  1525. // Ok, so what can I do with this ptaga? Well, we can set a value for it by doing:
  1526. //
  1527. spv.ulPropTag = CHANGE_PROP_TYPE(lptaga->aulPropTag[0],PT_STRING8);
  1528. spv.Value.lpszA = "This property brought to you by the letter M";
  1529. hr = lpEntry->lpVtbl->SetProps(lpEntry,
  1530. 1,
  1531. &spv,
  1532. NULL);
  1533. if (HR_FAILED(hr)) {
  1534. goto out;
  1535. }
  1536. lpEntry->lpVtbl->SaveChanges(lpEntry, // this
  1537. KEEP_OPEN_READONLY); // ulFlags
  1538. DebugObjectProps((LPMAPIPROP)lpEntry, "");
  1539. lpEntry->lpVtbl->DeleteProps(lpEntry, lptaga, NULL);
  1540. DebugObjectProps((LPMAPIPROP)lpEntry, "");
  1541. // Free the lptaga, as it was allocated by the object and returned to the calling
  1542. // app.
  1543. WABFreeBuffer(lptaga);
  1544. out:
  1545. return;
  1546. }
  1547. void CreateEntryTest(HWND hwnd, BOOL fDL) {
  1548. LPWABOBJECT lpWABObject = NULL;
  1549. LPADRBOOK lpAdrBook = NULL;
  1550. LPABCONT lpContainer = NULL;
  1551. HRESULT hResult = hrSuccess;
  1552. LPTSTR lpBuffer1 = NULL;
  1553. LPTSTR lpBuffer2 = NULL;
  1554. ULONG ulObjType;
  1555. LPMAPIPROP lpMailUser = NULL;
  1556. SPropValue spv[imuMax];
  1557. TCHAR lpszDisplayName[MAX_INPUT_STRING + 1] = "";
  1558. TCHAR lpszEmailName[MAX_INPUT_STRING + 1] = "[email protected]";
  1559. ULONG ulContactNumber;
  1560. ULONG cbWABEID;
  1561. LPENTRYID lpWABEID = NULL;
  1562. LPSPropValue lpCreateEIDs = NULL;
  1563. LPSPropValue lpNewDLProps = NULL;
  1564. ULONG cProps;
  1565. ULONG ulObjectType;
  1566. LPDISTLIST lpDistList = NULL;
  1567. LPBYTE lpBuffer;
  1568. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  1569. SetGlobalBufferFunctions(lpWABObject);
  1570. if (lpAdrBook) {
  1571. if (! (hResult = GetContainerEID(lpAdrBook, &cbWABEID, &lpWABEID))) {
  1572. if (! (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  1573. cbWABEID, // size of EntryID to open
  1574. lpWABEID, // EntryID to open
  1575. NULL, // interface
  1576. 0, // flags
  1577. &ulObjType, (LPUNKNOWN *)&lpContainer))) {
  1578. // Opened PAB container OK
  1579. DebugObjectProps((LPMAPIPROP)lpContainer, "WAB Container");
  1580. ulContactNumber = GetNewMessageReference();
  1581. if (! InputString(hInst, hwnd, szAppName, "Create Entry Name", lpszDisplayName, sizeof(lpszDisplayName))) {
  1582. wsprintf(lpszDisplayName, "Bruce Kelley %05u", ulContactNumber);
  1583. }
  1584. wsprintf(lpszEmailName, "brucek_%[email protected]", ulContactNumber);
  1585. // Get us the creation entryids
  1586. if ((hResult = lpContainer->lpVtbl->GetProps(lpContainer, (LPSPropTagArray)&ptaCon, 0, &cProps, &lpCreateEIDs))) {
  1587. DebugTrace("Can't get container properties for PAB\n");
  1588. // Bad stuff here!
  1589. return;
  1590. }
  1591. // Validate the properites
  1592. if (lpCreateEIDs[iconPR_DEF_CREATE_MAILUSER].ulPropTag != PR_DEF_CREATE_MAILUSER ||
  1593. lpCreateEIDs[iconPR_DEF_CREATE_DL].ulPropTag != PR_DEF_CREATE_DL) {
  1594. DebugTrace("Container property errors\n");
  1595. return;
  1596. }
  1597. if (fDL) {
  1598. LPDISTLIST lpNewObj = NULL;
  1599. // Create the default DL
  1600. if (! (hResult = lpContainer->lpVtbl->CreateEntry(lpContainer,
  1601. lpCreateEIDs[iconPR_DEF_CREATE_DL].Value.bin.cb,
  1602. (LPENTRYID)lpCreateEIDs[iconPR_DEF_CREATE_DL].Value.bin.lpb,
  1603. CREATE_CHECK_DUP_STRICT,
  1604. &lpMailUser))) {
  1605. // Set the display name
  1606. spv[imuPR_DISPLAY_NAME].ulPropTag = PR_DISPLAY_NAME;
  1607. spv[imuPR_DISPLAY_NAME].Value.lpszA = lpszDisplayName;
  1608. if (HR_FAILED(hResult = lpMailUser->lpVtbl->SetProps(lpMailUser, // this
  1609. 1, // cValues
  1610. spv, // property array
  1611. NULL))) { // problems array
  1612. }
  1613. hResult = lpMailUser->lpVtbl->SaveChanges(lpMailUser, // this
  1614. KEEP_OPEN_READONLY); // ulFlags
  1615. DebugObjectProps((LPMAPIPROP)lpMailUser, "New Distribution List");
  1616. lpNewObj = NULL;
  1617. lpMailUser->lpVtbl->QueryInterface(lpMailUser,
  1618. &IID_IDistList,
  1619. &lpNewObj);
  1620. if (lpNewObj) {
  1621. (lpNewObj)->lpVtbl->Release(lpNewObj);
  1622. }
  1623. // Get the EntryID so we can open it...
  1624. if ((hResult = lpMailUser->lpVtbl->GetProps(lpMailUser,
  1625. (LPSPropTagArray)&ptaEid,
  1626. 0,
  1627. &cProps,
  1628. &lpNewDLProps))) {
  1629. DebugTrace("Can't get DL properties\n");
  1630. // Bad stuff here!
  1631. return;
  1632. }
  1633. lpMailUser->lpVtbl->Release(lpMailUser);
  1634. // Now, open the new entry as a DL
  1635. hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  1636. lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb,
  1637. (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,
  1638. (LPIID)&IID_IDistList,
  1639. MAPI_MODIFY,
  1640. &ulObjectType,
  1641. (LPUNKNOWN*)&lpDistList);
  1642. if (lpDistList) {
  1643. ADRPARM AdrParms = {0};
  1644. LPADRLIST lpAdrList = NULL;
  1645. ULONG i;
  1646. LPSBinary lpsbEntryID;
  1647. LPMAPIPROP lpEntry = NULL;
  1648. LPMAPITABLE lpContentsTable = NULL;
  1649. // Do something with the DL object
  1650. // Add an entry to the DL
  1651. // Get entries to add.
  1652. AdrParms.ulFlags = DIALOG_MODAL;
  1653. AdrParms.lpszCaption = "Choose entries for this Distribution List";
  1654. AdrParms.cDestFields = 1;
  1655. hResult = lpAdrBook->lpVtbl->Address(lpAdrBook,
  1656. (LPULONG)&hwnd,
  1657. &AdrParms,
  1658. &lpAdrList);
  1659. if (! hResult && lpAdrList) {
  1660. for (i = 0; i < lpAdrList->cEntries; i++) {
  1661. if (lpsbEntryID = FindAdrEntryID(lpAdrList, i)) {
  1662. if (hResult = lpDistList->lpVtbl->CreateEntry(lpDistList,
  1663. lpsbEntryID->cb,
  1664. (LPENTRYID)lpsbEntryID->lpb,
  1665. CREATE_CHECK_DUP_STRICT,
  1666. &lpEntry)) {
  1667. break;
  1668. }
  1669. hResult = lpEntry->lpVtbl->SaveChanges(lpEntry, FORCE_SAVE);
  1670. if (lpEntry) {
  1671. lpEntry->lpVtbl->Release(lpEntry);
  1672. lpEntry = NULL;
  1673. }
  1674. }
  1675. }
  1676. DebugObjectProps((LPMAPIPROP)lpDistList, "Distribution List");
  1677. // Open the table object on the DL
  1678. if (! (hResult = lpDistList->lpVtbl->GetContentsTable(lpDistList,
  1679. 0,
  1680. &lpContentsTable))) {
  1681. ULONG ulRowCount;
  1682. if (hResult = lpContentsTable->lpVtbl->GetRowCount(lpContentsTable,
  1683. 0,
  1684. &ulRowCount)) {
  1685. DebugTrace("GetRowCount -> %x\n", hResult);
  1686. } else {
  1687. DebugTrace("GetRowCount found %u rows\n", ulRowCount);
  1688. }
  1689. DebugTrace("Distribution list contents:\n");
  1690. DebugMapiTable(lpContentsTable);
  1691. lpContentsTable->lpVtbl->Release(lpContentsTable);
  1692. }
  1693. // Delete the entry from the DL
  1694. {
  1695. ENTRYLIST el;
  1696. el.cValues = 1;
  1697. el.lpbin = lpsbEntryID;
  1698. if (hResult = lpDistList->lpVtbl->DeleteEntries(lpDistList,
  1699. &el,
  1700. 0)) {
  1701. DebugTrace("DISTLIST_DeleteEntries -> %x\n", GetScode(hResult));
  1702. }
  1703. }
  1704. }
  1705. if (lpAdrList) {
  1706. WABFreePadrlist(lpAdrList);
  1707. }
  1708. lpDistList->lpVtbl->Release(lpDistList);
  1709. }
  1710. if (lpNewDLProps) {
  1711. WABFreeBuffer(lpNewDLProps);
  1712. }
  1713. }
  1714. } else {
  1715. if (! (hResult = lpContainer->lpVtbl->CreateEntry(lpContainer,
  1716. lpCreateEIDs[iconPR_DEF_CREATE_MAILUSER].Value.bin.cb,
  1717. (LPENTRYID)lpCreateEIDs[iconPR_DEF_CREATE_MAILUSER].Value.bin.lpb,
  1718. CREATE_CHECK_DUP_STRICT,
  1719. &lpMailUser))) {
  1720. // Successful creation of entry. Do something with it.
  1721. #ifdef OLD_STUFF
  1722. // Try saving with no props. Should fail.
  1723. hResult = lpMailUser->lpVtbl->SaveChanges(lpMailUser, // this
  1724. KEEP_OPEN_READONLY); // ulFlags
  1725. // Try just setting PR_COMPANY_NAME
  1726. spv[0].ulPropTag = PR_COMPANY_NAME;
  1727. spv[0].Value.lpszA = "Somebody's Company";
  1728. if (HR_FAILED(hResult = lpMailUser->lpVtbl->SetProps(lpMailUser, // this
  1729. 1, // cValues
  1730. spv, // property array
  1731. NULL))) { // problems array
  1732. }
  1733. hResult = lpMailUser->lpVtbl->SaveChanges(lpMailUser, // this
  1734. KEEP_OPEN_READONLY); // ulFlags
  1735. DebugObjectProps((LPMAPIPROP)lpMailUser, "New MailUser");
  1736. #endif // OLD_STUFF
  1737. spv[imuPR_EMAIL_ADDRESS].ulPropTag = PR_EMAIL_ADDRESS;
  1738. spv[imuPR_EMAIL_ADDRESS].Value.lpszA = lpszEmailName;
  1739. spv[imuPR_ADDRTYPE].ulPropTag = PR_ADDRTYPE;
  1740. spv[imuPR_ADDRTYPE].Value.lpszA = "SMTP";
  1741. spv[imuPR_DISPLAY_NAME].ulPropTag = PR_DISPLAY_NAME;
  1742. spv[imuPR_DISPLAY_NAME].Value.lpszA = lpszDisplayName;
  1743. spv[imuPR_SURNAME].ulPropTag = PR_NULL;
  1744. spv[imuPR_GIVEN_NAME].ulPropTag = PR_NULL;
  1745. #ifdef OLD_STUFF
  1746. // This case exercises the display name regeneration
  1747. spv[imuPR_DISPLAY_NAME].ulPropTag = PR_DISPLAY_NAME;
  1748. spv[imuPR_DISPLAY_NAME].Value.lpszA = "Stan Freck";
  1749. spv[imuPR_SURNAME].ulPropTag = PR_SURNAME;
  1750. spv[imuPR_SURNAME].Value.lpszA = "Freck";
  1751. spv[imuPR_GIVEN_NAME].ulPropTag = PR_GIVEN_NAME;
  1752. spv[imuPR_GIVEN_NAME].Value.lpszA = "Stanley";
  1753. #endif
  1754. if (HR_FAILED(hResult = lpMailUser->lpVtbl->SetProps(lpMailUser, // this
  1755. imuMax, // cValues
  1756. spv, // property array
  1757. NULL))) { // problems array
  1758. }
  1759. #define ICON_SIZE 100000
  1760. WABAllocateBuffer(ICON_SIZE, &lpBuffer);
  1761. FillMemory(lpBuffer, ICON_SIZE, 'B');
  1762. spv[0].ulPropTag = PR_ICON;
  1763. spv[0].Value.bin.cb = ICON_SIZE;
  1764. spv[0].Value.bin.lpb = lpBuffer;
  1765. if (HR_FAILED(hResult = lpMailUser->lpVtbl->SetProps(lpMailUser, // this
  1766. 1, // cValues
  1767. spv, // property array
  1768. NULL))) { // problems array
  1769. }
  1770. WABFreeBuffer(lpBuffer);
  1771. TestNamedProps((LPMAILUSER)lpMailUser);
  1772. hResult = lpMailUser->lpVtbl->SaveChanges(lpMailUser, // this
  1773. KEEP_OPEN_READONLY); // ulFlags
  1774. DebugObjectProps((LPMAPIPROP)lpMailUser, "New MailUser");
  1775. lpMailUser->lpVtbl->Release(lpMailUser);
  1776. }
  1777. }
  1778. WABFreeBuffer(lpCreateEIDs);
  1779. lpContainer->lpVtbl->Release(lpContainer);
  1780. }
  1781. WABFreeBuffer(lpWABEID);
  1782. }
  1783. lpAdrBook->lpVtbl->Release(lpAdrBook);
  1784. }
  1785. if (lpWABObject) {
  1786. lpWABObject->lpVtbl->Release(lpWABObject);
  1787. }
  1788. }
  1789. void STDMETHODCALLTYPE TestDismissFunction(ULONG ulUIParam, LPVOID lpvContext)
  1790. {
  1791. LPDWORD lpdw = (LPDWORD) lpvContext;
  1792. DebugTrace("TestDismissFunction [5x]:[%d]\n",ulUIParam,*lpdw);
  1793. return;
  1794. }
  1795. DWORD dwContext = 77;
  1796. void WABAddressTest(HWND hWnd, int iFlag, int cDestWells)
  1797. {
  1798. LPWABOBJECT lpWABObject = NULL;
  1799. LPADRBOOK lpAdrBook = NULL;
  1800. LPADRLIST lpAdrList = NULL;
  1801. HRESULT hResult = hrSuccess;
  1802. LPSPropValue rgProps;
  1803. SCODE sc;
  1804. ADRPARM AdrParms = {0};
  1805. ULONG i=0;
  1806. DWORD dwEntryID1=22;
  1807. LPTSTR lpszDestFieldsTitles[]={ TEXT("Title # 1"),
  1808. TEXT("2nd Title"),
  1809. TEXT("Third in line")
  1810. };
  1811. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  1812. SetGlobalBufferFunctions(lpWABObject);
  1813. if (lpAdrBook)
  1814. {
  1815. if(iFlag!=ADDRESS_CONTENTS)
  1816. {
  1817. sc = WABAllocateBuffer(sizeof(ADRLIST)+sizeof(ADRENTRY), &lpAdrList);
  1818. lpAdrList->cEntries = 1;
  1819. lpAdrList->aEntries[0].cValues = 7;
  1820. sc = WABAllocateBuffer(7 * sizeof(SPropValue),&rgProps);
  1821. lpAdrList->aEntries[0].rgPropVals = rgProps;
  1822. lpAdrList->aEntries[0].rgPropVals[0].ulPropTag = PR_DISPLAY_NAME;
  1823. lpAdrList->aEntries[0].rgPropVals[0].Value.LPSZ = TEXT("Charlie Chaplin");
  1824. lpAdrList->aEntries[0].rgPropVals[1].ulPropTag = PR_EMAIL_ADDRESS;
  1825. lpAdrList->aEntries[0].rgPropVals[1].Value.LPSZ = TEXT("[email protected]");
  1826. lpAdrList->aEntries[0].rgPropVals[2].ulPropTag = PR_ADDRTYPE;
  1827. lpAdrList->aEntries[0].rgPropVals[2].Value.LPSZ = TEXT("SMTP");
  1828. lpAdrList->aEntries[0].rgPropVals[3].ulPropTag = PR_SURNAME;
  1829. lpAdrList->aEntries[0].rgPropVals[3].Value.LPSZ = TEXT("Chaplin");
  1830. lpAdrList->aEntries[0].rgPropVals[4].ulPropTag = PR_GIVEN_NAME;
  1831. lpAdrList->aEntries[0].rgPropVals[4].Value.LPSZ = TEXT("Charlie");
  1832. lpAdrList->aEntries[0].rgPropVals[5].ulPropTag = PR_RECIPIENT_TYPE;
  1833. lpAdrList->aEntries[0].rgPropVals[5].Value.l = MAPI_TO;
  1834. lpAdrList->aEntries[0].rgPropVals[6].ulPropTag = PR_ENTRYID;
  1835. dwEntryID1 = 22;
  1836. lpAdrList->aEntries[0].rgPropVals[6].Value.bin.lpb = NULL;
  1837. lpAdrList->aEntries[0].rgPropVals[6].Value.bin.cb = 0;
  1838. }
  1839. switch(iFlag)
  1840. {
  1841. case(ADDRESS_CONTENTS_BROWSE_MODAL):
  1842. AdrParms.cDestFields = 0;
  1843. AdrParms.ulFlags = DIALOG_MODAL;
  1844. break;
  1845. case(ADDRESS_CONTENTS_BROWSE):
  1846. AdrParms.cDestFields = 0;
  1847. AdrParms.ulFlags = DIALOG_SDI;
  1848. AdrParms.lpvDismissContext = &dwContext;
  1849. AdrParms.lpfnDismiss = &TestDismissFunction;
  1850. AdrParms.lpfnABSDI = NULL;
  1851. break;
  1852. case(ADDRESS_CONTENTS):
  1853. AdrParms.cDestFields = 0;
  1854. AdrParms.ulFlags = DIALOG_MODAL | ADDRESS_ONE;
  1855. lpAdrList = NULL;
  1856. break;
  1857. case(ADDRESS_WELLS):
  1858. AdrParms.cDestFields = cDestWells;
  1859. AdrParms.ulFlags = DIALOG_MODAL;
  1860. AdrParms.lppszDestTitles=lpszDestFieldsTitles;
  1861. break;
  1862. case(ADDRESS_WELLS_DEFAULT):
  1863. AdrParms.cDestFields = cDestWells;
  1864. AdrParms.ulFlags = DIALOG_MODAL;
  1865. AdrParms.lppszDestTitles=NULL;
  1866. break;
  1867. }
  1868. AdrParms.lpszCaption = "ApiTest Address Book Test";
  1869. AdrParms.nDestFieldFocus = AdrParms.cDestFields-1;
  1870. hResult = lpAdrBook->lpVtbl->Address( lpAdrBook,
  1871. (ULONG *) &hWnd,
  1872. &AdrParms,
  1873. &lpAdrList);
  1874. if (AdrParms.lpfnABSDI)
  1875. {
  1876. (*(AdrParms.lpfnABSDI))((ULONG) hWnd, (LPVOID) NULL);
  1877. }
  1878. if (lpAdrList)
  1879. {
  1880. for(i=0;i<lpAdrList->aEntries[0].cValues;i++)
  1881. {
  1882. if(lpAdrList->aEntries[0].rgPropVals[i].ulPropTag == PR_ENTRYID)
  1883. {
  1884. lpAdrBook->lpVtbl->Details(lpAdrBook,
  1885. (LPULONG)&hWnd,
  1886. NULL,
  1887. NULL,
  1888. lpAdrList->aEntries[0].rgPropVals[i].Value.bin.cb,
  1889. (LPENTRYID) lpAdrList->aEntries[0].rgPropVals[i].Value.bin.lpb,
  1890. NULL,
  1891. NULL,
  1892. NULL,
  1893. 0);
  1894. }
  1895. }
  1896. WABFreePadrlist(lpAdrList);
  1897. }
  1898. lpAdrBook->lpVtbl->Release(lpAdrBook);
  1899. }
  1900. if (lpWABObject) {
  1901. lpWABObject->lpVtbl->Release(lpWABObject);
  1902. }
  1903. }
  1904. int _stdcall WinMainCRTStartup (void)
  1905. {
  1906. int i;
  1907. STARTUPINFOA si;
  1908. PTSTR pszCmdLine = GetCommandLine();
  1909. SetErrorMode(SEM_FAILCRITICALERRORS);
  1910. if (*pszCmdLine == TEXT ('\"'))
  1911. {
  1912. // Scan, and skip over, subsequent characters until
  1913. // another double-quote or a null is encountered.
  1914. while (*++pszCmdLine && (*pszCmdLine != TEXT ('\"')));
  1915. // If we stopped on a double-quote (usual case), skip over it.
  1916. if (*pszCmdLine == TEXT ('\"')) pszCmdLine++;
  1917. }
  1918. else
  1919. {
  1920. while (*pszCmdLine > TEXT (' ')) pszCmdLine++;
  1921. }
  1922. // Skip past any white space preceeding the second token.
  1923. while (*pszCmdLine && (*pszCmdLine <= TEXT (' '))) pszCmdLine++;
  1924. si.dwFlags = 0;
  1925. GetStartupInfo (&si);
  1926. i = WinMainT(GetModuleHandle (NULL), NULL, pszCmdLine,
  1927. si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
  1928. ExitProcess(i);
  1929. return i;
  1930. }
  1931. void AddrBookDetailsTest(HWND hWnd)
  1932. {
  1933. TCHAR lpszInput[MAX_INPUT_STRING + 1] = "";
  1934. DWORD dwEntryID;
  1935. HRESULT hResult = hrSuccess;
  1936. LPWABOBJECT lpWABObject = NULL;
  1937. LPADRBOOK lpAdrBook = NULL;
  1938. SCODE sc = SUCCESS_SUCCESS;
  1939. LPMAILUSER lpMailUser = NULL;
  1940. int i = 0,nLen=0;
  1941. if (nLen = InputString(hInst, hWnd, szAppName, "Enter EntryID", lpszInput, MAX_INPUT_STRING))
  1942. {
  1943. dwEntryID=0;
  1944. for(i=0;i<nLen;i++)
  1945. {
  1946. char a = lpszInput[i];
  1947. if ((a <= '9') && (a >= '0'))
  1948. dwEntryID = dwEntryID*10 + a - '0';
  1949. }
  1950. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  1951. SetGlobalBufferFunctions(lpWABObject);
  1952. if (lpAdrBook)
  1953. {
  1954. hResult = lpAdrBook->lpVtbl->Details(lpAdrBook,
  1955. (LPULONG) &hWnd, // ulUIParam
  1956. NULL,
  1957. NULL,
  1958. sizeof(DWORD),
  1959. (LPENTRYID) &dwEntryID,
  1960. NULL,
  1961. NULL,
  1962. NULL,
  1963. 0);
  1964. lpAdrBook->lpVtbl->Release(lpAdrBook);
  1965. }
  1966. if (lpWABObject) {
  1967. lpWABObject->lpVtbl->Release(lpWABObject);
  1968. }
  1969. }
  1970. }
  1971. void AddrBookDetailsOneOffTest(HWND hWnd)
  1972. {
  1973. TCHAR lpszInput[MAX_INPUT_STRING + 1] = "";
  1974. HRESULT hResult = hrSuccess;
  1975. LPWABOBJECT lpWABObject = NULL;
  1976. LPADRBOOK lpAdrBook = NULL;
  1977. SCODE sc = SUCCESS_SUCCESS;
  1978. LPMAILUSER lpMailUser = NULL;
  1979. ULONG i = 0,nLen=0;
  1980. LPENTRYID lpEntryID = NULL;
  1981. ULONG cbEntryID = 0;
  1982. ULONG ulObjectType = 0;
  1983. LPADRLIST lpAdrList = NULL;
  1984. if (nLen = InputString(hInst, hWnd, szAppName, "Enter One-Off Address", lpszInput, MAX_INPUT_STRING))
  1985. {
  1986. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  1987. SetGlobalBufferFunctions(lpWABObject);
  1988. if (lpAdrBook)
  1989. {
  1990. // generate a one off entry-id by calling resolvenames on the input one-off address
  1991. if (! (sc = WABAllocateBuffer(sizeof(ADRLIST) + sizeof(ADRENTRY), &lpAdrList)))
  1992. {
  1993. lpAdrList->cEntries = 1;
  1994. lpAdrList->aEntries[0].ulReserved1 = 0;
  1995. lpAdrList->aEntries[0].cValues = 1;
  1996. if (! (sc = WABAllocateBuffer(lpAdrList->aEntries[0].cValues * sizeof(SPropValue),
  1997. &lpAdrList->aEntries[0].rgPropVals)))
  1998. {
  1999. lpAdrList->aEntries[0].rgPropVals[0].ulPropTag = PR_DISPLAY_NAME;
  2000. lpAdrList->aEntries[0].rgPropVals[0].Value.LPSZ = lpszInput;
  2001. hResult = lpAdrBook->lpVtbl->ResolveName(lpAdrBook,
  2002. (ULONG)hWnd, // ulUIParam
  2003. 0, // ulFlags
  2004. "APITest ResolveName", // lpszNewEntryTitle
  2005. lpAdrList);
  2006. DebugTrace("ResolveName [%s] -> %x\n", lpszInput, GetScode(hResult));
  2007. if (! HR_FAILED(hResult))
  2008. {
  2009. // Open the entry and dump it's properties
  2010. for(i=0;i<lpAdrList->aEntries[0].cValues;i++)
  2011. {
  2012. if (lpAdrList->aEntries[0].rgPropVals[i].ulPropTag == PR_ENTRYID)
  2013. {
  2014. cbEntryID = lpAdrList->aEntries[0].rgPropVals[i].Value.bin.cb;
  2015. lpEntryID = (LPENTRYID)lpAdrList->aEntries[0].rgPropVals[i].Value.bin.lpb;
  2016. if (! (HR_FAILED(hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  2017. cbEntryID,
  2018. lpEntryID,
  2019. NULL,
  2020. 0,
  2021. &ulObjectType,
  2022. (LPUNKNOWN *)&(lpMailUser)))))
  2023. {
  2024. DebugObjectProps((LPMAPIPROP)lpMailUser, "Resolved Entry Properties");
  2025. lpMailUser->lpVtbl->Release(lpMailUser);
  2026. }
  2027. hResult = lpAdrBook->lpVtbl->Details(lpAdrBook,
  2028. (LPULONG) &hWnd, // ulUIParam
  2029. NULL,
  2030. NULL,
  2031. cbEntryID,
  2032. lpEntryID,
  2033. NULL,
  2034. NULL,
  2035. NULL,
  2036. 0);
  2037. }
  2038. }
  2039. }
  2040. }
  2041. WABFreePadrlist(lpAdrList);
  2042. }
  2043. lpAdrBook->lpVtbl->Release(lpAdrBook);
  2044. }
  2045. if (lpWABObject)
  2046. {
  2047. lpWABObject->lpVtbl->Release(lpWABObject);
  2048. }
  2049. }
  2050. return;
  2051. }
  2052. //
  2053. // Properties to get for each row of the contents table
  2054. //
  2055. enum {
  2056. iptaColumnsPR_OBJECT_TYPE = 0,
  2057. iptaColumnsPR_ENTRYID,
  2058. iptaColumnsPR_DISPLAY_NAME,
  2059. iptaColumnsMax
  2060. };
  2061. static const SizedSPropTagArray(iptaColumnsMax, ptaColumns) =
  2062. {
  2063. iptaColumnsMax,
  2064. {
  2065. PR_OBJECT_TYPE,
  2066. PR_ENTRYID,
  2067. PR_DISPLAY_NAME,
  2068. }
  2069. };
  2070. void RootContainerTest(void) {
  2071. LPMAPITABLE lpRootTable = NULL;
  2072. HRESULT hResult;
  2073. LPWABOBJECT lpWABObject = NULL;
  2074. LPADRBOOK lpAdrBook = NULL;
  2075. LPABCONT lpRoot = NULL;
  2076. ULONG ulObjType;
  2077. ULONG cRows = 0;
  2078. LPSRowSet lpRow = NULL;
  2079. LPABCONT lpContainer = NULL;
  2080. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  2081. SetGlobalBufferFunctions(lpWABObject);
  2082. // Check out the ROOT container
  2083. if (! (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  2084. 0,
  2085. NULL,
  2086. NULL,
  2087. 0,
  2088. &ulObjType,
  2089. (LPUNKNOWN *)&lpRoot))) {
  2090. DebugObjectProps((LPMAPIPROP)lpRoot, "WAB Root Container");
  2091. if (! (hResult = lpRoot->lpVtbl->GetContentsTable(lpRoot,
  2092. 0,
  2093. &lpRootTable))) {
  2094. DebugTrace("Root container contents:\n");
  2095. DebugMapiTable(lpRootTable);
  2096. // Set the columns
  2097. lpRootTable->lpVtbl->SetColumns(lpRootTable,
  2098. (LPSPropTagArray)&ptaColumns,
  2099. 0);
  2100. // Open each container object
  2101. cRows = 1;
  2102. while (cRows) {
  2103. if (hResult = lpRootTable->lpVtbl->QueryRows(lpRootTable,
  2104. 1, // one row at a time
  2105. 0, // ulFlags
  2106. &lpRow)) {
  2107. DebugTrace("QueryRows -> %x\n", GetScode(hResult));
  2108. } else if (lpRow) {
  2109. if (cRows = lpRow->cRows) { // Yes, single '='
  2110. // Open the entry
  2111. if (! (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  2112. lpRow->aRow[0].lpProps[iptaColumnsPR_ENTRYID].Value.bin.cb,
  2113. (LPENTRYID)lpRow->aRow[0].lpProps[iptaColumnsPR_ENTRYID].Value.bin.lpb,
  2114. NULL,
  2115. 0,
  2116. &ulObjType,
  2117. (LPUNKNOWN *)&lpContainer))) {
  2118. DebugObjectProps((LPMAPIPROP)lpContainer, "Container");
  2119. lpContainer->lpVtbl->Release(lpContainer);
  2120. }
  2121. }
  2122. FreeProws(lpRow);
  2123. }
  2124. }
  2125. lpRootTable->lpVtbl->Release(lpRootTable);
  2126. }
  2127. lpRoot->lpVtbl->Release(lpRoot);
  2128. }
  2129. lpAdrBook->lpVtbl->Release(lpAdrBook);
  2130. lpWABObject->lpVtbl->Release(lpWABObject);
  2131. }
  2132. void GetMeTest(HWND hWnd)
  2133. {
  2134. HRESULT hResult = hrSuccess;
  2135. LPWABOBJECT lpWABObject = NULL;
  2136. LPADRBOOK lpAdrBook = NULL;
  2137. SCODE sc = SUCCESS_SUCCESS;
  2138. LPMAILUSER lpMailUser = NULL;
  2139. int i = 0,nLen=0;
  2140. SBinary sbEID;
  2141. {
  2142. hResult = WABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  2143. SetGlobalBufferFunctions(lpWABObject);
  2144. if(lpWABObject)
  2145. {
  2146. DWORD dwAction;
  2147. lpWABObject->lpVtbl->GetMe(lpWABObject, lpAdrBook,
  2148. 0, &dwAction,
  2149. &sbEID, 0);
  2150. }
  2151. if (lpAdrBook)
  2152. {
  2153. hResult = lpAdrBook->lpVtbl->Details(lpAdrBook,
  2154. (LPULONG) &hWnd, // ulUIParam
  2155. NULL,
  2156. NULL,
  2157. sbEID.cb,
  2158. (LPENTRYID) sbEID.lpb,
  2159. NULL,
  2160. NULL,
  2161. NULL,
  2162. 0);
  2163. lpAdrBook->lpVtbl->Release(lpAdrBook);
  2164. }
  2165. if (lpWABObject) {
  2166. lpWABObject->lpVtbl->Release(lpWABObject);
  2167. }
  2168. }
  2169. }