Leaked source code of windows server 2003
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
23 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: OleAPIs.cxx (16 bit target)
  7. //
  8. // Contents: OLE2 APIs
  9. //
  10. // Functions:
  11. //
  12. // History: 17-Dec-93 Johann Posch (johannp) Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include <headers.cxx>
  16. #pragma hdrstop
  17. // cdebug.cpp - implemention of debugstream and IDebug interface/class
  18. /*
  19. #include <olerem.h> //for RemLookupSHUnk
  20. #pragma SEG(cdebug)
  21. #include <string.h>
  22. #include <toolhelp.h>
  23. */
  24. //some constants used only in this file
  25. #define DBGMARGIN 45
  26. #define DBGTABSIZE 4
  27. #define HEADER 1
  28. #define NOHEADER 0
  29. #define DBGLOGFILENAME "debug.log"
  30. static void GetCurDateTime(LPSTR lpsz);
  31. STDAPI_(HFILE) DbgLogOpen(LPSTR lpszFile, LPSTR lpszMode)
  32. {
  33. #ifdef _DEBUG
  34. #ifndef _MAC
  35. HFILE fh;
  36. AssertSz( lpszFile && lpszMode, "Invalid arguments to DbgLogOpen");
  37. switch (lpszMode[0]) {
  38. case 'w':
  39. // Open for writing (overwrite if exists)
  40. fh = _lcreat(lpszFile, 0);
  41. break;
  42. case 'r':
  43. // Open for reading
  44. fh = _lopen(lpszFile, OF_READ);
  45. break;
  46. case 'a':
  47. // Open for appending
  48. // to append to log file seek to end before writing
  49. if ((fh = _lopen(lpszFile, OF_READWRITE)) != -1) {
  50. _llseek(fh, 0L, SEEK_END);
  51. } else {
  52. // file does not exist, create a new one.
  53. fh = _lcreat(lpszFile, 0);
  54. }
  55. break;
  56. }
  57. return fh;
  58. #endif //_MAC
  59. #else
  60. (void) lpszFile;
  61. (void) lpszMode;
  62. return -1;
  63. #endif //_DEBUG
  64. }
  65. STDAPI_(void) DbgLogClose(HFILE fh)
  66. {
  67. #ifdef _DEBUG
  68. #ifndef _MAC
  69. if (fh != -1)
  70. _lclose(fh);
  71. #endif
  72. #else
  73. (void) fh;
  74. #endif
  75. }
  76. STDAPI_(void) DbgLogWrite(HFILE fh, LPSTR lpsz)
  77. {
  78. #ifdef _DEBUG
  79. #ifndef _MAC
  80. if (fh != -1 && lpsz)
  81. _lwrite(fh, lpsz, lstrlen(lpsz));
  82. #endif
  83. #else
  84. (void) fh;
  85. (void) lpsz;
  86. #endif
  87. }
  88. STDAPI_(void) DbgLogTimeStamp(HFILE fh, LPSTR lpsz)
  89. {
  90. #ifdef _DEBUG
  91. char buffer[80];
  92. GetCurDateTime(buffer);
  93. DbgLogOutputDebugString(fh, "\n***************************************\n");
  94. if (lpsz) DbgLogOutputDebugString(fh, lpsz);
  95. DbgLogOutputDebugString(fh, ": ");
  96. DbgLogOutputDebugString(fh, buffer);
  97. DbgLogOutputDebugString(fh, "\n");
  98. DbgLogOutputDebugString(fh, ".......................................\n\n");
  99. #else
  100. (void) fh;
  101. (void) lpsz;
  102. #endif
  103. }
  104. STDAPI_(void) DbgLogWriteBanner(HFILE fh, LPSTR lpsz)
  105. {
  106. #ifdef _DEBUG
  107. DbgLogOutputDebugString(fh, "\n***************************************\n");
  108. if (lpsz) DbgLogOutputDebugString(fh, lpsz);
  109. DbgLogOutputDebugString(fh, "\n");
  110. DbgLogOutputDebugString(fh, ".......................................\n\n");
  111. #else
  112. (void) fh;
  113. (void) lpsz;
  114. #endif
  115. }
  116. STDAPI_(void) DbgLogOutputDebugString(HFILE fh, LPSTR lpsz)
  117. {
  118. #ifdef _DEBUG
  119. #ifndef _MAC
  120. if (fh != -1)
  121. DbgLogWrite(fh, lpsz);
  122. OutputDebugString(lpsz);
  123. #endif
  124. #else
  125. (void)fh;
  126. (void)lpsz;
  127. #endif
  128. }
  129. #ifdef _DEBUG
  130. static void GetCurDateTime(LPSTR lpsz)
  131. {
  132. unsigned year, month, day, dayOfweek, hours, min, sec;
  133. static char FAR* dayNames[7] =
  134. { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  135. static char FAR* monthNames[12] =
  136. { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  137. #ifndef _MAC
  138. #ifdef WIN32
  139. SYSTEMTIME st;
  140. GetLocalTime(&st);
  141. year = st.wYear;
  142. month = st.wMonth - 1;
  143. dayOfweek = st.wDayOfWeek;
  144. day = st.wDay;
  145. hours = st.wHour;
  146. min = st.wMinute;
  147. sec = st.wSecond;
  148. #else
  149. _asm {
  150. // Call GetDate
  151. mov ah, 0x2a
  152. int 0x21
  153. mov year, cx
  154. mov month, dx
  155. mov day, dx
  156. mov dayOfweek, ax
  157. // Call GetTime
  158. mov ah, 0x2c
  159. int 0x21
  160. mov hours, cx
  161. mov min, cx
  162. mov sec, dx
  163. }
  164. month >>= 8;
  165. month -= 1;
  166. day &= 0xFF;
  167. dayOfweek &= 0xFF;
  168. hours >>= 8;
  169. min &= 0xFF;
  170. sec >>= 8;
  171. #endif //_WIN32
  172. #else // defined(_MAC)
  173. // REVIEW MAC -- need function here to get current date & time
  174. day = 9;
  175. month = 1;
  176. year = 1960;
  177. hours = 12;
  178. min = 30;
  179. sec = 17;
  180. #endif //_MAC
  181. // Format time as: Wed Jan 02 02:03:55 1990
  182. // Format time as: Wed 05/02/1992 02:03:55
  183. wsprintf(lpsz, "%s %s %02d %02d:%02d:%02d %d",
  184. dayNames[dayOfweek],monthNames[month], day, hours, min, sec, year);
  185. }
  186. class FAR CDebugLog
  187. {
  188. private:
  189. HFILE m_fhLog;
  190. public:
  191. CDebugLog( ) { m_fhLog = -1; }
  192. CDebugLog( LPSTR lpszFileName );
  193. ~CDebugLog() { DbgLogClose(m_fhLog); }
  194. HFILE Open(LPSTR lpszFileName, LPSTR lpszMode)
  195. { return (m_fhLog = DbgLogOpen(lpszFileName, lpszMode)); }
  196. void Close(void) { DbgLogClose(m_fhLog); m_fhLog = -1; }
  197. void OutputDebugString(LPSTR lpsz) { DbgLogOutputDebugString(m_fhLog, lpsz); }
  198. void TimeStamp(LPSTR lpsz) { DbgLogTimeStamp(m_fhLog, lpsz); }
  199. void WriteBanner(LPSTR lpsz) { DbgLogWriteBanner(m_fhLog, lpsz); }
  200. };
  201. #if 0
  202. class FAR CDebugStream
  203. {
  204. public:
  205. OLESTATIC_(IDebugStream FAR *) Create( // no aggregation
  206. int margin, int tabsize, BOOL fHeader);
  207. private:
  208. CDebugStream( int margin, int tabsize, BOOL fHeader );
  209. ~CDebugStream();
  210. void OutputDebugString( LPSTR lpsz ) {m_DbgLog.OutputDebugString(lpsz);}
  211. implementations:
  212. implement CDSImpl : IDebugStream
  213. {
  214. public:
  215. CDSImpl( CDebugStream FAR * pDebugStream )
  216. { m_pDebugStream = pDebugStream; }
  217. ~CDSImpl( void ) ; //{ if (m_pDebugStream->m_pendingReturn) ForceReturn(); }
  218. void PrintString( LPSTR );
  219. void ForceReturn( void );
  220. void ReturnIfPending( void );
  221. OLEMETHOD(QueryInterface)(REFIID iid, LPVOID FAR* ppvObj );
  222. OLEMETHOD_(ULONG,AddRef)( void );
  223. OLEMETHOD_(ULONG,Release)( void );
  224. OLEMETHOD_(IDebugStream&, operator << ) ( IUnknown FAR * pDebug );
  225. OLEMETHOD_(IDebugStream&, operator << ) ( REFCLSID rclsid );
  226. OLEMETHOD_(IDebugStream&, operator << ) ( int n );
  227. OLEMETHOD_(IDebugStream&, operator << ) ( long l );
  228. OLEMETHOD_(IDebugStream&, operator << ) ( ULONG l );
  229. OLEMETHOD_(IDebugStream&, operator << ) ( LPSTR sz );
  230. OLEMETHOD_(IDebugStream&, operator << ) ( char ch );
  231. OLEMETHOD_(IDebugStream&, operator << ) ( void FAR * pv );
  232. OLEMETHOD_(IDebugStream&, operator << ) ( CBool b );
  233. OLEMETHOD_(IDebugStream&, operator << ) ( CAtom atom );
  234. OLEMETHOD_(IDebugStream&, operator << ) ( CHwnd hwnd );
  235. OLEMETHOD_(IDebugStream&, Tab) ( void );
  236. OLEMETHOD_(IDebugStream&, Indent) ( void );
  237. OLEMETHOD_(IDebugStream&, UnIndent) ( void );
  238. OLEMETHOD_(IDebugStream&, Return) ( void );
  239. OLEMETHOD_(IDebugStream&, LF) ( void );
  240. CDebugStream FAR * m_pDebugStream;
  241. };
  242. DECLARE_NC(CDebugStream,CDSImpl)
  243. CDSImpl m_DebugStream;
  244. shared_state:
  245. ULONG m_refs;
  246. int m_indent;
  247. int m_position;
  248. int m_margin;
  249. int m_tabsize;
  250. BOOL m_pendingReturn;
  251. CDebugLog m_DbgLog;
  252. };
  253. #endif
  254. #endif // _DEBUG
  255. /*
  256. * The member variable m_pendingReturn is a hack to allow
  257. * the sequence of operations Return, UnIndent put the character
  258. * at the *beginning of the unindented line* The debugwindow does
  259. * not seem to support going to the beginning of the line or
  260. * backspacing, so we do not actually do a Return until we know
  261. * that the next operation is not UnIndent.
  262. *
  263. */
  264. /*
  265. * Implementation of per process list heads
  266. */
  267. #ifdef NEVER // per-proces debug lists not used
  268. static IDebug FAR * GetIDHead()
  269. {
  270. if this gets enabled, the map should be in the etask
  271. }
  272. static void SetIDHead(IDebug FAR* pIDHead)
  273. {
  274. if this gets enabled, the map should be in the etask
  275. }
  276. #endif // NEVER
  277. /*
  278. * Implementation of IDebug constructor and destructor
  279. */
  280. #ifdef NEVER
  281. __export IDebug::IDebug( void )
  282. {
  283. SETPVTBL(IDebug);
  284. //#ifdef _DEBUG
  285. BOOL fIsShared = (SHARED == PlacementOf(this));
  286. IDebug FAR* pIDHead = (fIsShared ? pIDHeadShared : GetIDHead());
  287. pIDPrev = NULL;
  288. if (pIDHead)
  289. pIDHead->pIDPrev = this;
  290. pIDNext = pIDHead;
  291. if (fIsShared) pIDHeadShared = this;
  292. else SetIDHead(this);
  293. }
  294. #endif //NEVER
  295. #ifdef NEVER
  296. __export IDebug::~IDebug( void )
  297. {
  298. //#ifdef _DEBUG
  299. BOOL fIsShared = (SHARED == PlacementOf(this));
  300. if (pIDPrev)
  301. pIDPrev->pIDNext = pIDNext;
  302. else
  303. if (fIsShared) pIDHeadShared = pIDNext;
  304. else
  305. SetIDHead(pIDNext);
  306. if (pIDNext)
  307. pIDNext->pIDPrev = pIDPrev;
  308. }
  309. #endif //NEVER
  310. //REVIEW: maybe we should expose this later
  311. STDAPI OleGetClassID( LPUNKNOWN pUnk, LPCLSID lpclsid )
  312. {
  313. HRESULT hresult = NOERROR;
  314. #if 0
  315. LPRUNNABLEOBJECT lpRunnableObject = NULL;
  316. LPPERSIST lpPersist = NULL;
  317. VDATEIFACE(pUnk);
  318. VDATEPTROUT(lpclsid, LPCLSID);
  319. *lpclsid = CLSID_NULL;
  320. pUnk->QueryInterface(IID_IRunnableObject, (LPLPVOID)&lpRunnableObject);
  321. if( lpRunnableObject ){
  322. hresult = lpRunnableObject->GetRunningClass(lpclsid);
  323. lpRunnableObject->Release();
  324. } else {
  325. pUnk->QueryInterface(IID_IPersist, (LPLPVOID)&lpPersist);
  326. if( lpPersist ){
  327. hresult = lpPersist->GetClassID( lpclsid );
  328. lpPersist->Release();
  329. }
  330. }
  331. #endif
  332. return hresult;
  333. }
  334. #ifdef _DEBUG
  335. CDebugStream::CDebugStream( int margin, int tabsize, BOOL fHeader) : m_DebugStream(this)
  336. {
  337. #ifndef _MAC
  338. static BOOL fAppendFile = FALSE;
  339. // Create the debug log file. Overwrite the existing file if it exists.
  340. m_DbgLog.Open(DBGLOGFILENAME, (fAppendFile ? "a" : "w"));
  341. if( fHeader )
  342. // only add creation timestamp to top of file.
  343. if (! fAppendFile) {
  344. m_DbgLog.TimeStamp("Created");
  345. fAppendFile = TRUE;
  346. } else {
  347. m_DbgLog.WriteBanner(NULL);
  348. }
  349. #endif
  350. m_indent = 0;
  351. m_position = m_indent;
  352. m_margin = margin;
  353. m_tabsize = tabsize;
  354. m_refs = 1;
  355. m_pendingReturn = FALSE;
  356. }
  357. CDebugStream::~CDebugStream()
  358. {
  359. m_DbgLog.Close();
  360. }
  361. NC(CDebugStream,CDSImpl)::~CDSImpl(void)
  362. {
  363. if (m_pDebugStream->m_pendingReturn) ForceReturn();
  364. }
  365. OLEMETHODIMP NC(CDebugStream,CDSImpl)::QueryInterface(REFIID iidInterface,
  366. void FAR* FAR* ppvObj )
  367. {
  368. VDATEPTROUT(ppvObj, LPLPVOID);
  369. if (iidInterface == IID_IUnknown || iidInterface == IID_IDebugStream) {
  370. *ppvObj = (void FAR *)this;
  371. return NOERROR;
  372. } else {
  373. *ppvObj = NULL;
  374. return ReportResult(0, E_NOINTERFACE, 0, 0);
  375. }
  376. }
  377. OLEMETHODIMP_(ULONG) NC(CDebugStream,CDSImpl)::AddRef( void )
  378. {
  379. return ++m_pDebugStream->m_refs;
  380. }
  381. OLEMETHODIMP_(ULONG) NC(CDebugStream,CDSImpl)::Release( void )
  382. {
  383. if (--m_pDebugStream->m_refs == 0) {
  384. delete m_pDebugStream;
  385. return 0;
  386. }
  387. return m_pDebugStream->m_refs;
  388. }
  389. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (int n)
  390. {
  391. char buffer[12];
  392. ReturnIfPending();
  393. buffer[wsprintf(buffer, "%d", n)] = '\0';
  394. PrintString(buffer);
  395. return *this;
  396. }
  397. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (long l)
  398. {
  399. char buffer[16];
  400. ReturnIfPending();
  401. buffer[wsprintf(buffer, "%ld", l)] = '\0';
  402. PrintString(buffer);
  403. return *this;
  404. }
  405. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (ULONG l)
  406. {
  407. char buffer[16];
  408. ReturnIfPending();
  409. buffer[wsprintf(buffer, "%lu", l)] = '\0';
  410. PrintString(buffer);
  411. return *this;
  412. }
  413. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (CAtom atom)
  414. {
  415. char buffer[128];
  416. ReturnIfPending();
  417. if( (ATOM)atom ){
  418. if( !GetAtomName((ATOM)atom, (LPSTR)buffer, sizeof(buffer)) )
  419. buffer[wsprintf(buffer, "Invalid atom")] = '\0';
  420. }else
  421. buffer[wsprintf(buffer, "NULL atom")] = '\0';
  422. PrintString(buffer);
  423. return *this;
  424. }
  425. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (CHwnd hwnd)
  426. {
  427. char szBuf[128];
  428. ReturnIfPending();
  429. if( (HWND)hwnd )
  430. szBuf[wsprintf(szBuf, "window handle: %x", (HWND)hwnd)] = '\0';
  431. else
  432. szBuf[wsprintf(szBuf, "NULL window handle")] = '\0';
  433. PrintString(szBuf);
  434. return *this;
  435. }
  436. LPSTR FindBreak( LPSTR sz, int currentPosition, int margin )
  437. {
  438. LPSTR szBreak = sz;
  439. LPSTR szPtr = sz;
  440. if( !sz )
  441. return NULL;
  442. while (*szPtr)
  443. {
  444. while (*(szPtr) && *(szPtr++) <= ' ');
  445. while (*(szPtr) && *(szPtr++) > ' ');
  446. if (currentPosition+(szPtr-sz) < margin)
  447. {
  448. szBreak = szPtr;
  449. }
  450. else return szBreak;
  451. }
  452. return szPtr;
  453. }
  454. /*
  455. * PrintString is an internal utility routine that can assume that
  456. * everything in the string (other than the null at the end) is >=
  457. * ' '. Thus it knows that when it prints a single character, the
  458. * position on the debug terminal advances a single columm. This
  459. * would not be the case if the string could contain tabs,
  460. * returns, etc.
  461. */
  462. void NC(CDebugStream,CDSImpl)::PrintString (LPSTR sz)
  463. {
  464. // assert sz != NULL
  465. LPSTR szUnprinted = sz;
  466. LPSTR szPtr = sz;
  467. char chSave;
  468. #ifdef _MAC
  469. Puts(sz);
  470. return;
  471. #endif
  472. if( !sz )
  473. return;
  474. while (*szUnprinted)
  475. {
  476. szPtr = FindBreak( szUnprinted, m_pDebugStream->m_position, m_pDebugStream->m_margin );
  477. if (szPtr == szUnprinted && m_pDebugStream->m_position > m_pDebugStream->m_indent)
  478. {
  479. Return();
  480. szPtr = FindBreak( szUnprinted, m_pDebugStream->m_position, m_pDebugStream->m_margin );
  481. if (szPtr == szUnprinted) // text won't fit even after word wrapping
  482. {
  483. m_pDebugStream->OutputDebugString(szUnprinted);
  484. m_pDebugStream->m_position += _fstrlen(szUnprinted);
  485. return;
  486. }
  487. }
  488. chSave = *szPtr;
  489. *szPtr = '\0';
  490. if (m_pDebugStream->m_position == m_pDebugStream->m_indent) // no text on line, skip blanks
  491. {
  492. while (*szUnprinted == ' ') szUnprinted++;
  493. }
  494. m_pDebugStream->OutputDebugString(szUnprinted);
  495. *szPtr = chSave;
  496. m_pDebugStream->m_position += (szPtr - szUnprinted);
  497. szUnprinted = szPtr;
  498. }
  499. }
  500. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (char ch)
  501. {
  502. char buffer[2] = "a";
  503. if (ch=='\n') Return();
  504. else if (ch=='\t') Tab();
  505. else if (ch >= ' ')
  506. {
  507. ReturnIfPending();
  508. if (m_pDebugStream->m_position >= m_pDebugStream->m_margin) Return();
  509. *buffer = ch;
  510. m_pDebugStream->OutputDebugString(buffer);
  511. m_pDebugStream->m_position++;
  512. }
  513. return *this;
  514. }
  515. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (LPSTR sz)
  516. {
  517. LPSTR szCopy;
  518. char chSave;
  519. LPSTR szPtr;
  520. LPSTR szPtrSave;
  521. ReturnIfPending();
  522. if (!sz)
  523. return *this;
  524. szCopy = new FAR (TASK) char[2+_fstrlen(sz)];
  525. if (!szCopy)
  526. {
  527. Return();
  528. PrintString("Memory allocation error in DebugStream");
  529. Return();
  530. return *this;
  531. }
  532. _fstrcpy( szCopy, sz );
  533. for (szPtr = szCopy, szPtrSave = szCopy; *szPtr; szPtr++)
  534. {
  535. if ( *szPtr < ' ') // we hit a control character or the end
  536. {
  537. chSave = *szPtr;
  538. *szPtr = '\0';
  539. PrintString( szPtrSave );
  540. if (chSave != '\0')
  541. *szPtr = chSave;
  542. szPtrSave = szPtr+1;
  543. switch (chSave)
  544. {
  545. case '\t': Tab();
  546. break;
  547. case '\n': Return();
  548. break;
  549. case '\r': m_pDebugStream->OutputDebugString("\r");
  550. break;
  551. default:
  552. break;
  553. }
  554. }
  555. }
  556. PrintString( szPtrSave );
  557. delete szCopy;
  558. return *this;
  559. }
  560. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << (CBool b)
  561. {
  562. ReturnIfPending();
  563. if (b) PrintString("TRUE");
  564. else PrintString("FALSE");
  565. return *this;
  566. }
  567. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator << ( void FAR * pv )
  568. {
  569. char buffer[12];
  570. LPSTR sz = "NULL";
  571. ReturnIfPending();
  572. if (pv != NULL)
  573. {
  574. buffer[wsprintf(buffer, "%lX", pv)] = '\0';
  575. sz = buffer;
  576. }
  577. PrintString(sz);
  578. return *this;
  579. }
  580. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator <<
  581. ( REFCLSID rclsid )
  582. {
  583. char sz[256];
  584. // REVIEW: do lookup in reg.dat for user type name
  585. if( rclsid == CLSID_NULL )
  586. _fstrcpy(sz, "NULL CLSID");
  587. else if (StringFromCLSID2(rclsid, sz, sizeof(sz)) == 0)
  588. _fstrcpy(sz, "Unknown CLSID");
  589. *this << sz;
  590. return *this;
  591. }
  592. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::operator <<
  593. ( IUnknown FAR * pUnk )
  594. {
  595. IDebug FAR * pDebug = NULL;
  596. CLSID clsid = CLSID_NULL;
  597. ReturnIfPending();
  598. if( IsValidInterface(pUnk) ){
  599. pUnk->QueryInterface(IID_IDebug, (void FAR* FAR*)&pDebug);
  600. if (pDebug) {
  601. pDebug->Dump( this );
  602. if ( !pDebug->IsValid( 0 ) )
  603. *this << "Object is not valid" << '\n';
  604. /*
  605. * NB: Debug interfaces are *not* ref counted (so as not to skew the
  606. * counts of the objects they are debugging! :)
  607. */
  608. } else {
  609. OleGetClassID(pUnk, (LPCLSID)&clsid);
  610. *this << clsid << " @ "<<(VOID FAR *)pUnk << " doesn't support debug dumping";
  611. }
  612. } else if (!pUnk)
  613. *this << "NULL interface";
  614. else
  615. *this << "Invalid interface @ " << (VOID FAR *)pUnk;
  616. return *this;
  617. }
  618. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::Tab( void )
  619. {
  620. ReturnIfPending();
  621. int advance = m_pDebugStream->m_tabsize * ( 1 + m_pDebugStream->m_position/m_pDebugStream->m_tabsize) - m_pDebugStream->m_position;
  622. if (m_pDebugStream->m_position + advance < m_pDebugStream->m_margin)
  623. {
  624. for (int i = 0; i < advance; i++)
  625. m_pDebugStream->OutputDebugString(" ");
  626. m_pDebugStream->m_position += advance;
  627. }
  628. return *this;
  629. }
  630. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::Indent( void )
  631. {
  632. if (m_pDebugStream->m_indent + m_pDebugStream->m_tabsize < m_pDebugStream->m_margin)
  633. m_pDebugStream->m_indent += m_pDebugStream->m_tabsize;
  634. if (!m_pDebugStream->m_pendingReturn)
  635. while (m_pDebugStream->m_position < m_pDebugStream->m_indent)
  636. operator<<(' ');
  637. return *this;
  638. }
  639. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::UnIndent( void )
  640. {
  641. if (m_pDebugStream->m_indent > 0) m_pDebugStream->m_indent -= m_pDebugStream->m_tabsize;
  642. return *this;
  643. }
  644. void NC(CDebugStream,CDSImpl)::ForceReturn( void )
  645. {
  646. m_pDebugStream->OutputDebugString("\n");
  647. for (int i = 0; i<m_pDebugStream->m_indent; i++)
  648. m_pDebugStream->OutputDebugString(" ");
  649. m_pDebugStream->m_position = m_pDebugStream->m_indent;
  650. m_pDebugStream->m_pendingReturn = FALSE;
  651. }
  652. void NC(CDebugStream,CDSImpl)::ReturnIfPending( void )
  653. {
  654. if (m_pDebugStream->m_pendingReturn) ForceReturn();
  655. }
  656. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::Return( void )
  657. {
  658. ReturnIfPending();
  659. m_pDebugStream->m_pendingReturn = TRUE;
  660. Yield(); // let dbwin get control
  661. return *this;
  662. }
  663. OLEMETHODIMP_(IDebugStream&) NC(CDebugStream,CDSImpl)::LF( void )
  664. {
  665. return Return();
  666. }
  667. OLESTATICIMP_(IDebugStream FAR *) CDebugStream::Create( // no aggregation
  668. int margin, int tabsize, BOOL fHeader )
  669. {
  670. CDebugStream FAR * pcds = new FAR (TASK)CDebugStream( margin, tabsize, fHeader );
  671. if( !pcds ){
  672. AssertSz( pcds, "Out of Memory");
  673. return NULL;
  674. }
  675. return &(pcds->m_DebugStream);
  676. }
  677. #endif // _DEBUG
  678. #if 0
  679. STDAPI_(IDebugStream FAR *) MakeDebugStream( short margin, short tabsize, BOOL fHeader)
  680. {
  681. #ifdef _DEBUG
  682. return CDebugStream::Create( margin, tabsize, fHeader );
  683. #else
  684. (void) margin;
  685. (void) tabsize;
  686. (void) fHeader;
  687. return NULL;
  688. #endif // _DEBUG
  689. }
  690. #else
  691. STDAPI_(void FAR *) MakeDebugStream( short margin, short tabsize, BOOL fHeader)
  692. {
  693. return NULL;
  694. }
  695. #endif
  696. //
  697. // IDebug helpers
  698. //
  699. STDAPI_(void) DbgDumpObject( IUnknown FAR * pUnk, DWORD dwReserved )
  700. {
  701. #ifdef _DEBUG
  702. IDebugStream FAR * pcds = MakeDebugStream( DBGMARGIN, DBGTABSIZE, NOHEADER );
  703. (void)dwReserved;
  704. if( pcds ) {
  705. *pcds << pUnk;
  706. pcds->Return();
  707. pcds->Release();
  708. }
  709. #else
  710. (void) pUnk;
  711. (void) dwReserved;
  712. #endif
  713. }
  714. STDAPI_(void) DbgDumpExternalObject( IUnknown FAR * pUnk, DWORD dwReserved )
  715. {
  716. #ifdef _DEBUG
  717. SHREG shreg;
  718. (void) dwReserved;
  719. if( IsValidInterface(pUnk) ){
  720. if( RemLookupSHUnk(pUnk, NULL, &shreg) == NOERROR ){
  721. DbgDumpObject(shreg.m_pSM, 0);
  722. shreg.m_pSM->Release();
  723. }
  724. }
  725. #else
  726. (void) dwReserved;
  727. (void) pUnk;
  728. #endif
  729. }
  730. STDAPI_(BOOL) DbgIsObjectValid( IUnknown FAR * pUnk )
  731. {
  732. #ifdef _DEBUG
  733. BOOL fReturn = TRUE; // default value for objects that don't
  734. // support IDebug
  735. IDebug FAR * pDebug = NULL;
  736. if( IsValidInterface(pUnk) ){
  737. pUnk->QueryInterface( IID_IDebug, (void FAR* FAR*)&pDebug);
  738. if (pDebug)
  739. fReturn = pDebug->IsValid();
  740. //IDebug is not addref'd
  741. return fReturn;
  742. }
  743. return FALSE;
  744. #else
  745. (void) pUnk;
  746. return TRUE;
  747. #endif
  748. }
  749. STDAPI_(void) DbgDumpClassName( IUnknown FAR * pUnk )
  750. {
  751. #ifdef _DEBUG
  752. CLSID clsid;
  753. IDebugStream FAR * pcds = MakeDebugStream( DBGMARGIN, DBGTABSIZE, NOHEADER );
  754. if( pcds ) {
  755. if( IsValidInterface(pUnk) ){
  756. OleGetClassID( pUnk, (LPCLSID)&clsid);
  757. *pcds << clsid << " @ " << (void FAR* )pUnk << '\n';
  758. }else if (!pUnk)
  759. *pcds << "NULL interface" << '\n';
  760. else
  761. *pcds << (void FAR *)pUnk << " is not a valid interface" << '\n';
  762. pcds->Release();
  763. }
  764. #else
  765. (void)pUnk;
  766. #endif
  767. }
  768. STDAPI_(void) DumpAllObjects( void )
  769. {
  770. //#ifdef _DEBUG
  771. #ifdef NEVER
  772. IDebug FAR * pID = GetIDHead();
  773. IDebugStream FAR * pcds = MakeDebugStream( DBGMARGIN, DBGTABSIZE, NOHEADER );
  774. *pcds << "----TASK OBJECTS-------\n";
  775. while (pID)
  776. {
  777. pID->Dump( pcds );
  778. pID = pID->pIDNext;
  779. }
  780. *pcds << "----SHARED OBJECTS-------\n";
  781. pID = pIDHeadShared;
  782. while (pID)
  783. {
  784. pID->Dump( pcds );
  785. pID = pID->pIDNext;
  786. }
  787. pcds->Release();
  788. #endif
  789. }
  790. STDAPI_(BOOL) ValidateAllObjects( BOOL fSuspicious )
  791. {
  792. //#ifdef _DEBUG
  793. #ifdef NEVER
  794. IDebug FAR * pID = GetIDHead();
  795. int pass = 0;
  796. IDebugStream FAR * pcds = MakeDebugStream( DBGMARGIN, DBGTABSIZE, NOHEADER);
  797. BOOL fReturn = TRUE;
  798. while (pID)
  799. {
  800. if (!(pID->IsValid(fSuspicious)))
  801. {
  802. fReturn = FALSE;
  803. if (pass == 0)
  804. *pcds <<
  805. "\n****INVALID OBJECT*****\n";
  806. else
  807. *pcds << "\n****INVALID SHARED MEMORY OBJECT*****\n";
  808. pID->Dump( pcds );
  809. pcds->Return();
  810. }
  811. pID = pID->pIDNext;
  812. if ((pID == NULL) && (pass++ == 0))
  813. pID = pIDHeadShared;
  814. }
  815. pcds->Release();
  816. return fReturn;
  817. #endif //NEVER
  818. (void) fSuspicious;
  819. return TRUE;
  820. }
  821. #ifdef _DEBUG
  822. extern "C"
  823. BOOL CALLBACK __loadds DebCallBack(WORD wID, DWORD dwData)
  824. {
  825. // char rgchBuf[50];
  826. //// BOOL fTraceStack = FALSE;
  827. //// STACKTRACEENTRY ste;
  828. //// WORD wSS, wCS, wIP, wBP;
  829. // NFYLOADSEG FAR* pNFY = (NFYLOADSEG FAR *)dwData;
  830. //
  831. // if (wID == NFY_LOADSEG)
  832. // {
  833. // if (0 == _fstrcmp(pNFY->lpstrModuleName,"OLE2"))
  834. // {
  835. // wsprintf(rgchBuf, "Load seg %02x(%#04x), module %s", pNFY->wSegNum,
  836. // pNFY->wSelector, pNFY->lpstrModuleName);
  837. // OutputDebugString(rgchBuf);
  838. // _asm int 3
  839. //// if (fTraceStack)
  840. //// {
  841. //// _asm mov wSS, SS
  842. //// _asm mov wCS, CS
  843. //// _asm mov wIP, IP
  844. //// _asm mov wBP, BP
  845. //// ste.dwSize = sizeof(STACKTRACEENTRY);
  846. //// if (StackTraceCSIPFirst(&ste, wSS, wCS, wIP, wBP))
  847. //// {
  848. //// while (fTraceStack && StackTraceNext(&ste));
  849. //// }
  850. ////
  851. //// }
  852. // }
  853. // }
  854. // else if (wID == NFY_FREESEG)
  855. // {
  856. // }
  857. (void) wID;
  858. (void) dwData;
  859. return FALSE;
  860. }
  861. BOOL InstallHooks(void)
  862. {
  863. // return NotifyRegister(NULL, (LPFNNOTIFYCALLBACK)DebCallBack, NF_NORMAL);
  864. return TRUE;
  865. }
  866. BOOL UnInstallHooks()
  867. {
  868. // return NotifyUnRegister(NULL);
  869. return TRUE;
  870. }
  871. #endif