Index: include/reactos/subsys/win/conmsg.h
===================================================================
--- include/reactos/subsys/win/conmsg.h	(revision 62685)
+++ include/reactos/subsys/win/conmsg.h	(working copy)
@@ -674,6 +674,11 @@
     UINT CodePage;
 } CONSOLE_GETSETINPUTOUTPUTCP, *PCONSOLE_GETSETINPUTOUTPUTCP;
 
+typedef struct
+{
+    HANDLE ConsoleHandle;
+} CONSOLE_NOTIFYLASTCLOSE, *PCONSOLE_NOTIFYLASTCLOSE;
+
 typedef struct _CONSOLE_API_MESSAGE
 {
     PORT_MESSAGE Header;
@@ -765,6 +770,9 @@
 
         /* Input and Output Code Pages */
         CONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest;
+
+        /* Miscellaneous */
+        CONSOLE_NOTIFYLASTCLOSE NotifyLastCloseRequest;
     } Data;
 } CONSOLE_API_MESSAGE, *PCONSOLE_API_MESSAGE;
 
Index: include/psdk/wincon.h
===================================================================
--- include/psdk/wincon.h	(revision 62685)
+++ include/psdk/wincon.h	(working copy)
@@ -68,6 +68,7 @@
 #define CTRL_C_EVENT        0
 #define CTRL_BREAK_EVENT    1
 #define CTRL_CLOSE_EVENT    2
+#define CTRL_LAST_EVENT     3 /* Undocumented */
 #define CTRL_LOGOFF_EVENT   5
 #define CTRL_SHUTDOWN_EVENT 6
 
Index: win32ss/user/winsrv/consrv/consrv.h
===================================================================
--- win32ss/user/winsrv/consrv/consrv.h	(revision 62685)
+++ win32ss/user/winsrv/consrv/consrv.h	(working copy)
@@ -57,6 +57,7 @@
     HANDLE ParentConsoleHandle;
 
     BOOL ConsoleApp;    // TRUE if it is a CUI app, FALSE otherwise.
+    BOOL NotifyLast;
 
     RTL_CRITICAL_SECTION HandleTableLock;
     ULONG HandleTableSize;
Index: win32ss/user/winsrv/consrv/handle.c
===================================================================
--- win32ss/user/winsrv/consrv/handle.c	(revision 62685)
+++ win32ss/user/winsrv/consrv/handle.c	(working copy)
@@ -634,11 +634,20 @@
     return Status;
 }
 
+NTSTATUS
+ConDrvConsoleCtrlEvent(
+    IN ULONG Event,
+    IN PCONSOLE_PROCESS_DATA ProcessData
+);
+
 VOID
 FASTCALL
 ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
 {
     PCONSOLE Console;
+    PCONSOLE_PROCESS_DATA Process;
+    PLIST_ENTRY Entry;
+    ULONG ProcessesAttached = 0;
 
     DPRINT("ConSrvRemoveConsole\n");
 
@@ -663,6 +672,27 @@
         /* Update the internal info of the terminal */
         TermRefreshInternalInfo(Console);
 
+        /* Count the number of remaining processes attached to the console */
+        for (Entry = Console->ProcessList.Flink;
+             Entry != (PLIST_ENTRY)&Console->ProcessList;
+             Entry = Entry->Flink)
+        {
+            ProcessesAttached++;
+        }
+
+        if (ProcessesAttached == 1)
+        {
+            /* Get the last remaining process */
+            Process = CONTAINING_RECORD(Console->ProcessList.Flink,
+                                        CONSOLE_PROCESS_DATA,
+                                        ConsoleLink);
+            if (Process->NotifyLast)
+            {
+                /* Notify it that it's the only process on the console */
+                ConDrvConsoleCtrlEvent(CTRL_LAST_EVENT, Process);
+            }
+        }
+
         /* Release the console */
         DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount);
         ConDrvReleaseConsole(Console, TRUE);
Index: win32ss/user/winsrv/consrv/console.c
===================================================================
--- win32ss/user/winsrv/consrv/console.c	(revision 62685)
+++ win32ss/user/winsrv/consrv/console.c	(working copy)
@@ -638,8 +638,14 @@
 
 CSR_API(SrvConsoleNotifyLastClose)
 {
-    DPRINT1("%s not yet implemented\n", __FUNCTION__);
-    return STATUS_NOT_IMPLEMENTED;
+    PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
+
+    if (!ProcessData->NotifyLast)
+    {
+        ProcessData->NotifyLast = TRUE;
+        return STATUS_SUCCESS;
+    }
+    else return STATUS_ACCESS_DENIED;
 }
 
 
Index: win32ss/user/winsrv/consrv/condrv/console.c
===================================================================
--- win32ss/user/winsrv/consrv/condrv/console.c	(revision 62685)
+++ win32ss/user/winsrv/consrv/condrv/console.c	(working copy)
@@ -244,7 +244,7 @@
     return Status;
 }
 
-static NTSTATUS
+NTSTATUS
 ConDrvConsoleCtrlEvent(IN ULONG Event,
                        IN PCONSOLE_PROCESS_DATA ProcessData)
 {
Index: dll/win32/kernel32/client/console/console.c
===================================================================
--- dll/win32/kernel32/client/console/console.c	(revision 62685)
+++ dll/win32/kernel32/client/console/console.c	(working copy)
@@ -30,6 +30,7 @@
 PHANDLER_ROUTINE* CtrlHandlers;
 ULONG NrCtrlHandlers;
 ULONG NrAllocatedHandlers;
+BOOL LastConsoleNotify = FALSE;
 
 HANDLE InputWaitHandle = INVALID_HANDLE_VALUE;
 
@@ -129,8 +130,8 @@
         case CTRL_SHUTDOWN_EVENT:
             break;
 
-        case 3:
-            ExitThread(0);
+        case CTRL_LAST_EVENT:
+            if (!LastConsoleNotify) ExitThread(0);
             break;
 
         case 4:
@@ -2496,14 +2497,26 @@
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
-BOOL
+NTSTATUS
 WINAPI
 SetLastConsoleEventActive(VOID)
 {
-    STUB;
-    return FALSE;
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_NOTIFYLASTCLOSE NotifyLastCloseRequest = &ApiMessage.Data.NotifyLastCloseRequest;
+
+    /* Set the flag */
+    LastConsoleNotify = TRUE;
+
+    /* Set up the input arguments */
+    NotifyLastCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+
+    /* Call CSRSS */
+    return CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                               NULL,
+                               CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepNotifyLastClose),
+                               sizeof(CONSOLE_NOTIFYLASTCLOSE));
 }
 
 /* EOF */
