8823 lines
254 KiB
C++
8823 lines
254 KiB
C++
//--------------------------------------------------------------------
|
|
// Microsoft OLE DB Test
|
|
//
|
|
// Copyright 1995-2000 Microsoft Corporation.
|
|
//
|
|
// @doc
|
|
//
|
|
// @module ISrcRow.CPP | Template source file for all test modules.
|
|
//
|
|
|
|
#include "modstandard.hpp"
|
|
#define DBINITCONSTANTS // Must be defined to initialize constants in OLEDB.H
|
|
#define INITGUID
|
|
#include <process.h>
|
|
#include "ISrcRow.h"
|
|
|
|
|
|
const ULONG nThreads=15;
|
|
unsigned WINAPI ThreadProc(LPVOID lpvThreadParam);
|
|
|
|
class CSourcesRowset;
|
|
typedef struct inparam{
|
|
ULONG i;
|
|
CSourcesRowset *pObject;
|
|
} CInParam;
|
|
|
|
//macros
|
|
#define FILL_PROP_SET(RGPROPSET_EL, NPROP, RGPROP, PROP_GUID) \
|
|
RGPROPSET_EL.cProperties = NPROP; \
|
|
RGPROPSET_EL.rgProperties = RGPROP; \
|
|
RGPROPSET_EL.guidPropertySet = PROP_GUID; \
|
|
if (NULL != RGPROP) \
|
|
memset(RGPROP, 0, NPROP*sizeof(DBPROP));
|
|
|
|
#define FILL_PROP(RGPROP_EL, PROPID, VAR_TYPE, VAR_MACRO, VAR_VALUE, OPTION) \
|
|
memset(&RGPROP_EL, 0, sizeof(DBPROP)); \
|
|
RGPROP_EL.dwPropertyID = PROPID; \
|
|
RGPROP_EL.vValue.vt = VAR_TYPE; \
|
|
VAR_MACRO(&RGPROP_EL.vValue) = VAR_VALUE; \
|
|
RGPROP_EL.dwOptions = OPTION;
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Module Values
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// {{ TCW_MODULE_GLOBALS
|
|
DECLARE_MODULE_CLSID = { 0xf6542601, 0x0bf4, 0x11d0, { 0xa5, 0x5b, 0x00, 0xa0, 0xc9, 0x0d, 0x60, 0x52 }};
|
|
DECLARE_MODULE_NAME("ISourcesRowset");
|
|
DECLARE_MODULE_OWNER("Microsoft");
|
|
DECLARE_MODULE_DESCRIP("Test for ISourcesRowset");
|
|
DECLARE_MODULE_VERSION(795921705);
|
|
// TCW_WizardVersion(2)
|
|
// TCW_Automation(True)
|
|
// }} TCW_MODULE_GLOBALS_END
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Globals
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
// @gmember Supported property marker
|
|
struct DBPropMark
|
|
{
|
|
PROP_STATUS status;
|
|
//BOOL settable;
|
|
DBPROPID dwPropertyID;
|
|
};
|
|
|
|
// @gmember Supported property marker
|
|
DBPropMark* g_PropMark = NULL;
|
|
// @gmember The name of each column, skip the bookmark column
|
|
WCHAR* g_rgwszColumnName[] = { L"SOURCES_NAME", L"SOURCES_PARSENAME", L"SOURCES_DESCRIPTION", L"SOURCES_TYPE", L"SOURCES_ISPARENT", L"SOURCES_CLSID" };
|
|
// @gmember The type of each column, skip the bookmark column
|
|
DBTYPE g_ColumnType[] = {DBTYPE_WSTR, DBTYPE_WSTR, DBTYPE_WSTR, DBTYPE_UI2, DBTYPE_BOOL, DBTYPE_WSTR};
|
|
// @gmember An array hold SOURCE TYPE from the Registry
|
|
USHORT g_SourceType[ROW_COUNT];
|
|
// @gmember count of clsid that are both enum & dso
|
|
ULONG g_cDSOANDENUM = 0;
|
|
// @gmember An array hold SOURCES_NAME from the Registry
|
|
WCHAR g_rgwszSourceName[ROW_COUNT][REG_BUFFER];
|
|
// @gmember An array hold SOURCES_PARSENAME from the Registry
|
|
WCHAR g_rgwszSourceParseName[ROW_COUNT][REG_BUFFER];
|
|
// @gmember An array hold SOURCES_DESCRIPTION from the Registry
|
|
WCHAR g_rgwszSourceDescription[ROW_COUNT][REG_BUFFER];
|
|
// @gmember Counter of the OLE DB Enumerator and Provider entries in the Registry
|
|
ULONG g_cTotalEntries = 0;
|
|
// @gmember Counter of the Providers
|
|
ULONG g_cOLEDBProvNames = 0;
|
|
// @gmember Counter of the Providers
|
|
ULONG g_cOLEDBProvMDPNames = 0;
|
|
// @gmember Counter of the Enumerators
|
|
ULONG g_cOLEDBEnumNames = 0;
|
|
// @gmember Provider name
|
|
WCHAR g_rgwszProvName[MAX_NUM_PROV][REG_BUFFER];
|
|
// @gmember Provider parse name
|
|
WCHAR g_rgwszParseName[MAX_NUM_PROV][REG_BUFFER];
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// Verifies if there are duplicates in the array of strings //
|
|
// returns true if no duplicates found, false otherwise //
|
|
///////////////////////////////////////////////////////////////////////
|
|
bool VerifyNoDuplicates(WCHAR** rgNames, ULONG cNames);
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// Read OLE DB Enumerator and Data sources entries from the Registry,//
|
|
// so we can using this infor to check the rowset returned from the //
|
|
// root enumerator source rowset //
|
|
///////////////////////////////////////////////////////////////////////
|
|
BOOL GetEntriesFromRegistry()
|
|
{
|
|
HKEY hKey1, hKey2, hKey3;
|
|
TCHAR tszSrcName[REG_BUFFER];
|
|
TCHAR tszDesc[REG_BUFFER];
|
|
TCHAR tszQuery[REG_BUFFER];
|
|
TCHAR tszNameCLSID[REG_BUFFER];
|
|
TCHAR tszClsid[REG_BUFFER];
|
|
TCHAR tszProvOrEnum[REG_BUFFER];
|
|
TCHAR tszProvName[REG_BUFFER];
|
|
TCHAR tszProvNameMDP[REG_BUFFER];
|
|
TCHAR tszEnumName[REG_BUFFER];
|
|
DWORD initSize = REG_BUFFER * sizeof(TCHAR);
|
|
DWORD cbName = initSize;
|
|
DWORD cbValue = initSize;
|
|
ULONG index1 = 0;
|
|
ULONG index2;
|
|
ULONG arrayIndex = 0;
|
|
BOOL Result = TRUE;
|
|
BOOL fDSOANDENUM = FALSE; //flag to used to check if a clsid has already been read as a datasource or as a enumerator
|
|
|
|
// We are searching for the entries of OLE DB providers and enumerators
|
|
_tcscpy(tszNameCLSID, _T("CLSID"));
|
|
_tcscpy(tszProvName, _T("OLE DB Provider"));
|
|
_tcscpy(tszProvNameMDP, _T("OLE DB MD Provider"));
|
|
_tcscpy(tszEnumName, _T("OLE DB Enumerator"));
|
|
// In the Registry it is "No name", so we set an empty string
|
|
_tcscpy(tszQuery, _T(""));
|
|
|
|
// need to set g_cDSOANDENUM to 0
|
|
// if the test is run several times under ltm
|
|
// the global variables are not reinitialized
|
|
g_cDSOANDENUM = 0;
|
|
// Open CLSID subkey first
|
|
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, tszNameCLSID, 0,
|
|
KEY_READ, &hKey1) == ERROR_SUCCESS)
|
|
{
|
|
// Enumerate CLSID subkey
|
|
while(RegEnumKeyEx(hKey1, index1++, tszClsid,
|
|
&cbName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
|
{
|
|
// Have to reset the buffer size
|
|
cbName=initSize;
|
|
|
|
//reset flag
|
|
fDSOANDENUM = FALSE;
|
|
|
|
// Open clsid subkey under CLSID subkey
|
|
if (RegOpenKeyEx(hKey1, tszClsid, 0, KEY_READ, &hKey2) == ERROR_SUCCESS)
|
|
{
|
|
// The clsid of this key would be the value of SOURCES_PARSENAME in sources rowet
|
|
// The value of this key would be the value of SOURCES_NAME in sources rowet
|
|
// so I will query this value first.
|
|
// If this entry is not what we want, the value will be overwritten later.
|
|
// If this entry is what we want, the value will be recorded right away.
|
|
RegQueryValueEx(hKey2,tszQuery,NULL,NULL,(LPBYTE)tszSrcName,&cbValue);
|
|
|
|
// Reset the buffer size
|
|
cbValue = initSize;
|
|
index2=0;
|
|
|
|
// Enumerate subsubkey under clsid subkey
|
|
while(RegEnumKeyEx(hKey2, index2++, tszProvOrEnum,
|
|
&cbName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
|
{
|
|
// Reset buffer size
|
|
cbName = initSize;
|
|
|
|
// If we find an OLE DB provider or enumerator, record it.
|
|
if ( (!_tcscmp(tszProvOrEnum, tszProvNameMDP)) ||
|
|
(!_tcscmp(tszProvOrEnum, tszProvName)) ||
|
|
(!_tcscmp(tszProvOrEnum, tszEnumName))
|
|
)
|
|
{
|
|
//if this flag is true then this clsid has already been marked as either a dos or as a enum
|
|
//count it
|
|
if (fDSOANDENUM)
|
|
{
|
|
g_cDSOANDENUM++;
|
|
}
|
|
fDSOANDENUM = TRUE;
|
|
|
|
if (!_tcscmp(tszProvOrEnum, tszProvName))
|
|
{
|
|
g_SourceType[arrayIndex] = DBSOURCETYPE_DATASOURCE;
|
|
g_cOLEDBProvNames++;
|
|
}
|
|
if (!_tcscmp(tszProvOrEnum, tszProvNameMDP))
|
|
{
|
|
g_SourceType[arrayIndex] = DBSOURCETYPE_DATASOURCE_MDP;
|
|
g_cOLEDBProvMDPNames++;
|
|
}
|
|
if (!_tcscmp(tszProvOrEnum, tszEnumName))
|
|
{
|
|
g_SourceType[arrayIndex] = DBSOURCETYPE_ENUMERATOR;
|
|
g_cOLEDBEnumNames++;
|
|
}
|
|
|
|
// Count it
|
|
g_cTotalEntries++;
|
|
|
|
// Open it and get the value,
|
|
if (RegOpenKeyEx(hKey2, tszProvOrEnum, 0, KEY_READ, &hKey3) != ERROR_SUCCESS)
|
|
Result = FALSE;
|
|
|
|
// The value of this key would be the value of SOURCES_DESCRIPTION in sources rowet
|
|
if(RegQueryValueEx(hKey3,tszQuery,NULL,NULL,(LPBYTE)tszDesc,&cbValue) != ERROR_SUCCESS)
|
|
Result = FALSE;
|
|
|
|
// If we query the values properly
|
|
if (Result)
|
|
{
|
|
// Record all these values for checking the row info later
|
|
#ifdef _UNICODE
|
|
wcscpy(g_rgwszSourceName[arrayIndex],tszSrcName);
|
|
wcscpy(g_rgwszSourceParseName[arrayIndex],tszClsid);
|
|
wcscpy(g_rgwszSourceDescription[arrayIndex],tszDesc);
|
|
#else
|
|
MultiByteToWideChar(CP_ACP,0,tszSrcName,-1,g_rgwszSourceName[arrayIndex],REG_BUFFER);
|
|
MultiByteToWideChar(CP_ACP,0,tszClsid,-1,g_rgwszSourceParseName[arrayIndex],REG_BUFFER);
|
|
MultiByteToWideChar(CP_ACP,0,tszDesc,-1,g_rgwszSourceDescription[arrayIndex],REG_BUFFER);
|
|
#endif //_UNICODE
|
|
}
|
|
else
|
|
break;
|
|
|
|
// Increment index to record the column data of the next row
|
|
arrayIndex++;
|
|
|
|
// Reset buffersize and close registry key
|
|
cbValue = initSize;
|
|
RegCloseKey(hKey3);
|
|
}
|
|
}
|
|
|
|
// Close registry key
|
|
RegCloseKey(hKey2);
|
|
}
|
|
else
|
|
Result = FALSE;
|
|
}
|
|
|
|
// Close registry key
|
|
RegCloseKey(hKey1);
|
|
}
|
|
else
|
|
return TRUE;
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Mark properties surpported //
|
|
///////////////////////////////////////////////////////////////
|
|
BOOL MarkSupportedProperties(const GUID clsid = CLSID_OLEDB_ENUMERATOR)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = E_FAIL;
|
|
ULONG ulIndex = 0;
|
|
ISourcesRowset *pISrcRow = NULL;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
// Setup the input param DBPROPIDSET
|
|
ULONG cPropSets = 0;
|
|
DBPROPSET *rgPropSets = NULL;
|
|
DBPROPIDSET rgPropIDSets;
|
|
|
|
// Right now I focus on VT_BOOL type properties
|
|
DBPROPID dbPropid[PROPERTY_COUNT] = {
|
|
DBPROP_DEFERRED,
|
|
DBPROP_BOOKMARKS,
|
|
DBPROP_CACHEDEFERRED,
|
|
DBPROP_CANFETCHBACKWARDS,
|
|
DBPROP_CANHOLDROWS,
|
|
DBPROP_CANSCROLLBACKWARDS,
|
|
DBPROP_CHANGEINSERTEDROWS,
|
|
DBPROP_COLUMNRESTRICT,
|
|
DBPROP_IRowsetChange,
|
|
DBPROP_IRowsetIdentity,
|
|
DBPROP_IRowsetLocate,
|
|
DBPROP_IRowsetScroll,
|
|
DBPROP_IRowsetUpdate,
|
|
DBPROP_LITERALIDENTITY,
|
|
DBPROP_OTHERINSERT,
|
|
DBPROP_QUICKRESTART,
|
|
DBPROP_ROWRESTRICT,
|
|
DBPROP_TRANSACTEDOBJECT,
|
|
DBPROP_UPDATABILITY,
|
|
DBPROP_APPENDONLY,
|
|
};
|
|
|
|
// Create an enumerator object
|
|
TESTC_(hr=CoCreateInstance(clsid, NULL,
|
|
GetModInfo()->GetClassContext(), IID_ISourcesRowset,(void **)&pISrcRow), S_OK);
|
|
|
|
// Open sources rowset
|
|
TESTC_(hr=pISrcRow->GetSourcesRowset(NULL, IID_IRowsetInfo,
|
|
0, NULL, (IUnknown**)&pIRowsetInfo), S_OK);
|
|
|
|
TESTC(NULL != pIRowsetInfo);
|
|
|
|
// Copy the Properties to the Global
|
|
for(ulIndex=0; ulIndex < PROPERTY_COUNT; ulIndex++)
|
|
{
|
|
g_PropMark[ulIndex].dwPropertyID = dbPropid[ulIndex];
|
|
|
|
// find out whether the prop is supported or not
|
|
rgPropIDSets.rgPropertyIDs = &dbPropid[ulIndex];
|
|
rgPropIDSets.guidPropertySet = DBPROPSET_ROWSET;
|
|
rgPropIDSets.cPropertyIDs = 1;
|
|
|
|
// If the Property is VARIANT_TRUE
|
|
hr = pIRowsetInfo->GetProperties(1, &rgPropIDSets, &cPropSets, &rgPropSets);
|
|
if (COMPARE(NULL != rgPropSets, TRUE) && COMPARE(cPropSets, 1))
|
|
{
|
|
if (DBPROPSTATUS_OK == rgPropSets[0].rgProperties[0].dwStatus && CHECK(hr, S_OK))
|
|
g_PropMark[ulIndex].status = SUPPORTED;
|
|
else
|
|
{
|
|
COMPARE(rgPropSets[0].rgProperties[0].dwStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
g_PropMark[ulIndex].status = NOTSUPPORTED;
|
|
}
|
|
}
|
|
FreeProperties(&cPropSets,&rgPropSets);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
// Release the objects
|
|
SAFE_RELEASE(pISrcRow);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
TRETURN
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level initialization routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleInit(CThisTestModule * m_pThisTestModule)
|
|
{
|
|
g_cOLEDBProvNames = 0;
|
|
g_cOLEDBProvMDPNames = 0;
|
|
g_cOLEDBEnumNames = 0;
|
|
g_cTotalEntries = 0;
|
|
|
|
//Must either call CreateModInfo or CreateModuleDBSession before any testing
|
|
if(!CreateModInfo(m_pThisTestModule))
|
|
return FALSE;
|
|
|
|
g_PropMark = (DBPropMark*)PROVIDER_ALLOC(PROPERTY_COUNT * sizeof(DBPropMark));
|
|
if (!g_PropMark)
|
|
{
|
|
odtLog << wszMemoryAllocationError;
|
|
return FALSE;
|
|
}
|
|
|
|
// Initialize the buffer to 0's
|
|
memset(g_PropMark, 0, PROPERTY_COUNT * sizeof(DBPropMark));
|
|
|
|
// Read OLE DB enumerator and provider entries from the Registry
|
|
// Mark all supported properties from the Rowset property group
|
|
if (GetEntriesFromRegistry())
|
|
return MarkSupportedProperties();
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level termination routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleTerminate(CThisTestModule * m_pThisTestModule)
|
|
{
|
|
// Release memory and OLE memory allocator
|
|
PROVIDER_FREE(g_PropMark);
|
|
|
|
//Init
|
|
g_cOLEDBProvNames = 0;
|
|
g_cOLEDBProvMDPNames = 0;
|
|
g_cOLEDBEnumNames = 0;
|
|
g_cTotalEntries = 0;
|
|
return ReleaseModInfo(m_pThisTestModule);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Base Class Section
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
class CSourcesRowset : public COLEDB {
|
|
public:
|
|
CSourcesRowset(WCHAR* pwszTestCaseName = NULL);
|
|
~CSourcesRowset(){};
|
|
|
|
protected:
|
|
// @cmember enumerator class id
|
|
CLSID m_clsid;
|
|
// @cmember pointer to ISourcesRowset
|
|
ISourcesRowset * m_pISrcRow;
|
|
// @cmember pointer to IColumnsInfo
|
|
IColumnsInfo * m_pIColumnsInfo;
|
|
// @cmember pointer to IRowset
|
|
IRowset * m_pIRowset;
|
|
// @cmember pointer to IRowsetInfo
|
|
IRowsetInfo * m_pIRowsetInfo;
|
|
// @cmember pointer to IAccessor
|
|
IAccessor * m_pIAccessor;
|
|
// @cmember accessory handle
|
|
HACCESSOR m_hAccessor;
|
|
// @cmember pointer to the row buffer
|
|
void * m_pData;
|
|
// @cmember size of a row
|
|
DBLENGTH m_cRowSize;
|
|
// @cmember count of binding structure
|
|
DBCOUNTITEM m_cBinding;
|
|
// @cmember array of binding strucuture
|
|
DBBINDING * m_rgBinding;
|
|
// @cmember Array of property
|
|
DBPROP m_rgDBProp[MAXPROP];
|
|
// @cmember Array of Property Sets
|
|
DBPROPSET m_rgDBPropSets[MAXPROP];
|
|
// @cmember Count of Property Sets
|
|
ULONG m_cDBPropSets;
|
|
// @cmember Count of DBPROPINFOSETs
|
|
ULONG m_cDBPropInfoSets;
|
|
// @cmember Count of column
|
|
DBORDINAL m_cColumns;
|
|
// @cmember Count of column
|
|
DBCOUNTITEM m_cRows;
|
|
// @cmember An array of DBCOLUMNINFO
|
|
DBCOLUMNINFO * m_rgInfo;
|
|
// @cmember String buffer
|
|
WCHAR * m_pStringsBuffer;
|
|
// @cmember Count of Bindings
|
|
DBCOUNTITEM m_cDBBINDING;
|
|
// @cmember Count of columns in rowset
|
|
DBORDINAL m_cDBCOLUMNINFO;
|
|
// @cmember Count of supported properties
|
|
ULONG m_cSupportedProp;
|
|
|
|
// @cmember array of return values for threads
|
|
HRESULT m_rgResult[nThreads];
|
|
// @cmember array of number of rows in the rowset for each thread
|
|
ULONG m_rgRowsNo[nThreads];
|
|
// @cmember array of rowset interfaces for each thread
|
|
IRowset *m_rgRowset[nThreads];
|
|
|
|
WCHAR** m_rgSourcesNames[nThreads];
|
|
ULONG m_rgMaxSourcesNames[nThreads];
|
|
|
|
|
|
|
|
// methods
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
// @cmember SupportedProperty
|
|
//
|
|
// This function should return TRUE if the fuction succeeded and
|
|
// the property is supported by the Provider.
|
|
BOOL SupportedProperty(
|
|
DBPROPID PropertyID,
|
|
const GUID guidPropertySet,
|
|
IUnknown* pIUnknown,
|
|
EINTERFACE eCoType = DATASOURCE_INTERFACE
|
|
);
|
|
|
|
|
|
// @cmember SettableProperty
|
|
//
|
|
// This function should return TRUE if the fuction succeeded and
|
|
// the property is settable by the Provider.
|
|
BOOL SettableProperty(
|
|
DBPROPID PropertyID,
|
|
GUID guidPropertySet,
|
|
IUnknown* pIUnknown,
|
|
EINTERFACE eCoType = DATASOURCE_INTERFACE
|
|
);
|
|
|
|
// @cmember Set one property from rowset property group
|
|
void SetOneProperty(
|
|
DBPROPID dwPropertyID,
|
|
DBPROPOPTIONS dwOptions,
|
|
ULONG index,
|
|
VARENUM eType = VT_BOOL
|
|
);
|
|
// @cmember Check column info of the sources rowset
|
|
BOOL CheckColumnsInfo(ULONG ColCount, IUnknown *pRowset);
|
|
// @cmember Check rowset info of the sources rowset
|
|
BOOL CheckRowsInfo();
|
|
// @cmember Read Parse Name from sourse Rowset of an enumerator
|
|
BOOL ReadParseName(const CLSID clsid);
|
|
// @cmember Compare data in each column in one row
|
|
BOOL CompareData(ULONG *pcRowIndex);
|
|
// @cmember Free accessor handle and binding structure memories
|
|
BOOL FreeAccessorAndBindings();
|
|
// @cmember Check whether the property DBPROP_CANHOLDROWS is supported
|
|
BOOL NoHoldRows(IRowset *pIRowset);
|
|
// @cmember Check whether the IParseDisplayName is valid
|
|
BOOL VerifyParseDisplayName_root(IParseDisplayName *pIParseDisplayName);
|
|
// @cmember Check whether the IParseDisplayName is valid
|
|
BOOL VerifyParseDisplayName_std(IParseDisplayName *pIParseDisplayName);
|
|
// @cmember Tries calling GetNextRows without releasing all row handles
|
|
ULONG GetNextRowsWithoutRelAllRows();
|
|
// @cmember Verify how an invalid colid is treated
|
|
ULONG VerifyInvalidColID(DBPROPOPTIONS);
|
|
// @cmember Verify how an non rowset property set is treated
|
|
ULONG VerifyNonRowsetPropSet(ULONG);
|
|
|
|
// @cmember Verify aggregation on sources rowset, ask for something different from IID_IUnknown => DB_E_NOAGGREGATION
|
|
BOOL VerifyNotIUnknownInAggregation();
|
|
// @cmember Verify sources rowset aggregation
|
|
BOOL VerifySourcesRowsetAggregation();
|
|
// @cmember Verify IRowsetInfo::GetSpecification on sources rowset, aggregated enumerator
|
|
BOOL VerifyGetSpec_AggregatedEnum();
|
|
|
|
// @cmember Count the number of rows in the rowset (assume init position)
|
|
HRESULT CountNoOfRows(IRowset *pIRowset, ULONG *pulRowsNo);
|
|
HRESULT CountNoOfRowsAndGetSourcesNames(IRowset *pIRowset, ULONG *pulRowsNo, WCHAR** rgwszSourcesNames, ULONG cMaxSourcesNames);
|
|
|
|
|
|
// @cmember Execute the thread method
|
|
unsigned virtual MyThreadProc(ULONG iThread);
|
|
unsigned virtual MyThreadProc2(ULONG iThread);
|
|
|
|
friend unsigned WINAPI ThreadProc(LPVOID lpvThreadParam);
|
|
friend unsigned WINAPI ThreadProc2(LPVOID lpvThreadParam);
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Constructor //
|
|
///////////////////////////////////////////////////////////////
|
|
CSourcesRowset::CSourcesRowset(WCHAR* pwszTestCaseName) : COLEDB(pwszTestCaseName)
|
|
{
|
|
m_pISrcRow = NULL;
|
|
m_pIColumnsInfo = NULL;
|
|
m_pIRowset = NULL;
|
|
m_pIRowsetInfo = NULL;
|
|
m_pIAccessor = NULL;
|
|
m_cColumns = 0;
|
|
m_cRows = 0;
|
|
m_cRowSize = 0;
|
|
m_cDBPropSets = 0;
|
|
m_cDBPropInfoSets=0;
|
|
m_cDBBINDING = 0;
|
|
m_cDBCOLUMNINFO = 0;
|
|
m_cSupportedProp= 0;
|
|
m_cBinding = 0;
|
|
m_rgBinding = NULL;
|
|
m_pData = NULL;
|
|
m_rgInfo = NULL;
|
|
m_pStringsBuffer= NULL;
|
|
m_hAccessor = DB_NULL_HACCESSOR;
|
|
m_clsid = CLSID_OLEDB_ENUMERATOR;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Initialization //
|
|
///////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::Init()
|
|
{
|
|
return COLEDB::Init();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Termination //
|
|
///////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::Terminate()
|
|
{
|
|
return COLEDB::Terminate();
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func BOOL | SupportedProperty
|
|
//
|
|
// This function should return TRUE if the fuction succeeded and
|
|
// the property is supported by the Provider.
|
|
//
|
|
// eCoType defaults to DATASOURCE_INTERFACE in the prototype
|
|
//
|
|
//--------------------------------------------------------------------
|
|
BOOL CSourcesRowset::SupportedProperty(
|
|
DBPROPID PropertyID,
|
|
const GUID guidPropertySet,
|
|
IUnknown* pIUnknown,
|
|
EINTERFACE eCoType
|
|
)
|
|
{
|
|
IDBProperties *pIDBProperties = NULL;
|
|
ULONG cProp;
|
|
DBPROPIDSET rgPropIDSets;
|
|
HRESULT hr;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
DBPROPSET *rgPropSets = NULL;
|
|
ULONG cPropSets = 0;
|
|
BOOL fResult = FALSE;
|
|
|
|
// if a IDBProperties interface can be retrieved, call
|
|
if (VerifyInterface(pIUnknown, IID_IDBProperties, eCoType, (IUnknown**)&pIDBProperties))
|
|
{
|
|
SAFE_RELEASE(pIDBProperties);
|
|
return ::SupportedProperty(PropertyID, guidPropertySet, pIUnknown, eCoType);
|
|
}
|
|
|
|
// if the prop is an already checked one, just return the result
|
|
for (cProp = 0; cProp < PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (g_PropMark[cProp].dwPropertyID == PropertyID)
|
|
return (DBPROPSET_ROWSET == guidPropertySet) && (SUPPORTED == g_PropMark[cProp].status);
|
|
}
|
|
|
|
// make sure the ISourcesRowsetInterface is there
|
|
if (!m_pISrcRow)
|
|
return ::SupportedProperty(PropertyID, guidPropertySet, pIUnknown, eCoType);
|
|
|
|
// find out whether the prop is supported or not
|
|
rgPropIDSets.rgPropertyIDs = &PropertyID;
|
|
rgPropIDSets.guidPropertySet = guidPropertySet;
|
|
rgPropIDSets.cPropertyIDs = 1;
|
|
|
|
// Open sources rowset
|
|
hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetInfo, 0, NULL, (IUnknown**)&pIRowsetInfo);
|
|
TESTC_(hr, S_OK);
|
|
TESTC(NULL != pIRowsetInfo);
|
|
|
|
// If the Property is VARIANT_TRUE
|
|
hr = pIRowsetInfo->GetProperties(1, &rgPropIDSets, &cPropSets, &rgPropSets);
|
|
fResult = COMPARE(NULL != rgPropSets, TRUE) && COMPARE(cPropSets, 1)
|
|
&& (DBPROPSTATUS_OK == rgPropSets[0].rgProperties[0].dwStatus);
|
|
|
|
CLEANUP:
|
|
FreeProperties(&cPropSets,&rgPropSets);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
return fResult;
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func BOOL | SettableProperty
|
|
//
|
|
// This function should return TRUE if the fuction succeeded and
|
|
// the property is settable by the Provider.
|
|
//
|
|
// eCoType defaults to DATASOURCE_INTERFACE in the prototype
|
|
//
|
|
//--------------------------------------------------------------------
|
|
BOOL CSourcesRowset::SettableProperty(
|
|
DBPROPID PropertyID,
|
|
GUID guidPropertySet,
|
|
IUnknown* pIUnknown,
|
|
EINTERFACE eCoType
|
|
)
|
|
{
|
|
IDBProperties *pIDBProperties = NULL;
|
|
HRESULT hr;
|
|
DBPROPSET rgPropSets;
|
|
DBPROP rgProp;
|
|
BOOL fResult = FALSE;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
VARIANT vValue;
|
|
|
|
if (!SupportedProperty(PropertyID, guidPropertySet, pIUnknown, eCoType))
|
|
return FALSE;
|
|
|
|
// if a IDBProperties interface can be retrieved, call
|
|
if (VerifyInterface(pIUnknown, IID_IDBProperties, eCoType, (IUnknown**)&pIDBProperties))
|
|
{
|
|
fResult = ::SettableProperty(PropertyID, guidPropertySet, pIUnknown, eCoType);
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// make sure the ISourcesRowsetInterface is there
|
|
if (!m_pISrcRow)
|
|
return ::SupportedProperty(PropertyID, guidPropertySet, pIUnknown, eCoType);
|
|
|
|
// Open sources rowset
|
|
TESTC_(hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetInfo,
|
|
0, NULL, (IUnknown**)&pIRowsetInfo), S_OK);
|
|
VariantInit(&vValue);
|
|
TESTC(GetProperty(PropertyID, guidPropertySet, pIRowsetInfo, &vValue));
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
|
|
// find out whether the prop is supported or not
|
|
rgPropSets.rgProperties = &rgProp;
|
|
rgPropSets.cProperties = 1;
|
|
rgPropSets.guidPropertySet = guidPropertySet;
|
|
|
|
rgProp.dwPropertyID = PropertyID;
|
|
rgProp.dwOptions = DBPROPOPTIONS_REQUIRED;
|
|
rgProp.colid = DB_NULLID;
|
|
rgProp.vValue.vt = vValue.vt;
|
|
if (VT_BOOL == vValue.vt)
|
|
rgProp.vValue.boolVal = VARIANT_TRUE == vValue.boolVal? VARIANT_FALSE: VARIANT_TRUE; // anything else than what seems to be the default value
|
|
else
|
|
rgProp.vValue.intVal = vValue.intVal + 11; // anything else than what seems to be the default value
|
|
|
|
TESTC(VT_I4 == vValue.vt || VT_BOOL == vValue.vt);
|
|
|
|
// Open sources rowset
|
|
hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetInfo, 1, &rgPropSets, (IUnknown**)&pIRowsetInfo);
|
|
|
|
fResult = (DBPROPSTATUS_NOTSUPPORTED != rgPropSets.rgProperties[0].dwStatus)
|
|
&& (DBPROPSTATUS_NOTSETTABLE != rgPropSets.rgProperties[0].dwStatus)
|
|
&& (DBPROPSTATUS_NOTALLSETTABLE != rgPropSets.rgProperties[0].dwStatus)
|
|
&& (DBPROPSTATUS_NOTSET != rgPropSets.rgProperties[0].dwStatus)
|
|
&& (DBPROPSTATUS_BADVALUE != rgPropSets.rgProperties[0].dwStatus);
|
|
|
|
if (S_OK != hr)
|
|
TESTC_(hr, DB_E_ERRORSOCCURRED);
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBProperties);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
return fResult;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// set one property from rowset property group. Right now we//
|
|
// only set property with BOOL value //
|
|
///////////////////////////////////////////////////////////////
|
|
void CSourcesRowset::SetOneProperty(
|
|
DBPROPID dwPropertyID,
|
|
DBPROPOPTIONS dwOptions,
|
|
ULONG index,
|
|
VARENUM eType
|
|
)
|
|
{
|
|
ASSERT(index<MAXPROP);
|
|
m_rgDBProp[index].dwPropertyID = dwPropertyID;
|
|
m_rgDBProp[index].dwOptions = dwOptions;
|
|
m_rgDBProp[index].colid = DB_NULLID;
|
|
m_rgDBProp[index].vValue.vt = eType;
|
|
switch (eType)
|
|
{
|
|
case VT_I4:
|
|
V_I4(&(m_rgDBProp[index].vValue)) = rand();
|
|
break;
|
|
default:
|
|
V_BOOL(&(m_rgDBProp[index].vValue)) = VARIANT_FALSE;
|
|
}
|
|
|
|
m_cDBPropSets = 1;
|
|
m_rgDBPropSets[0].guidPropertySet = DBPROPSET_ROWSET;
|
|
m_rgDBPropSets[0].cProperties = index+1;
|
|
m_rgDBPropSets[0].rgProperties = m_rgDBProp;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Check column information of the sources rowset //
|
|
///////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::CheckColumnsInfo(ULONG ColCount, IUnknown *pRowset)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
ULONG cCol;
|
|
ULONG cOrdinal;
|
|
|
|
// Make sure we have valid pointer
|
|
TESTC(NULL != pRowset);
|
|
|
|
// Get a IColumnsInfo pointer
|
|
TESTC(VerifyInterface(pRowset, IID_IColumnsInfo,
|
|
ROWSET_INTERFACE,(IUnknown **)&m_pIColumnsInfo));
|
|
|
|
TESTC_(m_pIColumnsInfo->GetColumnInfo(&m_cColumns, &m_rgInfo, &m_pStringsBuffer), S_OK);
|
|
|
|
// Check to see if the Bookmark Property is on
|
|
if (!m_rgInfo[0].iOrdinal)
|
|
{
|
|
TESTC(GetProperty(DBPROP_BOOKMARKS, DBPROPSET_ROWSET, pRowset));
|
|
TESTC(m_cColumns == ColCount);
|
|
}
|
|
else
|
|
TESTC(m_cColumns == ColCount-1);
|
|
|
|
cCol = (0 == m_rgInfo[0].iOrdinal) ? 1 : 0;
|
|
cOrdinal = 1;
|
|
|
|
// if there is a bookmark column then Skip the bookmark column
|
|
for(; cCol < m_cColumns; cCol++, cOrdinal++)
|
|
{
|
|
if (!memcmp(m_rgInfo[cCol].pwszName,
|
|
g_rgwszColumnName[cOrdinal-1], sizeof(g_rgwszColumnName[cOrdinal-1])))
|
|
{
|
|
TESTC(m_rgInfo[cCol].iOrdinal == cOrdinal);
|
|
TESTC(m_rgInfo[cCol].wType == g_ColumnType[cOrdinal-1]);
|
|
}
|
|
}
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(m_pStringsBuffer);
|
|
SAFE_FREE(m_rgInfo);
|
|
SAFE_RELEASE(m_pIColumnsInfo);
|
|
return fResult;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Check row information of the sources rowset //
|
|
// 1. Get accessor and bindings. //
|
|
// 2. Compare the data in each column row by row to make //
|
|
// sure that the entries we are interested in are in the//
|
|
// rowset returned. //
|
|
///////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::CheckRowsInfo()
|
|
{
|
|
BOOL fResult = FALSE;
|
|
HROW hRow[1] = {NULL};
|
|
HROW *pHRow = hRow;
|
|
DBCOUNTITEM cRow = 0;
|
|
ULONG cRowIndex = 0;
|
|
BOOL *frgPresentSrc = NULL;
|
|
ULONG cFoundRowIndex;
|
|
ULONG cRemainingRows = g_cTotalEntries;
|
|
|
|
// Make sure we have valid pointer
|
|
if (!m_pIRowset)
|
|
return FALSE;
|
|
|
|
// Create an accessor on the sources rowset and get bindings
|
|
if (!CHECK(GetAccessorAndBindings(m_pIRowset,DBACCESSOR_ROWDATA,&m_hAccessor,
|
|
&m_rgBinding,&m_cBinding,&m_cRowSize,DBPART_VALUE|DBPART_STATUS|DBPART_LENGTH,
|
|
ALL_COLS_BOUND,FORWARD,NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV,DBPARAMIO_NOTPARAM,NO_BLOB_COLS),S_OK))
|
|
return FALSE;
|
|
|
|
// Allocate memory for the row
|
|
SAFE_ALLOC(m_pData, BYTE, m_cRowSize);
|
|
SAFE_ALLOC(frgPresentSrc, BOOL, g_cTotalEntries);
|
|
|
|
for (cRowIndex=0;cRowIndex<g_cTotalEntries;cRowIndex++)
|
|
{
|
|
frgPresentSrc[cRowIndex] = FALSE;
|
|
}
|
|
|
|
m_hr = m_pIRowset->RestartPosition(0);
|
|
|
|
// Loop through the rowset, retrieve one row at a time
|
|
for(cRowIndex=0;cRowIndex<g_cTotalEntries;cRowIndex++)
|
|
{
|
|
// Get the next row
|
|
if (!CHECK(m_pIRowset->GetNextRows(NULL,0,1,&cRow,&pHRow),S_OK))
|
|
break;
|
|
|
|
if (CHECK(m_pIRowset->GetData(hRow[0],m_hAccessor,m_pData), S_OK))
|
|
{
|
|
// Compare the rowset data with the data retrieved from Registry
|
|
fResult = CompareData(&cFoundRowIndex); // if fResult is FALSE break the loop
|
|
if (!COMPARE(cFoundRowIndex == g_cTotalEntries, FALSE))
|
|
fResult = FALSE;
|
|
else
|
|
{
|
|
// check that the source wasn't found before
|
|
if (!frgPresentSrc[cFoundRowIndex])
|
|
{
|
|
// decrease the number of sources not yet found in the rowset
|
|
cRemainingRows--;
|
|
frgPresentSrc[cFoundRowIndex] = TRUE;
|
|
}
|
|
else
|
|
odtLog << "WARNING, " << g_rgwszParseName[cFoundRowIndex]
|
|
<< "already found with the same type!\n";
|
|
}
|
|
}
|
|
|
|
// Release the row handle
|
|
CHECK(m_pIRowset->ReleaseRows(1,hRow,NULL,NULL,NULL),S_OK);
|
|
// if comparison was ok continue the loop
|
|
TESTC(fResult);
|
|
}
|
|
|
|
// The cursor should be at the end of the rowset
|
|
if (fResult)
|
|
CHECK(m_pIRowset->GetNextRows(NULL,0,1,&cRow,&pHRow),DB_S_ENDOFROWSET);
|
|
|
|
CLEANUP:
|
|
// Release the rowset created
|
|
if (!FreeAccessorAndBindings())
|
|
fResult = FALSE;
|
|
SAFE_FREE(frgPresentSrc);
|
|
return fResult && (0 == cRemainingRows);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Compare data in each column of one row //
|
|
///////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::CompareData(ULONG *pcRowIndex)
|
|
{
|
|
BOOL fErrorOccured = FALSE;
|
|
BOOL fCheckForTruncation = FALSE;
|
|
BOOL fCheckForNULL = FALSE;
|
|
BOOL fCheckForLength = FALSE;
|
|
BOOL fColumnError = FALSE;
|
|
void *pConsumerData = NULL;
|
|
ULONG cCount = 0;
|
|
USHORT uswSize = 0;
|
|
LONG lDBTypeSize = 0;
|
|
ULONG cRowIndex = g_cTotalEntries;
|
|
|
|
const ULONG nSrcName = 1;
|
|
const ULONG nSrcParseName = 2;
|
|
const ULONG nSrcDescription = 3;
|
|
const ULONG nSrcType = 4;
|
|
const ULONG nSrcIsParent = 5;
|
|
const ULONG nSrcCLSID = 6;
|
|
|
|
ULONG ulRowIndex;
|
|
WCHAR *wszParseName = NULL;
|
|
unsigned short ulSrcType;
|
|
ULONG cBndgParseName = m_rgBinding[0].iOrdinal? 1: 2;
|
|
ULONG cBndgType = m_rgBinding[0].iOrdinal? 3: 4;
|
|
|
|
|
|
// Input validation
|
|
if ((!m_rgBinding) || (!m_pData) || (!pcRowIndex))
|
|
return FALSE;
|
|
*pcRowIndex = g_cTotalEntries;
|
|
|
|
// identify the datasource/enumerator to be compared against the current row in the sources rowset
|
|
// get the parse name
|
|
// switch (*((DBSTATUS *)(dwAddrData + m_rgBinding[cBndgParseName].obStatus)))
|
|
switch (STATUS_BINDING(m_rgBinding[cBndgParseName],m_pData))
|
|
{
|
|
case DBSTATUS_S_ISNULL:
|
|
break;
|
|
case DBSTATUS_S_OK:
|
|
wszParseName = (WCHAR*)&VALUE_BINDING(m_rgBinding[cBndgParseName],m_pData);
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
// get source type
|
|
if (!COMPARE(STATUS_BINDING(m_rgBinding[cBndgType],m_pData), DBSTATUS_S_OK))
|
|
return FALSE;
|
|
ulSrcType = *(unsigned short*)(&VALUE_BINDING(m_rgBinding[cBndgType],m_pData));
|
|
|
|
// identify the source
|
|
for (ulRowIndex = 0; ulRowIndex < g_cTotalEntries; ulRowIndex++)
|
|
{
|
|
if ( (NULL == wszParseName && NULL != g_rgwszSourceParseName[ulRowIndex])
|
|
|| (NULL != wszParseName && NULL == g_rgwszSourceParseName[ulRowIndex])
|
|
|| (0 != wcscmp(wszParseName, g_rgwszSourceParseName[ulRowIndex])))
|
|
continue;
|
|
// check if the type is the same
|
|
if (g_SourceType[ulRowIndex] != ulSrcType)
|
|
continue;
|
|
// the target source was found
|
|
cRowIndex = ulRowIndex;
|
|
break;
|
|
}
|
|
if (ulRowIndex >= g_cTotalEntries)
|
|
return FALSE;
|
|
|
|
// Compare the data column by column
|
|
// Status, Length, and Valid binding are checked
|
|
for(cCount=0; cCount<m_cBinding; cCount++)
|
|
{
|
|
// If previous bindings have failed exit now
|
|
if (fErrorOccured)
|
|
break;
|
|
|
|
// Init
|
|
fCheckForTruncation = FALSE;
|
|
fCheckForNULL = FALSE;
|
|
fCheckForLength = FALSE;
|
|
fColumnError = FALSE;
|
|
|
|
//////////////////////////////
|
|
// check the status binding //
|
|
//////////////////////////////
|
|
if ((m_rgBinding[cCount].dwPart) & DBPART_STATUS)
|
|
{
|
|
// switch (*((DBSTATUS *)(dwAddrData + m_rgBinding[cCount].obStatus)))
|
|
switch(STATUS_BINDING(m_rgBinding[cCount],m_pData))
|
|
{
|
|
// Return FALSE if any error flags is set.
|
|
case DBSTATUS_E_SIGNMISMATCH:
|
|
case DBSTATUS_E_CANTCONVERTVALUE:
|
|
case DBSTATUS_E_CANTCREATE:
|
|
case DBSTATUS_E_UNAVAILABLE:
|
|
case DBSTATUS_E_DATAOVERFLOW:
|
|
case DBSTATUS_E_BADACCESSOR:
|
|
case DBSTATUS_E_INTEGRITYVIOLATION:
|
|
case DBSTATUS_E_SCHEMAVIOLATION:
|
|
fErrorOccured = TRUE;
|
|
continue;
|
|
|
|
// If the data is truncated,
|
|
// we need to check the length binding if appropriate
|
|
case DBSTATUS_S_TRUNCATED:
|
|
fCheckForTruncation = TRUE;
|
|
break;
|
|
|
|
// If the data is NULL,
|
|
// we need to check the length binding if appropriate
|
|
case DBSTATUS_S_ISNULL:
|
|
fCheckForNULL = TRUE;
|
|
break;
|
|
|
|
case DBSTATUS_S_OK:
|
|
break;
|
|
|
|
default:
|
|
fErrorOccured = TRUE;
|
|
}
|
|
} // end if status bindings
|
|
|
|
//////////////////////////////////
|
|
// check for the length binding //
|
|
//////////////////////////////////
|
|
if ((m_rgBinding[cCount].dwPart) & DBPART_LENGTH)
|
|
{
|
|
// If cbMaxLen > length,
|
|
// no truncation should occure
|
|
if (fCheckForTruncation)
|
|
{
|
|
if ((LENGTH_BINDING(m_rgBinding[cCount],m_pData)) < m_rgBinding[cCount].cbMaxLen)
|
|
fErrorOccured = TRUE;
|
|
continue;
|
|
}
|
|
|
|
// If status is NULL, skip length and value checks
|
|
if (fCheckForNULL)
|
|
continue;
|
|
|
|
// Length should be the same as the sizeof(DBTYPE) for fixed length data type
|
|
// Length should be number of bytes of the data for variable length data type,
|
|
switch(m_rgBinding[cCount].wType)
|
|
{
|
|
// No way to check variable lendth data type without a value binding
|
|
case DBTYPE_BYTES:
|
|
case DBTYPE_STR:
|
|
case DBTYPE_WSTR:
|
|
fCheckForLength = TRUE;
|
|
break;
|
|
default:
|
|
// For fixed length data type, make sure the length value is
|
|
// the same as the size of the data type
|
|
// get the size of the dta type
|
|
lDBTypeSize=GetDBTypeSize(m_rgBinding[cCount].wType);
|
|
|
|
if ((lDBTypeSize == 0) || (lDBTypeSize == INVALID_DBTYPE_SIZE))
|
|
{
|
|
fColumnError = TRUE;
|
|
break;
|
|
}
|
|
|
|
// Compare the data length with length binding
|
|
// if (*((ULONG *)(dwAddrData + m_rgBinding[cCount].obLength)) !=
|
|
if ((LENGTH_BINDING(m_rgBinding[cCount],m_pData)) !=
|
|
(ULONG)lDBTypeSize)
|
|
{
|
|
fColumnError = TRUE;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
// Free the memory allocated by the provider, goto next binding structure
|
|
if (fColumnError)
|
|
{
|
|
fErrorOccured=TRUE;
|
|
continue;
|
|
}
|
|
} // end if negth bindings
|
|
|
|
/////////////////////////////
|
|
// check for value binding //
|
|
/////////////////////////////
|
|
if ((m_rgBinding[cCount].dwPart) & DBPART_VALUE )
|
|
{
|
|
// Skip checking the value binding for BOOKMARKS
|
|
if (!m_rgBinding[cCount].iOrdinal)
|
|
continue;
|
|
|
|
// Get the data in the consumer's buffer
|
|
pConsumerData=(void *)(&VALUE_BINDING(m_rgBinding[cCount],m_pData));
|
|
|
|
// Compare with data selected from the Registry
|
|
// I can only verify four columnn now: sources name, sources parse name and
|
|
// description and type.
|
|
// For root enumerator, the sources clsid is the same as parse name.
|
|
|
|
// Right now, the column number is cCount, the row number is cRowIndex
|
|
switch(m_rgBinding[cCount].iOrdinal)
|
|
{
|
|
case nSrcName:
|
|
if (wcscmp(g_rgwszSourceName[cRowIndex], (WCHAR *)pConsumerData))
|
|
fErrorOccured = TRUE;
|
|
break;
|
|
case nSrcParseName:
|
|
if (wcscmp(g_rgwszSourceParseName[cRowIndex], (WCHAR *)pConsumerData))
|
|
fErrorOccured = TRUE;
|
|
break;
|
|
case nSrcDescription:
|
|
if (wcscmp(g_rgwszSourceDescription[cRowIndex], (WCHAR *)pConsumerData))
|
|
fErrorOccured = TRUE;
|
|
break;
|
|
case nSrcType:
|
|
// this should be done more agressive after specs merge in 2.1
|
|
switch (*(USHORT *)pConsumerData)
|
|
{
|
|
case DBSOURCETYPE_ENUMERATOR:
|
|
if (*(USHORT *)pConsumerData != g_SourceType[cRowIndex])
|
|
fErrorOccured = TRUE;
|
|
break;
|
|
case DBSOURCETYPE_DATASOURCE:
|
|
case DBSOURCETYPE_DATASOURCE_MDP:
|
|
// the actual g_SourceType[cRowIndex] value could be either
|
|
// DBSOURCETYPE_DATASOURCE or DBSOURCETYPE_DATASOURCE_MDP
|
|
if (DBSOURCETYPE_ENUMERATOR == g_SourceType[cRowIndex])
|
|
fErrorOccured = TRUE;
|
|
break;
|
|
default:
|
|
fErrorOccured = TRUE;
|
|
}
|
|
break;
|
|
case nSrcCLSID:
|
|
if (wcscmp(g_rgwszSourceParseName[cRowIndex], (WCHAR *)pConsumerData))
|
|
fErrorOccured=TRUE;
|
|
break;
|
|
case nSrcIsParent:
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
}
|
|
|
|
// Make sure for variable length data, the length in m_rgBinding[cCount] contains
|
|
// correct information
|
|
if (fCheckForLength)
|
|
{
|
|
switch(m_rgBinding[cCount].wType)
|
|
{
|
|
case DBTYPE_WSTR:
|
|
if ((LENGTH_BINDING(m_rgBinding[cCount],m_pData))
|
|
!= (wcslen((WCHAR *)pConsumerData)*sizeof(WCHAR)) )
|
|
fColumnError = TRUE;
|
|
break;
|
|
case DBTYPE_BYTES:
|
|
if ((LENGTH_BINDING(m_rgBinding[cCount],m_pData))
|
|
!= uswSize)
|
|
fColumnError = TRUE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Output an error message if the length binding fails
|
|
if (fColumnError)
|
|
fErrorOccured=TRUE;
|
|
}
|
|
|
|
} // end of value binding
|
|
|
|
}//end of the main loop
|
|
|
|
*pcRowIndex = cRowIndex;
|
|
return !fErrorOccured;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Read parse name from the sources rowset of root enumerator//
|
|
///////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::ReadParseName(const CLSID clsid)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
HRESULT hr = E_FAIL;
|
|
HROW hRow[1] = {NULL};
|
|
HROW *pHRow = hRow;
|
|
DBCOUNTITEM cRow = 0;
|
|
ULONG ulIndex = 0;
|
|
ULONG ulIndexMDP = 0;
|
|
ULONG ulIndexE = 0;
|
|
const ULONG nName = 0;
|
|
const ULONG nParseName = 1;
|
|
const ULONG nType = 3;
|
|
|
|
// Check pointer
|
|
if (!m_pISrcRow)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
m_pIRowset = NULL;
|
|
|
|
// Open sources rowset
|
|
if (!CHECK(hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,
|
|
(IUnknown **)&m_pIRowset), S_OK))
|
|
return FALSE;
|
|
|
|
// Make sure we have valid pointer
|
|
if (!m_pIRowset)
|
|
return FALSE;
|
|
|
|
// Create an accessor on the sources rowset and get bindings
|
|
TESTC_(GetAccessorAndBindings(m_pIRowset,DBACCESSOR_ROWDATA,&m_hAccessor,
|
|
&m_rgBinding,&m_cBinding,&m_cRowSize,DBPART_VALUE|DBPART_STATUS|DBPART_LENGTH,
|
|
ALL_COLS_EXCEPTBOOKMARK,FORWARD,NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV,DBPARAMIO_NOTPARAM,NO_BLOB_COLS),S_OK);
|
|
|
|
// Allocate memory for the row
|
|
SAFE_ALLOC(m_pData, BYTE, m_cRowSize);
|
|
|
|
// Loop over the rows, collecting providers and discarding
|
|
// enumerators.
|
|
while( (S_OK == (hr=m_pIRowset->GetNextRows(NULL,0,1,&cRow,&pHRow)))
|
|
&& (ulIndex < MAX_NUM_PROV))
|
|
{
|
|
// initialize fResult
|
|
fResult = FALSE;
|
|
|
|
// Get the next row
|
|
if (!CHECK(hr=m_pIRowset->GetData(hRow[0],m_hAccessor,m_pData), S_OK))
|
|
goto LOOP;
|
|
|
|
// Collect the data source row
|
|
// Store Provider Name and Parse Name
|
|
|
|
//bookmark columns are optional for the enumerator rowset. check to see if this rowset
|
|
//returned with a bookmark colum
|
|
ASSERT(m_rgBinding[0].iOrdinal != 0);
|
|
|
|
if ( DBSOURCETYPE_DATASOURCE == *((USHORT*)((BYTE *)m_pData + m_rgBinding[nType].obValue))
|
|
|| DBSOURCETYPE_DATASOURCE_MDP == *((USHORT*)((BYTE *)m_pData + m_rgBinding[nType].obValue)))
|
|
{
|
|
wcscpy(g_rgwszProvName[ulIndex], (WCHAR*)((BYTE *)m_pData + m_rgBinding[nName].obValue));
|
|
wcscpy(g_rgwszParseName[ulIndex], (WCHAR*)((BYTE *)m_pData + m_rgBinding[nParseName].obValue));
|
|
ulIndex++;
|
|
}
|
|
|
|
//just a test to see if the source type if enumerator
|
|
if (DBSOURCETYPE_ENUMERATOR == *((USHORT*)((BYTE *)m_pData + m_rgBinding[nType].obValue)))
|
|
{
|
|
ulIndexE++;
|
|
}
|
|
|
|
fResult = TRUE;
|
|
|
|
LOOP:
|
|
// Release the row handle
|
|
CHECK(hr=m_pIRowset->ReleaseRows(cRow,hRow,NULL,NULL,NULL),S_OK);
|
|
|
|
TESTC(fResult);
|
|
} // end while
|
|
|
|
if (MAX_NUM_PROV <= ulIndex)
|
|
TWARNING(L"There wasn't enough room to store all the rows provided by enumerator\n");
|
|
|
|
// The cursor should be at the end of the rowset
|
|
if (clsid == CLSID_OLEDB_ENUMERATOR)
|
|
COMPARE((ulIndex+ulIndexE+ulIndexMDP), (g_cOLEDBProvNames+g_cOLEDBEnumNames+g_cOLEDBProvMDPNames));
|
|
|
|
CLEANUP:
|
|
// Release the rowset created
|
|
if (!FreeAccessorAndBindings())
|
|
fResult = FALSE;
|
|
|
|
SAFE_RELEASE(m_pIRowset);
|
|
|
|
SAFE_FREE(m_pData);
|
|
|
|
// If no provider, something is wrong
|
|
if (!ulIndex)
|
|
return FALSE;
|
|
|
|
return fResult;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Free accessor handle and binding structure memories //
|
|
///////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::FreeAccessorAndBindings()
|
|
{
|
|
BOOL Result = FALSE;
|
|
|
|
//free binding structure
|
|
FreeAccessorBindings(m_cBinding, m_rgBinding);
|
|
|
|
// Free the consumer buffer
|
|
SAFE_FREE(m_pData);
|
|
|
|
// Free accessor handle
|
|
if (m_hAccessor)
|
|
{
|
|
// Get an IAccessor pointer if it was not yet a valid pointer
|
|
if (!m_pIAccessor)
|
|
CHECK(m_pIRowset->QueryInterface(IID_IAccessor,
|
|
(LPVOID *)&m_pIAccessor),S_OK);
|
|
|
|
if (m_pIAccessor)
|
|
{
|
|
if (CHECK(m_pIAccessor->ReleaseAccessor(m_hAccessor,NULL), S_OK))
|
|
Result = TRUE;
|
|
}
|
|
// Release the IAccessor interface pointer
|
|
SAFE_RELEASE(m_pIAccessor);
|
|
m_hAccessor = NULL;
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Check whether the property DBPROP_CANHOLDROWS is supported //
|
|
///////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::NoHoldRows(IRowset *pIRowset)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
ULONG cDBPropSets = 0;
|
|
DBPROPSET * prgDBPropSets = NULL;
|
|
ULONG cDBPropIDSets = 0;
|
|
DBPROPIDSET DBPropIDSets;
|
|
DBPROPID rgPropertyIDs;
|
|
IRowsetInfo * pIRowsetInfo = NULL;
|
|
|
|
rgPropertyIDs = DBPROP_CANHOLDROWS;
|
|
cDBPropIDSets = 1;
|
|
DBPropIDSets.rgPropertyIDs = &rgPropertyIDs;
|
|
DBPropIDSets.cPropertyIDs = 1;
|
|
DBPropIDSets.guidPropertySet = DBPROPSET_ROWSET;
|
|
|
|
TESTC(VerifyInterface(pIRowset, IID_IRowsetInfo,
|
|
ROWSET_INTERFACE,(IUnknown **)&pIRowsetInfo));
|
|
|
|
// Verify that DBPROP_CANHOLDROWS is VARIANT_FALSE
|
|
pIRowsetInfo->GetProperties(cDBPropIDSets, &DBPropIDSets, &cDBPropSets, &prgDBPropSets);
|
|
TESTC(NULL != prgDBPropSets && 1 == cDBPropSets);
|
|
|
|
if ( (DBPROPSTATUS_OK != prgDBPropSets->rgProperties[0].dwStatus)
|
|
|| (VARIANT_FALSE == V_BOOL(&prgDBPropSets->rgProperties[0].vValue)))
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
FreeProperties(&cDBPropSets, &prgDBPropSets);
|
|
return fResult;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Verify IParseDisplayName //
|
|
// 1. Parse a data source names into a moniker //
|
|
// 2. Binds that moniker with the interface on data source object/
|
|
// 3. Get the DSO initialized successfully //
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::VerifyParseDisplayName_root(IParseDisplayName * pIParseDisplayName)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
BOOL fBindInitProvDSO= FALSE;
|
|
ULONG chEaten = 0;
|
|
ULONG cPropSets = 0;
|
|
LPWSTR wszClsid = NULL;
|
|
DBPROPSET * rgPropSets = NULL;
|
|
IMoniker* pIMoniker = NULL;
|
|
IDBInitialize * pIDBInit = NULL;
|
|
IDBProperties * pIDBProperties = NULL;
|
|
ULONG i=0;
|
|
|
|
if(!pIParseDisplayName)
|
|
return FALSE;
|
|
|
|
// Check each data source
|
|
for(i=0; i<(g_cOLEDBProvNames+g_cOLEDBProvMDPNames); i++)
|
|
{
|
|
// Get a moniker
|
|
odtLog << g_rgwszProvName[i];
|
|
if (0 == wcscmp(L"MSDAIPP.DSO", g_rgwszProvName[i]))
|
|
{
|
|
odtLog << "\tSkipped\n";
|
|
continue;
|
|
}
|
|
if (CHECK(m_hr=pIParseDisplayName->ParseDisplayName(NULL,
|
|
g_rgwszParseName[i],&chEaten,&pIMoniker), S_OK))
|
|
{
|
|
odtLog << "\tgot the moniker";
|
|
fResult = FALSE;
|
|
if (pIMoniker)
|
|
{
|
|
// Binds the moniker with the IDBInitialize interface
|
|
CHECK(BindMoniker(pIMoniker,0,
|
|
IID_IDBInitialize,(LPVOID*)&pIDBInit), S_OK);
|
|
|
|
odtLog << "\tbound the moniker";
|
|
// We must have pIDBInit
|
|
if (!pIDBInit)
|
|
goto LOOP;
|
|
|
|
// Get the Provider String from the CLSID
|
|
StringFromCLSID(m_ProviderClsid, &wszClsid);
|
|
|
|
// If it is not the current provider, skip the initialization
|
|
if (_wcsicmp(g_rgwszParseName[i], wszClsid))
|
|
{
|
|
fResult = TRUE;
|
|
goto LOOP;
|
|
}
|
|
|
|
odtLog << "\ttry to set props on this";
|
|
|
|
// Build our init options from string passed to us from TMD for this provider
|
|
if (!GetInitProps(&cPropSets,&rgPropSets))
|
|
goto LOOP;
|
|
|
|
// Get IDBProperties Pointer
|
|
if (!VerifyInterface(pIDBInit, IID_IDBProperties,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIDBProperties))
|
|
goto LOOP;
|
|
|
|
// Set the properties before we Initialize
|
|
if (!CHECK(pIDBProperties->SetProperties(cPropSets, rgPropSets), S_OK))
|
|
goto LOOP;
|
|
|
|
//Initialize
|
|
if (CHECK(m_hr = pIDBInit->Initialize(), S_OK))
|
|
{
|
|
fResult = TRUE;
|
|
fBindInitProvDSO = TRUE;
|
|
}
|
|
odtLog << "\tinitialized";
|
|
}
|
|
}
|
|
else
|
|
odtLog << "\tfailed to get the moniker";
|
|
LOOP:
|
|
odtLog << "\n";
|
|
// Release the pointers
|
|
SAFE_RELEASE(pIDBInit);
|
|
SAFE_RELEASE(pIMoniker);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
|
|
// Free Properties we got back
|
|
FreeProperties(&cPropSets,&rgPropSets);
|
|
SAFE_FREE(wszClsid);
|
|
TESTC(fResult);
|
|
}
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
return fResult && fBindInitProvDSO;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Verify IParseDisplayName //
|
|
// 1. Parse a data source names into a moniker //
|
|
// 2. Binds that moniker with the interface on data source object/
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL CSourcesRowset::VerifyParseDisplayName_std(IParseDisplayName * pIParseDisplayName)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
ULONG chEaten = 0;
|
|
ULONG cPropSets = 0;
|
|
DBPROPSET * rgPropSets = NULL;
|
|
IMoniker* pIMoniker = NULL;
|
|
IDBInitialize * pIDBInit = NULL;
|
|
ULONG i=0;
|
|
|
|
if (!pIParseDisplayName)
|
|
return FALSE;
|
|
|
|
// Check each data source
|
|
for(i=0; i<(g_cOLEDBProvNames+g_cOLEDBProvMDPNames); i++)
|
|
{
|
|
// Get moniker
|
|
odtLog << g_rgwszProvName[i] << "\n";
|
|
if (CHECK(m_hr=pIParseDisplayName->ParseDisplayName(NULL,
|
|
g_rgwszParseName[i],&chEaten,&pIMoniker), S_OK))
|
|
{
|
|
if (pIMoniker)
|
|
{
|
|
// Binds the moniker with the IDBInitialize interface
|
|
CHECK(BindMoniker(pIMoniker, 0, IID_IDBInitialize, (LPVOID*)&pIDBInit), S_OK);
|
|
|
|
// We must have pIDBInit
|
|
TESTC(NULL != pIDBInit);
|
|
}
|
|
}
|
|
|
|
SAFE_RELEASE(pIDBInit);
|
|
SAFE_RELEASE(pIMoniker);
|
|
|
|
// Free Properties we got back
|
|
FreeProperties(&cPropSets,&rgPropSets);
|
|
}
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBInit);
|
|
SAFE_RELEASE(pIMoniker);
|
|
|
|
// Make sure we loop all Providers
|
|
COMPARE((g_cOLEDBProvNames+g_cOLEDBProvMDPNames), i);
|
|
|
|
return fResult;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Verify IRowset::GetNextRows on sources rowset //
|
|
// 1. Create the sources rowset, asking for DBPROP_CANHOLDROWS //
|
|
// to be VARIANT_FALSE if it is supported and writable //
|
|
// 2. Get a chunk of the rowset //
|
|
// 3. Call IRowset::GetNextRows again, without releasing the //
|
|
// handles
|
|
//////////////////////////////////////////////////////////////////
|
|
ULONG CSourcesRowset::GetNextRowsWithoutRelAllRows()
|
|
{
|
|
ULONG fTestRes = TEST_FAIL;
|
|
DBCOUNTITEM cRows = 0;
|
|
HROW rghRows[FETCH_ROW_STD];
|
|
HROW *prghRows = rghRows;
|
|
DBCOUNTITEM cRows1 = 0;
|
|
HROW rghRows1[FETCH_ROW_STD];
|
|
HROW *prghRows1 = rghRows1;
|
|
IRowset *pIRowset = NULL;
|
|
DBPROPSET *rgPropSet = NULL;
|
|
ULONG cPropSet = 0;
|
|
BOOL fContinue = TRUE;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
// This is either on root enumerator or on the provider enumerator
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
if (SettableProperty(DBPROP_CANHOLDROWS, DBPROPSET_ROWSET, m_pISrcRow, ENUMERATOR_INTERFACE))
|
|
SetProperty(DBPROP_CANHOLDROWS, DBPROPSET_ROWSET, &cPropSet, &rgPropSet, VT_BOOL, (ULONG_PTR) VARIANT_FALSE, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
|
|
TESTC_(m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset, cPropSet, rgPropSet,(IUnknown **) &pIRowset), S_OK);
|
|
|
|
// If the Property is Not Supported
|
|
if (cPropSet)
|
|
{
|
|
TESTC(NoHoldRows(pIRowset));
|
|
}
|
|
else
|
|
{
|
|
if (!NoHoldRows(pIRowset))
|
|
{
|
|
fTestRes = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
// go through all the rowset
|
|
while((m_hr=pIRowset->GetNextRows(NULL,0,FETCH_ROW_STD,&cRows,(HROW**)&prghRows)) == S_OK)
|
|
{
|
|
// verify that the proper return value is generated when the rows are not released
|
|
m_hr=pIRowset->GetNextRows(NULL,0,FETCH_ROW_STD, &cRows1,(HROW**)&prghRows1);
|
|
|
|
// release all rows now so in case verification fails we do not leak
|
|
fContinue = CHECK(pIRowset->ReleaseRows(cRows, rghRows, NULL, 0, NULL), S_OK);
|
|
if (SUCCEEDED(m_hr))
|
|
{
|
|
fContinue = fContinue && CHECK(pIRowset->ReleaseRows(cRows1, rghRows1, NULL, 0, NULL), S_OK);
|
|
}
|
|
|
|
//now do the verification
|
|
TESTC(cRows == FETCH_ROW_STD);
|
|
if (SUCCEEDED(m_hr))
|
|
{
|
|
TESTC(cRows1==FETCH_ROW_STD || m_hr==DB_S_ENDOFROWSET);
|
|
TEST2C_(m_hr, DB_S_ENDOFROWSET, S_OK);
|
|
}
|
|
else
|
|
{
|
|
TESTC_(m_hr, DB_E_ROWSNOTRELEASED);
|
|
}
|
|
//if there were failures do not continue
|
|
if(!fContinue)
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// Release rows from the last call to GetNextRows: even if it returned DB_S_ENDOFROWSET several rows still could be fetched
|
|
if (SUCCEEDED(m_hr) && cRows)
|
|
{
|
|
CHECK(pIRowset->ReleaseRows(cRows, rghRows, NULL, 0, NULL), S_OK);
|
|
}
|
|
|
|
// check that you have gone through the whole rowset
|
|
TESTC_(m_hr, DB_S_ENDOFROWSET);
|
|
|
|
fTestRes= TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowset);
|
|
FreeProperties(&cPropSet, &rgPropSet);
|
|
return fTestRes;
|
|
} //CSourcesRowset::GetNextRowsWithoutRelAllRows
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Checks how ISourcesRowset::GetSourcesRowset deals with //
|
|
// invalid colid passed in the DBPROP stru of a property //
|
|
//////////////////////////////////////////////////////////////////
|
|
ULONG CSourcesRowset::VerifyInvalidColID(DBPROPOPTIONS dbPropOption)
|
|
{
|
|
// there is not really much to be tested
|
|
// there is no info about which property
|
|
// is column specific that can ge obtained
|
|
// from the enumerator
|
|
BOOL fResult = TEST_FAIL;
|
|
DBPROPSTATUS dbPropStatus = DBPROPSTATUS_NOTSUPPORTED;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set the correct status
|
|
if (!SettableProperty(DBPROP_DEFERRED, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
fResult = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// Set a property which can be set to individual column
|
|
// Set an invalid colid
|
|
SetOneProperty(DBPROP_DEFERRED, dbPropOption, 0);
|
|
m_rgDBPropSets[0].rgProperties[0].colid = DBCOLUMN_MAYSORT;
|
|
|
|
m_hr = m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset);
|
|
|
|
switch (m_hr)
|
|
{
|
|
case S_OK:
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
break;
|
|
|
|
case DB_S_ERRORSOCCURRED:
|
|
TESTC(DBPROPOPTIONS_OPTIONAL == dbPropOption);
|
|
TESTC(NULL != m_pIRowset);
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_BADCOLUMN == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
break;
|
|
|
|
case DB_E_ERRORSOCCURRED:
|
|
TESTC(DBPROPOPTIONS_REQUIRED == dbPropOption);
|
|
TESTC(NULL == m_pIRowset);
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_BADCOLUMN == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
break;
|
|
}
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
} //CSourcesRowset::VerifyInvalidColID
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Checks how ISourcesRowset::VerifyNonRowsetPropSet deals with //
|
|
// non rowset property set asked //
|
|
//////////////////////////////////////////////////////////////////
|
|
ULONG CSourcesRowset::VerifyNonRowsetPropSet(ULONG nColNo)
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set the property in Column property group
|
|
memset(rgProp, 0, sizeof(rgProp));
|
|
memset(rgProp, 0, sizeof(rgProp));
|
|
rgPropSet[0].rgProperties = rgProp;
|
|
rgPropSet[0].cProperties = 1;
|
|
rgPropSet[0].guidPropertySet = DBPROPSET_COLUMN;
|
|
rgProp[0].dwPropertyID = DBPROP_COL_AUTOINCREMENT;
|
|
rgProp[0].dwOptions = DBPROPOPTIONS_OPTIONAL;
|
|
rgProp[0].vValue.vt = VT_BOOL;
|
|
V_BOOL(&rgProp[0].vValue) = VARIANT_TRUE;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
1,rgPropSet,(IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(nColNo, m_pIRowset));
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(rgPropSet[0].rgProperties[0].dwStatus != DBPROPSTATUS_OK);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
} //CSourcesRowset::VerifyNonRowsetPropSet
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Checks how ISourcesRowset::CountNoOfRows //
|
|
// Counts the number of rows in the rowset (assume init position)//
|
|
//////////////////////////////////////////////////////////////////
|
|
HRESULT CSourcesRowset::CountNoOfRows(IRowset *pIRowset, ULONG *pulRowsNo)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
DBCOUNTITEM cRowsObtained;
|
|
HROW rghRows[1];
|
|
HROW *prghRows = rghRows;
|
|
|
|
if (NULL == pIRowset || NULL == pulRowsNo)
|
|
return E_FAIL;
|
|
|
|
*pulRowsNo = 0;
|
|
|
|
for (; DB_S_ENDOFROWSET != hr; (*pulRowsNo)++)
|
|
{
|
|
TEST2C_(hr = pIRowset->GetNextRows(0, 0, 1, &cRowsObtained, (HROW**)&prghRows), S_OK, DB_S_ENDOFROWSET);
|
|
TESTC(S_OK != hr || S_OK == pIRowset->ReleaseRows(1, rghRows, NULL, NULL, NULL));
|
|
}
|
|
|
|
(*pulRowsNo)--;
|
|
hr = S_OK;
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //CSourcesRowset::CountNoOfRows
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Checks how ISourcesRowset::CountNoOfRows //
|
|
// Counts the number of rows in the rowset (assume init position) and stores first cMaxSourcesNames SOURCES_NAME in //
|
|
//////////////////////////////////////////////////////////////////
|
|
HRESULT CSourcesRowset::CountNoOfRowsAndGetSourcesNames(IRowset *pIRowset, ULONG *pulRowsNo, WCHAR** rgwszSourcesNames, ULONG cMaxSourcesNames)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
HROW *pHRow = NULL;
|
|
HACCESSOR hAccessor=DB_NULL_HACCESSOR;
|
|
void * pData=NULL;
|
|
DBLENGTH cRowSize;
|
|
DBCOUNTITEM cBinding=0;
|
|
DBBINDING * rgBinding=NULL;
|
|
DB_LORDINAL colOrdinal = 1; // we're interested in first column, SOURCES_NAME
|
|
WCHAR* wszSourceName = NULL;
|
|
|
|
if (NULL == pIRowset || NULL == pulRowsNo)
|
|
return E_FAIL;
|
|
|
|
*pulRowsNo = 0;
|
|
|
|
if (cMaxSourcesNames && rgwszSourcesNames)
|
|
{
|
|
// Create an accessor on the sources rowset and get bindings
|
|
TESTC_(hr=GetAccessorAndBindings(pIRowset,DBACCESSOR_ROWDATA,&hAccessor,
|
|
&rgBinding,&cBinding,&cRowSize,DBPART_VALUE|DBPART_STATUS|DBPART_LENGTH,
|
|
USE_COLS_TO_BIND_ARRAY,FORWARD,NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,1,&colOrdinal,NULL,
|
|
NO_COLS_OWNED_BY_PROV,DBPARAMIO_NOTPARAM,NO_BLOB_COLS),S_OK)
|
|
|
|
// Allocate memory for the row
|
|
SAFE_ALLOC(pData, BYTE, cRowSize);
|
|
}
|
|
|
|
for (; DB_S_ENDOFROWSET != hr; (*pulRowsNo)++)
|
|
{
|
|
TEST2C_(hr = pIRowset->GetNextRows(0, 0, 1, &cRowsObtained, (HROW**)&pHRow), S_OK, DB_S_ENDOFROWSET);
|
|
|
|
if (hr==S_OK && cMaxSourcesNames && rgwszSourcesNames && *pulRowsNo<cMaxSourcesNames && CHECK(pIRowset->GetData(*pHRow,hAccessor,pData), S_OK))
|
|
{
|
|
if (STATUS_BINDING(rgBinding[0],pData)==DBSTATUS_S_OK)
|
|
{
|
|
SAFE_ALLOC(rgwszSourcesNames[*pulRowsNo], WCHAR, wcslen((WCHAR*)&VALUE_BINDING(rgBinding[0],pData))+1);
|
|
wcscpy(rgwszSourcesNames[*pulRowsNo], (WCHAR*)&VALUE_BINDING(rgBinding[0],pData));
|
|
}
|
|
else
|
|
rgwszSourcesNames[*pulRowsNo]=NULL;
|
|
}
|
|
|
|
if (pHRow)
|
|
{
|
|
CHECK(pIRowset->ReleaseRows(1, pHRow, NULL, NULL, NULL), S_OK);
|
|
pHRow = NULL;
|
|
}
|
|
}
|
|
|
|
(*pulRowsNo)--;
|
|
|
|
hr = S_OK;
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
FreeAccessorBindings(cBinding,rgBinding);
|
|
if(hAccessor && pIRowset)
|
|
{
|
|
IAccessor * pIAccessor;
|
|
|
|
CHECK(pIRowset->QueryInterface(IID_IAccessor, (LPVOID *)&pIAccessor),S_OK);
|
|
if (pIAccessor)
|
|
{
|
|
pIAccessor->ReleaseAccessor(hAccessor, NULL);
|
|
SAFE_RELEASE(pIAccessor);
|
|
}
|
|
}
|
|
return hr;
|
|
} //CSourcesRowset::CountNoOfRows
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
//
|
|
// thread function
|
|
//------------------------------------------------------------------
|
|
unsigned CSourcesRowset::MyThreadProc(ULONG iThread)
|
|
{
|
|
HRESULT hr;
|
|
IRowset *pIRowset = NULL;
|
|
|
|
if (iThread >= nThreads)
|
|
return 0;
|
|
|
|
Sleep(0);
|
|
if (NULL != m_pISrcRow)
|
|
{
|
|
hr = m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset, 0, NULL, (IUnknown**)&pIRowset);
|
|
hr = SUCCEEDED(hr)? CountNoOfRows(pIRowset, &m_rgRowsNo[iThread]): hr;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
Sleep(0);
|
|
m_rgResult[iThread] = hr;
|
|
m_rgRowset[iThread] = pIRowset;
|
|
return 1;
|
|
} //CSourcesRowset::MyThreadProc
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
//
|
|
// thread function
|
|
//------------------------------------------------------------------
|
|
unsigned CSourcesRowset::MyThreadProc2(ULONG iThread)
|
|
{
|
|
HRESULT hr;
|
|
IRowset *pIRowset = NULL;
|
|
|
|
if (iThread >= nThreads)
|
|
return 0;
|
|
|
|
Sleep(0);
|
|
if (NULL != m_pISrcRow)
|
|
{
|
|
hr = m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset, 0, NULL, (IUnknown**)&pIRowset);
|
|
hr = SUCCEEDED(hr)? CountNoOfRowsAndGetSourcesNames(pIRowset, &m_rgRowsNo[iThread], m_rgSourcesNames[iThread], m_rgMaxSourcesNames[iThread]): hr;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
Sleep(0);
|
|
m_rgResult[iThread] = hr;
|
|
m_rgRowset[iThread] = pIRowset;
|
|
return 1;
|
|
} //CSourcesRowset::MyThreadProc
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------
|
|
//
|
|
// Verify aggregation on sources rowset, ask for something different from IID_IUnknown => DB_E_NOAGGREGATION
|
|
//
|
|
//----------------------------------------------------------------------------------------------------------
|
|
BOOL CSourcesRowset::VerifyNotIUnknownInAggregation()
|
|
{
|
|
TBEGIN
|
|
IUnknown *pIUnkOuter = NULL;
|
|
IUnknown *pIUnkInner = NULL;
|
|
HRESULT hr;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Create an outer rowset object
|
|
if (CHECK(m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset, 0, NULL, &pIUnkOuter), S_OK))
|
|
{
|
|
CAggregate Aggregate(pIUnkOuter);
|
|
|
|
// Dirty the output params
|
|
pIUnkInner = INVALID(IUnknown*);
|
|
|
|
// Create an inner rowset object on IID_IRowset
|
|
CHECK(hr = m_pISrcRow->GetSourcesRowset(&Aggregate, IID_IRowset, 0,
|
|
NULL, &pIUnkInner), DB_E_NOAGGREGATION);
|
|
|
|
//Inner object cannot RefCount the outer object - COM rule for CircularRef
|
|
COMPARE(Aggregate.GetRefCount(), 1);
|
|
COMPARE(pIUnkInner == NULL, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
// Release the outer rowset object
|
|
SAFE_RELEASE_(pIUnkOuter);
|
|
// No rowset returned
|
|
COMPARE(pIUnkInner, NULL);
|
|
TRETURN
|
|
} // CSourcesRowset::VerifyNotIUnknownInAggregation
|
|
|
|
|
|
|
|
//---------------------------------------------------
|
|
//
|
|
// Verify sources rowset aggregation
|
|
//
|
|
//---------------------------------------------------
|
|
BOOL CSourcesRowset::VerifySourcesRowsetAggregation()
|
|
{
|
|
TBEGIN
|
|
IUnknown *pIUnkOuter = NULL;
|
|
IUnknown *pIUnkInner = NULL;
|
|
HRESULT hr;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Create an outer rowset object
|
|
if (CHECK(hr = m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL, &pIUnkOuter), S_OK))
|
|
{
|
|
CAggregate Aggregate(pIUnkOuter);
|
|
|
|
// Dirty the output params
|
|
pIUnkInner = INVALID(IUnknown*);
|
|
|
|
// Create an inner rowset object on IID_IUnknown
|
|
hr = m_pISrcRow->GetSourcesRowset(&Aggregate, IID_IUnknown, 0, NULL, &pIUnkInner);
|
|
|
|
// Check the return code
|
|
if (FAILED(hr))
|
|
{
|
|
CHECK(hr, DB_E_NOAGGREGATION);
|
|
COMPARE(NULL == pIUnkInner, TRUE);
|
|
}
|
|
else
|
|
{
|
|
Aggregate.SetUnkInner(pIUnkInner);
|
|
CHECK(hr, S_OK);
|
|
COMPARE(NULL != pIUnkInner, TRUE);
|
|
COMPARE(Aggregate.VerifyAggregationQI(hr, IID_IRowset), TRUE);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
// Release the outer rowset object
|
|
SAFE_RELEASE_(pIUnkOuter);
|
|
// Release the inner rowset object
|
|
SAFE_RELEASE_(pIUnkInner);
|
|
TRETURN
|
|
} //CSourcesRowset::VerifySourcesRowsetAggregation
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
// Verify IRowsetInfo::GetSpecification on sources rowset, aggregated enumerator
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
BOOL CSourcesRowset::VerifyGetSpec_AggregatedEnum()
|
|
{
|
|
TBEGIN
|
|
ISourcesRowset *pISourcesRowset = NULL;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
IUnknown *pIAggregate = NULL;
|
|
IUnknown *pIUnkInner = NULL;
|
|
ULONG ulRefCountBefore;
|
|
ULONG ulRefCountAfter;
|
|
HRESULT hr;
|
|
|
|
CAggregate Aggregate(m_pISrcRow);
|
|
|
|
//Obtain the Enumerator (note: Enumerator is Aggregated, not rowset)
|
|
//NOTE: The ParseDisplayName interface has no way to do aggregation!
|
|
//Thus I'm reallying upon the Root Enumerator wszParseName to be the CLSID
|
|
//which it is ans will never change, but just a note as to why I'm not
|
|
//calling IParseDisplayName::ParseDisplayName on the Enum wszParseName...
|
|
hr = CoCreateInstance(m_clsid, &Aggregate, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pIUnkInner);
|
|
Aggregate.SetUnkInner(pIUnkInner);
|
|
|
|
//Verify Aggregation for this...
|
|
TESTC_PROVIDER(Aggregate.VerifyAggregationQI(hr, IID_ISourcesRowset, (IUnknown**)&pISourcesRowset));
|
|
|
|
//ISourcesRowset::GetRowset
|
|
ulRefCountBefore = Aggregate.GetRefCount();
|
|
TESTC_(hr = pISourcesRowset->GetSourcesRowset(NULL, IID_IRowsetInfo, 0, NULL, (IUnknown**)&pIRowsetInfo),S_OK);
|
|
ulRefCountAfter = Aggregate.GetRefCount();
|
|
|
|
//GetSpecification
|
|
TEST2C_(hr = pIRowsetInfo->GetSpecification(IID_IAggregate, (IUnknown**)&pIAggregate),S_OK,S_FALSE);
|
|
|
|
if(S_OK == hr)
|
|
{
|
|
TESTC(VerifyEqualInterface(pIAggregate, pISourcesRowset));
|
|
|
|
//Verify the child correctly addref'd the parent outer.
|
|
//The is an absolute requirement that the child keep the parent outer alive.
|
|
//If it doesn't addref the outer, the outer can be released externally since
|
|
//its not being used anymore due to the fact the outer controls the refcount
|
|
//of the inner. Many providers incorrectly addref the inner, which does nothing
|
|
//but guareentee the inner survives, but the inner will delegate to the outer
|
|
//and crash since it no longer exists...
|
|
COMPARE(ulRefCountAfter > ulRefCountBefore, TRUE);
|
|
}
|
|
else
|
|
{
|
|
COMPARE(NULL == pIAggregate, TRUE);
|
|
TWARNING(L"IRowsetInfo::GetSpecification unable to retrieve Parent object!");
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pISourcesRowset);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
SAFE_RELEASE(pIAggregate);
|
|
SAFE_RELEASE(pIUnkInner);
|
|
TRETURN
|
|
} //CSourcesRowset::VerifyGetSpec_AggregatedEnum
|
|
|
|
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Test Case Section
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCSourcesRowset_RootEnumerator)
|
|
//--------------------------------------------------------------------
|
|
// @class ISourcesRowset::GetSourcesRowset test for root enumerator
|
|
//
|
|
class TCSourcesRowset_RootEnumerator : public CSourcesRowset {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCSourcesRowset_RootEnumerator,CSourcesRowset);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember QI with NULL -- E_INVALIDARG
|
|
int Variation_1();
|
|
// @cmember PropertySets N, NULL -- E_INVALIDARG
|
|
int Variation_2();
|
|
// @cmember Property N, NULL -- E_INVALIDARG
|
|
int Variation_3();
|
|
// @cmember riid = IID_NULL, invalid property set -- E_INVALIDARG or E_NOINTERFACE
|
|
int Variation_4();
|
|
// @cmember ppSourcesRowset = NULL -- E_INVALIDARG
|
|
int Variation_5();
|
|
// @cmember QI IDBInitialize -- E_NOINTERFACE
|
|
int Variation_6();
|
|
// @cmember QI IDBProperties -- E_NOINTERFACE
|
|
int Variation_7();
|
|
// @cmember open sources rowset on IRowsetUpdate -- E_NOINTERFACE
|
|
int Variation_8();
|
|
// @cmember open sources rowset on IDBCreateSession -- E_NOINTERFACE
|
|
int Variation_9();
|
|
// @cmember riid = IID_NULL, valid ppSourcesRowset -- E_NOINTERFACE
|
|
int Variation_10();
|
|
// @cmember riid = IID_NULL, valid property -- E_NOINTERFACE
|
|
int Variation_11();
|
|
// @cmember pUnkOuter not NULL, IID_IRowset for pUnkInner -- E_NOINTERFACE or DB_E_NOAGGREGATION
|
|
int Variation_12();
|
|
// @cmember Call GetSourcesRowset while uninitialized -- E_UNEXPECTED
|
|
int Variation_13();
|
|
// @cmember pUnkOuter not NULL -- S_OK or DB_E_NOAGGREGATION
|
|
int Variation_14();
|
|
// @cmember QI IParseDisplayName -- S_OK
|
|
int Variation_15();
|
|
// @cmember QI ISupportErrorInfo -- S_OK
|
|
int Variation_16();
|
|
// @cmember create the enumerator object on IUnknown and QI ISourcesRowset -- S_OK
|
|
int Variation_17();
|
|
// @cmember pISourcesRowset->AddRef, Release -- S_OK
|
|
int Variation_18();
|
|
// @cmember PropertySets 0, NULL -- S_OK
|
|
int Variation_19();
|
|
// @cmember PropertySets 0, valid -- S_OK
|
|
int Variation_20();
|
|
// @cmember PropertySets N, valid -- S_OK
|
|
int Variation_21();
|
|
// @cmember DBPROP_COMMANDTIMEOUT -- S_OK
|
|
int Variation_22();
|
|
// @cmember Property 0, NULL -- S_OK
|
|
int Variation_23();
|
|
// @cmember Property 0, valid -- S_OK
|
|
int Variation_24();
|
|
// @cmember Property N, valid -- S_OK
|
|
int Variation_25();
|
|
// @cmember one prop, DBOPTION_REQUIRED -- S_OK
|
|
int Variation_26();
|
|
// @cmember create enumerator object on IParseDisplayName -- S_OK
|
|
int Variation_27();
|
|
// @cmember open sources rowset on IAccessor -- S_OK
|
|
int Variation_28();
|
|
// @cmember open sources rowset on IColunmsInfo -- S_OK
|
|
int Variation_29();
|
|
// @cmember open sources rowset on IRowsetInfo -- S_OK
|
|
int Variation_30();
|
|
// @cmember open sources rowset on IUnknown -- S_OK
|
|
int Variation_31();
|
|
// @cmember IRowsetInfo->GetSpecification -- S_FALSE
|
|
int Variation_32();
|
|
// @cmember open sources rowset, getnextrow, release, getnextrow -- S_OK
|
|
int Variation_33();
|
|
// @cmember property was not supported -- DB_S_ERRORSOCCURRED
|
|
int Variation_34();
|
|
// @cmember property was not in Rowset property group -- DB_S_ERRORSOCCURRED
|
|
int Variation_35();
|
|
// @cmember property set was not supported - DB_S_ERRORSOCCURRED
|
|
int Variation_36();
|
|
// @cmember property was not cheap to set -- DB_S_ERRORSOCCURRED
|
|
int Variation_37();
|
|
// @cmember invalid colid -- DB_S_ERRORSOCCURRED
|
|
int Variation_38();
|
|
// @cmember invalid dwOptions -- DB_E_ERRORSOCCURRED
|
|
int Variation_39();
|
|
// @cmember invalid vValue -- DB_S_ERRORSOCCURRED
|
|
int Variation_40();
|
|
// @cmember incorrect data type -- DB_S_ERRORSOCCURRED
|
|
int Variation_41();
|
|
// @cmember vValue = VT_EMPTY -- S_OK
|
|
int Variation_42();
|
|
// @cmember open sources rowset twice -- S_OK
|
|
int Variation_43();
|
|
// @cmember open sources rowset, close, open, open -- S_OK
|
|
int Variation_44();
|
|
// @cmember property was not applied to all columns -- DB_S_ERRORSOCCURRED
|
|
int Variation_45();
|
|
// @cmember property was not supported -- DB_E_ERRORSOCCURRED
|
|
int Variation_46();
|
|
// @cmember property was not in Rowset property group -- DB_E_ERRORSOCCURRED
|
|
int Variation_47();
|
|
// @cmember property set was not supported -- DB_E_ERRORSOCCURRED
|
|
int Variation_48();
|
|
// @cmember invalid colid -- DB_E_ERRORSOCCURRED
|
|
int Variation_49();
|
|
// @cmember invalid dwOptions -- DB_E_ERRORSOCCURRED
|
|
int Variation_50();
|
|
// @cmember invalid vValue -- DB_E_ERRORSOCCURRED
|
|
int Variation_51();
|
|
// @cmember incorrect data type -- DB_E_ERRORSOCCURRED
|
|
int Variation_52();
|
|
// @cmember vValue = VT_EMPTY -- S_OK
|
|
int Variation_53();
|
|
// @cmember IParseDisplayName::ParseDisplayName without rowset open -- S_OK
|
|
int Variation_54();
|
|
// @cmember IParseDisplayName::ParseDisplayName -- S_OK
|
|
int Variation_55();
|
|
// @cmember ParseDisplayName: displayName = NULL -- MK_E_NOOBJECT
|
|
int Variation_56();
|
|
// @cmember ParseDisplayName:pchEaten=NULL -- MK_E_NOOBJECT
|
|
int Variation_57();
|
|
// @cmember ParseDisplayName:pIMoniker = NULL -- E_UNEXPECTED
|
|
int Variation_58();
|
|
// @cmember IParseDisplayName::ParseDisplayName, bind Moniker to session object -- E_NOINTERFACE
|
|
int Variation_59();
|
|
// @cmember open sources rowset, getnextrow, not release all rows, getnextrow -- DB_E_ROWSNOTRELEASED
|
|
int Variation_60();
|
|
// @cmember check that all mutual dso & enum are in rowset -- S_OK
|
|
int Variation_61();
|
|
// @cmember Ask IID_IRowsetChange on sources rowset
|
|
int Variation_62();
|
|
// @cmember Ask IID_IRowsetUpdate on sources rowset
|
|
int Variation_63();
|
|
// @cmember Ask DBPROP_IRowsetChange on sources rowset
|
|
int Variation_64();
|
|
// @cmember Ask for DBPROP_IRowsetUpdate on sources rowset
|
|
int Variation_65();
|
|
// @cmember QI for IRowsetChange and IRowsetUpdate on a common sources rowset
|
|
int Variation_66();
|
|
// @cmember ParseDisplayName: unknown displayName (not a proper string) -- MK_E_NOOBJECT
|
|
int Variation_67();
|
|
// @cmember ParseDisplayName: not null pbc (IBindCtx) => S_OK
|
|
int Variation_68();
|
|
// @cmember Multiple threads retrieve the sources rowset: check the number of rows
|
|
int Variation_69();
|
|
// @cmember Aggregate The enumerator, get the sources rowset and call IRowsetInfo::GetSpecification
|
|
int Variation_70();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCSourcesRowset_RootEnumerator)
|
|
#define THE_CLASS TCSourcesRowset_RootEnumerator
|
|
BEG_TEST_CASE(TCSourcesRowset_RootEnumerator, CSourcesRowset, L"ISourcesRowset::GetSourcesRowset test for root enumerator")
|
|
TEST_VARIATION(1, L"QI with NULL -- E_INVALIDARG")
|
|
TEST_VARIATION(2, L"PropertySets N, NULL -- E_INVALIDARG")
|
|
TEST_VARIATION(3, L"Property N, NULL -- E_INVALIDARG")
|
|
TEST_VARIATION(4, L"riid = IID_NULL, invalid property set -- E_INVALIDARG or E_NOINTERFACE")
|
|
TEST_VARIATION(5, L"ppSourcesRowset = NULL -- E_INVALIDARG")
|
|
TEST_VARIATION(6, L"QI IDBInitialize -- E_NOINTERFACE")
|
|
TEST_VARIATION(7, L"QI IDBProperties -- E_NOINTERFACE")
|
|
TEST_VARIATION(8, L"open sources rowset on IRowsetUpdate -- E_NOINTERFACE")
|
|
TEST_VARIATION(9, L"open sources rowset on IDBCreateSession -- E_NOINTERFACE")
|
|
TEST_VARIATION(10, L"riid = IID_NULL, valid ppSourcesRowset -- E_NOINTERFACE")
|
|
TEST_VARIATION(11, L"riid = IID_NULL, valid property -- E_NOINTERFACE")
|
|
TEST_VARIATION(12, L"pUnkOuter not NULL, IID_IRowset for pUnkInner -- E_NOINTERFACE or DB_E_NOAGGREGATION")
|
|
TEST_VARIATION(13, L"Call GetSourcesRowset while uninitialized -- E_UNEXPECTED")
|
|
TEST_VARIATION(14, L"pUnkOuter not NULL -- S_OK or DB_E_NOAGGREGATION")
|
|
TEST_VARIATION(15, L"QI IParseDisplayName -- S_OK")
|
|
TEST_VARIATION(16, L"QI ISupportErrorInfo -- S_OK")
|
|
TEST_VARIATION(17, L"create the enumerator object on IUnknown and QI ISourcesRowset -- S_OK")
|
|
TEST_VARIATION(18, L"pISourcesRowset->AddRef, Release -- S_OK")
|
|
TEST_VARIATION(19, L"PropertySets 0, NULL -- S_OK")
|
|
TEST_VARIATION(20, L"PropertySets 0, valid -- S_OK")
|
|
TEST_VARIATION(21, L"PropertySets N, valid -- S_OK")
|
|
TEST_VARIATION(22, L"DBPROP_COMMANDTIMEOUT -- S_OK")
|
|
TEST_VARIATION(23, L"Property 0, NULL -- S_OK")
|
|
TEST_VARIATION(24, L"Property 0, valid -- S_OK")
|
|
TEST_VARIATION(25, L"Property N, valid -- S_OK")
|
|
TEST_VARIATION(26, L"one prop, DBOPTION_REQUIRED -- S_OK")
|
|
TEST_VARIATION(27, L"create enumerator object on IParseDisplayName -- S_OK")
|
|
TEST_VARIATION(28, L"open sources rowset on IAccessor -- S_OK")
|
|
TEST_VARIATION(29, L"open sources rowset on IColunmsInfo -- S_OK")
|
|
TEST_VARIATION(30, L"open sources rowset on IRowsetInfo -- S_OK")
|
|
TEST_VARIATION(31, L"open sources rowset on IUnknown -- S_OK")
|
|
TEST_VARIATION(32, L"IRowsetInfo->GetSpecification -- S_FALSE")
|
|
TEST_VARIATION(33, L"open sources rowset, getnextrow, release, getnextrow -- S_OK")
|
|
TEST_VARIATION(34, L"property was not supported -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(35, L"property was not in Rowset property group -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(36, L"property set was not supported - DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(37, L"property was not cheap to set -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(38, L"invalid colid -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(39, L"invalid dwOptions -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(40, L"invalid vValue -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(41, L"incorrect data type -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(42, L"vValue = VT_EMPTY -- S_OK")
|
|
TEST_VARIATION(43, L"open sources rowset twice -- S_OK")
|
|
TEST_VARIATION(44, L"open sources rowset, close, open, open -- S_OK")
|
|
TEST_VARIATION(45, L"property was not applied to all columns -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(46, L"property was not supported -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(47, L"property was not in Rowset property group -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(48, L"property set was not supported -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(49, L"invalid colid -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(50, L"invalid dwOptions -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(51, L"invalid vValue -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(52, L"incorrect data type -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(53, L"vValue = VT_EMPTY -- S_OK")
|
|
TEST_VARIATION(54, L"IParseDisplayName::ParseDisplayName without rowset open -- S_OK")
|
|
TEST_VARIATION(55, L"IParseDisplayName::ParseDisplayName -- S_OK")
|
|
TEST_VARIATION(56, L"ParseDisplayName: displayName = NULL -- MK_E_NOOBJECT")
|
|
TEST_VARIATION(57, L"ParseDisplayName:pchEaten=NULL -- MK_E_NOOBJECT")
|
|
TEST_VARIATION(58, L"ParseDisplayName:pIMoniker = NULL -- E_UNEXPECTED")
|
|
TEST_VARIATION(59, L"IParseDisplayName::ParseDisplayName, bind Moniker to session object -- E_NOINTERFACE")
|
|
TEST_VARIATION(60, L"open sources rowset, getnextrow, not release all rows, getnextrow -- DB_E_ROWSNOTRELEASED")
|
|
TEST_VARIATION(61, L"check that all mutual dso & enum are in rowset -- S_OK")
|
|
TEST_VARIATION(62, L"Ask IID_IRowsetChange on sources rowset")
|
|
TEST_VARIATION(63, L"Ask IID_IRowsetUpdate on sources rowset")
|
|
TEST_VARIATION(64, L"Ask DBPROP_IRowsetChange on sources rowset")
|
|
TEST_VARIATION(65, L"Ask for DBPROP_IRowsetUpdate on sources rowset")
|
|
TEST_VARIATION(66, L"QI for IRowsetChange and IRowsetUpdate on a common sources rowset")
|
|
TEST_VARIATION(67, L"ParseDisplayName: unknown displayName (not a proper string) -- MK_E_NOOBJECT")
|
|
TEST_VARIATION(68, L"ParseDisplayName: not null pbc (IBindCtx) => S_OK")
|
|
TEST_VARIATION(69, L"Multiple threads retrieve the sources rowset: check the number of rows")
|
|
TEST_VARIATION(70, L"Aggregate The enumerator, get the sources rowset and call IRowsetInfo::GetSpecification")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCExtendedErrors_RootEnumerator)
|
|
//--------------------------------------------------------------------
|
|
// @class Extended error test for root enumerator
|
|
//
|
|
class TCExtendedErrors_RootEnumerator : public CSourcesRowset {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCExtendedErrors_RootEnumerator,CSourcesRowset);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember S_OK -- with previous error existing
|
|
int Variation_1();
|
|
// @cmember E_INVALIDARG -- with previous error existing
|
|
int Variation_2();
|
|
// @cmember E_NOINTERFACE -- with no previous error existing
|
|
int Variation_3();
|
|
// @cmember DB_S_ERRORSOCCURRED -- with previous error existing
|
|
int Variation_4();
|
|
// @cmember DB_E_ERRORSOCCURRED -- with no previous error existing
|
|
int Variation_5();
|
|
// @cmember E_INVALIDARG -- with previous error existing
|
|
int Variation_6();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCExtendedErrors_RootEnumerator)
|
|
#define THE_CLASS TCExtendedErrors_RootEnumerator
|
|
BEG_TEST_CASE(TCExtendedErrors_RootEnumerator, CSourcesRowset, L"Extended error test for root enumerator")
|
|
TEST_VARIATION(1, L"S_OK -- with previous error existing")
|
|
TEST_VARIATION(2, L"E_INVALIDARG -- with previous error existing")
|
|
TEST_VARIATION(3, L"E_NOINTERFACE -- with no previous error existing")
|
|
TEST_VARIATION(4, L"DB_S_ERRORSOCCURRED -- with previous error existing")
|
|
TEST_VARIATION(5, L"DB_E_ERRORSOCCURRED -- with no previous error existing")
|
|
TEST_VARIATION(6, L"E_INVALIDARG -- with previous error existing")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCSourcesRowset_ProviderEnumerator)
|
|
//--------------------------------------------------------------------
|
|
// @class ISourcesRowset::GetSourcesRowset for standard enumerator
|
|
//
|
|
class TCSourcesRowset_ProviderEnumerator : public CSourcesRowset {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
// @cmember a string to hold SOURCES_PARSENAME for an enumerator assoc with the provider
|
|
WCHAR *m_rgwszSourceParseName;
|
|
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCSourcesRowset_ProviderEnumerator,CSourcesRowset);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember QI with NULL -- E_INVALIDARG
|
|
int Variation_1();
|
|
// @cmember PropertySets N, NULL -- E_INVALIDARG
|
|
int Variation_2();
|
|
// @cmember Property N, NULL -- E_INVALIDARG
|
|
int Variation_3();
|
|
// @cmember riid = IID_NULL, invalid property set -- E_INVALIDARG or E_NOINTERFACE
|
|
int Variation_4();
|
|
// @cmember ppSourcesRowset = NULL -- E_INVALIDARG
|
|
int Variation_5();
|
|
// @cmember QI IDBInitialize -- E_NOINTERFACE
|
|
int Variation_6();
|
|
// @cmember QI IDBProperties -- E_NOINTERFACE
|
|
int Variation_7();
|
|
// @cmember open sources rowset on IRowsetUpdate -- E_NOINTERFACE
|
|
int Variation_8();
|
|
// @cmember open sources rowset on IDBCreateSession -- E_NOINTERFACE
|
|
int Variation_9();
|
|
// @cmember riid = IID_NULL, valid ppSourcesRowset -- E_NOINTERFACE
|
|
int Variation_10();
|
|
// @cmember riid = IID_NULL, valid property -- E_NOINTERFACE
|
|
int Variation_11();
|
|
// @cmember pUnkOuter not NULL, IID_IRowset for pUnkInner -- E_NOINTERFACE or DB_E_NOAGGREGATION
|
|
int Variation_12();
|
|
// @cmember Call GetSourcesRowset while uninitialized -- E_UNEXPECTED
|
|
int Variation_13();
|
|
// @cmember pUnkOuter not NULL -- S_OK or DB_E_NOAGGREGATION
|
|
int Variation_14();
|
|
// @cmember QI IParseDisplayName -- S_OK
|
|
int Variation_15();
|
|
// @cmember QI ISupportErrorInfo -- S_OK
|
|
int Variation_16();
|
|
// @cmember create the enumerator object on IUnknown and QI ISourcesRowset -- S_OK
|
|
int Variation_17();
|
|
// @cmember pISourcesRowset->AddRef, Release -- S_OK
|
|
int Variation_18();
|
|
// @cmember PropertySets 0, NULL -- S_OK
|
|
int Variation_19();
|
|
// @cmember PropertySets 0, valid -- S_OK
|
|
int Variation_20();
|
|
// @cmember PropertySets N, valid -- S_OK
|
|
int Variation_21();
|
|
// @cmember DBPROP_COMMANDTIMEOUT -- S_OK
|
|
int Variation_22();
|
|
// @cmember Property 0, NULL -- S_OK
|
|
int Variation_23();
|
|
// @cmember Property 0, valid -- S_OK
|
|
int Variation_24();
|
|
// @cmember Property N, valid -- S_OK
|
|
int Variation_25();
|
|
// @cmember one prop, DBOPTION_REQUIRED -- S_OK
|
|
int Variation_26();
|
|
// @cmember create enumerator object on IParseDisplayName -- S_OK
|
|
int Variation_27();
|
|
// @cmember open sources rowset on IAccessor -- S_OK
|
|
int Variation_28();
|
|
// @cmember open sources rowset on IColunmsInfo -- S_OK
|
|
int Variation_29();
|
|
// @cmember open sources rowset on IRowsetInfo -- S_OK
|
|
int Variation_30();
|
|
// @cmember open sources rowset on IUnknown -- S_OK
|
|
int Variation_31();
|
|
// @cmember IRowsetInfo->GetSpecification -- S_FALSE
|
|
int Variation_32();
|
|
// @cmember open sources rowset, getnextrow, release, getnextrow -- S_OK
|
|
int Variation_33();
|
|
// @cmember property was not supported -- DB_S_ERRORSOCCURRED
|
|
int Variation_34();
|
|
// @cmember property was not in Rowset property group -- DB_S_ERRORSOCCURRED
|
|
int Variation_35();
|
|
// @cmember property set was not supported - DB_S_ERRORSOCCURRED
|
|
int Variation_36();
|
|
// @cmember property was not cheap to set -- DB_S_ERRORSOCCURRED
|
|
int Variation_37();
|
|
// @cmember invalid colid -- DB_S_ERRORSOCCURRED
|
|
int Variation_38();
|
|
// @cmember invalid dwOptions -- DB_E_ERRORSOCCURRED
|
|
int Variation_39();
|
|
// @cmember invalid vValue -- DB_S_ERRORSOCCURRED
|
|
int Variation_40();
|
|
// @cmember incorrect data type -- DB_S_ERRORSOCCURRED
|
|
int Variation_41();
|
|
// @cmember vValue = VT_EMPTY -- S_OK
|
|
int Variation_42();
|
|
// @cmember open sources rowset twice -- S_OK
|
|
int Variation_43();
|
|
// @cmember open sources rowset, close, open, open -- S_OK
|
|
int Variation_44();
|
|
// @cmember property was not applied to all columns -- DB_S_ERRORSOCCURRED
|
|
int Variation_45();
|
|
// @cmember property was not supported -- DB_E_ERRORSOCCURRED
|
|
int Variation_46();
|
|
// @cmember property was not in Rowset property group -- DB_E_ERRORSOCCURRED
|
|
int Variation_47();
|
|
// @cmember property set was not supported -- DB_E_ERRORSOCCURRED
|
|
int Variation_48();
|
|
// @cmember invalid colid -- DB_E_ERRORSOCCURRED
|
|
int Variation_49();
|
|
// @cmember invalid dwOptions -- DB_E_ERRORSOCCURRED
|
|
int Variation_50();
|
|
// @cmember invalid vValue -- DB_E_ERRORSOCCURRED
|
|
int Variation_51();
|
|
// @cmember incorrect data type -- DB_E_ERRORSOCCURRED
|
|
int Variation_52();
|
|
// @cmember vValue = VT_EMPTY -- S_OK
|
|
int Variation_53();
|
|
// @cmember IParseDisplayName::ParseDisplayName without rowset open -- S_OK
|
|
int Variation_54();
|
|
// @cmember IParseDisplayName::ParseDisplayName -- S_OK
|
|
int Variation_55();
|
|
// @cmember ParseDisplayName: displayName = NULL -- MK_E_NOOBJECT
|
|
int Variation_56();
|
|
// @cmember ParseDisplayName:pchEaten=NULL -- MK_E_NOOBJECT
|
|
int Variation_57();
|
|
// @cmember ParseDisplayName:pIMoniker = NULL -- E_UNEXPECTED
|
|
int Variation_58();
|
|
// @cmember IParseDisplayName::ParseDisplayName, bind Moniker to session object -- E_NOINTERFACE
|
|
int Variation_59();
|
|
// @cmember open sources rowset, getnextrow, not release all rows, getnextrow -- DB_E_ROWSNOTRELEASED
|
|
int Variation_60();
|
|
// @cmember Multiple threads retrieve the sources rowset: check the number of rows
|
|
int Variation_61();
|
|
// @cmember Aggregate The enumerator, get the sources rowset and call IRowsetInfo::GetSpecification
|
|
int Variation_62();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCSourcesRowset_ProviderEnumerator)
|
|
#define THE_CLASS TCSourcesRowset_ProviderEnumerator
|
|
BEG_TEST_CASE(TCSourcesRowset_ProviderEnumerator, CSourcesRowset, L"ISourcesRowset::GetSourcesRowset for standard enumerator")
|
|
TEST_VARIATION(1, L"QI with NULL -- E_INVALIDARG")
|
|
TEST_VARIATION(2, L"PropertySets N, NULL -- E_INVALIDARG")
|
|
TEST_VARIATION(3, L"Property N, NULL -- E_INVALIDARG")
|
|
TEST_VARIATION(4, L"riid = IID_NULL, invalid property set -- E_INVALIDARG or E_NOINTERFACE")
|
|
TEST_VARIATION(5, L"ppSourcesRowset = NULL -- E_INVALIDARG")
|
|
TEST_VARIATION(6, L"QI IDBInitialize -- E_NOINTERFACE")
|
|
TEST_VARIATION(7, L"QI IDBProperties -- E_NOINTERFACE")
|
|
TEST_VARIATION(8, L"open sources rowset on IRowsetUpdate -- E_NOINTERFACE")
|
|
TEST_VARIATION(9, L"open sources rowset on IDBCreateSession -- E_NOINTERFACE")
|
|
TEST_VARIATION(10, L"riid = IID_NULL, valid ppSourcesRowset -- E_NOINTERFACE")
|
|
TEST_VARIATION(11, L"riid = IID_NULL, valid property -- E_NOINTERFACE")
|
|
TEST_VARIATION(12, L"pUnkOuter not NULL, IID_IRowset for pUnkInner -- E_NOINTERFACE or DB_E_NOAGGREGATION")
|
|
TEST_VARIATION(13, L"Call GetSourcesRowset while uninitialized -- E_UNEXPECTED")
|
|
TEST_VARIATION(14, L"pUnkOuter not NULL -- S_OK or DB_E_NOAGGREGATION")
|
|
TEST_VARIATION(15, L"QI IParseDisplayName -- S_OK")
|
|
TEST_VARIATION(16, L"QI ISupportErrorInfo -- S_OK")
|
|
TEST_VARIATION(17, L"create the enumerator object on IUnknown and QI ISourcesRowset -- S_OK")
|
|
TEST_VARIATION(18, L"pISourcesRowset->AddRef, Release -- S_OK")
|
|
TEST_VARIATION(19, L"PropertySets 0, NULL -- S_OK")
|
|
TEST_VARIATION(20, L"PropertySets 0, valid -- S_OK")
|
|
TEST_VARIATION(21, L"PropertySets N, valid -- S_OK")
|
|
TEST_VARIATION(22, L"DBPROP_COMMANDTIMEOUT -- S_OK")
|
|
TEST_VARIATION(23, L"Property 0, NULL -- S_OK")
|
|
TEST_VARIATION(24, L"Property 0, valid -- S_OK")
|
|
TEST_VARIATION(25, L"Property N, valid -- S_OK")
|
|
TEST_VARIATION(26, L"one prop, DBOPTION_REQUIRED -- S_OK")
|
|
TEST_VARIATION(27, L"create enumerator object on IParseDisplayName -- S_OK")
|
|
TEST_VARIATION(28, L"open sources rowset on IAccessor -- S_OK")
|
|
TEST_VARIATION(29, L"open sources rowset on IColunmsInfo -- S_OK")
|
|
TEST_VARIATION(30, L"open sources rowset on IRowsetInfo -- S_OK")
|
|
TEST_VARIATION(31, L"open sources rowset on IUnknown -- S_OK")
|
|
TEST_VARIATION(32, L"IRowsetInfo->GetSpecification -- S_FALSE")
|
|
TEST_VARIATION(33, L"open sources rowset, getnextrow, release, getnextrow -- S_OK")
|
|
TEST_VARIATION(34, L"property was not supported -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(35, L"property was not in Rowset property group -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(36, L"property set was not supported - DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(37, L"property was not cheap to set -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(38, L"invalid colid -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(39, L"invalid dwOptions -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(40, L"invalid vValue -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(41, L"incorrect data type -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(42, L"vValue = VT_EMPTY -- S_OK")
|
|
TEST_VARIATION(43, L"open sources rowset twice -- S_OK")
|
|
TEST_VARIATION(44, L"open sources rowset, close, open, open -- S_OK")
|
|
TEST_VARIATION(45, L"property was not applied to all columns -- DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(46, L"property was not supported -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(47, L"property was not in Rowset property group -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(48, L"property set was not supported -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(49, L"invalid colid -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(50, L"invalid dwOptions -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(51, L"invalid vValue -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(52, L"incorrect data type -- DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(53, L"vValue = VT_EMPTY -- S_OK")
|
|
TEST_VARIATION(54, L"IParseDisplayName::ParseDisplayName without rowset open -- S_OK")
|
|
TEST_VARIATION(55, L"IParseDisplayName::ParseDisplayName -- S_OK")
|
|
TEST_VARIATION(56, L"ParseDisplayName: displayName = NULL -- MK_E_NOOBJECT")
|
|
TEST_VARIATION(57, L"ParseDisplayName:pchEaten=NULL -- MK_E_NOOBJECT")
|
|
TEST_VARIATION(58, L"ParseDisplayName:pIMoniker = NULL -- E_UNEXPECTED")
|
|
TEST_VARIATION(59, L"IParseDisplayName::ParseDisplayName, bind Moniker to session object -- E_NOINTERFACE")
|
|
TEST_VARIATION(60, L"open sources rowset, getnextrow, not release all rows, getnextrow -- DB_E_ROWSNOTRELEASED")
|
|
TEST_VARIATION(61, L"Multiple threads retrieve the sources rowset: check the number of rows")
|
|
TEST_VARIATION(62, L"Aggregate The enumerator, get the sources rowset and call IRowsetInfo::GetSpecification")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCExtendedErrors_ProviderEnumerator)
|
|
//--------------------------------------------------------------------
|
|
// @class Extended error test for standard enumerator
|
|
//
|
|
class TCExtendedErrors_ProviderEnumerator : public CSourcesRowset {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
// @cmember a string to hold SOURCES_PARSENAME for an enumerator assoc with the provider
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCExtendedErrors_ProviderEnumerator,CSourcesRowset);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember S_OK -- with previous error existing
|
|
int Variation_1();
|
|
// @cmember E_INVALIDARG -- with previous error existing
|
|
int Variation_2();
|
|
// @cmember E_NOINTERFACE -- with no previous error existing
|
|
int Variation_3();
|
|
// @cmember DB_S_ERRORSOCCURRED -- with previous error existing
|
|
int Variation_4();
|
|
// @cmember DB_E_ERRORSOCCURRED -- with no previous error existing
|
|
int Variation_5();
|
|
// @cmember E_INVALIDARG -- with previous error existing
|
|
int Variation_6();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCExtendedErrors_ProviderEnumerator)
|
|
#define THE_CLASS TCExtendedErrors_ProviderEnumerator
|
|
BEG_TEST_CASE(TCExtendedErrors_ProviderEnumerator, CSourcesRowset, L"Extended error test for standard enumerator")
|
|
TEST_VARIATION(1, L"S_OK -- with previous error existing")
|
|
TEST_VARIATION(2, L"E_INVALIDARG -- with previous error existing")
|
|
TEST_VARIATION(3, L"E_NOINTERFACE -- with no previous error existing")
|
|
TEST_VARIATION(4, L"DB_S_ERRORSOCCURRED -- with previous error existing")
|
|
TEST_VARIATION(5, L"DB_E_ERRORSOCCURRED -- with no previous error existing")
|
|
TEST_VARIATION(6, L"E_INVALIDARG -- with previous error existing")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// }} END_DECLARE_TEST_CASES()
|
|
|
|
// {{ TCW_TESTMODULE(ThisModule)
|
|
TEST_MODULE(4, ThisModule, gwszModuleDescrip)
|
|
TEST_CASE(1, TCSourcesRowset_RootEnumerator)
|
|
TEST_CASE(2, TCExtendedErrors_RootEnumerator)
|
|
TEST_CASE(3, TCSourcesRowset_ProviderEnumerator)
|
|
TEST_CASE(4, TCExtendedErrors_ProviderEnumerator)
|
|
END_TEST_MODULE()
|
|
// }} TCW_TESTMODULE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCSourcesRowset_RootEnumerator)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCSourcesRowset_RootEnumerator - ISourcesRowset::GetSourcesRowset test for root enumerator
|
|
//| Created: 09/11/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCSourcesRowset_RootEnumerator::Init()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
TESTC(CSourcesRowset::Init());
|
|
|
|
m_clsid = CLSID_OLEDB_ENUMERATOR;
|
|
|
|
// Create an enumerator Object
|
|
// Read the parse name from root enumerator sources rowset to a buffer
|
|
TESTC_(m_hr=CoCreateInstance(m_clsid, NULL,
|
|
GetModInfo()->GetClassContext(), IID_ISourcesRowset,(void **)&m_pISrcRow), S_OK);
|
|
TESTC(ReadParseName(CLSID_OLEDB_ENUMERATOR));
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
// }}
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI with NULL -- E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_1()
|
|
{
|
|
TBEGIN;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
if (!m_pISrcRow)
|
|
return TEST_FAIL;
|
|
|
|
// Pass a NULL pointer
|
|
// Note: From MSDN: QueryInterface returns S_OK if the interface is supported, E_NOINTERFACE if not
|
|
// QueryInterface does not require to return E_INVALIDARG on NULL pointer
|
|
TEST2C_(m_hr=m_pISrcRow->QueryInterface(IID_IParseDisplayName,NULL), E_INVALIDARG, E_POINTER);
|
|
CLEANUP:
|
|
TRETURN;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc PropertySets N, NULL -- E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_2()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// cPropertySets (3, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
3, NULL, (IUnknown **) &m_pIRowset), E_INVALIDARG);
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Property N, NULL -- E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_3()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
m_cDBPropSets = 1;
|
|
m_rgDBPropSets[0].guidPropertySet = DBPROPSET_ROWSET;
|
|
m_rgDBPropSets[0].cProperties = 2;
|
|
m_rgDBPropSets[0].rgProperties = NULL;
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// cProperty (N, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,m_cDBPropSets,
|
|
m_rgDBPropSets, (IUnknown **) &m_pIRowset), E_INVALIDARG);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc riid = IID_NULL, invalid property set -- E_INVALIDARG or E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_4()
|
|
{
|
|
TBEGIN
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// IID_NULL, cPropertySets (N, NULL)
|
|
TEST2C_(m_pISrcRow->GetSourcesRowset(NULL, IID_NULL,3,
|
|
NULL, (IUnknown **) &m_pIRowset), E_INVALIDARG, E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ppSourcesRowset = NULL -- E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_5()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
if (!m_pISrcRow)
|
|
return TEST_FAIL;
|
|
|
|
// ppSourcesRowset is NULL
|
|
if (CHECK(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL, NULL), E_INVALIDARG))
|
|
fResult = TEST_PASS;
|
|
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI IDBInitialize -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_6()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IDBInitialize * pIDBInitialize = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
if (!m_pISrcRow)
|
|
return TEST_FAIL;
|
|
|
|
// Dirty the output params
|
|
pIDBInitialize = (IDBInitialize*)0x12345678;
|
|
|
|
// Enumerator does not require IDBInitialize verifyInterface
|
|
if (!VerifyInterface(m_pISrcRow, IID_IDBInitialize,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pIDBInitialize))
|
|
{
|
|
// If not supported
|
|
fResult = TEST_PASS;
|
|
odtLog << L"IDBInitialize is not supported by the Enumerator." << ENDL;
|
|
}
|
|
else
|
|
fResult = TEST_PASS;
|
|
|
|
SAFE_RELEASE(pIDBInitialize);
|
|
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI IDBProperties -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_7()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IDBProperties * pIDBProperties = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
if (!m_pISrcRow)
|
|
return TEST_FAIL;
|
|
|
|
// Dirty the output params
|
|
pIDBProperties = (IDBProperties*)0x12345678;
|
|
|
|
// Enumerator do not require IDBProperties verifyInterface
|
|
if (!VerifyInterface(m_pISrcRow, IID_IDBProperties,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pIDBProperties))
|
|
{
|
|
// If not supported
|
|
fResult = TEST_PASS;
|
|
odtLog << L"IDBProperties is not supported by the Enumerator." << ENDL;
|
|
}
|
|
else
|
|
fResult = TEST_PASS;
|
|
|
|
SAFE_RELEASE(pIDBProperties);
|
|
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IRowsetUpdate -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_8()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetUpdate *pIRowsetUpdate = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
pIRowsetUpdate = (IRowsetUpdate*)0x12345678;
|
|
|
|
// Sources rowset is read-only
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetUpdate,
|
|
0, NULL, (IUnknown **) &pIRowsetUpdate), E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == pIRowsetUpdate);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IDBCreateSession -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_9()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IDBCreateSession* pIDBCreateSession = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
pIDBCreateSession = (IDBCreateSession*)0x12345678;
|
|
|
|
// For a session object interface
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IDBCreateSession,
|
|
0, NULL, (IUnknown **) &pIDBCreateSession), E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == pIDBCreateSession);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc riid = IID_NULL, valid ppSourcesRowset -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_10()
|
|
{
|
|
TBEGIN
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// IID_NULL
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_NULL,
|
|
0, NULL, (IUnknown **) &m_pIRowset), E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc riid = IID_NULL, valid property -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_11()
|
|
{
|
|
TBEGIN
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Initialize the properties
|
|
m_cDBPropSets = 0;
|
|
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// IID_NULL, cProperty (N, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_NULL,m_cDBPropSets,
|
|
m_rgDBPropSets, (IUnknown **) &m_pIRowset), E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pUnkOuter not NULL, IID_IRowset for pUnkInner -- E_NOINTERFACE or DB_E_NOAGGREGATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_12()
|
|
{
|
|
TBEGIN
|
|
IUnknown *pIUnkOuter = NULL;
|
|
IUnknown *pIUnkInner = NULL;
|
|
HRESULT hr;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Create an outer rowset object
|
|
if (CHECK(m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset, 0, NULL, &pIUnkOuter), S_OK))
|
|
{
|
|
CAggregate Aggregate(pIUnkOuter);
|
|
|
|
// Dirty the output params
|
|
pIUnkInner = INVALID(IUnknown*);
|
|
|
|
// Create an inner rowset object on IID_IRowset
|
|
CHECK(hr = m_pISrcRow->GetSourcesRowset(&Aggregate, IID_IRowset, 0,
|
|
NULL, &pIUnkInner), DB_E_NOAGGREGATION);
|
|
|
|
//Inner object cannot RefCount the outer object - COM rule for CircularRef
|
|
COMPARE(Aggregate.GetRefCount(), 1);
|
|
COMPARE(pIUnkInner == NULL, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
// Release the outer rowset object
|
|
SAFE_RELEASE_(pIUnkOuter);
|
|
// No rowset returned
|
|
COMPARE(pIUnkInner, NULL);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Call GetSourcesRowset while uninitialized -- E_UNEXPECTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_13()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IDBInitialize * pIDBInitialize = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Check to see if IDBInitialize is supported
|
|
if (!VerifyInterface(m_pISrcRow, IID_IDBInitialize,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pIDBInitialize))
|
|
{
|
|
odtLog<<L"IDBInitialize not supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
0,NULL,(IUnknown **)&m_pIRowset), E_UNEXPECTED);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pUnkOuter not NULL -- S_OK or DB_E_NOAGGREGATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_14()
|
|
{
|
|
TBEGIN
|
|
IUnknown *pIUnkOuter = NULL;
|
|
IUnknown *pIUnkInner = NULL;
|
|
HRESULT hr;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Create an outer rowset object
|
|
if (CHECK(hr = m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL, &pIUnkOuter), S_OK))
|
|
{
|
|
CAggregate Aggregate(pIUnkOuter);
|
|
|
|
// Dirty the output params
|
|
pIUnkInner = INVALID(IUnknown*);
|
|
|
|
// Create an inner rowset object on IID_IUnknown
|
|
hr = m_pISrcRow->GetSourcesRowset(&Aggregate, IID_IUnknown, 0, NULL, &pIUnkInner);
|
|
|
|
// Check the return code
|
|
if (FAILED(hr))
|
|
{
|
|
CHECK(hr, DB_E_NOAGGREGATION);
|
|
COMPARE(NULL == pIUnkInner, TRUE);
|
|
}
|
|
else
|
|
{
|
|
Aggregate.SetUnkInner(pIUnkInner);
|
|
CHECK(hr, S_OK);
|
|
COMPARE(NULL != pIUnkInner, TRUE);
|
|
COMPARE(Aggregate.VerifyAggregationQI(hr, IID_IRowset), TRUE);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
// Release the outer rowset object
|
|
SAFE_RELEASE_(pIUnkOuter);
|
|
// Release the inner rowset object
|
|
SAFE_RELEASE_(pIUnkInner);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI IParseDisplayName -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_15()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName * pIParseDisplayName = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Should be able to QI IParseDisplayName
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pIParseDisplayName));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI ISupportErrorInfo -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_16()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ISupportErrorInfo * pISupportErrorInfo = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Should be able to QI ISupportErrorInfo
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_ISupportErrorInfo,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pISupportErrorInfo));
|
|
TESTC(NULL != pISupportErrorInfo);
|
|
TEST2C_(m_hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_ISourcesRowset), S_OK, S_FALSE);
|
|
TEST2C_(m_hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_ISupportErrorInfo), S_OK, S_FALSE);
|
|
TEST2C_(m_hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_IParseDisplayName), S_OK, S_FALSE);
|
|
TESTC_(m_hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_IRowset), S_FALSE);
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pISupportErrorInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc create the enumerator object on IUnknown and QI ISourcesRowset -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_17()
|
|
{
|
|
IUnknown * pIUnknown = NULL;
|
|
ISourcesRowset *pISrcRow = NULL;
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Create an enumerator Object
|
|
TESTC_(m_hr = CoCreateInstance(m_clsid, NULL,
|
|
GetModInfo()->GetClassContext(), IID_IUnknown,(void **)&pIUnknown), S_OK);
|
|
|
|
TESTC(VerifyInterface(pIUnknown, IID_ISourcesRowset,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pISrcRow));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIUnknown);
|
|
SAFE_RELEASE(pISrcRow);
|
|
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pISourcesRowset->AddRef, Release -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_18()
|
|
{
|
|
ISourcesRowset *pISourcesRowset = NULL;
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Create an enumerator Object
|
|
// Read the parse name from root enumerator sources rowset to a buffer
|
|
TESTC_(m_hr=CoCreateInstance(CLSID_OLEDB_ENUMERATOR, NULL,
|
|
GetModInfo()->GetClassContext(), IID_ISourcesRowset,(void **)&pISourcesRowset), S_OK);
|
|
|
|
// Make sure we have enumerate object
|
|
TESTC(NULL != pISourcesRowset);
|
|
|
|
// increment and decrement the ref counter on pISourcesRowset
|
|
pISourcesRowset->AddRef();
|
|
pISourcesRowset->Release();
|
|
pISourcesRowset->AddRef();
|
|
pISourcesRowset->AddRef();
|
|
pISourcesRowset->Release();
|
|
pISourcesRowset->Release();
|
|
|
|
// check that in the end the reference counter is 0
|
|
if (0 != pISourcesRowset->Release())
|
|
{
|
|
odtLog << "The ref counter is not 0; make sure this is not a bug\n";
|
|
}
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc PropertySets 0, NULL -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_19()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// cPropertySets (0, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL, (IUnknown **) &m_pIRowset), S_OK);
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc PropertySets 0, valid -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_20()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property
|
|
SetOneProperty(DBPROP_BOOKMARKS, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// cPropertySets (0, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc PropertySets N, valid -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_21()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Initialize the properties
|
|
m_cDBPropSets = 0;
|
|
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// cPropertySets (N, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property is set correctly
|
|
if (m_cDBPropSets)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COMMANDTIMEOUT -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_22()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property
|
|
SetOneProperty(DBPROP_COMMANDTIMEOUT, DBPROPOPTIONS_OPTIONAL, 0, VT_I4);
|
|
|
|
m_hr = m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset);
|
|
|
|
TESTC(S_OK == m_hr || DB_S_ERRORSOCCURRED == m_hr);
|
|
if (SettableProperty(DBPROP_COMMANDTIMEOUT, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
TESTC_(m_hr, S_OK);
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
}
|
|
else if (!SupportedProperty(DBPROP_COMMANDTIMEOUT, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
TESTC_(m_hr, DB_S_ERRORSOCCURRED);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
}
|
|
else
|
|
{
|
|
// supported but not settable
|
|
// Make sure the property is set correctly
|
|
if (S_OK == m_hr)
|
|
{
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
}
|
|
else
|
|
{
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
}
|
|
}
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Property 0, NULL -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_23()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set property to 0 NULL in the rgProperties Structure
|
|
SetOneProperty(NULL, DBPROPOPTIONS_OPTIONAL, 0);
|
|
m_rgDBPropSets[0].cProperties = 0;
|
|
m_rgDBPropSets[0].rgProperties = NULL;
|
|
|
|
// cProperty (0, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Property 0, valid -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_24()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property
|
|
SetOneProperty(DBPROP_BOOKMARKS, DBPROPOPTIONS_REQUIRED, 0);
|
|
m_rgDBPropSets[0].cProperties = 0;
|
|
|
|
// cProperty (0, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Property N, valid -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_25()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Initialize the properties
|
|
m_cDBPropSets = 0;
|
|
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// cProperty (N, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property is set correctly
|
|
if (m_cDBPropSets)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc one prop, DBOPTION_REQUIRED -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_26()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Initialize the properties
|
|
m_cDBPropSets = 0;
|
|
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// cProperty (N, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property is set correctly
|
|
if (m_cDBPropSets)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc create enumerator object on IParseDisplayName -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_27()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName* pIParseDisplayName = NULL;
|
|
ISourcesRowset * pISrcRow = NULL;
|
|
|
|
// Create an enumerator Object
|
|
TESTC_(m_hr = CoCreateInstance(m_clsid, NULL, GetModInfo()->GetClassContext(),
|
|
IID_IParseDisplayName,(void **)&pIParseDisplayName), S_OK);
|
|
|
|
TESTC(VerifyInterface(pIParseDisplayName, IID_ISourcesRowset,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pISrcRow));
|
|
|
|
// Verify the IParseDisplayName
|
|
TESTC(VerifyParseDisplayName_root(pIParseDisplayName));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(pISrcRow);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IAccessor -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_28()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IAccessor * pIAccessor = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IAccessor,
|
|
0, NULL, (IUnknown **) &pIAccessor), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(VerifyInterface(pIAccessor, IID_IRowset,
|
|
ROWSET_INTERFACE,(IUnknown **)&m_pIRowset));
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, pIAccessor));
|
|
TESTC(CheckRowsInfo());
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIAccessor);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IColunmsInfo -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_29()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cCol;
|
|
ULONG ColCount = 7; // For root enumerator, there is 7 columns
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IColumnsInfo,
|
|
0, NULL, (IUnknown **) &m_pIColumnsInfo), S_OK);
|
|
|
|
TESTC(NULL != m_pIColumnsInfo);
|
|
|
|
TESTC_(m_pIColumnsInfo->GetColumnInfo(&m_cColumns,
|
|
&m_rgInfo, &m_pStringsBuffer), S_OK);
|
|
|
|
// Check to see if the Bookmark Property is on
|
|
if (!m_rgInfo[0].iOrdinal)
|
|
TESTC(GetProperty(DBPROP_BOOKMARKS, DBPROPSET_ROWSET, m_pIColumnsInfo));
|
|
|
|
// Skip bookmark column, check each column info
|
|
for(cCol=1; cCol<ColCount; cCol++)
|
|
{
|
|
if (!memcmp(m_rgInfo[cCol].pwszName,
|
|
g_rgwszColumnName[cCol-1], sizeof(g_rgwszColumnName[cCol-1])))
|
|
{
|
|
TESTC(m_rgInfo[cCol].iOrdinal == cCol);
|
|
TESTC(m_rgInfo[cCol].wType == g_ColumnType[cCol-1]);
|
|
}
|
|
}
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_FREE(m_pStringsBuffer);
|
|
SAFE_FREE(m_rgInfo);
|
|
SAFE_RELEASE(m_pIColumnsInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IRowsetInfo -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_30()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetInfo * pIRowsetInfo = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetInfo,
|
|
0, NULL, (IUnknown **) &pIRowsetInfo), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(VerifyInterface(pIRowsetInfo, IID_IRowset,
|
|
ROWSET_INTERFACE,(IUnknown **)&m_pIRowset));
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, pIRowsetInfo));
|
|
TESTC(CheckRowsInfo());
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IUnknown -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_31()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IUnknown * pIUnknown = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset is returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IUnknown,
|
|
0, NULL, &pIUnknown), S_OK);
|
|
// Check column data and data in each row
|
|
TESTC(VerifyInterface(pIUnknown, IID_IRowset,
|
|
ROWSET_INTERFACE,(IUnknown **)&m_pIRowset));
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, pIUnknown));
|
|
TESTC(CheckRowsInfo());
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIUnknown);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IRowsetInfo->GetSpecification -- S_FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_32()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetInfo * pIRowsetInfo = NULL;
|
|
IUnknown * pSpecification = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetInfo,
|
|
0, NULL, (IUnknown **) &pIRowsetInfo), S_OK);
|
|
|
|
TESTC(NULL != pIRowsetInfo);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(VerifyInterface(pIRowsetInfo, IID_IRowset,
|
|
ROWSET_INTERFACE,(IUnknown **)&m_pIRowset));
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, pIRowsetInfo));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// The provider does not have an object that created the rowset
|
|
// The pointer to the interface should be NULL
|
|
TESTC_(pIRowsetInfo->GetSpecification(IID_IUnknown, (IUnknown **)&pSpecification), S_FALSE);
|
|
TESTC(NULL == pSpecification);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pSpecification);
|
|
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset, getnextrow, release, getnextrow -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_33()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
HROW hRow[1] = {NULL};
|
|
HROW * pHRow = hRow;
|
|
DBCOUNTITEM cRow = 0;
|
|
ULONG cRowCounter = 0;
|
|
IRowset * pIRowset = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
TESTC_(m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL,(IUnknown **) &pIRowset), S_OK);
|
|
|
|
fResult = TEST_PASS;
|
|
// count rows in the rowset
|
|
while(S_OK == (m_hr=pIRowset->GetNextRows(NULL,0,1,&cRow,&pHRow)))
|
|
{
|
|
cRowCounter++;
|
|
if ( !COMPARE(cRow, 1) // check the number of returned rows
|
|
|| !CHECK(pIRowset->ReleaseRows(cRow, hRow,NULL,NULL,NULL),S_OK))
|
|
{
|
|
fResult = TEST_FAIL;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
if ( !COMPARE(DB_S_ENDOFROWSET, m_hr)
|
|
|| !COMPARE(cRow, 0)
|
|
|| !CHECK(pIRowset->RestartPosition(NULL), S_OK))
|
|
{
|
|
fResult = TEST_FAIL;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
while((m_hr=pIRowset->GetNextRows(NULL,0,1,&cRow,&pHRow)) == S_OK)
|
|
{
|
|
cRowCounter--;
|
|
if ( !COMPARE(cRow, 1)
|
|
|| !CHECK(pIRowset->ReleaseRows(cRow, hRow,NULL,NULL,NULL),S_OK))
|
|
{
|
|
fResult = TEST_FAIL;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
if ( !COMPARE(DB_S_ENDOFROWSET, m_hr)
|
|
|| !COMPARE(cRowCounter, 0)
|
|
|| !COMPARE(cRow, 0))
|
|
fResult = TEST_FAIL;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not supported -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_34()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
HRESULT hExpected = DB_S_ERRORSOCCURRED;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two unsupported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((!SupportedProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if (0 >= count)
|
|
hExpected = S_OK;
|
|
|
|
// try to call ISourcesRowset::GetSourcesRowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), hExpected);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property status were set correctly
|
|
TESTC((count < 2) || DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[1].dwStatus);
|
|
TESTC((count == 0) || DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not in Rowset property group -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_35()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two supported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
// Set the property not in the Rowset property group
|
|
SetOneProperty(DBPROP_AUTH_MASK_PASSWORD, DBPROPOPTIONS_OPTIONAL, count);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count == 2 )
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-2].dwStatus);
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property set was not supported - DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_36()
|
|
{
|
|
return VerifyNonRowsetPropSet(COLUMN_COUNT_ROOT);
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not cheap to set -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_37()
|
|
{
|
|
// TO DO: Add your own code here
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(38)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid colid -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_38()
|
|
{
|
|
return VerifyInvalidColID(DBPROPOPTIONS_OPTIONAL);
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(39)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid dwOptions -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_39()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
HRESULT Exphr = DB_E_ERRORSOCCURRED;
|
|
DBPROPSTATUS dbPropStatus = DBPROPSTATUS_NOTSUPPORTED;
|
|
DBPROPOPTIONS InvalidOptions = -997;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two unsupported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<1))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
// Set a settable property with dwOptions InvalidOptions
|
|
SetOneProperty(DBPROP_IRowsetLocate, InvalidOptions, count);
|
|
|
|
// Set the correct return code and status
|
|
if (SupportedProperty(DBPROP_IRowsetLocate, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
dbPropStatus = DBPROPSTATUS_BADOPTION;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(dbPropStatus == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(40)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid vValue -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_40()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if(SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
count++;
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Set next property which is settalbe
|
|
for(++cProp; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow, ENUMERATOR_INTERFACE))
|
|
{
|
|
// Set this property with dwOptions DBPROPOPTIONS_OPTIONAL
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, 1);
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (2 > count)
|
|
{
|
|
odtLog <<L"No second Settable Properties where supported by the Enumerator.\n";
|
|
}
|
|
|
|
// set a bad variant type for this property
|
|
VariantInit(&m_rgDBPropSets[0].rgProperties[count-1].vValue);
|
|
m_rgDBPropSets[0].rgProperties[count-1].vValue.vt = VT_BOOL;
|
|
m_rgDBPropSets[0].rgProperties[count-1].vValue.intVal = 20;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(count < 2 || DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(41)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc incorrect data type -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_41()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
count++;
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Set next property which is settalbe
|
|
for(++cProp; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow, ENUMERATOR_INTERFACE))
|
|
{
|
|
// Set this property with dwOptions DBPROPOPTIONS_OPTIONAL
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, 1);
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (2 > count)
|
|
{
|
|
odtLog <<L"No second Settable Properties where supported by the Enumerator.\n";
|
|
}
|
|
|
|
m_rgDBPropSets[0].rgProperties[count-1].vValue.vt = VT_R4; // none of the possible props is DBTYPE_R4
|
|
V_R4(&m_rgDBPropSets[0].rgProperties[count-1].vValue) = (float)0.28;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(count < 2 || DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(42)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc vValue = VT_EMPTY -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_42()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_PASS;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_OPTIONAL
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, 0);
|
|
m_rgDBPropSets[0].rgProperties[0].vValue.vt = VT_EMPTY;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(43)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset twice -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_43()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open one rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,(IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Open another rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowsetInfo,0,NULL,(IUnknown **) &m_pIRowsetInfo), S_OK);
|
|
fResult = TEST_PASS;;
|
|
|
|
CLEANUP:
|
|
// Close the first rowset
|
|
SAFE_RELEASE_(m_pIRowset);
|
|
// Close the second rowset
|
|
SAFE_RELEASE_(m_pIRowsetInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(44)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset, close, open, open -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_44()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open one rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,(IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Close the rowset
|
|
SAFE_RELEASE_(m_pIRowset);
|
|
|
|
// Open rowset again
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,(IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Open another rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowsetInfo,0,NULL,(IUnknown **) &m_pIRowsetInfo), S_OK);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
// Close the first rowset
|
|
SAFE_RELEASE_(m_pIRowset);
|
|
// Close the second rowset
|
|
SAFE_RELEASE_(m_pIRowsetInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(45)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not applied to all columns -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_45()
|
|
{
|
|
// TO DO: Add your own code here
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(46)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not supported -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_46()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two unsupported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((!SupportedProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if (count < 1)
|
|
{
|
|
odtLog << "could not identify 2 unsupported properties\n";
|
|
return TEST_PASS;
|
|
}
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status were set correctly
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[1].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(47)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not in Rowset property group -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_47()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two supported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
// Set the property not in the Rowset property group
|
|
SetOneProperty(DBPROP_AUTH_CACHE_AUTHINFO, DBPROPOPTIONS_REQUIRED, count);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count == 2)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-2].dwStatus);
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(48)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property set was not supported -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_48()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two supported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
// Set the property not in the Rowset property group
|
|
SetOneProperty(DBPROP_INDEX_AUTOUPDATE, DBPROPOPTIONS_REQUIRED, count);
|
|
m_rgDBPropSets[0].guidPropertySet = DBPROPSET_INDEX;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count == 2)
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count-2].dwStatus);
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(49)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid colid -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_49()
|
|
{
|
|
return VerifyInvalidColID(DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(50)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid dwOptions -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_50()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
DBPROPSTATUS dbPropStatus = DBPROPSTATUS_NOTSUPPORTED;
|
|
DBPROPOPTIONS InvalidOptions = -997;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two unsupported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<1)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
// Set a settable property with dwOptions InvalidOptions
|
|
SetOneProperty(DBPROP_IRowsetLocate, InvalidOptions, count);
|
|
|
|
// Set the correct return code and status
|
|
if (SupportedProperty(DBPROP_IRowsetLocate, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
dbPropStatus = DBPROPSTATUS_BADOPTION;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(dbPropStatus == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(51)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid vValue -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_51()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// Set next property which is settalbe
|
|
for(cProp++; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow, ENUMERATOR_INTERFACE))
|
|
break;
|
|
}
|
|
|
|
if (cProp >= PROPERTY_COUNT)
|
|
{
|
|
odtLog <<L"No second Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set this property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 1);
|
|
VariantInit(&m_rgDBPropSets[0].rgProperties[1].vValue);
|
|
m_rgDBPropSets[0].rgProperties[1].vValue.vt = DBTYPE_DBTIMESTAMP;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[1].dwStatus);
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(52)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc incorrect data type -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_52()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// Set next property which is settable
|
|
for(cProp++; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow, ENUMERATOR_INTERFACE))
|
|
break;
|
|
}
|
|
|
|
if (count >= PROPERTY_COUNT)
|
|
{
|
|
odtLog <<L"No second Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set this property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 1);
|
|
m_rgDBPropSets[0].rgProperties[1].vValue.vt = VT_R4;
|
|
V_R4(&m_rgDBPropSets[0].rgProperties[1].vValue) = (float)3.14;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[1].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(53)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc vValue = VT_EMPTY -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_53()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
m_rgDBPropSets[0].rgProperties[0].vValue.vt = VT_EMPTY;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(54)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IParseDisplayName::ParseDisplayName without rowset open -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_54()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName * pIParseDisplayName = NULL;
|
|
IMoniker * pIMoniker = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pIParseDisplayName));
|
|
|
|
TESTC(VerifyParseDisplayName_root(pIParseDisplayName));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIMoniker);
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(55)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IParseDisplayName::ParseDisplayName -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_55()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName* pIParseDisplayName = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
TESTC(VerifyParseDisplayName_root(pIParseDisplayName));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(56)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ParseDisplayName: displayName = NULL -- MK_E_NOOBJECT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_56()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG chEaten = 0;
|
|
IParseDisplayName * pIParseDisplayName = NULL;
|
|
IMoniker * pIMoniker = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
// Display name is NULL
|
|
TESTC_(m_hr=pIParseDisplayName->ParseDisplayName(NULL,
|
|
NULL,&chEaten,&pIMoniker), MK_E_NOOBJECT);
|
|
|
|
TESTC(NULL == pIMoniker);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(57)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ParseDisplayName:pchEaten=NULL -- MK_E_NOOBJECT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_57()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName * pIParseDisplayName = NULL;
|
|
IMoniker * pIMoniker = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
// pchEaten = NULL
|
|
TESTC_(m_hr=pIParseDisplayName->ParseDisplayName(NULL,
|
|
g_rgwszParseName[0],NULL,&pIMoniker), MK_E_NOOBJECT);
|
|
|
|
TESTC(NULL == pIMoniker);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(58)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ParseDisplayName:pIMoniker = NULL -- E_UNEXPECTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_58()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG chEaten = 0;
|
|
IParseDisplayName* pIParseDisplayName = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
// ppIMoniker = NULL
|
|
TESTC_(m_hr=pIParseDisplayName->ParseDisplayName(NULL,
|
|
g_rgwszParseName[0],&chEaten,NULL), E_INVALIDARG);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(59)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IParseDisplayName::ParseDisplayName, bind Moniker to session object -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_59()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG chEaten = 0;
|
|
IParseDisplayName * pIParseDisplayName = NULL;
|
|
IMoniker * pIMoniker = NULL;
|
|
IDBCreateCommand * pIDBCrtCmd = NULL;
|
|
IUnknown * pIUnknown = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(NULL != m_pIRowset);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
// Get moniker
|
|
TESTC_(m_hr=pIParseDisplayName->ParseDisplayName(NULL,
|
|
g_rgwszParseName[0],&chEaten,&pIMoniker), S_OK);
|
|
TESTC(NULL != pIMoniker);
|
|
TESTC(VerifyInterface(pIMoniker, IID_IUnknown,
|
|
UNKNOWN_INTERFACE,&pIUnknown));
|
|
|
|
// Binds the moniker with the IDBCreateCommand interface
|
|
TESTC_(BindMoniker(pIMoniker,0,IID_IDBCreateCommand,
|
|
(LPVOID*)&pIDBCrtCmd), E_NOINTERFACE);
|
|
|
|
// We should not have pIDBCrtCmd
|
|
TESTC(NULL == pIDBCrtCmd);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIUnknown);
|
|
SAFE_RELEASE(pIMoniker);
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(60)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset, getnextrow, not release all rows, getnextrow -- DB_E_ROWSNOTRELEASED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_60()
|
|
{
|
|
// uses it's very own m_pISrcRowset to check that
|
|
// calling IRowset::GetNextRows() without releasing
|
|
// the previously retrieved row handles results in
|
|
// DB_E_ROWSNOTRELEASED if DBPROP_CANHOLDROWSET is VARIANT_FALSE
|
|
return GetNextRowsWithoutRelAllRows();
|
|
}
|
|
// }}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(61)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc check that all mutual dso & enum are in rowset -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_61()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
HROW *pHRow = NULL;
|
|
DBCOUNTITEM cRows = 0;
|
|
IRowset *pIRowset = NULL;
|
|
HACCESSOR hAccessor = NULL;
|
|
DBLENGTH cRowSize = 0;
|
|
DBCOUNTITEM cBinding = 0;
|
|
DBBINDING *rgBinding = NULL;
|
|
LONG_PTR rgColToBind[1];
|
|
void *pData1 =NULL;
|
|
void *pData2 =NULL;
|
|
ULONG cCount = 0;
|
|
HRESULT hr;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
rgColToBind[0]=1; // bind the first column, SOURCES_NAME
|
|
|
|
TESTC_(m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL,(IUnknown **) &pIRowset), S_OK);
|
|
|
|
TESTC_(GetAccessorAndBindings(
|
|
pIRowset,
|
|
DBACCESSOR_ROWDATA,
|
|
&hAccessor,
|
|
&rgBinding,
|
|
&cBinding,
|
|
&cRowSize,
|
|
DBPART_VALUE|DBPART_STATUS|DBPART_LENGTH,
|
|
USE_COLS_TO_BIND_ARRAY,
|
|
FORWARD,
|
|
NO_COLS_BY_REF,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
DBTYPE_EMPTY,
|
|
1,
|
|
(LONG_PTR *)rgColToBind),S_OK);
|
|
|
|
fResult = TEST_PASS;
|
|
//prime loop with first row
|
|
if (S_OK==(hr = pIRowset->GetNextRows(NULL,0,1,&cRows, &pHRow)) || CHECK(hr, DB_S_ENDOFROWSET) )
|
|
{
|
|
//allocate memory
|
|
SAFE_ALLOC(pData1, BYTE, cRowSize);
|
|
SAFE_ALLOC(pData2, BYTE, cRowSize);
|
|
while (S_OK == hr)
|
|
{
|
|
//get the data of the current row
|
|
if ( !CHECK(pIRowset->GetData(*pHRow,hAccessor,pData1),S_OK)
|
|
|| !CHECK(pIRowset->ReleaseRows(1,pHRow,NULL,NULL,NULL),S_OK))
|
|
fResult = TEST_FAIL;
|
|
PROVIDER_FREE(pHRow);
|
|
//goto the next row if it is there
|
|
if (S_OK==(hr = pIRowset->GetNextRows(NULL,0,1,&cRows, &pHRow)) || hr == DB_S_ENDOFROWSET )
|
|
{
|
|
if(cRows==0)
|
|
{
|
|
break;
|
|
}
|
|
//get the data of the new current row
|
|
if (!CHECK(pIRowset->GetData(*pHRow,hAccessor,pData2),S_OK))
|
|
fResult = TEST_FAIL;
|
|
//compare SOURCES_NAME for each row, there will be double where the clsid is both an enum and a dso
|
|
if (CompareBuffer( pData1, pData2, cBinding, rgBinding,
|
|
m_pIMalloc, FALSE, FALSE, COMPARE_ONLY))
|
|
{
|
|
cCount++;
|
|
}
|
|
}
|
|
}
|
|
//free mem
|
|
if (pHRow)
|
|
{
|
|
if (!CHECK(pIRowset->ReleaseRows(1,pHRow,NULL,NULL,NULL),S_OK))
|
|
fResult = TEST_FAIL;
|
|
PROVIDER_FREE(pHRow);
|
|
}
|
|
}
|
|
//compare the number of doubles listed in Sources Rowset with the number of doubles
|
|
//read form the keys
|
|
if (!COMPARE(cCount, g_cDSOANDENUM))
|
|
fResult = TEST_FAIL;
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(pData1);
|
|
PROVIDER_FREE(pData2);
|
|
SAFE_RELEASE(pIRowset);
|
|
FreeAccessorBindings(cBinding,rgBinding);
|
|
if(hAccessor && m_pISrcRow)
|
|
{
|
|
IAccessor * pIAccessor;
|
|
ULONG cRefCounts=ULONG_MAX;
|
|
|
|
VerifyInterface(m_pISrcRow, IID_IAccessor, ENUMERATOR_INTERFACE, (IUnknown**)&pIAccessor);
|
|
if (pIAccessor)
|
|
{
|
|
pIAccessor->ReleaseAccessor(hAccessor, &cRefCounts);
|
|
SAFE_RELEASE(pIAccessor);
|
|
COMPARE(cRefCounts,0);
|
|
}
|
|
}
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(62)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Ask IID_IRowsetChange on sources rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_62()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// cPropertySets (0, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetChange,
|
|
0, NULL, (IUnknown **) &pIRowsetChange), E_NOINTERFACE);
|
|
|
|
TESTC(NULL == pIRowsetChange);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
return fResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(63)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Ask IID_IRowsetUpdate on sources rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_63()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetUpdate *pIRowsetUpdate = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// cPropertySets (0, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetUpdate,
|
|
0, NULL, (IUnknown **) &pIRowsetUpdate), E_NOINTERFACE);
|
|
|
|
TESTC(NULL == pIRowsetUpdate);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
return fResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(64)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Ask DBPROP_IRowsetChange on sources rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_64()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
const ULONG cPropSets = 1;
|
|
DBPROPSET rgPropSets[cPropSets];
|
|
const ULONG cProperties = 1;
|
|
DBPROP rgProperties[cProperties];
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// set DBPROP_IRowsetChange to VARIANT_TRUE, required
|
|
FILL_PROP_SET(rgPropSets[0], cProperties, rgProperties, DBPROPSET_ROWSET);
|
|
FILL_PROP(rgProperties[0], DBPROP_IRowsetChange, VT_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
cPropSets, rgPropSets, (IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
|
|
// set DBPROP_IRowsetChange to VARIANT_TRUE, optional
|
|
FILL_PROP(rgProperties[0], DBPROP_IRowsetChange, VT_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
cPropSets, rgPropSets, (IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
TESTC(NULL != m_pIRowset);
|
|
|
|
TESTC(!VerifyInterface(m_pIRowset, IID_IRowsetChange, ROWSET_INTERFACE,
|
|
(IUnknown**)&pIRowsetChange));
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// set DBPROP_IRowsetChange to VARIANT_FALSE, required
|
|
FILL_PROP_SET(rgPropSets[0], cProperties, rgProperties, DBPROPSET_ROWSET);
|
|
FILL_PROP(rgProperties[0], DBPROP_IRowsetChange, VT_BOOL, V_BOOL,
|
|
VARIANT_FALSE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TEST2C_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
cPropSets, rgPropSets, (IUnknown **)&m_pIRowset), S_OK, DB_E_ERRORSOCCURRED);
|
|
TESTC(S_OK == m_hr || NULL == m_pIRowset);
|
|
TESTC(S_OK == m_hr || DBPROPSTATUS_NOTSUPPORTED == rgProperties[0].dwStatus);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(S_OK != m_hr || CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(S_OK != m_hr || CheckRowsInfo());
|
|
|
|
// set DBPROP_IRowsetChange to VARIANT_FALSE, optional
|
|
FILL_PROP(rgProperties[0], DBPROP_IRowsetChange, VT_BOOL, V_BOOL,
|
|
VARIANT_FALSE, DBPROPOPTIONS_OPTIONAL);
|
|
|
|
TEST2C_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
cPropSets, rgPropSets, (IUnknown **)&m_pIRowset), S_OK, DB_S_ERRORSOCCURRED);
|
|
TESTC(NULL != m_pIRowset);
|
|
TESTC(S_OK == m_hr || DBPROPSTATUS_NOTSUPPORTED == rgProperties[0].dwStatus);
|
|
|
|
TESTC(!VerifyInterface(m_pIRowset, IID_IRowsetChange, ROWSET_INTERFACE,
|
|
(IUnknown**)&pIRowsetChange));
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
return fResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(65)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Ask for DBPROP_IRowsetUpdate on sources rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_65()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetUpdate *pIRowsetUpdate = NULL;
|
|
const ULONG cPropSets = 1;
|
|
DBPROPSET rgPropSets[cPropSets];
|
|
const ULONG cProperties = 1;
|
|
DBPROP rgProperties[cProperties];
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// cPropertySets (0, NULL)
|
|
FILL_PROP_SET(rgPropSets[0], cProperties, rgProperties, DBPROPSET_ROWSET);
|
|
FILL_PROP(rgProperties[0], DBPROP_IRowsetUpdate, VT_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
cPropSets, rgPropSets, (IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
FILL_PROP(rgProperties[0], DBPROP_IRowsetUpdate, VT_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
cPropSets, rgPropSets, (IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
TESTC(NULL != m_pIRowset);
|
|
|
|
TESTC(!VerifyInterface(m_pIRowset, IID_IRowsetUpdate, ROWSET_INTERFACE,
|
|
(IUnknown**)&pIRowsetUpdate));
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
return fResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(66)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI for IRowsetChange and IRowsetUpdate on a common sources rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_66()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
IRowsetUpdate *pIRowsetUpdate = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// cPropertySets (0, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
TESTC(!VerifyInterface(m_pIRowset, IID_IRowsetChange,
|
|
ROWSET_INTERFACE, (IUnknown**)&pIRowsetChange));
|
|
TESTC(!VerifyInterface(m_pIRowset, IID_IRowsetUpdate,
|
|
ROWSET_INTERFACE, (IUnknown**)&pIRowsetUpdate));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
return fResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(67)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ParseDisplayName: unknown displayName (not a proper string) -- MK_E_NOOBJECT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_67()
|
|
{
|
|
TBEGIN
|
|
IParseDisplayName *pIParseDisplayName = NULL;
|
|
ULONG chEaten;
|
|
IMoniker *pmkOut = NULL; //Address of output variable that receives the
|
|
//resulting IMoniker interface pointer
|
|
|
|
WCHAR pwszParseName[3000] = L"";
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
if (0 < g_cOLEDBProvNames + g_cOLEDBProvMDPNames)
|
|
{
|
|
wcscpy(pwszParseName, g_rgwszParseName[0]);
|
|
wcscat(pwszParseName, L"!new");
|
|
m_hr = pIParseDisplayName->ParseDisplayName(NULL, pwszParseName,
|
|
&chEaten, &pmkOut);
|
|
if (MK_E_NOOBJECT != m_hr)
|
|
{
|
|
CHECK(m_hr, MK_E_SYNTAX);
|
|
}
|
|
}
|
|
|
|
TEST2C_(m_hr = pIParseDisplayName->ParseDisplayName(NULL, L"Unsignificant",
|
|
&chEaten, &pmkOut), MK_E_NOOBJECT, MK_E_SYNTAX);
|
|
TESTC(MK_E_NOOBJECT != m_hr || 0 == chEaten);
|
|
TESTC(NULL == pmkOut);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(pmkOut);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(68)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ParseDisplayName: not null pbc (IBindCtx) => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_68()
|
|
{
|
|
TBEGIN
|
|
IParseDisplayName *pIParseDisplayName = NULL;
|
|
ULONG chEaten;
|
|
IBindCtx *pbc = NULL;
|
|
IDBInitialize *pIDBInitialize = NULL;
|
|
IMoniker *pmkOut = NULL; //Address of output variable that receives the
|
|
//resulting IMoniker interface pointer
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
TESTC_(m_hr = CreateBindCtx(NULL, &pbc), S_OK);
|
|
|
|
TESTC_PROVIDER(0 < g_cOLEDBProvNames + g_cOLEDBProvMDPNames);
|
|
|
|
TESTC_(m_hr = pIParseDisplayName->ParseDisplayName(pbc, g_rgwszParseName[0],
|
|
&chEaten, &pmkOut), S_OK);
|
|
TESTC(NULL != pmkOut);
|
|
|
|
TESTC_(m_hr = pmkOut->BindToObject(pbc, NULL, IID_IDBInitialize,
|
|
(void**)&pIDBInitialize), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBInitialize);
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(pmkOut);
|
|
SAFE_RELEASE(pbc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(69)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multiple threads retrieve the sources rowset: check the number of rows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_69()
|
|
{
|
|
TBEGIN
|
|
unsigned IDThread[nThreads];
|
|
HANDLE hThread[nThreads];
|
|
CInParam ThreadParam[nThreads];
|
|
ULONG nIndex;
|
|
ULONG cRefRowsNo = 0;
|
|
IRowset *pIRowset = NULL;
|
|
|
|
SAFE_RELEASE(m_pIRowset);
|
|
TESTC_(m_hr = m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL, (IUnknown**)&pIRowset), S_OK);
|
|
TESTC_(m_hr = CountNoOfRows(pIRowset, &cRefRowsNo), S_OK);
|
|
|
|
for (nIndex = 0; nIndex < nThreads; nIndex++)
|
|
{
|
|
m_rgResult[nIndex] = E_FAIL;
|
|
m_rgRowsNo[nIndex] = 0;
|
|
m_rgRowset[nIndex] = NULL;
|
|
|
|
ThreadParam[nIndex].i = nIndex;
|
|
ThreadParam[nIndex].pObject = this;
|
|
hThread[nIndex] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&ThreadParam[nIndex],
|
|
0,
|
|
&IDThread[nIndex]);
|
|
TESTC(hThread[nIndex] != 0);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, hThread, TRUE, INFINITE);
|
|
for (nIndex=0; nIndex<nThreads; nIndex++)
|
|
{
|
|
CloseHandle(hThread[nIndex]);
|
|
CHECK(m_rgResult[nIndex], S_OK);
|
|
COMPARE(m_rgRowsNo[nIndex] == cRefRowsNo, TRUE);
|
|
m_pIRowset = m_rgRowset[nIndex];
|
|
TESTC(CheckRowsInfo());
|
|
}
|
|
|
|
CLEANUP:
|
|
for (nIndex=0; nIndex<nThreads; nIndex++)
|
|
{
|
|
SAFE_RELEASE(m_rgRowset[nIndex]);
|
|
}
|
|
m_pIRowset = NULL;
|
|
SAFE_RELEASE(pIRowset);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(70)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Aggregate The enumerator, get the sources rowset and call IRowsetInfo::GetSpecification
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_RootEnumerator::Variation_70()
|
|
{
|
|
return VerifyGetSpec_AggregatedEnum();
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCSourcesRowset_RootEnumerator::Terminate()
|
|
{
|
|
// Delete enumerator object
|
|
SAFE_RELEASE(m_pISrcRow);
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CSourcesRowset::Terminate());
|
|
} //}}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCExtendedErrors_RootEnumerator)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCExtendedErrors_RootEnumerator - Extended error test for root enumerator
|
|
//| Created: 09/18/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCExtendedErrors_RootEnumerator::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if (CSourcesRowset::Init())
|
|
{
|
|
m_clsid = CLSID_OLEDB_ENUMERATOR;
|
|
|
|
// Create an enumerator Object
|
|
if (CHECK(m_hr = CoCreateInstance(m_clsid, NULL,
|
|
GetModInfo()->GetClassContext(), IID_ISourcesRowset,(void **)&m_pISrcRow), S_OK))
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
// }}
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc S_OK -- with previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_RootEnumerator::Variation_1()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Cause an error on the current thread
|
|
m_pExtError->CauseError();
|
|
|
|
// cPropertySets (0, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Do extended check
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_INVALIDARG -- with previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_RootEnumerator::Variation_2()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Cause an error on the current thread
|
|
m_pExtError->CauseError();
|
|
|
|
// ppSourcesRowset is NULL
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset, 0, NULL, NULL), E_INVALIDARG);
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_NOINTERFACE -- with no previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_RootEnumerator::Variation_3()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Sources rowset is read-only
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowsetUpdate,
|
|
0,NULL, (IUnknown **)&pIRowsetUpdate), E_NOINTERFACE);
|
|
// No rowset should be returned
|
|
TESTC(NULL == pIRowsetUpdate);
|
|
fResult = XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr) ? TEST_PASS: TEST_FAIL;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DB_S_ERRORSOCCURRED -- with previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_RootEnumerator::Variation_4()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
HRESULT hExpected;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Set two unsupported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((!SupportedProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, count);
|
|
count++;
|
|
}
|
|
}
|
|
hExpected = (0 == count)? S_OK: DB_S_ERRORSOCCURRED;
|
|
|
|
// Cause an error on the current thread
|
|
m_pExtError->CauseError();
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), hExpected);
|
|
|
|
// Do extended check
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_ROOT, m_pIRowset));
|
|
TESTC(CheckRowsInfo());
|
|
|
|
// Make sure the property status were set correctly
|
|
if (count == 2 )
|
|
TESTC(m_rgDBPropSets[0].rgProperties[count-2].dwStatus == DBPROPSTATUS_NOTSUPPORTED);
|
|
if (count >= 1 )
|
|
TESTC(m_rgDBPropSets[0].rgProperties[count-1].dwStatus == DBPROPSTATUS_NOTSUPPORTED);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DB_E_ERRORSOCCURRED -- with no previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_RootEnumerator::Variation_5()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) || (NULL != m_pExtError));
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// Set next property which is settalbe
|
|
for(cProp++; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow, ENUMERATOR_INTERFACE))
|
|
break;
|
|
}
|
|
|
|
// Set this property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
if (cProp < PROPERTY_COUNT)
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 1);
|
|
m_rgDBPropSets[0].rgProperties[1].vValue.vt = VT_R4;
|
|
V_R4(&m_rgDBPropSets[0].rgProperties[1].vValue) = (float)11.23;
|
|
}
|
|
else
|
|
{
|
|
m_rgDBPropSets[0].rgProperties[0].vValue.vt = VT_R4;
|
|
V_R4(&m_rgDBPropSets[0].rgProperties[0].vValue) = (float)11.23;
|
|
}
|
|
|
|
m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset, m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset);
|
|
|
|
// Do extended check
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
TESTC_(m_hr, DB_E_ERRORSOCCURRED);
|
|
// Check that a Rowset was not generated
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[1].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_INVALIDARG -- with previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_RootEnumerator::Variation_6()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Cause an error on the current thread
|
|
m_pExtError->CauseError();
|
|
|
|
// ppSourcesRowset is NULL
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,
|
|
IID_IRowset, 1, NULL, (IUnknown **) &m_pIRowset), E_INVALIDARG);
|
|
TESTC(NULL == m_pIRowset);
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCExtendedErrors_RootEnumerator::Terminate()
|
|
{
|
|
// Delete enumerator object
|
|
SAFE_RELEASE(m_pISrcRow);
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CSourcesRowset::Terminate());
|
|
} //}}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCSourcesRowset_ProviderEnumerator)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCSourcesRowset_ProviderEnumerator - ISourcesRowset::GetSourcesRowset for standard enumerator
|
|
//| Created: 09/26/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCSourcesRowset_ProviderEnumerator::Init()
|
|
{
|
|
WCHAR *wszProviderName = NULL;
|
|
WCHAR *wszDBMSName = NULL;
|
|
WCHAR *wszDBMSNameCopy = NULL;
|
|
ULONG cPropSets = 0;
|
|
const ULONG cPropIDs = 2;
|
|
DBPROPID rgPropIDs[2];
|
|
DBPROPIDSET PropIDSet;
|
|
DBPROPSET *rgSupportedPropSets = NULL;
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG i;
|
|
HRESULT hr;
|
|
BOOL fProviderFound = FALSE;
|
|
DBPROPSET *rgInitPropSets = NULL;
|
|
ULONG cInitPropSets = 0;
|
|
IDBProperties *pIDBProperties = NULL;
|
|
IDBInitialize *pIDBInitialize = NULL;
|
|
WCHAR *pwszEnumName = NULL;
|
|
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
m_rgwszSourceParseName = NULL;
|
|
TESTC(CSourcesRowset::Init());
|
|
|
|
//Create Session Object so test can see what provider it was asked to run against
|
|
TESTC(SUCCEEDED(hr = CoCreateInstance(m_pThisTestModule->m_ProviderClsid,NULL,
|
|
GetModInfo()->GetClassContext(),IID_IDBInitialize,(void **)&pIDBInitialize)));
|
|
// Get IDBProperties Pointer
|
|
TESTC(VerifyInterface(pIDBInitialize, IID_IDBProperties, DATASOURCE_INTERFACE, (IUnknown**)&pIDBProperties));
|
|
// Setup the arrays needed for init, based on string LTM passed to us
|
|
TESTC(GetInitProps(&cInitPropSets, &rgInitPropSets));
|
|
// Set the properties before we Initialize
|
|
TESTC(SUCCEEDED(pIDBProperties->SetProperties(cInitPropSets, rgInitPropSets)));
|
|
// Initialize (connect so i can get the provider name)
|
|
m_pThisTestModule->m_pError->Validate((hr = pIDBInitialize->Initialize()),
|
|
LONGSTRING(__FILE__), __LINE__,S_OK);
|
|
|
|
//set prop that will Get Provider Name
|
|
rgPropIDs[0] = DBPROP_PROVIDERNAME;
|
|
//set prop that will Get Provider Name
|
|
rgPropIDs[1] = DBPROP_DBMSNAME;
|
|
|
|
PropIDSet.cPropertyIDs = cPropIDs;
|
|
PropIDSet.rgPropertyIDs = rgPropIDs;
|
|
PropIDSet.guidPropertySet = DBPROPSET_DATASOURCEINFO;
|
|
|
|
//get provider name
|
|
hr = pIDBProperties->GetProperties(1, &PropIDSet, &cPropSets, &rgSupportedPropSets);
|
|
|
|
if ( DB_S_ERRORSOCCURRED != hr
|
|
&& DB_E_ERRORSOCCURRED != hr)
|
|
TESTC_(hr, S_OK);
|
|
TESTC(1==cPropSets);
|
|
//disconnect
|
|
TESTC_(hr = pIDBInitialize->Uninitialize(), S_OK);
|
|
|
|
//loop through the array of source name looking for the one with the provider's name and the word enumerator
|
|
if (GetModInfo()->GetEnumerator())
|
|
for (i=0;i< g_cTotalEntries;i++)
|
|
{
|
|
//look for the provider's enumerator in key read from registry now that test knows which provider to run against
|
|
if (!g_rgwszSourceName)
|
|
continue;
|
|
if ( !(wcsstr(_wcsupr(g_rgwszSourceName[i]), L" ENUMERATOR")==0)
|
|
&& (wcscmp(_wcsupr(g_rgwszSourceName[i]), _wcsupr(GetModInfo()->GetEnumerator()))==0)
|
|
)
|
|
{
|
|
// Get the CLSID from Provider String
|
|
fProviderFound = TRUE;
|
|
CLSIDFromString(g_rgwszSourceParseName[i],&m_clsid);
|
|
m_rgwszSourceParseName = wcsDuplicate(g_rgwszSourceParseName[i]);
|
|
pwszEnumName = wcsDuplicate(GetModInfo()->GetEnumerator());
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!fProviderFound)
|
|
{
|
|
odtLog << "Enumerator name, as indicated through ENUMNAME in init string could not be found\n";
|
|
odtLog << "Find an enumerator with similar name to the name of provider\n";
|
|
|
|
//get wchar of provider name
|
|
if (DBPROPSTATUS_OK == rgSupportedPropSets[0].rgProperties[0].dwStatus)
|
|
wszProviderName = wcstok(BSTR2WSTR(rgSupportedPropSets[0].rgProperties[0].vValue.bstrVal ), L"."); // Always returns first string
|
|
else
|
|
wszProviderName = NULL;
|
|
//get wchar of dbms name
|
|
if (DBPROPSTATUS_OK == rgSupportedPropSets[0].rgProperties[0].dwStatus)
|
|
wszDBMSName = wcstok(BSTR2WSTR(rgSupportedPropSets[0].rgProperties[1].vValue.bstrVal ), L"."); // Always returns first string
|
|
else
|
|
wszDBMSName = NULL;
|
|
|
|
//hack
|
|
if (wszDBMSName)
|
|
{
|
|
//Copy the pointer
|
|
wszDBMSNameCopy = wszDBMSName;
|
|
|
|
for (i=0;i<3;i++)
|
|
wszDBMSName++;
|
|
}
|
|
|
|
//make Enum string
|
|
//this assumes that the enumerator name will have the provider name and the word 'Enumerator' in it's name
|
|
for (i=0; !fProviderFound && i< g_cTotalEntries;i++)
|
|
{
|
|
//look for the provider's enumerator in key read from registry now that test knows which provider to run against
|
|
if (
|
|
(!(wcsstr(_wcsupr(g_rgwszSourceName[i]), L" ENUMERATOR")==0))
|
|
&& ( ( wszProviderName
|
|
&& !(wcsstr(_wcsupr(g_rgwszSourceName[i]), _wcsupr(wszProviderName))==0))
|
|
|| (wszDBMSName
|
|
&& !(wcsstr(_wcsupr(g_rgwszSourceName[i]), _wcsupr(wszDBMSName))==0)))
|
|
)
|
|
{
|
|
// Get the CLSID from Provider String
|
|
fProviderFound = TRUE;
|
|
CLSIDFromString(g_rgwszSourceParseName[i],&m_clsid);
|
|
m_rgwszSourceParseName = wcsDuplicate(g_rgwszSourceParseName[i]);;
|
|
pwszEnumName = wcsDuplicate(g_rgwszSourceName[i]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!fProviderFound)
|
|
{
|
|
odtLog << L"An Enumerator was not found for this Provider. " << ENDL;
|
|
fResult = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
else
|
|
odtLog << "Provider to be tested: " << pwszEnumName << "\n";
|
|
|
|
// Create an enumerator Object of provider test will run against
|
|
// Read the parse name from Provider's enumerator sources rowset to a buffer
|
|
TESTC_(m_hr = CoCreateInstance(m_clsid, NULL,
|
|
GetModInfo()->GetClassContext(), IID_ISourcesRowset,(void **)&m_pISrcRow), S_OK);
|
|
TESTC(ReadParseName(m_clsid));
|
|
TESTC(MarkSupportedProperties(m_clsid));
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBProperties);
|
|
SAFE_RELEASE(pIDBInitialize);
|
|
SAFE_FREE(pwszEnumName);
|
|
|
|
PROVIDER_FREE(wszProviderName);
|
|
PROVIDER_FREE(wszDBMSNameCopy);
|
|
|
|
FreeProperties(&cInitPropSets, &rgInitPropSets);
|
|
FreeProperties(&cPropSets, &rgSupportedPropSets);
|
|
return fResult;
|
|
// }}
|
|
}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI with NULL -- E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_1()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Pass a NULL pointer
|
|
TESTC_(m_hr=m_pISrcRow->QueryInterface(IID_IParseDisplayName,NULL), E_INVALIDARG);
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc PropertySets N, NULL -- E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_2()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// cPropertySets (3, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
3, NULL, (IUnknown **) &m_pIRowset), E_INVALIDARG);
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Property N, NULL -- E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_3()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
m_cDBPropSets = 1;
|
|
m_rgDBPropSets[0].guidPropertySet = DBPROPSET_ROWSET;
|
|
m_rgDBPropSets[0].cProperties = 2;
|
|
m_rgDBPropSets[0].rgProperties = NULL;
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// cProperty (N, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,m_cDBPropSets,
|
|
m_rgDBPropSets, (IUnknown **) &m_pIRowset), E_INVALIDARG);
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc riid = IID_NULL, invalid property set -- E_INVALIDARG or E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_4()
|
|
{
|
|
TBEGIN
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// IID_NULL, cPropertySets (N, NULL)
|
|
TEST2C_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_NULL,
|
|
3, NULL, (IUnknown **) &m_pIRowset), E_INVALIDARG, E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ppSourcesRowset = NULL -- E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_5()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// ppSourcesRowset is NULL
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset, 0, NULL, NULL), E_INVALIDARG);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI IDBInitialize -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_6()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IDBInitialize * pIDBInitialize = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
pIDBInitialize = (IDBInitialize*)0x12345678;
|
|
|
|
|
|
fResult = TEST_PASS;
|
|
// Enumerator do not require IDBInitialize verifyInterface
|
|
if (!VerifyInterface(m_pISrcRow, IID_IDBInitialize,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pIDBInitialize))
|
|
// If not supported
|
|
odtLog << L"IDBInitialize is not supported by the Enumerator." << ENDL;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBInitialize);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI IDBProperties -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_7()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IDBProperties * pIDBProperties = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
pIDBProperties = (IDBProperties*)0x12345678;
|
|
|
|
fResult = TEST_PASS;
|
|
// Enumerator do not require IDBProperties verifyInterface
|
|
if (!VerifyInterface(m_pISrcRow, IID_IDBProperties,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pIDBProperties))
|
|
// If not supported
|
|
odtLog << L"IDBProperties is not supported by the Enumerator." << ENDL;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBProperties);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IRowsetUpdate -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_8()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetUpdate *pIRowsetUpdate = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
pIRowsetUpdate = (IRowsetUpdate*)0x12345678;
|
|
|
|
// Sources rowset is read-only
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetUpdate,
|
|
0, NULL, (IUnknown **) &pIRowsetUpdate), E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == pIRowsetUpdate);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IDBCreateSession -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_9()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IDBCreateSession* pIDBCreateSession = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
pIDBCreateSession = (IDBCreateSession*)0x12345678;
|
|
|
|
// For a session object interface
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IDBCreateSession,
|
|
0, NULL, (IUnknown **) &pIDBCreateSession), E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == pIDBCreateSession);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBCreateSession);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc riid = IID_NULL, valid ppSourcesRowset -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_10()
|
|
{
|
|
TBEGIN
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// IID_NULL
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_NULL,
|
|
0, NULL, (IUnknown **) &m_pIRowset), E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc riid = IID_NULL, valid property -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_11()
|
|
{
|
|
TBEGIN
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Initialize the properties
|
|
m_cDBPropSets = 0;
|
|
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// IID_NULL, cProperty (N, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_NULL,m_cDBPropSets,
|
|
m_rgDBPropSets, (IUnknown **) &m_pIRowset), E_NOINTERFACE);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pUnkOuter not NULL, IID_IRowset for pUnkInner -- E_NOINTERFACE or DB_E_NOAGGREGATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_12()
|
|
{
|
|
return VerifyNotIUnknownInAggregation();
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Call GetSourcesRowset while uninitialized -- E_UNEXPECTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_13()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IDBInitialize * pIDBInitialize = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Check to see if IDBInitialize is supported
|
|
if (!VerifyInterface(m_pISrcRow, IID_IDBInitialize, ENUMERATOR_INTERFACE, (IUnknown **)&pIDBInitialize))
|
|
{
|
|
odtLog<<L"IDBInitialize not supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Dirty the output params
|
|
m_pIRowset = (IRowset*)0x12345678;
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset, 0, NULL,(IUnknown **)&m_pIRowset), E_UNEXPECTED);
|
|
|
|
// No rowset returned
|
|
TESTC(NULL == m_pIRowset);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pUnkOuter not NULL -- S_OK or DB_E_NOAGGREGATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_14()
|
|
{
|
|
return VerifySourcesRowsetAggregation();
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI IParseDisplayName -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_15()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName *pIParseDisplayName = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Should be able to QI IParseDisplayName
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pIParseDisplayName));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc QI ISupportErrorInfo -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_16()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ISupportErrorInfo *pISupportErrorInfo = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Should be able to QI ISupportErrorInfo
|
|
if (VerifyInterface(m_pISrcRow, IID_ISupportErrorInfo,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pISupportErrorInfo))
|
|
{
|
|
TESTC(NULL != pISupportErrorInfo);
|
|
TEST2C_(m_hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_ISourcesRowset), S_OK, S_FALSE);
|
|
TEST2C_(m_hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_ISupportErrorInfo), S_OK, S_FALSE);
|
|
TEST2C_(m_hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_IParseDisplayName), S_OK, S_FALSE);
|
|
TESTC_(m_hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_IRowset), S_FALSE);
|
|
}
|
|
else
|
|
{
|
|
TESTC(NULL == pISupportErrorInfo);
|
|
}
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pISupportErrorInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc create the enumerator object on IUnknown and QI ISourcesRowset -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_17()
|
|
{
|
|
IUnknown * pIUnknown = NULL;
|
|
ISourcesRowset *pISrcRow = NULL;
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Create an enumerator Object
|
|
TESTC_(m_hr = CoCreateInstance(m_clsid, NULL,
|
|
GetModInfo()->GetClassContext(), IID_IUnknown,(void **)&pIUnknown), S_OK);
|
|
|
|
TESTC(VerifyInterface(pIUnknown, IID_ISourcesRowset, ENUMERATOR_INTERFACE, (IUnknown **)&pISrcRow));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIUnknown);
|
|
SAFE_RELEASE(pISrcRow);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pISourcesRowset->AddRef, Release -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_18()
|
|
{
|
|
|
|
ISourcesRowset *pISourcesRowset = NULL;
|
|
IParseDisplayName *pIParseDisplayName = NULL;
|
|
IMoniker *pIMoniker = NULL;
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG chEaten = 0;
|
|
|
|
// Create an enumerator Object
|
|
// Read the parse name from root enumerator sources rowset to a buffer
|
|
TESTC_(m_hr=CoCreateInstance(CLSID_OLEDB_ENUMERATOR, NULL,
|
|
GetModInfo()->GetClassContext(), IID_IParseDisplayName,(void **)&pIParseDisplayName), S_OK);
|
|
TESTC_(m_hr=pIParseDisplayName->ParseDisplayName(NULL, m_rgwszSourceParseName,
|
|
&chEaten, &pIMoniker), S_OK);
|
|
TESTC_(BindMoniker(pIMoniker, 0, IID_ISourcesRowset, (LPVOID*)&pISourcesRowset), S_OK);
|
|
|
|
// Make sure we have enumerate object
|
|
TESTC(NULL != pISourcesRowset);
|
|
|
|
// increment and decrement the ref counter on pISourcesRowset
|
|
SAFE_RELEASE(pIMoniker);
|
|
pISourcesRowset->AddRef();
|
|
pISourcesRowset->Release();
|
|
pISourcesRowset->AddRef();
|
|
pISourcesRowset->AddRef();
|
|
pISourcesRowset->Release();
|
|
pISourcesRowset->Release();
|
|
|
|
// check that in the end the reference counter is 0
|
|
if (0 != pISourcesRowset->Release())
|
|
{
|
|
odtLog << "The ref counter is not 0; make sure this is not a bug\n";
|
|
}
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(pIMoniker);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc PropertySets 0, NULL -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_19()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// cPropertySets (0, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset, 0, NULL, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc PropertySets 0, valid -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_20()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property
|
|
SetOneProperty(DBPROP_BOOKMARKS, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// cPropertySets (0, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc PropertySets N, valid -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_21()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Initialize the properties
|
|
m_cDBPropSets = 0;
|
|
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
break;
|
|
}
|
|
|
|
// cPropertySets (N, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property is set correctly
|
|
if (m_cDBPropSets)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COMMANDTIMEOUT -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_22()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property
|
|
SetOneProperty(DBPROP_COMMANDTIMEOUT, DBPROPOPTIONS_OPTIONAL, 0, VT_I4);
|
|
|
|
m_hr = m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset);
|
|
|
|
TESTC(S_OK == m_hr || DB_S_ERRORSOCCURRED == m_hr);
|
|
if (SettableProperty(DBPROP_COMMANDTIMEOUT, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
TESTC_(m_hr, S_OK);
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
}
|
|
else if (!SupportedProperty(DBPROP_COMMANDTIMEOUT, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
TESTC_(m_hr, DB_S_ERRORSOCCURRED);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
}
|
|
else
|
|
{
|
|
// supported but not settable => read only
|
|
// Make sure the property is set correctly
|
|
if (S_OK == m_hr)
|
|
{
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[0].dwStatus
|
|
|| DBPROPSTATUS_NOTSET == m_rgDBPropSets[0].rgProperties[0].dwStatus
|
|
|| DBPROPSTATUS_NOTSETTABLE == m_rgDBPropSets[0].rgProperties[0].dwStatus
|
|
);
|
|
}
|
|
}
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Property 0, NULL -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_23()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set property to 0 NULL in the rgProperties Structure
|
|
SetOneProperty(0, DBPROPOPTIONS_OPTIONAL, 0);
|
|
m_rgDBPropSets[0].cProperties = 0;
|
|
m_rgDBPropSets[0].rgProperties = NULL;
|
|
|
|
// cProperty (0, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Property 0, valid -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_24()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property
|
|
SetOneProperty(DBPROP_BOOKMARKS, DBPROPOPTIONS_REQUIRED, 0);
|
|
m_rgDBPropSets[0].cProperties = 0;
|
|
|
|
// cProperty (0, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Property N, valid -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_25()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Initialize the properties
|
|
m_cDBPropSets = 0;
|
|
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, 0);
|
|
break;
|
|
}
|
|
|
|
// cProperty (N, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property is set correctly
|
|
if (m_cDBPropSets)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc one prop, DBOPTION_REQUIRED -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_26()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Initialize the properties
|
|
m_cDBPropSets = 0;
|
|
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
break;
|
|
}
|
|
|
|
// cProperty (N, valid)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
m_cDBPropSets, m_rgDBPropSets, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property is set correctly
|
|
if (m_cDBPropSets)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc create enumerator object on IParseDisplayName -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_27()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName* pIParseDisplayName = NULL;
|
|
ISourcesRowset * pISrcRow = NULL;
|
|
|
|
// Create an enumerator Object
|
|
TESTC_(m_hr = CoCreateInstance(m_clsid, NULL, GetModInfo()->GetClassContext(),
|
|
IID_IParseDisplayName,(void **)&pIParseDisplayName), S_OK);
|
|
|
|
TESTC(VerifyInterface(pIParseDisplayName, IID_ISourcesRowset,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pISrcRow));
|
|
|
|
// Verify the IParseDisplayName
|
|
TESTC(VerifyParseDisplayName_std(pIParseDisplayName));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(pISrcRow);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IAccessor -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_28()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IAccessor * pIAccessor = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IAccessor, 0, NULL, (IUnknown **) &pIAccessor), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(VerifyInterface(pIAccessor, IID_IRowset, ROWSET_INTERFACE,(IUnknown **)&m_pIRowset));
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, pIAccessor));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIAccessor);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IColunmsInfo -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_29()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG ColCount = COLUMN_COUNT_STD; // For provider enumerator, there are 6 columns
|
|
ULONG cCol;
|
|
ULONG cOrdinal; // the ordinal of the column compared
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IColumnsInfo,
|
|
0, NULL, (IUnknown **) &m_pIColumnsInfo), S_OK);
|
|
|
|
TESTC(NULL != m_pIColumnsInfo);
|
|
|
|
TESTC_(m_pIColumnsInfo->GetColumnInfo(&m_cColumns, &m_rgInfo, &m_pStringsBuffer), S_OK);
|
|
|
|
cCol = 0;
|
|
cOrdinal = 1;
|
|
if (!m_rgInfo[0].iOrdinal)
|
|
{
|
|
// Check to see if the Bookmark Property is on
|
|
TESTC(GetProperty(DBPROP_BOOKMARKS, DBPROPSET_ROWSET, m_pIColumnsInfo));
|
|
TESTC(m_cColumns == ColCount);
|
|
cCol = 1;
|
|
}
|
|
else
|
|
TESTC(m_cColumns == ColCount-1);
|
|
|
|
// if there is a bookmark column then Skip the bookmark column
|
|
for(; cCol < m_cColumns; cCol++, cOrdinal++)
|
|
{
|
|
if (!memcmp(m_rgInfo[cCol].pwszName,
|
|
g_rgwszColumnName[cOrdinal-1], sizeof(g_rgwszColumnName[cOrdinal-1])))
|
|
{
|
|
TESTC(m_rgInfo[cCol].iOrdinal == cOrdinal);
|
|
TESTC(m_rgInfo[cCol].wType == g_ColumnType[cOrdinal-1]);
|
|
}
|
|
}
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(m_pStringsBuffer);
|
|
SAFE_FREE(m_rgInfo);
|
|
SAFE_RELEASE(m_pIColumnsInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IRowsetInfo -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_30()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetInfo * pIRowsetInfo = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetInfo,
|
|
0, NULL, (IUnknown **) &pIRowsetInfo), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(VerifyInterface(pIRowsetInfo, IID_IRowset, ROWSET_INTERFACE,(IUnknown **)&m_pIRowset));
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, pIRowsetInfo));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset on IUnknown -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_31()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IUnknown * pIUnknown = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset is returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IUnknown, 0, NULL, &pIUnknown), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(VerifyInterface(pIUnknown, IID_IRowset, ROWSET_INTERFACE,(IUnknown **)&m_pIRowset));
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, pIUnknown));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIUnknown);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IRowsetInfo->GetSpecification -- S_FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_32()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetInfo * pIRowsetInfo = NULL;
|
|
IUnknown * pSpecification = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Sources rowset returned
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowsetInfo,
|
|
0, NULL, (IUnknown **) &pIRowsetInfo), S_OK);
|
|
|
|
TESTC(NULL != pIRowsetInfo);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(VerifyInterface(pIRowsetInfo, IID_IRowset, ROWSET_INTERFACE,(IUnknown **)&m_pIRowset));
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, pIRowsetInfo));
|
|
|
|
// The provider does not have an object that created the rowset
|
|
// The pointer to the interface should be NULL
|
|
TESTC_(pIRowsetInfo->GetSpecification(IID_IUnknown, (IUnknown **)&pSpecification), S_FALSE);
|
|
TESTC(NULL == pSpecification);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pSpecification);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset, getnextrow, release, getnextrow -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_33()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
HROW hRow[1] = {NULL};
|
|
HROW *pHRow = hRow;
|
|
DBCOUNTITEM cRow = 0;
|
|
ULONG cRowCounter = 0;
|
|
IRowset *pIRowset = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
TESTC_(m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL,(IUnknown **) &pIRowset), S_OK);
|
|
|
|
fResult = TEST_PASS;
|
|
while((m_hr=pIRowset->GetNextRows(NULL,0,1,&cRow,&pHRow)) == S_OK)
|
|
{
|
|
cRowCounter++;
|
|
if ( !COMPARE(cRow, 1)
|
|
|| !CHECK(pIRowset->ReleaseRows(cRow, hRow,NULL,NULL,NULL),S_OK))
|
|
{
|
|
fResult = TEST_FAIL;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
if ( !CHECK(m_hr, DB_S_ENDOFROWSET)
|
|
|| !COMPARE(cRow, 0)
|
|
|| !CHECK(pIRowset->RestartPosition(NULL), S_OK))
|
|
{
|
|
fResult = TEST_FAIL;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
while((m_hr=pIRowset->GetNextRows(NULL,0,1,&cRow,&pHRow)) == S_OK)
|
|
{
|
|
cRowCounter--;
|
|
if ( !COMPARE(cRow, 1)
|
|
|| !CHECK(pIRowset->ReleaseRows(cRow, hRow,NULL,NULL,NULL),S_OK))
|
|
{
|
|
fResult = TEST_FAIL;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
if ( !CHECK(m_hr, DB_S_ENDOFROWSET)
|
|
|| !COMPARE (cRowCounter, 0)
|
|
|| !COMPARE(cRow, 0))
|
|
fResult = TEST_FAIL;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not supported -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_34()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
IDBProperties* pIDBProperties = NULL;
|
|
ULONG cProp = 0;
|
|
HRESULT hExpected = DB_S_ERRORSOCCURRED;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two unsupported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((!SupportedProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if (0 == count)
|
|
hExpected = S_OK;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), hExpected);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property status were set correctly
|
|
if (count == 2 )
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count-2].dwStatus);
|
|
if (count >= 1 )
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not in Rowset property group -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_35()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two supported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, count);
|
|
count++;
|
|
}
|
|
|
|
// Set the property not in the Rowset property group
|
|
SetOneProperty(DBPROP_AUTH_MASK_PASSWORD, DBPROPOPTIONS_OPTIONAL, count);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count == 2 )
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-2].dwStatus);
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property set was not supported - DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_36()
|
|
{
|
|
return VerifyNonRowsetPropSet(COLUMN_COUNT_STD);
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not cheap to set -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_37()
|
|
{
|
|
// TO DO: Add your own code here
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(38)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid colid -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_38()
|
|
{
|
|
return VerifyInvalidColID(DBPROPOPTIONS_OPTIONAL);
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(39)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid dwOptions -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_39()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
DBPROPSTATUS dbPropStatus = DBPROPSTATUS_NOTSUPPORTED;
|
|
DBPROPOPTIONS InvalidOptions = 99;
|
|
ULONG count = 0;
|
|
IDBProperties *pIDBProperties = NULL;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one unsupported property
|
|
//supported propert assumes IDBProperties is available for the INTERFACE requested
|
|
//this is an optional interface of the SourcesRowset enumerator
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<1))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, count);
|
|
count++;
|
|
}
|
|
}
|
|
// Set a settable property with dwOptions InvalidOptions
|
|
SetOneProperty(DBPROP_IRowsetLocate, InvalidOptions, count);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
|
|
// Set the correct return code and status
|
|
if (SupportedProperty(DBPROP_IRowsetLocate, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
dbPropStatus = DBPROPSTATUS_BADOPTION;
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(dbPropStatus == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(40)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid vValue -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_40()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// Set next property which is settalbe
|
|
for(cProp++; cProp<PROPERTY_COUNT; cProp++)
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
// Set this property with dwOptions DBPROPOPTIONS_OPTIONAL
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, 1);
|
|
count++;
|
|
break;
|
|
}
|
|
|
|
// it's sure that the prop is of type bool
|
|
m_rgDBPropSets[0].rgProperties[count-1].vValue.vt = VT_BOOL;
|
|
m_rgDBPropSets[0].rgProperties[count-1].vValue.intVal = 12; // some other value
|
|
m_rgDBPropSets[0].rgProperties[count-1].dwOptions = DBPROPOPTIONS_OPTIONAL; // some other value
|
|
// than VARIANT_TRUE and VARIANT_FALSE
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(count < 2 || DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(41)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc incorrect data type -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_41()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// Set next property which is settalbe
|
|
for(cProp++; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
if (2 > count)
|
|
{
|
|
odtLog <<L"No seccond Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Set this property with dwOptions DBPROPOPTIONS_OPTIONAL
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, 1);
|
|
m_rgDBPropSets[0].rgProperties[1].vValue.vt = VT_R4;
|
|
V_R4(&m_rgDBPropSets[0].rgProperties[1].vValue) = (float)26.6;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[1].dwStatus);
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(42)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc vValue = VT_EMPTY -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_42()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_OPTIONAL
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, 0);
|
|
m_rgDBPropSets[0].rgProperties[0].vValue.vt = VT_EMPTY;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(43)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset twice -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_43()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open one rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,(IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Open another rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowsetInfo,0,NULL,(IUnknown **) &m_pIRowsetInfo), S_OK);
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
// Close the first rowset
|
|
SAFE_RELEASE_(m_pIRowset);
|
|
// Close the second rowset
|
|
SAFE_RELEASE_(m_pIRowsetInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(44)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset, close, open, open -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_44()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
m_pIRowset = NULL;
|
|
m_pIRowsetInfo = NULL;
|
|
|
|
// Open one rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,(IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Close the rowset
|
|
SAFE_RELEASE_(m_pIRowset);
|
|
|
|
// Open rowset again
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,(IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Open another rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowsetInfo,0,NULL,(IUnknown **) &m_pIRowsetInfo), S_OK);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
// Close the first rowset
|
|
SAFE_RELEASE_(m_pIRowset);
|
|
// Close the second rowset
|
|
SAFE_RELEASE_(m_pIRowsetInfo);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(45)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not applied to all columns -- DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_45()
|
|
{
|
|
// TO DO: Add your own code here
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(46)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not supported -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_46()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two unsupported properties
|
|
//supported propert assumes IDBProperties is available for the INTERFACE requested
|
|
//this is an optional interface of the SourcesRowset enumerator
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((!SupportedProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, count);
|
|
count++;
|
|
}
|
|
}
|
|
if (0 == count)
|
|
{
|
|
odtLog << "Could not find a not supported property\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status were set correctly
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(count == 0 || DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[1].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(47)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property was not in Rowset property group -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_47()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two supported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
// Set the property not in the Rowset property group
|
|
SetOneProperty(DBPROP_AUTH_CACHE_AUTHINFO, DBPROPOPTIONS_REQUIRED, count);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count == 2)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-2].dwStatus);
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(48)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc property set was not supported -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_48()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two supported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<2)) {
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, count);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
// Set the property not in the Rowset property group
|
|
SetOneProperty(DBPROP_INDEX_AUTOUPDATE, DBPROPOPTIONS_REQUIRED, count);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count == 2)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-2].dwStatus);
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(49)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid colid -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_49()
|
|
{
|
|
return VerifyInvalidColID(DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(50)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid dwOptions -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_50()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
DBPROPSTATUS dbPropStatus = DBPROPSTATUS_NOTSUPPORTED;
|
|
DBPROPOPTIONS InvalidOptions = 99;
|
|
ULONG count = 0;
|
|
IDBProperties *pIDBProperties = NULL;
|
|
ULONG cProp;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set two unsupported properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if ((SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) &&
|
|
(count<1))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, count);
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Set a settable property with dwOptions InvalidOptions
|
|
SetOneProperty(DBPROP_IRowsetLocate, InvalidOptions, count);
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
// No rowset should be returned
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Set the correct return code and status
|
|
if (SupportedProperty(DBPROP_IRowsetLocate, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
dbPropStatus = DBPROPSTATUS_BADOPTION;
|
|
|
|
// Make sure the property status was set correctly
|
|
if (count > 0)
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[count-1].dwStatus);
|
|
TESTC(dbPropStatus == m_rgDBPropSets[0].rgProperties[count].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(51)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid vValue -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_51()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// Set next property which is settalbe
|
|
for(cProp++; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
break;
|
|
}
|
|
if (cProp >= PROPERTY_COUNT)
|
|
{
|
|
odtLog << L"No seccond Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Set this property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 1);
|
|
VariantInit(&m_rgDBPropSets[0].rgProperties[1].vValue);
|
|
m_rgDBPropSets[0].rgProperties[1].vValue.vt = DBTYPE_DBTIMESTAMP;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[1].dwStatus);
|
|
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(52)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc incorrect data type -- DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_52()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE)) {
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// Set next property which is settalbe
|
|
for(cProp++; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
break;
|
|
}
|
|
if (cProp >= PROPERTY_COUNT)
|
|
{
|
|
odtLog <<L"No second Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set this property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 1);
|
|
m_rgDBPropSets[0].rgProperties[1].vValue.vt = VT_R4;
|
|
V_R4(&m_rgDBPropSets[0].rgProperties[1].vValue) = (float)2.14;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC( NULL == m_pIRowset);
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
TESTC(DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[1].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(53)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc vValue = VT_EMPTY -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_53()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
m_rgDBPropSets[0].rgProperties[0].vValue.vt = VT_EMPTY;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[0].dwStatus);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(54)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IParseDisplayName::ParseDisplayName without rowset open -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_54()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName *pIParseDisplayName = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE, (IUnknown **)&pIParseDisplayName));
|
|
|
|
TESTC(VerifyParseDisplayName_std(pIParseDisplayName));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(55)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IParseDisplayName::ParseDisplayName -- S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_55()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName *pIParseDisplayName = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset, 0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
TESTC(VerifyParseDisplayName_std(pIParseDisplayName));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(56)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ParseDisplayName: displayName = NULL -- MK_E_NOOBJECT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_56()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG chEaten = 0;
|
|
IParseDisplayName *pIParseDisplayName = NULL;
|
|
IMoniker *pIMoniker = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset, 0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
// Display name is NULL
|
|
TESTC_(m_hr=pIParseDisplayName->ParseDisplayName(NULL, NULL, &chEaten, &pIMoniker), MK_E_NOOBJECT);
|
|
|
|
TESTC(NULL == pIMoniker);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(57)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ParseDisplayName:pchEaten=NULL -- MK_E_NOOBJECT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_57()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IParseDisplayName * pIParseDisplayName = NULL;
|
|
IMoniker *pIMoniker = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
// pchEaten = NULL
|
|
TESTC_(m_hr=pIParseDisplayName->ParseDisplayName(NULL,g_rgwszParseName[0],NULL,&pIMoniker), MK_E_NOOBJECT);
|
|
TESTC(NULL == pIMoniker);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(58)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ParseDisplayName:pIMoniker = NULL -- E_UNEXPECTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_58()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG chEaten = 0;
|
|
IParseDisplayName *pIParseDisplayName = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
// ppIMoniker = NULL
|
|
TESTC_(m_hr=pIParseDisplayName->ParseDisplayName(NULL,
|
|
g_rgwszParseName[0],&chEaten,NULL), E_UNEXPECTED);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(59)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IParseDisplayName::ParseDisplayName, bind Moniker to session object -- E_NOINTERFACE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_59()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG chEaten = 0;
|
|
IParseDisplayName * pIParseDisplayName = NULL;
|
|
IMoniker * pIMoniker = NULL;
|
|
IDBCreateCommand * pIDBCrtCmd = NULL;
|
|
IUnknown * pIUnknown = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC(NULL != m_pISrcRow);
|
|
|
|
// Open sources rowset
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,0,NULL,(IUnknown **)&m_pIRowset), S_OK);
|
|
|
|
TESTC(NULL != m_pIRowset);
|
|
|
|
TESTC(VerifyInterface(m_pISrcRow, IID_IParseDisplayName,
|
|
ENUMERATOR_INTERFACE,(IUnknown **)&pIParseDisplayName));
|
|
|
|
// Get moniker
|
|
TESTC_(m_hr=pIParseDisplayName->ParseDisplayName(NULL,g_rgwszParseName[0],&chEaten,&pIMoniker), S_OK);
|
|
|
|
TESTC(NULL != pIMoniker);
|
|
|
|
TESTC(VerifyInterface(pIMoniker, IID_IUnknown, UNKNOWN_INTERFACE,&pIUnknown));
|
|
|
|
// Binds the moniker with the IDBCreateCommand interface
|
|
TESTC_(BindMoniker(pIMoniker,0,IID_IDBCreateCommand,(LPVOID*)&pIDBCrtCmd), E_NOINTERFACE);
|
|
|
|
// We should not have pIDBCrtCmd
|
|
TESTC(NULL == pIDBCrtCmd);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIUnknown);
|
|
SAFE_RELEASE(pIMoniker);
|
|
SAFE_RELEASE(pIParseDisplayName);
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(60)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc open sources rowset, getnextrow, not release all rows, getnextrow -- DB_E_ROWSNOTRELEASED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_60()
|
|
{
|
|
// uses it's very own m_pISrcRowset to check that
|
|
// calling IRowset::GetNextRows() without releasing
|
|
// the previously retrieved row handles results in
|
|
// DB_E_ROWSNOTRELEASED if DBPROP_CANHOLDROWSET is VARIANT_FALSE
|
|
return GetNextRowsWithoutRelAllRows();
|
|
}
|
|
// }}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(61)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multiple threads retrieve the sources rowset: check the number of rows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_61()
|
|
{
|
|
TBEGIN
|
|
unsigned IDThread[nThreads];
|
|
HANDLE hThread[nThreads];
|
|
CInParam ThreadParam[nThreads];
|
|
ULONG nIndex, i;
|
|
ULONG cRefRowsNo = 0;
|
|
IRowset *pIRowset = NULL;
|
|
|
|
TESTC_(m_hr = m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL, (IUnknown**)&pIRowset), S_OK);
|
|
TESTC_(m_hr = CountNoOfRows(pIRowset, &cRefRowsNo), S_OK);
|
|
|
|
for (nIndex = 0; nIndex < nThreads; nIndex++)
|
|
{
|
|
m_rgResult[nIndex] = E_FAIL;
|
|
m_rgRowsNo[nIndex] = 0;
|
|
m_rgRowset[nIndex] = NULL;
|
|
m_rgMaxSourcesNames[nIndex] = 100; // get data for the first 100 rows
|
|
SAFE_ALLOC(m_rgSourcesNames[nIndex], WCHAR*, m_rgMaxSourcesNames[nIndex]);
|
|
memset(m_rgSourcesNames[nIndex], 0, sizeof(m_rgSourcesNames[nIndex]));
|
|
|
|
|
|
ThreadParam[nIndex].i = nIndex;
|
|
ThreadParam[nIndex].pObject = this;
|
|
hThread[nIndex] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc2,
|
|
(void*)&ThreadParam[nIndex],
|
|
0,
|
|
&IDThread[nIndex]);
|
|
TESTC(hThread[nIndex] != 0);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, hThread, TRUE, INFINITE);
|
|
for (nIndex=0; nIndex<nThreads; nIndex++)
|
|
{
|
|
CloseHandle(hThread[nIndex]);
|
|
CHECK(m_rgResult[nIndex], S_OK);
|
|
if (!COMPARE((1-0.25)*cRefRowsNo<=m_rgRowsNo[nIndex] && m_rgRowsNo[nIndex]<=(1+0.25)*cRefRowsNo, TRUE))
|
|
{
|
|
odtLog << "Thread " << nIndex << " retrieved " << m_rgRowsNo[nIndex] << " rows; ";
|
|
odtLog << "expected: " << (1-0.25)*cRefRowsNo << "<=RowsCount<=" << (1+0.25)*cRefRowsNo << "\n";
|
|
}
|
|
|
|
if (m_rgResult[nIndex]==S_OK &&
|
|
!VerifyNoDuplicates(m_rgSourcesNames[nIndex], m_rgRowsNo[nIndex]<m_rgMaxSourcesNames[nIndex] ? m_rgRowsNo[nIndex] : m_rgMaxSourcesNames[nIndex]))
|
|
{
|
|
odtLog << "Thread " << nIndex << ": GetSourcesRowset returned duplicate sources\n";
|
|
// Dump sources names returned by GetSourcesRowset
|
|
// for(i=0; i< m_rgMaxSourcesNames[nIndex] && i< m_rgRowsNo[nIndex]; i++)
|
|
// odtLog << L"\t\tRow " << i << L": " << (m_rgSourcesNames[nIndex][i]? m_rgSourcesNames[nIndex][i] : L"NULL") << L"\n";
|
|
|
|
// Increment failure count
|
|
COMPARE(TRUE, FALSE);
|
|
}
|
|
|
|
}
|
|
|
|
CLEANUP:
|
|
for (nIndex=0; nIndex<nThreads; nIndex++)
|
|
{
|
|
SAFE_RELEASE(m_rgRowset[nIndex]);
|
|
for(i=0; i< m_rgMaxSourcesNames[nIndex] && i< m_rgRowsNo[nIndex]; i++)
|
|
{
|
|
SAFE_FREE(m_rgSourcesNames[nIndex][i]);
|
|
}
|
|
SAFE_FREE(m_rgSourcesNames[nIndex]);
|
|
}
|
|
SAFE_RELEASE(pIRowset);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(62)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Aggregate The enumerator, get the sources rowset and call IRowsetInfo::GetSpecification
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCSourcesRowset_ProviderEnumerator::Variation_62()
|
|
{
|
|
return VerifyGetSpec_AggregatedEnum();
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCSourcesRowset_ProviderEnumerator::Terminate()
|
|
{
|
|
// Delete enumerator object
|
|
SAFE_RELEASE(m_pISrcRow);
|
|
SAFE_FREE(m_rgwszSourceParseName);
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CSourcesRowset::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCExtendedErrors_ProviderEnumerator)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCExtendedErrors_ProviderEnumerator - Extended error test for standard enumerator
|
|
//| Created: 09/26/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCExtendedErrors_ProviderEnumerator::Init()
|
|
{
|
|
WCHAR *wszProviderName = NULL;
|
|
WCHAR *wszDBMSName = NULL;
|
|
WCHAR *wszDBMSNameCopy = NULL;
|
|
ULONG cPropSets = 0;
|
|
const ULONG cPropIDs = 2;
|
|
DBPROPID rgPropIDs[2];
|
|
DBPROPIDSET PropIDSet;
|
|
DBPROPSET *rgSupportedPropSets = NULL;
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG i;
|
|
HRESULT hr;
|
|
BOOL fProviderFound = TEST_FAIL;
|
|
DBPROPSET *rgInitPropSets = NULL;
|
|
ULONG cInitPropSets = 0;
|
|
IDBProperties *pIDBProperties = NULL;
|
|
IDBInitialize *pIDBInitialize = NULL;
|
|
WCHAR *pwszEnumName = NULL;
|
|
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
TESTC(CSourcesRowset::Init());
|
|
|
|
//Create Session Object so test can see what provider it was asked to run against
|
|
TESTC(SUCCEEDED(hr = CoCreateInstance(m_pThisTestModule->m_ProviderClsid,NULL,
|
|
GetModInfo()->GetClassContext(),
|
|
IID_IDBInitialize,(void **)&pIDBInitialize)));
|
|
|
|
// Get IDBProperties Pointer
|
|
TESTC(VerifyInterface(pIDBInitialize, IID_IDBProperties, DATASOURCE_INTERFACE, (IUnknown**)&pIDBProperties));
|
|
fResult = TEST_FAIL;
|
|
// Setup the arrays needed for init, based on string LTM passed to us
|
|
TESTC(GetInitProps(&cInitPropSets, &rgInitPropSets));
|
|
// Set the properties before we Initialize
|
|
TESTC(SUCCEEDED(pIDBProperties->SetProperties(cInitPropSets, rgInitPropSets)));
|
|
// Initialize (connect so i can get the provider name)
|
|
m_pThisTestModule->m_pError->Validate((hr = pIDBInitialize->Initialize()),
|
|
LONGSTRING(__FILE__), __LINE__,S_OK);
|
|
|
|
//set prop that will Get Provider Name
|
|
rgPropIDs[0] = DBPROP_PROVIDERNAME;
|
|
//set prop that will Get Provider Name
|
|
rgPropIDs[1] = DBPROP_DBMSNAME;
|
|
|
|
PropIDSet.cPropertyIDs = cPropIDs;
|
|
PropIDSet.rgPropertyIDs = rgPropIDs;
|
|
PropIDSet.guidPropertySet = DBPROPSET_DATASOURCEINFO;
|
|
|
|
//get provider name
|
|
hr = pIDBProperties->GetProperties(1, &PropIDSet, &cPropSets, &rgSupportedPropSets);
|
|
|
|
if ( DB_S_ERRORSOCCURRED != hr
|
|
&& DB_E_ERRORSOCCURRED != hr)
|
|
TESTC_(hr, S_OK);
|
|
TESTC(1 == cPropSets);
|
|
//disconnect
|
|
TESTC_(hr = pIDBInitialize->Uninitialize(), S_OK);
|
|
|
|
//loop through the array of source name looking for the one with the provider's name and the word enumerator
|
|
if (GetModInfo()->GetEnumerator())
|
|
for (i=0;i< g_cTotalEntries;i++)
|
|
{
|
|
//look for the provider's enumerator in key read from registry now that test knows which provider to run against
|
|
if (!g_rgwszSourceName)
|
|
continue;
|
|
if ( !(wcsstr(_wcsupr(g_rgwszSourceName[i]), L" ENUMERATOR")==0)
|
|
&& (wcscmp(_wcsupr(g_rgwszSourceName[i]), _wcsupr(GetModInfo()->GetEnumerator()))==0)
|
|
)
|
|
{
|
|
// Get the CLSID from Provider String
|
|
fProviderFound = TRUE;
|
|
CLSIDFromString(g_rgwszSourceParseName[i],&m_clsid);
|
|
pwszEnumName = wcsDuplicate(GetModInfo()->GetEnumerator());
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!fProviderFound)
|
|
{
|
|
odtLog << "Enumerator name, as indicated through ENUMNAME in init string could not be found\n";
|
|
odtLog << "Find an enumerator with similar name to the name of provider\n";
|
|
|
|
//get wchar of provider name
|
|
if (DBPROPSTATUS_OK == rgSupportedPropSets[0].rgProperties[0].dwStatus)
|
|
wszProviderName = wcstok(BSTR2WSTR(rgSupportedPropSets[0].rgProperties[0].vValue.bstrVal ), L"."); // Always returns first string
|
|
else
|
|
wszProviderName = NULL;
|
|
//get wchar of dbms name
|
|
if (DBPROPSTATUS_OK == rgSupportedPropSets[0].rgProperties[0].dwStatus)
|
|
wszDBMSName = wcstok(BSTR2WSTR(rgSupportedPropSets[0].rgProperties[1].vValue.bstrVal ), L"."); // Always returns first string
|
|
else
|
|
wszDBMSName = NULL;
|
|
|
|
//hack
|
|
if (wszDBMSName)
|
|
{
|
|
//Copy the pointer
|
|
wszDBMSNameCopy = wszDBMSName;
|
|
|
|
for (i=0;i<3;i++)
|
|
wszDBMSName++;
|
|
}
|
|
|
|
//make Enum string
|
|
//this assumes that the enumerator name will have the provider name and the word 'Enumerator' in its name
|
|
|
|
//loop through the array of source name looking for the one with the provider's name and the word enumerator
|
|
for (i=0;i< g_cTotalEntries;i++)
|
|
{
|
|
//look for the provider's enumerator in key read from registry now that test knows which provider to run against
|
|
if (
|
|
(!(wcsstr(_wcsupr(g_rgwszSourceName[i]), L" ENUMERATOR")==0))
|
|
&& ( ( wszProviderName
|
|
&& !(wcsstr(_wcsupr(g_rgwszSourceName[i]), _wcsupr(wszProviderName))==0))
|
|
|| (wszDBMSName
|
|
&& !(wcsstr(_wcsupr(g_rgwszSourceName[i]), _wcsupr(wszDBMSName))==0)))
|
|
)
|
|
{
|
|
// Get the CLSID from Provider String
|
|
fProviderFound = TRUE;
|
|
CLSIDFromString(g_rgwszSourceParseName[i],&m_clsid);
|
|
pwszEnumName = wcsDuplicate(g_rgwszSourceName[i]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!fProviderFound)
|
|
{
|
|
odtLog << L"An Enumerator was not found for this Provider. " << ENDL;
|
|
fResult = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
else
|
|
odtLog << "Provider to be tested: " << pwszEnumName << "\n";
|
|
|
|
// Create an enumerator Object
|
|
|
|
TESTC_(m_hr = CoCreateInstance(m_clsid, NULL,
|
|
GetModInfo()->GetClassContext(), IID_ISourcesRowset,(void **)&m_pISrcRow), S_OK);
|
|
TESTC(MarkSupportedProperties(m_clsid));
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBProperties);
|
|
SAFE_RELEASE(pIDBInitialize);
|
|
SAFE_FREE(pwszEnumName);
|
|
|
|
PROVIDER_FREE(wszProviderName);
|
|
PROVIDER_FREE(wszDBMSNameCopy);
|
|
|
|
FreeProperties(&cInitPropSets, &rgInitPropSets);
|
|
FreeProperties(&cPropSets, &rgSupportedPropSets);
|
|
return fResult;
|
|
// }}
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc S_OK -- with previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_ProviderEnumerator::Variation_1()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Cause an error on the current thread
|
|
m_pExtError->CauseError();
|
|
|
|
// cPropertySets (0, NULL)
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset,
|
|
0, NULL, (IUnknown **) &m_pIRowset), S_OK);
|
|
|
|
// Do extended check
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_INVALIDARG -- with previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_ProviderEnumerator::Variation_2()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Cause an error on the current thread
|
|
m_pExtError->CauseError();
|
|
|
|
// ppSourcesRowset is NULL
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset, 0, NULL, NULL), E_INVALIDARG);
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_NOINTERFACE -- with no previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_ProviderEnumerator::Variation_3()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Sources rowset is read-only
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowsetUpdate,
|
|
0,NULL, (IUnknown **)&pIRowsetUpdate), E_NOINTERFACE);
|
|
// No rowset should be returned
|
|
TESTC(NULL == pIRowsetUpdate);
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DB_S_ERRORSOCCURRED -- with previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_ProviderEnumerator::Variation_4()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG count = 0;
|
|
IDBProperties *pIDBProperties = NULL;
|
|
ULONG cProp = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Set settable properties
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_OPTIONAL, count);
|
|
count++;
|
|
}
|
|
}
|
|
if (0 == count)
|
|
return TEST_SKIPPED;
|
|
|
|
// Cause an error on the current thread
|
|
m_pExtError->CauseError();
|
|
count = count > 2 ? count - 2: 0;
|
|
m_rgDBPropSets[0].rgProperties[count].vValue.vt = VT_NULL;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_S_ERRORSOCCURRED);
|
|
|
|
// Do extended check
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
|
|
// Check column data and data in each row
|
|
TESTC(CheckColumnsInfo(COLUMN_COUNT_STD, m_pIRowset));
|
|
|
|
// Make sure the property status were set correctly
|
|
for (cProp=0; cProp<m_rgDBPropSets[0].cProperties; cProp++)
|
|
{
|
|
if (count == cProp )
|
|
{
|
|
TESTC( DBPROPSTATUS_BADVALUE == m_rgDBPropSets[0].rgProperties[cProp].dwStatus
|
|
|| DBPROPSTATUS_NOTSET == m_rgDBPropSets[0].rgProperties[cProp].dwStatus);
|
|
}
|
|
else
|
|
{
|
|
TESTC(DBPROPSTATUS_OK == m_rgDBPropSets[0].rgProperties[cProp].dwStatus);
|
|
}
|
|
}
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DB_E_ERRORSOCCURRED -- with no previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_ProviderEnumerator::Variation_5()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
ULONG cProp = 0;
|
|
ULONG count = 0;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Set one property which is settalbe
|
|
for(cProp=0; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
{
|
|
count++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if count is 0 no settable properties
|
|
if (!count)
|
|
{
|
|
odtLog <<L"No Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
// Set a settable property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 0);
|
|
|
|
// Set next property which is settalbe
|
|
for(cProp++; cProp<PROPERTY_COUNT; cProp++)
|
|
{
|
|
if (SettableProperty(g_PropMark[cProp].dwPropertyID, DBPROPSET_ROWSET, m_pISrcRow,ENUMERATOR_INTERFACE))
|
|
break;
|
|
}
|
|
|
|
// Set this property with dwOptions DBPROPOPTIONS_REQUIRED
|
|
if (cProp >= PROPERTY_COUNT)
|
|
{
|
|
odtLog << L"No second Settable Properties where supported by the Enumerator.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
SetOneProperty(g_PropMark[cProp].dwPropertyID, DBPROPOPTIONS_REQUIRED, 1);
|
|
m_rgDBPropSets[0].rgProperties[1].vValue.vt = VT_I4;
|
|
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL,IID_IRowset,
|
|
m_cDBPropSets,m_rgDBPropSets,(IUnknown **)&m_pIRowset), DB_E_ERRORSOCCURRED);
|
|
|
|
// Check that a Rowset was not generated
|
|
TESTC(NULL == m_pIRowset);
|
|
|
|
// Do extended check
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
|
|
// Make sure the property status was set correctly
|
|
TESTC(m_rgDBPropSets[0].rgProperties[0].dwStatus == DBPROPSTATUS_OK);
|
|
TESTC(m_rgDBPropSets[0].rgProperties[1].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_INVALIDARG -- with previous error existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors_ProviderEnumerator::Variation_6()
|
|
{
|
|
BOOL fResult = TEST_FAIL;
|
|
|
|
// Make sure we have ISrcRow pointer
|
|
TESTC((NULL != m_pISrcRow) && (NULL != m_pExtError));
|
|
|
|
// Cause an error on the current thread
|
|
m_pExtError->CauseError();
|
|
|
|
// ppSourcesRowset is NULL
|
|
TESTC_(m_hr=m_pISrcRow->GetSourcesRowset(NULL, IID_IRowset, 1, NULL,
|
|
(IUnknown **) &m_pIRowset), E_INVALIDARG);
|
|
TESTC(NULL == m_pIRowset);
|
|
TESTC(XCHECK(m_pISrcRow, IID_ISourcesRowset, m_hr));
|
|
fResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(m_pIRowset);
|
|
return fResult;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCExtendedErrors_ProviderEnumerator::Terminate()
|
|
{
|
|
// Delete enumerator object
|
|
SAFE_RELEASE(m_pISrcRow);
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CSourcesRowset::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// Hack to defile CoInitializeEx
|
|
WINOLEAPI CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
|
|
|
|
unsigned WINAPI ThreadProc(LPVOID lpvThreadParam)
|
|
{
|
|
CoInitializeEx(NULL, 0);
|
|
CSourcesRowset *pObject = ((CInParam*)lpvThreadParam)->pObject;
|
|
pObject->MyThreadProc(((CInParam*)lpvThreadParam)->i);
|
|
CoUninitialize();
|
|
return 0;
|
|
} //ThreadProc
|
|
unsigned WINAPI ThreadProc2(LPVOID lpvThreadParam)
|
|
{
|
|
CoInitializeEx(NULL, 0);
|
|
CSourcesRowset *pObject = ((CInParam*)lpvThreadParam)->pObject;
|
|
pObject->MyThreadProc2(((CInParam*)lpvThreadParam)->i);
|
|
CoUninitialize();
|
|
return 0;
|
|
} //ThreadProc
|
|
|
|
bool VerifyNoDuplicates(WCHAR** rgNames, ULONG cNames)
|
|
{
|
|
|
|
bool fDuplicates = false;
|
|
|
|
for(ULONG i=0; i<cNames-1 && !fDuplicates; i++)
|
|
{
|
|
for(ULONG j=i+1; rgNames[i] && j< cNames && !fDuplicates; j++)
|
|
{
|
|
if(fDuplicates=(rgNames[j] && wcscmp(rgNames[i], rgNames[j])==0))
|
|
odtLog << "Found duplicate for: " << rgNames[i] << "\n";
|
|
}
|
|
}
|
|
|
|
return !fDuplicates;
|
|
}
|