|
|
//+--------------------------------------------------------------
//
// 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 <memory.h>
#include <string.h>
#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).u.HighPart = ((LONG)(v)) < 0 ? -1 : 0, (li).u.LowPart = (v)) #endif
#ifndef ULISet32
#define ULISet32(li, v) ((li).u.HighPart = 0, (li).u.LowPart = (v))
#endif
#define LISetLow(li, v) ((li).u.LowPart = (v))
#define LISetHigh(li, v) ((li).u.HighPart = (v))
#define ULISetLow(li, v) ((li).u.LowPart = (v))
#define ULISetHigh(li, v) ((li).HighPart = (v))
#define LIGetLow(li) ((li).u.LowPart)
#define LIGetHigh(li) ((li).u.HighPart)
#define ULIGetLow(li) ((li).u.LowPart)
#define ULIGetHigh(li) ((li).u.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<CBSTORAGENAME/sizeof(WCHAR); i++) { ::ByteSwap(awName); awName++; } }
// Fast, fixed space iterator structure
struct SIterBuffer { CDfName dfnName; DWORD type; };
//SID is a Stream Identifier
typedef ULONG SID;
// IsEntry entry information
struct SEntryBuffer { DFLUID luid; DWORD dwType; SID sid; };
// Destroy flags
#define DESTROY_FROM_HANDLE 0
#define DESTROY_FROM_ENTRY 1
#define DESTROY_FROM 0x01
#define DESTROY_SELF 0x40
#define DESTROY_RECURSIVE 0x80
#define DESTROY_HANDLE (DESTROY_FROM_HANDLE | DESTROY_SELF)
#define DESTROY_ENTRY (DESTROY_FROM_ENTRY | DESTROY_SELF)
// Root startup flags
#define RSF_OPEN 0x00
#define RSF_CONVERT 0x01
#define RSF_TRUNCATE 0x02
#define RSF_CREATE 0x04
#define RSF_DELAY 0x08
#define RSF_DELETEONRELEASE 0x10
#define RSF_OPENCREATE 0x20
#define RSF_SCRATCH 0x40
#define RSF_SNAPSHOT 0x80
#define RSF_NO_BUFFERING 0x200
#define RSF_ENCRYPTED 0x400
#define RSF_SECTORSIZE4K 0xC000
#define RSF_CREATEFLAGS (RSF_CREATE | RSF_TRUNCATE | RSF_OPENCREATE)
// Stream copy buffer size
ULONG const STREAMBUFFERSIZE = 8192; ULONG const LARGESTREAMBUFFERSIZE = 256*1024;
// ILockBytes copy buffer size
ULONG const LOCKBYTESBUFFERSIZE = 16384;
// Docfile flags for permissions and other information kept
// on streams and docfiles
typedef WORD DFLAGS;
#define DF_TRANSACTEDSELF 0x0001
#define DF_TRANSACTED 0x0002
#define DF_DIRECT 0x0000
#define DF_INDEPENDENT 0x0004
#define DF_DEPENDENT 0x0000
#define DF_COMMIT 0x0008
#define DF_ABORT 0x0000
#define DF_INVALID 0x0010
#define DF_REVERTED 0x0020
#define DF_NOTREVERTED 0x0000
#define DF_READ 0x0040
#define DF_WRITE 0x0080
#define DF_READWRITE (DF_READ | DF_WRITE)
#define DF_DENYREAD 0x0100
#define DF_DENYWRITE 0x0200
#define DF_DENYALL (DF_DENYREAD | DF_DENYWRITE)
#define DF_PRIORITY 0x0400
#define DF_CREATE 0x0800
#define DF_CACHE 0x1000
#define DF_NOUPDATE 0x2000
// docfile can be bigger than 4G
#define DF_LARGE 0x80000
// Shift required to translate from DF_READWRITE to DF_DENYALL
#define DF_DENIALSHIFT 2
// Permission abstraction macros
// These only work with DF_* flags
#define P_READ(f) ((f) & DF_READ)
#define P_WRITE(f) ((f) & DF_WRITE)
#define P_READWRITE(f) (((f) & (DF_READ | DF_WRITE)) == (DF_READ | DF_WRITE))
#define P_DENYREAD(f) ((f) & DF_DENYREAD)
#define P_DENYWRITE(f) ((f) & DF_DENYWRITE)
#define P_DENYALL(f) (((f) & (DF_DENYREAD | DF_DENYWRITE)) == \
(DF_DENYREAD | DF_DENYWRITE)) #define P_PRIORITY(f) ((f) & DF_PRIORITY)
#define P_TRANSACTED(f) ((f) & DF_TRANSACTED)
#define P_DIRECT(f) (!P_TRANSACTED(f))
#define P_INDEPENDENT(f) ((f) & DF_INDEPENDENT)
#define P_DEPENDENT(f) (!P_INDEPENDENT(f))
#define P_TSELF(f) ((f) & DF_TRANSACTEDSELF)
#define P_INVALID(f) ((f) & DF_INVALID)
#define P_REVERTED(f) ((f) & DF_REVERTED)
#define P_COMMIT(f) ((f) & DF_COMMIT)
#define P_ABORT(f) (!P_COMMIT(f))
#define P_CREATE(f) ((f) & DF_CREATE)
#define P_CACHE(f) ((f) & DF_CACHE)
#define P_NOUPDATE(f) ((f) & DF_NOUPDATE)
// Translation functions
DFLAGS ModeToDFlags(DWORD const dwModeFlags); DWORD DFlagsToMode(DFLAGS const df);
// Flags for what state has been dirtied
#define DIRTY_CREATETIME 0x0001
#define DIRTY_MODIFYTIME 0x0002
#define DIRTY_ACCESSTIME 0x0004
#define DIRTY_CLASS 0x0008
#define DIRTY_STATEBITS 0x0010
// Allow text in asserts
#define aMsg(s) (s)
#define STGTY_REAL (STGTY_STORAGE | STGTY_STREAM | STGTY_LOCKBYTES)
#define REAL_STGTY(f) (f)
extern void *DfMemAlloc(DWORD dwFlags, size_t size); extern void DfMemFree(void *mem);
extern void *TaskMemAlloc(size_t size); extern void TaskMemFree(void *mem);
// Buffer management
#define CB_LARGEBUFFER 65536
#define CB_PAGEBUFFER 4096
#define CB_SMALLBUFFER 512
extern SCODE GetBuffer(USHORT cbMin, USHORT cbMax, BYTE **ppb, USHORT *pcbActual); extern void GetSafeBuffer(USHORT cbMin, USHORT cbMax, BYTE **ppb, USHORT *pcbActual); extern void FreeBuffer(BYTE *pb);
#endif // #ifndef __DFMSP_HXX__
|