windows-nt/Source/XPSP1/NT/ds/adsi/router/dbid.h
2020-09-26 16:20:57 +08:00

541 lines
11 KiB
C

//------------------------------------------------------------------------------
//
// Microsoft Sidewalk
// Copyright (C) Microsoft Corporation, 1997.
//
// File: oledbhelp.h
//
// Contents: OLE DB helper methods
//
// Owner: BassamT
//
// History: 11/30/97 BassamT Created.
//
//------------------------------------------------------------------------------
#if (!defined(BUILD_FOR_NT40))
#pragma once
//
// typedefs
//
// Column Number (cn). This number starts at 1.
typedef ULONG CNUM;
// Row number (rn). These numbers start at 0.
typedef ULONG RNUM;
// Offset (in bytes) into a structure or buffer (ob)
typedef DWORD OFFSET;
// Bookmark data type (bmk)
typedef ULONG BOOKMARK;
//
// constants that can be tuned for performance
//
// The maximum number of bytes to store inline for variable size data types.
const UINT k_cbInlineMax = 100;
// the number of rows to fetch at once.
const ULONG k_RowFetchCount = 20;
// Column alignment within a row.
// TODO : Should this be sizeof(DWORD) instead ?
const DWORD k_ColumnAlign = 8;
//
// constants
//
// invalid row number
const CNUM CNUM_INVALID = 0xFFFFFFFF;
// invalid row number
const RNUM RNUM_INVALID = 0xFFFFFFFF;
//
// conversion helpers
//
const UINT k_cchUCHARAsDecimalString = sizeof("255") - 1;
const UINT k_cchUSHORTAsDecimalString = sizeof("32767") - 1;
const UINT k_cchUINTAsDecimalString = sizeof("4294967294") - 1;
const UINT k_cchUINTAsHexString = sizeof("FFFFFFFF") - 1;
const UINT k_cchINTAsDecimalString = sizeof("-2147483648") - 1;
const UINT k_cchBOOLAsDecimalString = sizeof("1") - 1;
const UINT k_cchDOUBLEAsDecimalString = sizeof("2.2250738585072014 E + 308") - 1;
//
// macros
//
#define static_wcslen(pwsz) ((sizeof(pwsz) / sizeof(WCHAR)) - 1)
#define inrange(z,zmin,zmax) ( (zmin) <= (z) && (z) <= (zmax) )
#define DBID_USE_GUID_OR_PGUID(e) \
((1<<(e)) & \
( 1<<DBKIND_GUID \
| 1<<DBKIND_GUID_NAME \
| 1<<DBKIND_GUID_PROPID \
| 1<<DBKIND_PGUID_NAME \
| 1<<DBKIND_PGUID_PROPID ))
#define DBID_USE_GUID(e) \
((1<<(e)) & \
( 1<<DBKIND_GUID \
| 1<<DBKIND_GUID_NAME \
| 1<<DBKIND_GUID_PROPID ))
#define DBID_USE_PGUID(e) \
((1<<(e)) & \
( 1<<DBKIND_PGUID_NAME \
| 1<<DBKIND_PGUID_PROPID ))
#define DBID_USE_NAME(e) \
((1<<(e)) & \
( 1<<DBKIND_NAME \
| 1<<DBKIND_GUID_NAME \
| 1<<DBKIND_PGUID_NAME ))
#define DBID_USE_PROPID(e) \
((1<<(e)) & \
( 1<<DBKIND_PROPID \
| 1<<DBKIND_GUID_PROPID \
| 1<<DBKIND_PGUID_PROPID ))
#define DBID_IS_BOOKMARK(dbid) \
( DBID_USE_GUID(dbid.eKind) && dbid.uGuid.guid == DBCOL_SPECIALCOL \
|| DBID_USE_PGUID(dbid.eKind) && *dbid.uGuid.pguid == DBCOL_SPECIALCOL )
#define SET_DBID_FROM_NAME(dbid, pwsz) \
dbid.eKind = DBKIND_NAME;\
dbid.uName.pwszName = pwsz;
#define IsBadPointer(v) (IsBadReadPtr((void*)hAccessor, sizeof(void*)))
//
// functions
//
inline DWORD RoundDown(DWORD dwSize, DWORD dwAmount)
{
return dwSize & ~(dwAmount - 1);
}
inline DWORD RoundUp(DWORD dwSize, DWORD dwAmount)
{
return (dwSize + (dwAmount - 1)) & ~(dwAmount - 1);
}
#define CLIENT_MALLOC(cb) (CoTaskMemAlloc(cb))
#define CLIENT_FREE(x) (CoTaskMemFree(x), x = NULL)
HRESULT CopyDBIDs(DBID * pdbidDest, const DBID *pdbidSrc);
BOOL CompareDBIDs(const DBID *pdbid1, const DBID *pdbid2);
HRESULT IsValidDBID(const DBID *pdbid);
void FreeDBID(DBID *pdbid);
INT CompareOLEDBTypes(DBTYPE wType, void * pvValue1, void * pvValue2);
inline BOOL IsColumnVarLength
//------------------------------------------------------------------------------
// return TRUE if the column is of a variable length type
(
DBTYPE wType
)
{
if (wType == DBTYPE_BSTR ||
wType == DBTYPE_STR ||
wType == DBTYPE_WSTR ||
wType == DBTYPE_BYTES)
{
return TRUE;
}
return FALSE;
}
inline DWORD AdjustVariableTypesLength
//------------------------------------------------------------------------------
// adjusts the length of variable length data types
(
DBTYPE wType,
DWORD cb
)
{
if (wType == DBTYPE_STR)
{
return cb + 1;
}
if (wType == DBTYPE_WSTR)
{
return cb + sizeof(WCHAR);
}
return cb;
}
inline USHORT GetColumnMaxPrecision
//------------------------------------------------------------------------------
// returns the maximium possible precision of a column, given its type.
// Do not pass a byref, array, or vector column type.
(
DBTYPE wType
// [in] the OLE DB data type
)
{
if ((wType & DBTYPE_BYREF) ||
(wType & DBTYPE_ARRAY) ||
(wType & DBTYPE_VECTOR))
{
Assert (FALSE);
return 0;
}
switch( wType )
{
case DBTYPE_I1:
case DBTYPE_UI1:
return 3;
case DBTYPE_I2:
case DBTYPE_UI2:
return 5;
case DBTYPE_I4:
case DBTYPE_UI4:
return 10;
case DBTYPE_R4:
return 7;
case DBTYPE_I8:
return 19;
case DBTYPE_UI8:
return 20;
case DBTYPE_R8:
return 16;
case DBTYPE_DATE:
return 8;
case DBTYPE_CY:
return 19;
case DBTYPE_DECIMAL:
return 28;
case DBTYPE_NUMERIC:
return 38;
case DBTYPE_EMPTY:
case DBTYPE_NULL:
case DBTYPE_ERROR:
case DBTYPE_BOOL:
case DBTYPE_BSTR:
case DBTYPE_IDISPATCH:
case DBTYPE_IUNKNOWN:
case DBTYPE_VARIANT:
case DBTYPE_GUID:
case DBTYPE_BYTES:
case DBTYPE_STR:
case DBTYPE_WSTR:
case DBTYPE_DBDATE:
case DBTYPE_DBTIME:
case DBTYPE_DBTIMESTAMP:
case DBTYPE_HCHAPTER:
return 0;
default:
Assert (FALSE && "Unsupported data type");
return 0;
}
}
inline ULONG GetColumnSize
//------------------------------------------------------------------------------
// returns the size of the column in bytes
(
DBTYPE wType,
// [in] the OLE DB data type
DWORD cchMaxLength
// [in] if this is a variable size field then this is the max length
// if there is one defined. Otherwise this is 0xFFFFFFFF
)
{
// Handle BYREF destination separately
if ((wType & DBTYPE_BYREF) ||
(wType & DBTYPE_ARRAY) ||
(wType & DBTYPE_VECTOR))
{
return sizeof(void*);
}
switch( wType )
{
case DBTYPE_EMPTY:
case DBTYPE_NULL:
return 0;
case DBTYPE_I2:
case DBTYPE_UI2:
return 2;
case DBTYPE_I4:
case DBTYPE_R4:
case DBTYPE_UI4:
return 4;
case DBTYPE_I8:
case DBTYPE_R8:
case DBTYPE_DATE:
case DBTYPE_UI8:
return 8;
case DBTYPE_ERROR:
return sizeof(SCODE);
case DBTYPE_BOOL:
return sizeof(VARIANT_BOOL);
case DBTYPE_CY:
return sizeof(CY);
case DBTYPE_BSTR:
return sizeof(BSTR);
case DBTYPE_IDISPATCH:
return sizeof(IDispatch*);
case DBTYPE_IUNKNOWN:
return sizeof(IUnknown*);
case DBTYPE_VARIANT:
return sizeof(VARIANT);
case DBTYPE_DECIMAL:
return sizeof(DECIMAL);
case DBTYPE_I1:
case DBTYPE_UI1:
return 1;
case DBTYPE_GUID:
return sizeof(GUID);
case DBTYPE_BYTES:
return cchMaxLength;
case DBTYPE_STR:
return cchMaxLength * sizeof(char);
case DBTYPE_WSTR:
return cchMaxLength * sizeof(WCHAR);
case DBTYPE_NUMERIC:
return sizeof(DB_NUMERIC);
case DBTYPE_DBDATE:
return sizeof(DBDATE);
case DBTYPE_DBTIME:
return sizeof(DBTIME);
case DBTYPE_DBTIMESTAMP:
return sizeof(DBTIMESTAMP);
case DBTYPE_HCHAPTER:
return sizeof(HCHAPTER);
default:
Assert (FALSE && "Unsupported data type");
return 0;
}
}
//
// IUnknown Macros
//
// put this macros in your class definition. Make sure that
// you inherit from IUnknown and that you use the
// INIT_IUNKNOWN macro in your class constructor
#define DEFINE_IUNKNOWN \
private:\
LONG _cRefs;\
public:\
STDMETHOD(InternalQueryInterface)(REFIID riid, void ** ppv);\
STDMETHOD(QueryInterface)(REFIID riid, void ** ppv)\
{\
return InternalQueryInterface(riid, ppv);\
}\
STDMETHOD_(ULONG,AddRef)() \
{\
return InterlockedIncrement(&_cRefs);\
}\
STDMETHOD_(ULONG,Release)()\
{\
if (InterlockedDecrement(&_cRefs) == 0)\
{\
delete this;\
return 0;\
}\
return _cRefs;\
}
#define INIT_IUNKNOWN _cRefs = 1;
#define DEFINE_IUNKNOWN_WITH_CALLBACK(x) \
private:\
LONG _cRefs;\
public:\
STDMETHOD(InternalQueryInterface)(REFIID riid, void ** ppv);\
STDMETHOD(QueryInterface)(REFIID riid, void ** ppv)\
{\
return InternalQueryInterface(riid, ppv);\
}\
STDMETHOD_(ULONG,AddRef)() \
{\
return InterlockedIncrement(&_cRefs);\
}\
STDMETHOD_(ULONG,Release)()\
{\
if (InterlockedDecrement(&_cRefs) == 0)\
{\
x();\
return 0;\
}\
return _cRefs;\
}
// put this macros in your class definition. Make sure that
// you inherit from IUnknown and that you use the
// INIT_AGGREGATE_IUNKNOWN macro in your class constructor.
// Also make sure that you use SET_OUTER_IUNKNOWN in wherever
// you get a pointer to the Outer IUnknown
interface INonDelegatingUnknown
{
virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface
(
REFIID riid,
void __RPC_FAR *__RPC_FAR *ppvObject
) = 0;
virtual ULONG STDMETHODCALLTYPE NonDelegatingAddRef(void) = 0;
virtual ULONG STDMETHODCALLTYPE NonDelegatingRelease(void) = 0;
};
#define DEFINE_AGGREGATE_IUNKNOWN \
private:\
IUnknown * _punkOuter;\
LONG _cRefs;\
public:\
STDMETHOD(InternalQueryInterface)(REFIID riid, void ** ppv);\
STDMETHOD(NonDelegatingQueryInterface)(REFIID riid, void ** ppv)\
{\
if (ppv == NULL) return E_INVALIDARG;\
if (riid != IID_IUnknown)\
{\
return InternalQueryInterface(riid, ppv);\
}\
else\
{\
*ppv = static_cast<INonDelegatingUnknown*>(this);\
NonDelegatingAddRef();\
return NOERROR;\
}\
}\
STDMETHOD_(ULONG,NonDelegatingAddRef)() \
{\
return InterlockedIncrement(&_cRefs);\
}\
STDMETHOD_(ULONG,NonDelegatingRelease)()\
{\
if (InterlockedDecrement(&_cRefs) == 0)\
{\
delete this;\
return 0;\
}\
return _cRefs;\
}\
STDMETHOD(QueryInterface)(REFIID riid, void ** ppv)\
{\
return _punkOuter->QueryInterface(riid, ppv);\
}\
STDMETHOD_(ULONG,AddRef)() \
{\
return _punkOuter->AddRef();\
}\
STDMETHOD_(ULONG,Release)()\
{\
return _punkOuter->Release();\
}
#define INIT_AGGREGATE_IUNKNOWN \
_punkOuter = reinterpret_cast<IUnknown*>(static_cast<INonDelegatingUnknown*>(this)); \
_cRefs = 1;
#define SET_OUTER_IUNKNOWN(punk) if (punk != NULL) _punkOuter = punk;
#define DEFINE_AGGREGATE_IUNKNOWN_WITH_CALLBACKS(_AddRef, _Release) \
private:\
IUnknown * _punkOuter;\
LONG _cRefs;\
public:\
STDMETHOD(InternalQueryInterface)(REFIID riid, void ** ppv);\
STDMETHOD(NonDelegatingQueryInterface)(REFIID riid, void ** ppv)\
{\
if (ppv == NULL) return E_INVALIDARG;\
if (riid != IID_IUnknown)\
{\
return InternalQueryInterface(riid, ppv);\
}\
else\
{\
*ppv = static_cast<INonDelegatingUnknown*>(this);\
NonDelegatingAddRef();\
return NOERROR;\
}\
}\
STDMETHOD_(ULONG,NonDelegatingAddRef)() \
{\
_AddRef();\
return InterlockedIncrement(&_cRefs);\
}\
STDMETHOD_(ULONG,NonDelegatingRelease)()\
{\
_Release();\
if (InterlockedDecrement(&_cRefs) == 0)\
{\
delete this;\
return 0;\
}\
return _cRefs;\
}\
STDMETHOD(QueryInterface)(REFIID riid, void ** ppv)\
{\
return _punkOuter->QueryInterface(riid, ppv);\
}\
STDMETHOD_(ULONG,AddRef)() \
{\
return _punkOuter->AddRef();\
}\
STDMETHOD_(ULONG,Release)()\
{\
return _punkOuter->Release();\
}
#endif