mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-01 19:26:16 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -56,7 +56,7 @@ CloseConsoleHandle(HANDLE Handle);
|
||||
HANDLE WINAPI
|
||||
GetConsoleInputWaitHandle(VOID);
|
||||
|
||||
HANDLE FASTCALL
|
||||
HANDLE
|
||||
TranslateStdHandle(HANDLE hHandle);
|
||||
|
||||
VOID
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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: Gé 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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user