windows-nt/Source/XPSP1/NT/printscan/print/spooler/dbglib/dbgcap.cxx
2020-09-26 16:20:57 +08:00

443 lines
8.2 KiB
C++

/*++
Copyright (c) 1998-1999 Microsoft Corporation
All rights reserved.
Module Name:
dbgcap.cxx
Abstract:
Debug capture class
Author:
Steve Kiraly (SteveKi) 18-Jun-1998
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "dbgback.hxx"
#include "dbgcap.hxx"
/*++
Title:
TDebugCapture_Create
Routine Description:
Creates a debug capture object, and returns the newly created
caputure device handle.
Arguments:
pszConfiguration - pointe to backtrace configuration string.
uOutputDevice - what device to send the backtrace to.
pszOutputDeviceConfiguration - pointer to output device configuration
string.
Return Value:
Non null handle if successfull, NULL on failure.
--*/
extern "C"
HANDLE
TDebugCapture_Create(
IN LPCTSTR pszCaptureDeviceConfiguration,
IN UINT uOutputDevice,
IN LPCTSTR pszOutputDeviceConfiguration
)
{
HANDLE hHandle = NULL;
//
// The output device cannot be another back trace device.
//
if (uOutputDevice != kDbgBackTrace)
{
//
// Get access to the debug factory.
//
TDebugFactory DebugFactory;
//
// If we failed to create the debug factory then exit.
//
if (DebugFactory.bValid())
{
TDebugDeviceBacktrace *pBackTrace = NULL;
//
// CAUTION: We are down casting, however, we know this is
// safe since the factory was told produce a product of a
// particular kind.
//
// Create the specified debug device using the factory.
//
pBackTrace = reinterpret_cast<TDebugDeviceBacktrace *>(DebugFactory.Produce(kDbgBackTrace,
pszCaptureDeviceConfiguration,
Globals.CompiledCharType));
//
// If the backtrace device was create successfully.
//
if (pBackTrace)
{
//
// Initialize the output device.
//
pBackTrace->InitializeOutputDevice(uOutputDevice,
pszOutputDeviceConfiguration,
Globals.CompiledCharType);
//
// Return a opaque handle.
//
hHandle = pBackTrace;
}
}
}
return hHandle;
}
/*++
Title:
TDebugCapture_Destroy
Routine Description:
Destroys the capture device.
Arguments:
hHandle - opaque handle to backtrace device.
Return Value:
NULL
--*/
extern "C"
HANDLE
TDebugCapture_Destroy(
IN HANDLE hHandle
)
{
TDebugFactory::Dispose(reinterpret_cast<TDebugDevice *>(hHandle));
return NULL;
}
/*++
Title:
TDebugCapture_Capture
Routine Description:
This routine output a format string to the pre configured
output device then captures a stack back, also sending the
output to the pre configured output device.
Arguments:
hHandle - handle to instance of capture device.
uFlags - must be 0 not defined.
pszFile - pointer to string where call was made.
uLine - line number in file where call was made.
pszCapture - pointer to post formated capture string.
Return Value:
Nothing.
--*/
extern "C"
VOID
TDebugCapture_Capture(
IN HANDLE hHandle,
IN UINT uFlags,
IN LPCTSTR pszFile,
IN UINT uLine,
IN LPTSTR pszCapture
)
{
TDebugString strCapture;
//
// Format the pre-capture string.
//
BOOL bRetval = strCapture.bFormat(_T("Capture: %s %d tc=%x tid=%x %s"),
StripPathFromFileName(pszFile),
uLine,
GetTickCount(),
GetCurrentThreadId(),
pszCapture ? pszCapture : kstrNull);
//
// If the capture string was formated.
//
if (bRetval)
{
//
// Hold the critical section while we capture the backtrace.
//
TDebugCriticalSection::TLock CS( GlobalCriticalSection );
TDebugDeviceBacktrace *pBackTrace = reinterpret_cast<TDebugDeviceBacktrace *>(hHandle);
LPBYTE pData = reinterpret_cast<LPBYTE>(const_cast<LPTSTR>(
static_cast<LPCTSTR>(strCapture)));
bRetval = pBackTrace->bOutput(strCapture.uLen() * sizeof(TCHAR), pData);
}
//
// Release the capture string, if the passed in one was valid.
//
INTERNAL_DELETE [] pszCapture;
}
/*++
Title:
TDebugCapture_pszFmt
Routine Description:
Creates a output string from a printf style format
string and argument list.
Arguments:
pszFmt - pointer to printf style format string.
... - variable number of arguments.
Return Value:
Pointer to output string, caller must free.
--*/
LPTSTR
TDebugCapture_pszFmt(
IN LPCSTR pszFmt,
IN ...
)
{
va_list pArgs;
va_start(pArgs, pszFmt);
LPTSTR pszString = TDebugCapture_pszFmt_Helper(pszFmt, pArgs, FALSE);
va_end(pArgs);
return pszString;
}
/*++
Title:
TDebugCapture_pszFmt
Routine Description:
Creates a output string from a printf style format
string and argument list.
Arguments:
pszFmt - pointer to printf style format string.
... - variable number of arguments.
Return Value:
Pointer to output string, caller must free.
--*/
LPTSTR
TDebugCapture_pszFmt(
IN LPCWSTR pszFmt,
IN ...
)
{
va_list pArgs;
va_start(pArgs, pszFmt);
LPTSTR pszString = TDebugCapture_pszFmt_Helper(pszFmt, pArgs, TRUE);
va_end(pArgs);
return pszString;
}
/*++
Title:
TDebugCapture_pszFmt
Routine Description:
Creates a output string from a printf style format
string and argument list.
Arguments:
pszFmt - pointer to printf style format string.
... - variable number of arguments.
Return Value:
Pointer to output string, caller must free.
--*/
extern "C"
LPTSTR
WINAPIV
TDebugCapture_pszFmtA(
IN LPCSTR pszFmt,
IN ...
)
{
va_list pArgs;
va_start(pArgs, pszFmt);
LPTSTR pszString = TDebugCapture_pszFmt_Helper(pszFmt, pArgs, FALSE);
va_end(pArgs);
return pszString;
}
/*++
Title:
TDebugCapture_pszFmt
Routine Description:
Creates a output string from a printf style format
string and argument list.
Arguments:
pszFmt - pointer to printf style format string.
... - variable number of arguments.
Return Value:
Pointer to output string, caller must free.
--*/
extern "C"
LPTSTR
WINAPIV
TDebugCapture_pszFmtW(
IN LPCWSTR pszFmt,
IN ...
)
{
va_list pArgs;
va_start(pArgs, pszFmt);
LPTSTR pszString = TDebugCapture_pszFmt_Helper(pszFmt, pArgs, TRUE);
va_end(pArgs);
return pszString;
}
/*++
Title:
TDebugCapture_pszFmt_Helper
Routine Description:
Creates a output string from a printf style format
string and pointer to argument list.
Arguments:
pszFmt - pointer to printf style format string.
pArgs - pointer to variable number of arguments.
bUnicode - Flag indicating the provided string is unicode or ansi.
Return Value:
Pointer to output string, caller must free.
--*/
LPTSTR
TDebugCapture_pszFmt_Helper(
IN const VOID *pszFmt,
IN va_list pArgs,
IN BOOL bUnicode
)
{
LPTSTR pString = NULL;
PVOID pszResult = NULL;
if (pszFmt)
{
if (bUnicode)
{
pszResult = vFormatW(reinterpret_cast<LPCWSTR>(pszFmt), pArgs);
}
else
{
pszResult = vFormatA(reinterpret_cast<LPCSTR>(pszFmt), pArgs);
}
if (pszResult)
{
if (bUnicode)
{
(VOID)StringW2T(&pString, reinterpret_cast<LPWSTR>(pszResult));
}
else
{
(VOID)StringA2T(&pString, reinterpret_cast<LPSTR>(pszResult));
}
INTERNAL_DELETE [] pszResult;
}
}
return pString;
}