|
|
//------------------------------------------------------------------------------
//
// Microsoft Sidewalk
// Copyright (C) Microsoft Corporation, 1997.
//
// File: oledbhelp.cpp
//
// Contents: OLE DB helper methods
//
// Owner: BassamT
//
// History: 11/30/97 BassamT Created.
//
//------------------------------------------------------------------------------
#include "oleds.hxx"
#if (!defined(BUILD_FOR_NT40))
#define dimensionof(x) sizeof(x)/sizeof(x[0])
HRESULT IsValidDBID //------------------------------------------------------------------------------
// checks if we have a valid DBID
( const DBID * pdbid1 // [in] the DBID to check
) { Assert(pdbid1 != NULL);
if (pdbid1 && ((pdbid1->eKind == DBKIND_GUID_NAME) || (pdbid1->eKind == DBKIND_GUID_PROPID) || (pdbid1->eKind == DBKIND_NAME) || (pdbid1->eKind == DBKIND_PGUID_NAME) || (pdbid1->eKind == DBKIND_PGUID_PROPID) || (pdbid1->eKind == DBKIND_PROPID) || (pdbid1->eKind == DBKIND_GUID))) { return S_OK; } else { return S_FALSE; } }
BOOL CompareDBIDs //------------------------------------------------------------------------------
// Compares two DBIDs. Given two DBIDS to determine if they are the same.
// Returns TRUE if they are the same DBIDs or FALSE if different
( const DBID * pdbid1, // [in] pointer to DBID 1; can be badly formed eKind
const DBID * pdbid2 // [in] pointer to DBID 2; assumed valid eKind
) { // Array of valid eKind matches, in addition to matching exactly.
static BYTE abKind[] = { DBKIND_PGUID_NAME, // DBKIND_GUID_NAME
DBKIND_PGUID_PROPID, // DBKIND_GUID_PROPID
DBKIND_NAME, // DBKIND_NAME
DBKIND_GUID_NAME, // DBKIND_PGUID_NAME
DBKIND_GUID_PROPID, // DBKIND_PGUID_PROPID
DBKIND_PROPID, // DBKIND_PROPID
DBKIND_GUID // DBKIND_GUID
};
// Verify that offsets are correct (header file might change).
Assert( 0 == DBKIND_GUID_NAME && 1 == DBKIND_GUID_PROPID && 2 == DBKIND_NAME && 3 == DBKIND_PGUID_NAME && 4 == DBKIND_PGUID_PROPID && 5 == DBKIND_PROPID && 6 == DBKIND_GUID);
if (pdbid1 == NULL || pdbid2 == NULL) { return FALSE; }
// Assume a match, and discard early if we can.
// Don't assert for 1, since might be badly-formed.
// 2 is assumed to be well-formed.
Assert(inrange(((SHORT)pdbid2->eKind), 0, dimensionof(abKind)));
if (pdbid1->eKind != pdbid2->eKind && pdbid1->eKind != abKind[pdbid2->eKind]) { return FALSE; }
if (DBID_USE_GUID_OR_PGUID(pdbid1->eKind)) { if (!DBID_USE_GUID_OR_PGUID(pdbid2->eKind)) { return FALSE; }
// Compare GUIDs.
// Note that _GUID_ is equivalent to _PGUID_.
if (!IsEqualGUID( DBID_USE_PGUID(pdbid1->eKind) ? *(pdbid1->uGuid.pguid) : pdbid1->uGuid.guid, DBID_USE_PGUID(pdbid2->eKind) ? *(pdbid2->uGuid.pguid) : pdbid2->uGuid.guid)) { return FALSE; } }
if (DBID_USE_NAME(pdbid1->eKind)) { if (!DBID_USE_NAME(pdbid2->eKind)) { return FALSE; }
// Compare names.
// Need to check if 1 is null and the other is not.
if (((pdbid1->uName.pwszName == NULL) && (pdbid2->uName.pwszName != NULL)) || ((pdbid1->uName.pwszName != NULL) && (pdbid2->uName.pwszName == NULL))) { return FALSE; }
// Since the above check does not rule out both being null, which is
// a valid comparison, and wcscmp will GPF if they were, we need
// to check for valid pointers
if(pdbid1->uName.pwszName != NULL && pdbid2->uName.pwszName != NULL) { // Assume null-terminated.
if (_wcsicmp(pdbid1->uName.pwszName, pdbid2->uName.pwszName) != 0) { return FALSE; } } }
if (DBID_USE_PROPID(pdbid1->eKind)) { if (!DBID_USE_PROPID(pdbid2->eKind)) { return FALSE; } // Compare PROPID.
if (pdbid1->uName.ulPropid != pdbid2->uName.ulPropid) { return FALSE; } }
// a match
return TRUE; }
void FreeDBID //------------------------------------------------------------------------------
// FreeDBID
// Given a DBID free an allocated buffers
( DBID *pdbidSrc //[in] Pointer to DBID
) { Assert(pdbidSrc);
switch (pdbidSrc->eKind) { case DBKIND_GUID_NAME: CLIENT_FREE(pdbidSrc->uName.pwszName); break; case DBKIND_NAME: CLIENT_FREE(pdbidSrc->uName.pwszName); break; case DBKIND_PGUID_NAME: CLIENT_FREE(pdbidSrc->uGuid.pguid); CLIENT_FREE(pdbidSrc->uName.pwszName); break; case DBKIND_PGUID_PROPID: CLIENT_FREE(pdbidSrc->uGuid.pguid); break; case DBKIND_GUID_PROPID: case DBKIND_PROPID: case DBKIND_GUID: break; default: Assert(NULL && L"Unhandled dbid1.ekind"); break; } }
HRESULT CopyDBIDs //------------------------------------------------------------------------------
// Given a DBID to copy, put it in the new buffer
//
// Need to use IMalloc->Alloc and IMalloc->Free since this routine
// is used to copy the DBIDs from storage back into the memory handed to
// the consumer.
//
// HRESULT indicating the status of the copy
// S_OK = Copied
// S_FALSE = Problems copying
// E_OUTOFMEMORY = Could not allocate resources
//
( DBID * pdbidDest, // [in,out] Pointer to Destination DBID
const DBID *pdbidSrc // [in] Pointer to Source DBID
) { Assert(pdbidDest); Assert(pdbidSrc);
size_t cwchBuffer; HRESULT hr;
memset(pdbidDest, 0, sizeof(*pdbidDest));
// Save eKind
pdbidDest->eKind = pdbidSrc->eKind;
switch (pdbidSrc->eKind) { case DBKIND_GUID_NAME: pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid; cwchBuffer = wcslen(pdbidSrc->uName.pwszName) + 1;
if (pdbidDest->uName.pwszName = (PWSTR)CLIENT_MALLOC(cwchBuffer * sizeof(WCHAR))) { wcsncpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer); } else { hr = E_OUTOFMEMORY; //ErrorTrace(hr);
goto Error; } break;
case DBKIND_GUID_PROPID: pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid; pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid; break;
case DBKIND_NAME: cwchBuffer = wcslen(pdbidSrc->uName.pwszName) + 1; if (pdbidDest->uName.pwszName = (PWSTR)CLIENT_MALLOC(cwchBuffer * sizeof(WCHAR))) { wcsncpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer); } else { hr = E_OUTOFMEMORY; //ErrorTrace(hr);
goto Error; } break;
case DBKIND_PGUID_NAME: // convert the pguid into a guid so that we don't have to do an extra malloc
pdbidDest->eKind = DBKIND_GUID_NAME; pdbidDest->uGuid.guid = *pdbidSrc->uGuid.pguid; cwchBuffer = wcslen(pdbidSrc->uName.pwszName) + 1;
if (pdbidDest->uName.pwszName = (PWSTR)CLIENT_MALLOC(cwchBuffer * sizeof(WCHAR))) { wcsncpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer); } else { hr = E_OUTOFMEMORY; //ErrorTrace(hr);
goto Error; } break;
case DBKIND_PGUID_PROPID: // convert the pguid into a guid so that we don't have to do an extra malloc
pdbidDest->eKind = DBKIND_GUID_PROPID; pdbidDest->uGuid.guid = *pdbidSrc->uGuid.pguid; pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid; break;
case DBKIND_PROPID: pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid; break;
case DBKIND_GUID: pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid; break;
default: Assert(NULL && L"Unhandled dbid ekind"); hr = E_FAIL; //ErrorTrace(hr);
goto Error; }
return NOERROR;
Error: Assert(FAILED(hr)); return hr; }
INT CompareOLEDBTypes //------------------------------------------------------------------------------
// Compares two value of the same DBTYPE.
//
// Returns :
//
// 0 if both values are equal
// >0 if pvValue1 is greater than pvValue2
// <0 if pvValue1 is less than pvValue2
//
( DBTYPE wType, // [in] the OLE DB type of both values
void * pvValue1, // [in] a pointer to Value1
void * pvValue2 // [in] a pointer to Value2
) { Assert (pvValue1 != NULL); Assert (pvValue2 != NULL);
// TODO : Is this right ?
INT comp = -1;
/*
// TODO : how do we handle these ?
case DBTYPE_ARRAY: case DBTYPE_BYREF: case DBTYPE_VECTOR: */
// TODO : support the other DB_TYPES and check that all types work
// TODO : What about NULL values ?
// TODO : WE could generalize this function and let it handle values
// of different types.
switch (wType) { case DBTYPE_I2: comp = (*(SHORT*)pvValue1) - (*(SHORT*)pvValue2); break; case DBTYPE_I4: comp = (*(LONG*)pvValue1) - (*(LONG*)pvValue2); break; case DBTYPE_UI1: comp = (*(UCHAR*)pvValue1) - (*(UCHAR*)pvValue2); break; case DBTYPE_I1: comp = (*(CHAR*)pvValue1) - (*(CHAR*)pvValue2); break; case DBTYPE_UI2: comp = (*(USHORT*)pvValue1) - (*(USHORT*)pvValue2); break; case DBTYPE_UI4: comp = (*(ULONG*)pvValue1) - (*(ULONG*)pvValue2); break; case DBTYPE_STR: comp = strcmp((CHAR*)(pvValue1), (CHAR*)pvValue2); break; case DBTYPE_WSTR: comp = wcscmp((WCHAR*)(pvValue1), (WCHAR*)pvValue2); break; case DBTYPE_GUID: case DBTYPE_I8: case DBTYPE_UI8: case DBTYPE_R4: case DBTYPE_R8: case DBTYPE_CY: case DBTYPE_DATE: case DBTYPE_BSTR: case DBTYPE_IDISPATCH: case DBTYPE_ERROR: case DBTYPE_BOOL: case DBTYPE_VARIANT: case DBTYPE_IUNKNOWN: case DBTYPE_DECIMAL: case DBTYPE_RESERVED: case DBTYPE_BYTES: case DBTYPE_NUMERIC: case DBTYPE_UDT: case DBTYPE_DBDATE: case DBTYPE_DBTIME: case DBTYPE_DBTIMESTAMP: default: Assert(FALSE && "CIndex : Data type not supported"); return -1; }
return comp; }
#endif
|