811 lines
18 KiB
C
811 lines
18 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1989 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
dllssstb.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Debug Subsystem DbgSs API Stubs
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Mark Lucovsky (markl) 22-Jan-1990
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "dbgdllp.h"
|
||
|
#include "ldrp.h"
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSspConnectToDbg( VOID )
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine makes a connection between the caller and the
|
||
|
DbgSs port in the Dbg subsystem.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TBD.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
NTSTATUS st;
|
||
|
UNICODE_STRING PortName;
|
||
|
SECURITY_QUALITY_OF_SERVICE DynamicQos;
|
||
|
|
||
|
//
|
||
|
// Set up the security quality of service parameters to use over the
|
||
|
// port. Use the most efficient (least overhead) - which is dynamic
|
||
|
// rather than static tracking.
|
||
|
//
|
||
|
|
||
|
DynamicQos.ImpersonationLevel = SecurityImpersonation;
|
||
|
DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
||
|
DynamicQos.EffectiveOnly = TRUE;
|
||
|
|
||
|
|
||
|
RtlInitUnicodeString(&PortName,L"\\DbgSsApiPort");
|
||
|
st = NtConnectPort(
|
||
|
&DbgSspApiPort,
|
||
|
&PortName,
|
||
|
&DynamicQos,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0L
|
||
|
);
|
||
|
|
||
|
return st;
|
||
|
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSspException (
|
||
|
IN PDBGSS_CONTINUE_KEY ContinueKey,
|
||
|
IN PCLIENT_ID AppClientId,
|
||
|
IN PDBGKM_EXCEPTION Exception
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is called by emulation subsystems to report that
|
||
|
an exception occured in a thread.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ContinueKey - Supplies the captured DbgKm API message that needs a reply
|
||
|
should this API complete successfully.
|
||
|
|
||
|
AppClientId - Supplies the address of the ClientId of the thread that
|
||
|
encountered an exception.
|
||
|
|
||
|
Exception - Supplies the address of the Exception message as sent
|
||
|
through the applications DebugPort.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TBD
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
NTSTATUS st;
|
||
|
DBGSS_APIMSG ApiMsg;
|
||
|
|
||
|
PDBGKM_EXCEPTION args;
|
||
|
|
||
|
args = &ApiMsg.u.Exception;
|
||
|
|
||
|
DBGSS_FORMAT_API_MSG(ApiMsg,DbgSsExceptionApi,sizeof(*args),AppClientId,ContinueKey);
|
||
|
|
||
|
*args = *Exception;
|
||
|
|
||
|
st = NtRequestPort(DbgSspApiPort, (PPORT_MESSAGE) &ApiMsg);
|
||
|
|
||
|
return st;
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSspCreateThread (
|
||
|
IN PDBGSS_CONTINUE_KEY ContinueKey,
|
||
|
IN PCLIENT_ID AppClientId,
|
||
|
IN PDBGKM_CREATE_THREAD NewThread
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is called by emulation subsystems to report the
|
||
|
creation of a new thread to the Dbg subsystem.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ContinueKey - Supplies the captured DbgKm API message that needs a reply
|
||
|
should this API complete successfully.
|
||
|
|
||
|
AppClientId - Supplies the address of the new thread's ClientId.
|
||
|
|
||
|
NewThread - Supplies the address of the NewThread message as sent through
|
||
|
the applications DebugPort. The calling subsystem may modify the
|
||
|
SubSystemKey field of this message.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TBD
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
NTSTATUS st;
|
||
|
DBGSS_APIMSG ApiMsg;
|
||
|
|
||
|
PDBGKM_CREATE_THREAD args;
|
||
|
|
||
|
args = &ApiMsg.u.CreateThread;
|
||
|
|
||
|
DBGSS_FORMAT_API_MSG(ApiMsg,DbgSsCreateThreadApi,sizeof(*args),AppClientId, ContinueKey);
|
||
|
|
||
|
*args = *NewThread;
|
||
|
|
||
|
st = NtRequestPort(DbgSspApiPort, (PPORT_MESSAGE) &ApiMsg);
|
||
|
|
||
|
return st;
|
||
|
}
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSspCreateProcess (
|
||
|
IN PDBGSS_CONTINUE_KEY ContinueKey,
|
||
|
IN PCLIENT_ID AppClientId,
|
||
|
IN PCLIENT_ID DebugUiClientId,
|
||
|
IN PDBGKM_CREATE_PROCESS NewProcess
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is called by emulation subsystems to report the
|
||
|
creation of a new process to the Dbg subsystem. It is the
|
||
|
responsibility of individual subsystems to track a process and its
|
||
|
controlling DebugUi.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ContinueKey - Supplies the captured DbgKm API message that needs a reply
|
||
|
should this API complete successfully.
|
||
|
|
||
|
AppClientId - Supplies the address of the new thread's ClientId.
|
||
|
|
||
|
DebugUiClientId - Supplies the address of the ClientId of the user
|
||
|
interface controlling the new thread.
|
||
|
|
||
|
NewProcess - Supplies the address of the NewProcess message as sent through
|
||
|
the applications DebugPort. The calling subsystem may modify the
|
||
|
SubSystemKey fields of this message.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TBD
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
NTSTATUS st;
|
||
|
DBGSS_APIMSG ApiMsg;
|
||
|
|
||
|
PDBGSS_CREATE_PROCESS args;
|
||
|
|
||
|
args = &ApiMsg.u.CreateProcessInfo;
|
||
|
|
||
|
DBGSS_FORMAT_API_MSG(ApiMsg,DbgSsCreateProcessApi,sizeof(*args),AppClientId,ContinueKey);
|
||
|
|
||
|
args->DebugUiClientId = *DebugUiClientId;
|
||
|
args->NewProcess = *NewProcess;
|
||
|
|
||
|
st = NtRequestPort(DbgSspApiPort, (PPORT_MESSAGE) &ApiMsg);
|
||
|
|
||
|
return st;
|
||
|
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSspExitThread (
|
||
|
IN PDBGSS_CONTINUE_KEY ContinueKey,
|
||
|
IN PCLIENT_ID AppClientId,
|
||
|
IN PDBGKM_EXIT_THREAD ExitThread
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is called by emulation subsystems to report that
|
||
|
a thread is exiting.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ContinueKey - Supplies the captured DbgKm API message that needs a reply
|
||
|
should this API complete successfully.
|
||
|
|
||
|
AppClientId - Supplies the address of the exiting thread's ClientId.
|
||
|
|
||
|
ExitThread - Supplies the address of the ExitThread message as sent
|
||
|
through the applications DebugPort.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TBD
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
NTSTATUS st;
|
||
|
DBGSS_APIMSG ApiMsg;
|
||
|
|
||
|
PDBGKM_EXIT_THREAD args;
|
||
|
|
||
|
args = &ApiMsg.u.ExitThread;
|
||
|
|
||
|
DBGSS_FORMAT_API_MSG(ApiMsg,DbgSsExitThreadApi,sizeof(*args),AppClientId,ContinueKey);
|
||
|
|
||
|
*args = *ExitThread;
|
||
|
|
||
|
st = NtRequestPort(DbgSspApiPort, (PPORT_MESSAGE) &ApiMsg);
|
||
|
|
||
|
return st;
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSspExitProcess (
|
||
|
IN PDBGSS_CONTINUE_KEY ContinueKey,
|
||
|
IN PCLIENT_ID AppClientId,
|
||
|
IN PDBGKM_EXIT_PROCESS ExitProcess
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is called by emulation subsystems to report that
|
||
|
a process is exiting.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ContinueKey - Supplies the captured DbgKm API message that needs a reply
|
||
|
should this API complete successfully.
|
||
|
|
||
|
AppClientId - Supplies the address of the ClientId of the last thread
|
||
|
in the process to exit.
|
||
|
|
||
|
ExitProcess - Supplies the address of the ExitProcess message as sent
|
||
|
through the applications DebugPort.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TBD
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
NTSTATUS st;
|
||
|
DBGSS_APIMSG ApiMsg;
|
||
|
|
||
|
PDBGKM_EXIT_PROCESS args;
|
||
|
|
||
|
args = &ApiMsg.u.ExitProcess;
|
||
|
|
||
|
DBGSS_FORMAT_API_MSG(ApiMsg,DbgSsExitProcessApi,sizeof(*args),AppClientId,ContinueKey);
|
||
|
|
||
|
*args = *ExitProcess;
|
||
|
|
||
|
st = NtRequestPort(DbgSspApiPort, (PPORT_MESSAGE) &ApiMsg);
|
||
|
|
||
|
return st;
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSspLoadDll (
|
||
|
IN PDBGSS_CONTINUE_KEY ContinueKey,
|
||
|
IN PCLIENT_ID AppClientId,
|
||
|
IN PDBGKM_LOAD_DLL LoadDll
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is called by emulation subsystems to report that
|
||
|
a a process has loaded a DLL
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ContinueKey - Supplies the captured DbgKm API message that needs a reply
|
||
|
should this API complete successfully.
|
||
|
|
||
|
AppClientId - Supplies the address of the ClientId of the thread
|
||
|
that mapped the section.
|
||
|
|
||
|
LoadDll - Supplies the address of the LoadDll message as sent
|
||
|
through the applications DebugPort.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TBD
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
NTSTATUS st;
|
||
|
DBGSS_APIMSG ApiMsg;
|
||
|
|
||
|
PDBGKM_LOAD_DLL args;
|
||
|
|
||
|
args = &ApiMsg.u.LoadDll;
|
||
|
|
||
|
DBGSS_FORMAT_API_MSG(ApiMsg,DbgSsLoadDllApi,sizeof(*args),AppClientId,ContinueKey);
|
||
|
|
||
|
*args = *LoadDll;
|
||
|
|
||
|
st = NtRequestPort(DbgSspApiPort, (PPORT_MESSAGE) &ApiMsg);
|
||
|
|
||
|
return st;
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSspUnloadDll (
|
||
|
IN PDBGSS_CONTINUE_KEY ContinueKey,
|
||
|
IN PCLIENT_ID AppClientId,
|
||
|
IN PDBGKM_UNLOAD_DLL UnloadDll
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is called by emulation subsystems to report that
|
||
|
a a process has un-mapped a view of a section
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ContinueKey - Supplies the captured DbgKm API message that needs a reply
|
||
|
should this API complete successfully.
|
||
|
|
||
|
AppClientId - Supplies the address of the ClientId of the thread
|
||
|
that mapped the section.
|
||
|
|
||
|
UnloadDll - Supplies the address of the UnloadDll message as sent
|
||
|
through the applications DebugPort.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TBD
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
NTSTATUS st;
|
||
|
DBGSS_APIMSG ApiMsg;
|
||
|
|
||
|
PDBGKM_UNLOAD_DLL args;
|
||
|
|
||
|
args = &ApiMsg.u.UnloadDll;
|
||
|
|
||
|
DBGSS_FORMAT_API_MSG(ApiMsg,DbgSsUnloadDllApi,sizeof(*args),AppClientId,ContinueKey);
|
||
|
|
||
|
*args = *UnloadDll;
|
||
|
|
||
|
st = NtRequestPort(DbgSspApiPort, (PPORT_MESSAGE) &ApiMsg);
|
||
|
|
||
|
return st;
|
||
|
}
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSsInitialize(
|
||
|
IN HANDLE KmReplyPort,
|
||
|
IN PDBGSS_UI_LOOKUP UiLookUpRoutine,
|
||
|
IN PDBGSS_SUBSYSTEMKEY_LOOKUP SubsystemKeyLookupRoutine OPTIONAL,
|
||
|
IN PDBGSS_DBGKM_APIMSG_FILTER KmApiMsgFilter OPTIONAL
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is called by a subsystem to initialize
|
||
|
portions of the debug subsystem dll. The main purpose of
|
||
|
this function is to set up callouts that are needed in order
|
||
|
to use DbgSsHandleKmApiMsg, and to connect to the debug server.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
KmReplyPort - Supplies a handle to the port that the subsystem
|
||
|
receives DbgKm API messages on.
|
||
|
|
||
|
UiLookupRoutine - Supplies the address of a function that will
|
||
|
be called upon receipt of a process creation message. The
|
||
|
purpose of this function is to identify the client id of the
|
||
|
debug ui controlling the process.
|
||
|
|
||
|
SubsystemKeyLookupRoutine - Supplies the address of a function that
|
||
|
will be called upon receipt of process creation and thread
|
||
|
creation messages. The purpose of this function is to allow a
|
||
|
subsystem to correlate a key value with a given process or
|
||
|
thread.
|
||
|
|
||
|
KmApiMsgFilter - Supplies the address of a function that will be
|
||
|
called upon receipt of a DbgKm Api message. This function can
|
||
|
take any action. If it returns any value other than DBG_CONTINUE,
|
||
|
DbgSsHandleKmApiMsg will not process the message. This function
|
||
|
is called before any other call outs occur.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Return code of DbgSsConnectToDbg.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
NTSTATUS st;
|
||
|
|
||
|
st = DbgSspConnectToDbg();
|
||
|
|
||
|
if (NT_SUCCESS(st)) {
|
||
|
DbgSspKmReplyPort = KmReplyPort;
|
||
|
DbgSspUiLookUpRoutine = UiLookUpRoutine;
|
||
|
DbgSspSubsystemKeyLookupRoutine = SubsystemKeyLookupRoutine;
|
||
|
DbgSspKmApiMsgFilter = KmApiMsgFilter;
|
||
|
|
||
|
st = RtlCreateUserThread(
|
||
|
NtCurrentProcess(),
|
||
|
NULL,
|
||
|
FALSE,
|
||
|
0L,
|
||
|
0L,
|
||
|
0L,
|
||
|
DbgSspSrvApiLoop,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
ASSERT( NT_SUCCESS(st) );
|
||
|
}
|
||
|
|
||
|
return st;
|
||
|
}
|
||
|
|
||
|
|
||
|
#if DBG
|
||
|
PSZ DbgpKmApiName[ DbgKmMaxApiNumber+1 ] = {
|
||
|
"DbgKmException",
|
||
|
"DbgKmCreateThread",
|
||
|
"DbgKmCreateProcess",
|
||
|
"DbgKmExitThread",
|
||
|
"DbgKmExitProcess",
|
||
|
"DbgKmLoadDll",
|
||
|
"DbgKmUnloadDll",
|
||
|
"Unknown DbgKm Api Number"
|
||
|
};
|
||
|
#endif // DBG
|
||
|
|
||
|
VOID
|
||
|
DbgSsHandleKmApiMsg(
|
||
|
IN PDBGKM_APIMSG ApiMsg,
|
||
|
IN HANDLE ReplyEvent OPTIONAL
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is called by a subsystem upon receipt of a message whose
|
||
|
type is LPC_DEBUG_EVENT. The purpose of this function is to propagate
|
||
|
the debug event message to the debug server.
|
||
|
|
||
|
A number of callouts are performed prior to propagating the message:
|
||
|
|
||
|
- For all messages, the KmApiMsgFilter is called (if it was
|
||
|
supplied during DbgSsInitialize. If this returns anything other
|
||
|
that DBG_CONTINUE, the message is not propagated by this
|
||
|
function. The caller is responsible for event propagation, and
|
||
|
for replying to the thread reporting the debug event.
|
||
|
|
||
|
- For create process messages, the UiLookupRoutine is called. If
|
||
|
a success code is returned than message is propagated.
|
||
|
Otherwise, a reply is generated to the thread reporting the
|
||
|
debug event.
|
||
|
|
||
|
- For create process and create thread messages,
|
||
|
SubsystemKeyLookupRoutine is called. Failure does not effect
|
||
|
propagation. It simply inhibits the update of messages
|
||
|
SubSystemKey field.
|
||
|
|
||
|
Based on the debug event type, a DBGSS_APIMSG is formated and sent
|
||
|
as a datagram to the debug server.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ApiMsg - Supplies the debug event message to propagate to the debug
|
||
|
server.
|
||
|
|
||
|
ReplyEvent - An optional parameter, that if specified supplies a handle
|
||
|
to an event that is to be signaled rather that generating a reply
|
||
|
to this message.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
{
|
||
|
NTSTATUS st;
|
||
|
CLIENT_ID DebugUiClientId;
|
||
|
ULONG SubsystemKey;
|
||
|
PDBGSS_CONTINUE_KEY ContinueKey;
|
||
|
|
||
|
ApiMsg->ReturnedStatus = STATUS_PENDING;
|
||
|
|
||
|
#if DBG && 0
|
||
|
if (ApiMsg->ApiNumber >= DbgKmMaxApiNumber ) {
|
||
|
ApiMsg->ApiNumber = DbgKmMaxApiNumber;
|
||
|
}
|
||
|
DbgPrint( "DBG: %s Api Request received from %lx.%lx\n",
|
||
|
DbgpKmApiName[ ApiMsg->ApiNumber ],
|
||
|
ApiMsg->h.ClientId.UniqueProcess,
|
||
|
ApiMsg->h.ClientId.UniqueThread
|
||
|
);
|
||
|
#endif // DBG
|
||
|
|
||
|
if (DbgSspKmApiMsgFilter) {
|
||
|
if ( (DbgSspKmApiMsgFilter)(ApiMsg) != DBG_CONTINUE ) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ContinueKey = (PDBGSS_CONTINUE_KEY) RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( DBG_TAG ), sizeof(*ContinueKey));
|
||
|
if ( !ContinueKey ) {
|
||
|
ApiMsg->ReturnedStatus = STATUS_NO_MEMORY;
|
||
|
if ( ARGUMENT_PRESENT(ReplyEvent) ) {
|
||
|
st = NtSetEvent(ReplyEvent,NULL);
|
||
|
} else {
|
||
|
st = NtReplyPort(DbgSspKmReplyPort,
|
||
|
(PPORT_MESSAGE)ApiMsg
|
||
|
);
|
||
|
}
|
||
|
ASSERT(NT_SUCCESS(st));
|
||
|
return;
|
||
|
}
|
||
|
ContinueKey->KmApiMsg = *ApiMsg;
|
||
|
|
||
|
ContinueKey->ReplyEvent = ReplyEvent;
|
||
|
|
||
|
switch (ApiMsg->ApiNumber) {
|
||
|
|
||
|
case DbgKmExceptionApi :
|
||
|
st = DbgSspException(
|
||
|
ContinueKey,
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&ApiMsg->u.Exception
|
||
|
);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case DbgKmCreateThreadApi :
|
||
|
|
||
|
if ( DbgSspSubsystemKeyLookupRoutine ) {
|
||
|
|
||
|
st = (DbgSspSubsystemKeyLookupRoutine)(
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&SubsystemKey,
|
||
|
FALSE
|
||
|
);
|
||
|
|
||
|
if ( NT_SUCCESS(st) ) {
|
||
|
ApiMsg->u.CreateThread.SubSystemKey = SubsystemKey;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
st = DbgSspCreateThread(
|
||
|
ContinueKey,
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&ApiMsg->u.CreateThread
|
||
|
);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case DbgKmCreateProcessApi :
|
||
|
|
||
|
st = (DbgSspUiLookUpRoutine)(
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&DebugUiClientId
|
||
|
);
|
||
|
if ( !NT_SUCCESS(st) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( DbgSspSubsystemKeyLookupRoutine ) {
|
||
|
|
||
|
st = (DbgSspSubsystemKeyLookupRoutine)(
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&SubsystemKey,
|
||
|
TRUE
|
||
|
);
|
||
|
|
||
|
if ( NT_SUCCESS(st) ) {
|
||
|
ApiMsg->u.CreateProcessInfo.SubSystemKey = SubsystemKey;
|
||
|
}
|
||
|
|
||
|
st = (DbgSspSubsystemKeyLookupRoutine)(
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&SubsystemKey,
|
||
|
FALSE
|
||
|
);
|
||
|
|
||
|
if ( NT_SUCCESS(st) ) {
|
||
|
ApiMsg->u.CreateProcessInfo.InitialThread.SubSystemKey = SubsystemKey;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
st = DbgSspCreateProcess(
|
||
|
ContinueKey,
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&DebugUiClientId,
|
||
|
&ApiMsg->u.CreateProcessInfo
|
||
|
);
|
||
|
break;
|
||
|
|
||
|
|
||
|
case DbgKmExitThreadApi :
|
||
|
st = DbgSspExitThread(
|
||
|
ContinueKey,
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&ApiMsg->u.ExitThread
|
||
|
);
|
||
|
break;
|
||
|
|
||
|
case DbgKmExitProcessApi :
|
||
|
st = DbgSspExitProcess(
|
||
|
ContinueKey,
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&ApiMsg->u.ExitProcess
|
||
|
);
|
||
|
break;
|
||
|
|
||
|
case DbgKmLoadDllApi :
|
||
|
st = DbgSspLoadDll(
|
||
|
ContinueKey,
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&ApiMsg->u.LoadDll
|
||
|
);
|
||
|
break;
|
||
|
|
||
|
case DbgKmUnloadDllApi :
|
||
|
st = DbgSspUnloadDll(
|
||
|
ContinueKey,
|
||
|
&ApiMsg->h.ClientId,
|
||
|
&ApiMsg->u.UnloadDll
|
||
|
);
|
||
|
break;
|
||
|
|
||
|
default :
|
||
|
st = STATUS_NOT_IMPLEMENTED;
|
||
|
}
|
||
|
|
||
|
if ( !NT_SUCCESS(st) ) {
|
||
|
ApiMsg->ReturnedStatus = st;
|
||
|
RtlFreeHeap(RtlProcessHeap(), 0, ContinueKey);
|
||
|
if ( ARGUMENT_PRESENT(ReplyEvent) ) {
|
||
|
st = NtSetEvent(ReplyEvent,NULL);
|
||
|
} else {
|
||
|
st = NtReplyPort(DbgSspKmReplyPort,
|
||
|
(PPORT_MESSAGE)ApiMsg
|
||
|
);
|
||
|
}
|
||
|
ASSERT(NT_SUCCESS(st));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
DbgSspSrvApiLoop(
|
||
|
IN PVOID ThreadParameter
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This loop services Dbg Subsystem server originated messages.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ThreadParameter - Not used.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
DBGSRV_APIMSG DbgSrvApiMsg;
|
||
|
PDBGSS_CONTINUE_KEY ContinueKey;
|
||
|
NTSTATUS st;
|
||
|
|
||
|
for(;;) {
|
||
|
|
||
|
st = NtReplyWaitReceivePort(
|
||
|
DbgSspApiPort,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
(PPORT_MESSAGE) &DbgSrvApiMsg
|
||
|
);
|
||
|
|
||
|
if (!NT_SUCCESS( st )) {
|
||
|
DbgPrint( "DBGSS: NtReplyWaitReceivePort failed - Status == %x\n", st );
|
||
|
DbgBreakPoint();
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
ASSERT(DbgSrvApiMsg.ApiNumber < DbgSrvMaxApiNumber);
|
||
|
|
||
|
switch (DbgSrvApiMsg.ApiNumber ) {
|
||
|
case DbgSrvContinueApi :
|
||
|
|
||
|
//
|
||
|
// Might want to implement continue status based callout
|
||
|
// like DBG_TERMINATE_PROCESS/THREAD
|
||
|
//
|
||
|
|
||
|
ContinueKey = (PDBGSS_CONTINUE_KEY) DbgSrvApiMsg.ContinueKey;
|
||
|
ContinueKey->KmApiMsg.ReturnedStatus = DbgSrvApiMsg.ReturnedStatus;
|
||
|
|
||
|
if ( ContinueKey->ReplyEvent ) {
|
||
|
st = NtSetEvent(ContinueKey->ReplyEvent,NULL);
|
||
|
} else {
|
||
|
st = NtReplyPort(DbgSspKmReplyPort,
|
||
|
(PPORT_MESSAGE) &ContinueKey->KmApiMsg
|
||
|
);
|
||
|
}
|
||
|
|
||
|
RtlFreeHeap(RtlProcessHeap(), 0, ContinueKey);
|
||
|
break;
|
||
|
default :
|
||
|
ASSERT(FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Make the compiler happy
|
||
|
//
|
||
|
|
||
|
return st;
|
||
|
}
|