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
,
57 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
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
;
88 VdmpInitialize(PVOID ControlData
)
90 OBJECT_ATTRIBUTES ObjectAttributes
;
91 UNICODE_STRING PhysMemName
= RTL_CONSTANT_STRING(L
"\\Device\\PhysicalMemory");
95 volatile PVOID NullAddress
= NULL
;
99 /* Open the physical memory section */
100 InitializeObjectAttributes(&ObjectAttributes
,
105 Status
= ZwOpenSection(&PhysMemHandle
,
108 if (!NT_SUCCESS(Status
))
110 DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
114 /* Map the BIOS and device registers into the address space */
116 ViewSize
= PAGE_SIZE
;
118 Status
= ZwMapViewOfSection(PhysMemHandle
,
128 if (!NT_SUCCESS(Status
))
130 DPRINT1("Couldn't map physical memory (%x)\n", Status
);
131 ZwClose(PhysMemHandle
);
138 /* Copy the first physical page into the first virtual page */
139 RtlMoveMemory(NullAddress
, BaseAddress
, ViewSize
);
141 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
144 DPRINT1("Couldn't copy first page (%x)\n", Status
);
145 ZwClose(PhysMemHandle
);
146 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
147 _SEH2_YIELD(return _SEH2_GetExceptionCode());
151 /* Close physical memory section handle */
152 ZwClose(PhysMemHandle
);
154 /* Unmap the section */
155 Status
= ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
157 if (!NT_SUCCESS(Status
))
159 DPRINT1("Couldn't unmap the section (%x)\n", Status
);
163 return STATUS_SUCCESS
;
166 /* PUBLIC FUNCTIONS **********************************************************/
173 NtVdmControl(IN ULONG ControlCode
,
174 IN PVOID ControlData
)
179 /* Check which control code this is */
182 /* VDM Execution start */
183 case VdmStartExecution
:
185 /* Call the sub-function */
186 Status
= VdmpStartExecution();
191 /* Call the init sub-function */
192 Status
= VdmpInitialize(ControlData
);
198 DPRINT1("Unknown VDM call: %lx\n", ControlCode
);
199 Status
= STATUS_INVALID_PARAMETER
;
202 /* Return the status */