|
|
/*============================================================================
* * _ITABLE.H * * Internal header file for MAPI 1.0 In-memory MAPI Table DLL * * Copyright (C) 1993 and 1994 Microsoft Corporation * * * Hungarian shorthand: * To avoid excessively long identifier names, the following * shorthand expressions are used: * * LPSPropTagArray lppta * LPSRestriction lpres * LPSPropValue lpprop * LPSRow lprow * LPSRowSet lprows * LPSSortOrder lpso * LPSSortOrderSet lpsos */
// $MAC - Fix up some naming conflicts
#ifdef MAC
#define FFindColumn ITABLE_FFindColumn
#endif
typedef struct _TAD FAR * LPTAD; typedef struct _VUE FAR * LPVUE;
// Global Constants
#define ROW_CHUNK_SIZE 50
#define COLUMN_CHUNK_SIZE 15
// Max number of notifications to send in a batch
//
// Raid: Horsefly/Exchange/36281
// This was changed from 8 to 1 because code in itable.c which fills in
// the batch cannot guarantee the correct order of the notifications in
// it. If this is ever changed, that bug will have to be revisited.
//
#define MAX_BATCHED_NOTIFS 1
// For use in aligning data in buffers
#if defined (_AMD64_) || defined (_IA64_)
#define ALIGNTYPE LARGE_INTEGER
#else
#define ALIGNTYPE DWORD
#endif
#define ALIGN ((ULONG) (sizeof(ALIGNTYPE) - 1))
#define LcbAlignLcb(lcb) (((lcb) + ALIGN) & ~ALIGN)
#define PbAlignPb(pb) ((LPBYTE) ((((DWORD) (pb)) + ALIGN) & ~ALIGN))
// This structure is used to keep track of a private memory buffer which is
// used with the private AllocateMore function ScBufAllocateMore(). This
// allows for one MAPI memory allocation when the size of a property is known
// and the author wishes to use PropCopyMore. See ITABLE.C ScCopyTadRow()
// for an example.
typedef struct _CMB { ULONG ulcb; LPVOID lpv; } CMB, * LPCMB;
#if !defined(NO_VALIDATION)
#define VALIDATE_OBJ(lpobj,objtype,fn,lpVtbl) \
if ( BAD_STANDARD_OBJ(lpobj,objtype,fn,lpVtbl)) \ { \ DebugTrace( TEXT("%s::%s() - Invalid parameter passed as %s object\n"), \ #objtype, \
#fn, \
#objtype ); \
return ResultFromScode( MAPI_E_INVALID_PARAMETER ); \ }
#endif
#ifndef BEGIN_INTERFACE
#define BEGIN_INTERFACE
#endif
// $MAC - Supprt for WLM 4.0
#ifndef VTABLE_FILL
#define VTABLE_FILL
#endif
#define HrSetLastErrorIds(lpobj,sc,ids) \
UNKOBJ_HrSetLastError((LPUNKOBJ)(lpobj), \ (sc), \ (ids))
#ifdef WIN32
#define LockObj(lpobj) UNKOBJ_Lock((LPUNKOBJ)(lpobj))
__inline VOID UNKOBJ_Lock( LPUNKOBJ lpunkobj ) { EnterCriticalSection(&lpunkobj->csid); }
#define UnlockObj(lpobj) UNKOBJ_Unlock((LPUNKOBJ)(lpobj))
__inline VOID UNKOBJ_Unlock( LPUNKOBJ lpunkobj ) { LeaveCriticalSection(&lpunkobj->csid); } #else
#define LockObj(lpobj)
#define UnlockObj(lpobj)
#endif
// Memory Management Macros for code readability
#define ScAllocateBuffer(lpobj,ulcb,lppv) \
UNKOBJ_ScAllocate((LPUNKOBJ)(lpobj), \ (ulcb), \ (LPVOID FAR *)(lppv))
#define ScAllocateMore(lpobj,ulcb,lpv,lppv) \
UNKOBJ_ScAllocateMore((LPUNKOBJ)(lpobj), \ (ulcb), \ (lpv), \ (LPVOID FAR *)(lppv))
#define ScFreeBuffer(lpobj,lpv) \
UNKOBJ_Free((LPUNKOBJ)(lpobj), (lpv))
#define ScCOAllocate(lpunkobj,ulcb,lplpv) \
UNKOBJ_ScCOAllocate((LPUNKOBJ)(lpunkobj),(ulcb),(lplpv))
#define ScCOReallocate(lpunkobj,ulcb,lplpv) \
UNKOBJ_ScCOReallocate((LPUNKOBJ)(lpunkobj),(ulcb),(lplpv))
#define COFree(lpunkobj,lpv) \
UNKOBJ_COFree((LPUNKOBJ)(lpunkobj),(lpv))
#define MAPIFreeRows(lpobj,lprows) \
UNKOBJ_FreeRows((LPUNKOBJ)(lpobj),(lprows))
/*============================================================================
* TAD (table data class) * * Implementes in-memory table data object. */
#undef INTERFACE
#define INTERFACE struct _TAD
#undef MAPIMETHOD_
#define MAPIMETHOD_(type,method) MAPIMETHOD_DECLARE(type,method,TAD_)
MAPI_IUNKNOWN_METHODS(IMPL) MAPI_ITABLEDATA_METHODS(IMPL) #undef MAPIMETHOD_
#define MAPIMETHOD_(type,method) MAPIMETHOD_TYPEDEF(type,method,TAD_)
MAPI_IUNKNOWN_METHODS(IMPL) MAPI_ITABLEDATA_METHODS(IMPL) #undef MAPIMETHOD_
#define MAPIMETHOD_(type,method) STDMETHOD_(type,method)
DECLARE_MAPI_INTERFACE(TAD_) { BEGIN_INTERFACE MAPI_IUNKNOWN_METHODS(IMPL) MAPI_ITABLEDATA_METHODS(IMPL) };
typedef struct _TAD { TAD_Vtbl FAR * lpVtbl; UNKOBJ_MEMBERS;
UNKINST inst;
LPVUE lpvueList;
ULONG ulTableType; ULONG ulPropTagIndexCol;
ULONG ulcColsMac; LPSPropTagArray lpptaCols; // Initial view col set (CO)
ULONG ulcRowsAdd; ULONG ulcRowMacAdd; LPSRow * parglprowAdd; // Unsorted Row Set (CO)
ULONG ulcRowsIndex; ULONG ulcRowMacIndex; LPSRow * parglprowIndex; // Row Set Sorted by Index (CO)
LPVOID lpvDataSource; // used to store container specific data
ULONG cbDataSource; // bytes in lpvDataSource to copy to new allocation.
// If non-zero, CreateView should LocalAlloc this size
// and copy data from lpvDataSource into it. Release
// should LocalFree.
// With multiple containers, it becomes necessary to figure
// out which container the table represents. We cache the containers
// EID in the table for easy access. This is a pointer .. no need to free
LPSBinary pbinContEID;
// When calling get ContentsTable, we may sometimes want a list of
// contents from ALL the folders/containers for a particular profile and
// return those contents as a single contentstable. Following flag caches
// this setting so we collate contents of all folders. Works only if the
// container being opened was the PAB container and if bProfilesAPIEnabled
// (ie profiles were invoked explicitly)
BOOL bAllProfileContents;
// For PAB containers where profilesAPIEnabled=FALSE, GetContentsTable
// typically means return contents of ALL the WAB since user hasn;t asked for
// profiles. In this case we may want to have the option of opening only
// a particular folder and getting only the conetnts of that folder .. so we
// need a flag to cache this inverse option.
BOOL bContainerContentsOnly;
// When calling GetContentsTable, the caller can specify MAPI_UNICODE
// for unicode tables.. we cache that flag in case we need to refill the table
// at some later point ..
BOOL bMAPIUnicodeTable; } TAD;
SCODE ScCopyTadRowSet( LPTAD lptad, LPSRowSet lprowsetIn, ULONG * pcNewTags, ULONG * pcRows, LPSRow * * pparglprowUnsortedCopy, LPSRow * * pparglprowSortedCopy );
SCODE ScCopyTadRow( LPTAD lptad, LPSRow lprow, ULONG * pTagsAdded, LPSRow FAR * lplprowCopy );
VOID UpdateViews( LPTAD lptad, ULONG cRowsToRemove, LPSRow * parglprowToRemove, ULONG cRowsToAdd, LPSRow * parglprowToAddUnsorted, LPSRow * parglprowToAddSorted );
VOID FixupView( LPVUE lpvue, ULONG cRowsToRemove, LPSRow * parglprowToRemove, ULONG cRowsToAdd, LPSRow * parglprowToAddUnsorted, LPSRow * parglprowToAddSorted );
SCODE ScReplaceRows( LPTAD lptad, ULONG cRowsNew, LPSRow * parglprowNew, ULONG * pcRowsOld, LPSRow * * pparglprowOld );
SCODE ScFindRow( LPTAD lptad, LPSPropValue lpprop, LPSRow * * pplprow ); SCODE ScAddRow( LPUNKOBJ lpunkobj, LPSSortOrderSet lpsos, LPSRow lprow, ULONG uliRow, ULONG * pulcRows, ULONG * pulcRowsMac, LPSRow ** pparglprows, LPSRow ** pplprow );
/*============================================================================
* VUE (table view class) */
#undef INTERFACE
#define INTERFACE struct _VUE
#undef MAPIMETHOD_
#define MAPIMETHOD_(type,method) MAPIMETHOD_DECLARE(type,method,VUE_)
MAPI_IUNKNOWN_METHODS(IMPL) MAPI_IMAPITABLE_METHODS(IMPL) #undef MAPIMETHOD_
#define MAPIMETHOD_(type,method) MAPIMETHOD_TYPEDEF(type,method,VUE_)
MAPI_IUNKNOWN_METHODS(IMPL) MAPI_IMAPITABLE_METHODS(IMPL) #undef MAPIMETHOD_
#define MAPIMETHOD_(type,method) STDMETHOD_(type,method)
DECLARE_MAPI_INTERFACE(VUE_) { BEGIN_INTERFACE MAPI_IUNKNOWN_METHODS(IMPL) MAPI_IMAPITABLE_METHODS(IMPL) };
/* BOOKMARK status
* * dwfBKSFree is used for a bookmark that is NOT valid and * is available for use * dwfBKSValid is set for any used bookmark. * dwfChanged is used with dwfBKSValid to indicate that the marked row * has moved since the last query which in involved this * bookmark * dwfBKSMoving is used with dwfBKSValid to indicate that the marked row is * in the process of being moved relative to other rows. * dwfBKSStale is used with dwfBKSValid to indicate the given bookmark * no longer marks a row but has not been Freed * dwfBKSMask is the set of all valid bookmark status * */ #define dwfBKSFree ((DWORD) 0x00000000)
#define dwfBKSValid ((DWORD) 0x00000001)
#define dwfBKSChanged ((DWORD) 0x00000002)
#define dwfBKSMoving ((DWORD) 0x00000004)
#define dwfBKSStale ((DWORD) 0x00000008)
#define dwfBKSMask (~(dwfBKSValid|dwfBKSChanged|dwfBKSMoving|dwfBKSStale))
#define FBadBookmark(lpvue,bk) \
((bk) >= cBookmarksMax || \ ((lpvue)->rgbk[(bk)].dwfBKS == dwfBKSFree) || \ ((lpvue)->rgbk[(bk)].dwfBKS & dwfBKSMask)) \
typedef struct { DWORD dwfBKS; // Bookmark status
union { ULONG uliRow; // dwfBKSValid || dwfBKSChanged
LPSRow lprow; // dwfBKSMoving
}; } BK, * PBK;
// There is a maximum of 42 client defined bookmarks for each VUE. This
// seems adequate for an in-memory table.
// Bookmarks are kept as an array of 45 where the first three are
// the MAPI predefined bookmarks.
#define cBookmarksMax 45 // Max. # of bookmarks including reserved ones
#define cBookmarksReserved 3 // # of reserved bookmarks (begin, cur, end)
#define BOOKMARK_MEMBERS \
struct \ { \ union \ { \ struct \ { \ BK bkBeginning; \ BK bkCurrent; \ BK bkEnd; \ }; \ BK rgbk[cBookmarksMax]; \ }; \ } \
typedef BOOKMARK_MEMBERS UBK, * PUBK;
typedef struct _VUE { VUE_Vtbl FAR * lpVtbl; UNKOBJ_MEMBERS;
LPVUE lpvueNext; LPTAD lptadParent;
LPSPropTagArray lpptaCols; // Column set (MAPI)
LPSRestriction lpres; // Restriction (MAPI)
LPSSortOrderSet lpsos; // Sort order set (MAPI)
CALLERRELEASE FAR * lpfReleaseCallback; ULONG ulReleaseData;
ULONG ulcRowMac; // Space available for rows
LPSRow * parglprows; // Sorted Row Set
BOOKMARK_MEMBERS;
LPADVISELIST lpAdviseList; ULONG ulcAdvise; MAPIUID mapiuidNotif;
LPVOID lpvDataSource; // used to store container specific data
ULONG cbDataSource; // bytes in lpvDataSource to copy to new allocation.
// If non-zero, CreateView should LocalAlloc this size
// and copy data from lpvDataSource into it. Release
// should LocalFree.
BOOL bMAPIUnicodeTable; //tracks whether parent table needs UNICODE data or not
} VUE;
typedef struct _VUENOTIFKEY { ULONG ulcb; MAPIUID mapiuid;
} VUENOTIFKEY;
BOOL FBookMarkStale( LPVUE lpvue, BOOKMARK bk);
SCODE ScLoadRows( ULONG ulcRowsSrc, LPSRow * rglprowsSrc, LPVUE lpvue, LPSRestriction lpres, LPSSortOrderSet lpsos );
SCODE ScDeleteAllRows( LPTAD lptad);
SCODE ScMaybeAddRow( LPVUE lpvue, LPSRestriction lpres, LPSSortOrderSet lpsos, LPSRow lprow, ULONG uliRow, ULONG * pulcRows, ULONG * pulcRowMac, LPSRow ** pparglprows, LPSRow ** pplprow );
SCODE ScCopyVueRow( LPVUE lpvue, LPSPropTagArray lpptaCols, LPSRow lprowSrc, LPSRow lprowDst );
/*============================================================================
* Utilities */
SCODE ScDupRestriction( LPUNKOBJ lpunkobj, LPSRestriction lpres, LPSRestriction FAR * lplpresCopy );
SCODE ScDupRestrictionMore( LPUNKOBJ lpunkobj, LPSRestriction lpresSrc, LPVOID lpvLink, LPSRestriction lpresDst );
SCODE ScSatisfiesRestriction( LPSRow lprow, LPSRestriction lpres, ULONG * pfSatisfies ); SCODE ScDupRgbEx( LPUNKOBJ lpunkobj, ULONG ulcb, LPBYTE lpb, ULONG ulcbExtra, LPBYTE FAR * lplpbCopy );
LPSRow * PlprowCollateRow( ULONG ulcRows, LPSRow * rglprows, LPSSortOrderSet lpsos, BOOL fAfterExisting, LPSRow lprow );
LPSRow * PlprowByLprow( ULONG ulcRows, LPSRow * rglprows, LPSRow lprow );
LPSPropValue __fastcall LpSPropValueFindColumn( LPSRow lprow, ULONG ulPropTagColumn );
STDMETHODIMP_(SCODE) ScBufAllocateMore( ULONG ulcb, LPCMB lpcmb, LPVOID FAR * lplpv );
ULONG UlcbPropToCopy( LPSPropValue lpprop );
#ifndef WIN16 // WIN16 C (not C++) doesn't support INLINE functions.
// Functions are defined in ITABLE.C.
/*============================================================================
- FFindColumn() - * Checks a prop tag array to see if a given prop tag exists. * * NOTE! The prop tag must match completely (even type). * * * Parameters: * lpptaCols in Prop tag array to check * ulPropTag in Prop tag to check for. * * Returns: * TRUE if ulPropTag is in lpptaCols * FALSE if ulPropTag is not in lpptaCols */
__inline BOOL FFindColumn( LPSPropTagArray lpptaCols, ULONG ulPropTag ) { UNALIGNED ULONG * pulPropTag;
pulPropTag = lpptaCols->aulPropTag + lpptaCols->cValues; while ( --pulPropTag >= lpptaCols->aulPropTag ) if ( *pulPropTag == ulPropTag ) return TRUE;
return FALSE; }
/*============================================================================
- ScFindRow() - * Finds the first row in the table data whose index column property * value is equal to that of the specified property and returns the * location of that row in the table data, or, if no such row exists, * the end of the table data. * * Parameters: * lptad in TAD in which to find row * lpprop in Index property to match * puliRow out Pointer to location of found row * * Error returns: * MAPI_E_INVALID_PARAMETER If proptag of property isn't the TAD's * index column's proptag. * MAPI_E_NOT_FOUND If no matching row is found (*pplprow * is set to lptad->parglprows + * lptad->cRows in this case). */
__inline SCODE ScFindRow( LPTAD lptad, LPSPropValue lpprop, LPSRow * * pplprow) { SCODE sc = S_OK; SRow row = {0, 1, lpprop}; SizedSSortOrderSet(1, sosIndex) = { 1, 0, 0 };
if (lpprop->ulPropTag != lptad->ulPropTagIndexCol) { sc = MAPI_E_INVALID_PARAMETER; goto ret; }
Assert(!IsBadWritePtr(pplprow, sizeof(*pplprow)));
// Build a sort order set for the Index Column
sosIndex.aSort[0].ulPropTag = lptad->ulPropTagIndexCol; sosIndex.aSort[0].ulOrder = TABLE_SORT_ASCEND;
*pplprow = PlprowCollateRow(lptad->ulcRowsIndex, lptad->parglprowIndex, (LPSSortOrderSet) &sosIndex, FALSE, &row);
// Find the row in the Index Sorted Row Set
if ( !lptad->ulcRowsIndex || (*pplprow >= (lptad->parglprowIndex + lptad->ulcRowsIndex)) || LPropCompareProp( lpprop, (**pplprow)->lpProps)) { sc = MAPI_E_NOT_FOUND; }
ret: return sc; } #else // !WIN16
BOOL FFindColumn( LPSPropTagArray lpptaCols, ULONG ulPropTag ); SCODE ScFindRow( LPTAD lptad, LPSPropValue lpprop, LPSRow * * pplprow); #endif // !WIN16
// This macro is used on a ULONG or INT that is to be used as denominator
// If ul is non-zero it is returned unchanged. If ul is zero then a 1 is
// returned.
#define UlDenominator(ul) ((ul) | !(ul))
BOOL FRowContainsProp(LPSRow lprow, ULONG cValues, LPSPropValue lpsv);
STDAPI_(SCODE) CreateTableData(LPCIID lpiid, ALLOCATEBUFFER FAR * lpfAllocateBuffer, ALLOCATEMORE FAR * lpfAllocateMore, FREEBUFFER FAR * lpfFreeBuffer, LPVOID lpvReserved, ULONG ulTableType, ULONG ulPropTagIndexCol, LPSPropTagArray lpptaCols, LPVOID lpvDataSource, ULONG cbDataSource, LPSBinary pbinContEID, ULONG ulFlags, LPTABLEDATA FAR * lplptad);
HRESULT HrVUERestrict( LPVUE lpvue, LPSRestriction lpres, ULONG ulFlags );
|