update for HEAD-2003091401
[reactos.git] / ntoskrnl / nt / vdm.c
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS kernel
4  * FILE:            ntoskrnl/nt/vdm.c
5  * PURPOSE:         Virtual DOS machine support
6  * PROGRAMMER:      David Welch (welch@mcmail.com)
7  * UPDATE HISTORY:
8  *                  Created 22/05/98
9  */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/ps.h>
15 #include <internal/safe.h>
16 #include <internal/v86m.h>
17
18 #include <internal/debug.h>
19
20 /* GLOBALS *******************************************************************/
21
22 static UCHAR OrigIVT[1024];
23 static UCHAR OrigBDA[256];
24 /* static UCHAR OrigEBDA[]; */
25
26 extern VOID Ki386RetToV86Mode(PKV86M_REGISTERS InRegs,
27                               PKV86M_REGISTERS OutRegs);
28
29 /* FUNCTIONS *****************************************************************/
30
31 VOID
32 NtEarlyInitVdm(VOID)
33 {
34   /* GCC 3.4 warns if NULL is passed in parameter 2 to the standard function memcpy */
35   PVOID start = (PVOID)0x0;
36
37   /*
38    * Save various BIOS data tables. At this point the lower 4MB memory
39    * map is still active so we can just copy the data from low memory.
40    */
41   memcpy(OrigIVT, start, 1024);
42   memcpy(OrigBDA, (PVOID)0x400, 256);
43 }
44
45 NTSTATUS STDCALL NtVdmControl(ULONG ControlCode,
46                               PVOID ControlData)
47 {
48   switch (ControlCode)
49   {
50     case 0:
51       memcpy(ControlData, OrigIVT, 1024);
52       break;
53
54     case 1:
55       memcpy(ControlData, OrigBDA, 256);
56       break;
57
58     case 2:
59     {
60       KV86M_REGISTERS V86Registers;
61       ULONG ret;
62
63       ret = MmCopyFromCaller(&V86Registers,
64                              ControlData,
65                              sizeof(KV86M_REGISTERS));
66       if(!NT_SUCCESS(ret)) return ret;
67
68       KeGetCurrentProcess()->NtVdmFlag = 1;
69       Ki386RetToV86Mode(&V86Registers, &V86Registers);
70       KeGetCurrentProcess()->NtVdmFlag = 0;
71
72       ret = MmCopyToCaller(ControlData,
73                            &V86Registers,
74                            sizeof(KV86M_REGISTERS));
75       if(!NT_SUCCESS(ret)) return ret;
76
77       break;
78     }
79   }
80   return(STATUS_SUCCESS);
81 }
82
83 /* EOF */