Figure 13: UnHandledExceptionFilter Pseudocode

UnhandledExceptionFilter( STRUCT _EXCEPTION_POINTERS *pExceptionPtrs )
{
    PEXCEPTION_RECORD pExcptRec;
    DWORD currentESP;
    DWORD retValue;
    DWORD DEBUGPORT;
    DWORD   dwTemp2;
    DWORD   dwUseJustInTimeDebugger;
    CHAR    szDbgCmdFmt[256];   // Template string retrieved from AeDebug key
    CHAR    szDbgCmdLine[256];  // Actual debugger string after filling in
    STARTUPINFO startupinfo;
    PROCESS_INFORMATION pi;
    HARDERR_STRUCT  harderr;    // ???
    BOOL fAeDebugAuto;
    TIB * pTib;		 // Thread information block

    pExcptRec = pExceptionPtrs->ExceptionRecord;

    if (   (pExcptRec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
	&& (pExcptRec->ExceptionInformation[0]) )
    {
	retValue = 
	    _BasepCheckForReadOnlyResource(pExcptRec->ExceptionInformation[1]);

	if ( EXCEPTION_CONTINUE_EXECUTION == retValue )
	    return EXCEPTION_CONTINUE_EXECUTION;
     }

    // See if this process is being run under a debugger...
    retValue = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
					 &debugPort, sizeof(debugPort), 0 );

    if ( (retValue >= 0) && debugPort )     // Let debugger have it
	return EXCEPTION_CONTINUE_SEARCH;

    // Did the user call SetUnhandledExceptionFilter?  If so, call their
    // installed proc now.

    if ( _BasepCurrentTopLevelFilter )
    {
	retValue = _BasepCurrentTopLevelFilter( pExceptionPtrs );

	if ( EXCEPTION_EXECUTE_HANDLER == retValue )
	    return EXCEPTION_EXECUTE_HANDLER;
	
	if ( EXCEPTION_CONTINUE_EXECUTION == retValue )
	    return EXCEPTION_CONTINUE_EXECUTION;

	// Only EXCEPTION_CONTINUE_SEARCH goes on from here
    }

    // Has SetErrorMode(SEM_NOGPFAULTERRORBOX) been called?
    if ( 0 == (GetErrorMode() & SEM_NOGPFAULTERRORBOX) )
    {
	harderr.elem0 = pExcptRec->ExceptionCode;
	harderr.elem1 = pExcptRec->ExceptionAddress;

	if ( EXCEPTION_IN_PAGE_ERROR == pExcptRec->ExceptionCode )
	    harderr.elem2 = pExcptRec->ExceptionInformation[2];
	else
	    harderr.elem2 = pExcptRec->ExceptionInformation[0];

	dwTemp2 = 1;
	fAeDebugAuto = FALSE;

	harderr.elem3 = pExcptRec->ExceptionInformation[1];

	pTib = FS:[18h];

	DWORD someVal = pTib->pProcess->0xC;

	if ( pTib->threadID != someVal )
	{
	    __try
			{
		char szDbgCmdFmt[256]
		retValue = _GetProfileStringA( "AeDebug", "Debugger", 0,
				     szDbgCmdFmt, sizeof(szDbgCmdFmt)-1 );

		if ( retValue )
		    dwTemp2 = 2;

		char szAuto[8]

		retValue = GetProfileStringA(   "AeDebug", "Auto", "0",
						szAuto, sizeof(szAuto)-1 );
		if ( retValue )
		    if ( 0 == strcmp( szAuto, "1" ) )
			if ( 2 == dwTemp2 )
			    fAeDebugAuto = TRUE;
	    }
	    __except( EXCEPTION_EXECUTE_HANDLER )
	    {
		ESP = currentESP;
		dwTemp2 = 1
		fAeDebugAuto = FALSE;
	    }
	}

	if ( FALSE == fAeDebugAuto )
	{
	    retValue =  NtRaiseHardError(
				STATUS_UNHANDLED_EXCEPTION | 0x10000000,
				4, 0, &harderr,
				_BasepAlreadyHadHardError ? 1 : dwTemp2,
				&dwUseJustInTimeDebugger );
	}
	else
	{
	    dwUseJustInTimeDebugger = 3;
	    retValue = 0;
	}

	if (    retValue >= 0 
	    &&  ( dwUseJustInTimeDebugger == 3)
	    &&  ( !_BasepAlreadyHadHardError )
	    &&  ( !_BaseRunningInServerProcess ) )
	{
	    _BasepAlreadyHadHardError = 1;

	    SECURITY_ATTRIBUTES secAttr = { sizeof(secAttr), 0, TRUE };

	    HANDLE hEvent = CreateEventA( &secAttr, TRUE, 0, 0 );

	    memset( &startupinfo, 0, sizeof(startupinfo) );

	    sprintf(szDbgCmdLine, szDbgCmdFmt, GetCurrentProcessId(), hEvent);

	    startupinfo.cb = sizeof(startupinfo);
	    startupinfo.lpDesktop = "Winsta0\Default"

	    CsrIdentifyAlertableThread();   // ???

	    retValue = CreateProcessA(
			    0,	      // lpApplicationName
			    szDbgCmdLine,   // Command line
			    0, 0,	   // process, thread security attrs
			    1,	      // bInheritHandles
			    0, 0,	   // creation flags, environment
			    0,	      // current directory.
			    &statupinfo,    // STARTUPINFO
			    &pi );	  // PROCESS_INFORMATION

	    if ( retValue && hEvent )
	    {
		NtWaitForSingleObject( hEvent, 1, 0 );
		return EXCEPTION_CONTINUE_SEARCH;
	    }
	}

	if ( _BasepAlreadyHadHardError )
	    NtTerminateProcess(GetCurrentProcess(), pExcptRec->ExceptionCode);
    }

    return EXCEPTION_EXECUTE_HANDLER;
}

LPTOP_LEVEL_EXCEPTION_FILTER
SetUnhandledExceptionFilter(
    LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter );   
{ 
    // _BasepCurrentTopLevelFilter is a KERNEL32.DLL global var
    LPTOP_LEVEL_EXCEPTION_FILTER previous= _BasepCurrentTopLevelFilter;

    // Set the new value
    _BasepCurrentTopLevelFilter = lpTopLevelExceptionFilter;

    return previous;    // return the old value
}