Indy
February 1st, 2011, 11:28
At the beginning of the exception is delivered to the debug port, then exception port(in KiDispatchException()).
Code:
BOOLEAN
DbgkForwardException(
IN PEXCEPTION_RECORD ExceptionRecord,
IN BOOLEAN DebugException,
IN BOOLEAN SecondChance
)
/*++
Routine Description:
This function is called forward an exception to the calling process's
debug or subsystem exception port.
Arguments:
ExceptionRecord - Supplies a pointer to an exception record.
DebugException - Supplies a boolean variable that specifies whether
this exception is to be forwarded to the process's
DebugPort(TRUE), or to its ExceptionPort(FALSE).
Return Value:
TRUE - The process has a DebugPort or an ExceptionPort, and the reply
received from the port indicated that the exception was handled.
FALSE - The process either does not have a DebugPort or
ExceptionPort, or the process has a port, but the reply received
from the port indicated that the exception was not handled.
--*/
{
PEPROCESS Process;
PVOID Port;
DBGKM_APIMSG m;
PDBGKM_EXCEPTION args;
NTSTATUS st;
BOOLEAN LpcPort;
PAGED_CODE();
args = &m.u.Exception;
//
// Initialize the debug LPC message with default information.
//
DBGKM_FORMAT_API_MSG(m,DbgKmExceptionApi,sizeof(*args));
//
// Get the address of the destination LPC port.
//
Process = PsGetCurrentProcess();
if (DebugException) {
if (PsGetCurrentThread()->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_HIDEFROMDBG) {
Port = NULL;
} else {
Port = Process->DebugPort;
}
LpcPort = FALSE;
} else {
Port = Process->ExceptionPort;
m.h.u2.ZeroInit = LPC_EXCEPTION;
LpcPort = TRUE;
}
//
// If the destination LPC port address is NULL, then return FALSE.
//
if (Port == NULL) {
return FALSE;
}
//
// Fill in the remainder of the debug LPC message.
//
args->ExceptionRecord = *ExceptionRecord;
args->FirstChance = !SecondChance;
//
// Send the debug message to the destination LPC port.
//
if (LpcPort) {
st = DbgkpSendApiMessageLpc(&m,Port,DebugException);
} else {
st = DbgkpSendApiMessage(&m,DebugException);
}
//
// If the send was not successful, then return a FALSE indicating that
// the port did not handle the exception. Otherwise, if the debug port
// is specified, then look at the return status in the message.
//
if (!NT_SUCCESS(st) ||
((DebugException) &&
(m.ReturnedStatus == DBG_EXCEPTION_NOT_HANDLED || !NT_SUCCESS(m.ReturnedStatus)))) {
return FALSE;
} else {
return TRUE;
}
}
This type of lpc-messages LPC_EXCEPTION. Port handle can be passed to NtCreateProcess. Maybe one time set using NtSetInformationProcess(class:ProcessExceptionPort). The port is set in the notification csrss(\ApiPort):
Code:
CsrCreateProcess:
...
/* Set the Exception port to us */
Status = NtSetInformationProcess(hProcess, ProcessExceptionPort, &CsrApiPort, sizeof(HANDLE));
http://doxygen.reactos.org/db/da3/subsystems_2csr_2csrsrv_2api_8c_source.html ("http://doxygen.reactos.org/db/da3/subsystems_2csr_2csrsrv_2api_8c_source.html")
http://doxygen.reactos.org/d1/d3c/subsystems_2csr_2csrsrv_2process_8c_source.html ("http://doxygen.reactos.org/d1/d3c/subsystems_2csr_2csrsrv_2process_8c_source.html")
Processing messages in CsrApiRequestThread() ^.