DUMP.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:16k
源码类别:
Windows编程
开发平台:
Visual C++
- //--------------------------------------------------------------------
- // Microsoft OLE DB Sample Consumer
- // (C) Copyright 1995 - 1998 Microsoft Corporation. All Rights Reserved.
- //
- // File name: DUMP.CPP
- //
- // Dumpoutput routines for the SAMPCLNT sample OLE DB consumer.
- //
- // See README.TXT for more information on the SAMPCLNT sample.
- //
- // Functions:
- //
- // See SAMPCLNT.H for function prototypes
- //
- #include "sampclnt.h"
- void DumpErrorMsg
- (
- const char* format,
- ...
- )
- {
- va_list argptr;
- assert(format != NULL);
- // log this message to stderr and to our log file
- va_start( argptr, format );
- tvfprintf( stderr, format, argptr);
- tvfprintf( g_fpLogFile, format, argptr);
- va_end( argptr );
- }
- void DumpStatusMsg
- (
- const char* format,
- ...
- )
- {
- va_list argptr;
- assert(format != NULL);
- // log this message to stdout and to our log file
- va_start( argptr, format );
- tvfprintf( stdout, format, argptr );
- tvfprintf( g_fpLogFile, format, argptr );
- va_end( argptr );
- }
- HRESULT DumpErrorHResult
- (
- HRESULT hr_return,
- const char *format, // can be NULL
- ...
- )
- {
- char buff[100];
- int cBytesWritten;
- va_list argptr;
- //
- // Dump an error message.
- // Print the text of the HRESULT,
- // Return the HRESULT we were passed.
- // these result codes were generated from the oledberr.h
- static Note ResultCodes[] = {
- // oledberr.h error codes
- NOTE(DB_E_BADACCESSORHANDLE),
- NOTE(DB_E_BADACCESSORHANDLE),
- NOTE(DB_E_ROWLIMITEXCEEDED),
- NOTE(DB_E_READONLYACCESSOR),
- NOTE(DB_E_SCHEMAVIOLATION),
- NOTE(DB_E_BADROWHANDLE),
- NOTE(DB_E_OBJECTOPEN),
- NOTE(DB_E_BADBINDINFO),
- NOTE(DB_SEC_E_PERMISSIONDENIED),
- NOTE(DB_E_NOTAREFERENCECOLUMN),
- NOTE(DB_E_NOCOMMAND),
- NOTE(DB_E_BADBOOKMARK),
- NOTE(DB_E_BADLOCKMODE),
- NOTE(DB_E_PARAMNOTOPTIONAL),
- NOTE(DB_E_BADRATIO),
- NOTE(DB_E_ERRORSINCOMMAND),
- NOTE(DB_E_BADSTARTPOSITION),
- NOTE(DB_E_NOTREENTRANT),
- NOTE(DB_E_NOAGGREGATION),
- NOTE(DB_E_DELETEDROW),
- NOTE(DB_E_CANTFETCHBACKWARDS),
- NOTE(DB_E_ROWSNOTRELEASED),
- NOTE(DB_E_BADSTORAGEFLAG),
- NOTE(DB_E_BADSTATUSVALUE),
- NOTE(DB_E_CANTSCROLLBACKWARDS),
- NOTE(DB_E_INTEGRITYVIOLATION),
- NOTE(DB_E_ABORTLIMITREACHED),
- NOTE(DB_E_DUPLICATEINDEXID),
- NOTE(DB_E_NOINDEX),
- NOTE(DB_E_INDEXINUSE),
- NOTE(DB_E_NOTABLE),
- NOTE(DB_E_CONCURRENCYVIOLATION),
- NOTE(DB_E_BADCOPY),
- NOTE(DB_E_BADPRECISION),
- NOTE(DB_E_BADSCALE),
- NOTE(DB_E_BADID),
- NOTE(DB_E_BADTYPE),
- NOTE(DB_E_DUPLICATECOLUMNID),
- NOTE(DB_E_DUPLICATETABLEID),
- NOTE(DB_E_TABLEINUSE),
- NOTE(DB_E_NOLOCALE),
- NOTE(DB_E_BADRECORDNUM),
- NOTE(DB_E_BOOKMARKSKIPPED),
- NOTE(DB_E_BADPROPERTYVALUE),
- NOTE(DB_E_INVALID),
- NOTE(DB_E_BADACCESSORFLAGS),
- NOTE(DB_E_BADSTORAGEFLAGS),
- NOTE(DB_E_BYREFACCESSORNOTSUPPORTED),
- NOTE(DB_E_NULLACCESSORNOTSUPPORTED),
- NOTE(DB_E_NOTPREPARED),
- NOTE(DB_E_BADACCESSORTYPE),
- NOTE(DB_E_WRITEONLYACCESSOR),
- NOTE(DB_SEC_E_AUTH_FAILED),
- NOTE(DB_E_CANCELED),
- NOTE(DB_E_BADSOURCEHANDLE),
- NOTE(DB_S_ROWLIMITEXCEEDED),
- NOTE(DB_S_COLUMNTYPEMISMATCH),
- NOTE(DB_S_TYPEINFOOVERRIDDEN),
- NOTE(DB_S_BOOKMARKSKIPPED),
- NOTE(DB_S_ENDOFROWSET),
- NOTE(DB_S_BUFFERFULL),
- NOTE(DB_S_CANTRELEASE),
- NOTE(DB_S_DIALECTIGNORED),
- NOTE(DB_S_UNWANTEDPHASE),
- NOTE(DB_S_COLUMNSCHANGED),
- NOTE(DB_S_ERRORSRETURNED),
- NOTE(DB_S_BADROWHANDLE),
- NOTE(DB_S_DELETEDROW),
- NOTE(DB_S_STOPLIMITREACHED),
- NOTE(DB_S_LOCKUPGRADED),
- NOTE(DB_S_PROPERTIESCHANGED),
- NOTE(DB_S_ERRORSOCCURRED),
- NOTE(DB_S_PARAMUNAVAILABLE),
- NOTE(DB_S_MULTIPLECHANGES),
- // winerr.h
- NOTE(E_UNEXPECTED),
- NOTE(E_NOTIMPL),
- NOTE(E_OUTOFMEMORY),
- NOTE(E_INVALIDARG),
- NOTE(E_NOINTERFACE),
- NOTE(E_POINTER),
- NOTE(E_HANDLE),
- NOTE(E_ABORT),
- NOTE(E_FAIL),
- NOTE(E_ACCESSDENIED),
- NOTE(S_OK),
- NOTE(S_FALSE),
- NOTE(E_UNEXPECTED),
- NOTE(E_NOTIMPL),
- NOTE(E_OUTOFMEMORY),
- NOTE(E_INVALIDARG),
- NOTE(E_NOINTERFACE),
- NOTE(E_POINTER),
- NOTE(E_HANDLE),
- NOTE(E_ABORT),
- NOTE(E_FAIL),
- NOTE(E_ACCESSDENIED),
- // BindMoniker Errors
- NOTE(MK_E_NOOBJECT),
- NOTE(MK_E_EXCEEDEDDEADLINE),
- NOTE(MK_E_CONNECTMANUALLY),
- NOTE(MK_E_INTERMEDIATEINTERFACENOTSUPPORTED),
- NOTE(STG_E_ACCESSDENIED),
- NOTE(MK_E_SYNTAX),
- NOTE(MK_E_CANTOPENFILE),
- };
- // Format the message.
- // Print name of hresult code.
- if (format)
- {
- va_start( argptr, format );
- cBytesWritten = _vsnprintf( buff, sizeof(buff), format, argptr );
- va_end( argptr );
- }
- else
- strcpy( buff, "" );
- // log to stderr and also to our log file
- tfprintf( stderr, "%.*s: Returned %.30sn",
- sizeof(buff), buff,
- GetNoteString( ResultCodes, NUMELEM(ResultCodes), GetScode(hr_return)) );
- tfprintf( g_fpLogFile, "%.*s: Returned %.30sn",
- sizeof(buff), buff,
- GetNoteString( ResultCodes, NUMELEM(ResultCodes), GetScode(hr_return)) );
- return ResultFromScode( hr_return );
- }
- void DumpColumnsInfo
- (
- DBCOLUMNINFO* pColInfo,
- ULONG cCol
- )
- {
- ULONG j;
- assert(pColInfo != NULL);
- tfprintf( g_fpLogFile, "nColumn Information:nn");
- for (j=0; j < cCol; j++)
- {
- WriteColumnInfo( g_fpLogFile, &pColInfo[j] );
- }
- }
- void WriteColumnInfo
- (
- FILE* fp,
- DBCOLUMNINFO* p
- )
- {
- DBID *pCol;
- DBKIND eKind;
- wchar_t wszGuidBuff[MAX_GUID_STRING];
- wchar_t wszNameBuff[MAX_GUID_STRING];
- static char *szDbcolkind[] = { "Guid+Name", "Guid+PropID", "Name",
- "Guid+Name", "Guid+PropID", "PropID", "Guid" };
- assert(p != NULL);
- // For DBTYPEENUM. Doesn't need to be in order.
- // Below we mask off the high bits.
- static Note typenotes[] =
- {
- NOTE(DBTYPE_EMPTY),
- NOTE(DBTYPE_NULL),
- NOTE(DBTYPE_I2),
- NOTE(DBTYPE_I4),
- NOTE(DBTYPE_R4),
- NOTE(DBTYPE_R8),
- NOTE(DBTYPE_CY),
- NOTE(DBTYPE_DATE),
- NOTE(DBTYPE_BSTR),
- NOTE(DBTYPE_IDISPATCH),
- NOTE(DBTYPE_ERROR),
- NOTE(DBTYPE_BOOL),
- NOTE(DBTYPE_VARIANT),
- NOTE(DBTYPE_IUNKNOWN),
- NOTE(DBTYPE_DECIMAL),
- NOTE(DBTYPE_UI1),
- NOTE(DBTYPE_ARRAY),
- NOTE(DBTYPE_BYREF),
- NOTE(DBTYPE_I1),
- NOTE(DBTYPE_UI2),
- NOTE(DBTYPE_UI4),
- NOTE(DBTYPE_I8),
- NOTE(DBTYPE_UI8),
- NOTE(DBTYPE_GUID),
- NOTE(DBTYPE_VECTOR),
- NOTE(DBTYPE_RESERVED),
- NOTE(DBTYPE_BYTES),
- NOTE(DBTYPE_STR),
- NOTE(DBTYPE_WSTR),
- NOTE(DBTYPE_NUMERIC),
- NOTE(DBTYPE_UDT),
- NOTE(DBTYPE_DBDATE),
- NOTE(DBTYPE_DBTIME),
- NOTE(DBTYPE_DBTIMESTAMP),
- };
- static Note flagnotes[] =
- {
- NOTE(DBCOLUMNFLAGS_ISBOOKMARK),
- NOTE(DBCOLUMNFLAGS_MAYDEFER),
- NOTE(DBCOLUMNFLAGS_WRITE),
- NOTE(DBCOLUMNFLAGS_WRITEUNKNOWN),
- NOTE(DBCOLUMNFLAGS_ISFIXEDLENGTH),
- NOTE(DBCOLUMNFLAGS_ISNULLABLE),
- NOTE(DBCOLUMNFLAGS_MAYBENULL),
- NOTE(DBCOLUMNFLAGS_ISLONG),
- NOTE(DBCOLUMNFLAGS_ISROWID),
- NOTE(DBCOLUMNFLAGS_ISROWVER),
- NOTE(DBCOLUMNFLAGS_CACHEDEFERRED),
- };
- pCol = & p->columnid;
- eKind = pCol->eKind;
- // stringize GUID for pretty printing
- switch (eKind)
- {
- case DBKIND_GUID_NAME:
- case DBKIND_GUID_PROPID:
- case DBKIND_GUID:
- StringFromGUID2( pCol->uGuid.guid, wszGuidBuff, sizeof(wszGuidBuff) );
- break;
- case DBKIND_PGUID_NAME:
- case DBKIND_PGUID_PROPID:
- StringFromGUID2( *(pCol->uGuid.pguid), wszGuidBuff, sizeof(wszGuidBuff) );
- break;
- default:
- wcscpy( wszGuidBuff, L"<none>" );
- break;
- }
- // stringize name or propID for pretty printing
- switch (eKind)
- {
- case DBKIND_GUID_NAME:
- case DBKIND_NAME:
- case DBKIND_PGUID_NAME:
- swprintf( wszNameBuff, L"[name=%.50S]", pCol->uName.pwszName ? pCol->uName.pwszName : L"(unknown)" );
- break;
- case DBKIND_GUID_PROPID:
- case DBKIND_PGUID_PROPID:
- case DBKIND_PROPID:
- swprintf( wszNameBuff, L"[propid=%lu]", pCol->uName.ulPropid );
- break;
- default:
- wcscpy( wszNameBuff, L"" );
- break;
- }
- // pretty print column info
- tfprintf( fp, "ColumnId [kind=%.40s] [guid=%.40S] %.60Sn",
- szDbcolkind[eKind], wszGuidBuff, wszNameBuff );
- // Now move on to other stuff...
- // Name in DBCOLUMNINFO different than name in DBCOLUMNID (maybe).
- tfprintf(fp, " Name = '%.50S'n", p->pwszName );
- tfprintf(fp, " iOrdinal = %dn", p->iOrdinal);
- tfprintf(fp, " wType = %.100sn",
- GetNoteString( typenotes, NUMELEM(typenotes),
- p->wType & (~DBTYPE_BYREF) & (~DBTYPE_ARRAY) & (~DBTYPE_VECTOR) ) );
- if (p->wType & DBTYPE_BYREF)
- tfprintf(fp, " (BYREF)n");
- if (p->wType & DBTYPE_ARRAY)
- tfprintf(fp, " (ARRAY)n");
- if (p->wType & DBTYPE_VECTOR)
- tfprintf(fp, " (VECTOR)n");
- tfprintf(fp, " ulColumnSize = %ldn", p->ulColumnSize );
- tfprintf(fp, " bPrecision = %dn", p->bPrecision );
- tfprintf(fp, " bScale = %dn", p->bScale );
- tfprintf(fp, " dwFlags = %snn",
- GetNoteStringBitvals( flagnotes, NUMELEM(flagnotes), p->dwFlags ) );
- }
- char* GetNoteString
- (
- Note * rgNote,
- int cNote,
- DWORD dwValue
- )
- {
- int j;
- assert(rgNote != NULL);
- // Scan a table of value/string,
- // return ptr to string found.
- for (j=0; j < cNote; j++) {
- if (rgNote[j].dwFlag == dwValue)
- return rgNote[j].szText;
- }
- return "<unknown>";
- }
- char* GetNoteStringBitvals
- (
- Note* rgNote,
- int cNote,
- DWORD dwValue
- )
- {
- static char buff[400];
- int j;
- assert(rgNote != NULL);
- // Make a string that combines all the bits ORed together.
- strcpy(buff, "");
- for (j=0; j < cNote; j++) {
- if (rgNote[j].dwFlag & dwValue) {
- if (buff[0])
- strcat( buff, " | " );
- strcat( buff, rgNote[j].szText );
- }
- }
- assert(strlen(buff) < sizeof(buff));
- return buff;
- }
- ULONG CalcPrettyPrintMaxColWidth
- (
- DBBINDING* rgBind,
- ULONG cBind
- )
- {
- ULONG cMaxWidth;
- ULONG cTotalWidth;
- ULONG iBind;
- assert(rgBind != NULL);
- cMaxWidth = DEFAULT_CBMAXLENGTH;
- while (1)
- {
- cTotalWidth = 0;
- for (iBind=0; iBind < cBind; iBind++)
- cTotalWidth += min( cMaxWidth, rgBind[iBind].cbMaxLen ) + 1;
- if (cTotalWidth < PRETTYPRINT_MAXTOTALWIDTH || cMaxWidth < PRETTYPRINT_MINCOLWIDTH)
- break;
- cMaxWidth--;
- }
- return cMaxWidth;
- }
- void DumpColumnHeadings
- (
- DBBINDING* rgBind,
- ULONG cBind,
- DBCOLUMNINFO* pColInfo,
- ULONG cCol,
- ULONG cMaxColWidth
- )
- {
- ULONG iBind;
- assert(rgBind != NULL);
- assert(pColInfo != NULL);
- for (iBind=0; iBind < cBind; iBind++)
- tfprintf( g_fpLogFile, "%-*.*S ",
- min( cMaxColWidth, rgBind[iBind].cbMaxLen ),
- min( cMaxColWidth, rgBind[iBind].cbMaxLen ),
- LookupColumnName( pColInfo, cCol, rgBind[iBind].iOrdinal ) );
- tfprintf( g_fpLogFile, "n" );
- for (iBind=0; iBind < cBind; iBind++)
- tfprintf( g_fpLogFile, "%-*.*s ",
- min( cMaxColWidth, rgBind[iBind].cbMaxLen ),
- min( cMaxColWidth, rgBind[iBind].cbMaxLen ),
- "------------------------------" );
- tfprintf( g_fpLogFile, "n" );
- }
- WCHAR* LookupColumnName
- (
- DBCOLUMNINFO* rgColInfo,
- ULONG cCol,
- ULONG iCol
- )
- {
- ULONG j;
- assert(rgColInfo != NULL);
- // A really slow way to get the column name, given the ordinal.
- // The problem is that result-set ordinals do not necessarily match
- // the index into the ColumnInfo array.
- // (May have bookmark, which is always column 0.)
- for (j=0; j < cCol; j++)
- if (rgColInfo[j].iOrdinal == iCol)
- return rgColInfo[j].pwszName;
- return L"Error";
- }
- void DumpRow
- (
- DBBINDING* rgBind,
- ULONG cBind,
- ULONG cMaxColWidth,
- BYTE* pData
- )
- {
- ULONG iBind;
- COLUMNDATA* pColumn;
- assert(rgBind);
- assert( offsetof(COLUMNDATA, dwLength) == 0);
- // Print each column we're bound to.
- for (iBind=0; iBind < cBind; iBind++)
- {
- // Columns are bound differently; not so easy.
- // Print out to at least DEFAULT_CBMAXLENGTH width (pretty),
- // Limit to first dwLength characters.
- pColumn = (COLUMNDATA *) (pData + rgBind[iBind].obLength);
- PrintColumn( pColumn, rgBind, iBind, cMaxColWidth );
- }
- tfprintf( g_fpLogFile, "n" );
- }
- void PrintColumn
- (
- COLUMNDATA *pColumn,
- DBBINDING *rgBind,
- ULONG iBind,
- ULONG cMaxColWidth
- )
- {
- void* p;
- ULONG ulPrintWidth;
- ULONG ulPrintPrecision;
- DWORD dwStatus;
- DWORD dwLength;
- BOOL fDidVariant;
- BOOL fIsUnicode;
- char* sFormat;
- HRESULT hr;
- assert(pColumn != NULL);
- assert(rgBind != NULL);
- // Pretty print a column.
- // May have different type of binding.
- fDidVariant = FALSE;
- fIsUnicode = FALSE;
- dwStatus = pColumn->dwStatus;
- dwLength = pColumn->dwLength;
- if (dwStatus == DBSTATUS_S_ISNULL)
- {
- p = "<null>";
- dwLength = strlen( (char *) p);
- }
- else if (dwStatus == DBBINDSTATUS_UNSUPPORTEDCONVERSION)
- {
- p = "<unsupportedconversion>";
- dwLength = strlen( (char *) p);
- }
- else
- {
- switch (rgBind[iBind].wType)
- {
- case DBTYPE_STR:
- // We have a string in our buffer, so use it.
- p = (void *) &pColumn->bData;
- break;
- case DBTYPE_VARIANT:
- // We have a variant in our buffer, so convert to string.
- p = (void *) &pColumn->bData;
- hr = VariantChangeTypeEx(
- (VARIANT *) p, // Destination (convert in place)
- (VARIANT *) p, // Source
- LOCALE_SYSTEM_DEFAULT, // LCID
- 0, // dwFlags
- VT_BSTR );
- if (FAILED(hr))
- {
- DumpErrorHResult( hr, "VariantChangeTypeEx, field %d", iBind );
- return;
- }
- p = (wchar_t *) (((VARIANT *)p)->bstrVal) ;
- dwLength = ((DWORD *)p)[-1] / sizeof(wchar_t);
- fDidVariant = TRUE;
- fIsUnicode = TRUE;
- break;
- default:
- p = "??? unknown type ???";
- break;
- }
- }
- // Print the column.
- // If it has been truncated or rounded, print a '#' in
- // the far right-hand column.
- ulPrintWidth = min( cMaxColWidth, rgBind[iBind].cbMaxLen );
- ulPrintPrecision = min( cMaxColWidth, dwLength );
- if (dwStatus == DBSTATUS_S_TRUNCATED || cMaxColWidth < dwLength)
- {
- ulPrintWidth--;
- ulPrintPrecision--;
- }
- sFormat = fIsUnicode ? "%-*.*S" : "%-*.*s";
- tfprintf( g_fpLogFile, sFormat, ulPrintWidth, ulPrintPrecision, p );
- if (dwStatus == DBSTATUS_S_TRUNCATED || cMaxColWidth < dwLength)
- tfprintf( g_fpLogFile, "#" );
- tfprintf( g_fpLogFile, " " );
- // Free memory used by the variant.
- if (fDidVariant)
- VariantClear( (VARIANT *) &pColumn->bData );
- return;
- }
- void tfprintf
- (
- FILE* fp,
- const char* format,
- ...
- )
- {
- int cBytesWritten;
- char buff[400];
- va_list argptr;
- assert(format != NULL);
- // Dump a formatted string.
- // _vsnprintf prevents overflowing our buffer.
- va_start( argptr, format );
- cBytesWritten = _vsnprintf( buff, sizeof(buff), format, argptr );
- va_end( argptr );
- buff[sizeof(buff)-1] = ' ';
- // Can't use fprintf, because string could contain '%'.
- if (fp)
- fputs( buff, fp );
- }
- void tvfprintf
- (
- FILE* fp,
- const char* format,
- va_list argptr
- )
- {
- int cBytesWritten;
- char buff[400];
- assert(format != NULL);
- // Dump a formatted string.
- // _vsnprintf prevents overflowing our buffer.
- cBytesWritten = _vsnprintf( buff, sizeof(buff), format, argptr );
- buff[sizeof(buff)-1] = ' ';
- // Can't use fprintf, because string could contain '%'.
- if (fp)
- fputs( buff, fp );
- }