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 *******************************************************************/
19 /* 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
);
41 KeI386VdmInitialize(VOID
)
44 OBJECT_ATTRIBUTES ObjectAttributes
;
47 UCHAR KeyValueInfo
[sizeof(KEY_VALUE_BASIC_INFORMATION
) + 30];
50 /* Make sure that there is a WOW key */
51 RtlInitUnicodeString(&Name
,
52 L
"\\Registry\\Machine\\System\\CurrentControlSet\\"
54 InitializeObjectAttributes(&ObjectAttributes
,
59 Status
= ZwOpenKey(&RegHandle
, KEY_READ
, &ObjectAttributes
);
60 if (!NT_SUCCESS(Status
)) return;
62 /* Check if VME is enabled */
63 RtlInitUnicodeString(&Name
, L
"DisableVme");
64 Status
= ZwQueryValueKey(RegHandle
,
66 KeyValueBasicInformation
,
70 if (!NT_SUCCESS(Status
))
72 /* Not present, so check if the CPU supports VME */
73 if (KeGetPcr()->Prcb
->FeatureBits
& KF_V86_VIS
)
75 /* Enable them. FIXME: Use IPI */
76 Ki386VdmEnablePentiumExtentions(TRUE
);
77 KeI386VirtualIntExtensions
= TRUE
;
87 VdmpInitialize(PVOID ControlData
)
89 OBJECT_ATTRIBUTES ObjectAttributes
;
90 UNICODE_STRING PhysMemName
= RTL_CONSTANT_STRING(L
"\\Device\\PhysicalMemory");
94 PVOID NullAddress
= NULL
;
98 /* Open the physical memory section */
99 InitializeObjectAttributes(&ObjectAttributes
,
104 Status
= ZwOpenSection(&PhysMemHandle
,
107 if (!NT_SUCCESS(Status
))
109 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
113 /* Map the BIOS and device registers into the address space */
115 ViewSize
= PAGE_SIZE
;
117 Status
= ZwMapViewOfSection(PhysMemHandle
,
127 if (!NT_SUCCESS(Status
))
129 DPRINT1("Couldn't map physical memory (%x)\n", Status
);
130 ZwClose(PhysMemHandle
);
137 /* Copy the first physical page into the first virtual page */
138 RtlMoveMemory(NullAddress
, BaseAddress
, ViewSize
);
140 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
143 DPRINT1("Couldn't copy first page (%x)\n", Status
);
144 ZwClose(PhysMemHandle
);
145 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
146 _SEH2_YIELD(return _SEH2_GetExceptionCode());
150 /* Close physical memory section handle */
151 ZwClose(PhysMemHandle
);
153 /* Unmap the section */
154 Status
= ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
156 if (!NT_SUCCESS(Status
))
158 DPRINT1("Couldn't unmap the section (%x)\n", Status
);
162 return STATUS_SUCCESS
;
165 /* PUBLIC FUNCTIONS **********************************************************/
172 NtVdmControl(IN ULONG ControlCode
,
173 IN PVOID ControlData
)
178 /* Check which control code this is */
181 /* VDM Execution start */
182 case VdmStartExecution
:
184 /* Call the sub-function */
185 Status
= VdmpStartExecution();
190 /* Call the init sub-function */
191 Status
= VdmpInitialize(ControlData
);
197 DPRINT1("Unknown VDM call: %lx\n", ControlCode
);
198 Status
= STATUS_INVALID_PARAMETER
;
201 /* Return the status */