diff --git a/win32ss/drivers/videoprt/dispatch.c b/win32ss/drivers/videoprt/dispatch.c index b1be25b79a9..0f0d9ae3072 100644 --- a/win32ss/drivers/videoprt/dispatch.c +++ b/win32ss/drivers/videoprt/dispatch.c @@ -385,10 +385,10 @@ IntVideoPortDispatchOpen( ObReferenceObject(CsrProcess); INFO_(VIDEOPRT, "CsrProcess 0x%p\n", CsrProcess); - Status = IntInitializeVideoAddressSpace(); + Status = IntInitializeInt10(); if (!NT_SUCCESS(Status)) { - ERR_(VIDEOPRT, "IntInitializeVideoAddressSpace() failed: 0x%lx\n", Status); + ERR_(VIDEOPRT, "IntInitializeInt10() failed: 0x%lx\n", Status); ObDereferenceObject(CsrProcess); CsrProcess = NULL; return Status; diff --git a/win32ss/drivers/videoprt/int10.c b/win32ss/drivers/videoprt/int10.c index 4a2256ff71d..019ea9e7c10 100644 --- a/win32ss/drivers/videoprt/int10.c +++ b/win32ss/drivers/videoprt/int10.c @@ -22,20 +22,96 @@ #include "videoprt.h" #include -#include #include #define NDEBUG #include -/* PRIVATE FUNCTIONS **********************************************************/ +/* GLOBAL VARIABLES ***********************************************************/ + +#ifdef _M_IX86 +/* Use the 32-bit x86 emulator by default, on NT 6.x (Vista+), or on NT 5.x + * if the HAL has the necessary exports. Otherwise fall back to V86 mode. */ +BOOLEAN VideoPortDisableX86Emulator = FALSE; +#endif + +KMUTEX VideoPortInt10Mutex; + + +/* X86 EMULATOR & V86 MODE INITIALIZATION *************************************/ + +#if (NTDDI_VERSION < NTDDI_VISTA) && (DLL_EXPORT_VERSION < _WIN32_WINNT_VISTA) +/* + * x86 Emulator callbacks + */ +#include // For X86_BIOS_REGISTERS + +static BOOLEAN +(NTAPI *x86BiosCall)( + _In_ ULONG InterruptNumber, + _Inout_ PX86_BIOS_REGISTERS Registers); + +static NTSTATUS +(NTAPI *x86BiosAllocateBuffer)( + _Inout_ PULONG Size, + _Out_ PUSHORT Segment, + _Out_ PUSHORT Offset); + +static NTSTATUS +(NTAPI *x86BiosFreeBuffer)( + _In_ USHORT Segment, + _In_ USHORT Offset); + +static NTSTATUS +(NTAPI *x86BiosReadMemory)( + _In_ USHORT Segment, + _In_ USHORT Offset, + _Out_writes_bytes_(Size) PVOID Buffer, + _In_ ULONG Size); + +static NTSTATUS +(NTAPI *x86BiosWriteMemory)( + _In_ USHORT Segment, + _In_ USHORT Offset, + _In_reads_bytes_(Size) PVOID Buffer, + _In_ ULONG Size); + +#else // (NTDDI_VERSION >= NTDDI_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) +#include // For x86Bios*() +#endif + +static BOOLEAN +IntInitializeX86Emu(VOID) +{ +#if (NTDDI_VERSION < NTDDI_VISTA) && (DLL_EXPORT_VERSION < _WIN32_WINNT_VISTA) + UNICODE_STRING ImportName; +#define LOAD_IMPORT(func) \ + (RtlInitUnicodeString(&ImportName, L ## #func), \ + (func) = MmGetSystemRoutineAddress(&ImportName)) + + if (!LOAD_IMPORT(x86BiosCall)) // Check also HalInitializeBios ? + return FALSE; /* No emulator available */ + if (!LOAD_IMPORT(x86BiosAllocateBuffer)) + return FALSE; + if (!LOAD_IMPORT(x86BiosFreeBuffer)) + return FALSE; + if (!LOAD_IMPORT(x86BiosReadMemory)) + return FALSE; + if (!LOAD_IMPORT(x86BiosWriteMemory)) + return FALSE; +#undef LOAD_IMPORT +#endif + + return TRUE; +} + +#ifdef _M_IX86 #define IsLowV86Mem(_Seg, _Off) ((((_Seg) << 4) + (_Off)) < (0xa0000)) /* Those two functions below are there so that CSRSS can't access low mem. * Especially, MAKE IT CRASH ON NULL ACCESS */ -static -VOID +static VOID ProtectLowV86Mem(VOID) { /* We pass a non-NULL address so that ZwAllocateVirtualMemory really does it @@ -57,8 +133,7 @@ ProtectLowV86Mem(VOID) ASSERT(NT_SUCCESS(Status)); } -static -VOID +static VOID UnprotectLowV86Mem(VOID) { /* We pass a non-NULL address so that ZwAllocateVirtualMemory really does it @@ -80,9 +155,8 @@ UnprotectLowV86Mem(VOID) ASSERT(NT_SUCCESS(Status)); } -#if defined(_M_IX86) || defined(_M_AMD64) +static inline NTSTATUS -NTAPI IntInitializeVideoAddressSpace(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; @@ -92,9 +166,7 @@ IntInitializeVideoAddressSpace(VOID) PVOID BaseAddress; LARGE_INTEGER Offset; SIZE_T ViewSize; -#ifdef _M_IX86 CHAR IVTAndBda[1024 + 256]; -#endif // _M_IX86 /* We should only do that for CSRSS */ ASSERT(PsGetCurrentProcess() == (PEPROCESS)CsrProcess); @@ -181,7 +253,6 @@ IntInitializeVideoAddressSpace(VOID) return 0; } -#ifdef _M_IX86 /* Get the real mode IVT and BDA from the kernel */ Status = NtVdmControl(VdmInitialize, IVTAndBda); if (!NT_SUCCESS(Status)) @@ -189,7 +260,6 @@ IntInitializeVideoAddressSpace(VOID) DPRINT1("NtVdmControl failed (status %x)\n", Status); return Status; } -#endif // _M_IX86 /* Protect the V86 address space after this */ ProtectLowV86Mem(); @@ -197,33 +267,62 @@ IntInitializeVideoAddressSpace(VOID) /* Return success */ return STATUS_SUCCESS; } -#else -NTSTATUS -NTAPI -IntInitializeVideoAddressSpace(VOID) -{ - UNIMPLEMENTED; - NT_ASSERT(FALSE); - return STATUS_NOT_IMPLEMENTED; -} -#endif -VP_STATUS +#endif // _M_IX86 + + +/* VideoPortServicesInt10 CALLBACKS *******************************************/ + +#ifdef _M_IX86 +typedef struct _INT10_INTERFACE +{ + PINT10_ALLOCATE_BUFFER Int10AllocateBuffer; + PINT10_FREE_BUFFER Int10FreeBuffer; + PINT10_READ_MEMORY Int10ReadMemory; + PINT10_WRITE_MEMORY Int10WriteMemory; + PINT10_CALL_BIOS Int10CallBios; +} INT10_INTERFACE; + +// Remark: Instead of `Int10Vtbl->`, one could use: `Int10IFace[VideoPortDisableX86Emulator].` +static const INT10_INTERFACE *Int10Vtbl; // Int10IFace[2]; +#define INT10(func) Int10Vtbl->Int10##func +#else +#define INT10(func) IntInt10##func##Emu +#endif // _M_IX86 + + +static VP_STATUS NTAPI -IntInt10AllocateBuffer( - IN PVOID Context, - OUT PUSHORT Seg, - OUT PUSHORT Off, - IN OUT PULONG Length) +IntInt10AllocateBufferEmu( + _In_ PVOID Context, + _Out_ PUSHORT Seg, + _Out_ PUSHORT Off, + _Inout_ PULONG Length) { NTSTATUS Status; + + UNREFERENCED_PARAMETER(Context); + + Status = x86BiosAllocateBuffer(Length, Seg, Off); + return (NT_SUCCESS(Status) ? NO_ERROR : ERROR_NOT_ENOUGH_MEMORY); +} + #ifdef _M_IX86 +static VP_STATUS +NTAPI +IntInt10AllocateBufferV86( + _In_ PVOID Context, + _Out_ PUSHORT Seg, + _Out_ PUSHORT Off, + _Inout_ PULONG Length) +{ + NTSTATUS Status; PVOID MemoryAddress; PKPROCESS CallingProcess; KAPC_STATE ApcState; SIZE_T Size; - TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n"); + UNREFERENCED_PARAMETER(Context); /* Perform the call in the CSRSS context */ if (!IntAttachToCSRSS(&CallingProcess, &ApcState)) @@ -262,34 +361,63 @@ IntInt10AllocateBuffer( *Seg = (USHORT)((ULONG_PTR)MemoryAddress >> 4); *Off = (USHORT)((ULONG_PTR)MemoryAddress & 0xF); - INFO_(VIDEOPRT, "- Segment: %x\n", *Seg); - INFO_(VIDEOPRT, "- Offset: %x\n", *Off); - INFO_(VIDEOPRT, "- Length: %x\n", *Length); - return NO_ERROR; -#else - Status = x86BiosAllocateBuffer(Length, Seg, Off); - return NT_SUCCESS(Status) ? NO_ERROR : ERROR_NOT_ENOUGH_MEMORY; -#endif } +#endif // _M_IX86 VP_STATUS NTAPI -IntInt10FreeBuffer( - IN PVOID Context, - IN USHORT Seg, - IN USHORT Off) +IntInt10AllocateBuffer( + _In_ PVOID Context, + _Out_ PUSHORT Seg, + _Out_ PUSHORT Off, + _Inout_ PULONG Length) +{ + VP_STATUS Status; + + TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n"); + + Status = INT10(AllocateBuffer)(Context, Seg, Off, Length); + if (Status == NO_ERROR) + { + INFO_(VIDEOPRT, "- Segment: 0x%x\n", *Seg); + INFO_(VIDEOPRT, "- Offset : 0x%x\n", *Off); + INFO_(VIDEOPRT, "- Length : 0x%x\n", *Length); + } + return Status; +} + + +static VP_STATUS +NTAPI +IntInt10FreeBufferEmu( + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off) { NTSTATUS Status; + + UNREFERENCED_PARAMETER(Context); + + Status = x86BiosFreeBuffer(Seg, Off); + return (NT_SUCCESS(Status) ? NO_ERROR : ERROR_INVALID_PARAMETER); +} + #ifdef _M_IX86 +static VP_STATUS +NTAPI +IntInt10FreeBufferV86( + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off) +{ + NTSTATUS Status; PVOID MemoryAddress = (PVOID)((ULONG_PTR)(Seg << 4) | Off); PKPROCESS CallingProcess; KAPC_STATE ApcState; SIZE_T Size = 0; - TRACE_(VIDEOPRT, "IntInt10FreeBuffer\n"); - INFO_(VIDEOPRT, "- Segment: %x\n", Seg); - INFO_(VIDEOPRT, "- Offset: %x\n", Off); + UNREFERENCED_PARAMETER(Context); /* Perform the call in the CSRSS context */ if (!IntAttachToCSRSS(&CallingProcess, &ApcState)) @@ -303,30 +431,55 @@ IntInt10FreeBuffer( IntDetachFromCSRSS(CallingProcess, &ApcState); return Status; -#else - Status = x86BiosFreeBuffer(Seg, Off); - return NT_SUCCESS(Status) ? NO_ERROR : ERROR_INVALID_PARAMETER; -#endif } +#endif // _M_IX86 VP_STATUS NTAPI -IntInt10ReadMemory( - IN PVOID Context, - IN USHORT Seg, - IN USHORT Off, - OUT PVOID Buffer, - IN ULONG Length) +IntInt10FreeBuffer( + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off) { + TRACE_(VIDEOPRT, "IntInt10FreeBuffer\n"); + INFO_(VIDEOPRT, "- Segment: 0x%x\n", Seg); + INFO_(VIDEOPRT, "- Offset : 0x%x\n", Off); + + return INT10(FreeBuffer)(Context, Seg, Off); +} + + +static VP_STATUS +NTAPI +IntInt10ReadMemoryEmu( + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length) +{ + NTSTATUS Status; + + UNREFERENCED_PARAMETER(Context); + + Status = x86BiosReadMemory(Seg, Off, Buffer, Length); + return (NT_SUCCESS(Status) ? NO_ERROR : ERROR_INVALID_PARAMETER); +} + #ifdef _M_IX86 +static VP_STATUS +NTAPI +IntInt10ReadMemoryV86( + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length) +{ PKPROCESS CallingProcess; KAPC_STATE ApcState; - TRACE_(VIDEOPRT, "IntInt10ReadMemory\n"); - INFO_(VIDEOPRT, "- Segment: %x\n", Seg); - INFO_(VIDEOPRT, "- Offset: %x\n", Off); - INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer); - INFO_(VIDEOPRT, "- Length: %x\n", Length); + UNREFERENCED_PARAMETER(Context); /* Perform the call in the CSRSS context */ if (!IntAttachToCSRSS(&CallingProcess, &ApcState)) @@ -341,32 +494,59 @@ IntInt10ReadMemory( IntDetachFromCSRSS(CallingProcess, &ApcState); return NO_ERROR; -#else - NTSTATUS Status; - - Status = x86BiosReadMemory(Seg, Off, Buffer, Length); - return NT_SUCCESS(Status) ? NO_ERROR : ERROR_INVALID_PARAMETER; -#endif } +#endif // _M_IX86 VP_STATUS NTAPI -IntInt10WriteMemory( - IN PVOID Context, - IN USHORT Seg, - IN USHORT Off, - IN PVOID Buffer, - IN ULONG Length) +IntInt10ReadMemory( + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length) { + TRACE_(VIDEOPRT, "IntInt10ReadMemory\n"); + INFO_(VIDEOPRT, "- Segment: 0x%x\n", Seg); + INFO_(VIDEOPRT, "- Offset : 0x%x\n", Off); + INFO_(VIDEOPRT, "- Buffer : 0x%x\n", Buffer); + INFO_(VIDEOPRT, "- Length : 0x%x\n", Length); + + return INT10(ReadMemory)(Context, Seg, Off, Buffer, Length); +} + + +static VP_STATUS +NTAPI +IntInt10WriteMemoryEmu( + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length) +{ + NTSTATUS Status; + + UNREFERENCED_PARAMETER(Context); + + Status = x86BiosWriteMemory(Seg, Off, Buffer, Length); + return (NT_SUCCESS(Status) ? NO_ERROR : ERROR_INVALID_PARAMETER); +} + #ifdef _M_IX86 +static VP_STATUS +NTAPI +IntInt10WriteMemoryV86( + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length) +{ PKPROCESS CallingProcess; KAPC_STATE ApcState; - TRACE_(VIDEOPRT, "IntInt10WriteMemory\n"); - INFO_(VIDEOPRT, "- Segment: %x\n", Seg); - INFO_(VIDEOPRT, "- Offset: %x\n", Off); - INFO_(VIDEOPRT, "- Buffer: %x\n", Buffer); - INFO_(VIDEOPRT, "- Length: %x\n", Length); + UNREFERENCED_PARAMETER(Context); /* Perform the call in the CSRSS context */ if (!IntAttachToCSRSS(&CallingProcess, &ApcState)) @@ -381,29 +561,90 @@ IntInt10WriteMemory( IntDetachFromCSRSS(CallingProcess, &ApcState); return NO_ERROR; -#else - NTSTATUS Status; - - Status = x86BiosWriteMemory(Seg, Off, Buffer, Length); - return NT_SUCCESS(Status) ? NO_ERROR : ERROR_INVALID_PARAMETER; -#endif } +#endif // _M_IX86 VP_STATUS NTAPI -IntInt10CallBios( - IN PVOID Context, - IN OUT PINT10_BIOS_ARGUMENTS BiosArguments) +IntInt10WriteMemory( + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length) +{ + TRACE_(VIDEOPRT, "IntInt10WriteMemory\n"); + INFO_(VIDEOPRT, "- Segment: 0x%x\n", Seg); + INFO_(VIDEOPRT, "- Offset : 0x%x\n", Off); + INFO_(VIDEOPRT, "- Buffer : 0x%x\n", Buffer); + INFO_(VIDEOPRT, "- Length : 0x%x\n", Length); + + return INT10(WriteMemory)(Context, Seg, Off, Buffer, Length); +} + + +static VP_STATUS +NTAPI +IntInt10CallBiosEmu( + _In_ PVOID Context, + _Inout_ PINT10_BIOS_ARGUMENTS BiosArguments) { -#ifdef _M_AMD64 X86_BIOS_REGISTERS BiosContext; -#else + BOOLEAN Success; + + UNREFERENCED_PARAMETER(Context); + + /* Clear the context and fill out the BIOS arguments */ + RtlZeroMemory(&BiosContext, sizeof(BiosContext)); + BiosContext.Eax = BiosArguments->Eax; + BiosContext.Ebx = BiosArguments->Ebx; + BiosContext.Ecx = BiosArguments->Ecx; + BiosContext.Edx = BiosArguments->Edx; + BiosContext.Esi = BiosArguments->Esi; + BiosContext.Edi = BiosArguments->Edi; + BiosContext.Ebp = BiosArguments->Ebp; + BiosContext.SegDs = BiosArguments->SegDs; + BiosContext.SegEs = BiosArguments->SegEs; + + /* Do the ROM BIOS call */ + (void)KeWaitForMutexObject(&VideoPortInt10Mutex, + Executive, + KernelMode, + FALSE, + NULL); + + Success = x86BiosCall(0x10, &BiosContext); + + KeReleaseMutex(&VideoPortInt10Mutex, FALSE); + + /* Return the arguments */ + BiosArguments->Eax = BiosContext.Eax; + BiosArguments->Ebx = BiosContext.Ebx; + BiosArguments->Ecx = BiosContext.Ecx; + BiosArguments->Edx = BiosContext.Edx; + BiosArguments->Esi = BiosContext.Esi; + BiosArguments->Edi = BiosContext.Edi; + BiosArguments->Ebp = BiosContext.Ebp; + BiosArguments->SegDs = (USHORT)BiosContext.SegDs; + BiosArguments->SegEs = (USHORT)BiosContext.SegEs; + + return (Success ? NO_ERROR : ERROR_INVALID_PARAMETER); +} + +#ifdef _M_IX86 +static VP_STATUS +NTAPI +IntInt10CallBiosV86( + _In_ PVOID Context, + _Inout_ PINT10_BIOS_ARGUMENTS BiosArguments) +{ CONTEXT BiosContext; -#endif NTSTATUS Status; PKPROCESS CallingProcess; KAPC_STATE ApcState; + UNREFERENCED_PARAMETER(Context); + /* Clear the context and fill out the BIOS arguments */ RtlZeroMemory(&BiosContext, sizeof(BiosContext)); BiosContext.Eax = BiosArguments->Eax; @@ -429,11 +670,18 @@ IntInt10CallBios( /* The kernel needs access here */ UnprotectLowV86Mem(); -#ifdef _M_AMD64 - Status = x86BiosCall(0x10, &BiosContext) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; -#else - Status = Ke386CallBios(0x10, &BiosContext); -#endif + + /* Invoke the V86 monitor under SEH, as it can raise exceptions */ + _SEH2_TRY + { + Status = Ke386CallBios(0x10, &BiosContext); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + ProtectLowV86Mem(); KeReleaseMutex(&VideoPortInt10Mutex, FALSE); @@ -451,8 +699,67 @@ IntInt10CallBios( BiosArguments->SegDs = (USHORT)BiosContext.SegDs; BiosArguments->SegEs = (USHORT)BiosContext.SegEs; - return NT_SUCCESS(Status) ? NO_ERROR : ERROR_INVALID_PARAMETER; + return (NT_SUCCESS(Status) ? NO_ERROR : ERROR_INVALID_PARAMETER); } +#endif // _M_IX86 + +VP_STATUS +NTAPI +IntInt10CallBios( + _In_ PVOID Context, + _Inout_ PINT10_BIOS_ARGUMENTS BiosArguments) +{ + return INT10(CallBios)(Context, BiosArguments); +} + + +#ifdef _M_IX86 +static const INT10_INTERFACE Int10IFace[2] = +{ { IntInt10AllocateBufferEmu, + IntInt10FreeBufferEmu, + IntInt10ReadMemoryEmu, + IntInt10WriteMemoryEmu, + IntInt10CallBiosEmu } + , + { IntInt10AllocateBufferV86, + IntInt10FreeBufferV86, + IntInt10ReadMemoryV86, + IntInt10WriteMemoryV86, + IntInt10CallBiosV86 } +}; +static const INT10_INTERFACE *Int10Vtbl = &Int10IFace[0]; +#endif + + +/* PRIVATE FUNCTIONS **********************************************************/ + +NTSTATUS +IntInitializeInt10(VOID) +{ +#ifdef _M_IX86 + /* We should only do that for CSRSS */ + ASSERT(PsGetCurrentProcess() == (PEPROCESS)CsrProcess); + + /* Initialize the x86 emulator if necessary, otherwise fall back to V86 mode */ + if (!VideoPortDisableX86Emulator) + { + /* Use the emulation routines */ + //Int10Vtbl = &Int10IFace[0]; + if (IntInitializeX86Emu()) + return STATUS_SUCCESS; + DPRINT1("Could not initialize the x86 emulator; falling back to V86 mode\n"); + VideoPortDisableX86Emulator = TRUE; + } + + /* Fall back to the V86 routines */ + Int10Vtbl = &Int10IFace[1]; + return IntInitializeVideoAddressSpace(); +#else + /* Initialize the x86 emulator */ + return (IntInitializeX86Emu() ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED); +#endif +} + /* PUBLIC FUNCTIONS ***********************************************************/ @@ -465,13 +772,8 @@ VideoPortInt10( IN PVOID HwDeviceExtension, IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments) { - INT10_BIOS_ARGUMENTS Int10BiosArguments; VP_STATUS Status; - - if (!CsrProcess) - { - return ERROR_INVALID_PARAMETER; - } + INT10_BIOS_ARGUMENTS Int10BiosArguments; /* Copy arguments to other format */ RtlCopyMemory(&Int10BiosArguments, BiosArguments, sizeof(*BiosArguments)); diff --git a/win32ss/drivers/videoprt/videoprt.c b/win32ss/drivers/videoprt/videoprt.c index 5b225d4ed32..e527e821d53 100644 --- a/win32ss/drivers/videoprt/videoprt.c +++ b/win32ss/drivers/videoprt/videoprt.c @@ -39,7 +39,7 @@ BOOLEAN VpNoVesa = FALSE; PKPROCESS CsrProcess = NULL; static ULONG VideoPortMaxObjectNumber = -1; BOOLEAN VideoPortUseNewKey = FALSE; -KMUTEX VideoPortInt10Mutex; + KSPIN_LOCK HwResetAdaptersLock; RTL_STATIC_LIST_HEAD(HwResetAdaptersList); @@ -628,21 +628,21 @@ IntLoadRegistryParameters(VOID) { NTSTATUS Status; HANDLE KeyHandle; - UNICODE_STRING UseNewKeyPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\GraphicsDrivers\\UseNewKey"); - UNICODE_STRING Path = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control"); + UNICODE_STRING KeyPath; UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SystemStartOptions"); OBJECT_ATTRIBUTES ObjectAttributes; PKEY_VALUE_PARTIAL_INFORMATION KeyInfo; ULONG Length, NewLength; /* Check if we need to use new registry */ + RtlInitUnicodeString(&KeyPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\GraphicsDrivers\\UseNewKey"); InitializeObjectAttributes(&ObjectAttributes, - &UseNewKeyPath, + &KeyPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenKey(&KeyHandle, - GENERIC_READ | GENERIC_WRITE, + KEY_QUERY_VALUE, &ObjectAttributes); if (NT_SUCCESS(Status)) { @@ -650,9 +650,29 @@ IntLoadRegistryParameters(VOID) ZwClose(KeyHandle); } - /* Initialize object attributes with the path we want */ +#ifdef _M_IX86 + /* Check whether we need to use the 32-bit x86 emulator instead of V86 mode */ + RtlInitUnicodeString(&KeyPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\GraphicsDrivers\\DisableEmulator"); InitializeObjectAttributes(&ObjectAttributes, - &Path, + &KeyPath, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwOpenKey(&KeyHandle, + KEY_QUERY_VALUE, + &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + VideoPortDisableX86Emulator = TRUE; + ZwClose(KeyHandle); + } + DPRINT1("Using %s\n", VideoPortDisableX86Emulator ? "V86 mode" : "x86 emulator"); +#endif // _M_IX86 + + /* Initialize object attributes with the path we want */ + RtlInitUnicodeString(&KeyPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); @@ -677,7 +697,7 @@ IntLoadRegistryParameters(VOID) if (Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL) { VideoPortDebugPrint(Error, "ZwQueryValueKey failed (0x%x)\n", Status); - ObCloseHandle(KeyHandle, KernelMode); + ZwClose(KeyHandle); return; } @@ -686,7 +706,7 @@ IntLoadRegistryParameters(VOID) if (!KeyInfo) { VideoPortDebugPrint(Error, "Out of memory\n"); - ObCloseHandle(KeyHandle, KernelMode); + ZwClose(KeyHandle); return; } @@ -697,7 +717,7 @@ IntLoadRegistryParameters(VOID) KeyInfo, Length, &NewLength); - ObCloseHandle(KeyHandle, KernelMode); + ZwClose(KeyHandle); if (!NT_SUCCESS(Status)) { @@ -733,10 +753,9 @@ IntLoadRegistryParameters(VOID) /* If we are in BASEVIDEO, create the volatile registry key for Win32k */ if (VpBaseVideo) { - RtlInitUnicodeString(&Path, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\GraphicsDrivers\\BaseVideo"); - + RtlInitUnicodeString(&KeyPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\GraphicsDrivers\\BaseVideo"); InitializeObjectAttributes(&ObjectAttributes, - &Path, + &KeyPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); @@ -749,7 +768,7 @@ IntLoadRegistryParameters(VOID) REG_OPTION_VOLATILE, NULL); if (NT_SUCCESS(Status)) - ObCloseHandle(KeyHandle, KernelMode); + ZwClose(KeyHandle); else ERR_(VIDEOPRT, "Failed to create the BaseVideo key (0x%x)\n", Status); } diff --git a/win32ss/drivers/videoprt/videoprt.h b/win32ss/drivers/videoprt/videoprt.h index ffd03c0e5bb..192542b6221 100644 --- a/win32ss/drivers/videoprt/videoprt.h +++ b/win32ss/drivers/videoprt/videoprt.h @@ -254,7 +254,7 @@ IntVideoPortMapPhysicalMemory( extern PKPROCESS CsrProcess; extern ULONG VideoPortDeviceNumber; extern BOOLEAN VideoPortUseNewKey; -extern KMUTEX VideoPortInt10Mutex; + extern KSPIN_LOCK HwResetAdaptersLock; extern LIST_ENTRY HwResetAdaptersList; @@ -298,43 +298,52 @@ IntVideoPortEnumerateChildren( /* int10.c */ +#ifdef _M_IX86 +extern BOOLEAN VideoPortDisableX86Emulator; +#endif +extern KMUTEX VideoPortInt10Mutex; + NTSTATUS +IntInitializeInt10(VOID); + +VP_STATUS NTAPI -IntInitializeVideoAddressSpace(VOID); - -VP_STATUS NTAPI IntInt10AllocateBuffer( - IN PVOID Context, - OUT PUSHORT Seg, - OUT PUSHORT Off, - IN OUT PULONG Length); + _In_ PVOID Context, + _Out_ PUSHORT Seg, + _Out_ PUSHORT Off, + _Inout_ PULONG Length); -VP_STATUS NTAPI +VP_STATUS +NTAPI IntInt10FreeBuffer( - IN PVOID Context, - IN USHORT Seg, - IN USHORT Off); + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off); -VP_STATUS NTAPI +VP_STATUS +NTAPI IntInt10ReadMemory( - IN PVOID Context, - IN USHORT Seg, - IN USHORT Off, - OUT PVOID Buffer, - IN ULONG Length); + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length); -VP_STATUS NTAPI +VP_STATUS +NTAPI IntInt10WriteMemory( - IN PVOID Context, - IN USHORT Seg, - IN USHORT Off, - IN PVOID Buffer, - IN ULONG Length); + _In_ PVOID Context, + _In_ USHORT Seg, + _In_ USHORT Off, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length); -VP_STATUS NTAPI +VP_STATUS +NTAPI IntInt10CallBios( - IN PVOID Context, - IN OUT PINT10_BIOS_ARGUMENTS BiosArguments); + _In_ PVOID Context, + _Inout_ PINT10_BIOS_ARGUMENTS BiosArguments); /* registry.c */ @@ -368,5 +377,4 @@ IntCreateRegistryPath( IN ULONG DeviceNumber, OUT PUNICODE_STRING DeviceRegistryPath); - #endif /* VIDEOPRT_H */