ReactOS 0.4.16-dev-340-g0540c21
graphics.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Driver DLL
4 * FILE: win32ss/user/winsrv/consrv/condrv/graphics.c
5 * PURPOSE: Console Output Functions for graphics-mode screen-buffers
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 *
8 * NOTE: See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/
9 * for more information.
10 */
11
12/* INCLUDES *******************************************************************/
13
14#include <consrv.h>
15
16#define NDEBUG
17#include <debug.h>
18
19/* PRIVATE FUNCTIONS **********************************************************/
20
26 IN SIZE_T Size);
27
28VOID
30
31
36 IN PGRAPHICS_BUFFER_INFO GraphicsInfo)
37{
39 PGRAPHICS_SCREEN_BUFFER NewBuffer = NULL;
40
41 LARGE_INTEGER SectionSize;
42 SIZE_T ViewSize = 0;
43
44 if (Buffer == NULL || Console == NULL || GraphicsInfo == NULL)
46
47 *Buffer = NULL;
48
50 Console,
53 if (!NT_SUCCESS(Status)) return Status;
54
55 /*
56 * Remember the handle to the process so that we can close or unmap
57 * correctly the allocated resources when the client releases the
58 * screen buffer.
59 */
60 NewBuffer->ClientProcess = ProcessHandle;
61
62 /* Get information from the graphics buffer information structure */
63 NewBuffer->BitMapInfoLength = GraphicsInfo->Info.dwBitMapInfoLength;
64
66 if (NewBuffer->BitMapInfo == NULL)
67 {
70 }
71
72 /* Adjust the bitmap height if needed (bottom-top vs. top-bottom). Use always bottom-up. */
73 if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight > 0)
74 GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight = -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;
75
76 /* We do not use anything else than uncompressed bitmaps */
77 if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression != BI_RGB)
78 {
79 DPRINT1("biCompression == %d != BI_RGB, fix that!\n",
80 GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression);
81 GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression = BI_RGB;
82 }
83
84 RtlCopyMemory(NewBuffer->BitMapInfo,
85 GraphicsInfo->Info.lpBitMapInfo,
86 GraphicsInfo->Info.dwBitMapInfoLength);
87
88 NewBuffer->BitMapUsage = GraphicsInfo->Info.dwUsage;
89
90 /* Set the screen buffer size. Fight against overflows. */
91 if ( GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth <= 0xFFFF &&
92 -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight <= 0xFFFF )
93 {
94 /* Be careful about the sign of biHeight */
95 NewBuffer->ScreenBufferSize.X = (SHORT)GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth ;
96 NewBuffer->ScreenBufferSize.Y = (SHORT)-GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;
97
98 NewBuffer->OldViewSize = NewBuffer->ViewSize =
99 NewBuffer->OldScreenBufferSize = NewBuffer->ScreenBufferSize;
100 }
101 else
102 {
104 ConsoleFreeHeap(NewBuffer->BitMapInfo);
106 goto Quit;
107 }
108
109 /*
110 * Create a mutex to synchronize bitmap memory access
111 * between ourselves and the client.
112 */
114 if (!NT_SUCCESS(Status))
115 {
116 DPRINT1("NtCreateMutant() failed: %lu\n", Status);
117 ConsoleFreeHeap(NewBuffer->BitMapInfo);
119 goto Quit;
120 }
121
122 /*
123 * Duplicate the Mutex for the client. We must keep a trace of it
124 * so that we can close it when the client releases the screen buffer.
125 */
127 NewBuffer->Mutex,
129 &NewBuffer->ClientMutex,
131 if (!NT_SUCCESS(Status))
132 {
133 DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
134 NtClose(NewBuffer->Mutex);
135 ConsoleFreeHeap(NewBuffer->BitMapInfo);
137 goto Quit;
138 }
139
140 /*
141 * Create a memory section for the bitmap area, to share with the client.
142 */
143 SectionSize.QuadPart = NewBuffer->BitMapInfo->bmiHeader.biSizeImage;
144 Status = NtCreateSection(&NewBuffer->hSection,
146 NULL,
147 &SectionSize,
150 NULL);
151 if (!NT_SUCCESS(Status))
152 {
153 DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status);
156 NtClose(NewBuffer->Mutex);
157 ConsoleFreeHeap(NewBuffer->BitMapInfo);
159 goto Quit;
160 }
161
162 /*
163 * Create a view for our needs.
164 */
165 ViewSize = 0;
166 NewBuffer->BitMap = NULL;
169 (PVOID*)&NewBuffer->BitMap,
170 0,
171 0,
172 NULL,
173 &ViewSize,
174 ViewUnmap,
175 0,
177 if (!NT_SUCCESS(Status))
178 {
179 DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status);
180 NtClose(NewBuffer->hSection);
183 NtClose(NewBuffer->Mutex);
184 ConsoleFreeHeap(NewBuffer->BitMapInfo);
186 goto Quit;
187 }
188
189 /*
190 * Create a view for the client. We must keep a trace of it so that
191 * we can unmap it when the client releases the screen buffer.
192 */
193 ViewSize = 0;
194 NewBuffer->ClientBitMap = NULL;
197 (PVOID*)&NewBuffer->ClientBitMap,
198 0,
199 0,
200 NULL,
201 &ViewSize,
202 ViewUnmap,
203 0,
205 if (!NT_SUCCESS(Status))
206 {
207 DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status);
209 NtClose(NewBuffer->hSection);
212 NtClose(NewBuffer->Mutex);
213 ConsoleFreeHeap(NewBuffer->BitMapInfo);
215 goto Quit;
216 }
217
218 NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0;
219
220 NewBuffer->CursorBlinkOn = FALSE;
221 NewBuffer->ForceCursorOff = TRUE;
222 NewBuffer->CursorInfo.bVisible = FALSE;
223 NewBuffer->CursorInfo.dwSize = 0;
224 NewBuffer->CursorPosition.X = NewBuffer->CursorPosition.Y = 0;
225
226 NewBuffer->Mode = 0;
227
228 *Buffer = (PCONSOLE_SCREEN_BUFFER)NewBuffer;
230
231Quit:
232 return Status;
233}
234
235VOID
237{
239
240 /*
241 * IMPORTANT !! Reinitialize the type so that we don't enter a recursive
242 * infinite loop when calling CONSOLE_SCREEN_BUFFER_Destroy.
243 */
244 Buffer->Header.Type = SCREEN_BUFFER;
245
246 /*
247 * Uninitialize the graphics screen buffer
248 * in the reverse way we initialized it.
249 */
252 NtClose(Buff->hSection);
255 NtClose(Buff->Mutex);
257
259}
260
261/* EOF */
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3481
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3074
NTSTATUS NTAPI NtMapViewOfSection(IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3255
CConsole Console
Type
Definition: Type.h:7
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define BI_RGB
Definition: precomp.h:56
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI NtCreateMutant(OUT PHANDLE MutantHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN BOOLEAN InitialOwner)
Definition: mutant.c:79
#define MUTANT_ALL_ACCESS
Definition: extypes.h:110
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
#define SEC_COMMIT
Definition: mmtypes.h:100
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewUnmap
Definition: nt_native.h:1279
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
short SHORT
Definition: pedump.c:59
#define STATUS_SUCCESS
Definition: shellext.h:65
LPBITMAPINFO BitMapInfo
Definition: conio.h:150
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
VOID GRAPHICS_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer)
Definition: graphics.c:236
NTSTATUS GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER *Buffer, IN PCONSOLE Console, IN HANDLE ProcessHandle, IN PGRAPHICS_BUFFER_INFO GraphicsInfo)
Definition: graphics.c:33
VOID CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer)
Definition: conoutput.c:55
NTSTATUS CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER *Buffer, IN PCONSOLE Console, IN CONSOLE_IO_OBJECT_TYPE Type, IN SIZE_T Size)
Definition: conoutput.c:37
#define ConsoleAllocHeap(Flags, Size)
Definition: heap.h:14
#define ConsoleFreeHeap(HeapBase)
Definition: heap.h:15
enum _CONSOLE_IO_OBJECT_TYPE CONSOLE_IO_OBJECT_TYPE
@ SCREEN_BUFFER
Definition: conio.h:27
@ GRAPHICS_BUFFER
Definition: conio.h:26
struct _CONSOLE_SCREEN_BUFFER * PCONSOLE_SCREEN_BUFFER
struct _GRAPHICS_SCREEN_BUFFER * PGRAPHICS_SCREEN_BUFFER
#define DUPLICATE_SAME_ACCESS
#define DUPLICATE_CLOSE_SOURCE