PROPERTY.CPP

//----------------------------------------------------------------------------- 
// Microsoft OLE DB TABLECOPY Sample
// Copyright (C) 1996 By Microsoft Corporation.
//
// @doc
//
// @module PROPERTY.CPP
//
//-----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////
// Includes
//
////////////////////////////////////////////////////////////////////////
#include "WinMain.h"
#include "Property.h"



/////////////////////////////////////////////////////////////////////////////
// HRESULT GetProperty
//
// Get the property information from the data source or object.
// propid specifies the property and propset specifies the property set to which
// propid belongs. The datatype of the property is required for the correct
// coercion of the data
/////////////////////////////////////////////////////////////////////////////
HRESULT GetProperty(IUnknown* pIUnknown, DBPROPID PropertyID, GUID guidPropertySet,
DBPROP** ppProperty)
{
ASSERT(pIUnknown && ppProperty);
HRESULT hr;

IDBProperties* pIDBProperties = NULL;
ICommandProperties* pICommandProperties = NULL;
IRowsetInfo* pIRowsetInfo = NULL;

ULONGcPropSets = 0;
DBPROPSET*rgPropSets = NULL;

const ULONGcPropertyIDSets = 1;
DBPROPIDSETrgPropertyIDSets[cPropertyIDSets];

//SetUp input DBPROPIDSET struct (all static)
rgPropertyIDSets[0].cPropertyIDs = cPropertyIDSets;
rgPropertyIDSets[0].rgPropertyIDs = &PropertyID;
rgPropertyIDSets[0].guidPropertySet = guidPropertySet;

//Need to figure out which Interface was passed in
//IDBInitialize, or ICommand, or IRowset, all three allow GetProperties
if(SUCCEEDED(hr = pIUnknown->QueryInterface(IID_IDBProperties,(void **)&pIDBProperties)))
{
//GetProperties
XTESTC(hr = pIDBProperties->GetProperties(cPropertyIDSets, rgPropertyIDSets, &cPropSets, &rgPropSets));
}
else if(SUCCEEDED(hr = pIUnknown->QueryInterface(IID_ICommandProperties,(void **)&pICommandProperties)))
{
//GetProperties
XTESTC(hr = pICommandProperties->GetProperties(cPropertyIDSets, rgPropertyIDSets, &cPropSets, &rgPropSets));
}
else
{
XTESTC(hr = pIUnknown->QueryInterface(IID_IRowsetInfo, (void **)&pIRowsetInfo));

//GetProperties
XTESTC(hr = pIRowsetInfo->GetProperties(cPropertyIDSets, rgPropertyIDSets, &cPropSets, &rgPropSets));
}


//Verify results
ASSERT(cPropSets==1 && rgPropSets!=NULL);
ASSERT(rgPropSets[0].cProperties==1 && rgPropSets[0].rgProperties!=NULL);
ASSERT(rgPropSets[0].rgProperties[0].dwPropertyID == PropertyID);

//Return the property to the user
*ppProperty = rgPropSets[0].rgProperties;


CLEANUP:
//Just Free the outer Struct,
//since we return the inner Property for the user to free
SAFE_FREE(rgPropSets);

SAFE_RELEASE(pIDBProperties);
SAFE_RELEASE(pICommandProperties);
SAFE_RELEASE(pIRowsetInfo);
return hr;
}

/////////////////////////////////////////////////////////////////////////////
// HRESULT GetProperty
//
/////////////////////////////////////////////////////////////////////////////
HRESULT GetProperty(IUnknown* pIUnknown, DBPROPID PropertyID, GUID guidPropertySet,WCHAR** ppwszValue)
{
ASSERT(pIUnknown && ppwszValue);
HRESULT hr;

DBPROP* pProperty = NULL;

TESTC(hr = GetProperty(pIUnknown, PropertyID, guidPropertySet, &pProperty));

//Copy the value
ASSERT(pProperty->vValue.vt == VT_BSTR);
*ppwszValue = wcsDuplicate(V_BSTR(&pProperty->vValue));

CLEANUP:
FreeProperties(1, pProperty);
return hr;
}

/////////////////////////////////////////////////////////////////////////////
// HRESULT GetProperty
//
/////////////////////////////////////////////////////////////////////////////
HRESULT GetProperty(IUnknown* pIUnknown, DBPROPID PropertyID, GUID guidPropertySet,WCHAR* pwszValue)
{
ASSERT(pIUnknown && pwszValue);
HRESULT hr;

DBPROP* pProperty = NULL;

TESTC(hr = GetProperty(pIUnknown, PropertyID, guidPropertySet, &pProperty));

//Copy the value
ASSERT(pProperty->vValue.vt == VT_BSTR);
wcscpy(pwszValue, V_BSTR(&pProperty->vValue));

CLEANUP:
FreeProperties(1, pProperty);
return hr;
}

/////////////////////////////////////////////////////////////////////////////
// HRESULT GetProperty
//
/////////////////////////////////////////////////////////////////////////////
HRESULT GetProperty(IUnknown* pIUnknown, DBPROPID PropertyID, GUID guidPropertySet,ULONG* pcValue)
{
ASSERT(pIUnknown && pcValue);
HRESULT hr;

DBPROP* pProperty = NULL;

TESTC(hr = GetProperty(pIUnknown, PropertyID, guidPropertySet, &pProperty));

//Copy the value
ASSERT(pProperty->vValue.vt == VT_I4);
*pcValue = V_I4(&pProperty->vValue);

CLEANUP:
FreeProperties(1, pProperty);
return hr;
}

/////////////////////////////////////////////////////////////////////////////
// HRESULT GetProperty
//
/////////////////////////////////////////////////////////////////////////////
HRESULT GetProperty(IUnknown* pIUnknown, DBPROPID PropertyID, GUID guidPropertySet,BOOL* pbValue)
{
ASSERT(pIUnknown && pbValue);
HRESULT hr;

DBPROP* pProperty = NULL;

TESTC(hr = GetProperty(pIUnknown, PropertyID, guidPropertySet, &pProperty));

//Copy the value
ASSERT(pProperty->vValue.vt == VT_BOOL);
*pbValue = V_BOOL(&pProperty->vValue) == VARIANT_TRUE;

CLEANUP:
FreeProperties(1, pProperty);
return hr;
}


/////////////////////////////////////////////////////////////////////////////
// HRESULT FreeVariants
//
/////////////////////////////////////////////////////////////////////////////
HRESULT FreeVariants(ULONG cVariants, VARIANT* rgVariants)
{
HRESULT hr = S_OK;

//Free the inner variants first
for(ULONG i=0; i<cVariants; i++)
TEST(hr = VariantClear(&rgVariants[i]));

return hr;
}

/////////////////////////////////////////////////////////////////////////////
// HRESULT InitVariants
//
/////////////////////////////////////////////////////////////////////////////
HRESULT InitVariants(ULONG cVariants, VARIANT* rgVariants)
{
HRESULT hr = S_OK;

//Free all variants
for(ULONG i=0; i<cVariants; i++)
VariantInit(&rgVariants[i]);

return hr;
}

/////////////////////////////////////////////////////////////////////////////
// HRESULT FreeProperties
//
/////////////////////////////////////////////////////////////////////////////
HRESULT FreeProperties(ULONG cProperties, DBPROP* rgProperties)
{
HRESULT hr = S_OK;

//Free the inner variants first
for(ULONG i=0; i<cProperties; i++)
TEST(hr = VariantClear(&rgProperties[i].vValue));

//Now free the set
SAFE_FREE(rgProperties);
return hr;
}

/////////////////////////////////////////////////////////////////////////////
// HRESULT FreeProperties
//
/////////////////////////////////////////////////////////////////////////////
HRESULT FreeProperties(ULONG cPropSets, DBPROPSET* rgPropSets)
{
HRESULT hr = S_OK;

//Loop over all the property sets
for(ULONG i=0; i<cPropSets; i++)
TEST(hr = FreeProperties(rgPropSets[i].cProperties, rgPropSets[i].rgProperties));

//Now free the outer set
SAFE_FREE(rgPropSets);
return hr;
}