sync with trunk head (34904)
[reactos.git] / reactos / ntoskrnl / vdm / vdmmain.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/vdm/vdmmain.c
5 * PURPOSE: VDM Support Services
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS *******************************************************************/
16
17 static UCHAR OrigIVT[1024];
18 static UCHAR OrigBDA[256];
19
20 /* PRIVATE FUNCTIONS *********************************************************/
21
22 VOID
23 INIT_FUNCTION
24 NtEarlyInitVdm(VOID)
25 {
26 PCHAR start = MmCreateHyperspaceMapping(0);
27 memcpy(OrigIVT, start, 1024);
28 memcpy(OrigBDA, start+0x400, 256);
29 MmDeleteHyperspaceMapping(start);
30 }
31
32 VOID
33 NTAPI
34 Ki386VdmEnablePentiumExtentions(VOID)
35 {
36 DPRINT1("VME detected but not yet supported\n");
37 }
38
39 VOID
40 NTAPI
41 KeI386VdmInitialize(VOID)
42 {
43 NTSTATUS Status;
44 OBJECT_ATTRIBUTES ObjectAttributes;
45 HANDLE RegHandle;
46 UNICODE_STRING Name;
47 UCHAR KeyValueInfo[sizeof(KEY_VALUE_BASIC_INFORMATION) + 30];
48 ULONG ReturnLength;
49
50 /* Make sure that there is a WOW key */
51 RtlInitUnicodeString(&Name,
52 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
53 L"Control\\Wow");
54 InitializeObjectAttributes(&ObjectAttributes,
55 &Name,
56 OBJ_CASE_INSENSITIVE,
57 NULL,
58 NULL);
59 Status = ZwOpenKey(&RegHandle, KEY_READ, &ObjectAttributes);
60 if (!NT_SUCCESS(Status)) return;
61
62 /* Check if VME is enabled */
63 RtlInitUnicodeString(&Name, L"DisableVme");
64 Status = ZwQueryValueKey(RegHandle,
65 &Name,
66 KeyValueBasicInformation,
67 &KeyValueInfo,
68 sizeof(KeyValueInfo),
69 &ReturnLength);
70 if (!NT_SUCCESS(Status))
71 {
72 /* Not present, so check if the CPU supports VME */
73 if (KeGetPcr()->Prcb->FeatureBits & KF_V86_VIS)
74 {
75 /* Enable them. FIXME: Use IPI */
76 Ki386VdmEnablePentiumExtentions();
77 KeI386VirtualIntExtensions = TRUE;
78 }
79 }
80
81 /* Close the key */
82 ZwClose(RegHandle);
83 }
84
85 /* PUBLIC FUNCTIONS **********************************************************/
86
87 /*
88 * @implemented
89 */
90 NTSTATUS
91 NTAPI
92 NtVdmControl(IN ULONG ControlCode,
93 IN PVOID ControlData)
94 {
95 NTSTATUS Status;
96 PAGED_CODE();
97
98 /* Check which control code this is */
99 switch (ControlCode)
100 {
101 /* VDM Execution start */
102 case VdmStartExecution:
103
104 /* Call the sub-function */
105 Status = VdmpStartExecution();
106 break;
107
108 case VdmInitialize:
109
110 /* Pretty much a hack, since a lot more needs to happen */
111 memcpy(ControlData, OrigIVT, 1024);
112 memcpy((PVOID)((ULONG_PTR)ControlData + 1024), OrigBDA, 256);
113 Status = STATUS_SUCCESS;
114 break;
115
116 default:
117
118 /* Unsupported */
119 DPRINT1("Unknown VDM call: %lx\n", ControlCode);
120 Status = STATUS_INVALID_PARAMETER;
121 }
122
123 /* Return the status */
124 return Status;
125 }