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.
 
 
 
 
 
 

330 lines
6.8 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
output.cpp
Abstract:
This file contains routines and classes
to handle output.
Author:
Jason Hartman (JasonHa) 2000-10-16
Environment:
User Mode
--*/
#include <stdio.h>
#include <dbgeng.h>
#include "debug.h"
#include "output.h"
#define HISTORY_LENGTH 2048
typedef struct {
PDEBUG_CLIENT MonitorClient; // To be set by created thread
PDEBUG_CLIENT Client;
ULONG OutputMask;
} MonitorThreadParams;
DWORD WINAPI OutputMonitorThread(MonitorThreadParams *);
HRESULT
OutputMonitor::Monitor(
PDEBUG_CLIENT ClientToMonitor,
ULONG OutputMask
)
{
Client = ClientToMonitor;
if (Client == NULL) return S_FALSE;
Client->AddRef();
MonitorThreadParams NewThreadParams = { NULL, Client, OutputMask };
HANDLE hThread;
DWORD ThreadID = 0;
hThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)OutputMonitorThread,
&NewThreadParams,
0,
&ThreadID);
if (hThread)
{
while (NewThreadParams.MonitorClient == NULL)
{
DWORD ExitCode = 0;
if (!GetExitCodeThread(hThread, &ExitCode))
DbgPrint("GetExitCodeThread returned error %lx.\n", GetLastError());
if (ExitCode != STILL_ACTIVE)
{
ThreadID = 0;
break;
}
SleepEx(10, TRUE);
}
CloseHandle(hThread);
}
MonitorClient = NewThreadParams.MonitorClient;
return (MonitorClient != NULL) ? S_OK : S_FALSE;
}
HRESULT
OutputMonitor::GetOutputMask(
PULONG OutputMask
)
{
HRESULT hr = S_FALSE;
if (Client != NULL &&
MonitorClient != NULL)
{
hr = Client->GetOtherOutputMask(MonitorClient, OutputMask);
}
return hr;
}
HRESULT
OutputMonitor::SetOutputMask(
ULONG OutputMask
)
{
HRESULT hr = S_FALSE;
if (Client != NULL &&
MonitorClient != NULL)
{
hr = Client->SetOtherOutputMask(MonitorClient, OutputMask);
}
return hr;
}
OutputMonitor::~OutputMonitor()
{
if (Client)
{
if (MonitorClient)
{
Client->ExitDispatch(MonitorClient);
}
Client->Release();
}
}
DWORD
WINAPI
OutputMonitorThread(
MonitorThreadParams *Params
)
{
HRESULT hr = S_FALSE;
PDEBUG_CLIENT MonitorClient;
PrintOutputCallbacks PrintCallbacks;
if (Params != NULL &&
Params->Client != NULL &&
(hr = Params->Client->CreateClient(&MonitorClient)) == S_OK)
{
if ((hr = MonitorClient->SetOutputMask(Params->OutputMask |
DEBUG_OUTPUT_PROMPT |
DEBUG_OUTPUT_PROMPT_REGISTERS |
DEBUG_OUTPUT_DEBUGGEE |
DEBUG_OUTPUT_DEBUGGEE_PROMPT
)) == S_OK &&
(hr = MonitorClient->SetOutputCallbacks(&PrintCallbacks)) == S_OK)
{
if ((hr = MonitorClient->ConnectSession(DEBUG_CONNECT_SESSION_NO_ANNOUNCE, HISTORY_LENGTH)) != S_OK)
{
printf("Couldn't get debugger version/history: HRESULT 0x%lx\n", hr);
}
MonitorClient->SetOutputMask(Params->OutputMask);
Params->MonitorClient = MonitorClient;
hr = MonitorClient->DispatchCallbacks(INFINITE);
}
else
{
printf("Output callbacks setup failed, HRESULT: 0x%lx\n", hr);
}
MonitorClient->Release();
}
DbgPrint("OutputMonitorThread calling ExitThread().\n");
ExitThread((DWORD)hr);
}
//----------------------------------------------------------------------------
//
// Default output callbacks implementation, provides IUnknown for
// static classes.
//
//----------------------------------------------------------------------------
STDMETHODIMP
PrintOutputCallbacks::QueryInterface(
THIS_
IN REFIID InterfaceId,
OUT PVOID* Interface
)
{
*Interface = NULL;
if (//(InterfaceId == IID_IUnknown) ||
(InterfaceId == __uuidof(IDebugOutputCallbacks)))
{
*Interface = (IDebugOutputCallbacks *)this;
AddRef();
return S_OK;
}
else
{
return E_NOINTERFACE;
}
}
STDMETHODIMP_(ULONG)
PrintOutputCallbacks::AddRef(
THIS
)
{
// This class is designed to be static so
// there's no true refcount.
return 1;
}
STDMETHODIMP_(ULONG)
PrintOutputCallbacks::Release(
THIS
)
{
// This class is designed to be static so
// there's no true refcount.
return 0;
}
STDMETHODIMP
PrintOutputCallbacks::Output(
THIS_
IN ULONG Mask,
IN PCSTR Text
)
{
printf("%s", Text);
return S_OK;
}
#if 0
// Stuff we probably don't need
OutputMonitor::OutputMonitor(
PDEBUG_CLIENT DbgClient
)
{
Client = DbgClient;
if (Client != NULL)
{
Client->AddRef();
}
Saved = FALSE;
}
HRESULT
OutputMonitor::Setup(
ULONG OutMask,
PDEBUG_OUTPUT_CALLBACKS OutCallbacks
)
{
HRESULT Hr = S_FALSE;
ULONG LastOutMask;
PDEBUG_CLIENT f;
if (Client == NULL)
{
return Hr;
}
if (!Saved)
{
if ((Hr = Client->GetOutputMask(&OrgOutMask)) != S_OK ||
(Hr = Client->GetOutputCallbacks(&OrgOutCallbacks)) != S_OK)
{
return Hr;
}
Saved = TRUE;
}
if ((Hr = Client->GetOutputMask(&LastOutMask)) == S_OK &&
(Hr = Client->SetOutputMask(OutMask)) == S_OK)
{
if ((Hr = Client->SetOutputCallbacks(OutCallbacks)) != S_OK)
{
Client->SetOutputMask(LastOutMask);
}
}
return Hr;
}
HRESULT
OutputMonitor::Execute(
PCSTR pszCommand
)
{
HRESULT hr = S_FALSE;
PDEBUG_CONTROL DbgControl;
if (Client != NULL &&
(hr = Client->QueryInterface(__uuidof(IDebugControl),
(void **)&DbgControl)) == S_OK)
{
hr = DbgControl->Execute(DEBUG_OUTCTL_THIS_CLIENT |
DEBUG_OUTCTL_OVERRIDE_MASK,
pszCommand,
DEBUG_EXECUTE_NO_REPEAT);
DbgControl->Release();
}
return hr;
}
#endif