mirror of
https://github.com/reactos/reactos.git
synced 2026-06-21 23:22:48 +08:00
This problem was noticed by Zombiedeth. Addendum to commit89d5a3dbb8(PR #8451). There exist buggy 3rd-party miniport drivers, like those for the NVIDIA GeForce 8400 GS card (`nv4_mini.sys` from `181.22_geforce_winxp_32bit_english_whql.exe`) that invoke the VideoPort Int10 routines (either `VideoPortInt10()`, or the INT10 interface via `VideoPortQueryServices()`) from their `HwFindAdapter()` callback (invoked via `VideoPortInitialize()`) or from their `DriverEntry()`. However, at this point, the VideoPort Int10 services are not fully initialized: on the x86 port, the VDM memory isn't mapped until later, when the `\Device\VideoX` is opened by Win32k as part of its initialization in the context of the CSRSS process. Additionally on the x86 ReactOS port since commit89d5a3dbb8(PR #8451), the X86 emulator is used by default, unless either a registry setting is set to disable the emulator, or the HAL (e.g. the NT5.x HAL) doesn't export the X86 emulator routines; in these cases the VDM is employed instead. In the NT5.x builds VideoPort imports the HAL X86 emulator routines at runtime, since it has to handle their possible absence. However, this importing was previously delayed up until VideoPort initialized the Int10 services (when `\Device\VideoX` is opened the first time by Win32k from CSRSS), meaning, these services and the X86 emulator imports weren't initialized until then. When booting ReactOS in these conditions with the NVIDIA driver installed, its too-early `VideoPortInt10()` call was invoking the X86 emulator with no imports set up, which resulted in the invocation of a NULL function pointer, leading to a BSOD. ## Proposed changes - Make the existing `IntInitializeInt10()` function support two invocations: * When invoked the first time, it initializes the X86 emulator support, by importing the HAL emulator routines, if applicable. * When invoked the second+ time, it maps the VDM memory space (done when `Device\VideoX` is opened by Win32k/CSRSS initialization). - Actually perform the first `IntInitializeInt10()` invocation in the `if (!FirstInitialization)` block of `VideoPortInitialize()`. - Set a `VDMAddressSpaceInitialized` flag to TRUE only when the VDM memory space is mapped (during the second `IntInitializeInt10()` invocation). Check this flag in both `IntInt10CallBiosV86()` and `IntInt10CallBiosEmu()` (x86 build only). - Adjust two returned status values in `IntInitializeVideoAddressSpace()`.