//+-------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1996 // // File: dfmsp.hxx // // Contents: DocFile and MultiStream shared private definitions // //--------------------------------------------------------------- #ifndef __DFMSP_HXX__ #define __DFMSP_HXX__ #include "ref.hxx" #include "ole.hxx" #include "msf.hxx" #include "wchar.h" #include #include #include "../time.hxx" // Target-dependent things // // x86 16-bit build optimizations // // Some function parameters are always stack based pointers, // so we can let the compiler use near addressing via ss by // declaring the parameter stack based. // #define STACKBASED // // x86 16-bit retail build optimizations // // For the retail build, we group the code segments, // allowing us to make many calls near. // // Segmented memory model definitions #define HUGEP #ifndef LISet32 #define LISet32(li, v) \ ((li).HighPart = ((LONG)(v)) < 0 ? -1 : 0, (li).LowPart = (v)) #endif #ifndef ULISet32 #define ULISet32(li, v) ((li).HighPart = 0, (li).LowPart = (v)) #endif #define LISetLow(li, v) ((li).LowPart = (v)) #define LISetHigh(li, v) ((li).HighPart = (v)) #define ULISetLow(li, v) ((li).LowPart = (v)) #define ULISetHigh(li, v) ((li).HighPart = (v)) #define LIGetLow(li) ((li).LowPart) #define LIGetHigh(li) ((li).HighPart) #define ULIGetLow(li) ((li).LowPart) #define ULIGetHigh(li) ((li).HighPart) // Fast safe increment/decrement #define AtomicInc(lp) (++*(lp)) #define AtomicDec(lp) (--*(lp)) // Switchable ANSI/Unicode support // Conversion routines assume null termination before max characters //---------------------------------------------------------------------------- // The name of this function might change, so encapsulate it #define DfGetScode(hr) GetScode(hr) // // These function now just check for NULL values or are disabled // -- system dependent // // We leave these functions in so that it is a good place to verify memory, // if they can be implemented. // #define ValidateNotNull(x) \ ((x) ? S_OK : STG_E_INVALIDPOINTER) #define ValidateBuffer(pv, n) \ ValidateNotNull(pv) #define ValidatePtrBuffer(pv) \ ValidateNotNull(pv) #define ValidateHugeBuffer(pv, n) \ ValidateNotNull(pv) #define ValidateOutBuffer(pv, n) \ ValidateNotNull(pv) #define ValidateOutPtrBuffer(pv) \ ValidateNotNull(pv) #define ValidateHugeOutBuffer(pv, n) \ ValidateNotNull(pv) #define ValidateIid(riid) S_OK // disabled #define ValidateInterface(punk,riid) \ ValidateNotNull(punk) #define ValidateWcs(pwcs, cwcMax) \ ValdateNotNull(pwcs) #define ValidateSz(psz, cchMax) S_OK \ ValidateNotNull(psz) #define ValidateNameW(pwcs, cchMax) \ ((pwcs)?(S_OK):(STG_E_INVALIDNAME)) #define ValidateNameA(psz, cchMax) \ ((psz)?(S_OK):(STG_E_INVALIDNAME)) // Enumeration for Get/SetTime enum WHICHTIME { WT_CREATION=0, WT_MODIFICATION, WT_ACCESS }; // Signature for transactioning typedef DWORD DFSIGNATURE; #define DF_INVALIDSIGNATURE ((DFSIGNATURE)-1) // Convenience macros for signature creation #define LONGSIG(c1, c2, c3, c4) \ (((ULONG) (BYTE) (c1)) | \ (((ULONG) (BYTE) (c2)) << 8) | \ (((ULONG) (BYTE) (c3)) << 16) | \ (((ULONG) (BYTE) (c4)) << 24)) #ifndef min #define min(a, b) ((a)<(b) ? (a) : (b)) #endif #ifndef max #define max(a, b) ((a)>(b) ? (a) : (b)) #endif #define DfAllocWC(cwc, ppwcs) (*ppwcs = new WCHAR[cwc], \ (*ppwcs != NULL) ? S_OK: STG_E_INSUFFICIENTMEMORY) #define DfAllocWCS(pwcs, ppwcs) DfAllocWC(wcslen(pwcs)+1, ppwcs) // Docfile locally unique identity // Every entry in a multistream has a LUID generated and stored for it typedef DWORD DFLUID; #define DF_NOLUID 0 typedef WCHAR **SNBW; #ifndef _UNICODE typedef struct { WCHAR *pwcsName; DWORD type; ULARGE_INTEGER cbSize; FILETIME mtime; FILETIME ctime; FILETIME atime; DWORD grfMode; DWORD grfLocksSupported; CLSID clsid; DWORD grfStateBits; DWORD reserved; } STATSTGW; #else // if _UNICODE typedef STATSTG STATSTGW; #endif // ! _UNICODE #define TSTDMETHODIMP SCODE #define TSTDAPI(name) SCODE name##W #define CBSTORAGENAME (CWCSTORAGENAME*sizeof(WCHAR)) // A Unicode case-insensitive compare // No such thing really exists so we use our own #define dfwcsnicmp(wcsa, wcsb, len) wcsnicmp(wcsa, wcsb, len) // A name for a docfile element class CDfName { private: BYTE _ab[CBSTORAGENAME]; WORD _cb; public: CDfName(void) { _cb = 0; } void Set(WORD const cb, BYTE const *pb) { _cb = cb; if (pb) memcpy(_ab, pb, cb); } void Set(WCHAR const *pwcs) { Set( (WORD) ((wcslen(pwcs)+1)*sizeof(WCHAR)), (BYTE const *)pwcs); } // Special method for names with prepended character void Set(WCHAR const wcLead, WCHAR const *pwcs) { olAssert((wcslen(pwcs)+2)*sizeof(WCHAR) < CBSTORAGENAME); _cb = (USHORT) ((wcslen(pwcs)+2)*sizeof(WCHAR)); *(WCHAR *)_ab = wcLead; wcscpy((WCHAR *)_ab+1, pwcs); } inline void Set(CDfName const *pdfn); CDfName(WORD const cb, BYTE const *pb) { Set(cb, pb); } CDfName(WCHAR const *pwcs) { Set(pwcs); } // CDfName(char const *psz) { Set(psz); } WORD GetLength(void) const { return _cb; } BYTE *GetBuffer(void) const { return (BYTE *) _ab; } BOOL IsEqual(CDfName const *dfn) const { // This assumes that all DfNames are actually Unicode strings return _cb == dfn->_cb && dfwcsnicmp((WCHAR *)_ab, (WCHAR *)dfn->GetBuffer(), _cb) == 0; } inline void ByteSwap(void); }; inline void CDfName::Set(CDfName const *pdfn) { Set(pdfn->GetLength(), pdfn->GetBuffer()); } inline void CDfName::ByteSwap(void) { // assume all names are wide characters, we swap each word WCHAR *awName = (WCHAR*) _ab; ::ByteSwap(&_cb); for (unsigned int i=0; i