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 * Aleksey Bragin (aleksey@reactos.org)
10 /* INCLUDES ******************************************************************/
16 /* GLOBALS *******************************************************************/
18 /* PRIVATE FUNCTIONS *********************************************************/
23 Ki386VdmEnablePentiumExtentions(IN BOOLEAN Enable
)
27 /* Save interrupt state and disable them */
28 EFlags
= __readeflags();
31 /* Enable or disable VME as required */
33 __writecr4(Enable
? Cr4
| CR4_VME
: Cr4
& ~CR4_VME
);
35 /* Restore interrupt state */
36 __writeeflags(EFlags
);
42 KeI386VdmInitialize(VOID
)
45 OBJECT_ATTRIBUTES ObjectAttributes
;
48 UCHAR KeyValueInfo
[sizeof(KEY_VALUE_BASIC_INFORMATION
) + 30];
51 /* Make sure that there is a WOW key */
52 RtlInitUnicodeString(&Name
,
53 L
"\\Registry\\Machine\\System\\CurrentControlSet\\"
55 InitializeObjectAttributes(&ObjectAttributes
,
60 Status
= ZwOpenKey(&RegHandle
, KEY_READ
, &ObjectAttributes
);
61 if (!NT_SUCCESS(Status
)) return;
63 /* Check if VME is enabled */
64 RtlInitUnicodeString(&Name
, L
"DisableVme");
65 Status
= ZwQueryValueKey(RegHandle
,
67 KeyValueBasicInformation
,
71 if (!NT_SUCCESS(Status
))
73 /* Not present, so check if the CPU supports VME */
74 if (KeGetPcr()->Prcb
->FeatureBits
& KF_V86_VIS
)
76 /* Enable them. FIXME: Use IPI */
77 Ki386VdmEnablePentiumExtentions(TRUE
);
78 KeI386VirtualIntExtensions
= TRUE
;
89 VdmpInitialize(PVOID ControlData
)
91 OBJECT_ATTRIBUTES ObjectAttributes
;
92 UNICODE_STRING PhysMemName
= RTL_CONSTANT_STRING(L
"\\Device\\PhysicalMemory");
96 PVOID NullAddress
= NULL
;
100 /* Open the physical memory section */
101 InitializeObjectAttributes(&ObjectAttributes
,
106 Status
= ZwOpenSection(&PhysMemHandle
,
109 if (!NT_SUCCESS(Status
))
111 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
115 /* Map the BIOS and device registers into the address space */
117 ViewSize
= PAGE_SIZE
;
119 Status
= ZwMapViewOfSection(PhysMemHandle
,
129 if (!NT_SUCCESS(Status
))
131 DPRINT1("Couldn't map physical memory (%x)\n", Status
);
132 ZwClose(PhysMemHandle
);
139 /* Copy the first physical page into the first virtual page */
140 RtlMoveMemory(NullAddress
, BaseAddress
, ViewSize
);
142 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
145 DPRINT1("Couldn't copy first page (%x)\n", Status
);
146 ZwClose(PhysMemHandle
);
147 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
148 _SEH2_YIELD(return _SEH2_GetExceptionCode());
152 /* Close physical memory section handle */
153 ZwClose(PhysMemHandle
);
155 /* Unmap the section */
156 Status
= ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
158 if (!NT_SUCCESS(Status
))
160 DPRINT1("Couldn't unmap the section (%x)\n", Status
);
164 return STATUS_SUCCESS
;
167 /* PUBLIC FUNCTIONS **********************************************************/
174 NtVdmControl(IN ULONG ControlCode
,
175 IN PVOID ControlData
)
180 /* Check which control code this is */
183 /* VDM Execution start */
184 case VdmStartExecution
:
186 /* Call the sub-function */
187 Status
= VdmpStartExecution();
192 /* Call the init sub-function */
193 Status
= VdmpInitialize(ControlData
);
199 DPRINT1("Unknown VDM call: %lx\n", ControlCode
);
200 Status
= STATUS_INVALID_PARAMETER
;
203 /* Return the status */