Partial merge of the condrv_restructure branch, including:

- some consrv/condrv code refactoring for a better code separation,
- make kernel32 / winsrv console CSR structures Win2k3-compliant (see CORE-7931); only Alloc/Attach/FreeConsole APIs are still not Win2k3-compliant.
- fixes for CsrCaptureMessageString and implementation of CsrCaptureMessageMultiUnicodeStringsInPlace .

CORE-7931 #comment Partial merge of the condrv_restructure branch in revision 63810.

svn path=/trunk/; revision=63810
This commit is contained in:
Hermès Bélusca-Maïto
2014-08-04 21:33:20 +00:00
45 changed files with 5073 additions and 3302 deletions
+96 -43
View File
@@ -3,7 +3,8 @@
* PROJECT: ReactOS kernel
* FILE: dll/ntdll/csr/capture.c
* PURPOSE: Routines for probing and capturing CSR API Messages
* PROGRAMMER: Alex Ionescu ([email protected])
* PROGRAMMERS: Alex Ionescu ([email protected])
* Hermes Belusca-Maito ([email protected])
*/
/* INCLUDES *******************************************************************/
@@ -131,7 +132,7 @@ ULONG
NTAPI
CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
IN ULONG MessageLength,
OUT PVOID *CapturedData)
OUT PVOID* CapturedData)
{
if (MessageLength == 0)
{
@@ -168,7 +169,7 @@ NTAPI
CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
IN PVOID MessageBuffer OPTIONAL,
IN ULONG MessageLength,
OUT PVOID *CapturedData)
OUT PVOID* CapturedData)
{
/* Simply allocate a message pointer in the buffer */
CsrAllocateMessagePointer(CaptureBuffer, MessageLength, CapturedData);
@@ -191,35 +192,23 @@ CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
RtlFreeHeap(CsrPortHeap, 0, CaptureBuffer);
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER *CaptureBuffer,
IN ULONG MessageCount,
IN PVOID MessageStrings)
{
/* FIXME: allocate a buffer if we don't have one, and return it */
/* FIXME: call CsrCaptureMessageUnicodeStringInPlace for each string */
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @implemented
*/
VOID
NTAPI
CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
IN LPSTR String OPTIONAL,
IN PCSTR String OPTIONAL,
IN ULONG StringLength,
IN ULONG MaximumLength,
OUT PANSI_STRING CapturedString)
OUT PSTRING CapturedString)
{
ULONG ReturnedLength;
ASSERT(CapturedString != NULL);
/* If we don't have a string, initialize an empty one */
/*
* If we don't have a string, initialize an empty one,
* otherwise capture the given string.
*/
if (!String)
{
CapturedString->Length = 0;
@@ -229,31 +218,95 @@ CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
CsrAllocateMessagePointer(CaptureBuffer,
MaximumLength,
(PVOID*)&CapturedString->Buffer);
return;
}
/* Initialize this string */
CapturedString->Length = (USHORT)StringLength;
/* Allocate a buffer and get its size */
ReturnedLength = CsrAllocateMessagePointer(CaptureBuffer,
MaximumLength,
(PVOID*)&CapturedString->Buffer);
CapturedString->MaximumLength = (USHORT)ReturnedLength;
/* If the string had data */
if (StringLength)
else
{
/* Copy it into the capture buffer */
RtlMoveMemory(CapturedString->Buffer, String, MaximumLength);
/* Cut-off the string length if needed */
if (StringLength > MaximumLength)
StringLength = MaximumLength;
/* If we don't take up the whole space */
if (CapturedString->Length < CapturedString->MaximumLength)
{
/* Null-terminate it */
CapturedString->Buffer[CapturedString->Length] = '\0';
}
CapturedString->Length = (USHORT)StringLength;
/* Allocate a buffer and get its size */
CapturedString->MaximumLength =
(USHORT)CsrAllocateMessagePointer(CaptureBuffer,
MaximumLength,
(PVOID*)&CapturedString->Buffer);
/* If the string has data, copy it into the buffer */
if (StringLength)
RtlMoveMemory(CapturedString->Buffer, String, StringLength);
}
/* Null-terminate the string if we don't take up the whole space */
if (CapturedString->Length < CapturedString->MaximumLength)
CapturedString->Buffer[CapturedString->Length] = '\0';
}
static VOID
CsrCaptureMessageUnicodeStringInPlace(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
IN PUNICODE_STRING String)
{
ASSERT(String != NULL);
/* This is a way to capture the UNICODE string, since (Maximum)Length are also in bytes */
CsrCaptureMessageString(CaptureBuffer,
(PCSTR)String->Buffer,
String->Length,
String->MaximumLength,
(PSTRING)String);
/* Null-terminate the string */
if (String->MaximumLength >= String->Length + sizeof(WCHAR))
{
String->Buffer[String->Length / sizeof(WCHAR)] = L'\0';
}
}
/*
* @implemented
*/
NTSTATUS
NTAPI
CsrCaptureMessageMultiUnicodeStringsInPlace(OUT PCSR_CAPTURE_BUFFER* CaptureBuffer,
IN ULONG StringsCount,
IN PUNICODE_STRING* MessageStrings)
{
ULONG Count;
if (!CaptureBuffer) return STATUS_INVALID_PARAMETER;
/* Allocate a new capture buffer if we don't have one already */
if (!*CaptureBuffer)
{
/* Compute the required size for the capture buffer */
ULONG Size = 0;
Count = 0;
while (Count < StringsCount)
{
if (MessageStrings[Count])
Size += MessageStrings[Count]->MaximumLength;
++Count;
}
/* Allocate the capture buffer */
*CaptureBuffer = CsrAllocateCaptureBuffer(StringsCount, Size);
if (!*CaptureBuffer) return STATUS_NO_MEMORY;
}
/* Now capture each UNICODE string */
Count = 0;
while (Count < StringsCount)
{
if (MessageStrings[Count])
CsrCaptureMessageUnicodeStringInPlace(*CaptureBuffer, MessageStrings[Count]);
++Count;
}
return STATUS_SUCCESS;
}
/*
+284 -289
View File
@@ -18,31 +18,40 @@
/* FUNCTIONS ******************************************************************/
/*
* @implemented
*/
BOOL
WINAPI
AddConsoleAliasW(LPCWSTR lpSource,
LPCWSTR lpTarget,
LPCWSTR lpExeName)
static BOOL
IntAddConsoleAlias(LPCVOID Source,
USHORT SourceBufferLength,
LPCVOID Target,
USHORT TargetBufferLength,
LPCVOID lpExeName,
BOOLEAN bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_ADDGETALIAS ConsoleAliasRequest = &ApiMessage.Data.ConsoleAliasRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
ULONG CapturedStrings;
DPRINT("AddConsoleAliasW enterd with lpSource %S lpTarget %S lpExeName %S\n", lpSource, lpTarget, lpExeName);
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
ConsoleAliasRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
/* Determine the needed sizes */
ConsoleAliasRequest->SourceLength = (wcslen(lpSource ) + 1) * sizeof(WCHAR);
ConsoleAliasRequest->ExeLength = (wcslen(lpExeName) + 1) * sizeof(WCHAR);
ConsoleAliasRequest->SourceLength = SourceBufferLength;
ConsoleAliasRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
ConsoleAliasRequest->Unicode =
ConsoleAliasRequest->Unicode2 = bUnicode;
CapturedStrings = 2;
if (lpTarget) /* The target can be optional */
if (Target) /* The target can be optional */
{
ConsoleAliasRequest->TargetLength = (wcslen(lpTarget) + 1) * sizeof(WCHAR);
ConsoleAliasRequest->TargetLength = TargetBufferLength;
CapturedStrings++;
}
else
@@ -64,19 +73,19 @@ AddConsoleAliasW(LPCWSTR lpSource,
/* Capture the strings */
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpSource,
(PVOID)Source,
ConsoleAliasRequest->SourceLength,
(PVOID*)&ConsoleAliasRequest->Source);
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
ConsoleAliasRequest->ExeLength,
(PVOID*)&ConsoleAliasRequest->Exe);
(PVOID*)&ConsoleAliasRequest->ExeName);
if (lpTarget) /* The target can be optional */
if (Target) /* The target can be optional */
{
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpTarget,
(PVOID)Target,
ConsoleAliasRequest->TargetLength,
(PVOID*)&ConsoleAliasRequest->Target);
}
@@ -85,16 +94,16 @@ AddConsoleAliasW(LPCWSTR lpSource,
ConsoleAliasRequest->Target = NULL;
}
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAddAlias),
sizeof(CONSOLE_ADDGETALIAS));
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAddAlias),
sizeof(*ConsoleAliasRequest));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(Status);
BaseSetLastNTError(ApiMessage.Status);
return FALSE;
}
@@ -107,64 +116,83 @@ AddConsoleAliasW(LPCWSTR lpSource,
*/
BOOL
WINAPI
AddConsoleAliasA(LPCSTR lpSource,
LPCSTR lpTarget,
LPCSTR lpExeName)
AddConsoleAliasW(LPCWSTR lpSource,
LPCWSTR lpTarget,
LPCWSTR lpExeName)
{
LPWSTR lpSourceW = NULL;
LPWSTR lpTargetW = NULL;
LPWSTR lpExeNameW = NULL;
BOOL bRetVal;
USHORT SourceBufferLength = (USHORT)wcslen(lpSource) * sizeof(WCHAR);
USHORT TargetBufferLength = (USHORT)(lpTarget ? wcslen(lpTarget) * sizeof(WCHAR) : 0);
if (lpSource)
BasepAnsiStringToHeapUnicodeString(lpSource, (LPWSTR*)&lpSourceW);
if (lpTarget)
BasepAnsiStringToHeapUnicodeString(lpTarget, (LPWSTR*)&lpTargetW);
if (lpExeName)
BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*)&lpExeNameW);
DPRINT1("AddConsoleAliasW entered with lpSource '%S' lpTarget '%S' lpExeName '%S'\n",
lpSource, lpTarget, lpExeName);
bRetVal = AddConsoleAliasW(lpSourceW, lpTargetW, lpExeNameW);
/* Clean up */
if (lpSourceW)
RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*)lpSourceW);
if (lpTargetW)
RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*)lpTargetW);
if (lpExeNameW)
RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*)lpExeNameW);
return bRetVal;
return IntAddConsoleAlias(lpSource,
SourceBufferLength,
lpTarget,
TargetBufferLength,
lpExeName,
TRUE);
}
/*
* @implemented
*/
DWORD
BOOL
WINAPI
GetConsoleAliasW(LPWSTR lpSource,
LPWSTR lpTargetBuffer,
DWORD TargetBufferLength,
LPWSTR lpExeName)
AddConsoleAliasA(LPCSTR lpSource,
LPCSTR lpTarget,
LPCSTR lpExeName)
{
USHORT SourceBufferLength = (USHORT)strlen(lpSource) * sizeof(CHAR);
USHORT TargetBufferLength = (USHORT)(lpTarget ? strlen(lpTarget) * sizeof(CHAR) : 0);
DPRINT1("AddConsoleAliasA entered with lpSource '%s' lpTarget '%s' lpExeName '%s'\n",
lpSource, lpTarget, lpExeName);
return IntAddConsoleAlias(lpSource,
SourceBufferLength,
lpTarget,
TargetBufferLength,
lpExeName,
FALSE);
}
static DWORD
IntGetConsoleAlias(LPVOID Source,
USHORT SourceBufferLength,
LPVOID Target,
USHORT TargetBufferLength,
LPVOID lpExeName,
BOOLEAN bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_ADDGETALIAS ConsoleAliasRequest = &ApiMessage.Data.ConsoleAliasRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
DPRINT("GetConsoleAliasW entered with lpSource %S lpExeName %S\n", lpSource, lpExeName);
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpTargetBuffer == NULL)
if (Source == NULL || Target == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* Determine the needed sizes */
ConsoleAliasRequest->SourceLength = (wcslen(lpSource ) + 1) * sizeof(WCHAR);
ConsoleAliasRequest->ExeLength = (wcslen(lpExeName) + 1) * sizeof(WCHAR);
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
ConsoleAliasRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
/* Determine the needed sizes */
ConsoleAliasRequest->SourceLength = SourceBufferLength;
ConsoleAliasRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
ConsoleAliasRequest->Unicode =
ConsoleAliasRequest->Unicode2 = bUnicode;
ConsoleAliasRequest->Target = NULL;
ConsoleAliasRequest->TargetLength = TargetBufferLength;
/* Allocate a Capture Buffer */
@@ -180,36 +208,39 @@ GetConsoleAliasW(LPWSTR lpSource,
/* Capture the strings */
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpSource,
(PVOID)Source,
ConsoleAliasRequest->SourceLength,
(PVOID*)&ConsoleAliasRequest->Source);
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
ConsoleAliasRequest->ExeLength,
(PVOID*)&ConsoleAliasRequest->Exe);
(PVOID*)&ConsoleAliasRequest->ExeName);
/* Allocate space for the target buffer */
CsrAllocateMessagePointer(CaptureBuffer,
ConsoleAliasRequest->TargetLength,
(PVOID*)&ConsoleAliasRequest->Target);
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAlias),
sizeof(CONSOLE_ADDGETALIAS));
if (!NT_SUCCESS(Status))
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAlias),
sizeof(*ConsoleAliasRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
CsrFreeCaptureBuffer(CaptureBuffer);
BaseSetLastNTError(Status);
return 0;
BaseSetLastNTError(ApiMessage.Status);
if (ApiMessage.Status == STATUS_BUFFER_TOO_SMALL)
return ConsoleAliasRequest->TargetLength;
else
return 0;
}
/* Copy the returned target string into the user buffer */
// wcscpy(lpTargetBuffer, ConsoleAliasRequest->Target);
memcpy(lpTargetBuffer,
ConsoleAliasRequest->Target,
ConsoleAliasRequest->TargetLength);
RtlCopyMemory(Target,
ConsoleAliasRequest->Target,
ConsoleAliasRequest->TargetLength);
/* Release the capture buffer and exit */
CsrFreeCaptureBuffer(CaptureBuffer);
@@ -223,65 +254,20 @@ GetConsoleAliasW(LPWSTR lpSource,
*/
DWORD
WINAPI
GetConsoleAliasA(LPSTR lpSource,
LPSTR lpTargetBuffer,
GetConsoleAliasW(LPWSTR lpSource,
LPWSTR lpTargetBuffer,
DWORD TargetBufferLength,
LPSTR lpExeName)
LPWSTR lpExeName)
{
LPWSTR lpwSource;
LPWSTR lpwExeName;
LPWSTR lpwTargetBuffer;
UINT dwSourceSize;
UINT dwExeNameSize;
UINT dwResult;
DPRINT1("GetConsoleAliasW entered with lpSource '%S' lpExeName '%S'\n",
lpSource, lpExeName);
DPRINT("GetConsoleAliasA entered\n");
if (lpTargetBuffer == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
dwSourceSize = (strlen(lpSource)+1) * sizeof(WCHAR);
lpwSource = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSourceSize);
if (lpwSource == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
MultiByteToWideChar(CP_ACP, 0, lpSource, -1, lpwSource, dwSourceSize);
dwExeNameSize = (strlen(lpExeName)+1) * sizeof(WCHAR);
lpwExeName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwExeNameSize);
if (lpwExeName == NULL)
{
HeapFree(GetProcessHeap(), 0, lpwSource);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
MultiByteToWideChar(CP_ACP, 0, lpExeName, -1, lpwExeName, dwExeNameSize);
lpwTargetBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, TargetBufferLength * sizeof(WCHAR));
if (lpwTargetBuffer == NULL)
{
HeapFree(GetProcessHeap(), 0, lpwSource);
HeapFree(GetProcessHeap(), 0, lpwExeName);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
dwResult = GetConsoleAliasW(lpwSource, lpwTargetBuffer, TargetBufferLength * sizeof(WCHAR), lpwExeName);
HeapFree(GetProcessHeap(), 0, lpwSource);
HeapFree(GetProcessHeap(), 0, lpwExeName);
if (dwResult)
dwResult = WideCharToMultiByte(CP_ACP, 0, lpwTargetBuffer, dwResult / sizeof(WCHAR), lpTargetBuffer, TargetBufferLength, NULL, NULL);
HeapFree(GetProcessHeap(), 0, lpwTargetBuffer);
return dwResult;
return IntGetConsoleAlias(lpSource,
(USHORT)wcslen(lpSource) * sizeof(WCHAR),
lpTargetBuffer,
TargetBufferLength,
lpExeName,
TRUE);
}
@@ -290,25 +276,48 @@ GetConsoleAliasA(LPSTR lpSource,
*/
DWORD
WINAPI
GetConsoleAliasesW(LPWSTR AliasBuffer,
DWORD AliasBufferLength,
LPWSTR ExeName)
GetConsoleAliasA(LPSTR lpSource,
LPSTR lpTargetBuffer,
DWORD TargetBufferLength,
LPSTR lpExeName)
{
DPRINT1("GetConsoleAliasA entered with lpSource '%s' lpExeName '%s'\n",
lpSource, lpExeName);
return IntGetConsoleAlias(lpSource,
(USHORT)strlen(lpSource) * sizeof(CHAR),
lpTargetBuffer,
TargetBufferLength,
lpExeName,
FALSE);
}
static DWORD
IntGetConsoleAliases(LPVOID AliasBuffer,
DWORD AliasBufferLength,
LPVOID lpExeName,
BOOLEAN bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETALLALIASES GetAllAliasesRequest = &ApiMessage.Data.GetAllAliasesRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
DPRINT("GetConsoleAliasesW entered\n");
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
/* Determine the needed sizes */
GetAllAliasesRequest->ExeLength = GetConsoleAliasesLengthW(ExeName);
if (GetAllAliasesRequest->ExeLength == 0 ||
GetAllAliasesRequest->ExeLength > AliasBufferLength)
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
GetAllAliasesRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
/* Determine the needed sizes */
GetAllAliasesRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
GetAllAliasesRequest->Unicode =
GetAllAliasesRequest->Unicode2 = bUnicode;
GetAllAliasesRequest->AliasesBufferLength = AliasBufferLength;
/* Allocate a Capture Buffer */
@@ -323,7 +332,7 @@ GetConsoleAliasesW(LPWSTR AliasBuffer,
/* Capture the exe name and allocate space for the aliases buffer */
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)ExeName,
(PVOID)lpExeName,
GetAllAliasesRequest->ExeLength,
(PVOID*)&GetAllAliasesRequest->ExeName);
@@ -331,26 +340,45 @@ GetConsoleAliasesW(LPWSTR AliasBuffer,
GetAllAliasesRequest->AliasesBufferLength,
(PVOID*)&GetAllAliasesRequest->AliasesBuffer);
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliases),
sizeof(CONSOLE_GETALLALIASES));
if (!NT_SUCCESS(Status))
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliases),
sizeof(*GetAllAliasesRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(Status);
CsrFreeCaptureBuffer(CaptureBuffer);
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
/* Copy the returned aliases string into the user buffer */
// wcscpy(AliasBuffer, GetAllAliasesRequest->AliasesBuffer);
memcpy(AliasBuffer,
GetAllAliasesRequest->AliasesBuffer,
GetAllAliasesRequest->AliasesBufferLength);
RtlCopyMemory(AliasBuffer,
GetAllAliasesRequest->AliasesBuffer,
GetAllAliasesRequest->AliasesBufferLength);
/* Release the capture buffer and exit */
CsrFreeCaptureBuffer(CaptureBuffer);
return GetAllAliasesRequest->AliasesBufferLength; // / sizeof(WCHAR); (original code)
return GetAllAliasesRequest->AliasesBufferLength;
}
/*
* @implemented
*/
DWORD
WINAPI
GetConsoleAliasesW(LPWSTR AliasBuffer,
DWORD AliasBufferLength,
LPWSTR ExeName)
{
DPRINT1("GetConsoleAliasesW entered with lpExeName '%S'\n",
ExeName);
return IntGetConsoleAliases(AliasBuffer,
AliasBufferLength,
ExeName,
TRUE);
}
@@ -363,54 +391,36 @@ GetConsoleAliasesA(LPSTR AliasBuffer,
DWORD AliasBufferLength,
LPSTR ExeName)
{
DWORD dwRetVal = 0;
LPWSTR lpwExeName = NULL;
LPWSTR lpwAliasBuffer;
DPRINT1("GetConsoleAliasesA entered with lpExeName '%s'\n",
ExeName);
DPRINT("GetConsoleAliasesA entered\n");
if (ExeName)
BasepAnsiStringToHeapUnicodeString(ExeName, (LPWSTR*)&lpwExeName);
lpwAliasBuffer = HeapAlloc(GetProcessHeap(), 0, AliasBufferLength * sizeof(WCHAR));
dwRetVal = GetConsoleAliasesW(lpwAliasBuffer, AliasBufferLength * sizeof(WCHAR), lpwExeName);
if (lpwExeName)
RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*)lpwExeName);
if (dwRetVal)
dwRetVal = WideCharToMultiByte(CP_ACP, 0, lpwAliasBuffer, dwRetVal /**/ / sizeof(WCHAR) /**/, AliasBuffer, AliasBufferLength, NULL, NULL);
HeapFree(GetProcessHeap(), 0, lpwAliasBuffer);
return dwRetVal;
return IntGetConsoleAliases(AliasBuffer,
AliasBufferLength,
ExeName,
FALSE);
}
/*
* @implemented
*/
DWORD
WINAPI
GetConsoleAliasesLengthW(LPWSTR lpExeName)
static DWORD
IntGetConsoleAliasesLength(LPVOID lpExeName, BOOLEAN bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETALLALIASESLENGTH GetAllAliasesLengthRequest = &ApiMessage.Data.GetAllAliasesLengthRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
DPRINT("GetConsoleAliasesLengthW entered\n");
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpExeName == NULL)
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
GetAllAliasesLengthRequest->ExeLength = (wcslen(lpExeName) + 1) * sizeof(WCHAR);
GetAllAliasesLengthRequest->Length = 0;
GetAllAliasesLengthRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetAllAliasesLengthRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
GetAllAliasesLengthRequest->Unicode =
GetAllAliasesLengthRequest->Unicode2 = bUnicode;
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(1, GetAllAliasesLengthRequest->ExeLength);
if (!CaptureBuffer)
{
@@ -419,22 +429,21 @@ GetConsoleAliasesLengthW(LPWSTR lpExeName)
return 0;
}
/* Capture the exe name */
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
GetAllAliasesLengthRequest->ExeLength,
(PVOID)&GetAllAliasesLengthRequest->ExeName);
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliasesLength),
sizeof(CONSOLE_GETALLALIASESLENGTH));
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliasesLength),
sizeof(*GetAllAliasesLengthRequest));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(Status);
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
@@ -447,26 +456,68 @@ GetConsoleAliasesLengthW(LPWSTR lpExeName)
*/
DWORD
WINAPI
GetConsoleAliasesLengthA(LPSTR lpExeName)
GetConsoleAliasesLengthW(LPWSTR lpExeName)
{
DWORD dwRetVal = 0;
LPWSTR lpExeNameW = NULL;
if (lpExeName)
BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*)&lpExeNameW);
dwRetVal = GetConsoleAliasesLengthW(lpExeNameW);
if (dwRetVal)
dwRetVal /= sizeof(WCHAR);
/* Clean up */
if (lpExeNameW)
RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*)lpExeNameW);
return dwRetVal;
return IntGetConsoleAliasesLength(lpExeName, TRUE);
}
/*
* @implemented
*/
DWORD
WINAPI
GetConsoleAliasesLengthA(LPSTR lpExeName)
{
return IntGetConsoleAliasesLength(lpExeName, FALSE);
}
static DWORD
IntGetConsoleAliasExes(PVOID lpExeNameBuffer,
DWORD ExeNameBufferLength,
BOOLEAN bUnicode)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETALIASESEXES GetAliasesExesRequest = &ApiMessage.Data.GetAliasesExesRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
GetAliasesExesRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetAliasesExesRequest->Length = ExeNameBufferLength;
GetAliasesExesRequest->Unicode = bUnicode;
CaptureBuffer = CsrAllocateCaptureBuffer(1, ExeNameBufferLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
CsrAllocateMessagePointer(CaptureBuffer,
ExeNameBufferLength,
(PVOID*)&GetAliasesExesRequest->ExeNames);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliasExes),
sizeof(*GetAliasesExesRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
CsrFreeCaptureBuffer(CaptureBuffer);
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
RtlCopyMemory(lpExeNameBuffer,
GetAliasesExesRequest->ExeNames,
GetAliasesExesRequest->Length);
CsrFreeCaptureBuffer(CaptureBuffer);
return GetAliasesExesRequest->Length;
}
/*
* @implemented
*/
@@ -475,49 +526,8 @@ WINAPI
GetConsoleAliasExesW(LPWSTR lpExeNameBuffer,
DWORD ExeNameBufferLength)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETALIASESEXES GetAliasesExesRequest = &ApiMessage.Data.GetAliasesExesRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
DPRINT("GetConsoleAliasExesW entered\n");
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(1, ExeNameBufferLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
GetAliasesExesRequest->Length = ExeNameBufferLength;
/* Allocate space for the exe name buffer */
CsrAllocateMessagePointer(CaptureBuffer,
ExeNameBufferLength,
(PVOID*)&GetAliasesExesRequest->ExeNames);
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliasExes),
sizeof(CONSOLE_GETALIASESEXES));
if (!NT_SUCCESS(Status))
{
CsrFreeCaptureBuffer(CaptureBuffer);
BaseSetLastNTError(Status);
return 0;
}
/* Copy the returned target string into the user buffer */
memcpy(lpExeNameBuffer,
GetAliasesExesRequest->ExeNames,
GetAliasesExesRequest->Length);
/* Release the capture buffer and exit */
CsrFreeCaptureBuffer(CaptureBuffer);
return GetAliasesExesRequest->Length;
DPRINT1("GetConsoleAliasExesW called\n");
return IntGetConsoleAliasExes(lpExeNameBuffer, ExeNameBufferLength, TRUE);
}
@@ -529,46 +539,27 @@ WINAPI
GetConsoleAliasExesA(LPSTR lpExeNameBuffer,
DWORD ExeNameBufferLength)
{
LPWSTR lpwExeNameBuffer;
DWORD dwResult;
DPRINT("GetConsoleAliasExesA entered\n");
lpwExeNameBuffer = HeapAlloc(GetProcessHeap(), 0, ExeNameBufferLength * sizeof(WCHAR));
dwResult = GetConsoleAliasExesW(lpwExeNameBuffer, ExeNameBufferLength * sizeof(WCHAR));
if (dwResult)
dwResult = WideCharToMultiByte(CP_ACP, 0, lpwExeNameBuffer, dwResult / sizeof(WCHAR), lpExeNameBuffer, ExeNameBufferLength, NULL, NULL);
HeapFree(GetProcessHeap(), 0, lpwExeNameBuffer);
return dwResult;
DPRINT1("GetConsoleAliasExesA called\n");
return IntGetConsoleAliasExes(lpExeNameBuffer, ExeNameBufferLength, FALSE);
}
/*
* @implemented
*/
DWORD
WINAPI
GetConsoleAliasExesLengthW(VOID)
static DWORD
IntGetConsoleAliasExesLength(BOOLEAN bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETALIASESEXESLENGTH GetAliasesExesLengthRequest = &ApiMessage.Data.GetAliasesExesLengthRequest;
DPRINT("GetConsoleAliasExesLengthW entered\n");
GetAliasesExesLengthRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetAliasesExesLengthRequest->Unicode = bUnicode;
GetAliasesExesLengthRequest->Length = 0;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliasExesLength),
sizeof(CONSOLE_GETALIASESEXESLENGTH));
if (!NT_SUCCESS(Status))
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliasExesLength),
sizeof(*GetAliasesExesLengthRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(Status);
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
@@ -576,6 +567,18 @@ GetConsoleAliasExesLengthW(VOID)
}
/*
* @implemented
*/
DWORD
WINAPI
GetConsoleAliasExesLengthW(VOID)
{
DPRINT1("GetConsoleAliasExesLengthW called\n");
return IntGetConsoleAliasExesLength(TRUE);
}
/*
* @implemented
*/
@@ -583,16 +586,8 @@ DWORD
WINAPI
GetConsoleAliasExesLengthA(VOID)
{
DWORD dwLength;
DPRINT("GetConsoleAliasExesLengthA entered\n");
dwLength = GetConsoleAliasExesLengthW();
if (dwLength)
dwLength /= sizeof(WCHAR);
return dwLength;
DPRINT1("GetConsoleAliasExesLengthA called\n");
return IntGetConsoleAliasExesLength(FALSE);
}
/* EOF */
@@ -1392,15 +1392,29 @@ SetConsoleCursorInfo(HANDLE hConsoleOutput,
/*--------------------------------------------------------------
* GetNumberOfConsoleMouseButtons
*
* @unimplemented
* @implemented
*/
BOOL
WINAPI
GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
{
DPRINT1("GetNumberOfConsoleMouseButtons(0x%p) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETMOUSEINFO GetMouseInfoRequest = &ApiMessage.Data.GetMouseInfoRequest;
GetMouseInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMouseInfo),
sizeof(*GetMouseInfoRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(ApiMessage.Status);
return FALSE;
}
*lpNumberOfMouseButtons = GetMouseInfoRequest->NumButtons;
return TRUE;
}
@@ -1496,18 +1510,17 @@ SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
static
BOOL
IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
const SMALL_RECT *lpScrollRectangle,
const SMALL_RECT *lpClipRectangle,
CONST SMALL_RECT* lpScrollRectangle,
CONST SMALL_RECT* lpClipRectangle,
COORD dwDestinationOrigin,
const CHAR_INFO *lpFill,
CONST CHAR_INFO* lpFill,
BOOL bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest;
ScrollScreenBufferRequest->OutputHandle = hConsoleOutput;
ScrollScreenBufferRequest->Unicode = bUnicode;
ScrollScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
ScrollScreenBufferRequest->OutputHandle = hConsoleOutput;
ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
if (lpClipRectangle != NULL)
@@ -1521,16 +1534,16 @@ IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
}
ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin;
ScrollScreenBufferRequest->Fill = *lpFill;
ScrollScreenBufferRequest->Fill = *lpFill;
ScrollScreenBufferRequest->Unicode = bUnicode;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
sizeof(CONSOLE_SCROLLSCREENBUFFER));
if (!NT_SUCCESS(Status))
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
sizeof(*ScrollScreenBufferRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(Status);
BaseSetLastNTError(ApiMessage.Status);
return FALSE;
}
@@ -1546,16 +1559,16 @@ IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
BOOL
WINAPI
ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
CONST SMALL_RECT *lpScrollRectangle,
CONST SMALL_RECT *lpClipRectangle,
CONST SMALL_RECT* lpScrollRectangle,
CONST SMALL_RECT* lpClipRectangle,
COORD dwDestinationOrigin,
CONST CHAR_INFO *lpFill)
CONST CHAR_INFO* lpFill)
{
return IntScrollConsoleScreenBuffer(hConsoleOutput,
(PSMALL_RECT)lpScrollRectangle,
(PSMALL_RECT)lpClipRectangle,
lpScrollRectangle,
lpClipRectangle,
dwDestinationOrigin,
(PCHAR_INFO)lpFill,
lpFill,
FALSE);
}
@@ -1868,14 +1881,16 @@ GetConsoleTitleA(LPSTR lpConsoleTitle,
static BOOL
IntSetConsoleTitle(CONST VOID *lpConsoleTitle, DWORD dwNumChars, BOOLEAN bUnicode)
IntSetConsoleTitle(CONST VOID *lpConsoleTitle, BOOLEAN bUnicode)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
ULONG NumChars = (ULONG)(lpConsoleTitle ? (bUnicode ? wcslen(lpConsoleTitle) : strlen(lpConsoleTitle)) : 0);
TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
TitleRequest->Length = dwNumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
TitleRequest->Length = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
TitleRequest->Unicode = bUnicode;
CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
@@ -1916,7 +1931,7 @@ BOOL
WINAPI
SetConsoleTitleW(LPCWSTR lpConsoleTitle)
{
return IntSetConsoleTitle(lpConsoleTitle, wcslen(lpConsoleTitle), TRUE);
return IntSetConsoleTitle(lpConsoleTitle, TRUE);
}
@@ -1929,7 +1944,7 @@ BOOL
WINAPI
SetConsoleTitleA(LPCSTR lpConsoleTitle)
{
return IntSetConsoleTitle(lpConsoleTitle, strlen(lpConsoleTitle), FALSE);
return IntSetConsoleTitle(lpConsoleTitle, FALSE);
}
@@ -2522,14 +2537,6 @@ GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
return FALSE;
}
BOOL
WINAPI
GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
{
STUB;
return FALSE;
}
BOOL
WINAPI
SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
@@ -2540,7 +2547,7 @@ SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
BOOL
WINAPI
SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
{
STUB;
return FALSE;
@@ -2554,6 +2561,14 @@ SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
return FALSE;
}
BOOL
WINAPI
SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
{
STUB;
return FALSE;
}
BOOL
WINAPI
RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId)
@@ -16,13 +16,14 @@
/* PRIVATE FUNCTIONS **********************************************************/
#if 0
/* Get the size needed to copy a string to a capture buffer, including alignment */
static ULONG
IntStringSize(LPCVOID String,
BOOL Unicode)
{
ULONG Size = (Unicode ? wcslen(String) : strlen(String)) * sizeof(WCHAR);
return (Size + 3) & -4;
return (Size + 3) & ~3;
}
@@ -48,67 +49,81 @@ IntCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer,
}
RequestString->Length = RequestString->MaximumLength = (USHORT)Size;
}
#endif
static BOOL
IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOL bUnicode)
static VOID
IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOLEAN bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest = &ApiMessage.Data.ExpungeCommandHistoryRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
return;
}
CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
ExpungeCommandHistoryRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
ExpungeCommandHistoryRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
ExpungeCommandHistoryRequest->Unicode =
ExpungeCommandHistoryRequest->Unicode2 = bUnicode;
// CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
CaptureBuffer = CsrAllocateCaptureBuffer(1, ExpungeCommandHistoryRequest->ExeLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
return;
}
IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
&ExpungeCommandHistoryRequest->ExeName);
// IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
// &ExpungeCommandHistoryRequest->ExeName);
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
ExpungeCommandHistoryRequest->ExeLength,
(PVOID)&ExpungeCommandHistoryRequest->ExeName);
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepExpungeCommandHistory),
sizeof(CONSOLE_EXPUNGECOMMANDHISTORY));
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepExpungeCommandHistory),
sizeof(*ExpungeCommandHistoryRequest));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
return TRUE;
if (!NT_SUCCESS(ApiMessage.Status))
BaseSetLastNTError(ApiMessage.Status);
}
static DWORD
IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName, BOOL bUnicode)
IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName, BOOLEAN bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest = &ApiMessage.Data.GetCommandHistoryRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
DWORD HistoryLength = cbHistory * (bUnicode ? 1 : sizeof(WCHAR));
if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
CaptureBuffer = CsrAllocateCaptureBuffer(2, IntStringSize(lpExeName, bUnicode) +
HistoryLength);
GetCommandHistoryRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetCommandHistoryRequest->HistoryLength = cbHistory;
GetCommandHistoryRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
GetCommandHistoryRequest->Unicode =
GetCommandHistoryRequest->Unicode2 = bUnicode;
// CaptureBuffer = CsrAllocateCaptureBuffer(2, IntStringSize(lpExeName, bUnicode) +
// HistoryLength);
CaptureBuffer = CsrAllocateCaptureBuffer(2, GetCommandHistoryRequest->ExeLength +
GetCommandHistoryRequest->HistoryLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
@@ -116,60 +131,60 @@ IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName
return 0;
}
IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
&GetCommandHistoryRequest->ExeName);
GetCommandHistoryRequest->Length = HistoryLength;
CsrAllocateMessagePointer(CaptureBuffer, HistoryLength,
// IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
// &GetCommandHistoryRequest->ExeName);
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
GetCommandHistoryRequest->ExeLength,
(PVOID)&GetCommandHistoryRequest->ExeName);
// CsrAllocateMessagePointer(CaptureBuffer, HistoryLength,
CsrAllocateMessagePointer(CaptureBuffer, GetCommandHistoryRequest->HistoryLength,
(PVOID*)&GetCommandHistoryRequest->History);
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCommandHistory),
sizeof(CONSOLE_GETCOMMANDHISTORY));
if (!NT_SUCCESS(Status))
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCommandHistory),
sizeof(*GetCommandHistoryRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
CsrFreeCaptureBuffer(CaptureBuffer);
BaseSetLastNTError(Status);
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
if (bUnicode)
{
memcpy(lpHistory,
GetCommandHistoryRequest->History,
GetCommandHistoryRequest->Length);
}
else
{
WideCharToMultiByte(CP_ACP, 0,
GetCommandHistoryRequest->History,
GetCommandHistoryRequest->Length / sizeof(WCHAR),
lpHistory,
cbHistory,
NULL, NULL);
}
RtlCopyMemory(lpHistory,
GetCommandHistoryRequest->History,
GetCommandHistoryRequest->HistoryLength);
CsrFreeCaptureBuffer(CaptureBuffer);
return GetCommandHistoryRequest->Length;
return GetCommandHistoryRequest->HistoryLength;
}
static DWORD
IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest = &ApiMessage.Data.GetCommandHistoryLengthRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
GetCommandHistoryLengthRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetCommandHistoryLengthRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
GetCommandHistoryLengthRequest->Unicode =
GetCommandHistoryLengthRequest->Unicode2 = bUnicode;
// CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
CaptureBuffer = CsrAllocateCaptureBuffer(1, GetCommandHistoryLengthRequest->ExeLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
@@ -177,43 +192,55 @@ IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode)
return 0;
}
IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
&GetCommandHistoryLengthRequest->ExeName);
// IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
// &GetCommandHistoryLengthRequest->ExeName);
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
GetCommandHistoryLengthRequest->ExeLength,
(PVOID)&GetCommandHistoryLengthRequest->ExeName);
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCommandHistoryLength),
sizeof(CONSOLE_GETCOMMANDHISTORYLENGTH));
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCommandHistoryLength),
sizeof(*GetCommandHistoryLengthRequest));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(Status);
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
return GetCommandHistoryLengthRequest->Length;
return GetCommandHistoryLengthRequest->HistoryLength;
}
static BOOL
IntSetConsoleNumberOfCommands(DWORD dwNumCommands,
LPCVOID lpExeName,
BOOL bUnicode)
BOOLEAN bUnicode)
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest = &ApiMessage.Data.SetHistoryNumberCommandsRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
SetHistoryNumberCommandsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
SetHistoryNumberCommandsRequest->NumCommands = dwNumCommands;
SetHistoryNumberCommandsRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
SetHistoryNumberCommandsRequest->Unicode =
SetHistoryNumberCommandsRequest->Unicode2 = bUnicode;
// CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
CaptureBuffer = CsrAllocateCaptureBuffer(1, SetHistoryNumberCommandsRequest->ExeLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
@@ -221,20 +248,23 @@ IntSetConsoleNumberOfCommands(DWORD dwNumCommands,
return FALSE;
}
IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
&SetHistoryNumberCommandsRequest->ExeName);
SetHistoryNumberCommandsRequest->NumCommands = dwNumCommands;
// IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
// &SetHistoryNumberCommandsRequest->ExeName);
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
SetHistoryNumberCommandsRequest->ExeLength,
(PVOID)&SetHistoryNumberCommandsRequest->ExeName);
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetNumberOfCommands),
sizeof(CONSOLE_SETHISTORYNUMBERCOMMANDS));
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetNumberOfCommands),
sizeof(*SetHistoryNumberCommandsRequest));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(Status);
BaseSetLastNTError(ApiMessage.Status);
return FALSE;
}
@@ -247,22 +277,22 @@ IntSetConsoleNumberOfCommands(DWORD dwNumCommands,
/*
* @implemented (Undocumented)
*/
BOOL
VOID
WINAPI
ExpungeConsoleCommandHistoryW(LPCWSTR lpExeName)
{
return IntExpungeConsoleCommandHistory(lpExeName, TRUE);
IntExpungeConsoleCommandHistory(lpExeName, TRUE);
}
/*
* @implemented (Undocumented)
*/
BOOL
VOID
WINAPI
ExpungeConsoleCommandHistoryA(LPCSTR lpExeName)
{
return IntExpungeConsoleCommandHistory(lpExeName, FALSE);
IntExpungeConsoleCommandHistory(lpExeName, FALSE);
}
@@ -310,7 +340,7 @@ DWORD
WINAPI
GetConsoleCommandHistoryLengthA(LPCSTR lpExeName)
{
return IntGetConsoleCommandHistoryLength(lpExeName, FALSE) / sizeof(WCHAR);
return IntGetConsoleCommandHistoryLength(lpExeName, FALSE);
}
@@ -320,7 +350,7 @@ GetConsoleCommandHistoryLengthA(LPCSTR lpExeName)
BOOL
WINAPI
SetConsoleNumberOfCommandsW(DWORD dwNumCommands,
LPCSTR lpExeName)
LPCWSTR lpExeName)
{
return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, TRUE);
}
@@ -332,21 +362,36 @@ SetConsoleNumberOfCommandsW(DWORD dwNumCommands,
BOOL
WINAPI
SetConsoleNumberOfCommandsA(DWORD dwNumCommands,
LPCWSTR lpExeName)
LPCSTR lpExeName)
{
return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, FALSE);
}
/*
* @unimplemented
* @implemented
*/
BOOL
WINAPI
SetConsoleCommandHistoryMode(IN DWORD dwMode)
{
STUB;
return FALSE;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_SETHISTORYMODE SetHistoryModeRequest = &ApiMessage.Data.SetHistoryModeRequest;
SetHistoryModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
SetHistoryModeRequest->Mode = dwMode;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCommandHistoryMode),
sizeof(*SetHistoryModeRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(ApiMessage.Status);
return FALSE;
}
return TRUE;
}
/* EOF */
File diff suppressed because it is too large Load Diff
@@ -16,7 +16,6 @@
/* PRIVATE FUNCTIONS **********************************************************/
HANDLE
FASTCALL
TranslateStdHandle(IN HANDLE hHandle)
{
PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
+1 -1
View File
@@ -56,7 +56,7 @@ CloseConsoleHandle(HANDLE Handle);
HANDLE WINAPI
GetConsoleInputWaitHandle(VOID);
HANDLE FASTCALL
HANDLE
TranslateStdHandle(HANDLE hHandle);
VOID
+16 -10
View File
@@ -36,27 +36,33 @@ ULONG
NTAPI
CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
IN ULONG MessageLength,
OUT PVOID *CapturedData);
OUT PVOID* CapturedData);
VOID
NTAPI
CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
IN PVOID MessageBuffer OPTIONAL,
IN ULONG MessageLength,
OUT PVOID *CapturedData);
VOID
NTAPI
CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
IN LPSTR String OPTIONAL,
IN ULONG StringLength,
IN ULONG MaximumLength,
OUT PANSI_STRING CapturedString);
OUT PVOID* CapturedData);
VOID
NTAPI
CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer);
VOID
NTAPI
CsrCaptureMessageString(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer,
IN PCSTR String OPTIONAL,
IN ULONG StringLength,
IN ULONG MaximumLength,
OUT PSTRING CapturedString);
NTSTATUS
NTAPI
CsrCaptureMessageMultiUnicodeStringsInPlace(OUT PCSR_CAPTURE_BUFFER* CaptureBuffer,
IN ULONG StringsCount,
IN PUNICODE_STRING* MessageStrings);
PLARGE_INTEGER
NTAPI
CsrCaptureTimeout(IN ULONG Milliseconds,
+171 -129
View File
@@ -218,30 +218,40 @@ typedef struct
typedef struct
{
HANDLE ConsoleHandle;
HANDLE OutputHandle;
BOOL Unicode;
ULONG NrCharactersToWrite;
ULONG NrCharactersWritten;
CHAR StaticBuffer[80];
PVOID Buffer; // BufPtr
ULONG NumBytes;
ULONG BufferSize;
PVOID Buffer;
// On Windows, the client never uses this member
ULONG Reserved1;
BOOLEAN UsingStaticBuffer;
BOOLEAN Unicode;
// On Windows, the client never uses this member
CHAR Reserved2[6];
} CONSOLE_WRITECONSOLE, *PCONSOLE_WRITECONSOLE;
typedef struct
{
HANDLE ConsoleHandle;
HANDLE InputHandle;
BOOL Unicode;
ULONG NrCharactersToRead;
ULONG NrCharactersRead;
USHORT ExeLength;
UNICODE_STRING ExeName;
DWORD CtrlWakeupMask;
DWORD ControlKeyState;
CHAR StaticBuffer[80];
PVOID Buffer; // BufPtr
ULONG NumBytes;
ULONG BufferSize;
PVOID Buffer;
ULONG CaptureBufferSize;
ULONG InitialNumBytes;
ULONG CtrlWakeupMask;
ULONG ControlKeyState;
BOOLEAN Unicode;
} CONSOLE_READCONSOLE, *PCONSOLE_READCONSOLE;
typedef struct
@@ -319,6 +329,12 @@ typedef struct
*/
} CONSOLE_GETSETCURSORINFO, *PCONSOLE_GETSETCURSORINFO;
typedef struct
{
HANDLE ConsoleHandle;
ULONG NumButtons;
} CONSOLE_GETMOUSEINFO, *PCONSOLE_GETMOUSEINFO;
typedef struct
{
HANDLE ConsoleHandle;
@@ -370,7 +386,8 @@ typedef struct
DWORD DesiredAccess;
BOOL InheritHandle;
DWORD ShareMode;
DWORD ScreenBufferType; /* Type of the screen buffer: CONSOLE_TEXTMODE_BUFFER or CONSOLE_GRAPHICS_BUFFER */
/* Type of the screen buffer: CONSOLE_TEXTMODE_BUFFER or CONSOLE_GRAPHICS_BUFFER */
DWORD ScreenBufferType;
/*
* This structure holds the initialization information
* for graphics screen buffers.
@@ -405,22 +422,11 @@ typedef struct
typedef struct
{
HANDLE ConsoleHandle;
DWORD Length;
ULONG Length;
PVOID Title;
BOOLEAN Unicode;
} CONSOLE_GETSETCONSOLETITLE, *PCONSOLE_GETSETCONSOLETITLE;
typedef struct
{
HANDLE OutputHandle;
BOOL Unicode;
COORD BufferSize;
COORD BufferCoord;
SMALL_RECT WriteRegion;
PCHAR_INFO CharInfo;
} CONSOLE_WRITEOUTPUT, *PCONSOLE_WRITEOUTPUT;
typedef struct
{
HANDLE ConsoleHandle;
@@ -429,14 +435,14 @@ typedef struct
typedef struct
{
HANDLE OutputHandle;
BOOL Unicode;
HANDLE ConsoleHandle;
HANDLE OutputHandle;
SMALL_RECT ScrollRectangle;
BOOL UseClipRectangle;
SMALL_RECT ClipRectangle;
COORD DestinationOrigin;
CHAR_INFO Fill;
BOOL UseClipRectangle;
COORD DestinationOrigin;
CHAR_INFO Fill;
BOOLEAN Unicode;
} CONSOLE_SCROLLSCREENBUFFER, *PCONSOLE_SCROLLSCREENBUFFER;
@@ -452,100 +458,99 @@ typedef enum _CODE_TYPE
CODE_ATTRIBUTE = 0x03
} CODE_TYPE;
typedef struct
typedef union _CODE_ELEMENT
{
HANDLE OutputHandle;
DWORD NumCodesToRead;
COORD ReadCoord;
COORD EndCoord;
DWORD CodesRead;
CODE_TYPE CodeType;
union
{
PVOID pCode;
PCHAR AsciiChar;
PWCHAR UnicodeChar;
PWORD Attribute;
} pCode; // Either a pointer to a character or to an attribute.
} CONSOLE_READOUTPUTCODE, *PCONSOLE_READOUTPUTCODE;
CHAR AsciiChar;
WCHAR UnicodeChar;
WORD Attribute;
} CODE_ELEMENT;
typedef struct
{
HANDLE ConsoleHandle;
HANDLE OutputHandle;
ULONG BufferSize; // Seems unusued
WORD Length;
COORD Coord;
COORD EndCoord;
ULONG NrCharactersWritten; // Seems unusued
COORD Coord;
CODE_TYPE CodeType;
union
{
PVOID pCode;
PCHAR AsciiChar;
PWCHAR UnicodeChar;
PWORD Attribute;
} pCode; // Either a pointer to a character or to an attribute.
} CONSOLE_WRITEOUTPUTCODE, *PCONSOLE_WRITEOUTPUTCODE;
CHAR CodeStaticBuffer[80]; // == 40 * sizeof(CODE_ELEMENT)
PVOID pCode; // Either a pointer to a character or to an attribute.
// union
// {
// PVOID pCode;
// PCHAR AsciiChar;
// PWCHAR UnicodeChar;
// PWORD Attribute;
// } pCode; // Either a pointer to a character or to an attribute.
ULONG NumCodes;
} CONSOLE_READOUTPUTCODE , *PCONSOLE_READOUTPUTCODE,
CONSOLE_WRITEOUTPUTCODE, *PCONSOLE_WRITEOUTPUTCODE;
typedef struct
{
HANDLE ConsoleHandle;
HANDLE OutputHandle;
COORD WriteCoord;
CODE_TYPE CodeType;
union
{
CHAR AsciiChar;
WCHAR UnicodeChar;
WORD Attribute;
} Code; // Either a character or an attribute.
CODE_TYPE CodeType;
CODE_ELEMENT Code; // Either a character or an attribute.
COORD Coord;
ULONG Length;
ULONG NrCharactersWritten; // FIXME: Only for chars, is it removable ?
ULONG NumCodes;
} CONSOLE_FILLOUTPUTCODE, *PCONSOLE_FILLOUTPUTCODE;
typedef struct
{
HANDLE InputHandle;
ULONG InputsRead;
PINPUT_RECORD InputRecord;
ULONG Length;
WORD wFlags;
BOOLEAN Unicode;
HANDLE ConsoleHandle;
HANDLE InputHandle;
INPUT_RECORD RecordStaticBuffer[5];
PINPUT_RECORD RecordBufPtr;
ULONG NumRecords;
WORD Flags;
BOOLEAN Unicode;
} CONSOLE_GETINPUT, *PCONSOLE_GETINPUT;
typedef struct
{
HANDLE OutputHandle;
BOOL Unicode;
COORD BufferSize;
COORD BufferCoord;
SMALL_RECT ReadRegion;
PCHAR_INFO CharInfo;
} CONSOLE_READOUTPUT, *PCONSOLE_READOUTPUT;
typedef struct
{
HANDLE InputHandle;
DWORD Length;
INPUT_RECORD* InputRecord;
BOOL Unicode;
BOOL AppendToEnd;
HANDLE ConsoleHandle;
HANDLE InputHandle;
INPUT_RECORD RecordStaticBuffer[5];
PINPUT_RECORD RecordBufPtr;
ULONG NumRecords;
BOOLEAN Unicode;
BOOLEAN AppendToEnd;
} CONSOLE_WRITEINPUT, *PCONSOLE_WRITEINPUT;
typedef struct
{
HANDLE ConsoleHandle;
HANDLE OutputHandle;
CHAR_INFO StaticBuffer;
PCHAR_INFO CharInfo;
SMALL_RECT ReadRegion;
BOOLEAN Unicode;
} CONSOLE_READOUTPUT, *PCONSOLE_READOUTPUT;
typedef struct
{
HANDLE ConsoleHandle;
HANDLE OutputHandle;
CHAR_INFO StaticBuffer;
PCHAR_INFO CharInfo;
SMALL_RECT WriteRegion;
BOOLEAN Unicode;
ULONG Unknown;
} CONSOLE_WRITEOUTPUT, *PCONSOLE_WRITEOUTPUT;
typedef struct
{
HANDLE ConsoleHandle;
HANDLE InputHandle;
DWORD NumberOfEvents;
ULONG NumberOfEvents;
} CONSOLE_GETNUMINPUTEVENTS, *PCONSOLE_GETNUMINPUTEVENTS;
@@ -656,66 +661,85 @@ typedef struct
typedef struct
{
ULONG SourceLength;
ULONG TargetLength; // Also used for storing the number of bytes written.
ULONG ExeLength;
LPWSTR Source;
LPWSTR Target;
LPWSTR Exe;
HANDLE ConsoleHandle;
USHORT SourceLength;
USHORT TargetLength; // Also used for storing the number of bytes written.
USHORT ExeLength;
PVOID Source;
PVOID Target;
PVOID ExeName;
BOOLEAN Unicode;
BOOLEAN Unicode2;
} CONSOLE_ADDGETALIAS, *PCONSOLE_ADDGETALIAS;
typedef struct
{
DWORD ExeLength;
DWORD AliasesBufferLength;
LPWSTR ExeName;
LPWSTR AliasesBuffer;
HANDLE ConsoleHandle;
USHORT ExeLength;
PVOID ExeName;
BOOLEAN Unicode;
BOOLEAN Unicode2;
ULONG AliasesBufferLength;
PVOID AliasesBuffer;
} CONSOLE_GETALLALIASES, *PCONSOLE_GETALLALIASES;
typedef struct
{
DWORD Length;
DWORD ExeLength;
LPWSTR ExeName;
HANDLE ConsoleHandle;
USHORT ExeLength;
PVOID ExeName;
ULONG Length;
BOOLEAN Unicode;
BOOLEAN Unicode2;
} CONSOLE_GETALLALIASESLENGTH, *PCONSOLE_GETALLALIASESLENGTH;
typedef struct
{
DWORD Length;
LPWSTR ExeNames;
HANDLE ConsoleHandle;
ULONG Length ; // ExeLength; // ExesLength
PVOID ExeNames;
BOOLEAN Unicode;
} CONSOLE_GETALIASESEXES, *PCONSOLE_GETALIASESEXES;
typedef struct
{
DWORD Length;
HANDLE ConsoleHandle;
ULONG Length;
BOOLEAN Unicode;
} CONSOLE_GETALIASESEXESLENGTH, *PCONSOLE_GETALIASESEXESLENGTH;
typedef struct
{
UNICODE_STRING ExeName;
PWCHAR History;
DWORD Length;
HANDLE ConsoleHandle;
ULONG HistoryLength;
PVOID History;
USHORT ExeLength;
PVOID ExeName;
BOOLEAN Unicode;
BOOLEAN Unicode2;
} CONSOLE_GETCOMMANDHISTORY, *PCONSOLE_GETCOMMANDHISTORY;
typedef struct
{
UNICODE_STRING ExeName;
DWORD Length;
HANDLE ConsoleHandle;
ULONG HistoryLength;
USHORT ExeLength;
PVOID ExeName;
BOOLEAN Unicode;
BOOLEAN Unicode2;
} CONSOLE_GETCOMMANDHISTORYLENGTH, *PCONSOLE_GETCOMMANDHISTORYLENGTH;
typedef struct
{
UNICODE_STRING ExeName;
HANDLE ConsoleHandle;
USHORT ExeLength;
PVOID ExeName;
BOOLEAN Unicode;
BOOLEAN Unicode2;
} CONSOLE_EXPUNGECOMMANDHISTORY, *PCONSOLE_EXPUNGECOMMANDHISTORY;
typedef struct
{
UNICODE_STRING ExeName;
DWORD NumCommands;
} CONSOLE_SETHISTORYNUMBERCOMMANDS, *PCONSOLE_SETHISTORYNUMBERCOMMANDS;
typedef struct
{
UINT HistoryBufferSize;
@@ -723,6 +747,22 @@ typedef struct
DWORD dwFlags;
} CONSOLE_GETSETHISTORYINFO, *PCONSOLE_GETSETHISTORYINFO;
typedef struct
{
HANDLE ConsoleHandle;
ULONG NumCommands;
USHORT ExeLength;
PVOID ExeName;
BOOLEAN Unicode;
BOOLEAN Unicode2;
} CONSOLE_SETHISTORYNUMBERCOMMANDS, *PCONSOLE_SETHISTORYNUMBERCOMMANDS;
typedef struct
{
HANDLE ConsoleHandle;
ULONG Mode;
} CONSOLE_SETHISTORYMODE, *PCONSOLE_SETHISTORYMODE;
typedef struct
@@ -781,11 +821,12 @@ typedef struct _CONSOLE_API_MESSAGE
CONSOLE_GETHANDLEINFO GetHandleInfoRequest;
CONSOLE_SETHANDLEINFO SetHandleInfoRequest;
/* Cursor */
/* Cursor & Mouse */
CONSOLE_SHOWCURSOR ShowCursorRequest;
CONSOLE_SETCURSOR SetCursorRequest;
CONSOLE_GETSETCURSORINFO CursorInfoRequest;
CONSOLE_SETCURSORPOSITION SetCursorPositionRequest;
CONSOLE_GETMOUSEINFO GetMouseInfoRequest;
/* Screen-buffer */
CONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest;
@@ -841,8 +882,9 @@ typedef struct _CONSOLE_API_MESSAGE
CONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest;
CONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest;
CONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest;
CONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest;
CONSOLE_GETSETHISTORYINFO HistoryInfoRequest;
CONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest;
CONSOLE_SETHISTORYMODE SetHistoryModeRequest;
/* Input and Output Code Pages */
CONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest;
+2 -1
View File
@@ -18,10 +18,11 @@ list(APPEND CONSRV_SOURCE
consrv/condrv/coninput.c
consrv/condrv/conoutput.c
consrv/condrv/console.c
consrv/condrv/dummyfrontend.c
consrv/condrv/dummyterm.c
consrv/condrv/graphics.c
consrv/condrv/text.c
consrv/frontends/input.c
consrv/frontends/terminal.c
consrv/frontends/gui/conwnd.c
consrv/frontends/gui/fullscreen.c
consrv/frontends/gui/guiterm.c
File diff suppressed because it is too large Load Diff
@@ -16,21 +16,19 @@
/* GLOBALS ********************************************************************/
#define ConSrvGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \
(Access), (LockConsole), INPUT_BUFFER)
#define ConSrvGetInputBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \
(Access), (LockConsole), INPUT_BUFFER)
#define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked) \
ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked))
/*
* From MSDN:
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
* If they are the same, the function fails, and GetLastError returns
* ERROR_INVALID_PARAMETER."
*/
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
WideCharToMultiByte((Console)->InputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
MultiByteToWideChar((Console)->InputCodePage, 0, (sChar), 1, (dWChar), 1)
typedef struct ConsoleInput_t
{
@@ -41,7 +39,7 @@ typedef struct ConsoleInput_t
/* PRIVATE FUNCTIONS **********************************************************/
static VOID FASTCALL
static VOID
ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
{
if (InputEvent->EventType == KEY_EVENT)
@@ -54,7 +52,7 @@ ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
}
}
static VOID FASTCALL
static VOID
ConioInputEventToUnicode(PCONSOLE Console, PINPUT_RECORD InputEvent)
{
if (InputEvent->EventType == KEY_EVENT)
@@ -67,78 +65,214 @@ ConioInputEventToUnicode(PCONSOLE Console, PINPUT_RECORD InputEvent)
}
}
NTSTATUS FASTCALL
ConioAddInputEvent(PCONSOLE Console,
PINPUT_RECORD InputEvent,
BOOLEAN AppendToEnd)
{
ConsoleInput *ConInRec;
/* Check for pause or unpause */
if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown)
NTSTATUS
ConDrvAddInputEvents(PCONSOLE Console,
PINPUT_RECORD InputRecords, // InputEvent
ULONG NumEventsToWrite,
PULONG NumEventsWritten,
BOOLEAN AppendToEnd)
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG i = 0;
BOOLEAN SetWaitEvent = FALSE;
if (NumEventsWritten) *NumEventsWritten = 0;
/*
* When adding many single events, in the case of repeated mouse move or
* key down events, we try to coalesce them so that we do not saturate
* too quickly the input buffer.
*/
if (NumEventsToWrite == 1 && !IsListEmpty(&Console->InputBuffer.InputEvents))
{
WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode;
if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
PINPUT_RECORD InputRecord = InputRecords; // Only one element
PINPUT_RECORD LastInputRecord;
ConsoleInput* ConInRec; // Input
/* Get the "next" event of the input buffer */
if (AppendToEnd)
{
DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState;
if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT &&
(vk == VK_PAUSE || (vk == 'S' &&
(cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
!(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
{
ConioPause(Console, PAUSED_FROM_KEYBOARD);
return STATUS_SUCCESS;
}
/* Get the tail element */
ConInRec = CONTAINING_RECORD(Console->InputBuffer.InputEvents.Blink,
ConsoleInput, ListEntry);
}
else
{
if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
/* Get the head element */
ConInRec = CONTAINING_RECORD(Console->InputBuffer.InputEvents.Flink,
ConsoleInput, ListEntry);
}
LastInputRecord = &ConInRec->InputEvent;
if (InputRecord->EventType == MOUSE_EVENT &&
InputRecord->Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
{
if (LastInputRecord->EventType == MOUSE_EVENT &&
LastInputRecord->Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
{
ConioUnpause(Console, PAUSED_FROM_KEYBOARD);
return STATUS_SUCCESS;
/* Update the mouse position */
LastInputRecord->Event.MouseEvent.dwMousePosition.X =
InputRecord->Event.MouseEvent.dwMousePosition.X;
LastInputRecord->Event.MouseEvent.dwMousePosition.Y =
InputRecord->Event.MouseEvent.dwMousePosition.Y;
i = 1;
// return STATUS_SUCCESS;
Status = STATUS_SUCCESS;
}
}
else if (InputRecord->EventType == KEY_EVENT &&
InputRecord->Event.KeyEvent.bKeyDown)
{
if (LastInputRecord->EventType == KEY_EVENT &&
LastInputRecord->Event.KeyEvent.bKeyDown &&
(LastInputRecord->Event.KeyEvent.wVirtualScanCode == // Same scancode
InputRecord->Event.KeyEvent.wVirtualScanCode) &&
(LastInputRecord->Event.KeyEvent.uChar.UnicodeChar == // Same character
InputRecord->Event.KeyEvent.uChar.UnicodeChar) &&
(LastInputRecord->Event.KeyEvent.dwControlKeyState == // Same Ctrl/Alt/Shift state
InputRecord->Event.KeyEvent.dwControlKeyState) )
{
/* Update the repeat count */
LastInputRecord->Event.KeyEvent.wRepeatCount +=
InputRecord->Event.KeyEvent.wRepeatCount;
i = 1;
// return STATUS_SUCCESS;
Status = STATUS_SUCCESS;
}
}
}
/* Add event to the queue */
ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES;
/* If we coalesced the only one element, we can quit */
if (i == 1 && Status == STATUS_SUCCESS /* && NumEventsToWrite == 1 */)
goto Done;
ConInRec->InputEvent = *InputEvent;
/*
* No event coalesced, add them in the usual way.
*/
if (AppendToEnd)
{
/* Append the event to the end of the queue */
InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
/* Go to the beginning of the list */
// InputRecords = InputRecords;
}
else
{
/* Append the event to the beginning of the queue */
InsertHeadList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
/* Go to the end of the list */
InputRecords = &InputRecords[NumEventsToWrite - 1];
}
SetEvent(Console->InputBuffer.ActiveEvent);
CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue,
FALSE,
NULL,
NULL);
if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue))
/* Set the event if the list is going to be non-empty */
if (IsListEmpty(&Console->InputBuffer.InputEvents))
SetWaitEvent = TRUE;
for (i = 0; i < NumEventsToWrite && NT_SUCCESS(Status); ++i)
{
CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue);
PINPUT_RECORD InputRecord;
ConsoleInput* ConInRec;
if (AppendToEnd)
{
/* Select the event and go to the next one */
InputRecord = InputRecords++;
}
else
{
/* Select the event and go to the previous one */
InputRecord = InputRecords--;
}
/* Add event to the queue */
ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
if (ConInRec == NULL)
{
// return STATUS_INSUFFICIENT_RESOURCES;
Status = STATUS_INSUFFICIENT_RESOURCES;
continue;
}
ConInRec->InputEvent = *InputRecord;
if (AppendToEnd)
{
/* Append the event to the end of the queue */
InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
}
else
{
/* Append the event to the beginning of the queue */
InsertHeadList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
}
// return STATUS_SUCCESS;
Status = STATUS_SUCCESS;
}
return STATUS_SUCCESS;
if (SetWaitEvent) SetEvent(Console->InputBuffer.ActiveEvent);
Done:
if (NumEventsWritten) *NumEventsWritten = i;
return Status;
}
NTSTATUS FASTCALL
ULONG
PreprocessInput(PCONSOLE Console,
PINPUT_RECORD InputEvent,
ULONG NumEventsToWrite);
VOID
PostprocessInput(PCONSOLE Console);
NTSTATUS
ConioAddInputEvents(PCONSOLE Console,
PINPUT_RECORD InputRecords, // InputEvent
ULONG NumEventsToWrite,
PULONG NumEventsWritten,
BOOLEAN AppendToEnd)
{
NTSTATUS Status = STATUS_SUCCESS;
if (NumEventsWritten) *NumEventsWritten = 0;
/*
* This pre-processing code MUST be IN consrv ONLY!!
*/
NumEventsToWrite = PreprocessInput(Console, InputRecords, NumEventsToWrite);
if (NumEventsToWrite == 0) return STATUS_SUCCESS;
Status = ConDrvAddInputEvents(Console,
InputRecords,
NumEventsToWrite,
NumEventsWritten,
AppendToEnd);
/*
* This post-processing code MUST be IN consrv ONLY!!
*/
// if (NT_SUCCESS(Status))
if (Status == STATUS_SUCCESS) PostprocessInput(Console);
return Status;
}
/* Move elsewhere...*/
NTSTATUS
ConioProcessInputEvent(PCONSOLE Console,
PINPUT_RECORD InputEvent)
{
return ConioAddInputEvent(Console, InputEvent, TRUE);
ULONG NumEventsWritten;
return ConioAddInputEvents(Console,
InputEvent,
1,
&NumEventsWritten,
TRUE);
}
VOID FASTCALL
VOID
PurgeInputBuffer(PCONSOLE Console)
{
PLIST_ENTRY CurrentEntry;
@@ -154,88 +288,13 @@ PurgeInputBuffer(PCONSOLE Console)
CloseHandle(Console->InputBuffer.ActiveEvent);
}
/*
* This function explicitely references Console->ActiveBuffer
* (and also makes use of keyboard functions...).
* It is possible that it will move into frontends...
*/
VOID NTAPI
ConDrvProcessKey(IN PCONSOLE Console,
IN BOOLEAN Down,
IN UINT VirtualKeyCode,
IN UINT VirtualScanCode,
IN WCHAR UnicodeChar,
IN ULONG ShiftState,
IN BYTE KeyStateCtrl)
{
INPUT_RECORD er;
/* process Ctrl-C and Ctrl-Break */
if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
(ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) )
{
DPRINT1("Console_Api Ctrl-C\n");
ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
if (Console->LineBuffer && !Console->LineComplete)
{
/* Line input is in progress; end it */
Console->LinePos = Console->LineSize = 0;
Console->LineComplete = TRUE;
}
return;
}
if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
(VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) )
{
if (!Down) return;
/* scroll up or down */
if (VK_UP == VirtualKeyCode)
{
/* only scroll up if there is room to scroll up into */
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y++;
}
}
else
{
/* only scroll down if there is room to scroll down into */
if (Console->ActiveBuffer->CursorPosition.Y != 0)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y--;
}
}
ConioDrawConsole(Console);
return;
}
er.EventType = KEY_EVENT;
er.Event.KeyEvent.bKeyDown = Down;
er.Event.KeyEvent.wRepeatCount = 1;
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState;
ConioProcessInputEvent(Console, &er);
}
/* PUBLIC DRIVER APIS *********************************************************/
NTSTATUS NTAPI
ConDrvReadConsole(IN PCONSOLE Console,
IN PCONSOLE_INPUT_BUFFER InputBuffer,
/**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/
IN BOOLEAN Unicode,
OUT PVOID Buffer,
IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
@@ -256,8 +315,7 @@ ConDrvReadConsole(IN PCONSOLE Console,
/* Validity checks */
ASSERT(Console == InputBuffer->Header.Console);
ASSERT( (Buffer != NULL && NumCharsToRead >= 0) ||
(Buffer == NULL && NumCharsToRead == 0) );
ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
/* We haven't read anything (yet) */
@@ -268,17 +326,15 @@ ConDrvReadConsole(IN PCONSOLE Console,
if (Console->LineBuffer == NULL)
{
/* Starting a new line */
Console->LineMaxSize = (WORD)max(256, NumCharsToRead);
Console->LineMaxSize = max(256, NumCharsToRead);
Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR));
if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;
Console->LineComplete = FALSE;
Console->LineUpPressed = FALSE;
Console->LinePos = Console->LineSize = ReadControl->nInitialChars;
Console->LineComplete = Console->LineUpPressed = FALSE;
Console->LineInsertToggle = Console->InsertMode;
Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
Console->LineSize = ReadControl->nInitialChars;
Console->LinePos = Console->LineSize;
/*
* Pre-filling the buffer is only allowed in the Unicode API,
@@ -307,7 +363,8 @@ ConDrvReadConsole(IN PCONSOLE Console,
if (Input->InputEvent.EventType == KEY_EVENT &&
Input->InputEvent.Event.KeyEvent.bKeyDown)
{
LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent);
LineInputKeyDown(Console, ExeName,
&Input->InputEvent.Event.KeyEvent);
ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
}
ConsoleFreeHeap(Input);
@@ -378,6 +435,7 @@ ConDrvReadConsole(IN PCONSOLE Console,
}
}
// FIXME: Only set if Status == STATUS_SUCCESS ???
if (NumCharsRead) *NumCharsRead = i;
return Status;
@@ -402,11 +460,9 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
/* Validity checks */
ASSERT(Console == InputBuffer->Header.Console);
ASSERT( (InputRecord != NULL && NumEventsToRead >= 0) ||
(InputRecord == NULL && NumEventsToRead == 0) );
ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToRead == 0));
// Do NOT do that !! Use the existing number of events already read, if any...
// if (NumEventsRead) *NumEventsRead = 0;
if (NumEventsRead) *NumEventsRead = 0;
if (IsListEmpty(&InputBuffer->InputEvents))
{
@@ -419,19 +475,13 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
/* Only get input if there is any */
CurrentInput = InputBuffer->InputEvents.Flink;
if (NumEventsRead) i = *NumEventsRead; // We will read the remaining events...
i = 0;
while ((CurrentInput != &InputBuffer->InputEvents) && (i < NumEventsToRead))
{
Input = CONTAINING_RECORD(CurrentInput, ConsoleInput, ListEntry);
*InputRecord = Input->InputEvent;
if (!Unicode)
{
ConioInputEventToAnsi(InputBuffer->Header.Console, InputRecord);
}
++InputRecord;
++i;
CurrentInput = CurrentInput->Flink;
@@ -446,6 +496,15 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
if (NumEventsRead) *NumEventsRead = i;
/* Now translate everything to ANSI */
if (!Unicode)
{
for (; i > 0; --i)
{
ConioInputEventToAnsi(InputBuffer->Header.Console, --InputRecord);
}
}
if (IsListEmpty(&InputBuffer->InputEvents))
{
ResetEvent(InputBuffer->ActiveEvent);
@@ -472,23 +531,26 @@ ConDrvWriteConsoleInput(IN PCONSOLE Console,
/* Validity checks */
ASSERT(Console == InputBuffer->Header.Console);
ASSERT( (InputRecord != NULL && NumEventsToWrite >= 0) ||
(InputRecord == NULL && NumEventsToWrite == 0) );
ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToWrite == 0));
// Do NOT do that !! Use the existing number of events already written, if any...
// if (NumEventsWritten) *NumEventsWritten = 0;
for (i = (NumEventsWritten ? *NumEventsWritten : 0); i < NumEventsToWrite && NT_SUCCESS(Status); ++i)
/* First translate everything to UNICODE */
if (!Unicode)
{
if (!Unicode)
for (i = 0; i < NumEventsToWrite; ++i)
{
ConioInputEventToUnicode(Console, InputRecord);
ConioInputEventToUnicode(Console, &InputRecord[i]);
}
Status = ConioAddInputEvent(Console, InputRecord++, AppendToEnd);
}
if (NumEventsWritten) *NumEventsWritten = i;
/* Now, add the events */
// if (NumEventsWritten) *NumEventsWritten = 0;
// ConDrvAddInputEvents
Status = ConioAddInputEvents(Console,
InputRecord,
NumEventsToWrite,
NumEventsWritten,
AppendToEnd);
// if (NumEventsWritten) *NumEventsWritten = i;
return Status;
}
@@ -34,6 +34,7 @@ GRAPHICS_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer);
NTSTATUS
CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN OUT PCONSOLE Console,
IN PCONSOLE_SCREEN_BUFFER_VTBL Vtbl,
IN SIZE_T Size)
{
if (Buffer == NULL || Console == NULL)
@@ -44,7 +45,7 @@ CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
/* Initialize the header with the default type */
ConSrvInitObject(&(*Buffer)->Header, SCREEN_BUFFER, Console);
(*Buffer)->Vtbl = NULL;
(*Buffer)->Vtbl = Vtbl;
return STATUS_SUCCESS;
}
@@ -74,7 +75,7 @@ CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer)
}
// ConDrvCreateConsoleScreenBuffer
NTSTATUS FASTCALL
NTSTATUS
ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN OUT PCONSOLE Console,
IN ULONG BufferType,
@@ -151,7 +152,7 @@ ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
CONSOLE_SCREEN_BUFFER_Destroy(Buffer);
}
VOID FASTCALL
VOID
ConioDrawConsole(PCONSOLE Console)
{
SMALL_RECT Region;
@@ -159,7 +160,8 @@ ConioDrawConsole(PCONSOLE Console)
if (ActiveBuffer)
{
ConioInitRect(&Region, 0, 0, ActiveBuffer->ViewSize.Y - 1, ActiveBuffer->ViewSize.X - 1);
ConioInitRect(&Region, 0, 0,
ActiveBuffer->ViewSize.Y - 1, ActiveBuffer->ViewSize.X - 1);
TermDrawRegion(Console, &Region);
}
}
@@ -12,20 +12,18 @@
#include <consrv.h>
#include <alias.h>
#include <coninput.h>
#define NDEBUG
#include <debug.h>
// FIXME: Add this prototype to winternl.h / rtlfuncs.h / ...
NTSTATUS NTAPI RtlGetLastNtStatus(VOID);
/* GLOBALS ********************************************************************/
static ULONG ConsoleListSize;
static PCONSOLE* ConsoleList; /* The list of all the allocated consoles */
static ULONG CurrentConsoleID = 0;
/* Linked list of consoles */
static LIST_ENTRY ConsoleList;
static RTL_RESOURCE ListLock;
#define ConDrvLockConsoleListExclusive() \
@@ -37,6 +35,47 @@ static RTL_RESOURCE ListLock;
#define ConDrvUnlockConsoleList() \
RtlReleaseResource(&ListLock)
static NTSTATUS
InsertConsole(IN PCONSOLE Console)
{
ASSERT(Console);
/* All went right, so add the console to the list */
ConDrvLockConsoleListExclusive();
DPRINT1("Insert in the list\n");
InsertTailList(&ConsoleList, &Console->ListEntry);
// FIXME: Move this code to the caller function!!
/* Get a new console ID */
_InterlockedExchange((PLONG)&Console->ConsoleID, CurrentConsoleID);
_InterlockedIncrement((PLONG)&CurrentConsoleID);
/* Unlock the console list and return success */
ConDrvUnlockConsoleList();
return STATUS_SUCCESS;
}
static NTSTATUS
RemoveConsole(IN PCONSOLE Console)
{
// ASSERT(Console);
if (!Console) return STATUS_INVALID_PARAMETER;
/* Remove the console from the list */
ConDrvLockConsoleListExclusive();
RemoveEntryList(&Console->ListEntry);
/* Unlock the console list and return success */
ConDrvUnlockConsoleList();
return STATUS_SUCCESS;
}
/* PRIVATE FUNCTIONS **********************************************************/
// Adapted from reactos/lib/rtl/unicode.c, RtlCreateUnicodeString line 2180
static BOOLEAN
ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest,
@@ -66,219 +105,21 @@ ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
}
}
static NTSTATUS
InsertConsole(OUT PHANDLE Handle,
IN PCONSOLE Console)
VOID NTAPI
ConDrvPause(PCONSOLE Console)
{
#define CONSOLE_HANDLES_INCREMENT 2 * 3
NTSTATUS Status = STATUS_SUCCESS;
ULONG i = 0;
PCONSOLE* Block;
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
(ConsoleList != NULL && ConsoleListSize != 0) );
/* All went right, so add the console to the list */
ConDrvLockConsoleListExclusive();
DPRINT1("Insert in the list\n");
if (ConsoleList)
{
for (i = 0; i < ConsoleListSize; i++)
{
if (ConsoleList[i] == NULL) break;
}
}
if (i >= ConsoleListSize)
{
DPRINT1("Creation of a new handles table\n");
/* Allocate a new handles table */
Block = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
(ConsoleListSize +
CONSOLE_HANDLES_INCREMENT) * sizeof(PCONSOLE));
if (Block == NULL)
{
Status = STATUS_UNSUCCESSFUL;
goto Quit;
}
/* If we previously had a handles table, free it and use the new one */
if (ConsoleList)
{
/* Copy the handles from the old table to the new one */
RtlCopyMemory(Block,
ConsoleList,
ConsoleListSize * sizeof(PCONSOLE));
ConsoleFreeHeap(ConsoleList);
}
ConsoleList = Block;
ConsoleListSize += CONSOLE_HANDLES_INCREMENT;
}
ConsoleList[i] = Console;
*Handle = ULongToHandle((i << 2) | 0x3);
Quit:
/* Unlock the console list and return status */
ConDrvUnlockConsoleList();
return Status;
}
/* Unused */
#if 0
static NTSTATUS
RemoveConsoleByHandle(IN HANDLE Handle)
{
NTSTATUS Status = STATUS_SUCCESS;
PCONSOLE Console;
BOOLEAN ValidHandle = ((HandleToULong(Handle) & 0x3) == 0x3);
ULONG Index = HandleToULong(Handle) >> 2;
if (!ValidHandle) return STATUS_INVALID_HANDLE;
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
(ConsoleList != NULL && ConsoleListSize != 0) );
/* Remove the console from the list */
ConDrvLockConsoleListExclusive();
if (Index >= ConsoleListSize ||
(Console = ConsoleList[Index]) == NULL)
{
Status = STATUS_INVALID_HANDLE;
goto Quit;
}
ConsoleList[Index] = NULL;
Quit:
/* Unlock the console list and return status */
ConDrvUnlockConsoleList();
return Status;
}
#endif
static NTSTATUS
RemoveConsoleByPointer(IN PCONSOLE Console)
{
ULONG i = 0;
if (!Console) return STATUS_INVALID_PARAMETER;
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
(ConsoleList != NULL && ConsoleListSize != 0) );
/* Remove the console from the list */
ConDrvLockConsoleListExclusive();
if (ConsoleList)
{
for (i = 0; i < ConsoleListSize; i++)
{
if (ConsoleList[i] == Console) ConsoleList[i] = NULL;
}
}
/* Unlock the console list */
ConDrvUnlockConsoleList();
return STATUS_SUCCESS;
}
/* For resetting the frontend - defined in dummyfrontend.c */
VOID ResetFrontEnd(IN PCONSOLE Console);
/* PRIVATE FUNCTIONS **********************************************************/
static NTSTATUS
ConDrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
IN PCONSOLE_PROCESS_DATA ProcessData,
IN ULONG Timeout)
{
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("ConDrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
if (ProcessData->CtrlDispatcher)
{
_SEH2_TRY
{
HANDLE Thread = NULL;
_SEH2_TRY
{
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
ProcessData->CtrlDispatcher,
UlongToPtr(CtrlEvent), 0, NULL);
if (NULL == Thread)
{
Status = RtlGetLastNtStatus();
DPRINT1("Failed thread creation, Status = 0x%08lx\n", Status);
}
else
{
DPRINT("ProcessData->CtrlDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
WaitForSingleObject(Thread, Timeout);
}
}
_SEH2_FINALLY
{
CloseHandle(Thread);
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
DPRINT1("ConDrvConsoleCtrlEventTimeout - Caught an exception, Status = 0x%08lx\n", Status);
}
_SEH2_END;
}
return Status;
}
NTSTATUS
ConDrvConsoleCtrlEvent(IN ULONG CtrlEvent,
IN PCONSOLE_PROCESS_DATA ProcessData)
{
return ConDrvConsoleCtrlEventTimeout(CtrlEvent, ProcessData, 0);
}
VOID FASTCALL
ConioPause(PCONSOLE Console, UINT Flags)
{
Console->PauseFlags |= Flags;
if (!Console->UnpauseEvent)
Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
VOID FASTCALL
ConioUnpause(PCONSOLE Console, UINT Flags)
VOID NTAPI
ConDrvUnpause(PCONSOLE Console)
{
Console->PauseFlags &= ~Flags;
// if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
if (Console->PauseFlags == 0 && Console->UnpauseEvent)
if (Console->UnpauseEvent)
{
SetEvent(Console->UnpauseEvent);
CloseHandle(Console->UnpauseEvent);
Console->UnpauseEvent = NULL;
CsrNotifyWait(&Console->WriteWaitQueue,
TRUE,
NULL,
NULL);
if (!IsListEmpty(&Console->WriteWaitQueue))
{
CsrDereferenceWait(&Console->WriteWaitQueue);
}
}
}
@@ -326,103 +167,6 @@ ConDrvValidateConsoleUnsafe(IN PCONSOLE Console,
return TRUE;
}
BOOLEAN NTAPI
ConDrvValidateConsole(OUT PCONSOLE* Console,
IN HANDLE ConsoleHandle,
IN CONSOLE_STATE ExpectedState,
IN BOOLEAN LockConsole)
{
BOOLEAN RetVal = FALSE;
PCONSOLE ValidatedConsole;
BOOLEAN ValidHandle = ((HandleToULong(ConsoleHandle) & 0x3) == 0x3);
ULONG Index = HandleToULong(ConsoleHandle) >> 2;
if (!ValidHandle) return FALSE;
if (!Console) return FALSE;
*Console = NULL;
/*
* Forbid creation or deletion of consoles when
* checking for the existence of a console.
*/
ConDrvLockConsoleListShared();
if (Index >= ConsoleListSize ||
(ValidatedConsole = ConsoleList[Index]) == NULL)
{
/* Unlock the console list */
ConDrvUnlockConsoleList();
return FALSE;
}
ValidatedConsole = ConsoleList[Index];
/* Unlock the console list and return */
ConDrvUnlockConsoleList();
RetVal = ConDrvValidateConsoleUnsafe(ValidatedConsole,
ExpectedState,
LockConsole);
if (RetVal) *Console = ValidatedConsole;
return RetVal;
}
NTSTATUS NTAPI
ConDrvGetConsole(OUT PCONSOLE* Console,
IN HANDLE ConsoleHandle,
IN BOOLEAN LockConsole)
{
NTSTATUS Status = STATUS_INVALID_HANDLE;
PCONSOLE GrabConsole;
if (Console == NULL) return STATUS_INVALID_PARAMETER;
*Console = NULL;
if (ConDrvValidateConsole(&GrabConsole,
ConsoleHandle,
CONSOLE_RUNNING,
LockConsole))
{
InterlockedIncrement(&GrabConsole->ReferenceCount);
*Console = GrabConsole;
Status = STATUS_SUCCESS;
}
return Status;
}
VOID NTAPI
ConDrvReleaseConsole(IN PCONSOLE Console,
IN BOOLEAN WasConsoleLocked)
{
LONG RefCount = 0;
if (!Console) return;
// if (Console->ReferenceCount == 0) return; // This shouldn't happen
ASSERT(Console->ReferenceCount > 0);
/* The console must be locked */
// ASSERT(Console_locked);
/*
* Decrement the reference count. Save the new value too,
* because Console->ReferenceCount might be modified after
* the console gets unlocked but before we check whether we
* can destroy it.
*/
RefCount = _InterlockedDecrement(&Console->ReferenceCount);
/* Unlock the console if needed */
if (WasConsoleLocked) LeaveCriticalSection(&Console->Lock);
/* Delete the console if needed */
if (RefCount <= 0) ConDrvDeleteConsole(Console);
}
/* CONSOLE INITIALIZATION FUNCTIONS *******************************************/
@@ -432,93 +176,44 @@ ConDrvInitConsoleSupport(VOID)
DPRINT("CONSRV: ConDrvInitConsoleSupport()\n");
/* Initialize the console list and its lock */
ConsoleListSize = 0;
ConsoleList = NULL;
InitializeListHead(&ConsoleList);
RtlInitializeResource(&ListLock);
/* Should call LoadKeyboardLayout */
}
/* For resetting the terminal - defined in dummyterm.c */
VOID ResetTerminal(IN PCONSOLE Console);
NTSTATUS NTAPI
ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
OUT PCONSOLE* NewConsole,
IN PCONSOLE_INFO ConsoleInfo,
IN ULONG ConsoleLeaderProcessId)
ConDrvInitConsole(OUT PCONSOLE* NewConsole,
IN PCONSOLE_INFO ConsoleInfo)
{
NTSTATUS Status;
SECURITY_ATTRIBUTES SecurityAttributes;
// CONSOLE_INFO CapturedConsoleInfo;
TEXTMODE_BUFFER_INFO ScreenBufferInfo;
HANDLE ConsoleHandle;
PCONSOLE Console;
PCONSOLE_SCREEN_BUFFER NewBuffer;
// WCHAR DefaultTitle[128];
#if 0
WCHAR DefaultTitle[128];
#endif
if (NewConsoleHandle == NULL || NewConsole == NULL || ConsoleInfo == NULL)
if (NewConsole == NULL || ConsoleInfo == NULL)
return STATUS_INVALID_PARAMETER;
*NewConsoleHandle = NULL;
*NewConsole = NULL;
/*
* Allocate a console structure
* Allocate a new console
*/
Console = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(CONSOLE));
Console = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*Console));
if (NULL == Console)
{
DPRINT1("Not enough memory for console creation.\n");
return STATUS_NO_MEMORY;
}
/*
* Load the console settings
*/
/* 1. Load the default settings */
// ConSrvGetDefaultSettings(ConsoleInfo, ProcessId);
// /* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */
// Length = min(wcslen(ConsoleStartInfo->ConsoleTitle),
// sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1);
// wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length);
// ConsoleInfo.ConsoleTitle[Length] = L'\0';
/*
* 4. Load the remaining console settings via the registry.
*/
#if 0
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
{
/*
* Either we weren't created by an app launched via a shell-link,
* or we failed to load shell-link console properties.
* Therefore, load the console infos for the application from the registry.
*/
ConSrvReadUserSettings(ConsoleInfo, ProcessId);
/*
* Now, update them with the properties the user might gave to us
* via the STARTUPINFO structure before calling CreateProcess
* (and which was transmitted via the ConsoleStartInfo structure).
* We therefore overwrite the values read in the registry.
*/
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
{
ConsoleInfo->ScreenAttrib = (USHORT)ConsoleStartInfo->FillAttribute;
}
if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
{
ConsoleInfo->ScreenBufferSize = ConsoleStartInfo->ScreenBufferSize;
}
if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
{
// ConsoleInfo->ConsoleSize = ConsoleStartInfo->ConsoleWindowSize;
ConsoleInfo->ConsoleSize.X = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cx;
ConsoleInfo->ConsoleSize.Y = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cy;
}
}
#endif
/*
* Fix the screen buffer size if needed. The rule is:
* ScreenBufferSize >= ConsoleSize
@@ -534,16 +229,13 @@ ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
Console->State = CONSOLE_INITIALIZING;
Console->ReferenceCount = 0;
InitializeCriticalSection(&Console->Lock);
InitializeListHead(&Console->ProcessList);
Console->NotifiedLastCloseProcess = NULL;
Console->NotifyLastClose = FALSE;
/* Initialize the frontend interface */
ResetFrontEnd(Console);
/* Initialize the terminal interface */
ResetTerminal(Console);
memcpy(Console->Colors, ConsoleInfo->Colors, sizeof(ConsoleInfo->Colors));
Console->ConsoleSize = ConsoleInfo->ConsoleSize;
Console->FixedSize = FALSE; // Value by default; is reseted by the front-ends if needed.
Console->FixedSize = FALSE; // Value by default; is reseted by the terminals if needed.
/*
* Initialize the input buffer
@@ -563,20 +255,18 @@ ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
Console->InputBuffer.InputBufferSize = 0; // FIXME!
InitializeListHead(&Console->InputBuffer.InputEvents);
InitializeListHead(&Console->InputBuffer.ReadWaitQueue);
Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
Console->QuickEdit = ConsoleInfo->QuickEdit;
Console->InsertMode = ConsoleInfo->InsertMode;
Console->LineBuffer = NULL;
Console->LineMaxSize = Console->LineSize = Console->LinePos = 0;
Console->LinePos = Console->LineMaxSize = Console->LineSize = 0;
Console->LineComplete = Console->LineUpPressed = FALSE;
Console->LineInsertToggle = Console->InsertMode;
// LineWakeupMask
/* Set-up the code page */
Console->CodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
/* Initialize a new text-mode screen buffer with default settings */
ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize;
@@ -600,44 +290,34 @@ ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
}
/* Make the new screen buffer active */
Console->ActiveBuffer = NewBuffer;
InitializeListHead(&Console->WriteWaitQueue);
Console->PauseFlags = 0;
Console->UnpauseEvent = NULL;
/*
* Initialize the alias and history buffers
*/
Console->Aliases = NULL;
InitializeListHead(&Console->HistoryBuffers);
Console->HistoryBufferSize = ConsoleInfo->HistoryBufferSize;
Console->NumberOfHistoryBuffers = ConsoleInfo->NumberOfHistoryBuffers;
Console->HistoryNoDup = ConsoleInfo->HistoryNoDup;
/* Initialize the console title */
ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo->ConsoleTitle);
// if (ConsoleInfo.ConsoleTitle[0] == L'\0')
// {
// if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0])))
// {
// ConsoleCreateUnicodeString(&Console->Title, DefaultTitle);
// }
// else
// {
// ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console");
// }
// }
// else
// {
#if 0
if (ConsoleInfo.ConsoleTitle[0] == L'\0')
{
if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0])))
{
ConsoleCreateUnicodeString(&Console->Title, DefaultTitle);
}
else
{
ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console");
}
}
else
{
#endif
ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo->ConsoleTitle);
// }
/* Lock the console until its initialization is finished */
// EnterCriticalSection(&Console->Lock);
#if 0
}
#endif
DPRINT("Console initialized\n");
/* All went right, so add the console to the list */
Status = InsertConsole(&ConsoleHandle, Console);
Status = InsertConsole(Console);
if (!NT_SUCCESS(Status))
{
/* Fail */
@@ -649,73 +329,69 @@ ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
DPRINT("Change state\n");
Console->State = CONSOLE_RUNNING;
/* Unlock the console */
// LeaveCriticalSection(&Console->Lock);
/* Return the newly created console to the caller and a success code too */
*NewConsoleHandle = ConsoleHandle;
*NewConsole = Console;
*NewConsole = Console;
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
ConDrvRegisterFrontEnd(IN PCONSOLE Console,
IN PFRONTEND FrontEnd)
ConDrvRegisterTerminal(IN PCONSOLE Console,
IN PTERMINAL Terminal)
{
NTSTATUS Status;
if (Console == NULL || FrontEnd == NULL)
if (Console == NULL || Terminal == NULL)
return STATUS_INVALID_PARAMETER;
/* FIXME: Lock the console before ?? */
/*
* Attach the frontend to the console. Use now the TermIFace of the console,
* and not the user-defined temporary FrontEnd pointer.
* Attach the terminal to the console. Use now the TermIFace of the console,
* and not the user-defined temporary Terminal pointer.
*/
Console->TermIFace = *FrontEnd;
Console->TermIFace = *Terminal;
Console->TermIFace.Console = Console;
/* Initialize the frontend AFTER having attached it to the console */
DPRINT("Finish initialization of frontend\n");
Status = Console->TermIFace.Vtbl->InitFrontEnd(&Console->TermIFace, Console);
/* Initialize the terminal AFTER having attached it to the console */
DPRINT("Finish initialization of terminal\n");
Status = Console->TermIFace.Vtbl->InitTerminal(&Console->TermIFace, Console);
if (!NT_SUCCESS(Status))
{
DPRINT1("FrontEnd initialization failed, Status = 0x%08lx\n", Status);
DPRINT1("Terminal initialization failed, Status = 0x%08lx\n", Status);
/* We failed, detach the frontend from the console */
FrontEnd->Console = NULL; // For the caller
ResetFrontEnd(Console);
/* We failed, detach the terminal from the console */
Terminal->Console = NULL; // For the caller
ResetTerminal(Console);
return Status;
}
/* Copy buffer contents to screen */
// FrontEnd.Draw();
// Terminal.Draw();
// ConioDrawConsole(Console);
DPRINT("Console drawn\n");
DPRINT("Terminal FrontEnd initialization done\n");
DPRINT("Terminal initialization done\n");
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
ConDrvDeregisterFrontEnd(IN PCONSOLE Console)
ConDrvDeregisterTerminal(IN PCONSOLE Console)
{
if (Console == NULL) return STATUS_INVALID_PARAMETER;
/* FIXME: Lock the console before ?? */
/* Deinitialize the frontend BEFORE detaching it from the console */
Console->TermIFace.Vtbl->DeinitFrontEnd(&Console->TermIFace/*, Console*/);
/* Deinitialize the terminal BEFORE detaching it from the console */
Console->TermIFace.Vtbl->DeinitTerminal(&Console->TermIFace/*, Console*/);
/*
* Detach the frontend from the console:
* reinitialize the frontend interface.
* Detach the terminal from the console:
* reinitialize the terminal interface.
*/
ResetFrontEnd(Console);
ResetTerminal(Console);
DPRINT("Terminal FrontEnd unregistered\n");
DPRINT("Terminal unregistered\n");
return STATUS_SUCCESS;
}
@@ -752,7 +428,7 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
/*
* Allow other threads to finish their job: basically, unlock
* all other calls to EnterCriticalSection(&Console->Lock); by
* ConDrvValidateConsole(Unsafe) functions so that they just see
* ConDrvValidateConsoleUnsafe functions so that they just see
* that we are not in CONSOLE_RUNNING state anymore, or unlock
* other concurrent calls to ConDrvDeleteConsole so that they
* can see that we are in fact already deleting the console.
@@ -764,7 +440,7 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
/* Cleanup the UI-oriented part */
DPRINT("Deregister console\n");
ConDrvDeregisterFrontEnd(Console);
ConDrvDeregisterTerminal(Console);
DPRINT("Console deregistered\n");
/***
@@ -788,16 +464,13 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
Console->ReferenceCount = 0;
/* Remove the console from the list */
RemoveConsoleByPointer(Console);
RemoveConsole(Console);
/* Discard all entries in the input event queue */
PurgeInputBuffer(Console);
if (Console->LineBuffer) ConsoleFreeHeap(Console->LineBuffer);
IntDeleteAllAliases(Console);
HistoryDeleteBuffers(Console);
/* Delete the last screen buffer */
ConioDeleteScreenBuffer(Console->ActiveBuffer);
Console->ActiveBuffer = NULL;
if (!IsListEmpty(&Console->BufferList))
@@ -983,7 +656,7 @@ ConDrvGetConsoleTitle(IN PCONSOLE Console,
if (*BufLength >= sizeof(CHAR))
{
Length = min(*BufLength - sizeof(CHAR), Console->Title.Length / sizeof(WCHAR));
Length = WideCharToMultiByte(Console->CodePage, 0,
Length = WideCharToMultiByte(Console->InputCodePage, 0,
Console->Title.Buffer, Length,
TitleBuffer, Length,
NULL, NULL);
@@ -1019,7 +692,7 @@ ConDrvSetConsoleTitle(IN PCONSOLE Console,
else
{
/* Use the console input CP for the conversion */
Length = MultiByteToWideChar(Console->CodePage, 0,
Length = MultiByteToWideChar(Console->InputCodePage, 0,
TitleBuffer, BufLength,
NULL, 0);
/* The returned Length was in number of wchars, convert it in bytes */
@@ -1044,7 +717,7 @@ ConDrvSetConsoleTitle(IN PCONSOLE Console,
}
else
{
MultiByteToWideChar(Console->CodePage, 0,
MultiByteToWideChar(Console->InputCodePage, 0,
TitleBuffer, BufLength,
Console->Title.Buffer,
Console->Title.Length / sizeof(WCHAR));
@@ -1065,7 +738,7 @@ ConDrvGetConsoleCP(IN PCONSOLE Console,
if (Console == NULL || CodePage == NULL)
return STATUS_INVALID_PARAMETER;
*CodePage = (OutputCP ? Console->OutputCodePage : Console->CodePage);
*CodePage = (OutputCP ? Console->OutputCodePage : Console->InputCodePage);
return STATUS_SUCCESS;
}
@@ -1081,86 +754,9 @@ ConDrvSetConsoleCP(IN PCONSOLE Console,
if (OutputCP)
Console->OutputCodePage = CodePage;
else
Console->CodePage = CodePage;
Console->InputCodePage = CodePage;
return STATUS_SUCCESS;
}
PCONSOLE_PROCESS_DATA NTAPI
ConDrvGetConsoleLeaderProcess(IN PCONSOLE Console)
{
if (Console == NULL) return NULL;
return CONTAINING_RECORD(Console->ProcessList.Blink,
CONSOLE_PROCESS_DATA,
ConsoleLink);
}
NTSTATUS NTAPI
ConDrvGetConsoleProcessList(IN PCONSOLE Console,
IN OUT PULONG ProcessIdsList,
IN ULONG MaxIdListItems,
OUT PULONG ProcessIdsTotal)
{
PCONSOLE_PROCESS_DATA current;
PLIST_ENTRY current_entry;
if (Console == NULL || ProcessIdsList == NULL || ProcessIdsTotal == NULL)
return STATUS_INVALID_PARAMETER;
*ProcessIdsTotal = 0;
for (current_entry = Console->ProcessList.Flink;
current_entry != &Console->ProcessList;
current_entry = current_entry->Flink)
{
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
if (++(*ProcessIdsTotal) <= MaxIdListItems)
{
*ProcessIdsList++ = HandleToUlong(current->Process->ClientId.UniqueProcess);
}
}
return STATUS_SUCCESS;
}
// ConDrvGenerateConsoleCtrlEvent
NTSTATUS NTAPI
ConDrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
IN ULONG ProcessGroupId,
IN ULONG CtrlEvent)
{
NTSTATUS Status = STATUS_SUCCESS;
PLIST_ENTRY current_entry;
PCONSOLE_PROCESS_DATA current;
/* If the console is already being destroyed, just return */
if (!ConDrvValidateConsoleState(Console, CONSOLE_RUNNING))
return STATUS_UNSUCCESSFUL;
/*
* Loop through the process list, from the most recent process
* (the active one) to the oldest one (the first created, i.e.
* the console leader process), and for each, send an event
* (new processes are inserted at the head of the console process list).
*/
current_entry = Console->ProcessList.Flink;
while (current_entry != &Console->ProcessList)
{
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
current_entry = current_entry->Flink;
/*
* Only processes belonging to the same process group are signaled.
* If the process group ID is zero, then all the processes are signaled.
*/
if (ProcessGroupId == 0 || current->Process->ProcessGroupId == ProcessGroupId)
{
Status = ConDrvConsoleCtrlEvent(CtrlEvent, current);
}
}
return Status;
}
/* EOF */
@@ -1,213 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/winsrv/consrv/condrv/dummyfrontend.c
* PURPOSE: Dummy Terminal Front-End used when no frontend
* is attached to the specified console.
* PROGRAMMERS: Hermes Belusca-Maito ([email protected])
*/
/* INCLUDES *******************************************************************/
#include <consrv.h>
/* DUMMY FRONTEND INTERFACE ***************************************************/
static NTSTATUS NTAPI
DummyInitFrontEnd(IN OUT PFRONTEND This,
IN PCONSOLE Console)
{
/* Load some settings ?? */
return STATUS_SUCCESS;
}
static VOID NTAPI
DummyDeinitFrontEnd(IN OUT PFRONTEND This)
{
/* Free some settings ?? */
}
static VOID NTAPI
DummyDrawRegion(IN OUT PFRONTEND This,
SMALL_RECT* Region)
{
}
static VOID NTAPI
DummyWriteStream(IN OUT PFRONTEND This,
SMALL_RECT* Region,
SHORT CursorStartX,
SHORT CursorStartY,
UINT ScrolledLines,
PWCHAR Buffer,
UINT Length)
{
}
static BOOL NTAPI
DummySetCursorInfo(IN OUT PFRONTEND This,
PCONSOLE_SCREEN_BUFFER Buff)
{
return TRUE;
}
static BOOL NTAPI
DummySetScreenInfo(IN OUT PFRONTEND This,
PCONSOLE_SCREEN_BUFFER Buff,
SHORT OldCursorX,
SHORT OldCursorY)
{
return TRUE;
}
static VOID NTAPI
DummyResizeTerminal(IN OUT PFRONTEND This)
{
}
static VOID NTAPI
DummySetActiveScreenBuffer(IN OUT PFRONTEND This)
{
}
static VOID NTAPI
DummyReleaseScreenBuffer(IN OUT PFRONTEND This,
IN PCONSOLE_SCREEN_BUFFER ScreenBuffer)
{
}
static BOOL NTAPI
DummyProcessKeyCallback(IN OUT PFRONTEND This,
MSG* msg,
BYTE KeyStateMenu,
DWORD ShiftState,
UINT VirtualKeyCode,
BOOL Down)
{
return FALSE;
}
static VOID NTAPI
DummyRefreshInternalInfo(IN OUT PFRONTEND This)
{
}
static VOID NTAPI
DummyChangeTitle(IN OUT PFRONTEND This)
{
}
static BOOL NTAPI
DummyChangeIcon(IN OUT PFRONTEND This,
HICON IconHandle)
{
return TRUE;
}
static HWND NTAPI
DummyGetConsoleWindowHandle(IN OUT PFRONTEND This)
{
return NULL;
}
static VOID NTAPI
DummyGetLargestConsoleWindowSize(IN OUT PFRONTEND This,
PCOORD pSize)
{
}
static BOOL NTAPI
DummyGetSelectionInfo(IN OUT PFRONTEND This,
PCONSOLE_SELECTION_INFO pSelectionInfo)
{
return TRUE;
}
static BOOL NTAPI
DummySetPalette(IN OUT PFRONTEND This,
HPALETTE PaletteHandle,
UINT PaletteUsage)
{
return TRUE;
}
static ULONG NTAPI
DummyGetDisplayMode(IN OUT PFRONTEND This)
{
return 0;
}
static BOOL NTAPI
DummySetDisplayMode(IN OUT PFRONTEND This,
ULONG NewMode)
{
return TRUE;
}
static INT NTAPI
DummyShowMouseCursor(IN OUT PFRONTEND This,
BOOL Show)
{
return 0;
}
static BOOL NTAPI
DummySetMouseCursor(IN OUT PFRONTEND This,
HCURSOR CursorHandle)
{
return TRUE;
}
static HMENU NTAPI
DummyMenuControl(IN OUT PFRONTEND This,
UINT CmdIdLow,
UINT CmdIdHigh)
{
return NULL;
}
static BOOL NTAPI
DummySetMenuClose(IN OUT PFRONTEND This,
BOOL Enable)
{
return TRUE;
}
static FRONTEND_VTBL DummyVtbl =
{
DummyInitFrontEnd,
DummyDeinitFrontEnd,
DummyDrawRegion,
DummyWriteStream,
DummySetCursorInfo,
DummySetScreenInfo,
DummyResizeTerminal,
DummySetActiveScreenBuffer,
DummyReleaseScreenBuffer,
DummyProcessKeyCallback,
DummyRefreshInternalInfo,
DummyChangeTitle,
DummyChangeIcon,
DummyGetConsoleWindowHandle,
DummyGetLargestConsoleWindowSize,
DummyGetSelectionInfo,
DummySetPalette,
DummyGetDisplayMode,
DummySetDisplayMode,
DummyShowMouseCursor,
DummySetMouseCursor,
DummyMenuControl,
DummySetMenuClose,
};
VOID
ResetFrontEnd(IN PCONSOLE Console)
{
if (!Console) return;
/* Reinitialize the frontend interface */
RtlZeroMemory(&Console->TermIFace, sizeof(Console->TermIFace));
Console->TermIFace.Vtbl = &DummyVtbl;
}
/* EOF */
@@ -0,0 +1,140 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: condrv/dummyterm.c
* PURPOSE: Dummy Terminal used when no terminal
* is attached to the specified console.
* PROGRAMMERS: Hermes Belusca-Maito ([email protected])
*/
/* INCLUDES *******************************************************************/
#include <consrv.h>
/* DUMMY TERMINAL INTERFACE ***************************************************/
static NTSTATUS NTAPI
DummyInitTerminal(IN OUT PTERMINAL This,
IN PCONSOLE Console)
{
return STATUS_SUCCESS;
}
static VOID NTAPI
DummyDeinitTerminal(IN OUT PTERMINAL This)
{
}
static VOID NTAPI
DummyDrawRegion(IN OUT PTERMINAL This,
SMALL_RECT* Region)
{
}
static VOID NTAPI
DummyWriteStream(IN OUT PTERMINAL This,
SMALL_RECT* Region,
SHORT CursorStartX,
SHORT CursorStartY,
UINT ScrolledLines,
PWCHAR Buffer,
UINT Length)
{
}
static BOOL NTAPI
DummySetCursorInfo(IN OUT PTERMINAL This,
PCONSOLE_SCREEN_BUFFER ScreenBuffer)
{
return TRUE;
}
static BOOL NTAPI
DummySetScreenInfo(IN OUT PTERMINAL This,
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
SHORT OldCursorX,
SHORT OldCursorY)
{
return TRUE;
}
static VOID NTAPI
DummyResizeTerminal(IN OUT PTERMINAL This)
{
}
static VOID NTAPI
DummySetActiveScreenBuffer(IN OUT PTERMINAL This)
{
}
static VOID NTAPI
DummyReleaseScreenBuffer(IN OUT PTERMINAL This,
IN PCONSOLE_SCREEN_BUFFER ScreenBuffer)
{
}
static VOID NTAPI
DummyChangeTitle(IN OUT PTERMINAL This)
{
}
static VOID NTAPI
DummyGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
PCOORD pSize)
{
}
/*
static BOOL NTAPI
DummyGetSelectionInfo(IN OUT PTERMINAL This,
PCONSOLE_SELECTION_INFO pSelectionInfo)
{
return TRUE;
}
*/
static BOOL NTAPI
DummySetPalette(IN OUT PTERMINAL This,
HPALETTE PaletteHandle,
UINT PaletteUsage)
{
return TRUE;
}
static INT NTAPI
DummyShowMouseCursor(IN OUT PTERMINAL This,
BOOL Show)
{
return 0;
}
static TERMINAL_VTBL DummyVtbl =
{
DummyInitTerminal,
DummyDeinitTerminal,
DummyDrawRegion,
DummyWriteStream,
DummySetCursorInfo,
DummySetScreenInfo,
DummyResizeTerminal,
DummySetActiveScreenBuffer,
DummyReleaseScreenBuffer,
DummyChangeTitle,
DummyGetLargestConsoleWindowSize,
// DummyGetSelectionInfo,
DummySetPalette,
DummyShowMouseCursor,
};
VOID
ResetTerminal(IN PCONSOLE Console)
{
if (!Console) return;
/* Reinitialize the terminal interface */
RtlZeroMemory(&Console->TermIFace, sizeof(Console->TermIFace));
Console->TermIFace.Vtbl = &DummyVtbl;
}
/* EOF */
@@ -34,6 +34,7 @@ static CONSOLE_SCREEN_BUFFER_VTBL GraphicsVtbl =
NTSTATUS
CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN OUT PCONSOLE Console,
IN PCONSOLE_SCREEN_BUFFER_VTBL Vtbl,
IN SIZE_T Size);
VOID
CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer);
@@ -58,10 +59,10 @@ GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer,
Console,
&GraphicsVtbl,
sizeof(GRAPHICS_SCREEN_BUFFER));
if (!NT_SUCCESS(Status)) return Status;
NewBuffer->Header.Type = GRAPHICS_BUFFER;
NewBuffer->Vtbl = &GraphicsVtbl;
/*
* Remember the handle to the process so that we can close or unmap
+85 -196
View File
@@ -33,13 +33,14 @@ static CONSOLE_SCREEN_BUFFER_VTBL TextVtbl =
};
static VOID FASTCALL
static VOID
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff);
NTSTATUS
CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN OUT PCONSOLE Console,
IN PCONSOLE_SCREEN_BUFFER_VTBL Vtbl,
IN SIZE_T Size);
VOID
CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer);
@@ -60,10 +61,10 @@ TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer,
Console,
&TextVtbl,
sizeof(TEXTMODE_SCREEN_BUFFER));
if (!NT_SUCCESS(Status)) return Status;
NewBuffer->Header.Type = TEXTMODE_BUFFER;
NewBuffer->Vtbl = &TextVtbl;
NewBuffer->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
TextModeInfo->ScreenBufferSize.X *
@@ -126,7 +127,7 @@ ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
return &Buff->Buffer[((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X];
}
static VOID FASTCALL
static VOID
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff)
{
PCHAR_INFO Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y);
@@ -140,66 +141,7 @@ ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff)
}
}
static __inline BOOLEAN
ConioGetIntersection(OUT PSMALL_RECT Intersection,
IN PSMALL_RECT Rect1,
IN PSMALL_RECT Rect2)
{
if ( ConioIsRectEmpty(Rect1) ||
ConioIsRectEmpty(Rect2) ||
(Rect1->Top > Rect2->Bottom) ||
(Rect1->Left > Rect2->Right) ||
(Rect1->Bottom < Rect2->Top) ||
(Rect1->Right < Rect2->Left) )
{
/* The rectangles do not intersect */
ConioInitRect(Intersection, 0, -1, 0, -1);
return FALSE;
}
ConioInitRect(Intersection,
max(Rect1->Top , Rect2->Top ),
max(Rect1->Left , Rect2->Left ),
min(Rect1->Bottom, Rect2->Bottom),
min(Rect1->Right , Rect2->Right ));
return TRUE;
}
static __inline BOOLEAN
ConioGetUnion(OUT PSMALL_RECT Union,
IN PSMALL_RECT Rect1,
IN PSMALL_RECT Rect2)
{
if (ConioIsRectEmpty(Rect1))
{
if (ConioIsRectEmpty(Rect2))
{
ConioInitRect(Union, 0, -1, 0, -1);
return FALSE;
}
else
{
*Union = *Rect2;
}
}
else if (ConioIsRectEmpty(Rect2))
{
*Union = *Rect1;
}
else
{
ConioInitRect(Union,
min(Rect1->Top , Rect2->Top ),
min(Rect1->Left , Rect2->Left ),
max(Rect1->Bottom, Rect2->Bottom),
max(Rect1->Right , Rect2->Right ));
}
return TRUE;
}
static VOID FASTCALL
static VOID
ConioComputeUpdateRect(IN PTEXTMODE_SCREEN_BUFFER Buff,
IN OUT PSMALL_RECT UpdateRect,
IN PCOORD Start,
@@ -233,7 +175,7 @@ ConioComputeUpdateRect(IN PTEXTMODE_SCREEN_BUFFER Buff,
* Move from one rectangle to another. We must be careful about the order that
* this is done, to avoid overwriting parts of the source before they are moved.
*/
static VOID FASTCALL
static VOID
ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
PSMALL_RECT SrcRegion,
PSMALL_RECT DstRegion,
@@ -293,16 +235,6 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
}
}
DWORD FASTCALL
ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale)
{
DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
/* If line input in progress, perhaps adjust for insert toggle */
if (Console->LineBuffer && !Console->LineComplete && (Console->InsertMode ? !Console->LineInsertToggle : Console->LineInsertToggle))
return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
return Size;
}
NTSTATUS
ConioResizeBuffer(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
@@ -422,7 +354,7 @@ ConioResizeBuffer(PCONSOLE Console,
return STATUS_SUCCESS;
}
static VOID FASTCALL
static VOID
ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, PSMALL_RECT UpdateRect, PUINT ScrolledLines)
{
/* If we hit bottom, slide the viewable screen */
@@ -669,21 +601,15 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
OUT PCHAR_INFO CharInfo/*Buffer*/,
IN PCOORD BufferSize,
IN PCOORD BufferCoord,
IN OUT PSMALL_RECT ReadRegion)
{
SHORT X, Y;
SMALL_RECT ScreenBuffer;
PCHAR_INFO CurCharInfo;
SHORT SizeX, SizeY;
SMALL_RECT CapturedReadRegion;
SMALL_RECT ScreenRect;
DWORD i;
PCHAR_INFO Ptr;
LONG X, Y;
UINT CodePage;
if (Console == NULL || Buffer == NULL || CharInfo == NULL ||
BufferSize == NULL || BufferCoord == NULL || ReadRegion == NULL)
if (Console == NULL || Buffer == NULL || CharInfo == NULL || ReadRegion == NULL)
{
return STATUS_INVALID_PARAMETER;
}
@@ -693,26 +619,24 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console,
CapturedReadRegion = *ReadRegion;
/* FIXME: Is this correct? */
CodePage = Console->OutputCodePage;
SizeX = min(BufferSize->X - BufferCoord->X, ConioRectWidth(&CapturedReadRegion));
SizeY = min(BufferSize->Y - BufferCoord->Y, ConioRectHeight(&CapturedReadRegion));
CapturedReadRegion.Right = CapturedReadRegion.Left + SizeX;
CapturedReadRegion.Bottom = CapturedReadRegion.Top + SizeY;
ConioInitRect(&ScreenRect, 0, 0, Buffer->ScreenBufferSize.Y, Buffer->ScreenBufferSize.X);
if (!ConioGetIntersection(&CapturedReadRegion, &ScreenRect, &CapturedReadRegion))
/* Make sure ReadRegion is inside the screen buffer */
ConioInitRect(&ScreenBuffer, 0, 0,
Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
if (!ConioGetIntersection(&CapturedReadRegion, &ScreenBuffer, &CapturedReadRegion))
{
/*
* It is okay to have a ReadRegion completely outside
* the screen buffer. No data is read then.
*/
return STATUS_SUCCESS;
}
for (i = 0, Y = CapturedReadRegion.Top; Y < CapturedReadRegion.Bottom; ++i, ++Y)
{
CurCharInfo = CharInfo + (i * BufferSize->X);
CurCharInfo = CharInfo;
for (Y = CapturedReadRegion.Top; Y <= CapturedReadRegion.Bottom; ++Y)
{
Ptr = ConioCoordToPointer(Buffer, CapturedReadRegion.Left, Y);
for (X = CapturedReadRegion.Left; X < CapturedReadRegion.Right; ++X)
for (X = CapturedReadRegion.Left; X <= CapturedReadRegion.Right; ++X)
{
if (Unicode)
{
@@ -721,7 +645,7 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console,
else
{
// ConsoleUnicodeCharToAnsiChar(Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar);
WideCharToMultiByte(CodePage, 0, &Ptr->Char.UnicodeChar, 1,
WideCharToMultiByte(Console->OutputCodePage, 0, &Ptr->Char.UnicodeChar, 1,
&CurCharInfo->Char.AsciiChar, 1, NULL, NULL);
}
CurCharInfo->Attributes = Ptr->Attributes;
@@ -730,10 +654,7 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console,
}
}
ReadRegion->Left = CapturedReadRegion.Left;
ReadRegion->Top = CapturedReadRegion.Top ;
ReadRegion->Right = CapturedReadRegion.Left + SizeX - 1;
ReadRegion->Bottom = CapturedReadRegion.Top + SizeY - 1;
*ReadRegion = CapturedReadRegion;
return STATUS_SUCCESS;
}
@@ -743,18 +664,15 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
IN PCHAR_INFO CharInfo/*Buffer*/,
IN PCOORD BufferSize,
IN PCOORD BufferCoord,
IN OUT PSMALL_RECT WriteRegion)
{
SHORT i, X, Y, SizeX, SizeY;
SHORT X, Y;
SMALL_RECT ScreenBuffer;
PCHAR_INFO CurCharInfo;
SMALL_RECT CapturedWriteRegion;
PCHAR_INFO Ptr;
if (Console == NULL || Buffer == NULL || CharInfo == NULL ||
BufferSize == NULL || BufferCoord == NULL || WriteRegion == NULL)
if (Console == NULL || Buffer == NULL || CharInfo == NULL || WriteRegion == NULL)
{
return STATUS_INVALID_PARAMETER;
}
@@ -764,13 +682,9 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console,
CapturedWriteRegion = *WriteRegion;
SizeX = min(BufferSize->X - BufferCoord->X, ConioRectWidth(&CapturedWriteRegion));
SizeY = min(BufferSize->Y - BufferCoord->Y, ConioRectHeight(&CapturedWriteRegion));
CapturedWriteRegion.Right = CapturedWriteRegion.Left + SizeX - 1;
CapturedWriteRegion.Bottom = CapturedWriteRegion.Top + SizeY - 1;
/* Make sure WriteRegion is inside the screen buffer */
ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
ConioInitRect(&ScreenBuffer, 0, 0,
Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer, &CapturedWriteRegion))
{
/*
@@ -780,12 +694,12 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console,
return STATUS_SUCCESS;
}
for (i = 0, Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; i++, Y++)
{
CurCharInfo = CharInfo + (i + BufferCoord->Y) * BufferSize->X + BufferCoord->X;
CurCharInfo = CharInfo;
for (Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; ++Y)
{
Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y);
for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; X++)
for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; ++X)
{
if (Unicode)
{
@@ -803,10 +717,7 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console,
TermDrawRegion(Console, &CapturedWriteRegion);
WriteRegion->Left = CapturedWriteRegion.Left;
WriteRegion->Top = CapturedWriteRegion.Top ;
WriteRegion->Right = CapturedWriteRegion.Left + SizeX - 1;
WriteRegion->Bottom = CapturedWriteRegion.Top + SizeY - 1;
*WriteRegion = CapturedWriteRegion;
return STATUS_SUCCESS;
}
@@ -829,14 +740,10 @@ ConDrvWriteConsole(IN PCONSOLE Console,
/* Validity checks */
ASSERT(Console == ScreenBuffer->Header.Console);
ASSERT( (StringBuffer != NULL && NumCharsToWrite >= 0) ||
(StringBuffer == NULL && NumCharsToWrite == 0) );
ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCharsToWrite == 0));
// if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION))
if (Console->PauseFlags && Console->UnpauseEvent != NULL)
{
return STATUS_PENDING;
}
/* Stop here if the console is paused */
if (Console->UnpauseEvent != NULL) return STATUS_PENDING;
if (Unicode)
{
@@ -892,8 +799,8 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
OUT PVOID StringBuffer,
IN ULONG NumCodesToRead,
IN PCOORD ReadCoord,
OUT PCOORD EndCoord,
OUT PULONG CodesRead)
// OUT PCOORD EndCoord,
OUT PULONG NumCodesRead OPTIONAL)
{
SHORT Xpos, Ypos;
PVOID ReadBuffer;
@@ -901,29 +808,29 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
ULONG CodeSize;
PCHAR_INFO Ptr;
if (Console == NULL || Buffer == NULL ||
ReadCoord == NULL || EndCoord == NULL || CodesRead == NULL)
if (Console == NULL || Buffer == NULL || ReadCoord == NULL /* || EndCoord == NULL */)
{
return STATUS_INVALID_PARAMETER;
}
/* Validity checks */
ASSERT(Console == Buffer->Header.Console);
ASSERT( (StringBuffer != NULL && NumCodesToRead >= 0) ||
(StringBuffer == NULL && NumCodesToRead == 0) );
ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToRead == 0));
if (NumCodesRead) *NumCodesRead = 0;
switch (CodeType)
{
case CODE_ASCII:
CodeSize = sizeof(CHAR);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
break;
case CODE_UNICODE:
CodeSize = sizeof(WCHAR);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
break;
case CODE_ATTRIBUTE:
CodeSize = sizeof(WORD);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
break;
default:
@@ -984,25 +891,11 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
}
}
// switch (CodeType)
// {
// case CODE_UNICODE:
// *(PWCHAR)ReadBuffer = 0;
// break;
// EndCoord->X = Xpos;
// EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y;
// case CODE_ASCII:
// *(PCHAR)ReadBuffer = 0;
// break;
// case CODE_ATTRIBUTE:
// *(PWORD)ReadBuffer = 0;
// break;
// }
EndCoord->X = Xpos;
EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y;
*CodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize;
if (NumCodesRead)
*NumCodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize;
// <= NumCodesToRead
return STATUS_SUCCESS;
@@ -1014,9 +907,9 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
IN CODE_TYPE CodeType,
IN PVOID StringBuffer,
IN ULONG NumCodesToWrite,
IN PCOORD WriteCoord /*,
OUT PCOORD EndCoord,
OUT PULONG CodesWritten */)
IN PCOORD WriteCoord,
// OUT PCOORD EndCoord,
OUT PULONG NumCodesWritten OPTIONAL)
{
NTSTATUS Status = STATUS_SUCCESS;
PVOID WriteBuffer = NULL;
@@ -1025,29 +918,29 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
ULONG CodeSize;
PCHAR_INFO Ptr;
if (Console == NULL || Buffer == NULL ||
WriteCoord == NULL /* || EndCoord == NULL || CodesWritten == NULL */)
if (Console == NULL || Buffer == NULL || WriteCoord == NULL /* || EndCoord == NULL */)
{
return STATUS_INVALID_PARAMETER;
}
/* Validity checks */
ASSERT(Console == Buffer->Header.Console);
ASSERT( (StringBuffer != NULL && NumCodesToWrite >= 0) ||
(StringBuffer == NULL && NumCodesToWrite == 0) );
ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToWrite == 0));
if (NumCodesWritten) *NumCodesWritten = 0;
switch (CodeType)
{
case CODE_ASCII:
CodeSize = sizeof(CHAR);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
break;
case CODE_UNICODE:
CodeSize = sizeof(WCHAR);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
break;
case CODE_ATTRIBUTE:
CodeSize = sizeof(WORD);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
break;
default:
@@ -1073,6 +966,12 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
{
Status = STATUS_NO_MEMORY;
}
// FIXME: Quick fix: fix the CodeType and CodeSize since the
// ASCII string was converted into UNICODE.
// A proper fix needs to be written.
CodeType = CODE_UNICODE;
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
}
else
{
@@ -1132,7 +1031,7 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
Cleanup:
if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);
// CodesWritten = Written;
if (NumCodesWritten) *NumCodesWritten = NumCodesToWrite; // Written;
return Status;
}
@@ -1140,16 +1039,15 @@ NTSTATUS NTAPI
ConDrvFillConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
IN PVOID Code,
IN CODE_ELEMENT Code,
IN ULONG NumCodesToWrite,
IN PCOORD WriteCoord /*,
OUT PULONG CodesWritten */)
IN PCOORD WriteCoord,
OUT PULONG NumCodesWritten OPTIONAL)
{
DWORD X, Y, Length; // , Written = 0;
PCHAR_INFO Ptr;
if (Console == NULL || Buffer == NULL || Code == NULL ||
WriteCoord == NULL /* || CodesWritten == NULL */)
if (Console == NULL || Buffer == NULL || WriteCoord == NULL)
{
return STATUS_INVALID_PARAMETER;
}
@@ -1157,29 +1055,15 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
/* Validity check */
ASSERT(Console == Buffer->Header.Console);
#if 0
switch (CodeType)
{
case CODE_ASCII:
/* On-place conversion from the ASCII char to the UNICODE char */
ConsoleAnsiCharToUnicodeChar(Console, &Code->UnicodeChar, &Code->AsciiChar);
/* Fall through */
case CODE_UNICODE:
Code = &Code->UnicodeChar;
break;
if (NumCodesWritten) *NumCodesWritten = 0;
case CODE_ATTRIBUTE:
Code = &Code->Attribute;
break;
}
#else
if (CodeType == CODE_ASCII)
{
/* On-place conversion from the ASCII char to the UNICODE char */
// FIXME: What if Code points to an invalid memory zone ??
ConsoleAnsiCharToUnicodeChar(Console, (PWCHAR)Code, (PCHAR)Code);
/* Conversion from the ASCII char to the UNICODE char */
CODE_ELEMENT tmp;
ConsoleAnsiCharToUnicodeChar(Console, &tmp.UnicodeChar, &Code.AsciiChar);
Code = tmp;
}
#endif
X = WriteCoord->X;
Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
@@ -1196,11 +1080,11 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
{
case CODE_ASCII:
case CODE_UNICODE:
Ptr->Char.UnicodeChar = *(PWCHAR)Code;
Ptr->Char.UnicodeChar = Code.UnicodeChar;
break;
case CODE_ATTRIBUTE:
Ptr->Attributes = *(PWORD)Code;
Ptr->Attributes = Code.Attribute;
break;
}
// ++Ptr;
@@ -1224,7 +1108,7 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
TermDrawRegion(Console, &UpdateRect);
}
// CodesWritten = Written; // NumCodesToWrite;
if (NumCodesWritten) *NumCodesWritten = NumCodesToWrite; // Written;
return STATUS_SUCCESS;
}
@@ -1323,7 +1207,8 @@ ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console,
CapturedDestinationOrigin = *DestinationOrigin;
/* Make sure the source rectangle is inside the screen buffer */
ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
ConioInitRect(&ScreenBuffer, 0, 0,
Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, ScrollRectangle))
{
return STATUS_SUCCESS;
@@ -1359,7 +1244,11 @@ ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console,
CapturedDestinationOrigin.X + ConioRectWidth(&SrcRegion ) - 1);
if (!Unicode)
ConsoleAnsiCharToUnicodeChar(Console, &FillChar.Char.UnicodeChar, &FillChar.Char.AsciiChar);
{
WCHAR tmp;
ConsoleAnsiCharToUnicodeChar(Console, &tmp, &FillChar.Char.AsciiChar);
FillChar.Char.UnicodeChar = tmp;
}
ConioMoveRegion(Buffer, &SrcRegion, &DstRegion, &CapturedClipRectangle, FillChar);
+255 -40
View File
@@ -36,6 +36,88 @@ typedef struct _GET_INPUT_INFO
/* PRIVATE FUNCTIONS **********************************************************/
/*
* This pre-processing code MUST be IN consrv ONLY
*/
/* static */ ULONG
PreprocessInput(PCONSOLE Console,
PINPUT_RECORD InputEvent,
ULONG NumEventsToWrite)
{
ULONG NumEvents;
/*
* Loop each event, and for each, check for pause or unpause
* and perform adequate behaviour.
*/
for (NumEvents = NumEventsToWrite; NumEvents > 0; --NumEvents)
{
/* Check for pause or unpause */
if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown)
{
WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode;
if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
{
DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState;
if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT &&
(vk == VK_PAUSE ||
(vk == 'S' && (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
!(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
{
ConioPause(Console, PAUSED_FROM_KEYBOARD);
/* Skip the event */
RtlMoveMemory(InputEvent,
InputEvent + 1,
(NumEvents - 1) * sizeof(INPUT_RECORD));
--NumEventsToWrite;
continue;
}
}
else
{
if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
{
ConioUnpause(Console, PAUSED_FROM_KEYBOARD);
/* Skip the event */
RtlMoveMemory(InputEvent,
InputEvent + 1,
(NumEvents - 1) * sizeof(INPUT_RECORD));
--NumEventsToWrite;
continue;
}
}
}
/* Go to the next event */
++InputEvent;
}
return NumEventsToWrite;
}
/*
* This post-processing code MUST be IN consrv ONLY
*/
/* static */ VOID
PostprocessInput(PCONSOLE Console)
{
CsrNotifyWait(&Console->ReadWaitQueue,
FALSE,
NULL,
NULL);
if (!IsListEmpty(&Console->ReadWaitQueue))
{
CsrDereferenceWait(&Console->ReadWaitQueue);
}
}
static NTSTATUS
WaitBeforeReading(IN PGET_INPUT_INFO InputInfo,
IN PCSR_API_MESSAGE ApiMessage,
@@ -51,7 +133,7 @@ WaitBeforeReading(IN PGET_INPUT_INFO InputInfo,
RtlMoveMemory(CapturedInputInfo, InputInfo, sizeof(GET_INPUT_INFO));
if (!CsrCreateWait(&InputInfo->InputBuffer->ReadWaitQueue,
if (!CsrCreateWait(&InputInfo->InputBuffer->Header.Console->ReadWaitQueue,
WaitFunction,
InputInfo->CallingThread,
ApiMessage,
@@ -133,6 +215,7 @@ Quit:
NTSTATUS NTAPI
ConDrvReadConsole(IN PCONSOLE Console,
IN PCONSOLE_INPUT_BUFFER InputBuffer,
/**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/
IN BOOLEAN Unicode,
OUT PVOID Buffer,
IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
@@ -148,20 +231,64 @@ ReadChars(IN PGET_INPUT_INFO InputInfo,
PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
CONSOLE_READCONSOLE_CONTROL ReadControl;
UNICODE_STRING ExeName;
PVOID Buffer;
ULONG NrCharactersRead = 0;
ULONG CharSize = (ReadConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));
/* Compute the executable name, if needed */
if (ReadConsoleRequest->InitialNumBytes == 0 &&
ReadConsoleRequest->ExeLength <= sizeof(ReadConsoleRequest->StaticBuffer))
{
ExeName.Length = ExeName.MaximumLength = ReadConsoleRequest->ExeLength;
ExeName.Buffer = (PWCHAR)ReadConsoleRequest->StaticBuffer;
}
else
{
ExeName.Length = ExeName.MaximumLength = 0;
ExeName.Buffer = NULL;
}
/* Build the ReadControl structure */
ReadControl.nLength = sizeof(CONSOLE_READCONSOLE_CONTROL);
ReadControl.nInitialChars = ReadConsoleRequest->NrCharactersRead;
ReadControl.nInitialChars = ReadConsoleRequest->InitialNumBytes / CharSize;
ReadControl.dwCtrlWakeupMask = ReadConsoleRequest->CtrlWakeupMask;
ReadControl.dwControlKeyState = ReadConsoleRequest->ControlKeyState;
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than eighty
* bytes are read. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (ReadConsoleRequest->CaptureBufferSize <= sizeof(ReadConsoleRequest->StaticBuffer))
{
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer;
Buffer = ReadConsoleRequest->StaticBuffer;
}
else
{
Buffer = ReadConsoleRequest->Buffer;
}
DPRINT1("Calling ConDrvReadConsole(%wZ)\n", &ExeName);
Status = ConDrvReadConsole(InputBuffer->Header.Console,
InputBuffer,
&ExeName,
ReadConsoleRequest->Unicode,
ReadConsoleRequest->Buffer,
Buffer,
&ReadControl,
ReadConsoleRequest->NrCharactersToRead,
&ReadConsoleRequest->NrCharactersRead);
ReadConsoleRequest->NumBytes / CharSize, // NrCharactersToRead
&NrCharactersRead);
DPRINT1("ConDrvReadConsole returned (%d ; Status = 0x%08x)\n",
NrCharactersRead, Status);
ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState;
// ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState;
if (Status == STATUS_PENDING)
{
@@ -173,7 +300,13 @@ ReadChars(IN PGET_INPUT_INFO InputInfo,
}
else
{
/* We read all what we wanted, we return the error code we were given */
/*
* We read all what we wanted. Set the number of bytes read and
* return the error code we were given.
*/
ReadConsoleRequest->NumBytes = NrCharactersRead * CharSize;
ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState;
return Status;
// return STATUS_SUCCESS;
}
@@ -260,17 +393,39 @@ ReadInputBuffer(IN PGET_INPUT_INFO InputInfo,
NTSTATUS Status;
PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest;
PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer;
ULONG NumEventsRead;
// GetInputRequest->InputsRead = 0;
PINPUT_RECORD InputRecord;
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than five
* input records are read. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (GetInputRequest->NumRecords <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
{
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
InputRecord = GetInputRequest->RecordStaticBuffer;
}
else
{
InputRecord = GetInputRequest->RecordBufPtr;
}
NumEventsRead = 0;
Status = ConDrvGetConsoleInput(InputBuffer->Header.Console,
InputBuffer,
(GetInputRequest->wFlags & CONSOLE_READ_KEEPEVENT) != 0,
(GetInputRequest->wFlags & CONSOLE_READ_CONTINUE ) == 0,
(GetInputRequest->Flags & CONSOLE_READ_KEEPEVENT) != 0,
(GetInputRequest->Flags & CONSOLE_READ_CONTINUE ) == 0,
GetInputRequest->Unicode,
GetInputRequest->InputRecord,
GetInputRequest->Length,
&GetInputRequest->InputsRead);
InputRecord,
GetInputRequest->NumRecords,
&NumEventsRead);
if (Status == STATUS_PENDING)
{
@@ -282,7 +437,12 @@ ReadInputBuffer(IN PGET_INPUT_INFO InputInfo,
}
else
{
/* We read all what we wanted, we return the error code we were given */
/*
* We read all what we wanted. Set the number of events read and
* return the error code we were given.
*/
GetInputRequest->NumRecords = NumEventsRead;
return Status;
// return STATUS_SUCCESS;
}
@@ -302,15 +462,32 @@ CSR_API(SrvReadConsole)
DPRINT("SrvReadConsole\n");
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&ReadConsoleRequest->Buffer,
ReadConsoleRequest->BufferSize,
sizeof(BYTE)))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than eighty
* bytes are read. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (ReadConsoleRequest->CaptureBufferSize <= sizeof(ReadConsoleRequest->StaticBuffer))
{
return STATUS_INVALID_PARAMETER;
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&ReadConsoleRequest->Buffer,
ReadConsoleRequest->CaptureBufferSize,
sizeof(BYTE)))
{
return STATUS_INVALID_PARAMETER;
}
}
if (ReadConsoleRequest->NrCharactersRead > ReadConsoleRequest->NrCharactersToRead)
if (ReadConsoleRequest->InitialNumBytes > ReadConsoleRequest->NumBytes)
{
return STATUS_INVALID_PARAMETER;
}
@@ -318,9 +495,6 @@ CSR_API(SrvReadConsole)
Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, ReadConsoleRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE);
if (!NT_SUCCESS(Status)) return Status;
// This member is set by the caller (IntReadConsole in kernel32)
// ReadConsoleRequest->NrCharactersRead = 0;
InputInfo.CallingThread = CsrGetClientThread();
InputInfo.HandleEntry = HandleEntry;
InputInfo.InputBuffer = InputBuffer;
@@ -345,22 +519,37 @@ CSR_API(SrvGetConsoleInput)
DPRINT("SrvGetConsoleInput\n");
if (GetInputRequest->wFlags & ~(CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE))
if (GetInputRequest->Flags & ~(CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE))
return STATUS_INVALID_PARAMETER;
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&GetInputRequest->InputRecord,
GetInputRequest->Length,
sizeof(INPUT_RECORD)))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than five
* input records are read. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (GetInputRequest->NumRecords <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
{
return STATUS_INVALID_PARAMETER;
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&GetInputRequest->RecordBufPtr,
GetInputRequest->NumRecords,
sizeof(INPUT_RECORD)))
{
return STATUS_INVALID_PARAMETER;
}
}
Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, GetInputRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE);
if (!NT_SUCCESS(Status)) return Status;
GetInputRequest->InputsRead = 0;
InputInfo.CallingThread = CsrGetClientThread();
InputInfo.HandleEntry = HandleEntry;
InputInfo.InputBuffer = InputBuffer;
@@ -389,30 +578,56 @@ CSR_API(SrvWriteConsoleInput)
PCONSOLE_INPUT_BUFFER InputBuffer;
ULONG NumEventsWritten;
PINPUT_RECORD InputRecord;
DPRINT("SrvWriteConsoleInput\n");
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&WriteInputRequest->InputRecord,
WriteInputRequest->Length,
sizeof(INPUT_RECORD)))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than five
* input records are written. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (WriteInputRequest->NumRecords <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
{
return STATUS_INVALID_PARAMETER;
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
InputRecord = WriteInputRequest->RecordStaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&WriteInputRequest->RecordBufPtr,
WriteInputRequest->NumRecords,
sizeof(INPUT_RECORD)))
{
return STATUS_INVALID_PARAMETER;
}
InputRecord = WriteInputRequest->RecordBufPtr;
}
Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
WriteInputRequest->InputHandle,
&InputBuffer, GENERIC_WRITE, TRUE);
if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status))
{
WriteInputRequest->NumRecords = 0;
return Status;
}
NumEventsWritten = 0;
Status = ConDrvWriteConsoleInput(InputBuffer->Header.Console,
InputBuffer,
WriteInputRequest->Unicode,
WriteInputRequest->AppendToEnd,
WriteInputRequest->InputRecord,
WriteInputRequest->Length,
InputRecord,
WriteInputRequest->NumRecords,
&NumEventsWritten);
WriteInputRequest->Length = NumEventsWritten;
WriteInputRequest->NumRecords = NumEventsWritten;
ConSrvReleaseInputBuffer(InputBuffer, TRUE);
return Status;
+1 -10
View File
@@ -9,13 +9,4 @@
#pragma once
VOID FASTCALL PurgeInputBuffer(PCONSOLE Console);
VOID NTAPI
ConDrvProcessKey(IN PCONSOLE Console,
IN BOOLEAN Down,
IN UINT VirtualKeyCode,
IN UINT VirtualScanCode,
IN WCHAR UnicodeChar,
IN ULONG ShiftState,
IN BYTE KeyStateCtrl);
VOID PurgeInputBuffer(PCONSOLE Console);
+221 -74
View File
@@ -373,17 +373,45 @@ DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest;
PTEXTMODE_SCREEN_BUFFER ScreenBuffer;
PVOID Buffer;
ULONG NrCharactersWritten = 0;
ULONG CharSize = (WriteConsoleRequest->Unicode ? sizeof(WCHAR) : sizeof(CHAR));
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process),
WriteConsoleRequest->OutputHandle,
&ScreenBuffer, GENERIC_WRITE, FALSE);
if (!NT_SUCCESS(Status)) return Status;
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than eighty
* bytes are written. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (WriteConsoleRequest->UsingStaticBuffer &&
WriteConsoleRequest->NumBytes <= sizeof(WriteConsoleRequest->StaticBuffer))
{
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
Buffer = WriteConsoleRequest->StaticBuffer;
}
else
{
Buffer = WriteConsoleRequest->Buffer;
}
DPRINT("Calling ConDrvWriteConsole\n");
Status = ConDrvWriteConsole(ScreenBuffer->Header.Console,
ScreenBuffer,
WriteConsoleRequest->Unicode,
WriteConsoleRequest->Buffer,
WriteConsoleRequest->NrCharactersToWrite,
&WriteConsoleRequest->NrCharactersWritten);
Buffer,
WriteConsoleRequest->NumBytes / CharSize, // NrCharactersToWrite
&NrCharactersWritten);
DPRINT("ConDrvWriteConsole returned (%d ; Status = 0x%08x)\n",
NrCharactersWritten, Status);
if (Status == STATUS_PENDING)
{
@@ -404,6 +432,11 @@ DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
/* Wait until we un-pause the console */
// Status = STATUS_PENDING;
}
else
{
/* We read all what we wanted. Set the number of bytes written. */
WriteConsoleRequest->NumBytes = NrCharactersWritten * CharSize;
}
Quit:
ConSrvReleaseScreenBuffer(ScreenBuffer, FALSE);
@@ -418,8 +451,6 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
OUT PCHAR_INFO CharInfo/*Buffer*/,
IN PCOORD BufferSize,
IN PCOORD BufferCoord,
IN OUT PSMALL_RECT ReadRegion);
CSR_API(SrvReadConsoleOutput)
{
@@ -427,14 +458,40 @@ CSR_API(SrvReadConsoleOutput)
PCONSOLE_READOUTPUT ReadOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest;
PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG NumCells;
PCHAR_INFO CharInfo;
DPRINT("SrvReadConsoleOutput\n");
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&ReadOutputRequest->CharInfo,
ReadOutputRequest->BufferSize.X * ReadOutputRequest->BufferSize.Y,
sizeof(CHAR_INFO)))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than one
* cell is read. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
NumCells = (ReadOutputRequest->ReadRegion.Right - ReadOutputRequest->ReadRegion.Left + 1) *
(ReadOutputRequest->ReadRegion.Bottom - ReadOutputRequest->ReadRegion.Top + 1);
if (NumCells <= 1)
{
return STATUS_INVALID_PARAMETER;
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// ReadOutputRequest->CharInfo = &ReadOutputRequest->StaticBuffer;
CharInfo = &ReadOutputRequest->StaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&ReadOutputRequest->CharInfo,
NumCells,
sizeof(CHAR_INFO)))
{
return STATUS_INVALID_PARAMETER;
}
CharInfo = ReadOutputRequest->CharInfo;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
@@ -445,9 +502,7 @@ CSR_API(SrvReadConsoleOutput)
Status = ConDrvReadConsoleOutput(Buffer->Header.Console,
Buffer,
ReadOutputRequest->Unicode,
ReadOutputRequest->CharInfo,
&ReadOutputRequest->BufferSize,
&ReadOutputRequest->BufferCoord,
CharInfo,
&ReadOutputRequest->ReadRegion);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
@@ -459,8 +514,6 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOLEAN Unicode,
IN PCHAR_INFO CharInfo/*Buffer*/,
IN PCOORD BufferSize,
IN PCOORD BufferCoord,
IN OUT PSMALL_RECT WriteRegion);
CSR_API(SrvWriteConsoleOutput)
{
@@ -468,14 +521,40 @@ CSR_API(SrvWriteConsoleOutput)
PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest;
PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG NumCells;
PCHAR_INFO CharInfo;
DPRINT("SrvWriteConsoleOutput\n");
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&WriteOutputRequest->CharInfo,
WriteOutputRequest->BufferSize.X * WriteOutputRequest->BufferSize.Y,
sizeof(CHAR_INFO)))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than one
* cell is written. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
NumCells = (WriteOutputRequest->WriteRegion.Right - WriteOutputRequest->WriteRegion.Left + 1) *
(WriteOutputRequest->WriteRegion.Bottom - WriteOutputRequest->WriteRegion.Top + 1);
if (NumCells <= 1)
{
return STATUS_INVALID_PARAMETER;
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer;
CharInfo = &WriteOutputRequest->StaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&WriteOutputRequest->CharInfo,
NumCells,
sizeof(CHAR_INFO)))
{
return STATUS_INVALID_PARAMETER;
}
CharInfo = WriteOutputRequest->CharInfo;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
@@ -486,9 +565,7 @@ CSR_API(SrvWriteConsoleOutput)
Status = ConDrvWriteConsoleOutput(Buffer->Header.Console,
Buffer,
WriteOutputRequest->Unicode,
WriteOutputRequest->CharInfo,
&WriteOutputRequest->BufferSize,
&WriteOutputRequest->BufferCoord,
CharInfo,
&WriteOutputRequest->WriteRegion);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
@@ -502,12 +579,30 @@ CSR_API(SrvWriteConsole)
DPRINT("SrvWriteConsole\n");
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID)&WriteConsoleRequest->Buffer,
WriteConsoleRequest->BufferSize,
sizeof(BYTE)))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than eighty
* bytes are written. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (WriteConsoleRequest->UsingStaticBuffer &&
WriteConsoleRequest->NumBytes <= sizeof(WriteConsoleRequest->StaticBuffer))
{
return STATUS_INVALID_PARAMETER;
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID)&WriteConsoleRequest->Buffer,
WriteConsoleRequest->NumBytes,
sizeof(BYTE)))
{
return STATUS_INVALID_PARAMETER;
}
}
Status = DoWriteConsole(ApiMessage, CsrGetClientThread(), TRUE);
@@ -524,8 +619,8 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
OUT PVOID StringBuffer,
IN ULONG NumCodesToRead,
IN PCOORD ReadCoord,
OUT PCOORD EndCoord,
OUT PULONG CodesRead);
// OUT PCOORD EndCoord,
OUT PULONG NumCodesRead OPTIONAL);
CSR_API(SrvReadConsoleOutputString)
{
NTSTATUS Status;
@@ -533,47 +628,73 @@ CSR_API(SrvReadConsoleOutputString)
PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG CodeSize;
PVOID pCode;
DPRINT("SrvReadConsoleOutputString\n");
switch (ReadOutputCodeRequest->CodeType)
{
case CODE_ASCII:
CodeSize = sizeof(CHAR);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
break;
case CODE_UNICODE:
CodeSize = sizeof(WCHAR);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
break;
case CODE_ATTRIBUTE:
CodeSize = sizeof(WORD);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
break;
default:
return STATUS_INVALID_PARAMETER;
}
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&ReadOutputCodeRequest->pCode.pCode,
ReadOutputCodeRequest->NumCodesToRead,
CodeSize))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than eighty
* bytes are read. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (ReadOutputCodeRequest->NumCodes * CodeSize <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
{
return STATUS_INVALID_PARAMETER;
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
pCode = ReadOutputCodeRequest->CodeStaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&ReadOutputCodeRequest->pCode,
ReadOutputCodeRequest->NumCodes,
CodeSize))
{
return STATUS_INVALID_PARAMETER;
}
pCode = ReadOutputCodeRequest->pCode;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
ReadOutputCodeRequest->OutputHandle,
&Buffer, GENERIC_READ, TRUE);
if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status))
{
ReadOutputCodeRequest->NumCodes = 0;
return Status;
}
Status = ConDrvReadConsoleOutputString(Buffer->Header.Console,
Buffer,
ReadOutputCodeRequest->CodeType,
ReadOutputCodeRequest->pCode.pCode,
ReadOutputCodeRequest->NumCodesToRead,
&ReadOutputCodeRequest->ReadCoord,
&ReadOutputCodeRequest->EndCoord,
&ReadOutputCodeRequest->CodesRead);
pCode,
ReadOutputCodeRequest->NumCodes,
&ReadOutputCodeRequest->Coord,
// &ReadOutputCodeRequest->EndCoord,
&ReadOutputCodeRequest->NumCodes);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
return Status;
@@ -585,9 +706,9 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
IN CODE_TYPE CodeType,
IN PVOID StringBuffer,
IN ULONG NumCodesToWrite,
IN PCOORD WriteCoord /*,
OUT PCOORD EndCoord,
OUT PULONG CodesWritten */);
IN PCOORD WriteCoord,
// OUT PCOORD EndCoord,
OUT PULONG NumCodesWritten OPTIONAL);
CSR_API(SrvWriteConsoleOutputString)
{
NTSTATUS Status;
@@ -595,49 +716,73 @@ CSR_API(SrvWriteConsoleOutputString)
PTEXTMODE_SCREEN_BUFFER Buffer;
ULONG CodeSize;
PVOID pCode;
DPRINT("SrvWriteConsoleOutputString\n");
switch (WriteOutputCodeRequest->CodeType)
{
case CODE_ASCII:
CodeSize = sizeof(CHAR);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
break;
case CODE_UNICODE:
CodeSize = sizeof(WCHAR);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
break;
case CODE_ATTRIBUTE:
CodeSize = sizeof(WORD);
CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
break;
default:
return STATUS_INVALID_PARAMETER;
}
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&WriteOutputCodeRequest->pCode.pCode,
WriteOutputCodeRequest->Length,
CodeSize))
/*
* For optimization purposes, Windows (and hence ReactOS, too, for
* compatibility reasons) uses a static buffer if no more than eighty
* bytes are written. Otherwise a new buffer is used.
* The client-side expects that we know this behaviour.
*/
if (WriteOutputCodeRequest->NumCodes * CodeSize <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
{
return STATUS_INVALID_PARAMETER;
/*
* Adjust the internal pointer, because its old value points to
* the static buffer in the original ApiMessage structure.
*/
// WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
pCode = WriteOutputCodeRequest->CodeStaticBuffer;
}
else
{
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&WriteOutputCodeRequest->pCode,
WriteOutputCodeRequest->NumCodes,
CodeSize))
{
return STATUS_INVALID_PARAMETER;
}
pCode = WriteOutputCodeRequest->pCode;
}
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
WriteOutputCodeRequest->OutputHandle,
&Buffer, GENERIC_WRITE, TRUE);
if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status))
{
WriteOutputCodeRequest->NumCodes = 0;
return Status;
}
Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console,
Buffer,
WriteOutputCodeRequest->CodeType,
WriteOutputCodeRequest->pCode.pCode,
WriteOutputCodeRequest->Length, // NumCodesToWrite,
&WriteOutputCodeRequest->Coord /*, // WriteCoord,
&WriteOutputCodeRequest->EndCoord,
&WriteOutputCodeRequest->NrCharactersWritten */);
// WriteOutputCodeRequest->NrCharactersWritten = Written;
pCode,
WriteOutputCodeRequest->NumCodes,
&WriteOutputCodeRequest->Coord,
// &WriteOutputCodeRequest->EndCoord,
&WriteOutputCodeRequest->NumCodes);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
return Status;
@@ -647,16 +792,16 @@ NTSTATUS NTAPI
ConDrvFillConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN CODE_TYPE CodeType,
IN PVOID Code,
IN CODE_ELEMENT Code,
IN ULONG NumCodesToWrite,
IN PCOORD WriteCoord /*,
OUT PULONG CodesWritten */);
IN PCOORD WriteCoord,
OUT PULONG NumCodesWritten OPTIONAL);
CSR_API(SrvFillConsoleOutput)
{
NTSTATUS Status;
PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest;
PTEXTMODE_SCREEN_BUFFER Buffer;
USHORT CodeType = FillOutputRequest->CodeType;
CODE_TYPE CodeType = FillOutputRequest->CodeType;
DPRINT("SrvFillConsoleOutput\n");
@@ -670,17 +815,19 @@ CSR_API(SrvFillConsoleOutput)
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
FillOutputRequest->OutputHandle,
&Buffer, GENERIC_WRITE, TRUE);
if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status))
{
FillOutputRequest->NumCodes = 0;
return Status;
}
Status = ConDrvFillConsoleOutput(Buffer->Header.Console,
Buffer,
CodeType,
&FillOutputRequest->Code,
FillOutputRequest->Length, // NumCodesToWrite,
&FillOutputRequest->Coord /*, // WriteCoord,
&FillOutputRequest->NrCharactersWritten */);
// FillOutputRequest->NrCharactersWritten = Written;
FillOutputRequest->Code,
FillOutputRequest->NumCodes,
&FillOutputRequest->WriteCoord,
&FillOutputRequest->NumCodes);
ConSrvReleaseScreenBuffer(Buffer, TRUE);
return Status;
@@ -33,12 +33,12 @@
#define ConSrvReleaseScreenBuffer(Buff, IsConsoleLocked) \
ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked))
NTSTATUS FASTCALL ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
NTSTATUS ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN OUT PCONSOLE Console,
IN ULONG BufferType,
IN PVOID ScreenBufferInfo);
VOID NTAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
// VOID FASTCALL ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
// VOID ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
PCONSOLE_SCREEN_BUFFER
ConDrvGetActiveScreenBuffer(IN PCONSOLE Console);
+456 -137
View File
@@ -14,102 +14,217 @@
#include <ndk/psfuncs.h>
#include <alias.h>
#include "procinit.h"
#ifdef TUITERM_COMPILE
#include "frontends/tui/tuiterm.h"
#endif
#define NDEBUG
#include <debug.h>
// FIXME: Add this prototype to winternl.h / rtlfuncs.h / ...
NTSTATUS NTAPI RtlGetLastNtStatus(VOID);
/* GLOBALS ********************************************************************/
/***************/
#ifdef TUITERM_COMPILE
NTSTATUS NTAPI
TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
IN OUT PCONSOLE_INFO ConsoleInfo,
IN OUT PVOID ExtraConsoleInfo,
IN ULONG ProcessId);
NTSTATUS NTAPI
TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd);
static ULONG ConsoleListSize;
static PCONSOLE* ConsoleList; /* The list of the ConSrv consoles */
static RTL_RESOURCE ListLock;
#define ConSrvLockConsoleListExclusive() \
RtlAcquireResourceExclusive(&ListLock, TRUE)
#define ConSrvLockConsoleListShared() \
RtlAcquireResourceShared(&ListLock, TRUE)
#define ConSrvUnlockConsoleList() \
RtlReleaseResource(&ListLock)
static NTSTATUS
InsertConsole(OUT PHANDLE Handle,
IN PCONSOLE Console)
{
#define CONSOLE_HANDLES_INCREMENT 2 * 3
NTSTATUS Status = STATUS_SUCCESS;
ULONG i = 0;
PCONSOLE* Block;
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
(ConsoleList != NULL && ConsoleListSize != 0) );
/* All went right, so add the console to the list */
ConSrvLockConsoleListExclusive();
DPRINT1("Insert in the list\n");
if (ConsoleList)
{
for (i = 0; i < ConsoleListSize; i++)
{
if (ConsoleList[i] == NULL) break;
}
}
if (i >= ConsoleListSize)
{
DPRINT1("Creation of a new handles table\n");
/* Allocate a new handles table */
Block = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
(ConsoleListSize +
CONSOLE_HANDLES_INCREMENT) * sizeof(PCONSOLE));
if (Block == NULL)
{
Status = STATUS_UNSUCCESSFUL;
goto Quit;
}
/* If we previously had a handles table, free it and use the new one */
if (ConsoleList)
{
/* Copy the handles from the old table to the new one */
RtlCopyMemory(Block,
ConsoleList,
ConsoleListSize * sizeof(PCONSOLE));
ConsoleFreeHeap(ConsoleList);
}
ConsoleList = Block;
ConsoleListSize += CONSOLE_HANDLES_INCREMENT;
}
ConsoleList[i] = Console;
*Handle = ULongToHandle((i << 2) | 0x3);
Quit:
/* Unlock the console list and return status */
ConSrvUnlockConsoleList();
return Status;
}
/* Unused */
#if 0
static NTSTATUS
RemoveConsoleByHandle(IN HANDLE Handle)
{
NTSTATUS Status = STATUS_SUCCESS;
PCONSOLE Console;
BOOLEAN ValidHandle = ((HandleToULong(Handle) & 0x3) == 0x3);
ULONG Index = HandleToULong(Handle) >> 2;
if (!ValidHandle) return STATUS_INVALID_HANDLE;
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
(ConsoleList != NULL && ConsoleListSize != 0) );
/* Remove the console from the list */
ConSrvLockConsoleListExclusive();
if (Index >= ConsoleListSize ||
(Console = ConsoleList[Index]) == NULL)
{
Status = STATUS_INVALID_HANDLE;
goto Quit;
}
ConsoleList[Index] = NULL;
Quit:
/* Unlock the console list and return status */
ConSrvUnlockConsoleList();
return Status;
}
#endif
NTSTATUS NTAPI
GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
IN OUT PCONSOLE_INFO ConsoleInfo,
IN OUT PVOID ExtraConsoleInfo,
IN ULONG ProcessId);
NTSTATUS NTAPI
GuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd);
/***************/
typedef
NTSTATUS (NTAPI *FRONTEND_LOAD)(IN OUT PFRONTEND FrontEnd,
IN OUT PCONSOLE_INFO ConsoleInfo,
IN OUT PVOID ExtraConsoleInfo,
IN ULONG ProcessId);
typedef
NTSTATUS (NTAPI *FRONTEND_UNLOAD)(IN OUT PFRONTEND FrontEnd);
/*
* If we are not in GUI-mode, start the text-mode terminal emulator.
* If we fail, try to start the GUI-mode terminal emulator.
*
* Try to open the GUI-mode terminal emulator. Two cases are possible:
* - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
* failed and we start GUI-mode terminal emulator.
* - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
* succeeded BUT we failed at starting text-mode terminal emulator.
* Then GuiMode was switched to TRUE in order to try to open the GUI-mode
* terminal emulator (Win32k will automatically switch to graphical mode,
* therefore no additional code is needed).
*/
/*
* NOTE: Each entry of the table should be retrieved when loading a front-end
* (examples of the CSR servers which register some data for CSRSS).
*/
struct
static NTSTATUS
RemoveConsoleByPointer(IN PCONSOLE Console)
{
CHAR FrontEndName[80];
FRONTEND_LOAD FrontEndLoad;
FRONTEND_UNLOAD FrontEndUnload;
} FrontEndLoadingMethods[] =
{
#ifdef TUITERM_COMPILE
{"TUI", TuiLoadFrontEnd, TuiUnloadFrontEnd},
#endif
{"GUI", GuiLoadFrontEnd, GuiUnloadFrontEnd},
ULONG i = 0;
// {"Not found", 0, NULL}
};
if (!Console) return STATUS_INVALID_PARAMETER;
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
(ConsoleList != NULL && ConsoleListSize != 0) );
/* Remove the console from the list */
ConSrvLockConsoleListExclusive();
if (ConsoleList)
{
for (i = 0; i < ConsoleListSize; i++)
{
if (ConsoleList[i] == Console) ConsoleList[i] = NULL;
}
}
/* Unlock the console list */
ConSrvUnlockConsoleList();
return STATUS_SUCCESS;
}
BOOLEAN NTAPI
ConSrvValidateConsole(OUT PCONSOLE* Console,
IN HANDLE ConsoleHandle,
IN CONSOLE_STATE ExpectedState,
IN BOOLEAN LockConsole)
{
BOOLEAN RetVal = FALSE;
PCONSOLE ValidatedConsole;
BOOLEAN ValidHandle = ((HandleToULong(ConsoleHandle) & 0x3) == 0x3);
ULONG Index = HandleToULong(ConsoleHandle) >> 2;
if (!ValidHandle) return FALSE;
if (!Console) return FALSE;
*Console = NULL;
/*
* Forbid creation or deletion of consoles when
* checking for the existence of a console.
*/
ConSrvLockConsoleListShared();
if (Index >= ConsoleListSize ||
(ValidatedConsole = ConsoleList[Index]) == NULL)
{
/* Unlock the console list */
ConSrvUnlockConsoleList();
return FALSE;
}
ValidatedConsole = ConsoleList[Index];
/* Unlock the console list and return */
ConSrvUnlockConsoleList();
RetVal = ConDrvValidateConsoleUnsafe(ValidatedConsole,
ExpectedState,
LockConsole);
if (RetVal) *Console = ValidatedConsole;
return RetVal;
}
/* PRIVATE FUNCTIONS **********************************************************/
#if 0000
VOID FASTCALL
VOID
ConioPause(PCONSOLE Console, UINT Flags)
{
Console->PauseFlags |= Flags;
if (!Console->UnpauseEvent)
Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ConDrvPause(Console);
}
VOID FASTCALL
VOID
ConioUnpause(PCONSOLE Console, UINT Flags)
{
Console->PauseFlags &= ~Flags;
// if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
if (Console->PauseFlags == 0 && Console->UnpauseEvent)
if (Console->PauseFlags == 0)
{
SetEvent(Console->UnpauseEvent);
CloseHandle(Console->UnpauseEvent);
Console->UnpauseEvent = NULL;
ConDrvUnpause(Console);
CsrNotifyWait(&Console->WriteWaitQueue,
TRUE,
@@ -121,38 +236,87 @@ ConioUnpause(PCONSOLE Console, UINT Flags)
}
}
}
#endif
NTSTATUS FASTCALL
ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
PCONSOLE* Console,
BOOL LockConsole)
NTSTATUS
ConSrvGetConsole(IN PCONSOLE_PROCESS_DATA ProcessData,
OUT PCONSOLE* Console,
IN BOOLEAN LockConsole)
{
NTSTATUS Status = STATUS_SUCCESS;
PCONSOLE ProcessConsole;
NTSTATUS Status = STATUS_INVALID_HANDLE;
PCONSOLE GrabConsole;
// if (Console == NULL) return STATUS_INVALID_PARAMETER;
ASSERT(Console);
*Console = NULL;
// RtlEnterCriticalSection(&ProcessData->HandleTableLock);
Status = ConDrvGetConsole(&ProcessConsole, ProcessData->ConsoleHandle, LockConsole);
if (NT_SUCCESS(Status)) *Console = ProcessConsole;
if (ConSrvValidateConsole(&GrabConsole,
ProcessData->ConsoleHandle,
CONSOLE_RUNNING,
LockConsole))
{
InterlockedIncrement(&GrabConsole->ReferenceCount);
*Console = GrabConsole;
Status = STATUS_SUCCESS;
}
// RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
VOID FASTCALL
ConSrvReleaseConsole(PCONSOLE Console,
BOOL WasConsoleLocked)
VOID
ConSrvReleaseConsole(IN PCONSOLE Console,
IN BOOLEAN WasConsoleLocked)
{
/* Just call the driver */
ConDrvReleaseConsole(Console, WasConsoleLocked);
LONG RefCount = 0;
if (!Console) return;
// if (Console->ReferenceCount == 0) return; // This shouldn't happen
ASSERT(Console->ReferenceCount > 0);
/* The console must be locked */
// ASSERT(Console_locked);
/*
* Decrement the reference count. Save the new value too,
* because Console->ReferenceCount might be modified after
* the console gets unlocked but before we check whether we
* can destroy it.
*/
RefCount = _InterlockedDecrement(&Console->ReferenceCount);
/* Unlock the console if needed */
if (WasConsoleLocked) LeaveCriticalSection(&Console->Lock);
/* Delete the console if needed */
if (RefCount <= 0) ConSrvDeleteConsole(Console);
}
/* CONSOLE INITIALIZATION FUNCTIONS *******************************************/
VOID NTAPI
ConSrvInitConsoleSupport(VOID)
{
DPRINT("CONSRV: ConSrvInitConsoleSupport()\n");
/* Initialize the console list and its lock */
ConsoleListSize = 0;
ConsoleList = NULL;
RtlInitializeResource(&ListLock);
/* Should call LoadKeyboardLayout */
}
NTSTATUS NTAPI
ConSrvInitTerminal(IN OUT PTERMINAL Terminal,
IN OUT PCONSOLE_INFO ConsoleInfo,
IN OUT PVOID ExtraConsoleInfo,
IN ULONG ProcessId);
NTSTATUS NTAPI
ConSrvDeinitTerminal(IN OUT PTERMINAL Terminal);
NTSTATUS NTAPI
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
OUT PCONSOLE* NewConsole,
@@ -164,8 +328,8 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
PCONSOLE Console;
CONSOLE_INFO ConsoleInfo;
SIZE_T Length = 0;
ULONG i = 0;
FRONTEND FrontEnd;
TERMINAL Terminal; /* The ConSrv terminal for this console */
if (NewConsole == NULL || ConsoleStartInfo == NULL)
return STATUS_INVALID_PARAMETER;
@@ -185,39 +349,18 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length);
ConsoleInfo.ConsoleTitle[Length] = L'\0';
/*
* Choose an adequate terminal front-end to load, and load it
*/
Status = STATUS_SUCCESS;
for (i = 0; i < sizeof(FrontEndLoadingMethods) / sizeof(FrontEndLoadingMethods[0]); ++i)
{
DPRINT("CONSRV: Trying to load %s terminal emulator...\n", FrontEndLoadingMethods[i].FrontEndName);
Status = FrontEndLoadingMethods[i].FrontEndLoad(&FrontEnd,
&ConsoleInfo,
ConsoleStartInfo,
ConsoleLeaderProcessId);
if (NT_SUCCESS(Status))
{
DPRINT("CONSRV: %s terminal emulator loaded successfully\n", FrontEndLoadingMethods[i].FrontEndName);
break;
}
else
{
DPRINT1("CONSRV: Loading %s terminal emulator failed, Status = 0x%08lx , continuing...\n", FrontEndLoadingMethods[i].FrontEndName, Status);
}
}
/* 3. Initialize the ConSrv terminal */
Status = ConSrvInitTerminal(&Terminal,
&ConsoleInfo,
ConsoleStartInfo,
ConsoleLeaderProcessId);
if (!NT_SUCCESS(Status))
{
DPRINT1("CONSRV: Failed to initialize a frontend, Status = 0x%08lx\n", Status);
DPRINT1("CONSRV: Failed to initialize a terminal, Status = 0x%08lx\n", Status);
return Status;
}
DPRINT("CONSRV: Terminal initialized\n");
DPRINT("CONSRV: Frontend initialized\n");
/******************************************************************************/
/*
* 4. Load the remaining console settings via the registry.
*/
@@ -252,31 +395,53 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
/* Set-up the code page */
ConsoleInfo.CodePage = GetOEMCP();
/******************************************************************************/
Status = ConDrvInitConsole(&ConsoleHandle,
&Console,
&ConsoleInfo,
ConsoleLeaderProcessId);
/* Initialize a new console via the driver */
Status = ConDrvInitConsole(&Console, &ConsoleInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("Creating a new console failed, Status = 0x%08lx\n", Status);
FrontEndLoadingMethods[i].FrontEndUnload(&FrontEnd);
ConSrvDeinitTerminal(&Terminal);
return Status;
}
ASSERT(Console);
DPRINT("Console initialized\n");
Status = ConDrvRegisterFrontEnd(Console, &FrontEnd);
/*** Register ConSrv features ***/
/* Initialize process support */
InitializeListHead(&Console->ProcessList);
Console->NotifiedLastCloseProcess = NULL;
Console->NotifyLastClose = FALSE;
/* Initialize pausing support */
Console->PauseFlags = 0;
InitializeListHead(&Console->ReadWaitQueue);
InitializeListHead(&Console->WriteWaitQueue);
/* Initialize the alias and history buffers */
Console->Aliases = NULL;
InitializeListHead(&Console->HistoryBuffers);
Console->HistoryBufferSize = ConsoleInfo.HistoryBufferSize;
Console->NumberOfHistoryBuffers = ConsoleInfo.NumberOfHistoryBuffers;
Console->HistoryNoDup = ConsoleInfo.HistoryNoDup;
Console->QuickEdit = ConsoleInfo.QuickEdit;
/* Attach the ConSrv terminal to the console */
Status = ConDrvRegisterTerminal(Console, &Terminal);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to register frontend to the given console, Status = 0x%08lx\n", Status);
DPRINT1("Failed to register terminal to the given console, Status = 0x%08lx\n", Status);
ConDrvDeleteConsole(Console);
FrontEndLoadingMethods[i].FrontEndUnload(&FrontEnd);
ConSrvDeinitTerminal(&Terminal);
return Status;
}
DPRINT("FrontEnd registered\n");
DPRINT("Terminal registered\n");
/* All went right, so add the console to the list */
Status = InsertConsole(&ConsoleHandle, Console);
/* Return the newly created console to the caller and a success code too */
*NewConsoleHandle = ConsoleHandle;
@@ -289,11 +454,160 @@ ConSrvDeleteConsole(PCONSOLE Console)
{
DPRINT("ConSrvDeleteConsole\n");
/* Just call the driver. ConSrvDeregisterFrontEnd is called on-demand. */
// FIXME: Send a terminate message to all the processes owning this console
/* Remove the console from the list */
RemoveConsoleByPointer(Console);
/* Clean aliases and history */
IntDeleteAllAliases(Console);
HistoryDeleteBuffers(Console);
/* Now, call the driver. ConDrvDeregisterTerminal is called on-demand. */
ConDrvDeleteConsole(Console);
}
static NTSTATUS
ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
IN PCONSOLE_PROCESS_DATA ProcessData,
IN ULONG Timeout)
{
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("ConSrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
if (ProcessData->CtrlDispatcher)
{
_SEH2_TRY
{
HANDLE Thread = NULL;
_SEH2_TRY
{
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
ProcessData->CtrlDispatcher,
UlongToPtr(CtrlEvent), 0, NULL);
if (NULL == Thread)
{
Status = RtlGetLastNtStatus();
DPRINT1("Failed thread creation, Status = 0x%08lx\n", Status);
}
else
{
DPRINT("ProcessData->CtrlDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
WaitForSingleObject(Thread, Timeout);
}
}
_SEH2_FINALLY
{
CloseHandle(Thread);
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
DPRINT1("ConSrvConsoleCtrlEventTimeout - Caught an exception, Status = 0x%08lx\n", Status);
}
_SEH2_END;
}
return Status;
}
NTSTATUS
ConSrvConsoleCtrlEvent(IN ULONG CtrlEvent,
IN PCONSOLE_PROCESS_DATA ProcessData)
{
return ConSrvConsoleCtrlEventTimeout(CtrlEvent, ProcessData, 0);
}
PCONSOLE_PROCESS_DATA NTAPI
ConSrvGetConsoleLeaderProcess(IN PCONSOLE Console)
{
if (Console == NULL) return NULL;
return CONTAINING_RECORD(Console->ProcessList.Blink,
CONSOLE_PROCESS_DATA,
ConsoleLink);
}
NTSTATUS NTAPI
ConSrvGetConsoleProcessList(IN PCONSOLE Console,
IN OUT PULONG ProcessIdsList,
IN ULONG MaxIdListItems,
OUT PULONG ProcessIdsTotal)
{
PCONSOLE_PROCESS_DATA current;
PLIST_ENTRY current_entry;
if (Console == NULL || ProcessIdsList == NULL || ProcessIdsTotal == NULL)
return STATUS_INVALID_PARAMETER;
*ProcessIdsTotal = 0;
for (current_entry = Console->ProcessList.Flink;
current_entry != &Console->ProcessList;
current_entry = current_entry->Flink)
{
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
if (++(*ProcessIdsTotal) <= MaxIdListItems)
{
*ProcessIdsList++ = HandleToUlong(current->Process->ClientId.UniqueProcess);
}
}
return STATUS_SUCCESS;
}
// ConSrvGenerateConsoleCtrlEvent
NTSTATUS NTAPI
ConSrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
IN ULONG ProcessGroupId,
IN ULONG CtrlEvent)
{
NTSTATUS Status = STATUS_SUCCESS;
PLIST_ENTRY current_entry;
PCONSOLE_PROCESS_DATA current;
/* If the console is already being destroyed, just return */
if (!ConDrvValidateConsoleState(Console, CONSOLE_RUNNING))
return STATUS_UNSUCCESSFUL;
/*
* Loop through the process list, from the most recent process
* (the active one) to the oldest one (the first created, i.e.
* the console leader process), and for each, send an event
* (new processes are inserted at the head of the console process list).
*/
current_entry = Console->ProcessList.Flink;
while (current_entry != &Console->ProcessList)
{
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
current_entry = current_entry->Flink;
/*
* Only processes belonging to the same process group are signaled.
* If the process group ID is zero, then all the processes are signaled.
*/
if (ProcessGroupId == 0 || current->Process->ProcessGroupId == ProcessGroupId)
{
Status = ConSrvConsoleCtrlEvent(CtrlEvent, current);
}
}
return Status;
}
/* PUBLIC SERVER APIS *********************************************************/
CSR_API(SrvAllocConsole)
@@ -331,7 +645,7 @@ CSR_API(SrvAllocConsole)
/* Return the console handle and the input wait handle to the caller */
AllocConsoleRequest->ConsoleHandle = ProcessData->ConsoleHandle;
AllocConsoleRequest->InputWaitHandle = ProcessData->ConsoleEvent;
AllocConsoleRequest->InputWaitHandle = ProcessData->InputWaitHandle;
/* Set the Property-Dialog and Control-Dispatcher handlers */
ProcessData->PropDispatcher = AllocConsoleRequest->PropDispatcher;
@@ -408,7 +722,7 @@ CSR_API(SrvAttachConsole)
/* Return the console handle and the input wait handle to the caller */
AttachConsoleRequest->ConsoleHandle = TargetProcessData->ConsoleHandle;
AttachConsoleRequest->InputWaitHandle = TargetProcessData->ConsoleEvent;
AttachConsoleRequest->InputWaitHandle = TargetProcessData->InputWaitHandle;
/* Set the Property-Dialog and Control-Dispatcher handlers */
TargetProcessData->PropDispatcher = AttachConsoleRequest->PropDispatcher;
@@ -591,11 +905,6 @@ CSR_API(SrvSetConsoleCP)
return Status;
}
NTSTATUS NTAPI
ConDrvGetConsoleProcessList(IN PCONSOLE Console,
IN OUT PULONG ProcessIdsList,
IN ULONG MaxIdListItems,
OUT PULONG ProcessIdsTotal);
CSR_API(SrvGetConsoleProcessList)
{
NTSTATUS Status;
@@ -613,7 +922,7 @@ CSR_API(SrvGetConsoleProcessList)
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
Status = ConDrvGetConsoleProcessList(Console,
Status = ConSrvGetConsoleProcessList(Console,
GetProcessListRequest->ProcessIdsList,
GetProcessListRequest->ProcessCount,
&GetProcessListRequest->ProcessCount);
@@ -631,7 +940,7 @@ CSR_API(SrvGenerateConsoleCtrlEvent)
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
Status = ConDrvConsoleProcessCtrlEvent(Console,
Status = ConSrvConsoleProcessCtrlEvent(Console,
GenerateCtrlEventRequest->ProcessGroupId,
GenerateCtrlEventRequest->CtrlEvent);
@@ -668,8 +977,18 @@ CSR_API(SrvConsoleNotifyLastClose)
CSR_API(SrvGetConsoleMouseInfo)
{
DPRINT1("%s not yet implemented\n", __FUNCTION__);
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status;
PCONSOLE_GETMOUSEINFO GetMouseInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetMouseInfoRequest;
PCONSOLE Console;
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
/* Just retrieve the number of buttons of the mouse attached to this console */
GetMouseInfoRequest->NumButtons = GetSystemMetrics(SM_CMOUSEBUTTONS);
ConSrvReleaseConsole(Console, TRUE);
return STATUS_SUCCESS;
}
CSR_API(SrvSetConsoleKeyShortcuts)
+16 -7
View File
@@ -8,8 +8,8 @@
#pragma once
// FIXME: Fix compilation
struct _CONSOLE;
VOID NTAPI
ConSrvInitConsoleSupport(VOID);
NTSTATUS NTAPI
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
@@ -18,8 +18,17 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
IN ULONG ConsoleLeaderProcessId);
VOID NTAPI ConSrvDeleteConsole(struct _CONSOLE* /* PCONSOLE */ Console);
NTSTATUS FASTCALL ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
struct _CONSOLE** /* PCONSOLE* */ Console,
BOOL LockConsole);
VOID FASTCALL ConSrvReleaseConsole(struct _CONSOLE* /* PCONSOLE */ Console,
BOOL WasConsoleLocked);
NTSTATUS
ConSrvGetConsole(IN PCONSOLE_PROCESS_DATA ProcessData,
OUT struct _CONSOLE** /* PCONSOLE* */ Console,
IN BOOLEAN LockConsole);
VOID
ConSrvReleaseConsole(IN struct _CONSOLE* /* PCONSOLE */ Console,
IN BOOLEAN WasConsoleLocked);
BOOLEAN NTAPI
ConSrvValidateConsole(OUT struct _CONSOLE** /* PCONSOLE* */ Console,
IN HANDLE ConsoleHandle,
IN CONSOLE_STATE ExpectedState,
IN BOOLEAN LockConsole);
+2 -2
View File
@@ -51,12 +51,12 @@ typedef struct _CONSOLE_PROCESS_DATA
{
LIST_ENTRY ConsoleLink;
PCSR_PROCESS Process; // Process owning this structure.
HANDLE ConsoleEvent;
HANDLE InputWaitHandle;
HANDLE ConsoleHandle;
HANDLE ParentConsoleHandle;
BOOL ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise.
BOOLEAN ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise.
RTL_CRITICAL_SECTION HandleTableLock;
ULONG HandleTableSize;
@@ -30,7 +30,7 @@
* with NT's, but values are not.
*/
#if 0
static NTSTATUS FASTCALL
static NTSTATUS
SetConsoleHardwareState(PCONSOLE Console, ULONG ConsoleHwState)
{
DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
@@ -48,7 +48,7 @@ SetConWndConsoleLeaderCID(IN PGUI_CONSOLE_DATA GuiData)
PCONSOLE_PROCESS_DATA ProcessData;
CLIENT_ID ConsoleLeaderCID;
ProcessData = ConDrvGetConsoleLeaderProcess(GuiData->Console);
ProcessData = ConSrvGetConsoleLeaderProcess(GuiData->Console);
ConsoleLeaderCID = ProcessData->Process->ClientId;
SetWindowLongPtrW(GuiData->hWindow, GWLP_CONSOLE_LEADER_PID,
(LONG_PTR)(ConsoleLeaderCID.UniqueProcess));
@@ -610,7 +610,6 @@ GuiConsoleSwitchFullScreen(PGUI_CONSOLE_DATA GuiData);
static VOID
OnActivate(PGUI_CONSOLE_DATA GuiData, WPARAM wParam)
{
PCONSOLE Console = GuiData->Console;
WORD ActivationState = LOWORD(wParam);
DPRINT1("WM_ACTIVATE - ActivationState = %d\n");
@@ -637,12 +636,11 @@ OnActivate(PGUI_CONSOLE_DATA GuiData, WPARAM wParam)
}
/*
* When we are in QuickEdit mode, ignore the next mouse signal
* when we are going to be enabled again via the mouse, in order
* to prevent e.g. an erroneous right-click from the user which
* would have as an effect to paste some unwanted text...
* Ignore the next mouse signal when we are going to be enabled again via
* the mouse, in order to prevent, e.g. when we are in Edit mode, erroneous
* mouse actions from the user that could spoil text selection or copy/pastes.
*/
if (Console->QuickEdit && (ActivationState == WA_CLICKACTIVE))
if (ActivationState == WA_CLICKACTIVE)
GuiData->IgnoreNextMouseSignal = TRUE;
}
@@ -947,12 +945,10 @@ GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
static VOID
OnPaint(PGUI_CONSOLE_DATA GuiData)
{
PCONSOLE_SCREEN_BUFFER ActiveBuffer;
PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
PAINTSTRUCT ps;
RECT rcPaint;
ActiveBuffer = GuiData->ActiveBuffer;
BeginPaint(GuiData->hWindow, &ps);
if (ps.hdc != NULL &&
ps.rcPaint.left < ps.rcPaint.right &&
@@ -1325,7 +1321,7 @@ OnClose(PGUI_CONSOLE_DATA GuiData)
* We shouldn't wait here, though, since the console lock is entered.
* A copy of the thread list probably needs to be made.
*/
ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT);
ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT);
LeaveCriticalSection(&Console->Lock);
return FALSE;
@@ -1386,15 +1382,18 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam)
BOOL Err = FALSE;
PCONSOLE Console = GuiData->Console;
// FIXME: It's here that we need to check whether we has focus or not
// and whether we are in edit mode or not, to know if we need to deal
// with the mouse, or not.
if (GuiData->IgnoreNextMouseSignal)
{
if (msg != WM_LBUTTONDOWN &&
msg != WM_MBUTTONDOWN &&
msg != WM_RBUTTONDOWN &&
msg != WM_MOUSEMOVE)
msg != WM_RBUTTONDOWN)
{
/*
* If this mouse signal is not a button-down action or a move,
* If this mouse signal is not a button-down action
* then it is the last signal being ignored.
*/
GuiData->IgnoreNextMouseSignal = FALSE;
@@ -1402,7 +1401,7 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam)
else
{
/*
* This mouse signal is a button-down action or a move.
* This mouse signal is a button-down action.
* Ignore it and perform default action.
*/
Err = TRUE;
@@ -1610,6 +1609,20 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam)
break;
}
/*
* HACK FOR CORE-8394: Ignore the next mouse move signal
* just after mouse down click actions.
*/
switch (msg)
{
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
GuiData->IgnoreNextMouseSignal = TRUE;
default:
break;
}
if (!Err)
{
if (wKeyState & MK_LBUTTON)
@@ -1832,7 +1845,6 @@ OnMove(PGUI_CONSOLE_DATA GuiData)
// HACK: This functionality is standard for general scrollbars. Don't add it by hand.
VOID
FASTCALL
GuiConsoleHandleScrollbarMenu(VOID)
{
HMENU hMenu;
@@ -2071,7 +2083,7 @@ ConWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
/* Detect Alt-Esc/Space/Tab presses defer to DefWindowProc */
if ( (HIWORD(lParam) & KF_ALTDOWN) && (wParam == VK_ESCAPE || wParam == VK_SPACE || wParam == VK_TAB))
{
return DefWindowProcW(hWnd, msg, wParam, lParam);
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
OnKey(GuiData, msg, wParam, lParam);
@@ -357,7 +357,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);
/* Get the console leader process, our client */
ProcessData = ConDrvGetConsoleLeaderProcess(Console);
ProcessData = ConSrvGetConsoleLeaderProcess(Console);
/* Duplicate the section handle for the client */
Status = NtDuplicateObject(NtCurrentProcess(),
@@ -433,7 +433,7 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
/* Get the console leader process, our client */
ProcessData = ConDrvGetConsoleLeaderProcess(Console);
ProcessData = ConSrvGetConsoleLeaderProcess(Console);
/* Duplicate the section handle for ourselves */
Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
@@ -457,7 +457,7 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
&ViewSize,
ViewUnmap,
0,
PAGE_READONLY);
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Error when mapping view of file, Status = %lu\n", Status);
@@ -433,7 +433,7 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
DPRINT1("CONSRV: Failed to create GUI_CONSOLE_DATA\n");
return STATUS_UNSUCCESSFUL;
}
///// /* HACK */ Console->TermIFace.Data = (PVOID)GuiData; /* HACK */
///// /* HACK */ Console->FrontEndIFace.Data = (PVOID)GuiData; /* HACK */
GuiData->Console = Console;
GuiData->ActiveBuffer = Console->ActiveBuffer;
GuiData->hWindow = NULL;
@@ -802,25 +802,6 @@ GuiReleaseScreenBuffer(IN OUT PFRONTEND This,
}
}
static BOOL NTAPI
GuiProcessKeyCallback(IN OUT PFRONTEND This,
MSG* msg,
BYTE KeyStateMenu,
DWORD ShiftState,
UINT VirtualKeyCode,
BOOL Down)
{
if ((ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED) || KeyStateMenu & 0x80) &&
(VirtualKeyCode == VK_ESCAPE || VirtualKeyCode == VK_TAB || VirtualKeyCode == VK_SPACE))
{
DPRINT1("GuiProcessKeyCallback\n");
//DefWindowProcW(msg->hwnd, msg->message, msg->wParam, msg->lParam);
//return TRUE;
}
return FALSE;
}
static BOOL NTAPI
GuiSetMouseCursor(IN OUT PFRONTEND This,
HCURSOR CursorHandle);
@@ -1105,7 +1086,6 @@ static FRONTEND_VTBL GuiVtbl =
GuiResizeTerminal,
GuiSetActiveScreenBuffer,
GuiReleaseScreenBuffer,
GuiProcessKeyCallback,
GuiRefreshInternalInfo,
GuiChangeTitle,
GuiChangeIcon,
@@ -14,7 +14,7 @@
#include "guisettings.h"
#include "conwnd.h"
NTSTATUS FASTCALL GuiInitConsole(PCONSOLE Console,
NTSTATUS GuiInitConsole(PCONSOLE Console,
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
PCONSOLE_INFO ConsoleInfo,
DWORD ProcessId,
@@ -20,7 +20,78 @@
/* PRIVATE FUNCTIONS **********************************************************/
static DWORD FASTCALL
static VOID
ConDrvProcessKey(IN PCONSOLE Console,
IN BOOLEAN Down,
IN UINT VirtualKeyCode,
IN UINT VirtualScanCode,
IN WCHAR UnicodeChar,
IN ULONG ShiftState,
IN BYTE KeyStateCtrl)
{
INPUT_RECORD er;
/* process Ctrl-C and Ctrl-Break */
if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
(ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) )
{
DPRINT1("Console_Api Ctrl-C\n");
ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
if (Console->LineBuffer && !Console->LineComplete)
{
/* Line input is in progress; end it */
Console->LinePos = Console->LineSize = 0;
Console->LineComplete = TRUE;
}
return;
}
if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
(VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) )
{
if (!Down) return;
/* scroll up or down */
if (VK_UP == VirtualKeyCode)
{
/* only scroll up if there is room to scroll up into */
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y++;
}
}
else
{
/* only scroll down if there is room to scroll down into */
if (Console->ActiveBuffer->CursorPosition.Y != 0)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y--;
}
}
ConioDrawConsole(Console);
return;
}
er.EventType = KEY_EVENT;
er.Event.KeyEvent.bKeyDown = Down;
er.Event.KeyEvent.wRepeatCount = 1;
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState;
ConioProcessInputEvent(Console, &er);
}
static DWORD
ConioGetShiftState(PBYTE KeyState, LPARAM lParam)
{
DWORD ssOut = 0;
@@ -104,16 +175,6 @@ ConioProcessKey(PCONSOLE Console, MSG* msg)
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
}
if (TermProcessKeyCallback(Console,
msg,
KeyState[VK_MENU],
ShiftState,
VirtualKeyCode,
Down))
{
return;
}
Fake = UnicodeChar &&
(msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
@@ -143,4 +204,14 @@ ConioProcessKey(PCONSOLE Console, MSG* msg)
KeyState[VK_CONTROL]);
}
DWORD
ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale)
{
DWORD Size = (Console->ActiveBuffer->CursorInfo.dwSize * Scale + 99) / 100;
/* If line input in progress, perhaps adjust for insert toggle */
if (Console->LineBuffer && !Console->LineComplete && (Console->InsertMode ? !Console->LineInsertToggle : Console->LineInsertToggle))
return (Size * 2 <= Scale) ? (Size * 2) : (Size / 2);
return Size;
}
/* EOF */
@@ -0,0 +1,363 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: frontends/terminal.c
* PURPOSE: ConSrv terminal.
* PROGRAMMERS: Hermes Belusca-Maito ([email protected])
*/
/* INCLUDES *******************************************************************/
#include <consrv.h>
// #include "frontends/gui/guiterm.h"
#ifdef TUITERM_COMPILE
#include "frontends/tui/tuiterm.h"
#endif
#define NDEBUG
#include <debug.h>
/* CONSRV TERMINAL FRONTENDS INTERFACE ****************************************/
/***************/
#ifdef TUITERM_COMPILE
NTSTATUS NTAPI
TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
IN OUT PCONSOLE_INFO ConsoleInfo,
IN OUT PVOID ExtraConsoleInfo,
IN ULONG ProcessId);
NTSTATUS NTAPI
TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd);
#endif
NTSTATUS NTAPI
GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
IN OUT PCONSOLE_INFO ConsoleInfo,
IN OUT PVOID ExtraConsoleInfo,
IN ULONG ProcessId);
NTSTATUS NTAPI
GuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd);
/***************/
typedef
NTSTATUS (NTAPI *FRONTEND_LOAD)(IN OUT PFRONTEND FrontEnd,
IN OUT PCONSOLE_INFO ConsoleInfo,
IN OUT PVOID ExtraConsoleInfo,
IN ULONG ProcessId);
typedef
NTSTATUS (NTAPI *FRONTEND_UNLOAD)(IN OUT PFRONTEND FrontEnd);
/*
* If we are not in GUI-mode, start the text-mode terminal emulator.
* If we fail, try to start the GUI-mode terminal emulator.
*
* Try to open the GUI-mode terminal emulator. Two cases are possible:
* - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
* failed and we start GUI-mode terminal emulator.
* - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
* succeeded BUT we failed at starting text-mode terminal emulator.
* Then GuiMode was switched to TRUE in order to try to open the GUI-mode
* terminal emulator (Win32k will automatically switch to graphical mode,
* therefore no additional code is needed).
*/
/*
* NOTE: Each entry of the table should be retrieved when loading a front-end
* (examples of the CSR servers which register some data for CSRSS).
*/
struct
{
CHAR FrontEndName[80];
FRONTEND_LOAD FrontEndLoad;
FRONTEND_UNLOAD FrontEndUnload;
} FrontEndLoadingMethods[] =
{
#ifdef TUITERM_COMPILE
{"TUI", TuiLoadFrontEnd, TuiUnloadFrontEnd},
#endif
{"GUI", GuiLoadFrontEnd, GuiUnloadFrontEnd},
// {"Not found", 0, NULL}
};
static NTSTATUS
ConSrvLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
IN OUT PCONSOLE_INFO ConsoleInfo,
IN OUT PVOID ExtraConsoleInfo,
IN ULONG ProcessId)
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG i;
/*
* Choose an adequate terminal front-end to load, and load it
*/
for (i = 0; i < sizeof(FrontEndLoadingMethods) / sizeof(FrontEndLoadingMethods[0]); ++i)
{
DPRINT("CONSRV: Trying to load %s frontend...\n",
FrontEndLoadingMethods[i].FrontEndName);
Status = FrontEndLoadingMethods[i].FrontEndLoad(FrontEnd,
ConsoleInfo,
ExtraConsoleInfo,
ProcessId);
if (NT_SUCCESS(Status))
{
/* Save the unload callback */
FrontEnd->UnloadFrontEnd = FrontEndLoadingMethods[i].FrontEndUnload;
DPRINT("CONSRV: %s frontend loaded successfully\n",
FrontEndLoadingMethods[i].FrontEndName);
break;
}
else
{
DPRINT1("CONSRV: Loading %s frontend failed, Status = 0x%08lx , continuing...\n",
FrontEndLoadingMethods[i].FrontEndName, Status);
}
}
return Status;
}
static NTSTATUS
ConSrvUnloadFrontEnd(IN PFRONTEND FrontEnd)
{
if (FrontEnd == NULL) return STATUS_INVALID_PARAMETER;
// return FrontEnd->Vtbl->UnloadFrontEnd(FrontEnd);
return FrontEnd->UnloadFrontEnd(FrontEnd);
}
// See after...
static TERMINAL_VTBL ConSrvTermVtbl;
NTSTATUS NTAPI
ConSrvInitTerminal(IN OUT PTERMINAL Terminal,
IN OUT PCONSOLE_INFO ConsoleInfo,
IN OUT PVOID ExtraConsoleInfo,
IN ULONG ProcessId)
{
NTSTATUS Status;
PFRONTEND FrontEnd;
/* Load a suitable frontend for the ConSrv terminal */
FrontEnd = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*FrontEnd));
if (!FrontEnd) return STATUS_NO_MEMORY;
Status = ConSrvLoadFrontEnd(FrontEnd,
ConsoleInfo,
ExtraConsoleInfo,
ProcessId);
if (!NT_SUCCESS(Status))
{
DPRINT1("CONSRV: Failed to initialize a frontend, Status = 0x%08lx\n", Status);
ConsoleFreeHeap(FrontEnd);
return Status;
}
DPRINT("CONSRV: Frontend initialized\n");
/* Initialize the ConSrv terminal */
Terminal->Vtbl = &ConSrvTermVtbl;
// Terminal->Console will be initialized by ConDrvRegisterTerminal
Terminal->Data = FrontEnd; /* We store the frontend pointer in the terminal private data */
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
ConSrvDeinitTerminal(IN OUT PTERMINAL Terminal)
{
NTSTATUS Status = STATUS_SUCCESS;
PFRONTEND FrontEnd = Terminal->Data;
/* Reset the ConSrv terminal */
Terminal->Data = NULL;
Terminal->Vtbl = NULL;
/* Unload the frontend */
if (FrontEnd != NULL)
{
Status = ConSrvUnloadFrontEnd(FrontEnd);
ConsoleFreeHeap(FrontEnd);
}
return Status;
}
/* CONSRV TERMINAL INTERFACE **************************************************/
static NTSTATUS NTAPI
ConSrvTermInitTerminal(IN OUT PTERMINAL This,
IN PCONSOLE Console)
{
NTSTATUS Status;
PFRONTEND FrontEnd = This->Data;
/* Initialize the console pointer for our frontend */
FrontEnd->Console = Console;
/** HACK HACK!! Copy FrontEnd into the console!! **/
DPRINT1("Using FrontEndIFace HACK(1), should be removed after proper implementation!\n");
Console->FrontEndIFace = *FrontEnd;
Status = FrontEnd->Vtbl->InitFrontEnd(FrontEnd, FrontEnd->Console);
/** HACK HACK!! Be sure FrontEndIFace is correctly updated in the console!! **/
DPRINT1("Using FrontEndIFace HACK(2), should be removed after proper implementation!\n");
Console->FrontEndIFace = *FrontEnd;
return Status;
}
static VOID NTAPI
ConSrvTermDeinitTerminal(IN OUT PTERMINAL This)
{
PFRONTEND FrontEnd = This->Data;
FrontEnd->Vtbl->DeinitFrontEnd(FrontEnd);
}
static VOID NTAPI
ConSrvTermDrawRegion(IN OUT PTERMINAL This,
SMALL_RECT* Region)
{
PFRONTEND FrontEnd = This->Data;
FrontEnd->Vtbl->DrawRegion(FrontEnd, Region);
}
static VOID NTAPI
ConSrvTermWriteStream(IN OUT PTERMINAL This,
SMALL_RECT* Region,
SHORT CursorStartX,
SHORT CursorStartY,
UINT ScrolledLines,
PWCHAR Buffer,
UINT Length)
{
PFRONTEND FrontEnd = This->Data;
FrontEnd->Vtbl->WriteStream(FrontEnd,
Region,
CursorStartX,
CursorStartY,
ScrolledLines,
Buffer,
Length);
}
static BOOL NTAPI
ConSrvTermSetCursorInfo(IN OUT PTERMINAL This,
PCONSOLE_SCREEN_BUFFER ScreenBuffer)
{
PFRONTEND FrontEnd = This->Data;
return FrontEnd->Vtbl->SetCursorInfo(FrontEnd, ScreenBuffer);
}
static BOOL NTAPI
ConSrvTermSetScreenInfo(IN OUT PTERMINAL This,
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
SHORT OldCursorX,
SHORT OldCursorY)
{
PFRONTEND FrontEnd = This->Data;
return FrontEnd->Vtbl->SetScreenInfo(FrontEnd,
ScreenBuffer,
OldCursorX,
OldCursorY);
}
static VOID NTAPI
ConSrvTermResizeTerminal(IN OUT PTERMINAL This)
{
PFRONTEND FrontEnd = This->Data;
FrontEnd->Vtbl->ResizeTerminal(FrontEnd);
}
static VOID NTAPI
ConSrvTermSetActiveScreenBuffer(IN OUT PTERMINAL This)
{
PFRONTEND FrontEnd = This->Data;
FrontEnd->Vtbl->SetActiveScreenBuffer(FrontEnd);
}
static VOID NTAPI
ConSrvTermReleaseScreenBuffer(IN OUT PTERMINAL This,
IN PCONSOLE_SCREEN_BUFFER ScreenBuffer)
{
PFRONTEND FrontEnd = This->Data;
FrontEnd->Vtbl->ReleaseScreenBuffer(FrontEnd, ScreenBuffer);
}
static VOID NTAPI
ConSrvTermChangeTitle(IN OUT PTERMINAL This)
{
PFRONTEND FrontEnd = This->Data;
FrontEnd->Vtbl->ChangeTitle(FrontEnd);
}
static VOID NTAPI
ConSrvTermGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
PCOORD pSize)
{
PFRONTEND FrontEnd = This->Data;
FrontEnd->Vtbl->GetLargestConsoleWindowSize(FrontEnd, pSize);
}
/*
static BOOL NTAPI
ConSrvTermGetSelectionInfo(IN OUT PTERMINAL This,
PCONSOLE_SELECTION_INFO pSelectionInfo)
{
PFRONTEND FrontEnd = This->Data;
return FrontEnd->Vtbl->GetSelectionInfo(FrontEnd, pSelectionInfo);
}
*/
static BOOL NTAPI
ConSrvTermSetPalette(IN OUT PTERMINAL This,
HPALETTE PaletteHandle,
UINT PaletteUsage)
{
PFRONTEND FrontEnd = This->Data;
return FrontEnd->Vtbl->SetPalette(FrontEnd, PaletteHandle, PaletteUsage);
}
static INT NTAPI
ConSrvTermShowMouseCursor(IN OUT PTERMINAL This,
BOOL Show)
{
PFRONTEND FrontEnd = This->Data;
return FrontEnd->Vtbl->ShowMouseCursor(FrontEnd, Show);
}
static TERMINAL_VTBL ConSrvTermVtbl =
{
ConSrvTermInitTerminal,
ConSrvTermDeinitTerminal,
ConSrvTermDrawRegion,
ConSrvTermWriteStream,
ConSrvTermSetCursorInfo,
ConSrvTermSetScreenInfo,
ConSrvTermResizeTerminal,
ConSrvTermSetActiveScreenBuffer,
ConSrvTermReleaseScreenBuffer,
ConSrvTermChangeTitle,
ConSrvTermGetLargestConsoleWindowSize,
// ConSrvTermGetSelectionInfo,
ConSrvTermSetPalette,
ConSrvTermShowMouseCursor,
};
#if 0
VOID
ResetFrontEnd(IN PCONSOLE Console)
{
if (!Console) return;
/* Reinitialize the frontend interface */
RtlZeroMemory(&Console->FrontEndIFace, sizeof(Console->FrontEndIFace));
Console->FrontEndIFace.Vtbl = &ConSrvTermVtbl;
}
#endif
/* EOF */
@@ -24,13 +24,6 @@
/* GLOBALS ********************************************************************/
#define GetNextConsole(Console) \
CONTAINING_RECORD(Console->Entry.Flink, TUI_CONSOLE_DATA, Entry)
#define GetPrevConsole(Console) \
CONTAINING_RECORD(Console->Entry.Blink, TUI_CONSOLE_DATA, Entry)
/* TUI Console Window Class name */
#define TUI_CONSOLE_WINDOW_CLASS L"TuiConsoleWindowClass"
@@ -46,6 +39,13 @@ typedef struct _TUI_CONSOLE_DATA
// TUI_CONSOLE_INFO TuiInfo; /* TUI terminal settings */
} TUI_CONSOLE_DATA, *PTUI_CONSOLE_DATA;
#define GetNextConsole(Console) \
CONTAINING_RECORD(Console->Entry.Flink, TUI_CONSOLE_DATA, Entry)
#define GetPrevConsole(Console) \
CONTAINING_RECORD(Console->Entry.Blink, TUI_CONSOLE_DATA, Entry)
/* List of the maintained virtual consoles and its lock */
static LIST_ENTRY VirtConsList;
static PTUI_CONSOLE_DATA ActiveConsole; /* The active console on screen */
@@ -164,7 +164,7 @@ done:
/**\
\******************************************************************************/
static BOOL FASTCALL
static BOOL
TuiSwapConsole(INT Next)
{
static PTUI_CONSOLE_DATA SwapConsole = NULL; /* Console we are thinking about swapping with */
@@ -231,7 +231,7 @@ TuiSwapConsole(INT Next)
}
}
static VOID FASTCALL
static VOID
TuiCopyRect(PCHAR Dest, PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
{
UINT SrcDelta, DestDelta;
@@ -276,6 +276,21 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_KEYUP:
case WM_SYSKEYUP:
{
#if 0
if ((HIWORD(lParam) & KF_ALTDOWN) && wParam == VK_TAB)
{
// if ((HIWORD(lParam) & (KF_UP | KF_REPEAT)) != KF_REPEAT)
TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
break;
}
else if (wParam == VK_MENU /* && !Down */)
{
TuiSwapConsole(0);
break;
}
#endif
if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE))
{
MSG Message;
@@ -459,7 +474,7 @@ TuiInitFrontEnd(IN OUT PFRONTEND This,
// return STATUS_INVALID_PARAMETER;
// /* Initialize the console */
// Console->TermIFace.Vtbl = &TuiVtbl;
// Console->FrontEndIFace.Vtbl = &TuiVtbl;
TuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(TUI_CONSOLE_DATA));
if (!TuiData)
@@ -467,7 +482,7 @@ TuiInitFrontEnd(IN OUT PFRONTEND This,
DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n");
return STATUS_UNSUCCESSFUL;
}
// Console->TermIFace.Data = (PVOID)TuiData;
// Console->FrontEndIFace.Data = (PVOID)TuiData;
TuiData->Console = Console;
TuiData->hWindow = NULL;
@@ -525,7 +540,7 @@ static VOID NTAPI
TuiDeinitFrontEnd(IN OUT PFRONTEND This)
{
// PCONSOLE Console = This->Console;
PTUI_CONSOLE_DATA TuiData = This->Data; // Console->TermIFace.Data;
PTUI_CONSOLE_DATA TuiData = This->Data; // Console->FrontEndIFace.Data;
/* Close the notification window */
DestroyWindow(TuiData->hWindow);
@@ -556,7 +571,7 @@ TuiDeinitFrontEnd(IN OUT PFRONTEND This)
/* Switch to the next console */
if (NULL != ActiveConsole) ConioDrawConsole(ActiveConsole->Console);
// Console->TermIFace.Data = NULL;
// Console->FrontEndIFace.Data = NULL;
This->Data = NULL;
DeleteCriticalSection(&TuiData->Lock);
ConsoleFreeHeap(TuiData);
@@ -688,32 +703,6 @@ TuiResizeTerminal(IN OUT PFRONTEND This)
{
}
static BOOL NTAPI
TuiProcessKeyCallback(IN OUT PFRONTEND This,
MSG* msg,
BYTE KeyStateMenu,
DWORD ShiftState,
UINT VirtualKeyCode,
BOOL Down)
{
if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) &&
VK_TAB == VirtualKeyCode)
{
if (Down)
{
TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
}
return TRUE;
}
else if (VK_MENU == VirtualKeyCode && !Down)
{
return TuiSwapConsole(0);
}
return FALSE;
}
static VOID NTAPI
TuiRefreshInternalInfo(IN OUT PFRONTEND This)
{
@@ -814,7 +803,6 @@ static FRONTEND_VTBL TuiVtbl =
TuiSetCursorInfo,
TuiSetScreenInfo,
TuiResizeTerminal,
TuiProcessKeyCallback,
TuiRefreshInternalInfo,
TuiChangeTitle,
TuiChangeIcon,
@@ -11,7 +11,7 @@
#pragma once
NTSTATUS FASTCALL TuiInitConsole(PCONSOLE Console,
NTSTATUS TuiInitConsole(PCONSOLE Console,
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
PCONSOLE_INFO ConsoleInfo,
DWORD ProcessId);
+15 -22
View File
@@ -72,7 +72,8 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
*/
if (Object->Type == INPUT_BUFFER)
{
PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
// PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
PCONSOLE Console = Object->Console;
/*
* Wake up all the writing waiters related to this handle for this
@@ -83,13 +84,13 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
* whether or not they are related to this handle and if so, they
* return.
*/
CsrNotifyWait(&InputBuffer->ReadWaitQueue,
CsrNotifyWait(&Console->ReadWaitQueue,
TRUE,
NULL,
(PVOID)Entry);
if (!IsListEmpty(&InputBuffer->ReadWaitQueue))
if (!IsListEmpty(&Console->ReadWaitQueue))
{
CsrDereferenceWait(&InputBuffer->ReadWaitQueue);
CsrDereferenceWait(&Console->ReadWaitQueue);
}
}
@@ -290,7 +291,6 @@ ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
}
VOID
FASTCALL
ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object,
IN CONSOLE_IO_OBJECT_TYPE Type,
IN PCONSOLE Console)
@@ -306,7 +306,6 @@ ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object,
}
NTSTATUS
FASTCALL
ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE Handle,
PCONSOLE_IO_OBJECT Object,
@@ -372,7 +371,6 @@ ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
}
NTSTATUS
FASTCALL
ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
HANDLE Handle)
{
@@ -399,7 +397,6 @@ ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
}
NTSTATUS
FASTCALL
ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
HANDLE Handle,
PCONSOLE_IO_OBJECT* Object,
@@ -443,7 +440,7 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
// Status = ConDrvGetConsole(&ObjectConsole, ProcessData->ConsoleHandle, LockConsole);
// Status = ConSrvGetConsole(ProcessData, &ObjectConsole, LockConsole);
// if (NT_SUCCESS(Status))
if (ConDrvValidateConsoleUnsafe(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole))
{
@@ -464,7 +461,6 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
}
VOID
FASTCALL
ConSrvReleaseObject(PCONSOLE_IO_OBJECT Object,
BOOL IsConsoleLocked)
{
@@ -472,7 +468,6 @@ ConSrvReleaseObject(PCONSOLE_IO_OBJECT Object,
}
NTSTATUS
FASTCALL
ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
@@ -527,7 +522,7 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
Status = NtDuplicateObject(NtCurrentProcess(),
Console->InputBuffer.ActiveEvent,
ProcessData->Process->ProcessHandle,
&ProcessData->ConsoleEvent,
&ProcessData->InputWaitHandle,
EVENT_ALL_ACCESS, 0, 0);
if (!NT_SUCCESS(Status))
{
@@ -551,7 +546,6 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
}
NTSTATUS
FASTCALL
ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
HANDLE ConsoleHandle,
BOOL CreateNewHandlesTable,
@@ -563,7 +557,7 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
PCONSOLE Console;
/* Validate and lock the console */
if (!ConDrvValidateConsole(&Console,
if (!ConSrvValidateConsole(&Console,
ConsoleHandle,
CONSOLE_RUNNING, TRUE))
{
@@ -606,7 +600,7 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
Status = NtDuplicateObject(NtCurrentProcess(),
Console->InputBuffer.ActiveEvent,
ProcessData->Process->ProcessHandle,
&ProcessData->ConsoleEvent,
&ProcessData->InputWaitHandle,
EVENT_ALL_ACCESS, 0, 0);
if (!NT_SUCCESS(Status))
{
@@ -634,7 +628,6 @@ Quit:
}
VOID
FASTCALL
ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
{
PCONSOLE Console;
@@ -644,12 +637,12 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
// RtlEnterCriticalSection(&ProcessData->HandleTableLock);
/* Validate and lock the console */
if (ConDrvValidateConsole(&Console,
if (ConSrvValidateConsole(&Console,
ProcessData->ConsoleHandle,
CONSOLE_RUNNING, TRUE))
{
/* Retrieve the console leader process */
PCONSOLE_PROCESS_DATA ConsoleLeaderProcess = ConDrvGetConsoleLeaderProcess(Console);
PCONSOLE_PROCESS_DATA ConsoleLeaderProcess = ConSrvGetConsoleLeaderProcess(Console);
DPRINT("ConSrvRemoveConsole - Locking OK\n");
@@ -684,7 +677,7 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
* and then send the last close notification.
*/
Console->NotifyLastClose = FALSE;
ConDrvConsoleCtrlEvent(CTRL_LAST_CLOSE_EVENT, Console->NotifiedLastCloseProcess);
ConSrvConsoleCtrlEvent(CTRL_LAST_CLOSE_EVENT, Console->NotifiedLastCloseProcess);
/* Only now, reset the pointer */
Console->NotifiedLastCloseProcess = NULL;
@@ -696,9 +689,9 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
/* Release the console */
DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount);
ConDrvReleaseConsole(Console, TRUE);
//CloseHandle(ProcessData->ConsoleEvent);
//ProcessData->ConsoleEvent = NULL;
ConSrvReleaseConsole(Console, TRUE);
//CloseHandle(ProcessData->InputWaitHandle);
//ProcessData->InputWaitHandle = NULL;
}
// RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+5 -5
View File
@@ -10,23 +10,23 @@
#pragma once
VOID FASTCALL ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object,
VOID ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object,
IN CONSOLE_IO_OBJECT_TYPE Type,
IN PCONSOLE Console);
NTSTATUS FASTCALL ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
NTSTATUS ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE Handle,
PCONSOLE_IO_OBJECT Object,
DWORD Access,
BOOL Inheritable,
DWORD ShareMode);
NTSTATUS FASTCALL ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
NTSTATUS ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
HANDLE Handle);
NTSTATUS FASTCALL ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
NTSTATUS ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
HANDLE Handle,
PCONSOLE_IO_OBJECT* Object,
PVOID* Entry OPTIONAL,
DWORD Access,
BOOL LockConsole,
CONSOLE_IO_OBJECT_TYPE Type);
VOID FASTCALL ConSrvReleaseObject(PCONSOLE_IO_OBJECT Object,
VOID ConSrvReleaseObject(PCONSOLE_IO_OBJECT Object,
BOOL IsConsoleLocked);
@@ -1,7 +1,7 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/winsrv/consrv/include/conio.h
* FILE: consrv/include/conio.h
* PURPOSE: Public Console I/O Interface
* PROGRAMMERS: Gé van Geldorp
* Jeffrey Morlan
@@ -10,6 +10,8 @@
#pragma once
#include "rect.h"
#define CSR_DEFAULT_CURSOR_SIZE 25
/* Default attributes */
@@ -64,8 +66,6 @@ struct _CONSOLE_SCREEN_BUFFER
LIST_ENTRY ListEntry; /* Entry in console's list of buffers */
// PVOID Data; /* Private data for the frontend to use */
COORD ScreenBufferSize; /* Size of this screen buffer. (Rows, Columns) for text-mode and (Width, Height) for graphics-mode */
COORD ViewSize; /* Associated "view" (i.e. console) size */
@@ -90,6 +90,8 @@ struct _CONSOLE_SCREEN_BUFFER
// WORD ScreenDefaultAttrib; /* Default screen char attribute */
// WORD PopupDefaultAttrib; /* Default popup char attribute */
USHORT Mode; /* Output buffer modes */
// PVOID Data; /* Private data for the frontend to use */
};
@@ -125,8 +127,8 @@ typedef struct _TEXTMODE_BUFFER_INFO
COORD ScreenBufferSize;
USHORT ScreenAttrib;
USHORT PopupAttrib;
BOOLEAN IsCursorVisible;
ULONG CursorSize;
BOOLEAN IsCursorVisible;
} TEXTMODE_BUFFER_INFO, *PTEXTMODE_BUFFER_INFO;
typedef struct _TEXTMODE_SCREEN_BUFFER
@@ -158,6 +160,7 @@ typedef struct _GRAPHICS_SCREEN_BUFFER
ULONG BitMapUsage; /* See the uUsage parameter of GetDIBits */
HANDLE hSection; /* Handle to the memory shared section for the bitmap buffer */
PVOID BitMap; /* Our bitmap buffer */
PVOID ClientBitMap; /* A copy of the client view of our bitmap buffer */
HANDLE Mutex; /* Our mutex, used to synchronize read / writes to the bitmap buffer */
HANDLE ClientMutex; /* A copy of the client handle to our mutex */
@@ -173,97 +176,75 @@ typedef struct _CONSOLE_INPUT_BUFFER
ULONG InputBufferSize; /* Size of this input buffer */
LIST_ENTRY InputEvents; /* List head for input event queue */
HANDLE ActiveEvent; /* Event set when an input event is added in its queue */
LIST_ENTRY ReadWaitQueue; /* List head for the queue of read wait blocks */
USHORT Mode; /* Input buffer modes */
} CONSOLE_INPUT_BUFFER, *PCONSOLE_INPUT_BUFFER;
typedef struct _FRONTEND FRONTEND, *PFRONTEND;
typedef struct _TERMINAL TERMINAL, *PTERMINAL;
/* HACK: */ typedef struct _CONSOLE_INFO *PCONSOLE_INFO;
typedef struct _FRONTEND_VTBL
typedef struct _TERMINAL_VTBL
{
/*
* Internal interface (functions called by the console server only)
*/
NTSTATUS (NTAPI *InitFrontEnd)(IN OUT PFRONTEND This,
NTSTATUS (NTAPI *InitTerminal)(IN OUT PTERMINAL This,
IN struct _CONSOLE* Console);
VOID (NTAPI *DeinitFrontEnd)(IN OUT PFRONTEND This);
VOID (NTAPI *DeinitTerminal)(IN OUT PTERMINAL This);
/* Interface used for both text-mode and graphics screen buffers */
VOID (NTAPI *DrawRegion)(IN OUT PFRONTEND This,
VOID (NTAPI *DrawRegion)(IN OUT PTERMINAL This,
SMALL_RECT* Region);
/* Interface used only for text-mode screen buffers */
VOID (NTAPI *WriteStream)(IN OUT PFRONTEND This,
SMALL_RECT* Block,
VOID (NTAPI *WriteStream)(IN OUT PTERMINAL This,
SMALL_RECT* Region,
SHORT CursorStartX,
SHORT CursorStartY,
UINT ScrolledLines,
PWCHAR Buffer,
UINT Length);
BOOL (NTAPI *SetCursorInfo)(IN OUT PFRONTEND This,
BOOL (NTAPI *SetCursorInfo)(IN OUT PTERMINAL This,
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
BOOL (NTAPI *SetScreenInfo)(IN OUT PFRONTEND This,
BOOL (NTAPI *SetScreenInfo)(IN OUT PTERMINAL This,
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
SHORT OldCursorX,
SHORT OldCursorY);
VOID (NTAPI *ResizeTerminal)(IN OUT PFRONTEND This);
VOID (NTAPI *SetActiveScreenBuffer)(IN OUT PFRONTEND This);
VOID (NTAPI *ReleaseScreenBuffer)(IN OUT PFRONTEND This,
VOID (NTAPI *ResizeTerminal)(IN OUT PTERMINAL This);
VOID (NTAPI *SetActiveScreenBuffer)(IN OUT PTERMINAL This);
VOID (NTAPI *ReleaseScreenBuffer)(IN OUT PTERMINAL This,
IN PCONSOLE_SCREEN_BUFFER ScreenBuffer);
BOOL (NTAPI *ProcessKeyCallback)(IN OUT PFRONTEND This,
MSG* msg,
BYTE KeyStateMenu,
DWORD ShiftState,
UINT VirtualKeyCode,
BOOL Down);
VOID (NTAPI *RefreshInternalInfo)(IN OUT PFRONTEND This);
/*
* External interface (functions corresponding to the Console API)
*/
VOID (NTAPI *ChangeTitle)(IN OUT PFRONTEND This);
BOOL (NTAPI *ChangeIcon)(IN OUT PFRONTEND This,
HICON IconHandle);
HWND (NTAPI *GetConsoleWindowHandle)(IN OUT PFRONTEND This);
VOID (NTAPI *GetLargestConsoleWindowSize)(IN OUT PFRONTEND This,
VOID (NTAPI *ChangeTitle)(IN OUT PTERMINAL This);
VOID (NTAPI *GetLargestConsoleWindowSize)(IN OUT PTERMINAL This,
PCOORD pSize);
BOOL (NTAPI *GetSelectionInfo)(IN OUT PFRONTEND This,
PCONSOLE_SELECTION_INFO pSelectionInfo);
BOOL (NTAPI *SetPalette)(IN OUT PFRONTEND This,
// BOOL (NTAPI *GetSelectionInfo)(IN OUT PTERMINAL This,
// PCONSOLE_SELECTION_INFO pSelectionInfo);
BOOL (NTAPI *SetPalette)(IN OUT PTERMINAL This,
HPALETTE PaletteHandle,
UINT PaletteUsage);
ULONG (NTAPI *GetDisplayMode)(IN OUT PFRONTEND This);
BOOL (NTAPI *SetDisplayMode)(IN OUT PFRONTEND This,
ULONG NewMode);
INT (NTAPI *ShowMouseCursor)(IN OUT PFRONTEND This,
INT (NTAPI *ShowMouseCursor)(IN OUT PTERMINAL This,
BOOL Show);
BOOL (NTAPI *SetMouseCursor)(IN OUT PFRONTEND This,
HCURSOR CursorHandle);
HMENU (NTAPI *MenuControl)(IN OUT PFRONTEND This,
UINT CmdIdLow,
UINT CmdIdHigh);
BOOL (NTAPI *SetMenuClose)(IN OUT PFRONTEND This,
BOOL Enable);
#if 0 // Possible future front-end interface
BOOL (NTAPI *GetFrontEndProperty)(IN OUT PFRONTEND This,
BOOL (NTAPI *GetTerminalProperty)(IN OUT PTERMINAL This,
ULONG Flag,
PVOID Info,
ULONG Size);
BOOL (NTAPI *SetFrontEndProperty)(IN OUT PFRONTEND This,
BOOL (NTAPI *SetTerminalProperty)(IN OUT PTERMINAL This,
ULONG Flag,
PVOID Info /*,
ULONG Size */);
#endif
} FRONTEND_VTBL, *PFRONTEND_VTBL;
} TERMINAL_VTBL, *PTERMINAL_VTBL;
struct _FRONTEND
struct _TERMINAL
{
PFRONTEND_VTBL Vtbl; /* Virtual table */
PTERMINAL_VTBL Vtbl; /* Virtual table */
struct _CONSOLE* Console; /* Console to which the frontend is attached to */
PVOID Data; /* Private data */
PVOID OldData; /* Reserved */
};
/*
@@ -277,112 +258,109 @@ typedef enum _CONSOLE_STATE
CONSOLE_IN_DESTRUCTION /* Console in destruction */
} CONSOLE_STATE, *PCONSOLE_STATE;
// HACK!!
struct _CONSOLE;
struct _WINSRV_CONSOLE;
/* HACK: */ typedef struct _CONSOLE *PCONSOLE;
#include "conio_winsrv.h"
typedef struct _CONSOLE
{
/******************************* Console Set-up *******************************/
LONG ReferenceCount; /* Is incremented each time a handle to something in the console (a screen-buffer or the input buffer of this console) gets referenced */
CRITICAL_SECTION Lock;
/**/WINSRV_CONSOLE;/**/ // HACK HACK!!
CONSOLE_STATE State; /* State of the console */
TERMINAL TermIFace; /* Frontend-specific interface */
LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */
PCONSOLE_PROCESS_DATA NotifiedLastCloseProcess; /* Pointer to the unique process that needs to be notified when the console leader process is killed */
BOOLEAN NotifyLastClose; /* TRUE if the console should send a control event when the console leader process is killed */
FRONTEND TermIFace; /* Frontend-specific interface */
ULONG ConsoleID; /* The ID of the console */
LIST_ENTRY ListEntry; /* Entry in the list of consoles */
/**************************** Input buffer and data ***************************/
CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */
UINT InputCodePage;
/** Put those things in TEXTMODE_SCREEN_BUFFER ?? **/
PWCHAR LineBuffer; /* Current line being input, in line buffered mode */
WORD LineMaxSize; /* Maximum size of line in characters (including CR+LF) */
WORD LineSize; /* Current size of line */
WORD LinePos; /* Current position within line */
/** Put those things in CONSOLE_INPUT_BUFFER ?? **/
PWCHAR LineBuffer; /* Current line being input, in line buffered mode */
ULONG LineMaxSize; /* Maximum size of line in characters (including CR+LF) */
ULONG LineSize; /* Current size of line */
ULONG LinePos; /* Current position within line */
BOOLEAN LineComplete; /* User pressed enter, ready to send back to client */
BOOLEAN LineUpPressed;
BOOLEAN LineInsertToggle; /* Replace character over cursor instead of inserting */
ULONG LineWakeupMask; /* Bitmap of which control characters will end line input */
/***************************************************/
ULONG LineWakeupMask; /* Bitmap of which control characters will end line input */
/*************************************************/
BOOLEAN QuickEdit;
BOOLEAN InsertMode;
UINT CodePage;
/******************************* Screen buffers *******************************/
LIST_ENTRY BufferList; /* List of all screen buffers for this console */
PCONSOLE_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */
BYTE PauseFlags;
HANDLE UnpauseEvent;
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
UINT OutputCodePage;
/**************************** Aliases and Histories ***************************/
struct _ALIAS_HEADER *Aliases;
LIST_ENTRY HistoryBuffers;
ULONG HistoryBufferSize; /* Size for newly created history buffers */
ULONG NumberOfHistoryBuffers; /* Maximum number of history buffers allowed */
BOOLEAN HistoryNoDup; /* Remove old duplicate history entries */
/****************************** Other properties ******************************/
UNICODE_STRING OriginalTitle; /* Original title of console, the one defined when the console leader is launched; it never changes. Always NULL-terminated */
UNICODE_STRING Title; /* Title of console. Always NULL-terminated */
HANDLE UnpauseEvent; /* When != NULL, event for pausing the console */
COORD ConsoleSize; /* The current size of the console, for text-mode only */
BOOLEAN FixedSize; /* TRUE if the console is of fixed size */
COLORREF Colors[16]; /* Colour palette */
} CONSOLE, *PCONSOLE;
} CONSOLE; // , *PCONSOLE;
/* PauseFlags values (internal only) */
#define PAUSED_FROM_KEYBOARD 0x1
#define PAUSED_FROM_SCROLLBAR 0x2
#define PAUSED_FROM_SELECTION 0x4
// #include "conio_winsrv.h"
/* console.c */
VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
VOID NTAPI
ConDrvPause(PCONSOLE Console);
VOID NTAPI
ConDrvUnpause(PCONSOLE Console);
PCONSOLE_PROCESS_DATA NTAPI
ConDrvGetConsoleLeaderProcess(IN PCONSOLE Console);
ConSrvGetConsoleLeaderProcess(IN PCONSOLE Console);
NTSTATUS
ConDrvConsoleCtrlEvent(IN ULONG CtrlEvent,
ConSrvConsoleCtrlEvent(IN ULONG CtrlEvent,
IN PCONSOLE_PROCESS_DATA ProcessData);
NTSTATUS NTAPI
ConDrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
ConSrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
IN ULONG ProcessGroupId,
IN ULONG CtrlEvent);
/* coninput.c */
VOID NTAPI ConioProcessKey(PCONSOLE Console, MSG* msg);
NTSTATUS FASTCALL ConioAddInputEvent(PCONSOLE Console,
PINPUT_RECORD InputEvent,
BOOLEAN AppendToEnd);
NTSTATUS FASTCALL ConioProcessInputEvent(PCONSOLE Console,
PINPUT_RECORD InputEvent);
NTSTATUS
ConioAddInputEvents(PCONSOLE Console,
PINPUT_RECORD InputRecords,
ULONG NumEventsToWrite,
PULONG NumEventsWritten,
BOOLEAN AppendToEnd);
NTSTATUS
ConioProcessInputEvent(PCONSOLE Console,
PINPUT_RECORD InputEvent);
/* conoutput.c */
#define ConioInitRect(Rect, top, left, bottom, right) \
do { \
((Rect)->Top) = top; \
((Rect)->Left) = left; \
((Rect)->Bottom) = bottom; \
((Rect)->Right) = right; \
} while (0)
#define ConioIsRectEmpty(Rect) \
(((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
#define ConioRectHeight(Rect) \
(((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1)
#define ConioRectWidth(Rect) \
(((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1)
/*
* From MSDN:
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
* If they are the same, the function fails, and GetLastError returns
* ERROR_INVALID_PARAMETER."
*/
#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
PCHAR_INFO ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y);
VOID FASTCALL ConioDrawConsole(PCONSOLE Console);
VOID ConioDrawConsole(PCONSOLE Console);
NTSTATUS ConioResizeBuffer(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
COORD Size);
@@ -391,7 +369,7 @@ NTSTATUS ConioWriteConsole(PCONSOLE Console,
PWCHAR Buffer,
DWORD Length,
BOOL Attrib);
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console,
DWORD ConioEffectiveCursorSize(PCONSOLE Console,
DWORD Scale);
/* EOF */
@@ -0,0 +1,185 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: consrv/include/conio_winsrv.h
* PURPOSE: Public Console I/O Interface
* PROGRAMMERS: Gé van Geldorp
* Jeffrey Morlan
* Hermes Belusca-Maito ([email protected])
*/
#pragma once
#include "rect.h"
#define CSR_DEFAULT_CURSOR_SIZE 25
typedef struct _FRONTEND FRONTEND, *PFRONTEND;
/* HACK: */ typedef struct _CONSOLE_INFO *PCONSOLE_INFO;
typedef struct _FRONTEND_VTBL
{
// NTSTATUS (NTAPI *UnloadFrontEnd)(IN OUT PFRONTEND This);
/*
* Internal interface (functions called by the console server only)
*/
NTSTATUS (NTAPI *InitFrontEnd)(IN OUT PFRONTEND This,
IN struct _CONSOLE* Console);
VOID (NTAPI *DeinitFrontEnd)(IN OUT PFRONTEND This);
/* Interface used for both text-mode and graphics screen buffers */
VOID (NTAPI *DrawRegion)(IN OUT PFRONTEND This,
SMALL_RECT* Region);
/* Interface used only for text-mode screen buffers */
VOID (NTAPI *WriteStream)(IN OUT PFRONTEND This,
SMALL_RECT* Region,
SHORT CursorStartX,
SHORT CursorStartY,
UINT ScrolledLines,
PWCHAR Buffer,
UINT Length);
BOOL (NTAPI *SetCursorInfo)(IN OUT PFRONTEND This,
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
BOOL (NTAPI *SetScreenInfo)(IN OUT PFRONTEND This,
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
SHORT OldCursorX,
SHORT OldCursorY);
VOID (NTAPI *ResizeTerminal)(IN OUT PFRONTEND This);
VOID (NTAPI *SetActiveScreenBuffer)(IN OUT PFRONTEND This);
VOID (NTAPI *ReleaseScreenBuffer)(IN OUT PFRONTEND This,
IN PCONSOLE_SCREEN_BUFFER ScreenBuffer);
VOID (NTAPI *RefreshInternalInfo)(IN OUT PFRONTEND This);
/*
* External interface (functions corresponding to the Console API)
*/
VOID (NTAPI *ChangeTitle)(IN OUT PFRONTEND This);
BOOL (NTAPI *ChangeIcon)(IN OUT PFRONTEND This,
HICON IconHandle);
HWND (NTAPI *GetConsoleWindowHandle)(IN OUT PFRONTEND This);
VOID (NTAPI *GetLargestConsoleWindowSize)(IN OUT PFRONTEND This,
PCOORD pSize);
BOOL (NTAPI *GetSelectionInfo)(IN OUT PFRONTEND This,
PCONSOLE_SELECTION_INFO pSelectionInfo);
BOOL (NTAPI *SetPalette)(IN OUT PFRONTEND This,
HPALETTE PaletteHandle,
UINT PaletteUsage);
ULONG (NTAPI *GetDisplayMode)(IN OUT PFRONTEND This);
BOOL (NTAPI *SetDisplayMode)(IN OUT PFRONTEND This,
ULONG NewMode);
INT (NTAPI *ShowMouseCursor)(IN OUT PFRONTEND This,
BOOL Show);
BOOL (NTAPI *SetMouseCursor)(IN OUT PFRONTEND This,
HCURSOR CursorHandle);
HMENU (NTAPI *MenuControl)(IN OUT PFRONTEND This,
UINT CmdIdLow,
UINT CmdIdHigh);
BOOL (NTAPI *SetMenuClose)(IN OUT PFRONTEND This,
BOOL Enable);
} FRONTEND_VTBL, *PFRONTEND_VTBL;
struct _FRONTEND
{
PFRONTEND_VTBL Vtbl; /* Virtual table */
NTSTATUS (NTAPI *UnloadFrontEnd)(IN OUT PFRONTEND This);
struct _CONSOLE* Console; /* Console to which the frontend is attached to */
PVOID Data; /* Private data */
PVOID OldData; /* Reserved */
};
/* PauseFlags values (internal only) */
#define PAUSED_FROM_KEYBOARD 0x1
#define PAUSED_FROM_SCROLLBAR 0x2
#define PAUSED_FROM_SELECTION 0x4
typedef struct _WINSRV_CONSOLE
{
/******************************* Console Set-up *******************************/
/* This **MUST** be FIRST!! */
// CONSOLE;
// LONG ReferenceCount; /* Is incremented each time a handle to something in the console (a screen-buffer or the input buffer of this console) gets referenced */
// CRITICAL_SECTION Lock;
// CONSOLE_STATE State; /* State of the console */
FRONTEND FrontEndIFace; /* Frontend-specific interface */
/******************************* Process support ******************************/
LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */
PCONSOLE_PROCESS_DATA NotifiedLastCloseProcess; /* Pointer to the unique process that needs to be notified when the console leader process is killed */
BOOLEAN NotifyLastClose; /* TRUE if the console should send a control event when the console leader process is killed */
BOOLEAN QuickEdit;
/******************************* Pausing support ******************************/
BYTE PauseFlags;
LIST_ENTRY ReadWaitQueue; /* List head for the queue of unique input buffer read wait blocks */
LIST_ENTRY WriteWaitQueue; /* List head for the queue of current screen-buffer write wait blocks */
/**************************** Aliases and Histories ***************************/
struct _ALIAS_HEADER *Aliases;
LIST_ENTRY HistoryBuffers;
ULONG HistoryBufferSize; /* Size for newly created history buffers */
ULONG NumberOfHistoryBuffers; /* Maximum number of history buffers allowed */
BOOLEAN HistoryNoDup; /* Remove old duplicate history entries */
} WINSRV_CONSOLE, *PWINSRV_CONSOLE;
/* console.c */
VOID ConioPause(PCONSOLE Console, UINT Flags);
VOID ConioUnpause(PCONSOLE Console, UINT Flags);
PCONSOLE_PROCESS_DATA NTAPI
ConSrvGetConsoleLeaderProcess(IN PCONSOLE Console);
NTSTATUS
ConSrvConsoleCtrlEvent(IN ULONG CtrlEvent,
IN PCONSOLE_PROCESS_DATA ProcessData);
NTSTATUS NTAPI
ConSrvConsoleProcessCtrlEvent(IN PCONSOLE Console,
IN ULONG ProcessGroupId,
IN ULONG CtrlEvent);
/* coninput.c */
VOID NTAPI ConioProcessKey(PCONSOLE Console, MSG* msg);
DWORD ConioEffectiveCursorSize(PCONSOLE Console,
DWORD Scale);
NTSTATUS
ConioAddInputEvents(PCONSOLE Console,
PINPUT_RECORD InputRecords,
ULONG NumEventsToWrite,
PULONG NumEventsWritten,
BOOLEAN AppendToEnd);
NTSTATUS
ConioProcessInputEvent(PCONSOLE Console,
PINPUT_RECORD InputEvent);
/* conoutput.c */
/*
* From MSDN:
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
* If they are the same, the function fails, and GetLastError returns
* ERROR_INVALID_PARAMETER."
*/
#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
PCHAR_INFO ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y);
VOID ConioDrawConsole(PCONSOLE Console);
NTSTATUS ConioResizeBuffer(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
COORD Size);
NTSTATUS ConioWriteConsole(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER Buff,
PWCHAR Buffer,
DWORD Length,
BOOL Attrib);
/* EOF */
@@ -12,15 +12,13 @@ VOID NTAPI
ConDrvInitConsoleSupport(VOID);
NTSTATUS NTAPI
ConDrvInitConsole(OUT PHANDLE NewConsoleHandle,
OUT PCONSOLE* NewConsole,
IN PCONSOLE_INFO ConsoleInfo,
IN ULONG ConsoleLeaderProcessId);
ConDrvInitConsole(OUT PCONSOLE* NewConsole,
IN PCONSOLE_INFO ConsoleInfo);
NTSTATUS NTAPI
ConDrvRegisterFrontEnd(IN PCONSOLE Console,
IN PFRONTEND FrontEnd);
ConDrvRegisterTerminal(IN PCONSOLE Console,
IN PTERMINAL Terminal);
NTSTATUS NTAPI
ConDrvDeregisterFrontEnd(IN PCONSOLE Console);
ConDrvDeregisterTerminal(IN PCONSOLE Console);
VOID NTAPI
ConDrvDeleteConsole(IN PCONSOLE Console);
@@ -35,20 +33,4 @@ ConDrvValidateConsoleUnsafe(IN PCONSOLE Console,
IN CONSOLE_STATE ExpectedState,
IN BOOLEAN LockConsole);
BOOLEAN NTAPI
ConDrvValidateConsole(OUT PCONSOLE* Console,
IN HANDLE ConsoleHandle,
IN CONSOLE_STATE ExpectedState,
IN BOOLEAN LockConsole);
NTSTATUS NTAPI
ConDrvGetConsole(OUT PCONSOLE* Console,
IN HANDLE ConsoleHandle,
IN BOOLEAN LockConsole);
VOID NTAPI
ConDrvReleaseConsole(IN PCONSOLE Console,
IN BOOLEAN WasConsoleLocked);
/* EOF */
@@ -0,0 +1,85 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: consrv/include/rect.h
* PURPOSE: Rectangle helper functions
* PROGRAMMERS: van Geldorp
* Jeffrey Morlan
*/
#pragma once
#define ConioInitRect(Rect, top, left, bottom, right) \
do { \
((Rect)->Top) = top; \
((Rect)->Left) = left; \
((Rect)->Bottom) = bottom; \
((Rect)->Right) = right; \
} while (0)
#define ConioIsRectEmpty(Rect) \
(((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
#define ConioRectHeight(Rect) \
(((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1)
#define ConioRectWidth(Rect) \
(((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1)
static __inline BOOLEAN
ConioGetIntersection(OUT PSMALL_RECT Intersection,
IN PSMALL_RECT Rect1,
IN PSMALL_RECT Rect2)
{
if ( ConioIsRectEmpty(Rect1) ||
ConioIsRectEmpty(Rect2) ||
(Rect1->Top > Rect2->Bottom) ||
(Rect1->Left > Rect2->Right) ||
(Rect1->Bottom < Rect2->Top) ||
(Rect1->Right < Rect2->Left) )
{
/* The rectangles do not intersect */
ConioInitRect(Intersection, 0, -1, 0, -1);
return FALSE;
}
ConioInitRect(Intersection,
max(Rect1->Top , Rect2->Top ),
max(Rect1->Left , Rect2->Left ),
min(Rect1->Bottom, Rect2->Bottom),
min(Rect1->Right , Rect2->Right ));
return TRUE;
}
static __inline BOOLEAN
ConioGetUnion(OUT PSMALL_RECT Union,
IN PSMALL_RECT Rect1,
IN PSMALL_RECT Rect2)
{
if (ConioIsRectEmpty(Rect1))
{
if (ConioIsRectEmpty(Rect2))
{
ConioInitRect(Union, 0, -1, 0, -1);
return FALSE;
}
else
{
*Union = *Rect2;
}
}
else if (ConioIsRectEmpty(Rect2))
{
*Union = *Rect1;
}
else
{
ConioInitRect(Union,
min(Rect1->Top , Rect2->Top ),
min(Rect1->Left , Rect2->Left ),
max(Rect1->Bottom, Rect2->Bottom),
max(Rect1->Right , Rect2->Right ));
}
return TRUE;
}
@@ -12,8 +12,8 @@
#define TermDrawRegion(Console, Region) \
(Console)->TermIFace.Vtbl->DrawRegion(&(Console)->TermIFace, (Region))
#define TermWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
(Console)->TermIFace.Vtbl->WriteStream(&(Console)->TermIFace, (Block), (CurStartX), (CurStartY), \
#define TermWriteStream(Console, Region, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
(Console)->TermIFace.Vtbl->WriteStream(&(Console)->TermIFace, (Region), (CurStartX), (CurStartY), \
(ScrolledLines), (Buffer), (Length))
#define TermSetCursorInfo(Console, ScreenBuffer) \
(Console)->TermIFace.Vtbl->SetCursorInfo(&(Console)->TermIFace, (ScreenBuffer))
@@ -25,34 +25,32 @@
(Console)->TermIFace.Vtbl->SetActiveScreenBuffer(&(Console)->TermIFace)
#define TermReleaseScreenBuffer(Console, ScreenBuffer) \
(Console)->TermIFace.Vtbl->ReleaseScreenBuffer(&(Console)->TermIFace, (ScreenBuffer))
#define TermProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) \
(Console)->TermIFace.Vtbl->ProcessKeyCallback(&(Console)->TermIFace, (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down))
#define TermRefreshInternalInfo(Console) \
(Console)->TermIFace.Vtbl->RefreshInternalInfo(&(Console)->TermIFace)
(Console)->FrontEndIFace.Vtbl->RefreshInternalInfo(&(Console)->FrontEndIFace)
#define TermChangeTitle(Console) \
(Console)->TermIFace.Vtbl->ChangeTitle(&(Console)->TermIFace)
#define TermChangeIcon(Console, IconHandle) \
(Console)->TermIFace.Vtbl->ChangeIcon(&(Console)->TermIFace, (IconHandle))
(Console)->FrontEndIFace.Vtbl->ChangeIcon(&(Console)->FrontEndIFace, (IconHandle))
#define TermGetConsoleWindowHandle(Console) \
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle(&(Console)->TermIFace)
(Console)->FrontEndIFace.Vtbl->GetConsoleWindowHandle(&(Console)->FrontEndIFace)
#define TermGetLargestConsoleWindowSize(Console, pSize) \
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize))
#define TermGetSelectionInfo(Console, pSelectionInfo) \
(Console)->TermIFace.Vtbl->GetSelectionInfo(&(Console)->TermIFace, (pSelectionInfo))
(Console)->FrontEndIFace.Vtbl->GetSelectionInfo(&(Console)->FrontEndIFace, (pSelectionInfo))
#define TermSetPalette(Console, PaletteHandle, PaletteUsage) \
(Console)->TermIFace.Vtbl->SetPalette(&(Console)->TermIFace, (PaletteHandle), (PaletteUsage))
#define TermGetDisplayMode(Console) \
(Console)->TermIFace.Vtbl->GetDisplayMode(&(Console)->TermIFace)
(Console)->FrontEndIFace.Vtbl->GetDisplayMode(&(Console)->FrontEndIFace)
#define TermSetDisplayMode(Console, NewMode) \
(Console)->TermIFace.Vtbl->SetDisplayMode(&(Console)->TermIFace, (NewMode))
(Console)->FrontEndIFace.Vtbl->SetDisplayMode(&(Console)->FrontEndIFace, (NewMode))
#define TermShowMouseCursor(Console, Show) \
(Console)->TermIFace.Vtbl->ShowMouseCursor(&(Console)->TermIFace, (Show))
#define TermSetMouseCursor(Console, CursorHandle) \
(Console)->TermIFace.Vtbl->SetMouseCursor(&(Console)->TermIFace, (CursorHandle))
(Console)->FrontEndIFace.Vtbl->SetMouseCursor(&(Console)->FrontEndIFace, (CursorHandle))
#define TermMenuControl(Console, CmdIdLow, CmdIdHigh) \
(Console)->TermIFace.Vtbl->MenuControl(&(Console)->TermIFace, (CmdIdLow), (CmdIdHigh))
(Console)->FrontEndIFace.Vtbl->MenuControl(&(Console)->FrontEndIFace, (CmdIdLow), (CmdIdHigh))
#define TermSetMenuClose(Console, Enable) \
(Console)->TermIFace.Vtbl->SetMenuClose(&(Console)->TermIFace, (Enable))
(Console)->FrontEndIFace.Vtbl->SetMenuClose(&(Console)->FrontEndIFace, (Enable))
/* EOF */
+4 -3
View File
@@ -353,7 +353,7 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
/* Initialize the new (target) process */
RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
TargetProcessData->Process = TargetProcess;
TargetProcessData->ConsoleEvent = NULL;
TargetProcessData->InputWaitHandle = NULL;
TargetProcessData->ConsoleHandle = TargetProcessData->ParentConsoleHandle = NULL;
TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE);
@@ -383,7 +383,7 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
PCONSOLE SourceConsole;
/* Validate and lock the parent's console */
if (ConDrvValidateConsole(&SourceConsole,
if (ConSrvValidateConsole(&SourceConsole,
SourceProcessData->ConsoleHandle,
CONSOLE_RUNNING, TRUE))
{
@@ -484,7 +484,7 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
/* Return the console handle and the input wait handle to the caller */
ConnectInfo->ConsoleHandle = ProcessData->ConsoleHandle;
ConnectInfo->InputWaitHandle = ProcessData->ConsoleEvent;
ConnectInfo->InputWaitHandle = ProcessData->InputWaitHandle;
/* Set the Property-Dialog and Control-Dispatcher handlers */
ProcessData->PropDispatcher = ConnectInfo->ConsoleStartInfo.PropDispatcher;
@@ -529,6 +529,7 @@ CSR_SERVER_DLL_INIT(ConServerDllInitialization)
*/
ConDrvInitConsoleSupport();
ConSrvInitConsoleSupport();
/* Setup the DLL Object */
LoadedServerDll->ApiBase = CONSRV_FIRST_API_NUMBER;
+247 -118
View File
@@ -4,8 +4,6 @@
* FILE: win32ss/user/winsrv/consrv/lineinput.c
* PURPOSE: Console line input functions
* PROGRAMMERS: Jeffrey Morlan
*
* NOTE: It's something frontend-related... (--> read my mind... ;) )
*/
/* INCLUDES *******************************************************************/
@@ -21,30 +19,45 @@ typedef struct _HISTORY_BUFFER
UINT Position;
UINT MaxEntries;
UINT NumEntries;
PUNICODE_STRING Entries;
UNICODE_STRING ExeName;
PUNICODE_STRING Entries;
} HISTORY_BUFFER, *PHISTORY_BUFFER;
BOOLEAN
ConvertInputAnsiToUnicode(PCONSOLE Console,
PVOID Source,
USHORT SourceLength,
// BOOLEAN IsUnicode,
PWCHAR* Target,
PUSHORT TargetLength);
BOOLEAN
ConvertInputUnicodeToAnsi(PCONSOLE Console,
PVOID Source,
USHORT SourceLength,
// BOOLEAN IsAnsi,
PCHAR/* * */ Target,
/*P*/USHORT TargetLength);
/* PRIVATE FUNCTIONS **********************************************************/
static PHISTORY_BUFFER
HistoryCurrentBuffer(PCONSOLE Console)
HistoryCurrentBuffer(PCONSOLE Console,
PUNICODE_STRING ExeName)
{
/* TODO: use actual EXE name sent from process that called ReadConsole */
UNICODE_STRING ExeName = { 14, 14, L"cmd.exe" };
PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
PHISTORY_BUFFER Hist;
for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink)
{
Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
if (RtlEqualUnicodeString(&ExeName, &Hist->ExeName, FALSE))
if (RtlEqualUnicodeString(ExeName, &Hist->ExeName, FALSE))
return Hist;
}
/* Couldn't find the buffer, create a new one */
Hist = ConsoleAllocHeap(0, sizeof(HISTORY_BUFFER) + ExeName.Length);
Hist = ConsoleAllocHeap(0, sizeof(HISTORY_BUFFER) + ExeName->Length);
if (!Hist) return NULL;
Hist->MaxEntries = Console->HistoryBufferSize;
Hist->NumEntries = 0;
@@ -54,18 +67,19 @@ HistoryCurrentBuffer(PCONSOLE Console)
ConsoleFreeHeap(Hist);
return NULL;
}
Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName.Length;
Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName->Length;
Hist->ExeName.Buffer = (PWCHAR)(Hist + 1);
memcpy(Hist->ExeName.Buffer, ExeName.Buffer, ExeName.Length);
memcpy(Hist->ExeName.Buffer, ExeName->Buffer, ExeName->Length);
InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry);
return Hist;
}
static VOID
HistoryAddEntry(PCONSOLE Console)
HistoryAddEntry(PCONSOLE Console,
PUNICODE_STRING ExeName)
{
UNICODE_STRING NewEntry;
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console);
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
INT i;
if (!Hist) return;
@@ -113,9 +127,11 @@ HistoryAddEntry(PCONSOLE Console)
}
static VOID
HistoryGetCurrentEntry(PCONSOLE Console, PUNICODE_STRING Entry)
HistoryGetCurrentEntry(PCONSOLE Console,
PUNICODE_STRING ExeName,
PUNICODE_STRING Entry)
{
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console);
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
if (!Hist || Hist->NumEntries == 0)
Entry->Length = 0;
@@ -124,17 +140,51 @@ HistoryGetCurrentEntry(PCONSOLE Console, PUNICODE_STRING Entry)
}
static PHISTORY_BUFFER
HistoryFindBuffer(PCONSOLE Console, PUNICODE_STRING ExeName)
HistoryFindBuffer(PCONSOLE Console,
PVOID ExeName,
USHORT ExeLength,
BOOLEAN UnicodeExe)
{
PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
UNICODE_STRING ExeNameU;
PLIST_ENTRY Entry;
PHISTORY_BUFFER Hist = NULL;
if (ExeName == NULL) return NULL;
if (UnicodeExe)
{
ExeNameU.Buffer = ExeName;
/* Length is in bytes */
ExeNameU.MaximumLength = ExeLength;
}
else
{
if (!ConvertInputAnsiToUnicode(Console,
ExeName, ExeLength,
&ExeNameU.Buffer, &ExeNameU.MaximumLength))
{
return NULL;
}
}
ExeNameU.Length = ExeNameU.MaximumLength;
Entry = Console->HistoryBuffers.Flink;
while (Entry != &Console->HistoryBuffers)
{
Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
/* For the history APIs, the caller is allowed to give only part of the name */
PHISTORY_BUFFER Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE))
if (RtlPrefixUnicodeString(&ExeNameU, &Hist->ExeName, TRUE))
{
if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
return Hist;
}
Entry = Entry->Flink;
}
if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
return NULL;
}
@@ -151,7 +201,7 @@ HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
ConsoleFreeHeap(Hist);
}
VOID FASTCALL
VOID
HistoryDeleteBuffers(PCONSOLE Console)
{
PLIST_ENTRY CurrentEntry;
@@ -190,7 +240,7 @@ LineInputSetPos(PCONSOLE Console, UINT Pos)
}
static VOID
LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion)
LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, PWCHAR Insertion)
{
PTEXTMODE_SCREEN_BUFFER ActiveBuffer;
UINT Pos = Console->LinePos;
@@ -227,9 +277,11 @@ LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Inser
}
static VOID
LineInputRecallHistory(PCONSOLE Console, INT Offset)
LineInputRecallHistory(PCONSOLE Console,
PUNICODE_STRING ExeName,
INT Offset)
{
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console);
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
UINT Position = 0;
if (!Hist || Hist->NumEntries == 0) return;
@@ -244,8 +296,10 @@ LineInputRecallHistory(PCONSOLE Console, INT Offset)
Hist->Entries[Hist->Position].Buffer);
}
VOID FASTCALL
LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
VOID
LineInputKeyDown(PCONSOLE Console,
PUNICODE_STRING ExeName,
KEY_EVENT_RECORD *KeyEvent)
{
UINT Pos = Console->LinePos;
PHISTORY_BUFFER Hist;
@@ -298,7 +352,7 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
else
{
/* Recall one character (but don't overwrite current line) */
HistoryGetCurrentEntry(Console, &Entry);
HistoryGetCurrentEntry(Console, ExeName, &Entry);
if (Pos < Console->LineSize)
LineInputSetPos(Console, Pos + 1);
else if (Pos * sizeof(WCHAR) < Entry.Length)
@@ -317,26 +371,26 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
return;
case VK_PRIOR:
/* Recall first history entry */
LineInputRecallHistory(Console, -((WORD)-1));
LineInputRecallHistory(Console, ExeName, -((WORD)-1));
return;
case VK_NEXT:
/* Recall last history entry */
LineInputRecallHistory(Console, +((WORD)-1));
LineInputRecallHistory(Console, ExeName, +((WORD)-1));
return;
case VK_UP:
case VK_F5:
/* Recall previous history entry. On first time, actually recall the
* current (usually last) entry; on subsequent times go back. */
LineInputRecallHistory(Console, Console->LineUpPressed ? -1 : 0);
LineInputRecallHistory(Console, ExeName, Console->LineUpPressed ? -1 : 0);
Console->LineUpPressed = TRUE;
return;
case VK_DOWN:
/* Recall next history entry */
LineInputRecallHistory(Console, +1);
LineInputRecallHistory(Console, ExeName, +1);
return;
case VK_F3:
/* Recall remainder of current history entry */
HistoryGetCurrentEntry(Console, &Entry);
HistoryGetCurrentEntry(Console, ExeName, &Entry);
if (Pos * sizeof(WCHAR) < Entry.Length)
{
UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
@@ -350,11 +404,11 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
break;
case VK_F7:
if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
HistoryDeleteBuffer(HistoryCurrentBuffer(Console));
HistoryDeleteBuffer(HistoryCurrentBuffer(Console, ExeName));
return;
case VK_F8:
/* Search for history entries starting with input. */
Hist = HistoryCurrentBuffer(Console);
Hist = HistoryCurrentBuffer(Console, ExeName);
if (!Hist || Hist->NumEntries == 0) return;
/* Like Up/F5, on first time start from current (usually last) entry,
@@ -398,7 +452,7 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
}
else if (KeyEvent->uChar.UnicodeChar == L'\r')
{
HistoryAddEntry(Console);
HistoryAddEntry(Console, ExeName);
/* TODO: Expand aliases */
@@ -455,163 +509,216 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
CSR_API(SrvGetConsoleCommandHistory)
{
PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryRequest;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
NTSTATUS Status;
PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryRequest;
PCONSOLE Console;
ULONG BytesWritten = 0;
PHISTORY_BUFFER Hist;
PBYTE Buffer = (PBYTE)GetCommandHistoryRequest->History;
ULONG BufferSize = GetCommandHistoryRequest->Length;
UINT i;
DPRINT1("SrvGetConsoleCommandHistory entered\n");
if ( !CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&GetCommandHistoryRequest->History,
GetCommandHistoryRequest->Length,
GetCommandHistoryRequest->HistoryLength,
sizeof(BYTE)) ||
!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&GetCommandHistoryRequest->ExeName.Buffer,
GetCommandHistoryRequest->ExeName.Length,
(PVOID*)&GetCommandHistoryRequest->ExeName,
GetCommandHistoryRequest->ExeLength,
sizeof(BYTE)) )
{
return STATUS_INVALID_PARAMETER;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (NT_SUCCESS(Status))
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
Hist = HistoryFindBuffer(Console,
GetCommandHistoryRequest->ExeName,
GetCommandHistoryRequest->ExeLength,
GetCommandHistoryRequest->Unicode2);
if (Hist)
{
Hist = HistoryFindBuffer(Console, &GetCommandHistoryRequest->ExeName);
if (Hist)
UINT i;
LPSTR TargetBufferA;
LPWSTR TargetBufferW;
ULONG BufferSize = GetCommandHistoryRequest->HistoryLength;
UINT Offset = 0;
UINT SourceLength;
if (GetCommandHistoryRequest->Unicode)
{
for (i = 0; i < Hist->NumEntries; i++)
TargetBufferW = GetCommandHistoryRequest->History;
BufferSize /= sizeof(WCHAR);
}
else
{
TargetBufferA = GetCommandHistoryRequest->History;
}
for (i = 0; i < Hist->NumEntries; i++)
{
SourceLength = Hist->Entries[i].Length / sizeof(WCHAR);
if (Offset + SourceLength + 1 > BufferSize)
{
if (BufferSize < (Hist->Entries[i].Length + sizeof(WCHAR)))
{
Status = STATUS_BUFFER_OVERFLOW;
break;
}
memcpy(Buffer, Hist->Entries[i].Buffer, Hist->Entries[i].Length);
Buffer += Hist->Entries[i].Length;
*(PWCHAR)Buffer = L'\0';
Buffer += sizeof(WCHAR);
Status = STATUS_BUFFER_OVERFLOW;
break;
}
if (GetCommandHistoryRequest->Unicode)
{
RtlCopyMemory(&TargetBufferW[Offset], Hist->Entries[i].Buffer, SourceLength * sizeof(WCHAR));
Offset += SourceLength;
TargetBufferW[Offset++] = L'\0';
}
else
{
ConvertInputUnicodeToAnsi(Console,
Hist->Entries[i].Buffer, SourceLength * sizeof(WCHAR),
&TargetBufferA[Offset], SourceLength);
Offset += SourceLength;
TargetBufferA[Offset++] = '\0';
}
}
GetCommandHistoryRequest->Length = Buffer - (PBYTE)GetCommandHistoryRequest->History;
ConSrvReleaseConsole(Console, TRUE);
if (GetCommandHistoryRequest->Unicode)
BytesWritten = Offset * sizeof(WCHAR);
else
BytesWritten = Offset;
}
// GetCommandHistoryRequest->HistoryLength = TargetBuffer - (PBYTE)GetCommandHistoryRequest->History;
GetCommandHistoryRequest->HistoryLength = BytesWritten;
ConSrvReleaseConsole(Console, TRUE);
return Status;
}
CSR_API(SrvGetConsoleCommandHistoryLength)
{
PCONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryLengthRequest;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
NTSTATUS Status;
PCONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryLengthRequest;
PCONSOLE Console;
PHISTORY_BUFFER Hist;
ULONG Length = 0;
UINT i;
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&GetCommandHistoryLengthRequest->ExeName.Buffer,
GetCommandHistoryLengthRequest->ExeName.Length,
(PVOID*)&GetCommandHistoryLengthRequest->ExeName,
GetCommandHistoryLengthRequest->ExeLength,
sizeof(BYTE)))
{
return STATUS_INVALID_PARAMETER;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (NT_SUCCESS(Status))
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
Hist = HistoryFindBuffer(Console,
GetCommandHistoryLengthRequest->ExeName,
GetCommandHistoryLengthRequest->ExeLength,
GetCommandHistoryLengthRequest->Unicode2);
if (Hist)
{
Hist = HistoryFindBuffer(Console, &GetCommandHistoryLengthRequest->ExeName);
if (Hist)
{
for (i = 0; i < Hist->NumEntries; i++)
Length += Hist->Entries[i].Length + sizeof(WCHAR);
}
GetCommandHistoryLengthRequest->Length = Length;
ConSrvReleaseConsole(Console, TRUE);
for (i = 0; i < Hist->NumEntries; i++)
Length += Hist->Entries[i].Length + sizeof(WCHAR); // Each entry is returned NULL-terminated
}
/*
* Quick and dirty way of getting the number of bytes of the
* corresponding ANSI string from the one in UNICODE.
*/
if (!GetCommandHistoryLengthRequest->Unicode)
Length /= sizeof(WCHAR);
GetCommandHistoryLengthRequest->HistoryLength = Length;
ConSrvReleaseConsole(Console, TRUE);
return Status;
}
CSR_API(SrvExpungeConsoleCommandHistory)
{
NTSTATUS Status;
PCONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ExpungeCommandHistoryRequest;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
PHISTORY_BUFFER Hist;
NTSTATUS Status;
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&ExpungeCommandHistoryRequest->ExeName.Buffer,
ExpungeCommandHistoryRequest->ExeName.Length,
(PVOID*)&ExpungeCommandHistoryRequest->ExeName,
ExpungeCommandHistoryRequest->ExeLength,
sizeof(BYTE)))
{
return STATUS_INVALID_PARAMETER;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (NT_SUCCESS(Status))
{
Hist = HistoryFindBuffer(Console, &ExpungeCommandHistoryRequest->ExeName);
HistoryDeleteBuffer(Hist);
ConSrvReleaseConsole(Console, TRUE);
}
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
Hist = HistoryFindBuffer(Console,
ExpungeCommandHistoryRequest->ExeName,
ExpungeCommandHistoryRequest->ExeLength,
ExpungeCommandHistoryRequest->Unicode2);
HistoryDeleteBuffer(Hist);
ConSrvReleaseConsole(Console, TRUE);
return Status;
}
CSR_API(SrvSetConsoleNumberOfCommands)
{
NTSTATUS Status;
PCONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryNumberCommandsRequest;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
PHISTORY_BUFFER Hist;
NTSTATUS Status;
UINT MaxEntries = SetHistoryNumberCommandsRequest->NumCommands;
PUNICODE_STRING OldEntryList, NewEntryList;
if (!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&SetHistoryNumberCommandsRequest->ExeName.Buffer,
SetHistoryNumberCommandsRequest->ExeName.Length,
(PVOID*)&SetHistoryNumberCommandsRequest->ExeName,
SetHistoryNumberCommandsRequest->ExeLength,
sizeof(BYTE)))
{
return STATUS_INVALID_PARAMETER;
}
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (NT_SUCCESS(Status))
{
Hist = HistoryFindBuffer(Console, &SetHistoryNumberCommandsRequest->ExeName);
if (Hist)
{
OldEntryList = Hist->Entries;
NewEntryList = ConsoleAllocHeap(0, MaxEntries * sizeof(UNICODE_STRING));
if (!NewEntryList)
{
Status = STATUS_NO_MEMORY;
}
else
{
/* If necessary, shrink by removing oldest entries */
for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--)
{
RtlFreeUnicodeString(Hist->Entries++);
Hist->Position += (Hist->Position == 0);
}
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
Hist->MaxEntries = MaxEntries;
Hist->Entries = memcpy(NewEntryList, Hist->Entries,
Hist->NumEntries * sizeof(UNICODE_STRING));
ConsoleFreeHeap(OldEntryList);
}
Hist = HistoryFindBuffer(Console,
SetHistoryNumberCommandsRequest->ExeName,
SetHistoryNumberCommandsRequest->ExeLength,
SetHistoryNumberCommandsRequest->Unicode2);
if (Hist)
{
UINT MaxEntries = SetHistoryNumberCommandsRequest->NumCommands;
PUNICODE_STRING OldEntryList = Hist->Entries;
PUNICODE_STRING NewEntryList = ConsoleAllocHeap(0, MaxEntries * sizeof(UNICODE_STRING));
if (!NewEntryList)
{
Status = STATUS_NO_MEMORY;
}
else
{
/* If necessary, shrink by removing oldest entries */
for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--)
{
RtlFreeUnicodeString(Hist->Entries++);
Hist->Position += (Hist->Position == 0);
}
Hist->MaxEntries = MaxEntries;
Hist->Entries = memcpy(NewEntryList, Hist->Entries,
Hist->NumEntries * sizeof(UNICODE_STRING));
ConsoleFreeHeap(OldEntryList);
}
ConSrvReleaseConsole(Console, TRUE);
}
ConSrvReleaseConsole(Console, TRUE);
return Status;
}
CSR_API(SrvGetConsoleHistory)
{
#if 0 // Vista+
PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
PCONSOLE Console;
NTSTATUS Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
@@ -623,10 +730,15 @@ CSR_API(SrvGetConsoleHistory)
ConSrvReleaseConsole(Console, TRUE);
}
return Status;
#else
DPRINT1("%s not yet implemented\n", __FUNCTION__);
return STATUS_NOT_IMPLEMENTED;
#endif
}
CSR_API(SrvSetConsoleHistory)
{
#if 0 // Vista+
PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
PCONSOLE Console;
NTSTATUS Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
@@ -638,12 +750,29 @@ CSR_API(SrvSetConsoleHistory)
ConSrvReleaseConsole(Console, TRUE);
}
return Status;
#else
DPRINT1("%s not yet implemented\n", __FUNCTION__);
return STATUS_NOT_IMPLEMENTED;
#endif
}
CSR_API(SrvSetConsoleCommandHistoryMode)
{
DPRINT1("%s not yet implemented\n", __FUNCTION__);
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status;
PCONSOLE_SETHISTORYMODE SetHistoryModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryModeRequest;
PCONSOLE Console;
DPRINT1("SrvSetConsoleCommandHistoryMode(Mode = %d) is not yet implemented\n",
SetHistoryModeRequest->Mode);
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if (!NT_SUCCESS(Status)) return Status;
/* This API is not yet implemented */
Status = STATUS_NOT_IMPLEMENTED;
ConSrvReleaseConsole(Console, TRUE);
return Status;
}
/* EOF */
@@ -8,5 +8,9 @@
#pragma once
VOID FASTCALL HistoryDeleteBuffers(PCONSOLE Console);
VOID FASTCALL LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent);
VOID HistoryDeleteBuffers(PCONSOLE Console);
VOID
LineInputKeyDown(PCONSOLE Console,
PUNICODE_STRING ExeName,
KEY_EVENT_RECORD *KeyEvent);
@@ -8,15 +8,15 @@
#pragma once
NTSTATUS FASTCALL ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
NTSTATUS ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle,
PCONSOLE_START_INFO ConsoleStartInfo);
NTSTATUS FASTCALL ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
HANDLE ConsoleHandle,
BOOL CreateNewHandlesTable,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle);
VOID FASTCALL ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData);
VOID ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData);