-/*\r
- * PROJECT: ReactOS Kernel\r
- * LICENSE: GPL - See COPYING in the top level directory\r
- * FILE: ntoskrnl/vdm/vdmmain.c\r
- * PURPOSE: VDM Support Services\r
- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)\r
- */\r
-\r
-/* INCLUDES ******************************************************************/\r
-\r
-#include <ntoskrnl.h>\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* GLOBALS *******************************************************************/\r
-\r
-static UCHAR OrigIVT[1024];\r
-static UCHAR OrigBDA[256];\r
-\r
-/* PRIVATE FUNCTIONS *********************************************************/\r
-\r
-VOID\r
-INIT_FUNCTION\r
-NtEarlyInitVdm(VOID)\r
-{\r
- /* GCC 3.4 hack */\r
- PVOID start = (PVOID)0x0;\r
-\r
- /*\r
- * Save various BIOS data tables. At this point the lower 4MB memory\r
- * map is still active so we can just copy the data from low memory.\r
- * HACK HACK HACK: We should just map Physical Memory!!!\r
- */\r
- memcpy(OrigIVT, start, 1024);\r
- memcpy(OrigBDA, (PVOID)0x400, 256);\r
-}\r
-\r
-VOID\r
-NTAPI\r
-Ki386VdmEnablePentiumExtentions(VOID)\r
-{\r
- DPRINT1("VME detected but not yet supported\n");\r
-}\r
-\r
-VOID\r
-NTAPI\r
-KeI386VdmInitialize(VOID)\r
-{\r
- NTSTATUS Status;\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- HANDLE RegHandle;\r
- UNICODE_STRING Name;\r
- UCHAR KeyValueInfo[sizeof(KEY_VALUE_BASIC_INFORMATION) + 30];\r
- ULONG ReturnLength;\r
-\r
- /* Make sure that there is a WOW key */\r
- RtlInitUnicodeString(&Name,\r
- L"\\Registry\\Machine\\System\\CurrentControlSet\\"\r
- L"Control\\Wow");\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &Name,\r
- OBJ_CASE_INSENSITIVE,\r
- NULL,\r
- NULL);\r
- Status = ZwOpenKey(&RegHandle, KEY_READ, &ObjectAttributes);\r
- if (!NT_SUCCESS(Status)) return;\r
-\r
- /* Check if VME is enabled */\r
- RtlInitUnicodeString(&Name, L"DisableVme");\r
- Status = ZwQueryValueKey(RegHandle,\r
- &Name,\r
- KeyValueBasicInformation,\r
- &KeyValueInfo,\r
- sizeof(KeyValueInfo),\r
- &ReturnLength);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- /* Not present, so check if the CPU supports VME */\r
- if (KeGetPcr()->Prcb->FeatureBits & KF_V86_VIS)\r
- {\r
- /* Enable them. FIXME: Use IPI */\r
- Ki386VdmEnablePentiumExtentions();\r
- KeI386VirtualIntExtensions = TRUE;\r
- }\r
- }\r
-\r
- /* Close the key */\r
- ZwClose(RegHandle);\r
-}\r
-\r
-/* PUBLIC FUNCTIONS **********************************************************/\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS\r
-NTAPI\r
-NtVdmControl(IN ULONG ControlCode,\r
- IN PVOID ControlData)\r
-{\r
- NTSTATUS Status;\r
- PAGED_CODE();\r
-\r
- /* Check which control code this is */\r
- switch (ControlCode)\r
- {\r
- /* VDM Execution start */\r
- case VdmStartExecution:\r
-\r
- /* Call the sub-function */\r
- Status = VdmpStartExecution();\r
- break;\r
-\r
- case VdmInitialize:\r
-\r
- /* Pretty much a hack, since a lot more needs to happen */\r
- memcpy(ControlData, OrigIVT, 1024);\r
- memcpy((PVOID)((ULONG_PTR)ControlData + 1024), OrigBDA, 256);\r
- Status = STATUS_SUCCESS;\r
- break;\r
-\r
- default:\r
-\r
- /* Unsupported */\r
- DPRINT1("Unknown VDM call: %lx\n", ControlCode);\r
- Status = STATUS_INVALID_PARAMETER;\r
- }\r
-\r
- /* Return the status */\r
- return Status;\r
-}\r
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/vdm/vdmmain.c
+ * PURPOSE: VDM Support Services
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ * Aleksey Bragin (aleksey@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+Ki386VdmEnablePentiumExtentions(VOID)
+{
+ DPRINT1("VME detected but not yet supported\n");
+}
+
+VOID
+NTAPI
+KeI386VdmInitialize(VOID)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE RegHandle;
+ UNICODE_STRING Name;
+ UCHAR KeyValueInfo[sizeof(KEY_VALUE_BASIC_INFORMATION) + 30];
+ ULONG ReturnLength;
+
+ /* Make sure that there is a WOW key */
+ RtlInitUnicodeString(&Name,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\"
+ L"Control\\Wow");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = ZwOpenKey(&RegHandle, KEY_READ, &ObjectAttributes);
+ if (!NT_SUCCESS(Status)) return;
+
+ /* Check if VME is enabled */
+ RtlInitUnicodeString(&Name, L"DisableVme");
+ Status = ZwQueryValueKey(RegHandle,
+ &Name,
+ KeyValueBasicInformation,
+ &KeyValueInfo,
+ sizeof(KeyValueInfo),
+ &ReturnLength);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Not present, so check if the CPU supports VME */
+ if (KeGetPcr()->Prcb->FeatureBits & KF_V86_VIS)
+ {
+ /* Enable them. FIXME: Use IPI */
+ Ki386VdmEnablePentiumExtentions();
+ KeI386VirtualIntExtensions = TRUE;
+ }
+ }
+
+ /* Close the key */
+ ZwClose(RegHandle);
+}
+
+NTSTATUS
+NTAPI
+VdmpInitialize(PVOID ControlData)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
+ NTSTATUS Status;
+ HANDLE PhysMemHandle;
+ PVOID BaseAddress;
+ PVOID NullAddress = NULL;
+ LARGE_INTEGER Offset;
+ ULONG ViewSize;
+
+ /* Open the physical memory section */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &PhysMemName,
+ 0,
+ NULL,
+ NULL);
+ Status = ZwOpenSection(&PhysMemHandle,
+ SECTION_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
+ return Status;
+ }
+
+ /* Map the BIOS and device registers into the address space */
+ Offset.QuadPart = 0;
+ ViewSize = PAGE_SIZE;
+ BaseAddress = 0;
+ Status = ZwMapViewOfSection(PhysMemHandle,
+ NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ ViewSize,
+ &Offset,
+ &ViewSize,
+ ViewUnmap,
+ 0,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Couldn't map physical memory (%x)\n", Status);
+ ZwClose(PhysMemHandle);
+ return Status;
+ }
+
+ /* Enter SEH */
+ _SEH2_TRY
+ {
+ /* Copy the first physical page into the first virtual page */
+ RtlMoveMemory(NullAddress, BaseAddress, ViewSize);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Fail */
+ DPRINT1("Couldn't copy first page (%x)\n", Status);
+ ZwClose(PhysMemHandle);
+ ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ /* Close physical memory section handle */
+ ZwClose(PhysMemHandle);
+
+ /* Unmap the section */
+ Status = ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Couldn't unmap the section (%x)\n", Status);
+ return Status;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+NtVdmControl(IN ULONG ControlCode,
+ IN PVOID ControlData)
+{
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Check which control code this is */
+ switch (ControlCode)
+ {
+ /* VDM Execution start */
+ case VdmStartExecution:
+
+ /* Call the sub-function */
+ Status = VdmpStartExecution();
+ break;
+
+ case VdmInitialize:
+
+ /* Call the init sub-function */
+ Status = VdmpInitialize(ControlData);
+ break;
+
+ default:
+
+ /* Unsupported */
+ DPRINT1("Unknown VDM call: %lx\n", ControlCode);
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ /* Return the status */
+ return Status;
+}