|
|
// Copyright (c) 1996-1999 Microsoft Corporation
/*
Implementation of Win95 tracing facility to mimic that of NT. Works on both. */
#pragma warning(disable:4201) // allows nameless structs and unions
#pragma warning(disable:4514) // don't care when unreferenced inline functions are removed
#pragma warning(disable:4706) // we are allowed to assign within a conditional
#include "windows.h"
#include <stdio.h>
#include <stdarg.h>
#include <process.h>
#include "w95trace.h"
// Uncomment the following line if you need debugging but can't use the mutex
//#define NOMUTEX
#if defined( _DEBUG ) ||defined( DEBUG ) || defined( DBG )
#ifdef __cplusplus
extern "C" { #endif
static HANDLE g_hSpewFile = INVALID_HANDLE_VALUE;
__inline BOOL TestMutex() { #ifndef NOMUTEX
HANDLE hTestMutex = OpenMutex( SYNCHRONIZE, FALSE, TEXT("oleacc-msaa-use-dbwin") ); if( ! hTestMutex ) return FALSE; CloseHandle( hTestMutex ); #endif
return TRUE; }
void OutputDebugStringW95( LPCTSTR lpOutputString, ...) { // Only produce output if this mutex is set...
if (TestMutex()) { HANDLE heventDBWIN; /* DBWIN32 synchronization object */ HANDLE heventData; /* data passing synch object */ HANDLE hSharedFile; /* memory mapped file shared data */ LPTSTR lpszSharedMem; TCHAR achBuffer[500]; int cch;
/* create the output buffer */ va_list args; va_start(args, lpOutputString); cch = wvsprintf(achBuffer, lpOutputString, args); va_end(args);
/*
Do a regular OutputDebugString so that the output is still seen in the debugger window if it exists.
This ifdef is necessary to avoid infinite recursion from the inclusion of W95TRACE.H */ #ifdef UNICODE
OutputDebugStringW(achBuffer); #else
::OutputDebugStringA(achBuffer); #endif
// Uncomment the following lines if you need DBPRINTF lines to go to a file
// (your code will have to open and close the file)
// if (g_hSpewFile && g_hSpewFile != INVALID_HANDLE_VALUE)
// {
// SpewToFile(achBuffer);
// }
/* bail if it's not Win95 */ { OSVERSIONINFO VerInfo; VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&VerInfo); if ( VerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS ) return; }
/* make sure DBWIN is open and waiting */ heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("DBWIN_BUFFER_READY")); if ( !heventDBWIN ) { //MessageBox(NULL, TEXT("DBWIN_BUFFER_READY nonexistent"), NULL, MB_OK);
return; }
/* get a handle to the data synch object */ heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("DBWIN_DATA_READY")); if ( !heventData ) { // MessageBox(NULL, TEXT("DBWIN_DATA_READY nonexistent"), NULL, MB_OK);
CloseHandle(heventDBWIN); return; } hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, TEXT("DBWIN_BUFFER")); if (!hSharedFile) { //MessageBox(NULL, TEXT("DebugTrace: Unable to create file mapping object DBWIN_BUFFER"), TEXT("Error"), MB_OK);
CloseHandle(heventDBWIN); CloseHandle(heventData); return; }
lpszSharedMem = (LPTSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512); if (!lpszSharedMem) { //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
CloseHandle(heventDBWIN); CloseHandle(heventData); return; }
/* wait for buffer event */ WaitForSingleObject(heventDBWIN, INFINITE);
/* write it to the shared memory */ *((LPDWORD)lpszSharedMem) = _getpid(); wsprintf(lpszSharedMem + sizeof(DWORD), TEXT("%s"), achBuffer);
/* signal data ready event */ SetEvent(heventData);
/* clean up handles */ CloseHandle(hSharedFile); CloseHandle(heventData); CloseHandle(heventDBWIN); } return; } void SpewOpenFile(LPCTSTR pszSpewFile) { #ifdef UNICODE // only works for unicode
// Only produce output if this mutex is set...
if (g_hSpewFile == INVALID_HANDLE_VALUE && TestMutex()) { TCHAR szSpewFile[MAX_PATH] = TEXT("C:\\"); #ifndef NOMUTEX
// if NOMUTEX is defined most likely you are debugging when
// there's no interactive user (so no temp path)
GetTempPath(MAX_PATH, szSpewFile); #endif
if (lstrlen(szSpewFile)+lstrlen(pszSpewFile) >= MAX_PATH) { MessageBox(NULL, TEXT("SpewOpenFile: Name will be longer than MAX_PATH"), TEXT("OOPS"), MB_OK); return; } lstrcat(szSpewFile, pszSpewFile); g_hSpewFile = CreateFile(szSpewFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == g_hSpewFile) { // MessageBox(NULL, TEXT("SpewOpenFile: Unable to open spew file"), TEXT("Error"), MB_OK);
} } #endif
} void SpewToFile( LPCTSTR lpOutputString, ...) { #ifdef UNICODE // only works for unicode
if (g_hSpewFile != INVALID_HANDLE_VALUE && TestMutex()) { TCHAR achBuffer[1025]; CHAR achAnsiBuf[500]; DWORD dwcBytesWr, dwcBytes; va_list args; va_start(args, lpOutputString); wvsprintf(achBuffer, lpOutputString, args); dwcBytes = WideCharToMultiByte(CP_ACP, 0, achBuffer, -1, achAnsiBuf, sizeof(achAnsiBuf)*sizeof(CHAR), NULL, NULL); if (!WriteFile(g_hSpewFile, achAnsiBuf, dwcBytes-1, &dwcBytesWr, NULL)) { // MessageBox(NULL, TEXT("SpewToFile: Unable to write to spew file"), TEXT("Error"), MB_OK);
} va_end(args); } #endif
} void SpewCloseFile() { #ifdef UNICODE // only works for unicode
if (g_hSpewFile != INVALID_HANDLE_VALUE && TestMutex()) CloseHandle(g_hSpewFile); #endif
} #ifdef __cplusplus
} #endif
#endif
|