Author: hbelusca
Date: Sat Aug 9 19:47:40 2014
New Revision: 63849
URL:
http://svn.reactos.org/svn/reactos?rev=63849&view=rev
Log:
[KERNEL32][CONSRV]: Implement a basic RegisterConsoleVDM (see revision 62371 for more
details).
Modified:
branches/condrv_restructure/dll/win32/kernel32/client/vdm.c
branches/condrv_restructure/include/psdk/wincon.h
branches/condrv_restructure/include/reactos/subsys/win/conmsg.h
branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/conoutput.c
branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c
branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h
branches/condrv_restructure/win32ss/user/winsrv/consrv/subsysreg.c
Modified: branches/condrv_restructure/dll/win32/kernel32/client/vdm.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/dll/win32/ke…
==============================================================================
--- branches/condrv_restructure/dll/win32/kernel32/client/vdm.c [iso-8859-1] (original)
+++ branches/condrv_restructure/dll/win32/kernel32/client/vdm.c [iso-8859-1] Sat Aug 9
19:47:40 2014
@@ -1640,26 +1640,101 @@
/*
- * @unimplemented
+ * @implemented (undocumented)
*/
BOOL
WINAPI
-RegisterConsoleVDM (
- DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3,
- DWORD Unknown4,
- DWORD Unknown5,
- DWORD Unknown6,
- DWORD Unknown7,
- DWORD Unknown8,
- DWORD Unknown9,
- DWORD Unknown10
- )
-{
- STUB;
- return FALSE;
+RegisterConsoleVDM(IN DWORD dwRegisterFlags,
+ IN HANDLE hStartHardwareEvent,
+ IN HANDLE hEndHardwareEvent,
+ IN HANDLE hErrorHardwareEvent,
+ IN DWORD dwUnusedVar,
+ OUT LPDWORD lpVideoStateLength,
+ OUT PVOID* lpVideoState, // PVIDEO_HARDWARE_STATE_HEADER*
+ IN PVOID lpUnusedBuffer,
+ IN DWORD dwUnusedBufferLength,
+ IN COORD dwVDMBufferSize,
+ OUT PVOID* lpVDMBuffer)
+{
+ BOOL Success;
+ CONSOLE_API_MESSAGE ApiMessage;
+ PCONSOLE_REGISTERVDM RegisterVDMRequest = &ApiMessage.Data.RegisterVDMRequest;
+ PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
+
+ /* Set up the data to send to the Console Server */
+ RegisterVDMRequest->ConsoleHandle =
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+ RegisterVDMRequest->RegisterFlags = dwRegisterFlags;
+
+ if (dwRegisterFlags != 0)
+ {
+ RegisterVDMRequest->StartHardwareEvent = hStartHardwareEvent;
+ RegisterVDMRequest->EndHardwareEvent = hEndHardwareEvent;
+ RegisterVDMRequest->ErrorHardwareEvent = hErrorHardwareEvent;
+
+ RegisterVDMRequest->VDMBufferSize = dwVDMBufferSize;
+
+#if 0
+ RegisterVDMRequest->UnusedBufferLength = dwUnusedBufferLength;
+
+ /* Allocate a Capture Buffer */
+ CaptureBuffer = CsrAllocateCaptureBuffer(1, dwUnusedBufferLength);
+ if (CaptureBuffer == NULL)
+ {
+ DPRINT1("CsrAllocateCaptureBuffer failed!\n");
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ /* Capture the buffer to write */
+ CsrCaptureMessageBuffer(CaptureBuffer,
+ (PVOID)lpUnusedBuffer,
+ dwUnusedBufferLength,
+ (PVOID*)&RegisterVDMRequest->UnusedBuffer);
+#endif
+ }
+ else
+ {
+ // CaptureBuffer = NULL;
+ }
+
+ /* Call the server */
+ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ CaptureBuffer,
+ CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX,
ConsolepRegisterVDM),
+ sizeof(*RegisterVDMRequest));
+
+ /* Check for success */
+ Success = NT_SUCCESS(ApiMessage.Status);
+
+ /* Release the capture buffer if needed */
+ if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
+
+ /* Retrieve the results */
+ if (Success)
+ {
+ if (dwRegisterFlags != 0)
+ {
+ _SEH2_TRY
+ {
+ *lpVideoStateLength = RegisterVDMRequest->VideoStateLength;
+ *lpVideoState = RegisterVDMRequest->VideoState;
+ *lpVDMBuffer = RegisterVDMRequest->VDMBuffer;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastError(ERROR_INVALID_ACCESS);
+ Success = FALSE;
+ }
+ _SEH2_END;
+ }
+ }
+ else
+ {
+ BaseSetLastNTError(ApiMessage.Status);
+ }
+
+ /* Return success status */
+ return Success;
}
@@ -1756,9 +1831,8 @@
{
DPRINT1("VDMOperationStarted(%d)\n", Unknown0);
- return
- BaseUpdateVDMEntry(VdmEntryUpdateControlCHandler,
- NULL,
- 0,
- Unknown0);
-}
+ return BaseUpdateVDMEntry(VdmEntryUpdateControlCHandler,
+ NULL,
+ 0,
+ Unknown0);
+}
Modified: branches/condrv_restructure/include/psdk/wincon.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/include/psdk…
==============================================================================
--- branches/condrv_restructure/include/psdk/wincon.h [iso-8859-1] (original)
+++ branches/condrv_restructure/include/psdk/wincon.h [iso-8859-1] Sat Aug 9 19:47:40
2014
@@ -618,6 +618,12 @@
// BOOL WINAPI SetStdHandle(_In_ DWORD, _In_ HANDLE);
/* Undocumented */
BOOL WINAPI VerifyConsoleIoHandle(_In_ HANDLE);
+/* Undocumented */
+BOOL
+WINAPI
+RegisterConsoleVDM(_In_ DWORD, _In_ HANDLE, _In_ HANDLE, _In_ HANDLE, _In_ DWORD,
+ _Out_ LPDWORD, _Out_ PVOID*, _In_ PVOID, _In_ DWORD, _In_ COORD,
+ _Out_ PVOID*);
BOOL
WINAPI
Modified: branches/condrv_restructure/include/reactos/subsys/win/conmsg.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/include/reac…
==============================================================================
--- branches/condrv_restructure/include/reactos/subsys/win/conmsg.h [iso-8859-1]
(original)
+++ branches/condrv_restructure/include/reactos/subsys/win/conmsg.h [iso-8859-1] Sat Aug
9 19:47:40 2014
@@ -806,6 +806,28 @@
BOOL Ansi;
} CONSOLE_GETKBDLAYOUTNAME, *PCONSOLE_GETKBDLAYOUTNAME;
+typedef struct
+{
+ HANDLE ConsoleHandle;
+ ULONG RegisterFlags;
+ HANDLE StartHardwareEvent;
+ HANDLE EndHardwareEvent;
+ HANDLE ErrorHardwareEvent;
+
+ /* Unused member */
+ ULONG UnusedVar;
+
+ ULONG VideoStateLength;
+ PVOID VideoState; // PVIDEO_HARDWARE_STATE_HEADER
+
+ /* Unused members */
+ PVOID UnusedBuffer;
+ ULONG UnusedBufferLength;
+
+ COORD VDMBufferSize;
+ PVOID VDMBuffer;
+} CONSOLE_REGISTERVDM, *PCONSOLE_REGISTERVDM;
+
typedef struct _CONSOLE_API_MESSAGE
{
PORT_MESSAGE Header;
@@ -903,6 +925,9 @@
CONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest;
CONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest;
CONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest;
+
+ /* Virtual DOS Machine */
+ CONSOLE_REGISTERVDM RegisterVDMRequest;
} Data;
} CONSOLE_API_MESSAGE, *PCONSOLE_API_MESSAGE;
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/conoutput.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/conoutput.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/conoutput.c [iso-8859-1]
Sat Aug 9 19:47:40 2014
@@ -208,6 +208,13 @@
/* PUBLIC DRIVER APIS *********************************************************/
NTSTATUS NTAPI
+ConDrvWriteConsoleOutputVDM(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN PCHAR_CELL CharInfo/*Buffer*/,
+ IN COORD CharInfoSize,
+ IN OUT PSMALL_RECT WriteRegion,
+ IN BOOLEAN DrawRegion);
+NTSTATUS NTAPI
ConDrvInvalidateBitMapRect(IN PCONSOLE Console,
IN PCONSOLE_SCREEN_BUFFER Buffer,
IN PSMALL_RECT Region)
@@ -217,6 +224,19 @@
/* Validity check */
ASSERT(Console == Buffer->Header.Console);
+
+ /* In text-mode only, draw the VDM buffer if present */
+ if (GetType(Buffer) == TEXTMODE_BUFFER)
+ {
+ PTEXTMODE_SCREEN_BUFFER TextBuffer = (PTEXTMODE_SCREEN_BUFFER)Buffer;
+
+ /*Status =*/ ConDrvWriteConsoleOutputVDM(Buffer->Header.Console,
+ TextBuffer,
+ Console->VDMBuffer,
+ Console->VDMBufferSize,
+ Region,
+ FALSE);
+ }
/* If the output buffer is the current one, redraw the correct portion of the screen
*/
if (Buffer == Console->ActiveBuffer) TermDrawRegion(Console, Region);
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/condrv/text.c [iso-8859-1] Sat
Aug 9 19:47:40 2014
@@ -722,6 +722,68 @@
return STATUS_SUCCESS;
}
+/*
+ * NOTE: This function is strongly inspired by ConDrvWriteConsoleOutput...
+ */
+NTSTATUS NTAPI
+ConDrvWriteConsoleOutputVDM(IN PCONSOLE Console,
+ IN PTEXTMODE_SCREEN_BUFFER Buffer,
+ IN PCHAR_CELL CharInfo/*Buffer*/,
+ IN COORD CharInfoSize,
+ IN OUT PSMALL_RECT WriteRegion,
+ IN BOOLEAN DrawRegion)
+{
+ SHORT X, Y;
+ SMALL_RECT ScreenBuffer;
+ PCHAR_CELL CurCharInfo;
+ SMALL_RECT CapturedWriteRegion;
+ PCHAR_INFO Ptr;
+
+ if (Console == NULL || Buffer == NULL || CharInfo == NULL || WriteRegion == NULL)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Validity check */
+ ASSERT(Console == Buffer->Header.Console);
+
+ CapturedWriteRegion = *WriteRegion;
+
+ /* Make sure WriteRegion is inside the screen buffer */
+ ConioInitRect(&ScreenBuffer, 0, 0,
+ Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1);
+ if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer,
&CapturedWriteRegion))
+ {
+ /*
+ * It is okay to have a WriteRegion completely outside
+ * the screen buffer. No data is written then.
+ */
+ return STATUS_SUCCESS;
+ }
+
+ // CurCharInfo = CharInfo;
+
+ for (Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; ++Y)
+ {
+ /**/CurCharInfo = CharInfo + Y * CharInfoSize.X + CapturedWriteRegion.Left;/**/
+
+ Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y);
+ for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; ++X)
+ {
+ ConsoleAnsiCharToUnicodeChar(Console, &Ptr->Char.UnicodeChar,
&CurCharInfo->Char);
+ Ptr->Attributes = CurCharInfo->Attributes;
+ ++Ptr;
+ ++CurCharInfo;
+ }
+ }
+
+ if (DrawRegion) TermDrawRegion(Console, &CapturedWriteRegion);
+
+ *WriteRegion = CapturedWriteRegion;
+
+ return STATUS_SUCCESS;
+}
+
NTSTATUS NTAPI
ConDrvWriteConsole(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/include/conio.h [iso-8859-1]
Sat Aug 9 19:47:40 2014
@@ -18,6 +18,15 @@
#define DEFAULT_SCREEN_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
#define DEFAULT_POPUP_ATTRIB (FOREGROUND_BLUE | FOREGROUND_RED | \
BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED |
BACKGROUND_INTENSITY)
+
+/* VGA character cell */
+typedef struct _CHAR_CELL
+{
+ CHAR Char;
+ BYTE Attributes;
+} CHAR_CELL, *PCHAR_CELL;
+C_ASSERT(sizeof(CHAR_CELL) == 2);
+
/* Object type magic numbers */
typedef enum _CONSOLE_IO_OBJECT_TYPE
@@ -300,6 +309,17 @@
PCONSOLE_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer
*/
UINT OutputCodePage;
+ /**** Per-console Virtual DOS Machine Text-mode Buffer ****/
+ COORD VDMBufferSize; /* Real size of the VDM buffer, in units of ???
*/
+ HANDLE VDMBufferSection; /* Handle to the memory shared section for the VDM
buffer */
+ PVOID VDMBuffer; /* Our VDM buffer */
+ PVOID ClientVDMBuffer; /* A copy of the client view of our VDM buffer */
+ HANDLE VDMClientProcess; /* Handle to the client process who opened the
buffer, to unmap the view */
+
+ HANDLE StartHardwareEvent;
+ HANDLE EndHardwareEvent;
+ HANDLE ErrorHardwareEvent;
+
/****************************** 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
*/
Modified: branches/condrv_restructure/win32ss/user/winsrv/consrv/subsysreg.c
URL:
http://svn.reactos.org/svn/reactos/branches/condrv_restructure/win32ss/user…
==============================================================================
--- branches/condrv_restructure/win32ss/user/winsrv/consrv/subsysreg.c [iso-8859-1]
(original)
+++ branches/condrv_restructure/win32ss/user/winsrv/consrv/subsysreg.c [iso-8859-1] Sat
Aug 9 19:47:40 2014
@@ -21,8 +21,132 @@
CSR_API(SrvRegisterConsoleVDM)
{
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PCONSOLE_REGISTERVDM RegisterVDMRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.RegisterVDMRequest;
+ PCONSOLE Console;
+
+ DPRINT1("SrvRegisterConsoleVDM(%d)\n",
RegisterVDMRequest->RegisterFlags);
+
+ Status =
ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
+ &Console, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Can't get console\n");
+ return Status;
+ }
+
+ if (RegisterVDMRequest->RegisterFlags != 0)
+ {
+ LARGE_INTEGER SectionSize;
+ ULONG Size, ViewSize = 0;
+ HANDLE ProcessHandle;
+
+ /*
+ * Remember the handle to the process so that we can close or unmap
+ * correctly the allocated resources when the client releases the
+ * screen buffer.
+ */
+ ProcessHandle = CsrGetClientThread()->Process->ProcessHandle;
+ Console->VDMClientProcess = ProcessHandle;
+
+ Console->VDMBufferSize = RegisterVDMRequest->VDMBufferSize;
+
+ Size = Console->VDMBufferSize.X * Console->VDMBufferSize.Y
+ * sizeof(CHAR_CELL);
+
+ /*
+ * Create a memory section for the VDM buffer, to share with the client.
+ */
+ SectionSize.QuadPart = Size;
+ Status = NtCreateSection(&Console->VDMBufferSection,
+ SECTION_ALL_ACCESS,
+ NULL,
+ &SectionSize,
+ PAGE_READWRITE,
+ SEC_COMMIT,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error: Impossible to create a shared section ; Status =
%lu\n", Status);
+ goto Quit;
+ }
+
+ /*
+ * Create a view for our needs.
+ */
+ ViewSize = 0;
+ Console->VDMBuffer = NULL;
+ Status = NtMapViewOfSection(Console->VDMBufferSection,
+ NtCurrentProcess(),
+ (PVOID*)&Console->VDMBuffer,
+ 0,
+ 0,
+ NULL,
+ &ViewSize,
+ ViewUnmap,
+ 0,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error: Impossible to map the shared section ; Status =
%lu\n", Status);
+ NtClose(Console->VDMBufferSection);
+ goto Quit;
+ }
+
+ /*
+ * Create a view for the client. We must keep a trace of it so that
+ * we can unmap it when the client releases the VDM buffer.
+ */
+ ViewSize = 0;
+ Console->ClientVDMBuffer = NULL;
+ Status = NtMapViewOfSection(Console->VDMBufferSection,
+ ProcessHandle,
+ (PVOID*)&Console->ClientVDMBuffer,
+ 0,
+ 0,
+ NULL,
+ &ViewSize,
+ ViewUnmap,
+ 0,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error: Impossible to map the shared section ; Status =
%lu\n", Status);
+ NtUnmapViewOfSection(NtCurrentProcess(), Console->VDMBuffer);
+ NtClose(Console->VDMBufferSection);
+ goto Quit;
+ }
+
+ // TODO: Duplicate the event handles.
+
+ RegisterVDMRequest->VDMBuffer = Console->ClientVDMBuffer;
+
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* RegisterFlags == 0 means we are unregistering the VDM */
+
+ // TODO: Close the duplicated handles.
+
+ if (Console->VDMBuffer)
+ {
+ /*
+ * Uninitialize the graphics screen buffer
+ * in the reverse way we initialized it.
+ */
+ NtUnmapViewOfSection(Console->VDMClientProcess,
Console->ClientVDMBuffer);
+ NtUnmapViewOfSection(NtCurrentProcess(), Console->VDMBuffer);
+ NtClose(Console->VDMBufferSection);
+ }
+ Console->VDMBuffer = Console->ClientVDMBuffer = NULL;
+
+ Console->VDMBufferSize.X = Console->VDMBufferSize.Y = 0;
+ }
+
+Quit:
+ ConSrvReleaseConsole(Console, TRUE);
+ return Status;
}
CSR_API(SrvVDMConsoleOperation)