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.

671 lines
22 KiB

  1. /***********************************************************************
  2. *
  3. * ENTRYID.C
  4. *
  5. * Windows AB EntryID functions
  6. *
  7. * Copyright 1992 - 1996 Microsoft Corporation. All Rights Reserved.
  8. *
  9. * Revision History:
  10. *
  11. * When Who What
  12. * -------- ------------------ ---------------------------------------
  13. * 05.13.96 Bruce Kelley Created
  14. *
  15. ***********************************************************************/
  16. #include <_apipch.h>
  17. #define _WAB_ENTRYID_C
  18. static UUID WABGUID = { /* d3ad91c0-9d51-11cf-a4a9-00aa0047faa4 */
  19. 0xd3ad91c0,
  20. 0x9d51,
  21. 0x11cf,
  22. {0xa4, 0xa9, 0x00, 0xaa, 0x00, 0x47, 0xfa, 0xa4}
  23. };
  24. static UUID MAPIGUID = { /* a41f2b81-a3be-1910-9d6e-00dd010f5402 */
  25. 0xa41f2b81,
  26. 0xa3be,
  27. 0x1910,
  28. {0x9d, 0x6e, 0x00, 0xdd, 0x01, 0x0f, 0x54, 0x02}
  29. };
  30. #ifdef _WIN64
  31. #define MYALIGN ((POINTER_64_INT) (sizeof(ALIGNTYPE) - 1))
  32. // #define MYALIGN ((ULONG) (sizeof(ALIGNTYPE) - 1))
  33. // #define MyPbAlignPb(pb) ((LPBYTE) ((((DWORD) (pb)) + ALIGN) & ~ALIGN))
  34. #define MyPbAlignPb(pb) ((LPBYTE) ((((POINTER_64_INT) (pb)) + MYALIGN) & ~MYALIGN))
  35. #endif
  36. /***************************************************************************
  37. Name : CreateWABEntryID
  38. Purpose : Creates a WAB EntryID
  39. Parameters: bType = one of WAB_PAB, WAB_DEF_DL, WAB_DEF_MAILUSER,
  40. WAB_ONEOFF, WAB_LDAP_CONTAINER, WAB_LDAP_MAILUSER, WAB_PABSHARED
  41. lpData1, lpData2, lpData3 = data to be placed in entryid
  42. lpRoot = AllocMore root structure (NULL if we should
  43. use AllocateBuffer instead of AllocateMore)
  44. lpcbEntryID -> returned size of lpEntryID.
  45. lpEntryID -> returned buffer containing entryid. This buffer
  46. is AllocMore'd onto the lpAllocMore buffer. Caller is
  47. responsible for MAPIFreeing this buffer.
  48. Returns : HRESULT
  49. Comment : WAB EID format is MAPI_ENTRYID:
  50. BYTE abFlags[4];
  51. MAPIUID mapiuid; // = WABONEOFFEID
  52. BYTE bData[]; // Contains BYTE type followed by type
  53. // specific data:
  54. // WAB_ONEOFF:
  55. // szDisplayName, szAddrType and szAddress.
  56. // the delimiter is the null between the strings.
  57. //
  58. 4/21/97
  59. Outlook doesnt understand WAB One-Off EntryIDs. Outlook wants MAPI
  60. One-off EntryIDs. What Outlook wants, Outlook gets.
  61. MAPI EntryIDs have a slightly different format than WAB entryids.
  62. ***************************************************************************/
  63. HRESULT CreateWABEntryID(
  64. BYTE bType,
  65. LPVOID lpData1,
  66. LPVOID lpData2,
  67. LPVOID lpData3,
  68. ULONG ulData1,
  69. ULONG ulData2,
  70. LPVOID lpRoot,
  71. LPULONG lpcbEntryID,
  72. LPENTRYID * lppEntryID)
  73. {
  74. // [PaulHi] 1/21/99 @review
  75. // I assume that the default WAB_ONEOFF EID we create is UNICODE. If we want an ANSI
  76. // WAB_ONEOFF EID then the CreateWABEntryEx() function needs to be called instead of
  77. // this one, with the first parameter set to FALSE.
  78. return CreateWABEntryIDEx(TRUE, bType, lpData1, lpData2, lpData3, ulData1, ulData2, lpRoot, lpcbEntryID, lppEntryID);
  79. }
  80. ////////////////////////////////////////////////////////////////////////////////
  81. // CreateWABEntryIDEx
  82. //
  83. // Same as CreateWABEntryID except that this function also takes a bIsUnicode
  84. // parameter. If this boolean is TRUE then a WAB_ONEOFF MAPI EID will have
  85. // the MAPI_UNICODE bit set in the ulDataType flag, otherwise it this bit
  86. // won't be set.
  87. ////////////////////////////////////////////////////////////////////////////////
  88. HRESULT CreateWABEntryIDEx(
  89. BOOL bIsUnicode,
  90. BYTE bType,
  91. LPVOID lpData1,
  92. LPVOID lpData2,
  93. LPVOID lpData3,
  94. ULONG ulData1,
  95. ULONG ulData2,
  96. LPVOID lpRoot,
  97. LPULONG lpcbEntryID,
  98. LPENTRYID * lppEntryID)
  99. {
  100. SCODE sc = SUCCESS_SUCCESS;
  101. LPMAPI_ENTRYID lpeid;
  102. ULONG ulSize = sizeof(MAPI_ENTRYID) + sizeof(bType);
  103. ULONG cbData1, cbData2, cbData3;
  104. UNALIGNED LPBYTE *llpb;
  105. LPBYTE lpb23;
  106. LPSTR lpszData1 = NULL;
  107. LPSTR lpszData2 = NULL;
  108. LPSTR lpszData3 = NULL;
  109. #ifdef _WIN64
  110. ulSize = LcbAlignLcb(ulSize);
  111. #endif
  112. switch ((int)bType) {
  113. case WAB_PAB:
  114. case WAB_PABSHARED:
  115. case WAB_DEF_DL:
  116. case WAB_DEF_MAILUSER:
  117. break;
  118. case WAB_ONEOFF:
  119. if (! lpData1 || ! lpData2 || ! lpData3) {
  120. sc = MAPI_E_INVALID_PARAMETER;
  121. goto exit;
  122. }
  123. ///--- 4/22/97 - MAPI One Off stuff
  124. // No Type here
  125. ulSize -= sizeof(bType);
  126. // Instead, add space for version and type
  127. ulSize += sizeof(DWORD);
  128. ///---
  129. // Need more space for data strings
  130. // [PaulHi] 1/21/99 Raid 64211 External clients may request non-UNICODE
  131. // MAPI EID strings.
  132. if (!bIsUnicode)
  133. {
  134. // First convert strings to ANSI to get accurate DBCS count
  135. lpszData1 = ConvertWtoA((LPTSTR)lpData1);
  136. lpszData2 = ConvertWtoA((LPTSTR)lpData2);
  137. lpszData3 = ConvertWtoA((LPTSTR)lpData3);
  138. if (!lpszData1 || !lpszData2 || !lpszData3)
  139. {
  140. sc = E_OUTOFMEMORY;
  141. goto exit;
  142. }
  143. // Compute size for single byte strings
  144. #ifdef _WIN64
  145. ulSize += cbData1 = LcbAlignLcb((lstrlenA(lpszData1) + 1));
  146. ulSize += cbData2 = LcbAlignLcb((lstrlenA(lpszData2) + 1));
  147. ulSize += cbData3 = LcbAlignLcb((lstrlenA(lpszData3) + 1));
  148. #else
  149. ulSize += cbData1 = (lstrlenA(lpszData1) + 1);
  150. ulSize += cbData2 = (lstrlenA(lpszData2) + 1);
  151. ulSize += cbData3 = (lstrlenA(lpszData3) + 1);
  152. #endif // _WIN64
  153. }
  154. else
  155. {
  156. // Compute size for double byte strings
  157. #ifdef _WIN64
  158. ulSize += cbData1 = LcbAlignLcb((sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1)));
  159. ulSize += cbData2 = LcbAlignLcb((sizeof(TCHAR)*(lstrlen((LPTSTR)lpData2) + 1)));
  160. ulSize += cbData3 = LcbAlignLcb(sizeof(TCHAR)*(lstrlen((LPTSTR)lpData3) + 1));
  161. #else
  162. ulSize += cbData1 = (sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1));
  163. ulSize += cbData2 = (sizeof(TCHAR)*(lstrlen((LPTSTR)lpData2) + 1));
  164. ulSize += cbData3 = (sizeof(TCHAR)*(lstrlen((LPTSTR)lpData3) + 1));
  165. #endif // _WIN64
  166. }
  167. break;
  168. case WAB_ROOT:
  169. // NULL entryid
  170. *lppEntryID = NULL;
  171. *lpcbEntryID = 0;
  172. goto exit;
  173. case WAB_CONTAINER:
  174. if (! lpData1) {
  175. sc = MAPI_E_INVALID_PARAMETER;
  176. goto exit;
  177. }
  178. ulSize += sizeof(ULONG) + ulData1;
  179. break;
  180. case WAB_LDAP_CONTAINER:
  181. if (! lpData1) {
  182. sc = MAPI_E_INVALID_PARAMETER;
  183. goto exit;
  184. }
  185. #ifdef _WIN64
  186. ulSize += cbData1 = LcbAlignLcb((sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1)));
  187. #else
  188. ulSize += cbData1 = (sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1));
  189. #endif // _WIN64
  190. break;
  191. case WAB_LDAP_MAILUSER:
  192. if (! lpData1 || ! lpData2) {
  193. sc = MAPI_E_INVALID_PARAMETER;
  194. goto exit;
  195. }
  196. #ifdef _WIN64
  197. ulSize += cbData1 = LcbAlignLcb((sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1)));
  198. ulSize += cbData2 = LcbAlignLcb((sizeof(TCHAR)*(lstrlen((LPTSTR)lpData2) + 1)));
  199. ulSize += LcbAlignLcb(sizeof(ULONG)) // this one stores the cached array count
  200. + LcbAlignLcb(sizeof(ULONG)) // this one stores the cached array buf size
  201. + LcbAlignLcb(ulData2); // this one stores the cached array
  202. #else
  203. ulSize += cbData1 = (sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1));
  204. ulSize += cbData2 = (sizeof(TCHAR)*(lstrlen((LPTSTR)lpData2) + 1));
  205. ulSize += sizeof(ULONG) // this one stores the cached array count
  206. + sizeof(ULONG) // this one stores the cached array buf size
  207. + ulData2; // this one stores the cached array
  208. #endif // _WIN64
  209. break;
  210. default:
  211. Assert(FALSE);
  212. sc = MAPI_E_INVALID_PARAMETER;
  213. goto exit;
  214. }
  215. *lppEntryID = NULL;
  216. #ifdef _WIN64
  217. ulSize = LcbAlignLcb(ulSize);
  218. #endif
  219. if (lpRoot) {
  220. if (sc = MAPIAllocateMore(ulSize, lpRoot, lppEntryID)) {
  221. goto exit;
  222. }
  223. } else {
  224. if (sc = MAPIAllocateBuffer(ulSize, lppEntryID)) {
  225. goto exit;
  226. }
  227. }
  228. lpeid = (LPMAPI_ENTRYID)*lppEntryID;
  229. *lpcbEntryID = ulSize;
  230. lpeid->abFlags[0] = 0;
  231. lpeid->abFlags[1] = 0;
  232. lpeid->abFlags[2] = 0;
  233. lpeid->abFlags[3] = 0;
  234. ///--- 4/22/97 - MAPI One Off stuff
  235. lpb23 = lpeid->bData;
  236. llpb = &lpb23;
  237. // Mark this EID as WAB
  238. if(bType == WAB_ONEOFF)
  239. {
  240. MemCopy(&lpeid->mapiuid, &MAPIGUID, sizeof(MAPIGUID));
  241. /*
  242. // version and flag are 0
  243. // *((LPDWORD)lpb) = 0;
  244. // lpb += sizeof(DWORD);
  245. //
  246. // Bug 32101 dont set flag to 0 - this means always send rich info
  247. */
  248. // [PaulHi] 1/21/99 Raid 64211 Set MAPI_UNICODE flag as appropriate
  249. *((LPULONG)*llpb) = MAKELONG(0, MAPI_ONE_OFF_NO_RICH_INFO);
  250. if (bIsUnicode)
  251. *((LPULONG)*llpb) += MAPI_UNICODE;
  252. (*llpb) += sizeof(ULONG);
  253. }
  254. else
  255. {
  256. LPBYTE lpb1 = *llpb;
  257. MemCopy(&lpeid->mapiuid, &WABGUID, sizeof(WABGUID));
  258. // Fill in the EntryID Data
  259. *lpb1 = bType;
  260. (*llpb)++;
  261. }
  262. ///---
  263. // Fill in any other data
  264. switch ((int)bType)
  265. {
  266. case WAB_ONEOFF:
  267. if (!bIsUnicode)
  268. {
  269. // single byte characters, converted above
  270. #ifdef _WIN64
  271. LPBYTE lpb = *llpb;
  272. Assert(lpszData1 && lpszData2 && lpszData3);
  273. lpb = MyPbAlignPb(lpb);
  274. StrCpyNA((LPSTR)lpb, lpszData1, cbData1/sizeof(CHAR));
  275. lpb += cbData1;
  276. StrCpyNA((LPSTR)lpb, lpszData2, cbData2/sizeof(CHAR));
  277. lpb += cbData2;
  278. StrCpyNA((LPSTR)lpb, lpszData3, cbData3/sizeof(CHAR));
  279. (*llpb) = lpb;
  280. #else
  281. Assert(lpszData1 && lpszData2 && lpszData3);
  282. StrCpyNA((LPSTR)*llpb, lpszData1, cbData1/sizeof(CHAR));
  283. (*llpb) += cbData1;
  284. StrCpyNA((LPSTR)*llpb, lpszData2, cbData2/sizeof(CHAR));
  285. (*llpb) += cbData2;
  286. StrCpyNA((LPSTR)*llpb, lpszData3, cbData3/sizeof(CHAR));
  287. #endif //_WIN64
  288. }
  289. else
  290. {
  291. // double byte characters
  292. StrCpyN((LPTSTR)*llpb, (LPTSTR)lpData1, cbData1/sizeof(TCHAR));
  293. (*llpb) += cbData1;
  294. StrCpyN((LPTSTR)*llpb, (LPTSTR)lpData2, cbData2/sizeof(TCHAR));
  295. (*llpb) += cbData2;
  296. StrCpyN((LPTSTR)*llpb, (LPTSTR)lpData3, cbData3/sizeof(TCHAR));
  297. }
  298. break;
  299. case WAB_CONTAINER:
  300. CopyMemory(*llpb, &ulData1, sizeof(ULONG));
  301. (*llpb) += sizeof(ULONG);
  302. CopyMemory(*llpb, lpData1, ulData1);
  303. break;
  304. case WAB_LDAP_CONTAINER:
  305. {
  306. UNALIGNED WCHAR * lp2 = lpData1;
  307. #ifdef _WIN64
  308. LPBYTE lpb = *llpb;
  309. lpb = MyPbAlignPb(lpb);
  310. StrCpyN((LPTSTR) lpb, (LPCTSTR) lp2, cbData1/sizeof(TCHAR)); // LDAP Server name
  311. #else
  312. StrCpyN((LPTSTR) *llpb, (LPCTSTR) lp2, cbData1/sizeof(TCHAR)); // LDAP Server name
  313. #endif
  314. }
  315. break;
  316. case WAB_LDAP_MAILUSER:
  317. {
  318. UNALIGNED WCHAR * lp2 = lpData1;
  319. #ifdef _WIN64
  320. LPBYTE lpb = *llpb;
  321. lpb = MyPbAlignPb(lpb);
  322. StrCpyN((LPTSTR) lpb, (LPCTSTR) lp2, cbData1/sizeof(TCHAR)); // LDAP Server name
  323. lpb += cbData1;
  324. #else
  325. StrCpyN((LPTSTR)*llpb, (LPTSTR)lpData1, cbData1/sizeof(TCHAR)); // LDAP Server name
  326. (*llpb) += cbData1;
  327. #endif
  328. #ifdef _WIN64
  329. // lpb = *llpb;
  330. // lpb = MyPbAlignPb(lpb);
  331. StrCpyN((LPTSTR) lpb, (LPCTSTR) lpData2, cbData2/sizeof(TCHAR)); // LDAP Server name
  332. (*llpb) = lpb;
  333. lpb += cbData2;
  334. CopyMemory(lpb, &ulData1, sizeof(ULONG));
  335. lpb += sizeof(ULONG);
  336. lpb = MyPbAlignPb(lpb);
  337. CopyMemory(lpb, &ulData2, sizeof(ULONG));
  338. lpb += sizeof(ULONG);
  339. lpb = MyPbAlignPb(lpb);
  340. CopyMemory(lpb, lpData3, ulData2);
  341. (*llpb) = lpb;
  342. #else
  343. StrCpyN((LPTSTR)*llpb, (LPTSTR)lpData2, cbData2/sizeof(TCHAR)); // LDAP search name
  344. (*llpb) += cbData2;
  345. CopyMemory(*llpb, &ulData1, sizeof(ULONG));
  346. (*llpb) += sizeof(ULONG);
  347. CopyMemory(*llpb, &ulData2, sizeof(ULONG));
  348. (*llpb) += sizeof(ULONG);
  349. CopyMemory(*llpb, lpData3, ulData2);
  350. #endif
  351. }
  352. break;
  353. } // end switch
  354. exit:
  355. // Clean up
  356. LocalFreeAndNull(&lpszData1);
  357. LocalFreeAndNull(&lpszData2);
  358. LocalFreeAndNull(&lpszData3);
  359. return(ResultFromScode(sc));
  360. }
  361. /***************************************************************************
  362. Name : IsWABEntryID
  363. Purpose : Validates a WAB EntryID
  364. Parameters: cbEntryID = size of lpEntryID.
  365. lpEntryID -> entryid to check.
  366. lppData1, lppData2 lppData3 = data from the entryid
  367. These returned pointers are pointers WITHIN the input
  368. lpEntryID and are not allocated seperately. They should
  369. not be freed.
  370. If lpData1 is NULL, then these values will not be returned.
  371. Returns : bType = one of WAB_PAB, WAB_DEF_DL, WAB_DEF_MAILUSER,
  372. WAB_ONEOFF, WAB_LDAP_CONTAINER, WAB_LDAP_MAILUSER, WAB_PABSHARED or 0 if
  373. this is not a WAB EntryID.
  374. Comment :
  375. ***************************************************************************/
  376. BYTE IsWABEntryID(
  377. ULONG cbEntryID,
  378. LPENTRYID lpEntryID,
  379. LPVOID * lppData1,
  380. LPVOID * lppData2,
  381. LPVOID * lppData3,
  382. LPVOID * lppData4,
  383. LPVOID * lppData5)
  384. {
  385. BYTE bType;
  386. LPMAPI_ENTRYID lpeid;
  387. LPBYTE lpData1, lpData2, lpData3;
  388. ULONG cbData1, cbData2;
  389. UNALIGNED BYTE *lpb = NULL ;
  390. ULONG ulMapiDataType = 0;
  391. // First check... is it big enough?
  392. if (cbEntryID < sizeof(MAPI_ENTRYID) + sizeof(bType)) {
  393. return(0);
  394. }
  395. lpeid = (LPMAPI_ENTRYID)lpEntryID;
  396. // Next check... does it contain our GUID?
  397. ///--- 4/22/97 - MAPI One Off stuff
  398. if (!memcmp(&lpeid->mapiuid, &MAPIGUID, sizeof(MAPIGUID)))
  399. {
  400. // [PaulHi] 1/21/99 The first ULONG in lpeid->bData is the MAPI datatype.
  401. // This will indicate whether the EID strings are ANSI or UNICODE.
  402. #ifdef _WIN64
  403. UNALIGNED ULONG * lpu;
  404. lpb = lpeid->bData;
  405. lpu = (UNALIGNED ULONG *)lpb;
  406. ulMapiDataType = *lpu;
  407. #else
  408. lpb = lpeid->bData;
  409. ulMapiDataType = *((ULONG *)lpb);
  410. #endif // _WIN64
  411. lpb += sizeof(ULONG);
  412. bType = WAB_ONEOFF;
  413. }
  414. else if (!memcmp(&lpeid->mapiuid, &WABGUID, sizeof(WABGUID)))
  415. {
  416. lpb = lpeid->bData;
  417. bType = *lpb;
  418. lpb++;
  419. }
  420. else
  421. {
  422. return(0); // No match
  423. }
  424. ///---
  425. switch ((int)bType) {
  426. case WAB_PABSHARED:
  427. case WAB_PAB:
  428. case WAB_DEF_DL:
  429. case WAB_DEF_MAILUSER:
  430. // No more data
  431. break;
  432. case WAB_CONTAINER:
  433. CopyMemory(&cbData1, lpb, sizeof(ULONG));
  434. lpb += sizeof(ULONG);
  435. lpData1 = lpb;
  436. if(lppData1)
  437. {
  438. *lppData1 = lpData1;
  439. *lppData2 = (LPVOID) IntToPtr(cbData1);
  440. }
  441. break;
  442. case WAB_ONEOFF:
  443. // Validate the data strings
  444. // [PaulHi] 1/20/99 Raid 64211
  445. // Outlook2K may pass in MAPI ANSI EIDs or EIDs with UNICODE strings.
  446. // OL2K will set the MAPI_UNICODE flag accordingly.
  447. if (ulMapiDataType & MAPI_UNICODE)
  448. {
  449. // Double byte strings
  450. lpData1 = lpb;
  451. if (IsBadStringPtr((LPTSTR)lpData1, 0xFFFFFFFF)) {
  452. return(0);
  453. }
  454. #ifdef _WIN64
  455. cbData1 = LcbAlignLcb((sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1)));
  456. #else
  457. cbData1 = (sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1));
  458. #endif //_WIN64
  459. lpData2 = lpData1 + cbData1;
  460. if (IsBadStringPtr((LPTSTR)lpData2, 0xFFFFFFFF)) {
  461. return(0);
  462. }
  463. #ifdef _WIN64
  464. cbData2 = LcbAlignLcb((sizeof(TCHAR)*(lstrlen((LPTSTR)lpData2) + 1)));
  465. #else
  466. cbData2 = (sizeof(TCHAR)*(lstrlen((LPTSTR)lpData2) + 1));
  467. #endif // _WIN64
  468. lpData3 = lpData2 + cbData2;
  469. if (IsBadStringPtr((LPTSTR)lpData3, 0xFFFFFFFF)) {
  470. return(0);
  471. }
  472. }
  473. else
  474. {
  475. // Single byte strings
  476. #ifdef _WIN64
  477. lpb = MyPbAlignPb(lpb);
  478. lpData1 = lpb;
  479. if (IsBadStringPtrA((LPSTR)lpData1, 0xFFFFFFFF)) {
  480. return(0);
  481. }
  482. cbData1 = lstrlenA((LPSTR)lpData1) + 1;
  483. lpData2 = lpData1 + LcbAlignLcb(cbData1);
  484. if (IsBadStringPtrA((LPSTR)lpData2, 0xFFFFFFFF)) {
  485. return(0);
  486. }
  487. cbData2 = lstrlenA((LPSTR)lpData2) + 1;
  488. lpData3 = lpData2 + LcbAlignLcb(cbData2);
  489. if (IsBadStringPtrA((LPSTR)lpData3, 0xFFFFFFFF)) {
  490. return(0);
  491. }
  492. #else
  493. lpData1 = lpb;
  494. if (IsBadStringPtrA((LPSTR)lpData1, 0xFFFFFFFF)) {
  495. return(0);
  496. }
  497. cbData1 = lstrlenA((LPSTR)lpData1) + 1;
  498. lpData2 = lpData1 + cbData1;
  499. if (IsBadStringPtrA((LPSTR)lpData2, 0xFFFFFFFF)) {
  500. return(0);
  501. }
  502. cbData2 = lstrlenA((LPSTR)lpData2) + 1;
  503. lpData3 = lpData2 + cbData2;
  504. if (IsBadStringPtrA((LPSTR)lpData3, 0xFFFFFFFF)) {
  505. return(0);
  506. }
  507. #endif // _WIN64
  508. }
  509. if (lppData1)
  510. {
  511. Assert(lppData2);
  512. Assert(lppData3);
  513. *lppData1 = lpData1;
  514. *lppData2 = lpData2;
  515. *lppData3 = lpData3;
  516. // [PaulHi] Also return the MAPI data type variable, if requested
  517. if (lppData4)
  518. *((ULONG *)lppData4) = ulMapiDataType;
  519. }
  520. break;
  521. case WAB_LDAP_CONTAINER:
  522. // Validate the data strings
  523. #ifdef _WIN64
  524. lpData1 = MyPbAlignPb(lpb);
  525. #else
  526. lpData1 = lpb;
  527. #endif // _WIN64
  528. if (IsBadStringPtr((LPTSTR)lpData1, 0xFFFFFFFF)) {
  529. return(0);
  530. }
  531. if (lppData1) {
  532. *lppData1 = lpData1;
  533. }
  534. break;
  535. case WAB_LDAP_MAILUSER:
  536. // Validate the data strings
  537. {
  538. #ifdef _WIN64
  539. UNALIGNED BYTE * lp2 = lpb;
  540. lp2 = MyPbAlignPb(lp2);
  541. lpData1 = lp2;
  542. #else
  543. lpData1 = lpb;
  544. #endif
  545. if (IsBadStringPtr((LPTSTR)lpData1, 0xFFFFFFFF))
  546. {
  547. return(0);
  548. }
  549. #ifdef _WIN64
  550. cbData1 = LcbAlignLcb(sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1));
  551. #else
  552. cbData1 = sizeof(TCHAR)*(lstrlen((LPTSTR)lpData1) + 1);
  553. #endif // _WIN64
  554. lpData2 = lpData1 + cbData1;
  555. if (IsBadStringPtr((LPTSTR)lpData2, 0xFFFFFFFF))
  556. {
  557. return(0);
  558. }
  559. #ifdef _WIN64
  560. cbData2 = LcbAlignLcb(sizeof(TCHAR)*(lstrlen((LPTSTR)lpData2) + 1));
  561. #else
  562. cbData2 = sizeof(TCHAR)*(lstrlen((LPTSTR)lpData2) + 1);
  563. #endif // _WIN64
  564. lpData3 = lpData2 + cbData2;
  565. if (lppData4)
  566. {
  567. CopyMemory(lppData4, lpData3, sizeof(ULONG)); //Copy the # of props in cached buffer
  568. }
  569. lpData3 += sizeof(ULONG);
  570. #ifdef _WIN64
  571. lpData3 = MyPbAlignPb(lpData3);
  572. #endif //_WIN64
  573. if (lppData5)
  574. {
  575. CopyMemory(lppData5, lpData3, sizeof(ULONG)); //Copy the size of cached buffer
  576. }
  577. lpData3 += sizeof(ULONG);
  578. #ifdef _WIN64
  579. lpData3 = MyPbAlignPb(lpData3);
  580. #endif //_WIN64
  581. if (lppData1)
  582. {
  583. *lppData1 = lpData1;
  584. if(lppData2)
  585. *lppData2 = lpData2;
  586. if(lppData3)
  587. *lppData3 = lpData3;
  588. }
  589. }
  590. break;
  591. default:
  592. return(0); // Not a valid WAB EID
  593. }
  594. return(bType);
  595. }