#define NDEBUG
#include <debug.h>
-extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
-extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
extern RTL_CRITICAL_SECTION ConsoleLock;
extern BOOL ConsoleInitialized;
extern BOOL WINAPI IsDebuggerPresent(VOID);
/* GLOBALS *******************************************************************/
-static PHANDLER_ROUTINE* CtrlHandlers = NULL;
-static ULONG NrCtrlHandlers = 0;
+PHANDLER_ROUTINE InitialHandler[1];
+PHANDLER_ROUTINE* CtrlHandlers;
+ULONG NrCtrlHandlers;
+ULONG NrAllocatedHandlers;
+
#define INPUTEXENAME_BUFLEN 256
static WCHAR InputExeName[INPUTEXENAME_BUFLEN] = L"";
WINAPI
DefaultConsoleCtrlHandler(DWORD Event)
{
+ DPRINT("Default handler called: %lx\n", Event);
switch(Event)
{
case CTRL_C_EVENT:
break;
}
- ExitProcess(0);
+ ExitProcess(CONTROL_C_EXIT);
return TRUE;
}
-
__declspec(noreturn)
VOID
CALLBACK
DWORD nExitCode = 0;
DWORD nCode = CodeAndFlag & MAXLONG;
UINT i;
-
+ EXCEPTION_RECORD erException;
+
+ DPRINT("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
switch(nCode)
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
{
- if(IsDebuggerPresent())
+ if (IsDebuggerPresent())
{
- EXCEPTION_RECORD erException;
- erException.ExceptionCode =
- (nCode == CTRL_C_EVENT ? DBG_CONTROL_C : DBG_CONTROL_BREAK);
+ erException.ExceptionCode = (nCode == CTRL_C_EVENT ?
+ DBG_CONTROL_C : DBG_CONTROL_BREAK);
erException.ExceptionFlags = 0;
erException.ExceptionRecord = NULL;
- erException.ExceptionAddress = &DefaultConsoleCtrlHandler;
+ erException.ExceptionAddress = DefaultConsoleCtrlHandler;
erException.NumberParameters = 0;
- RtlRaiseException(&erException);
- }
-
- if (!ConsoleInitialized) ExitThread(0);
- RtlEnterCriticalSection(&ConsoleLock);
-
- if (!(nCode == CTRL_C_EVENT &&
- NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1))
- {
- for(i = NrCtrlHandlers; i > 0; -- i)
- if(CtrlHandlers[i - 1](nCode)) break;
+
+ _SEH2_TRY
+ {
+ RtlRaiseException(&erException);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ RtlEnterCriticalSection(&ConsoleLock);
+
+ if ((nCode != CTRL_C_EVENT) ||
+ (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
+ {
+ for (i = NrCtrlHandlers; i > 0; i--)
+ {
+ if (CtrlHandlers[i - 1](nCode)) break;
+ }
+ }
+
+ RtlLeaveCriticalSection(&ConsoleLock);
+ }
+ _SEH2_END;
+
+ ExitThread(0);
}
- RtlLeaveCriticalSection(&ConsoleLock);
- ExitThread(0);
+
+ break;
}
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
break;
+
+ case 3:
+
+ ExitThread(0);
+ break;
+
+ case 4:
+
+ ExitProcess(CONTROL_C_EXIT);
+ break;
- default: ExitThread(0);
+ default:
+
+ ASSERT(FALSE);
+ break;
}
-
- if (!ConsoleInitialized) ExitThread(0);
+
+ ASSERT(ConsoleInitialized);
+
RtlEnterCriticalSection(&ConsoleLock);
-
- if (!(nCode == CTRL_C_EVENT &&
- NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1))
+ nExitCode = 0;
+ if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
{
- i = NrCtrlHandlers;
- while (i > 0)
+ for (i = NrCtrlHandlers; i > 0; i--)
{
- if (i == 1 && (CodeAndFlag & MINLONG) &&
- (nCode == CTRL_LOGOFF_EVENT || nCode == CTRL_SHUTDOWN_EVENT))
+ if ((i == 1) &&
+ (CodeAndFlag & MINLONG) &&
+ ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT)))
+ {
+ DPRINT("Skipping system/service apps\n");
break;
+ }
if (CtrlHandlers[i - 1](nCode))
{
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
+ case 3:
nExitCode = CodeAndFlag;
+ break;
}
break;
}
- --i;
}
}
+
RtlLeaveCriticalSection(&ConsoleLock);
ExitThread(nExitCode);
}
ULONG CsrRequest;
NTSTATUS Status = STATUS_SUCCESS;
- if (0 == _wcsicmp(wsName, L"CONIN$"))
+ if (wsName && 0 == _wcsicmp(wsName, L"CONIN$"))
{
CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE);
}
- else if (0 == _wcsicmp(wsName, L"CONOUT$"))
+ else if (wsName && 0 == _wcsicmp(wsName, L"CONOUT$"))
{
CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE);
}
/* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */
Request.Data.GetInputHandleRequest.Access = dwDesiredAccess;
Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle;
+ Request.Data.GetInputHandleRequest.ShareMode = dwShareMode;
Status = CsrClientCallServer(&Request,
NULL,
return INVALID_HANDLE_VALUE;
}
- return Request.Data.GetInputHandleRequest.InputHandle;
+ return Request.Data.GetInputHandleRequest.Handle;
}
Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher;
Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE;
+ Request.Data.AllocConsoleRequest.Visible = TRUE;
CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE);
/*--------------------------------------------------------------
* SetConsoleScreenBufferSize
*
- * @unimplemented
+ * @implemented
*/
BOOL
WINAPI
SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
COORD dwSize)
{
- DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ CSR_API_MESSAGE Request;
+ ULONG CsrRequest;
+ NTSTATUS Status;
+
+ CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER_SIZE, CSR_CONSOLE);
+ Request.Data.SetScreenBufferSize.OutputHandle = hConsoleOutput;
+ Request.Data.SetScreenBufferSize.Size = dwSize;
+
+ Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
+ if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ return TRUE;
}
/*--------------------------------------------------------------
BOOL
AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
{
+ PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
+
if (HandlerRoutine == NULL)
{
NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
- return(TRUE);
+ return TRUE;
}
- else
+
+ if (NrCtrlHandlers == NrAllocatedHandlers)
{
- NrCtrlHandlers++;
- if (CtrlHandlers == NULL)
- {
- CtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
- }
- else
+ NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
+ if (NewCtrlHandlers == NULL)
{
- CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- (PVOID)CtrlHandlers,
- NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
- }
-
- if (CtrlHandlers == NULL)
- {
- NrCtrlHandlers = 0;
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
-
- CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
- return TRUE;
+
+ memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
+
+ if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
+
+ CtrlHandlers = NewCtrlHandlers;
+ NrAllocatedHandlers += 4;
}
+
+ ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
+
+ CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
+ return TRUE;
}
if (HandlerRoutine == NULL)
{
NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
- return(TRUE);
+ return TRUE;
}
- else
+
+ for (i = 0; i < NrCtrlHandlers; i++)
{
- for (i = 0; i < NrCtrlHandlers; i++)
+ if (CtrlHandlers[i] == HandlerRoutine)
{
- if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
+ if (i < (NrCtrlHandlers - 1))
{
- NrCtrlHandlers--;
- memmove(CtrlHandlers + i,
- CtrlHandlers + i + 1,
- (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
-
- CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- (PVOID)CtrlHandlers,
- NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
- return(TRUE);
+ memmove(&CtrlHandlers[i],
+ &CtrlHandlers[i+1],
+ (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
}
+
+ NrCtrlHandlers--;
+ return TRUE;
}
}
SetLastError(ERROR_INVALID_PARAMETER);
- return(FALSE);
+ return FALSE;
}
GetConsoleProcessList(LPDWORD lpdwProcessList,
DWORD dwProcessCount)
{
- PCSR_API_MESSAGE Request;
+ PCSR_CAPTURE_BUFFER CaptureBuffer;
+ CSR_API_MESSAGE Request;
ULONG CsrRequest;
ULONG nProcesses;
NTSTATUS Status;
return 0;
}
- Request = RtlAllocateHeap(RtlGetProcessHeap(),
- 0,
- max(sizeof(CSR_API_MESSAGE),
- CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
- + min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)) * sizeof(DWORD)));
- if (Request == NULL)
+ CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
+ if (CaptureBuffer == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE);
- Request->Data.GetProcessListRequest.nMaxIds = min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD));
+ Request.Data.GetProcessListRequest.nMaxIds = dwProcessCount;
+ CsrAllocateMessagePointer(CaptureBuffer,
+ dwProcessCount * sizeof(DWORD),
+ (PVOID*)&Request.Data.GetProcessListRequest.ProcessId);
- Status = CsrClientCallServer(Request,
- NULL,
+ Status = CsrClientCallServer(&Request,
+ CaptureBuffer,
CsrRequest,
- max(sizeof(CSR_API_MESSAGE),
- CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
- + Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)));
- if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
+ sizeof(CSR_API_MESSAGE));
+ if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
{
- RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
SetLastErrorByStatus (Status);
nProcesses = 0;
}
else
{
- nProcesses = Request->Data.GetProcessListRequest.nProcessIdsCopied;
+ nProcesses = Request.Data.GetProcessListRequest.nProcessIdsTotal;
if (dwProcessCount >= nProcesses)
{
- memcpy(lpdwProcessList, Request->Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD));
+ memcpy(lpdwProcessList, Request.Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD));
}
}
- RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
-
+ CsrFreeCaptureBuffer(CaptureBuffer);
return nProcesses;
}