197 lines
6.1 KiB
C
197 lines
6.1 KiB
C
// 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 |