ReactOS 0.4.15-dev-7842-g558ab78
int10.c
Go to the documentation of this file.
1/*
2 * VideoPort driver
3 *
4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21
22#include "videoprt.h"
23
24#include <ndk/kefuncs.h>
25#include <ndk/halfuncs.h>
26#include <ndk/mmfuncs.h>
27
28#define NDEBUG
29#include <debug.h>
30
31/* PRIVATE FUNCTIONS **********************************************************/
32
33#define IsLowV86Mem(_Seg, _Off) ((((_Seg) << 4) + (_Off)) < (0xa0000))
34
35/* Those two functions below are there so that CSRSS can't access low mem.
36 * Expecially, MAKE IT CRASH ON NULL ACCESS */
37static
38VOID
40{
41 /* We pass a non-NULL address so that ZwAllocateVirtualMemory really does it
42 * And we truncate one page to get the right range spanned. */
45 SIZE_T ViewSize = 0xa0000 - PAGE_SIZE;
46
47 /* We should only do that for CSRSS. */
49
50 /* Commit (again) the pages, but with PAGE_NOACCESS protection */
51 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
53 0,
54 &ViewSize,
58}
59
60static
61VOID
63{
64 /* We pass a non-NULL address so that ZwAllocateVirtualMemory really does it
65 * And we truncate one page to get the right range spanned. */
68 SIZE_T ViewSize = 0xa0000 - PAGE_SIZE;
69
70 /* We should only do that for CSRSS, for the v86 address space */
72
73 /* Commit (again) the pages, but with PAGE_READWRITE protection */
74 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
76 0,
77 &ViewSize,
81}
82
83#if defined(_M_IX86) || defined(_M_AMD64)
87{
89 UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
91 HANDLE PhysMemHandle;
95#ifdef _M_IX86
96 CHAR IVTAndBda[1024 + 256];
97#endif // _M_IX86
98
99 /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
100 BaseAddress = 0;
101 ViewSize = 1024 * 1024;
102 Status = ZwFreeVirtualMemory(NtCurrentProcess(),
104 &ViewSize,
106 if (!NT_SUCCESS(Status))
107 {
108 DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
109 return 0;
110 }
111
112 /* Open the physical memory section */
114 &PhysMemName,
116 NULL,
117 NULL);
118 Status = ZwOpenSection(&PhysMemHandle,
121 if (!NT_SUCCESS(Status))
122 {
123 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
124 return Status;
125 }
126
127 /* Map the BIOS and device registers into the address space */
128 Offset.QuadPart = 0xa0000;
129 ViewSize = 0x100000 - 0xa0000;
130 BaseAddress = (PVOID)0xa0000;
131 Status = ZwMapViewOfSection(PhysMemHandle,
134 0,
135 ViewSize,
136 &Offset,
137 &ViewSize,
138 ViewUnmap,
139 0,
141 if (!NT_SUCCESS(Status))
142 {
143 DPRINT1("Couldn't map physical memory (%x)\n", Status);
144 ZwClose(PhysMemHandle);
145 return Status;
146 }
147
148 /* Close physical memory section handle */
149 ZwClose(PhysMemHandle);
150
151 if (BaseAddress != (PVOID)0xa0000)
152 {
153 DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
155 return STATUS_UNSUCCESSFUL;
156 }
157
158 /* Allocate some low memory to use for the non-BIOS
159 * parts of the v86 mode address space
160 */
161 BaseAddress = (PVOID)0x1;
162 ViewSize = 0xa0000 - 0x1000;
163 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
165 0,
166 &ViewSize,
169 if (!NT_SUCCESS(Status))
170 {
171 DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
172 return Status;
173 }
174 if (BaseAddress != (PVOID)0x0)
175 {
176 DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
178 return 0;
179 }
180
181#ifdef _M_IX86
182 /* Get the real mode IVT and BDA from the kernel */
183 Status = NtVdmControl(VdmInitialize, IVTAndBda);
184 if (!NT_SUCCESS(Status))
185 {
186 DPRINT1("NtVdmControl failed (status %x)\n", Status);
187 return Status;
188 }
189#endif // _M_IX86
190
191 /* Protect the V86 address space after this */
193
194 /* Return success */
195 return STATUS_SUCCESS;
196}
197#else
199NTAPI
201{
205}
206#endif
207
209NTAPI
212 OUT PUSHORT Seg,
213 OUT PUSHORT Off,
215{
217#ifdef _M_IX86
218 PVOID MemoryAddress;
219 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
221 SIZE_T Size;
222
223 TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n");
224
225 IntAttachToCSRSS(&CallingProcess, &ApcState);
226
227 Size = *Length;
228 MemoryAddress = (PVOID)0x20000;
229
230 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
231 &MemoryAddress,
232 0,
233 &Size,
236 if (!NT_SUCCESS(Status))
237 {
238 WARN_(VIDEOPRT, "- ZwAllocateVirtualMemory failed\n");
239 IntDetachFromCSRSS(&CallingProcess, &ApcState);
241 }
242
243 if (MemoryAddress > (PVOID)(0x100000 - Size))
244 {
245 ZwFreeVirtualMemory(NtCurrentProcess(),
246 &MemoryAddress,
247 &Size,
249 WARN_(VIDEOPRT, "- Unacceptable memory allocated\n");
250 IntDetachFromCSRSS(&CallingProcess, &ApcState);
252 }
253
254 *Length = (ULONG)Size;
255 *Seg = (USHORT)((ULONG_PTR)MemoryAddress >> 4);
256 *Off = (USHORT)((ULONG_PTR)MemoryAddress & 0xF);
257
258 INFO_(VIDEOPRT, "- Segment: %x\n", (ULONG_PTR)MemoryAddress >> 4);
259 INFO_(VIDEOPRT, "- Offset: %x\n", (ULONG_PTR)MemoryAddress & 0xF);
260 INFO_(VIDEOPRT, "- Length: %x\n", *Length);
261
262 IntDetachFromCSRSS(&CallingProcess, &ApcState);
263
264 return NO_ERROR;
265#else
268#endif
269}
270
272NTAPI
275 IN USHORT Seg,
276 IN USHORT Off)
277{
279#ifdef _M_IX86
280 PVOID MemoryAddress = (PVOID)((ULONG_PTR)(Seg << 4) | Off);
281 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
283 SIZE_T Size = 0;
284
285 TRACE_(VIDEOPRT, "IntInt10FreeBuffer\n");
286 INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
287 INFO_(VIDEOPRT, "- Offset: %x\n", Off);
288
289 IntAttachToCSRSS(&CallingProcess, &ApcState);
290 Status = ZwFreeVirtualMemory(NtCurrentProcess(),
291 &MemoryAddress,
292 &Size,
294
295 IntDetachFromCSRSS(&CallingProcess, &ApcState);
296
297 return Status;
298#else
299 Status = x86BiosFreeBuffer(Seg, Off);
301#endif
302}
303
305NTAPI
308 IN USHORT Seg,
309 IN USHORT Off,
312{
313#ifdef _M_IX86
314 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
316
317 TRACE_(VIDEOPRT, "IntInt10ReadMemory\n");
318 INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
319 INFO_(VIDEOPRT, "- Offset: %x\n", Off);
320 INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
321 INFO_(VIDEOPRT, "- Length: %x\n", Length);
322
323 IntAttachToCSRSS(&CallingProcess, &ApcState);
324
325 if (IsLowV86Mem(Seg, Off))
327 RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)(Seg << 4) | Off), Length);
328 if (IsLowV86Mem(Seg, Off))
330
331 IntDetachFromCSRSS(&CallingProcess, &ApcState);
332
333 return NO_ERROR;
334#else
336
339#endif
340}
341
343NTAPI
346 IN USHORT Seg,
347 IN USHORT Off,
350{
351#ifdef _M_IX86
352 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
354
355 TRACE_(VIDEOPRT, "IntInt10WriteMemory\n");
356 INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
357 INFO_(VIDEOPRT, "- Offset: %x\n", Off);
358 INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer);
359 INFO_(VIDEOPRT, "- Length: %x\n", Length);
360
361 IntAttachToCSRSS(&CallingProcess, &ApcState);
362 if (IsLowV86Mem(Seg, Off))
364 RtlCopyMemory((PVOID)((ULONG_PTR)(Seg << 4) | Off), Buffer, Length);
365 if (IsLowV86Mem(Seg, Off))
367 IntDetachFromCSRSS(&CallingProcess, &ApcState);
368
369 return NO_ERROR;
370#else
372
375#endif
376}
377
379NTAPI
382 IN OUT PINT10_BIOS_ARGUMENTS BiosArguments)
383{
384#ifdef _M_AMD64
386#else
388#endif
390 PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
392
393 /* Attach to CSRSS */
394 IntAttachToCSRSS(&CallingProcess, &ApcState);
395
396 /* Clear the context */
398
399 /* Fill out the bios arguments */
400 BiosContext.Eax = BiosArguments->Eax;
401 BiosContext.Ebx = BiosArguments->Ebx;
402 BiosContext.Ecx = BiosArguments->Ecx;
403 BiosContext.Edx = BiosArguments->Edx;
404 BiosContext.Esi = BiosArguments->Esi;
405 BiosContext.Edi = BiosArguments->Edi;
406 BiosContext.Ebp = BiosArguments->Ebp;
407 BiosContext.SegDs = BiosArguments->SegDs;
408 BiosContext.SegEs = BiosArguments->SegEs;
409
410 /* Do the ROM BIOS call */
412 Executive,
414 FALSE,
415 NULL);
416
417 /* The kernel needs access here */
419#ifdef _M_AMD64
421#else
423#endif
425
427
428 /* Return the arguments */
429 BiosArguments->Eax = BiosContext.Eax;
430 BiosArguments->Ebx = BiosContext.Ebx;
431 BiosArguments->Ecx = BiosContext.Ecx;
432 BiosArguments->Edx = BiosContext.Edx;
433 BiosArguments->Esi = BiosContext.Esi;
434 BiosArguments->Edi = BiosContext.Edi;
435 BiosArguments->Ebp = BiosContext.Ebp;
436 BiosArguments->SegDs = (USHORT)BiosContext.SegDs;
437 BiosArguments->SegEs = (USHORT)BiosContext.SegEs;
438
439 /* Detach and return status */
440 IntDetachFromCSRSS(&CallingProcess, &ApcState);
441
442 if (NT_SUCCESS(Status))
443 {
444 return NO_ERROR;
445 }
446
448}
449
450/* PUBLIC FUNCTIONS ***********************************************************/
451
452/*
453 * @implemented
454 */
456NTAPI
458 IN PVOID HwDeviceExtension,
459 IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
460{
461 INT10_BIOS_ARGUMENTS Int10BiosArguments;
463
464 if (!CsrProcess)
465 {
467 }
468
469 /* Copy arguments to other format */
470 RtlCopyMemory(&Int10BiosArguments, BiosArguments, sizeof(*BiosArguments));
471 Int10BiosArguments.SegDs = 0;
472 Int10BiosArguments.SegEs = 0;
473
474 /* Do the BIOS call */
475 Status = IntInt10CallBios(NULL, &Int10BiosArguments);
476
477 /* Copy results back */
478 RtlCopyMemory(BiosArguments, &Int10BiosArguments, sizeof(*BiosArguments));
479
480 return Status;
481}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
CALLBACK16 BiosContext
Definition: bios32.c:45
#define UNIMPLEMENTED
Definition: debug.h:115
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NO_ERROR
Definition: dderror.h:5
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define TRACE_(x)
Definition: compat.h:76
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:25
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define IsLowV86Mem(_Seg, _Off)
Definition: int10.c:33
VP_STATUS NTAPI IntInt10ReadMemory(IN PVOID Context, IN USHORT Seg, IN USHORT Off, OUT PVOID Buffer, IN ULONG Length)
Definition: int10.c:306
VP_STATUS NTAPI IntInt10WriteMemory(IN PVOID Context, IN USHORT Seg, IN USHORT Off, IN PVOID Buffer, IN ULONG Length)
Definition: int10.c:344
VP_STATUS NTAPI VideoPortInt10(IN PVOID HwDeviceExtension, IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
Definition: int10.c:457
VP_STATUS NTAPI IntInt10FreeBuffer(IN PVOID Context, IN USHORT Seg, IN USHORT Off)
Definition: int10.c:273
VP_STATUS NTAPI IntInt10AllocateBuffer(IN PVOID Context, OUT PUSHORT Seg, OUT PUSHORT Off, IN OUT PULONG Length)
Definition: int10.c:210
VP_STATUS NTAPI IntInt10CallBios(IN PVOID Context, IN OUT PINT10_BIOS_ARGUMENTS BiosArguments)
Definition: int10.c:380
NTSTATUS NTAPI IntInitializeVideoAddressSpace(VOID)
Definition: int10.c:200
static VOID UnprotectLowV86Mem(VOID)
Definition: int10.c:62
static VOID ProtectLowV86Mem(VOID)
Definition: int10.c:39
#define ASSERT(a)
Definition: mode.c:44
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KernelMode
Definition: asm.h:34
@ VdmInitialize
Definition: ketypes.h:475
NTSYSAPI NTSTATUS NTAPI ZwOpenSection(_Out_ PHANDLE SectionHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_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
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#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
#define MEM_RESERVE
Definition: nt_native.h:1314
#define MEM_RELEASE
Definition: nt_native.h:1316
#define MEM_COMMIT
Definition: nt_native.h:1313
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
NTSTATUS NTAPI NtVdmControl(IN ULONG ControlCode, IN PVOID ControlData)
Definition: stubs.c:194
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
LONG VP_STATUS
Definition: video.h:153
#define INFO_(ch,...)
Definition: debug.h:159
#define WARN_(ch,...)
Definition: debug.h:157
#define STATUS_SUCCESS
Definition: shellext.h:65
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSTATUS NTAPI Ke386CallBios(IN ULONG Int, OUT PCONTEXT Context)
Definition: v86vdm.c:614
PKPROCESS CsrProcess
Definition: videoprt.c:39
VOID FASTCALL IntDetachFromCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
Definition: videoprt.c:588
VOID FASTCALL IntAttachToCSRSS(PKPROCESS *CallingProcess, PKAPC_STATE ApcState)
Definition: videoprt.c:575
KMUTEX VideoPortInt10Mutex
Definition: videoprt.c:42
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
struct _KPROCESS * PKPROCESS
Definition: wdm.template.h:201
NTSTATUS NTAPI x86BiosFreeBuffer(_In_ USHORT Segment, _In_ USHORT Offset)
Definition: x86bios.c:180
NTSTATUS NTAPI x86BiosReadMemory(_In_ USHORT Segment, _In_ USHORT Offset, _Out_writes_bytes_(Size) PVOID Buffer, _In_ ULONG Size)
Definition: x86bios.c:204
BOOLEAN NTAPI x86BiosCall(_In_ ULONG InterruptNumber, _Inout_ PX86_BIOS_REGISTERS Registers)
Definition: x86bios.c:410
NTSTATUS NTAPI x86BiosWriteMemory(_In_ USHORT Segment, _In_ USHORT Offset, _In_reads_bytes_(Size) PVOID Buffer, _In_ ULONG Size)
Definition: x86bios.c:231
NTSTATUS NTAPI x86BiosAllocateBuffer(_In_ ULONG *Size, _In_ USHORT *Segment, _In_ USHORT *Offset)
Definition: x86bios.c:151
#define KeWaitForMutexObject
Definition: kefuncs.h:543
@ Executive
Definition: ketypes.h:415
KAPC_STATE
Definition: ketypes.h:1409
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define NT_ASSERT
Definition: rtlfuncs.h:3310
char CHAR
Definition: xmlstorage.h:175