Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1044 lines
22 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: OleAPIs.cxx (16 bit target)
//
// Contents: OLE2 APIs
//
// Functions:
//
// History: 17-Dec-93 Johann Posch (johannp) Created
//
//--------------------------------------------------------------------------
#include <headers.cxx>
#pragma hdrstop
// cdebug.cpp - implemention of debugstream and IDebug interface/class
/*
#include <olerem.h> //for RemLookupSHUnk
#pragma SEG(cdebug)
#include <string.h>
#include <toolhelp.h>
*/
//some constants used only in this file
#define DBGMARGIN 45
#define DBGTABSIZE 4
#define HEADER 1
#define NOHEADER 0
#define DBGLOGFILENAME "debug.log"
static void GetCurDateTime(LPSTR lpsz);
STDAPI_(HFILE) DbgLogOpen(LPSTR lpszFile, LPSTR lpszMode)
{
#ifdef _DEBUG
#ifndef _MAC
HFILE fh;
AssertSz( lpszFile && lpszMode, "Invalid arguments to DbgLogOpen");
switch (lpszMode[0]) {
case 'w':
// Open for writing (overwrite if exists)
fh = _lcreat(lpszFile, 0);
break;
case 'r':
// Open for reading
fh = _lopen(lpszFile, OF_READ);
break;
case 'a':
// Open for appending
// to append to log file seek to end before writing
if ((fh = _lopen(lpszFile, OF_READWRITE)) != -1) {
_llseek(fh, 0L, SEEK_END);
} else {
// file does not exist, create a new one.
fh = _lcreat(lpszFile, 0);
}
break;
}
return fh;
#endif //_MAC
#else
(void) lpszFile;
(void) lpszMode;
return -1;
#endif //_DEBUG
}
STDAPI_(void) DbgLogClose(HFILE fh)
{
#ifdef _DEBUG
#ifndef _MAC
if (fh != -1)
_lclose(fh);
#endif
#else
(void) fh;
#endif
}
STDAPI_(void) DbgLogWrite(HFILE fh, LPSTR lpsz)
{
#ifdef _DEBUG
#ifndef _MAC
if (fh != -1 && lpsz)
_lwrite(fh, lpsz, lstrlen(lpsz));
#endif
#else
(void) fh;
(void) lpsz;
#endif
}
STDAPI_(void) DbgLogTimeStamp(HFILE fh, LPSTR lpsz)
{
#ifdef _DEBUG
char buffer[80];
GetCurDateTime(buffer);
DbgLogOutputDebugString(fh, "\n***************************************\n");
if (lpsz) DbgLogOutputDebugString(fh, lpsz);
DbgLogOutputDebugString(fh, ": ");
DbgLogOutputDebugString(fh, buffer);
DbgLogOutputDebugString(fh, "\n");
DbgLogOutputDebugString(fh, ".......................................\n\n");
#else
(void) fh;
(void) lpsz;
#endif
}
STDAPI_(void) DbgLogWriteBanner(HFILE fh, LPSTR lpsz)
{
#ifdef _DEBUG
DbgLogOutputDebugString(fh, "\n***************************************\n");
if (lpsz) DbgLogOutputDebugString(fh, lpsz);
DbgLogOutputDebugString(fh, "\n");
DbgLogOutputDebugString(fh, ".......................................\n\n");
#else
(void) fh;
(void) lpsz;
#endif
}
STDAPI_(void) DbgLogOutputDebugString(HFILE fh, LPSTR lpsz)
{
#ifdef _DEBUG
#ifndef _MAC
if (fh != -1)
DbgLogWrite(fh, lpsz);
OutputDebugString(lpsz);
#endif
#else
(void)fh;
(void)lpsz;
#endif
}
#ifdef _DEBUG
static void GetCurDateTime(LPSTR lpsz)
{
unsigned year, month, day, dayOfweek, hours, min, sec;
static char FAR* dayNames[7] =
{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
static char FAR* monthNames[12] =
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
#ifndef _MAC
#ifdef WIN32
SYSTEMTIME st;
GetLocalTime(&st);
year = st.wYear;
month = st.wMonth - 1;
dayOfweek = st.wDayOfWeek;
day = st.wDay;
hours = st.wHour;
min = st.wMinute;
sec = st.wSecond;
#else
_asm {
// Call GetDate
mov ah, 0x2a
int 0x21
mov year, cx
mov month, dx
mov day, dx
mov dayOfweek, ax
// Call GetTime
mov ah, 0x2c
int 0x21
mov hours, cx
mov min, cx
mov sec, dx
}
month >>= 8;
month -= 1;
day &= 0xFF;
dayOfweek &= 0xFF;
hours >>= 8;
min &= 0xFF;
sec >>= 8;
#endif //_WIN32
#else // defined(_MAC)
// REVIEW MAC -- need function here to get current date & time
day = 9;
month = 1;
year = 1960;
hours = 12;
min = 30;
sec = 17;
#endif //_MAC
// Format time as: Wed Jan 02 02:03:55 1990
// Format time as: Wed 05/02/1992 02:03:55
wsprintf(lpsz, "%s %s %02d %02d:%02d:%02d %d",
dayNames[dayOfweek],monthNames[month], day, hours, min, sec, year);
}
class FAR CDebugLog
{
private:
HFILE m_fhLog;
public:
CDebugLog( ) { m_fhLog = -1; }
CDebugLog( LPSTR lpszFileName );
~CDebugLog() { DbgLogClose(m_fhLog); }
HFILE Open(LPSTR lpszFileName, LPSTR lpszMode)
{ return (m_fhLog = DbgLogOpen(lpszFileName, lpszMode)); }
void Close(void) { DbgLogClose(m_fhLog); m_fhLog = -1; }
void OutputDebugString(LPSTR lpsz) { DbgLogOutputDebugString(m_fhLog, lpsz); }
void TimeStamp(LPSTR lpsz) { DbgLogTimeStamp(m_fhLog, lpsz); }
void WriteBanner(LPSTR lpsz) { DbgLogWriteBanner(m_fhLog, lpsz); }
};
#if 0
class FAR CDebugStream
{
public:
OLESTATIC_(IDebugStream FAR *) Create( // no aggregation
int margin, int tabsize, BOOL fHeader);
private:
CDebugStream( int margin, int tabsize, BOOL fHeader );
~CDebugStream();
void OutputDebugString( LPSTR lpsz ) {m_DbgLog.OutputDebugString(lpsz);}
implementations:
implement CDSImpl : IDebugStream
{
public:
CDSImpl( CDebugStream FAR * pDebugStream )
{ m_pDebugStream = pDebugStream; }
~CDSImpl( void ) ; //{ if (m_pDebugStream->m_pendingReturn) ForceReturn(); }
void PrintString( LPSTR );
void ForceReturn( void );
void ReturnIfPending( void );
OLEMETHOD(QueryInterface)(REFIID iid, LPVOID FAR* ppvObj );
OLEMETHOD_(ULONG,AddRef)( void );
OLEMETHOD_(ULONG,Release)( void );
OLEMETHOD_(IDebugStream&, operator << ) ( IUnknown FAR * pDebug );
OLEMETHOD_(IDebugStream&, operator << ) ( REFCLSID rclsid );
OLEMETHOD_(IDebugStream&, operator << ) ( int n );
OLEMETHOD_(IDebugStream&, operator << ) ( long l );
OLEMETHOD_(IDebugStream&, operator << ) ( ULONG l );
OLEMETHOD_(IDebugStream&, operator << ) ( LPSTR sz );
OLEMETHOD_(IDebugStream&, operator << ) ( char ch );
OLEMETHOD_(IDebugStream&, operator << ) ( void FAR * pv );
OLEMETHOD_(IDebugStream&, operator << ) ( CBool b );
OLEMETHOD_(IDebugStream&, operator << ) ( CAtom atom );
OLEMETHOD_(IDebugStream&, operator << ) ( CHwnd hwnd );
OLEMETHOD_(IDebugStream&, Tab) ( void );
OLEMETHOD_(IDebugStream&, Indent) ( void );
OLEMETHOD_(IDebugStream&, UnIndent) ( void );
OLEMETHOD_(IDebugStream&, Return) ( void );
OLEMETHOD_(IDebugStream&, LF) ( void );
CDebugStream FAR * m_pDebugStream;
};
DECLARE_NC(CDebugStream,CDSImpl)
CDSImpl m_DebugStream;
shared_state:
ULONG m_refs;
int m_indent;
int m_position;
int m_margin;
int m_tabsize;
BOOL m_pendingReturn;
CDebugLog m_DbgLog;
};
#endif
#endif // _DEBUG
/*
* The member variable m_pendingReturn is a hack to allow
* the sequence of operations Return, UnIndent put the character
* at the *beginning of the unindented line* The debugwindow does
* not seem to support going to the beginning of the line or
* backspacing, so we do not actually do a Return until we know
* that the next operation is not UnIndent.
*
*/
/*
* Implementation of per process list heads
*/
#ifdef NEVER // per-proces debug lists not used
static IDebug FAR * GetIDHead()
{
if this gets enabled, the map should be in the etask
}
static void SetIDHead(IDebug FAR* pIDHead)
{
if this gets enabled, the map should be in the etask
}
#endif // NEVER
/*
* Implementation of IDebug constructor and destructor
*/
#ifdef NEVER
__export IDebug::IDebug( void )
{
SETPVTBL(IDebug);
//#ifdef _DEBUG
BOOL fIsShared = (SHARED == PlacementOf(this));
IDebug FAR* pIDHead = (fIsShared ? pIDHeadShared : GetIDHead());
pIDPrev = NULL;
if (pIDHead)
pIDHead->pIDPrev = this;
pIDNext = pIDHead;
if (fIsShared) pIDHeadShared = this;
else SetIDHead(this);
}
#endif //NEVER
#ifdef NEVER
__export IDebug::~IDebug( void )
{
//#ifdef _DEBUG
BOOL fIsShared = (SHARED == PlacementOf(this));
if (pIDPrev)
pIDPrev->pIDNext = pIDNext;
else
if (fIsShared) pIDHeadShared = pIDNext;
else
SetIDHead(pIDNext);
if (pIDNext)
pIDNext->pIDPrev = pIDPrev;
}
#endif //NEVER
//REVIEW: maybe we should expose this later
STDAPI OleGetClassID( LPUNKNOWN pUnk, LPCLSID lpclsid )
{
HRESULT hresult = NOERROR;
#if 0
LPRUNNABLEOBJECT lpRunnableObject = NULL;
LPPERSIST lpPersist = NULL;
VDATEIFACE(pUnk);
VDATEPTROUT(lpclsid, LPCLSID);
*lpclsid = CLSID_NULL;
pUnk->QueryInterface(IID_IRunnableObject, (LPLPVOID)&lpRunnableObject);
if( lpRunnableObject ){
hresult = lpRunnableObject->GetRunningClass(lpclsid);
lpRunnableObject->Release();
} else {
pUnk->QueryInterface(IID_IPersist, (LPLPVOID)&lpPersist);
if( lpPersist ){
hresult = lpPersist->GetClassID( lpclsid );
lpPersist->Release();
}
}
#endif
return hresult;
}
#ifdef _DEBUG
CDebugStream::CDebugStream( int margin, int tabsize, BOOL fHeader) : m_DebugStream(this)
{
#ifndef _MAC
static BOOL fAppendFile = FALSE;
// Create the debug log file. Overwrite the existing file if it exists.
m_DbgLog.Open(DBGLOGFILENAME, (fAppendFile ? "a" : "w"));
if( fHeader )
// only add creation timestamp to top of file.
if (! fAppendFile) {
m_DbgLog.TimeStamp("Created");
fAppendFile = TRUE;
} else {
m_DbgLog.WriteBanner(NULL);
}
#endif
m_indent = 0;
m_position = m_indent;
m_margin = margin;
m_tabsize = tabsize;
m_refs = 1;
m_pendingReturn = FALSE;
}
CDebugStream::~CDebugStream()
{
m_DbgLog.Close();
}
NC(CDebugStream,CDSImpl)::~CDSImpl(void)
{
if (m_pDebugStream->m_pendingReturn) ForceReturn();
}
OLEMETHODIMP NC(CDebugStream,CDSImpl)::QueryInterface(REFIID iidInterface,
void FAR* FAR* ppvObj )
{
VDATEPTROUT(ppvObj, LPLPVOID);
if (iidInterface == IID_IUnknown || iidInterface == IID_IDebugStream) {
*ppvObj = (void FAR *)this;
return NOERROR;
} else {
*ppvObj = NULL;
return ReportResult(0, E_NOINTERFACE, 0, 0);
}
}
OLEMETHODIMP_(ULONG) NC(CDebugStream,CDSImpl)::AddRef( void )
{
return ++m_pDebugStream->m_refs;
}
OLEMETHODIMP_(ULONG) NC(CDebugStream,CDSImpl)::Release( void )
{
if (--m_pDebugStream->m_refs == 0) {
delete m_pDebugStream;
return 0;
}
return m_pDebugStream->m_refs;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (int n)
{
char buffer[12];
ReturnIfPending();
buffer[wsprintf(buffer, "%d", n)] = '\0';
PrintString(buffer);
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (long l)
{
char buffer[16];
ReturnIfPending();
buffer[wsprintf(buffer, "%ld", l)] = '\0';
PrintString(buffer);
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (ULONG l)
{
char buffer[16];
ReturnIfPending();
buffer[wsprintf(buffer, "%lu", l)] = '\0';
PrintString(buffer);
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (CAtom atom)
{
char buffer[128];
ReturnIfPending();
if( (ATOM)atom ){
if( !GetAtomName((ATOM)atom, (LPSTR)buffer, sizeof(buffer)) )
buffer[wsprintf(buffer, "Invalid atom")] = '\0';
}else
buffer[wsprintf(buffer, "NULL atom")] = '\0';
PrintString(buffer);
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (CHwnd hwnd)
{
char szBuf[128];
ReturnIfPending();
if( (HWND)hwnd )
szBuf[wsprintf(szBuf, "window handle: %x", (HWND)hwnd)] = '\0';
else
szBuf[wsprintf(szBuf, "NULL window handle")] = '\0';
PrintString(szBuf);
return *this;
}
LPSTR FindBreak( LPSTR sz, int currentPosition, int margin )
{
LPSTR szBreak = sz;
LPSTR szPtr = sz;
if( !sz )
return NULL;
while (*szPtr)
{
while (*(szPtr) && *(szPtr++) <= ' ');
while (*(szPtr) && *(szPtr++) > ' ');
if (currentPosition+(szPtr-sz) < margin)
{
szBreak = szPtr;
}
else return szBreak;
}
return szPtr;
}
/*
* PrintString is an internal utility routine that can assume that
* everything in the string (other than the null at the end) is >=
* ' '. Thus it knows that when it prints a single character, the
* position on the debug terminal advances a single columm. This
* would not be the case if the string could contain tabs,
* returns, etc.
*/
void NC(CDebugStream,CDSImpl)::PrintString (LPSTR sz)
{
// assert sz != NULL
LPSTR szUnprinted = sz;
LPSTR szPtr = sz;
char chSave;
#ifdef _MAC
Puts(sz);
return;
#endif
if( !sz )
return;
while (*szUnprinted)
{
szPtr = FindBreak( szUnprinted, m_pDebugStream->m_position, m_pDebugStream->m_margin );
if (szPtr == szUnprinted && m_pDebugStream->m_position > m_pDebugStream->m_indent)
{
Return();
szPtr = FindBreak( szUnprinted, m_pDebugStream->m_position, m_pDebugStream->m_margin );
if (szPtr == szUnprinted) // text won't fit even after word wrapping
{
m_pDebugStream->OutputDebugString(szUnprinted);
m_pDebugStream->m_position += _fstrlen(szUnprinted);
return;
}
}
chSave = *szPtr;
*szPtr = '\0';
if (m_pDebugStream->m_position == m_pDebugStream->m_indent) // no text on line, skip blanks
{
while (*szUnprinted == ' ') szUnprinted++;
}
m_pDebugStream->OutputDebugString(szUnprinted);
*szPtr = chSave;
m_pDebugStream->m_position += (szPtr - szUnprinted);
szUnprinted = szPtr;
}
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (char ch)
{
char buffer[2] = "a";
if (ch=='\n') Return();
else if (ch=='\t') Tab();
else if (ch >= ' ')
{
ReturnIfPending();
if (m_pDebugStream->m_position >= m_pDebugStream->m_margin) Return();
*buffer = ch;
m_pDebugStream->OutputDebugString(buffer);
m_pDebugStream->m_position++;
}
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (LPSTR sz)
{
LPSTR szCopy;
char chSave;
LPSTR szPtr;
LPSTR szPtrSave;
ReturnIfPending();
if (!sz)
return *this;
szCopy = new FAR (TASK) char[2+_fstrlen(sz)];
if (!szCopy)
{
Return();
PrintString("Memory allocation error in DebugStream");
Return();
return *this;
}
_fstrcpy( szCopy, sz );
for (szPtr = szCopy, szPtrSave = szCopy; *szPtr; szPtr++)
{
if ( *szPtr < ' ') // we hit a control character or the end
{
chSave = *szPtr;
*szPtr = '\0';
PrintString( szPtrSave );
if (chSave != '\0')
*szPtr = chSave;
szPtrSave = szPtr+1;
switch (chSave)
{
case '\t': Tab();
break;
case '\n': Return();
break;
case '\r': m_pDebugStream->OutputDebugString("\r");
break;
default:
break;
}
}
}
PrintString( szPtrSave );
delete szCopy;
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (CBool b)
{
ReturnIfPending();
if (b) PrintString("TRUE");
else PrintString("FALSE");
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << ( void FAR * pv )
{
char buffer[12];
LPSTR sz = "NULL";
ReturnIfPending();
if (pv != NULL)
{
buffer[wsprintf(buffer, "%lX", pv)] = '\0';
sz = buffer;
}
PrintString(sz);
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator <<
( REFCLSID rclsid )
{
char sz[256];
// REVIEW: do lookup in reg.dat for user type name
if( rclsid == CLSID_NULL )
_fstrcpy(sz, "NULL CLSID");
else if (StringFromCLSID2(rclsid, sz, sizeof(sz)) == 0)
_fstrcpy(sz, "Unknown CLSID");
*this << sz;
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator <<
( IUnknown FAR * pUnk )
{
IDebug FAR * pDebug = NULL;
CLSID clsid = CLSID_NULL;
ReturnIfPending();
if( IsValidInterface(pUnk) ){
pUnk->QueryInterface(IID_IDebug, (void FAR* FAR*)&pDebug);
if (pDebug) {
pDebug->Dump( this );
if ( !pDebug->IsValid( 0 ) )
*this << "Object is not valid" << '\n';
/*
* NB: Debug interfaces are *not* ref counted (so as not to skew the
* counts of the objects they are debugging! :)
*/
} else {
OleGetClassID(pUnk, (LPCLSID)&clsid);
*this << clsid << " @ "<<(VOID FAR *)pUnk << " doesn't support debug dumping";
}
} else if (!pUnk)
*this << "NULL interface";
else
*this << "Invalid interface @ " << (VOID FAR *)pUnk;
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::Tab( void )
{
ReturnIfPending();
int advance = m_pDebugStream->m_tabsize * ( 1 + m_pDebugStream->m_position/m_pDebugStream->m_tabsize) - m_pDebugStream->m_position;
if (m_pDebugStream->m_position + advance < m_pDebugStream->m_margin)
{
for (int i = 0; i < advance; i++)
m_pDebugStream->OutputDebugString(" ");
m_pDebugStream->m_position += advance;
}
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::Indent( void )
{
if (m_pDebugStream->m_indent + m_pDebugStream->m_tabsize < m_pDebugStream->m_margin)
m_pDebugStream->m_indent += m_pDebugStream->m_tabsize;
if (!m_pDebugStream->m_pendingReturn)
while (m_pDebugStream->m_position < m_pDebugStream->m_indent)
operator<<(' ');
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::UnIndent( void )
{
if (m_pDebugStream->m_indent > 0) m_pDebugStream->m_indent -= m_pDebugStream->m_tabsize;
return *this;
}
void NC(CDebugStream,CDSImpl)::ForceReturn( void )
{
m_pDebugStream->OutputDebugString("\n");
for (int i = 0; i<m_pDebugStream->m_indent; i++)
m_pDebugStream->OutputDebugString(" ");
m_pDebugStream->m_position = m_pDebugStream->m_indent;
m_pDebugStream->m_pendingReturn = FALSE;
}
void NC(CDebugStream,CDSImpl)::ReturnIfPending( void )
{
if (m_pDebugStream->m_pendingReturn) ForceReturn();
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::Return( void )
{
ReturnIfPending();
m_pDebugStream->m_pendingReturn = TRUE;
Yield(); // let dbwin get control
return *this;
}
OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::LF( void )
{
return Return();
}
OLESTATICIMP_(IDebugStream FAR *) CDebugStream::Create( // no aggregation
int margin, int tabsize, BOOL fHeader )
{
CDebugStream FAR * pcds = new FAR (TASK)CDebugStream( margin, tabsize, fHeader );
if( !pcds ){
AssertSz( pcds, "Out of Memory");
return NULL;
}
return &(pcds->m_DebugStream);
}
#endif // _DEBUG
#if 0
STDAPI_(IDebugStream FAR *) MakeDebugStream( short margin, short tabsize, BOOL fHeader)
{
#ifdef _DEBUG
return CDebugStream::Create( margin, tabsize, fHeader );
#else
(void) margin;
(void) tabsize;
(void) fHeader;
return NULL;
#endif // _DEBUG
}
#else
STDAPI_(void FAR *) MakeDebugStream( short margin, short tabsize, BOOL fHeader)
{
return NULL;
}
#endif
//
// IDebug helpers
//
STDAPI_(void) DbgDumpObject( IUnknown FAR * pUnk, DWORD dwReserved )
{
#ifdef _DEBUG
IDebugStream FAR * pcds = MakeDebugStream( DBGMARGIN, DBGTABSIZE, NOHEADER );
(void)dwReserved;
if( pcds ) {
*pcds << pUnk;
pcds->Return();
pcds->Release();
}
#else
(void) pUnk;
(void) dwReserved;
#endif
}
STDAPI_(void) DbgDumpExternalObject( IUnknown FAR * pUnk, DWORD dwReserved )
{
#ifdef _DEBUG
SHREG shreg;
(void) dwReserved;
if( IsValidInterface(pUnk) ){
if( RemLookupSHUnk(pUnk, NULL, &shreg) == NOERROR ){
DbgDumpObject(shreg.m_pSM, 0);
shreg.m_pSM->Release();
}
}
#else
(void) dwReserved;
(void) pUnk;
#endif
}
STDAPI_(BOOL) DbgIsObjectValid( IUnknown FAR * pUnk )
{
#ifdef _DEBUG
BOOL fReturn = TRUE; // default value for objects that don't
// support IDebug
IDebug FAR * pDebug = NULL;
if( IsValidInterface(pUnk) ){
pUnk->QueryInterface( IID_IDebug, (void FAR* FAR*)&pDebug);
if (pDebug)
fReturn = pDebug->IsValid();
//IDebug is not addref'd
return fReturn;
}
return FALSE;
#else
(void) pUnk;
return TRUE;
#endif
}
STDAPI_(void) DbgDumpClassName( IUnknown FAR * pUnk )
{
#ifdef _DEBUG
CLSID clsid;
IDebugStream FAR * pcds = MakeDebugStream( DBGMARGIN, DBGTABSIZE, NOHEADER );
if( pcds ) {
if( IsValidInterface(pUnk) ){
OleGetClassID( pUnk, (LPCLSID)&clsid);
*pcds << clsid << " @ " << (void FAR* )pUnk << '\n';
}else if (!pUnk)
*pcds << "NULL interface" << '\n';
else
*pcds << (void FAR *)pUnk << " is not a valid interface" << '\n';
pcds->Release();
}
#else
(void)pUnk;
#endif
}
STDAPI_(void) DumpAllObjects( void )
{
//#ifdef _DEBUG
#ifdef NEVER
IDebug FAR * pID = GetIDHead();
IDebugStream FAR * pcds = MakeDebugStream( DBGMARGIN, DBGTABSIZE, NOHEADER );
*pcds << "----TASK OBJECTS-------\n";
while (pID)
{
pID->Dump( pcds );
pID = pID->pIDNext;
}
*pcds << "----SHARED OBJECTS-------\n";
pID = pIDHeadShared;
while (pID)
{
pID->Dump( pcds );
pID = pID->pIDNext;
}
pcds->Release();
#endif
}
STDAPI_(BOOL) ValidateAllObjects( BOOL fSuspicious )
{
//#ifdef _DEBUG
#ifdef NEVER
IDebug FAR * pID = GetIDHead();
int pass = 0;
IDebugStream FAR * pcds = MakeDebugStream( DBGMARGIN, DBGTABSIZE, NOHEADER);
BOOL fReturn = TRUE;
while (pID)
{
if (!(pID->IsValid(fSuspicious)))
{
fReturn = FALSE;
if (pass == 0)
*pcds <<
"\n****INVALID OBJECT*****\n";
else
*pcds << "\n****INVALID SHARED MEMORY OBJECT*****\n";
pID->Dump( pcds );
pcds->Return();
}
pID = pID->pIDNext;
if ((pID == NULL) && (pass++ == 0))
pID = pIDHeadShared;
}
pcds->Release();
return fReturn;
#endif //NEVER
(void) fSuspicious;
return TRUE;
}
#ifdef _DEBUG
extern "C"
BOOL CALLBACK __loadds DebCallBack(WORD wID, DWORD dwData)
{
// char rgchBuf[50];
//// BOOL fTraceStack = FALSE;
//// STACKTRACEENTRY ste;
//// WORD wSS, wCS, wIP, wBP;
// NFYLOADSEG FAR* pNFY = (NFYLOADSEG FAR *)dwData;
//
// if (wID == NFY_LOADSEG)
// {
// if (0 == _fstrcmp(pNFY->lpstrModuleName,"OLE2"))
// {
// wsprintf(rgchBuf, "Load seg %02x(%#04x), module %s", pNFY->wSegNum,
// pNFY->wSelector, pNFY->lpstrModuleName);
// OutputDebugString(rgchBuf);
// _asm int 3
//// if (fTraceStack)
//// {
//// _asm mov wSS, SS
//// _asm mov wCS, CS
//// _asm mov wIP, IP
//// _asm mov wBP, BP
//// ste.dwSize = sizeof(STACKTRACEENTRY);
//// if (StackTraceCSIPFirst(&ste, wSS, wCS, wIP, wBP))
//// {
//// while (fTraceStack && StackTraceNext(&ste));
//// }
////
//// }
// }
// }
// else if (wID == NFY_FREESEG)
// {
// }
(void) wID;
(void) dwData;
return FALSE;
}
BOOL InstallHooks(void)
{
// return NotifyRegister(NULL, (LPFNNOTIFYCALLBACK)DebCallBack, NF_NORMAL);
return TRUE;
}
BOOL UnInstallHooks()
{
// return NotifyUnRegister(NULL);
return TRUE;
}
#endif