2025-04-27 07:49:33 -04:00

1157 lines
32 KiB
C++

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMI OLE DB Client test app
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#define INITGUID
#define DBINITCONSTANTS
#include "wmiclnt.h"
#include <headers.h>
IMalloc* g_pIMalloc = NULL;
FILE* g_fpLogFile = NULL; // our log file
WCHAR * g_pwcsTable = NULL;
WCHAR * g_pwcsNamespace = NULL;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void AllocateAndConvertAnsiToUnicode(char * pstr, WCHAR *& pszW)
{
pszW = NULL;
int nSize = strlen(pstr);
if (nSize != 0 ){
// Determine number of wide characters to be allocated for the
// Unicode string.
nSize++;
try{
pszW = new WCHAR[nSize * 2];
if (NULL != pszW){
// Covert to Unicode.
MultiByteToWideChar(CP_ACP, 0, pstr, nSize,pszW,nSize);
}
}
catch(...){
throw;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
BOOL GetDataFromCommandLine(int argc,int & i, WCHAR *& p, char * argv[])
{
i++;
if( i > argc ){
return FALSE;
}
AllocateAndConvertAnsiToUnicode(argv[i],p);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
BOOL ParseCommandLine(int argc, char * argv[])
{
BOOL fFlag = FALSE;
if ( argc > 1 ){
g_pwcsTable = NULL;
g_pwcsNamespace = NULL;
//======================================================================
// Now, go thru and get the ones we support
//======================================================================
for( int i = 0; i < argc; i++){
//==================================================================
// NAMESPACE
//==================================================================
if(_stricmp(argv[i],"-Namespace")== 0){
GetDataFromCommandLine(argc,i,g_pwcsNamespace,argv);
}
//==================================================================
// TABLE
//==================================================================
if(_stricmp(argv[i],"-Table")== 0){
GetDataFromCommandLine(argc,i,g_pwcsTable,argv);
}
}
if( g_pwcsTable && g_pwcsNamespace ) {
fFlag = TRUE;
}
}
if( !fFlag ){
printf( "-Namespace name\n" );
printf( "-Table tablename\n" );
}
return fFlag;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
void InitializeLogFile()
{
time_t ttime;
g_fpLogFile = fopen( "wmiclnt.out", "at");
if (!g_fpLogFile){
DumpErrorMsg( "Warning: cannot open log file wmiclnt.out\n" );
}
time(&ttime);
DumpStatusMsg( "\n-------------------------\n\n");
DumpStatusMsg( "running wmiclnt.exe\n%s\n\n", ctime(&ttime) );
}
//**********************************************************************
//
// GetWMIOLEDBDataSource
//
// Purpose:
//
// Calls OLE to find and load the WMIOLEDB data provider.
// Returns an IDBInitialize interface pointer on WMIOLEDB's
// Data Source object.
//
// Parameters:
//
// IDBInitialize** ppIDBInitialize_out - out pointer through which to return
// IDBInitialize pointer on data
// provider's Data Source object
//
// Return Value:
//
// S_OK - Success
// E_* - Failure
//
//
// Comments:
//
// The call to CoCreateInstance is hard-coded with WMIOLEDB's CLSID.
// The pointer returned through ppIDBInitialize_out has been AddRef'ed,
// it must be Release'd later by the caller.
//
//**********************************************************************
HRESULT GetWMIOLEDBDataSource(IDBInitialize** ppIDBInitialize_out )
{
IDBInitialize* pIDBInit = NULL;
IDBProperties* pIDBProperties = NULL;
DBPROPSET dbPropSet[1];
DBPROP dbProp[1];
HRESULT hr;
DumpStatusMsg( "Connecting to the WMIOLEDB data provider...\n" );
assert(ppIDBInitialize_out != NULL);
VariantInit(&(dbProp[0].vValue));
//===========================================================================
// Create an instance of the WMIOLEDB data provider
//===========================================================================
hr = CoCreateInstance( CLSID_WMIOLEDB, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void **)&pIDBInit );
if (FAILED(hr)){
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "CoCreateInstance" );
goto error;
}
//===========================================================================
// Initialize this provider with the namespace
//===========================================================================
dbPropSet[0].rgProperties = &dbProp[0];
dbPropSet[0].cProperties = 1;
dbPropSet[0].guidPropertySet = DBPROPSET_DBINIT;
dbProp[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
dbProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
dbProp[0].colid = DB_NULLID;
V_VT(&(dbProp[0].vValue)) = VT_BSTR;
V_BSTR(&(dbProp[0].vValue)) = SysAllocString( g_pwcsNamespace );
if ( NULL == V_BSTR(&(dbProp[0].vValue)) ){
DUMP_ERROR_LINENUMBER();
DumpErrorMsg( "SysAllocString failed\n" );
goto error;
}
hr = pIDBInit->QueryInterface( IID_IDBProperties, (void**)&pIDBProperties);
if (FAILED(hr)){
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "IDBInitialize::QI for IDBProperties");
goto error;
}
hr = pIDBProperties->SetProperties( 1, &dbPropSet[0]);
if (FAILED(hr)){
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "IDBProperties::SetProperties" );
goto error;
}
hr = pIDBInit->Initialize();
if (FAILED(hr)){
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "IDBInitialize::Initialize" );
goto error;
}
*ppIDBInitialize_out = pIDBInit;
hr = ResultFromScode( S_OK );
error:
VariantClear( &(dbProp[0].vValue) );
if( pIDBProperties )
pIDBProperties->Release();
if( FAILED(hr) )
{
if (pIDBInit){
pIDBInit->Release();
}
*ppIDBInitialize_out = NULL;
}
return hr;
}
// **********************************************************************
//
// GetDBSessionFromDataSource
//
// Purpose:
// Calls the provider's Data Source object to get an IOpenRowset interface
// pointer on a DBSession object.
//
// Parameters:
// pIDBInitialize - pointer to Data Source object
// ppIOpenRowset_out - out pointer through which to return
// IOpenRowset pointer on DBSession object
//
// Return Value:
//
// S_OK - Success
// E_* - Failure
//
//
// Comments:
//
// The interface pointer returned through ppIOpenRowset_out has been
// AddRef'ed, the caller must Release it later.
//
//**********************************************************************
HRESULT GetDBSessionFromDataSource
(
IDBInitialize* pIDBInitialize, // [in]
IOpenRowset** ppIOpenRowset_out // [out]
)
{
IDBCreateSession* pIDBCreateSession;
IOpenRowset* pIOpenRowset;
HRESULT hr;
DumpStatusMsg( "Getting a DBSession object from the data source object...\n" );
assert(pIDBInitialize != NULL);
assert(ppIOpenRowset_out != NULL );
hr = pIDBInitialize->QueryInterface( IID_IDBCreateSession, (void**)&pIDBCreateSession);
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "IDBInitialize::QI for IDBCreateSession");
goto error;
}
hr = pIDBCreateSession->CreateSession( NULL, IID_IOpenRowset, (IUnknown**)&pIOpenRowset );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "IDBCreateSession::CreateSession");
goto error;
}
pIDBCreateSession->Release();
pIDBCreateSession = NULL;
// all went well
*ppIOpenRowset_out = pIOpenRowset;
return ResultFromScode( S_OK );
error:
if (pIDBCreateSession)
pIDBCreateSession->Release();
*ppIOpenRowset_out = NULL;
return ResultFromScode( hr );
}
//**********************************************************************
//
// GetRowsetFromDBSession
//
// Purpose:
// Calls the provider's DBSession object to get an IRowset interface
// pointer on a Rowset object.
//
// Parameters:
// pIOpenRowset - interface pointer on DBSession object
// pwszTableName - name of "table" (in this case text file)
// ppIRowset_out - out pointer through which to return
// IRowset pointer on Rowset object
//
// Return Value:
//
// S_OK - Success
// E_* - Failure
//
// Comments:
//
// The interface pointer returned through ppIRowset_out has been
// AddRef'ed, the caller must Release it later.
//
///**********************************************************************
HRESULT GetRowsetFromDBSession
(
IOpenRowset* pIOpenRowset, // [in]
LPWSTR pwszTableName, // [in]
IRowset** ppIRowset_out // [out]
)
{
DBID dbcolid;
IRowset* pIRowset = NULL;
HRESULT hr;
DumpStatusMsg( "Getting a rowset object from the DBSession object...\n" );
assert(pIOpenRowset != NULL);
assert(ppIRowset_out != NULL );
// tell the provider which table to open
dbcolid.eKind = DBKIND_NAME;
dbcolid.uName.pwszName = pwszTableName;
hr = pIOpenRowset->OpenRowset
(
NULL, // pUnkOuter - we are not aggregating
&dbcolid, // pTableID - the table we want
NULL, // pIndexID - the index we want
IID_IRowset, // riid - interface we want on the rowset object
0, // cProperties - we are niave about props for now
NULL, // prgProperties[]
(IUnknown**)&pIRowset // ppRowset
);
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "IOpenRowset::OpenRowset" );
goto error;
}
// all went well
*ppIRowset_out = pIRowset;
return ResultFromScode( S_OK );
error:
if (pIRowset)
pIRowset->Release();
*ppIRowset_out = NULL;
return ResultFromScode( hr );
}
//**********************************************************************
//
// GetColumnsInfo
//
// Purpose:
//
// Obtains information (metadata) about the columns in the rowset - the types
// of the data and so on.
//
//
// Parameters:
// IRowset* pIRowset - interface pointer on data provider's
// Rowset object
// ULONG* pcCol_out - out pointer through which to return
// number of columns in the rowset
// DBCOLUMNINFO** ppColumnInfo_out - out pointer through which to return
// pointer to structure containing
// metadata for the columns in the rowset
// WCHAR** ppStringsBuffer_out - out pointer through which to return
// pointer to table of strings. see comments.
//
// Return Value:
// S_OK - Success
// E_* - Failure
//
//
// Comments:
//
// ppColumnInfo_out and ppStringsBuffer_out are used to return pointers
// to two buffers. These buffers are allocated by the data provider
// (when GetColumnsInfo calls IColumnsInfo::GetColumnInfo). The data
// provider uses IMalloc to allocate the buffers; therefore, the caller
// of this routine must at a later point use IMalloc::Free to free
// both of these buffers. The StringsBuffer contains strings pointed
// to by pointers in the ColumnInfo buffer, therefore the StringsBuffer
// should be freed *after* the ColumnInfo pointer.
//
// GetColumnsInfo calls DumpColumnsInfo to dump the column metadata to
// the log file.
//
//**********************************************************************
HRESULT GetColumnsInfo
(
IRowset* pIRowset,
ULONG* pcCol_out,
DBCOLUMNINFO** ppColumnInfo_out,
WCHAR** ppStringsBuffer_out
)
{
IColumnsInfo* pIColumnsInfo = NULL;
ULONG cCol;
DBCOLUMNINFO* pColumnInfo;
WCHAR* pStringsBuffer;
HRESULT hr;
assert(pIRowset != NULL);
assert(pcCol_out != NULL);
assert(ppColumnInfo_out != NULL);
assert(ppStringsBuffer_out != NULL);
// get column information from the command object via IColumnsInfo
hr = pIRowset->QueryInterface( IID_IColumnsInfo, (void **) &pIColumnsInfo );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "IRowset::QI for IID_IColumnsInfo" );
goto error;
}
hr = pIColumnsInfo->GetColumnInfo(
&cCol,
&pColumnInfo,
&pStringsBuffer );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "pIColumnsInfo->GetColumnInfo" );
goto error;
}
pIColumnsInfo->Release();
pIColumnsInfo = NULL;
DumpColumnsInfo( pColumnInfo, cCol );
// fill out-params
*pcCol_out = cCol;
*ppColumnInfo_out = pColumnInfo;
*ppStringsBuffer_out = pStringsBuffer;
return ResultFromScode( S_OK );
error:
if (pIColumnsInfo)
pIColumnsInfo->Release();
*pcCol_out = 0;
*ppColumnInfo_out = NULL;
*ppStringsBuffer_out = NULL;
return ResultFromScode( hr );
}
//**********************************************************************
//
// SetupBindings
//
// Purpose:
//
// Creates bindings that map the data in the rowset's columns to
// slots in the consumer's data buffer.
//
// Parameters:
//
// ULONG cCol - number of columns in rowset to bind
// DBCOLUMNINFO* pColumnInfo - pointer to column metadata
// DBBINDING* rgBind_out - out pointer through which to return
// an array of binding structures, one
// structure per column bound
// ULONG* pcBind_out - out pointer through which to return
// the number of columns bound (number
// of valid elements in rgBind_out)
// ULONG* pcMaxRowSize_out - out pointer through which to return
// the buffer size necessary to hold
// the largest row data
//
// Return Value:
// S_OK - Success
// E_* - Failure
//
//
// Comments:
//
//
//**********************************************************************
HRESULT SetupBindings
(
ULONG cCol,
DBCOLUMNINFO* pColumnInfo,
DBBINDING* rgBind_out,
ULONG* pcBind_out,
ULONG* pcMaxRowSize_out
)
{
ULONG dwOffset;
ULONG iCol;
ULONG iBind;
assert(pColumnInfo != NULL);
assert(rgBind_out != NULL);
assert(pcBind_out != NULL);
assert(pcMaxRowSize_out != NULL);
// Create bindings.
// Bind everything as a string just to keep things simple.
dwOffset = 0;
iBind=0;
for (iCol=0; iCol < cCol; iCol++)
{
// Skip columns of type _VECTOR. Probably binary data.
if (pColumnInfo[iCol].wType & DBTYPE_VECTOR)
continue;
rgBind_out[iBind].dwPart = DBPART_VALUE | DBPART_LENGTH |
DBPART_STATUS;
rgBind_out[iBind].eParamIO = DBPARAMIO_NOTPARAM;
rgBind_out[iBind].iOrdinal = pColumnInfo[iCol].iOrdinal;
rgBind_out[iBind].wType = DBTYPE_STR;
rgBind_out[iBind].pTypeInfo = NULL;
rgBind_out[iBind].obValue = dwOffset + offsetof(TMPCOLUMNDATA,bData);
rgBind_out[iBind].obLength = dwOffset + offsetof(TMPCOLUMNDATA,dwLength);
rgBind_out[iBind].obStatus = dwOffset + offsetof(TMPCOLUMNDATA,dwStatus);
rgBind_out[iBind].cbMaxLen = pColumnInfo[iCol].wType == DBTYPE_STR ?
pColumnInfo[iCol].ulColumnSize + sizeof(char) : DEFAULT_CBMAXLENGTH;
rgBind_out[iBind].pObject = NULL;
dwOffset += rgBind_out[iBind].cbMaxLen + offsetof( TMPCOLUMNDATA, bData );
dwOffset = ROUND_UP( dwOffset, COLUMN_ALIGNVAL );
iBind++;
}
*pcBind_out = iBind;
*pcMaxRowSize_out = dwOffset;
return ResultFromScode( S_OK );
}
//**********************************************************************
//
// CreateAccessor
//
// Purpose:
//
// Passes a set of bindings to the data provider and recieves in return
// an accessor handle that represents those bindings.
//
// Parameters:
// IRowset* pIRowset - interface pointer on data provider's Rowset
// object
// DBBINDING* rgBind - array of binding structures
// ULONG cBind - number of binding structures in rgBind
// HACCESSOR* phAccessor_out - out pointer through which to return an
// accessor handle that represents all the bindings
// in rgBind
//
// Return Value:
// S_OK - Success
// E_* - Failure
//
//
// Comments:
//
//
//**********************************************************************
HRESULT CreateAccessor
(
IRowset* pIRowset,
DBBINDING* rgBind,
ULONG cBind,
HACCESSOR* phAccessor_out
)
{
IAccessor* pIAccessor = NULL;
HACCESSOR hAccessor;
HRESULT hr;
assert(pIRowset != NULL);
assert(rgBind != NULL);
assert(phAccessor_out != NULL);
// Get an accessor for our bindings from the rowset, via IAccessor
hr = pIRowset->QueryInterface( IID_IAccessor, (void**)&pIAccessor );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "pIRowset->QI for IID_IAccessor" );
goto error;
}
hr = pIAccessor->CreateAccessor( DBACCESSOR_ROWDATA, cBind, rgBind, 0,
&hAccessor, NULL );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "pIAccessor->CreateAccessor" );
goto error;
}
pIAccessor->Release();
pIAccessor = NULL;
*phAccessor_out = hAccessor;
return ResultFromScode( S_OK );
error:
if (pIAccessor)
pIAccessor->Release();
*phAccessor_out = NULL;
return ResultFromScode( hr );
}
//**********************************************************************
//
// GetData
//
// Purpose:
//
// Reads the data from a rowset.
//
// Parameters:
//
// IRowset* pIRowset - interface pointer on data provider's
// Rowset object
// ULONG cMaxRowSize - size of buffer needed to hold the data
// for the largest row
// HACCESSOR hAccessor - accessor handle representing the set
// of desired bindings
// DBBINDING* rgBind - needed only for pretty printing
// ULONG cBind - for pretty printing
// DBCOLUMNINFO* pColumnInfo - for pretty printing
// ULONG cCol - for pretty printing
//
//
// Return Value:
// S_OK - Success
// E_* - Failure
//
//
//
// Comments:
//
// GetData reads all the rows in the rowset, sequentially.
//
// GetData calls CalcPrettyPrintMaxColWidth, DumpColumnHeadings, and
// DumpRow to dump the row data to a log file.
//
//
//**********************************************************************
HRESULT GetData( IRowset* pIRowset,ULONG cMaxRowSize, HACCESSOR hAccessor, DBBINDING* rgBind,
ULONG cBind, DBCOLUMNINFO* pColumnInfo, ULONG cCol
)
{
ULONG cRowsObtained;
ULONG iRow;
BYTE* pRowData = NULL;
HROW rghRows[NUMROWS_CHUNK];
HROW* pRows = &rghRows[0];
ULONG cMaxColWidth; // needed for pretty printing
HRESULT hr;
assert(pIRowset != NULL);
assert(rgBind != NULL);
assert(pColumnInfo != NULL);
// create a buffer for row data, big enough to hold the biggest row
pRowData = (BYTE *) malloc( cMaxRowSize );
if (!pRowData)
{
DUMP_ERROR_LINENUMBER();
DumpErrorMsg("GetData: malloc failed\n");
goto error;
}
// pretty print
cMaxColWidth = CalcPrettyPrintMaxColWidth( rgBind, cBind );
// pretty print
DumpColumnHeadings( rgBind, cBind, pColumnInfo, cCol, cMaxColWidth );
// process all the rows, NUMROWS_CHUNK rows at a time
while (1)
{
hr = pIRowset->GetNextRows(
NULL, // hChapter
0, // cRowsToSkip
NUMROWS_CHUNK, // cRowsDesired
&cRowsObtained, // pcRowsObtained
&pRows ); // filled in w/ row handles
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "pIRowset->GetNextRows" );
goto error;
}
if ( cRowsObtained == 0 ) // all done, no more rows left to get
break;
// loop over rows obtained, getting data for each
for ( iRow=0; iRow < cRowsObtained; iRow++ )
{
hr = pIRowset->GetData(
rghRows[iRow],
hAccessor,
pRowData );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "pIRowset->GetData" );
goto error;
}
// pretty print
DumpRow( rgBind, cBind, cMaxColWidth, pRowData );
}
// release row handles
hr = pIRowset->ReleaseRows( cRowsObtained, rghRows, NULL, NULL, NULL );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "pIRowset->ReleaseRows" );
goto error;
}
} // end while
// free row data buffer
free( pRowData );
return ResultFromScode( S_OK );
error:
if (pRowData)
free( pRowData );
return ResultFromScode( hr );
}
//**********************************************************************
//
// CleanupRowset
//
// Purpose:
//
// Allows the rowset to perform any necessary cleanup.
//
// Parameters:
//
// IRowset* pIRowset - interface pointer on data provider's Rowset
// object
// HACCESSOR hAccessor - accessor handle to release
//
// Return Value:
//
// S_OK - Success
// E_* - Failure
//
//
// Comments:
//
// In this , the only cleanup that the rowset needs to do is
// release the accessor handle.
//
//**********************************************************************
HRESULT CleanupRowset
(
IRowset* pIRowset,
HACCESSOR hAccessor
)
{
IAccessor* pIAccessor = NULL;
HRESULT hr;
assert(pIRowset != NULL);
// tell the rowset object it can release the accessor, via IAccessor
hr = pIRowset->QueryInterface( IID_IAccessor, (void**)&pIAccessor );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "pIRowset->QI for IID_IAccessor" );
goto error;
}
hr = pIAccessor->ReleaseAccessor( hAccessor, NULL );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "pIAccessor->ReleaseAccessor" );
goto error;
}
pIAccessor->Release();
pIAccessor = NULL;
return ResultFromScode( S_OK );
error:
if (pIAccessor)
pIAccessor->Release();
return ResultFromScode( hr );
}
//**********************************************************************
//
// GetDataFromRowset
//
// Purpose:
//
// Pulls the data from a Rowset object.
//
// Parameters:
//
// IRowset* pIRowset - interface pointer on data provider's
// Rowset object
//
// Return Value:
//
// S_OK - Success
// E_* - Failure
//
// Comments:
//
// At a high level, a consumer pulls the data from a Rowset object by:
//
// 1. getting metadata for the Rowset's columns
// 2. using that metadata, along with the consumer's own knowledge of
// how it wants to recieve the data, to create bindings. Bindings
// represent how the actual data in the Rowset's columns is
// actually transferred to the consumer's buffer.
// 3. pass the bindings to the Rowset, and get in return an accessor
// handle that represents that particulr set of bindings
// 4. get the actual data
// 5. clean up the rowset (at a minumum, release the accessor)
//
// GetDataFromRowset performs these steps by calling GetColumnsInfo,
// SetupBindings, CreateAccessor, GetData, and CleanupRowset
//
//**********************************************************************
HRESULT GetDataFromRowset
(
IRowset* pIRowset
)
{
ULONG cCol;
ULONG cbMaxRowSize; // buffer size for 1 row's data
ULONG cBind;
DBBINDING rgBind[MAX_BINDINGS];
HACCESSOR hAccessor = NULL;
DBCOLUMNINFO* pColumnInfo = NULL;
WCHAR* pStringsBuffer = NULL;
HRESULT hr;
DumpStatusMsg( "Reading all the data in the rowset...\n" );
assert(pIRowset != NULL);
assert(g_pIMalloc != NULL);
hr = GetColumnsInfo( pIRowset, &cCol, &pColumnInfo, &pStringsBuffer );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "GetColumnsInfo");
goto error;
}
hr = SetupBindings( cCol, pColumnInfo, rgBind, &cBind, &cbMaxRowSize );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "SetupBindings");
goto error;
}
hr = CreateAccessor( pIRowset, rgBind, cBind, &hAccessor );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "CreateAccessor" );
goto error;
}
hr = GetData( pIRowset, cbMaxRowSize, hAccessor, rgBind, cBind, pColumnInfo, cCol );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "GetData" );
goto error;
}
g_pIMalloc->Free( pColumnInfo );
pColumnInfo = NULL;
g_pIMalloc->Free( pStringsBuffer );
pStringsBuffer = NULL;
hr = CleanupRowset( pIRowset, hAccessor );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "CleanupRowset" );
goto error;
}
return ResultFromScode( S_OK );
error:
if (pColumnInfo)
g_pIMalloc->Free( pColumnInfo );
if (pStringsBuffer)
g_pIMalloc->Free( pStringsBuffer );
return ResultFromScode( hr );
}
//**********************************************************************
//
// DoTests
//
// Purpose:
//
// Hooks up to the WMIOLEDB provider application,
// Parameters:
//
// none
//
// Return Value:
//
// S_OK - Success
// E_* - Failure
//
//
// Comments:
//
// At a high level, an OLE DB data consumer obtains data by
//
// 1. Getting hooked up to a data provider's Data Source object,
// and initializing that object
// 2. Getting a DBSession object from the Data Source object
// 3. Getting the data from the Rowset object.
//
// DoTests follows these steps by making calls to GetWMIOLEDBDataSource,
// GetDBSessionDataSource, and GetDataFromRowset
//
//**********************************************************************
HRESULT DoTests
(
)
{
IDBInitialize* pIDBInitialize = NULL;
IOpenRowset* pIOpenRowset = NULL;
IRowset* pIRowset = NULL;
HRESULT hr;
hr = GetWMIOLEDBDataSource( &pIDBInitialize );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "GetWMIOLEDBDataSource" );
goto error;
}
hr = GetDBSessionFromDataSource( pIDBInitialize, &pIOpenRowset );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "GetDBSessionFromDataSource" );
goto error;
}
pIDBInitialize->Release();
pIDBInitialize = NULL;
hr = GetRowsetFromDBSession( pIOpenRowset, g_pwcsTable, &pIRowset );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "GetRowsetFromDBCreateSession" );
goto error;
}
pIOpenRowset->Release();
pIOpenRowset = NULL;
hr = GetDataFromRowset( pIRowset );
if (FAILED(hr))
{
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "GetDataFromRowset" );
goto error;
}
pIRowset->Release();
pIRowset = NULL;
CoFreeUnusedLibraries();
DumpStatusMsg( "\nDone! ");
printf("\n\nFor more data from this run, see the log file wmiclnt.out\n" );
return ResultFromScode( S_OK );
error:
if (pIRowset)
pIRowset->Release();
if (pIOpenRowset)
pIOpenRowset->Release();
if (pIDBInitialize)
pIDBInitialize->Release();
return ResultFromScode( hr );
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//extern "C" int wmain( int argc, WCHAR * argv[] )
int main( int argc, char * argv[] )
{
DWORD dwVersion;
HRESULT hr;
BOOL fOleInitialized = FALSE;
char ch;
//=====================================================================================
// Parse the command line
//=====================================================================================
if( !ParseCommandLine(argc,argv) ){
return 1;
}
InitializeLogFile();
dwVersion = OleBuildVersion();
if (HIWORD(dwVersion) != rmm){
DumpErrorMsg( "Error: OLE version mismatch. Build version %ld, current version %ld\n",
rmm, HIWORD(dwVersion) );
goto error;
}
hr = OleInitialize( NULL );
if (FAILED(hr)){
DUMP_ERROR_LINENUMBER();
DumpErrorMsg("Error: OleInitialize failed\n");
goto error;
}
fOleInitialized = TRUE;
hr = CoGetMalloc( MEMCTX_TASK, &g_pIMalloc );
if (FAILED(hr)) {
DUMP_ERROR_LINENUMBER();
DumpErrorMsg("Error: CoGetMalloc failed\n");
goto error;
}
hr = DoTests();
if (FAILED(hr)){
DUMP_ERROR_LINENUMBER();
DumpErrorHResult( hr, "DoTests");
goto error;
}
g_pIMalloc->Release();
OleUninitialize();
if (g_fpLogFile)
fclose(g_fpLogFile);
/* Pause before we quit, in case user ran from an icon, so they can see our messages. */
printf("\n\n>>> Output has gone into 'wmiclnt.out'.");
printf("\n>>> You may wish to use a wide-column editor to view this file.\n\n");
printf("<press any key to continue>");
ch = _getch();
return -1;
error:
if (g_pIMalloc)
g_pIMalloc->Release();
if (fOleInitialized)
OleUninitialize();
if (g_fpLogFile)
fclose(g_fpLogFile);
/* Pause before we quit, in case user ran from an icon, so they can see our messages. */
printf("\n\n>>> Output has gone into 'wmiclnt.out'.");
printf("\n>>> You may wish to use a wide-column editor to view this file.\n\n");
printf("<press any key to continue>");
ch = _getch();
return 2;
}