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.

636 lines
17 KiB

  1. /*============================================================================
  2. *
  3. * _ITABLE.H
  4. *
  5. * Internal header file for MAPI 1.0 In-memory MAPI Table DLL
  6. *
  7. * Copyright (C) 1993 and 1994 Microsoft Corporation
  8. *
  9. *
  10. * Hungarian shorthand:
  11. * To avoid excessively long identifier names, the following
  12. * shorthand expressions are used:
  13. *
  14. * LPSPropTagArray lppta
  15. * LPSRestriction lpres
  16. * LPSPropValue lpprop
  17. * LPSRow lprow
  18. * LPSRowSet lprows
  19. * LPSSortOrder lpso
  20. * LPSSortOrderSet lpsos
  21. */
  22. // $MAC - Fix up some naming conflicts
  23. #ifdef MAC
  24. #define FFindColumn ITABLE_FFindColumn
  25. #endif
  26. typedef struct _TAD FAR * LPTAD;
  27. typedef struct _VUE FAR * LPVUE;
  28. // Global Constants
  29. #define ROW_CHUNK_SIZE 50
  30. #define COLUMN_CHUNK_SIZE 15
  31. // Max number of notifications to send in a batch
  32. //
  33. // Raid: Horsefly/Exchange/36281
  34. // This was changed from 8 to 1 because code in itable.c which fills in
  35. // the batch cannot guarantee the correct order of the notifications in
  36. // it. If this is ever changed, that bug will have to be revisited.
  37. //
  38. #define MAX_BATCHED_NOTIFS 1
  39. // For use in aligning data in buffers
  40. #if defined (_AMD64_) || defined (_IA64_)
  41. #define ALIGNTYPE LARGE_INTEGER
  42. #else
  43. #define ALIGNTYPE DWORD
  44. #endif
  45. #define ALIGN ((ULONG) (sizeof(ALIGNTYPE) - 1))
  46. #define LcbAlignLcb(lcb) (((lcb) + ALIGN) & ~ALIGN)
  47. #define PbAlignPb(pb) ((LPBYTE) ((((DWORD) (pb)) + ALIGN) & ~ALIGN))
  48. // This structure is used to keep track of a private memory buffer which is
  49. // used with the private AllocateMore function ScBufAllocateMore(). This
  50. // allows for one MAPI memory allocation when the size of a property is known
  51. // and the author wishes to use PropCopyMore. See ITABLE.C ScCopyTadRow()
  52. // for an example.
  53. typedef struct _CMB
  54. {
  55. ULONG ulcb;
  56. LPVOID lpv;
  57. } CMB, * LPCMB;
  58. #if !defined(NO_VALIDATION)
  59. #define VALIDATE_OBJ(lpobj,objtype,fn,lpVtbl) \
  60. if ( BAD_STANDARD_OBJ(lpobj,objtype,fn,lpVtbl)) \
  61. { \
  62. DebugTrace( TEXT("%s::%s() - Invalid parameter passed as %s object\n"), \
  63. #objtype, \
  64. #fn, \
  65. #objtype ); \
  66. return ResultFromScode( MAPI_E_INVALID_PARAMETER ); \
  67. }
  68. #endif
  69. #ifndef BEGIN_INTERFACE
  70. #define BEGIN_INTERFACE
  71. #endif
  72. // $MAC - Supprt for WLM 4.0
  73. #ifndef VTABLE_FILL
  74. #define VTABLE_FILL
  75. #endif
  76. #define HrSetLastErrorIds(lpobj,sc,ids) \
  77. UNKOBJ_HrSetLastError((LPUNKOBJ)(lpobj), \
  78. (sc), \
  79. (ids))
  80. #ifdef WIN32
  81. #define LockObj(lpobj) UNKOBJ_Lock((LPUNKOBJ)(lpobj))
  82. __inline VOID
  83. UNKOBJ_Lock( LPUNKOBJ lpunkobj )
  84. {
  85. EnterCriticalSection(&lpunkobj->csid);
  86. }
  87. #define UnlockObj(lpobj) UNKOBJ_Unlock((LPUNKOBJ)(lpobj))
  88. __inline VOID
  89. UNKOBJ_Unlock( LPUNKOBJ lpunkobj )
  90. {
  91. LeaveCriticalSection(&lpunkobj->csid);
  92. }
  93. #else
  94. #define LockObj(lpobj)
  95. #define UnlockObj(lpobj)
  96. #endif
  97. // Memory Management Macros for code readability
  98. #define ScAllocateBuffer(lpobj,ulcb,lppv) \
  99. UNKOBJ_ScAllocate((LPUNKOBJ)(lpobj), \
  100. (ulcb), \
  101. (LPVOID FAR *)(lppv))
  102. #define ScAllocateMore(lpobj,ulcb,lpv,lppv) \
  103. UNKOBJ_ScAllocateMore((LPUNKOBJ)(lpobj), \
  104. (ulcb), \
  105. (lpv), \
  106. (LPVOID FAR *)(lppv))
  107. #define ScFreeBuffer(lpobj,lpv) \
  108. UNKOBJ_Free((LPUNKOBJ)(lpobj), (lpv))
  109. #define ScCOAllocate(lpunkobj,ulcb,lplpv) \
  110. UNKOBJ_ScCOAllocate((LPUNKOBJ)(lpunkobj),(ulcb),(lplpv))
  111. #define ScCOReallocate(lpunkobj,ulcb,lplpv) \
  112. UNKOBJ_ScCOReallocate((LPUNKOBJ)(lpunkobj),(ulcb),(lplpv))
  113. #define COFree(lpunkobj,lpv) \
  114. UNKOBJ_COFree((LPUNKOBJ)(lpunkobj),(lpv))
  115. #define MAPIFreeRows(lpobj,lprows) \
  116. UNKOBJ_FreeRows((LPUNKOBJ)(lpobj),(lprows))
  117. /*============================================================================
  118. * TAD (table data class)
  119. *
  120. * Implementes in-memory table data object.
  121. */
  122. #undef INTERFACE
  123. #define INTERFACE struct _TAD
  124. #undef MAPIMETHOD_
  125. #define MAPIMETHOD_(type,method) MAPIMETHOD_DECLARE(type,method,TAD_)
  126. MAPI_IUNKNOWN_METHODS(IMPL)
  127. MAPI_ITABLEDATA_METHODS(IMPL)
  128. #undef MAPIMETHOD_
  129. #define MAPIMETHOD_(type,method) MAPIMETHOD_TYPEDEF(type,method,TAD_)
  130. MAPI_IUNKNOWN_METHODS(IMPL)
  131. MAPI_ITABLEDATA_METHODS(IMPL)
  132. #undef MAPIMETHOD_
  133. #define MAPIMETHOD_(type,method) STDMETHOD_(type,method)
  134. DECLARE_MAPI_INTERFACE(TAD_)
  135. {
  136. BEGIN_INTERFACE
  137. MAPI_IUNKNOWN_METHODS(IMPL)
  138. MAPI_ITABLEDATA_METHODS(IMPL)
  139. };
  140. typedef struct _TAD
  141. {
  142. TAD_Vtbl FAR * lpVtbl;
  143. UNKOBJ_MEMBERS;
  144. UNKINST inst;
  145. LPVUE lpvueList;
  146. ULONG ulTableType;
  147. ULONG ulPropTagIndexCol;
  148. ULONG ulcColsMac;
  149. LPSPropTagArray lpptaCols; // Initial view col set (CO)
  150. ULONG ulcRowsAdd;
  151. ULONG ulcRowMacAdd;
  152. LPSRow * parglprowAdd; // Unsorted Row Set (CO)
  153. ULONG ulcRowsIndex;
  154. ULONG ulcRowMacIndex;
  155. LPSRow * parglprowIndex; // Row Set Sorted by Index (CO)
  156. LPVOID lpvDataSource; // used to store container specific data
  157. ULONG cbDataSource; // bytes in lpvDataSource to copy to new allocation.
  158. // If non-zero, CreateView should LocalAlloc this size
  159. // and copy data from lpvDataSource into it. Release
  160. // should LocalFree.
  161. // With multiple containers, it becomes necessary to figure
  162. // out which container the table represents. We cache the containers
  163. // EID in the table for easy access. This is a pointer .. no need to free
  164. LPSBinary pbinContEID;
  165. // When calling get ContentsTable, we may sometimes want a list of
  166. // contents from ALL the folders/containers for a particular profile and
  167. // return those contents as a single contentstable. Following flag caches
  168. // this setting so we collate contents of all folders. Works only if the
  169. // container being opened was the PAB container and if bProfilesAPIEnabled
  170. // (ie profiles were invoked explicitly)
  171. BOOL bAllProfileContents;
  172. // For PAB containers where profilesAPIEnabled=FALSE, GetContentsTable
  173. // typically means return contents of ALL the WAB since user hasn;t asked for
  174. // profiles. In this case we may want to have the option of opening only
  175. // a particular folder and getting only the conetnts of that folder .. so we
  176. // need a flag to cache this inverse option.
  177. BOOL bContainerContentsOnly;
  178. // When calling GetContentsTable, the caller can specify MAPI_UNICODE
  179. // for unicode tables.. we cache that flag in case we need to refill the table
  180. // at some later point ..
  181. BOOL bMAPIUnicodeTable;
  182. } TAD;
  183. SCODE
  184. ScCopyTadRowSet(
  185. LPTAD lptad,
  186. LPSRowSet lprowsetIn,
  187. ULONG * pcNewTags,
  188. ULONG * pcRows,
  189. LPSRow * * pparglprowUnsortedCopy,
  190. LPSRow * * pparglprowSortedCopy );
  191. SCODE
  192. ScCopyTadRow( LPTAD lptad,
  193. LPSRow lprow,
  194. ULONG * pTagsAdded,
  195. LPSRow FAR * lplprowCopy );
  196. VOID
  197. UpdateViews( LPTAD lptad,
  198. ULONG cRowsToRemove,
  199. LPSRow * parglprowToRemove,
  200. ULONG cRowsToAdd,
  201. LPSRow * parglprowToAddUnsorted,
  202. LPSRow * parglprowToAddSorted );
  203. VOID
  204. FixupView(
  205. LPVUE lpvue,
  206. ULONG cRowsToRemove,
  207. LPSRow * parglprowToRemove,
  208. ULONG cRowsToAdd,
  209. LPSRow * parglprowToAddUnsorted,
  210. LPSRow * parglprowToAddSorted );
  211. SCODE
  212. ScReplaceRows(
  213. LPTAD lptad,
  214. ULONG cRowsNew,
  215. LPSRow * parglprowNew,
  216. ULONG * pcRowsOld,
  217. LPSRow * * pparglprowOld );
  218. SCODE
  219. ScFindRow( LPTAD lptad,
  220. LPSPropValue lpprop,
  221. LPSRow * * pplprow );
  222. SCODE
  223. ScAddRow( LPUNKOBJ lpunkobj,
  224. LPSSortOrderSet lpsos,
  225. LPSRow lprow,
  226. ULONG uliRow,
  227. ULONG * pulcRows,
  228. ULONG * pulcRowsMac,
  229. LPSRow ** pparglprows,
  230. LPSRow ** pplprow );
  231. /*============================================================================
  232. * VUE (table view class)
  233. */
  234. #undef INTERFACE
  235. #define INTERFACE struct _VUE
  236. #undef MAPIMETHOD_
  237. #define MAPIMETHOD_(type,method) MAPIMETHOD_DECLARE(type,method,VUE_)
  238. MAPI_IUNKNOWN_METHODS(IMPL)
  239. MAPI_IMAPITABLE_METHODS(IMPL)
  240. #undef MAPIMETHOD_
  241. #define MAPIMETHOD_(type,method) MAPIMETHOD_TYPEDEF(type,method,VUE_)
  242. MAPI_IUNKNOWN_METHODS(IMPL)
  243. MAPI_IMAPITABLE_METHODS(IMPL)
  244. #undef MAPIMETHOD_
  245. #define MAPIMETHOD_(type,method) STDMETHOD_(type,method)
  246. DECLARE_MAPI_INTERFACE(VUE_)
  247. {
  248. BEGIN_INTERFACE
  249. MAPI_IUNKNOWN_METHODS(IMPL)
  250. MAPI_IMAPITABLE_METHODS(IMPL)
  251. };
  252. /* BOOKMARK status
  253. *
  254. * dwfBKSFree is used for a bookmark that is NOT valid and
  255. * is available for use
  256. * dwfBKSValid is set for any used bookmark.
  257. * dwfChanged is used with dwfBKSValid to indicate that the marked row
  258. * has moved since the last query which in involved this
  259. * bookmark
  260. * dwfBKSMoving is used with dwfBKSValid to indicate that the marked row is
  261. * in the process of being moved relative to other rows.
  262. * dwfBKSStale is used with dwfBKSValid to indicate the given bookmark
  263. * no longer marks a row but has not been Freed
  264. * dwfBKSMask is the set of all valid bookmark status
  265. *
  266. */
  267. #define dwfBKSFree ((DWORD) 0x00000000)
  268. #define dwfBKSValid ((DWORD) 0x00000001)
  269. #define dwfBKSChanged ((DWORD) 0x00000002)
  270. #define dwfBKSMoving ((DWORD) 0x00000004)
  271. #define dwfBKSStale ((DWORD) 0x00000008)
  272. #define dwfBKSMask (~(dwfBKSValid|dwfBKSChanged|dwfBKSMoving|dwfBKSStale))
  273. #define FBadBookmark(lpvue,bk) \
  274. ((bk) >= cBookmarksMax || \
  275. ((lpvue)->rgbk[(bk)].dwfBKS == dwfBKSFree) || \
  276. ((lpvue)->rgbk[(bk)].dwfBKS & dwfBKSMask)) \
  277. typedef struct
  278. {
  279. DWORD dwfBKS; // Bookmark status
  280. union
  281. {
  282. ULONG uliRow; // dwfBKSValid || dwfBKSChanged
  283. LPSRow lprow; // dwfBKSMoving
  284. };
  285. } BK, * PBK;
  286. // There is a maximum of 42 client defined bookmarks for each VUE. This
  287. // seems adequate for an in-memory table.
  288. // Bookmarks are kept as an array of 45 where the first three are
  289. // the MAPI predefined bookmarks.
  290. #define cBookmarksMax 45 // Max. # of bookmarks including reserved ones
  291. #define cBookmarksReserved 3 // # of reserved bookmarks (begin, cur, end)
  292. #define BOOKMARK_MEMBERS \
  293. struct \
  294. { \
  295. union \
  296. { \
  297. struct \
  298. { \
  299. BK bkBeginning; \
  300. BK bkCurrent; \
  301. BK bkEnd; \
  302. }; \
  303. BK rgbk[cBookmarksMax]; \
  304. }; \
  305. } \
  306. typedef BOOKMARK_MEMBERS UBK, * PUBK;
  307. typedef struct _VUE
  308. {
  309. VUE_Vtbl FAR * lpVtbl;
  310. UNKOBJ_MEMBERS;
  311. LPVUE lpvueNext;
  312. LPTAD lptadParent;
  313. LPSPropTagArray lpptaCols; // Column set (MAPI)
  314. LPSRestriction lpres; // Restriction (MAPI)
  315. LPSSortOrderSet lpsos; // Sort order set (MAPI)
  316. CALLERRELEASE FAR * lpfReleaseCallback;
  317. ULONG ulReleaseData;
  318. ULONG ulcRowMac; // Space available for rows
  319. LPSRow * parglprows; // Sorted Row Set
  320. BOOKMARK_MEMBERS;
  321. LPADVISELIST lpAdviseList;
  322. ULONG ulcAdvise;
  323. MAPIUID mapiuidNotif;
  324. LPVOID lpvDataSource; // used to store container specific data
  325. ULONG cbDataSource; // bytes in lpvDataSource to copy to new allocation.
  326. // If non-zero, CreateView should LocalAlloc this size
  327. // and copy data from lpvDataSource into it. Release
  328. // should LocalFree.
  329. BOOL bMAPIUnicodeTable; //tracks whether parent table needs UNICODE data or not
  330. } VUE;
  331. typedef struct _VUENOTIFKEY
  332. {
  333. ULONG ulcb;
  334. MAPIUID mapiuid;
  335. } VUENOTIFKEY;
  336. BOOL
  337. FBookMarkStale( LPVUE lpvue,
  338. BOOKMARK bk);
  339. SCODE
  340. ScLoadRows( ULONG ulcRowsSrc,
  341. LPSRow * rglprowsSrc,
  342. LPVUE lpvue,
  343. LPSRestriction lpres,
  344. LPSSortOrderSet lpsos );
  345. SCODE
  346. ScDeleteAllRows( LPTAD lptad);
  347. SCODE
  348. ScMaybeAddRow( LPVUE lpvue,
  349. LPSRestriction lpres,
  350. LPSSortOrderSet lpsos,
  351. LPSRow lprow,
  352. ULONG uliRow,
  353. ULONG * pulcRows,
  354. ULONG * pulcRowMac,
  355. LPSRow ** pparglprows,
  356. LPSRow ** pplprow );
  357. SCODE
  358. ScCopyVueRow( LPVUE lpvue,
  359. LPSPropTagArray lpptaCols,
  360. LPSRow lprowSrc,
  361. LPSRow lprowDst );
  362. /*============================================================================
  363. * Utilities
  364. */
  365. SCODE
  366. ScDupRestriction( LPUNKOBJ lpunkobj,
  367. LPSRestriction lpres,
  368. LPSRestriction FAR * lplpresCopy );
  369. SCODE
  370. ScDupRestrictionMore( LPUNKOBJ lpunkobj,
  371. LPSRestriction lpresSrc,
  372. LPVOID lpvLink,
  373. LPSRestriction lpresDst );
  374. SCODE
  375. ScSatisfiesRestriction( LPSRow lprow,
  376. LPSRestriction lpres,
  377. ULONG * pfSatisfies );
  378. SCODE
  379. ScDupRgbEx( LPUNKOBJ lpunkobj,
  380. ULONG ulcb,
  381. LPBYTE lpb,
  382. ULONG ulcbExtra,
  383. LPBYTE FAR * lplpbCopy );
  384. LPSRow *
  385. PlprowCollateRow( ULONG ulcRows,
  386. LPSRow * rglprows,
  387. LPSSortOrderSet lpsos,
  388. BOOL fAfterExisting,
  389. LPSRow lprow );
  390. LPSRow *
  391. PlprowByLprow( ULONG ulcRows,
  392. LPSRow * rglprows,
  393. LPSRow lprow );
  394. LPSPropValue __fastcall
  395. LpSPropValueFindColumn( LPSRow lprow,
  396. ULONG ulPropTagColumn );
  397. STDMETHODIMP_(SCODE)
  398. ScBufAllocateMore( ULONG ulcb,
  399. LPCMB lpcmb,
  400. LPVOID FAR * lplpv );
  401. ULONG
  402. UlcbPropToCopy( LPSPropValue lpprop );
  403. #ifndef WIN16 // WIN16 C (not C++) doesn't support INLINE functions.
  404. // Functions are defined in ITABLE.C.
  405. /*============================================================================
  406. - FFindColumn()
  407. -
  408. * Checks a prop tag array to see if a given prop tag exists.
  409. *
  410. * NOTE! The prop tag must match completely (even type).
  411. *
  412. *
  413. * Parameters:
  414. * lpptaCols in Prop tag array to check
  415. * ulPropTag in Prop tag to check for.
  416. *
  417. * Returns:
  418. * TRUE if ulPropTag is in lpptaCols
  419. * FALSE if ulPropTag is not in lpptaCols
  420. */
  421. __inline BOOL
  422. FFindColumn( LPSPropTagArray lpptaCols,
  423. ULONG ulPropTag )
  424. {
  425. UNALIGNED ULONG * pulPropTag;
  426. pulPropTag = lpptaCols->aulPropTag + lpptaCols->cValues;
  427. while ( --pulPropTag >= lpptaCols->aulPropTag )
  428. if ( *pulPropTag == ulPropTag )
  429. return TRUE;
  430. return FALSE;
  431. }
  432. /*============================================================================
  433. - ScFindRow()
  434. -
  435. * Finds the first row in the table data whose index column property
  436. * value is equal to that of the specified property and returns the
  437. * location of that row in the table data, or, if no such row exists,
  438. * the end of the table data.
  439. *
  440. * Parameters:
  441. * lptad in TAD in which to find row
  442. * lpprop in Index property to match
  443. * puliRow out Pointer to location of found row
  444. *
  445. * Error returns:
  446. * MAPI_E_INVALID_PARAMETER If proptag of property isn't the TAD's
  447. * index column's proptag.
  448. * MAPI_E_NOT_FOUND If no matching row is found (*pplprow
  449. * is set to lptad->parglprows +
  450. * lptad->cRows in this case).
  451. */
  452. __inline SCODE
  453. ScFindRow(
  454. LPTAD lptad,
  455. LPSPropValue lpprop,
  456. LPSRow * * pplprow)
  457. {
  458. SCODE sc = S_OK;
  459. SRow row = {0, 1, lpprop};
  460. SizedSSortOrderSet(1, sosIndex) = { 1, 0, 0 };
  461. if (lpprop->ulPropTag != lptad->ulPropTagIndexCol)
  462. {
  463. sc = MAPI_E_INVALID_PARAMETER;
  464. goto ret;
  465. }
  466. Assert(!IsBadWritePtr(pplprow, sizeof(*pplprow)));
  467. // Build a sort order set for the Index Column
  468. sosIndex.aSort[0].ulPropTag = lptad->ulPropTagIndexCol;
  469. sosIndex.aSort[0].ulOrder = TABLE_SORT_ASCEND;
  470. *pplprow = PlprowCollateRow(lptad->ulcRowsIndex,
  471. lptad->parglprowIndex,
  472. (LPSSortOrderSet) &sosIndex,
  473. FALSE,
  474. &row);
  475. // Find the row in the Index Sorted Row Set
  476. if ( !lptad->ulcRowsIndex
  477. || (*pplprow >= (lptad->parglprowIndex + lptad->ulcRowsIndex))
  478. || LPropCompareProp( lpprop, (**pplprow)->lpProps))
  479. {
  480. sc = MAPI_E_NOT_FOUND;
  481. }
  482. ret:
  483. return sc;
  484. }
  485. #else // !WIN16
  486. BOOL FFindColumn( LPSPropTagArray lpptaCols, ULONG ulPropTag );
  487. SCODE ScFindRow( LPTAD lptad, LPSPropValue lpprop, LPSRow * * pplprow);
  488. #endif // !WIN16
  489. // This macro is used on a ULONG or INT that is to be used as denominator
  490. // If ul is non-zero it is returned unchanged. If ul is zero then a 1 is
  491. // returned.
  492. #define UlDenominator(ul) ((ul) | !(ul))
  493. BOOL
  494. FRowContainsProp(LPSRow lprow,
  495. ULONG cValues,
  496. LPSPropValue lpsv);
  497. STDAPI_(SCODE)
  498. CreateTableData(LPCIID lpiid,
  499. ALLOCATEBUFFER FAR * lpfAllocateBuffer,
  500. ALLOCATEMORE FAR * lpfAllocateMore,
  501. FREEBUFFER FAR * lpfFreeBuffer,
  502. LPVOID lpvReserved,
  503. ULONG ulTableType,
  504. ULONG ulPropTagIndexCol,
  505. LPSPropTagArray lpptaCols,
  506. LPVOID lpvDataSource,
  507. ULONG cbDataSource,
  508. LPSBinary pbinContEID,
  509. ULONG ulFlags,
  510. LPTABLEDATA FAR * lplptad);
  511. HRESULT HrVUERestrict( LPVUE lpvue,
  512. LPSRestriction lpres,
  513. ULONG ulFlags );