- Implement the rest of Hard Error support.
authorAlex Ionescu <aionescu@gmail.com>
Mon, 30 Oct 2006 14:20:45 +0000 (14:20 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Mon, 30 Oct 2006 14:20:45 +0000 (14:20 +0000)
- Kernel support is complete (except temporary LPC hack), and CSRSS properly receives the event and sends it off to win32csr's hard error handler (much like on NT). However, the handler doesn't call NtUserHardErrorControl nor do much of the complex sequence of events that NT does, instead, we only display a hello-world style message box. Anyone up for implementing the rest is welcome.

svn path=/trunk/; revision=24665

reactos/ntoskrnl/ex/error.c
reactos/ntoskrnl/lpc/reply.c
reactos/ntoskrnl/lpc/send.c
reactos/subsystems/win32/csrss/api/wapi.c
reactos/subsystems/win32/csrss/include/csrplugin.h
reactos/subsystems/win32/csrss/init.c
reactos/subsystems/win32/csrss/win32csr/dllmain.c
reactos/subsystems/win32/csrss/win32csr/win32csr.def

index 23cd803..33c2131 100644 (file)
@@ -112,11 +112,6 @@ ExpRaiseHardError(IN NTSTATUS ErrorStatus,
     HANDLE PortHandle;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
     PAGED_CODE();
-    DPRINT1("Hard error, baby!: %lx, %lx, %lx %p\n",
-            ErrorStatus,
-            NumberOfParameters,
-            UnicodeStringParameterMask,
-            Parameters);
 
     /* Check if this error will shutdown the system */
     if (ValidResponseOptions == OptionShutdownSystem)
@@ -235,15 +230,42 @@ ExpRaiseHardError(IN NTSTATUS ErrorStatus,
                                       Parameters,
                                       sizeof(ULONG_PTR) * NumberOfParameters);
 
-        /* Send the message */
+        /* Send the LPC Message */
         Status = LpcRequestWaitReplyPort(PortHandle,
                                          (PVOID)Message,
                                          (PVOID)Message);
-        DPRINT1("Checkpoint 2: %lx\n", Status);
+        if (NT_SUCCESS(Status))
+        {
+            /* Check what kind of response we got */
+            if ((Message->Response != ResponseReturnToCaller) &&
+                (Message->Response != ResponseNotHandled) &&
+                (Message->Response != ResponseAbort) &&
+                (Message->Response != ResponseCancel) &&
+                (Message->Response != ResponseIgnore) &&
+                (Message->Response != ResponseNo) &&
+                (Message->Response != ResponseOk) &&
+                (Message->Response != ResponseRetry) &&
+                (Message->Response != ResponseYes) &&
+                (Message->Response != ResponseTryAgain) &&
+                (Message->Response != ResponseContinue))
+            {
+                /* Reset to a default one */
+                Message->Response = ResponseReturnToCaller;
+            }
+
+            /* Set the response */
+            *Response = Message->Response;
+        }
+    }
+    else
+    {
+        /* Set defaults */
+        *Response = ResponseReturnToCaller;
+        Status = STATUS_SUCCESS;
     }
 
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    /* Return status */
+    return Status;
 }
 
 /*++
index 58159f8..5fb58c2 100644 (file)
@@ -429,22 +429,26 @@ LpcRequestWaitReplyPort(IN PVOID Port,
 {
     HANDLE PortHandle;
     NTSTATUS Status;
+    UNICODE_STRING PortName;
+    ULONG ConnectInfoLength;
+
+    //
+    // OMG HAXX!
+    //
+    RtlInitUnicodeString(&PortName, L"\\Windows\\ApiPort");
+    ConnectInfoLength = 0;
+    Status = ZwConnectPort(&PortHandle,
+                           &PortName,
+                           NULL,
+                           NULL,
+                           NULL,
+                           NULL,
+                           NULL,
+                           &ConnectInfoLength);
 
-    /* This is a SICK hack */
-    Status = ObOpenObjectByPointer(Port,
-                                   0,
-                                   NULL,
-                                   PORT_ALL_ACCESS,
-                                   LpcPortObjectType,
-                                   KernelMode,
-                                   &PortHandle);
-    DPRINT1("LPC Hack active: %lx %lx\n", Status, PortHandle);
-
-    /* Call the Nt function. Do a ring transition to get Kmode. */
     Status = ZwRequestWaitReplyPort(PortHandle,
                                     LpcMessageRequest,
                                     LpcMessageReply);
-    DPRINT1("LPC Hack active: %lx %lx\n", Status, PortHandle);
 
     /* Close the handle */
     ObCloseHandle(PortHandle, KernelMode);
index 53bae72..1dc522f 100644 (file)
@@ -288,7 +288,7 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
 
    Status = EiReplyOrRequestPort(Port->OtherPort,
                                 LpcRequest,
-                                LPC_REQUEST,
+                 LpcRequest->u2.s2.Type == LPC_ERROR_EVENT ? LPC_ERROR_EVENT : LPC_REQUEST,
                                 Port);
    if (!NT_SUCCESS(Status))
      {
index 92a726e..c647a05 100644 (file)
@@ -104,6 +104,20 @@ CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
     }
 }
 
+BOOL FASTCALL CallHardError(void);
+
+static
+VOID
+NTAPI
+CsrHandleHardError(IN PCSRSS_PROCESS_DATA ProcessData,
+                   IN OUT PHARDERROR_MSG Message)
+{
+    DPRINT1("CSR: received hard error %lx\n", Message->Status);
+
+    /* Call the hard error handler in win32csr */
+    CallHardError();
+}
+
 static
 VOID
 STDCALL
@@ -133,7 +147,7 @@ ClientConnectionThread(HANDLE ServerPort)
           DPRINT1("NtReplyWaitReceivePort failed\n");
           break;
         }
-        
+
         /* If the connection was closed, handle that */
         if (Request->Header.u2.s2.Type == LPC_PORT_CLOSED)
         {
@@ -161,9 +175,18 @@ ClientConnectionThread(HANDLE ServerPort)
             continue;
         }
 
-        /* Call the Handler */
-        CsrApiCallHandler(ProcessData, Request);
-        
+        /* Check if we got a hard error */
+        if (Request->Header.u2.s2.Type == LPC_ERROR_EVENT)
+        {
+            /* Call the Handler */
+            CsrHandleHardError(ProcessData, (PHARDERROR_MSG)Request);
+        }
+        else
+        {
+            /* Call the Handler */
+            CsrApiCallHandler(ProcessData, Request);
+        }
+
         /* Send back the reply */
         Reply = Request;
     }
index 9a435cb..a5f250b 100644 (file)
@@ -43,9 +43,12 @@ typedef struct tagCSRSS_EXPORTED_FUNCS
 
 typedef BOOL (STDCALL *CSRPLUGIN_INIT_COMPLETE_PROC)(void);
 
+typedef BOOL (STDCALL *CSRPLUGIN_HARDERROR_PROC)(void);
+
 typedef BOOL (STDCALL *CSRPLUGIN_INITIALIZE_PROC)(PCSRSS_API_DEFINITION *ApiDefinitions,
                                                   PCSRSS_OBJECT_DEFINITION *ObjectDefinitions,
                                                   CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProc,
+                                                  CSRPLUGIN_HARDERROR_PROC *HardErrorProc,
                                                   PCSRSS_EXPORTED_FUNCS Exports,
                                                   HANDLE CsrssApiHeap);
 
index d1b80bc..9ff6bf5 100644 (file)
@@ -28,6 +28,9 @@ extern HANDLE CsrssApiHeap;
 static unsigned InitCompleteProcCount;
 static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL;
 
+static unsigned HardErrorProcCount;
+static CSRPLUGIN_HARDERROR_PROC *HardErrorProcs = NULL;
+
 HANDLE hSbApiPort = (HANDLE) 0;
 
 HANDLE hBootstrapOk = (HANDLE) 0;
@@ -66,6 +69,34 @@ CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
   return STATUS_SUCCESS;
 }
 
+static NTSTATUS FASTCALL
+CsrpAddHardErrorProc(CSRPLUGIN_HARDERROR_PROC Proc)
+{
+    CSRPLUGIN_HARDERROR_PROC *NewProcs;
+
+    DPRINT("CSR: %s called\n", __FUNCTION__);
+
+    NewProcs = RtlAllocateHeap(CsrssApiHeap, 0,
+                               (HardErrorProcCount + 1)
+                               * sizeof(CSRPLUGIN_HARDERROR_PROC));
+    if (NULL == NewProcs)
+    {
+        return STATUS_NO_MEMORY;
+    }
+    if (0 != HardErrorProcCount)
+    {
+        RtlCopyMemory(NewProcs, HardErrorProcs,
+            HardErrorProcCount * sizeof(CSRPLUGIN_HARDERROR_PROC));
+        RtlFreeHeap(CsrssApiHeap, 0, HardErrorProcs);
+    }
+
+    NewProcs[HardErrorProcCount] = Proc;
+    HardErrorProcs = NewProcs;
+    HardErrorProcCount++;
+
+    return STATUS_SUCCESS;
+}
+
 /**********************************************************************
  * CallInitComplete/0
  */
@@ -90,6 +121,27 @@ CallInitComplete(void)
   return Ok;
 }
 
+BOOL
+FASTCALL
+CallHardError(void)
+{
+    BOOL Ok;
+    unsigned i;
+
+    DPRINT("CSR: %s called\n", __FUNCTION__);
+
+    Ok = TRUE;
+    if (0 != HardErrorProcCount)
+    {
+        for (i = 0; i < HardErrorProcCount && Ok; i++)
+        {
+            Ok = (*(HardErrorProcs[i]))();
+        }
+    }
+
+    return Ok;
+}
+
 ULONG
 InitializeVideoAddressSpace(VOID);
 
@@ -182,6 +234,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp)
   PCSRSS_API_DEFINITION ApiDefinitions;
   PCSRSS_OBJECT_DEFINITION ObjectDefinitions;
   CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc;
+  CSRPLUGIN_HARDERROR_PROC HardErrorProc;
 
   DPRINT("CSR: %s called\n", __FUNCTION__);
 
@@ -202,7 +255,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp)
   Exports.CsrReleaseObjectProc = CsrReleaseObject;
   Exports.CsrEnumProcessesProc = CsrEnumProcesses;
   if (! (*InitProc)(&ApiDefinitions, &ObjectDefinitions, &InitCompleteProc,
-                    &Exports, CsrssApiHeap))
+                    &HardErrorProc, &Exports, CsrssApiHeap))
     {
       return STATUS_UNSUCCESSFUL;
     }
@@ -221,6 +274,7 @@ CsrpInitWin32Csr (int argc, char ** argv, char ** envp)
     {
       Status = CsrpAddInitCompleteProc(InitCompleteProc);
     }
+  if (HardErrorProc) Status = CsrpAddHardErrorProc(HardErrorProc);
 
   return Status;
 }
index 683ec51..3127206 100644 (file)
@@ -163,10 +163,19 @@ Win32CsrInitComplete(void)
   return TRUE;
 }
 
+static BOOL STDCALL
+Win32CsrHardError(void)
+{
+    MessageBox(0, "Hard Error", "TODO", 0);
+    return TRUE;
+}
+
+
 BOOL STDCALL
 Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
                        PCSRSS_OBJECT_DEFINITION *ObjectDefinitions,
                        CSRPLUGIN_INIT_COMPLETE_PROC *InitComplete,
+                       CSRPLUGIN_HARDERROR_PROC *HardError,
                        PCSRSS_EXPORTED_FUNCS Exports,
                        HANDLE CsrssApiHeap)
 {
@@ -179,6 +188,7 @@ Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
   *ApiDefinitions = Win32CsrApiDefinitions;
   *ObjectDefinitions = Win32CsrObjectDefinitions;
   *InitComplete = Win32CsrInitComplete;
+  *HardError = Win32CsrHardError;
 
   return TRUE;
 }