Windows2003-3790/inetcore/outlookexpress/wabw/wabapi/_itable.h
2020-09-30 16:53:55 +02:00

637 lines
17 KiB
C

/*============================================================================
*
* _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 );