Einzelnen Beitrag anzeigen
Alt 10.11.2016, 01:14   #8
leecher
Moderator
NTVDM Helper to enable Fullscreen operation with WDDM display driver

#unhide (This post can be viewed by guests also)

What is it
----------
Short version:
A package that enables you to switch between Windowed and Fullscreen mode
in a console in Windows 7 like it used to be in Windows XP, even though you
are using a WDDM display driver.

Long version:
You may already know that ALT+Enter is a commonly used hotkey to switch
application between window mode and full-screen mode. For the cmd prompt,
the hotkey should work as expected on prior windows OS up to windows XP
and for example enters real text mode for DOS applications.
But for Windows Vista and Windows 7, cmd can't be switched to
full-screen mode, this is by design.
For further information see http://support.microsoft.com/kb/926657
There is a very interesting article explaining the rasons behind this:
https://colinxu.wordpress.com/2011/0...ssue-analysis/

Now it's also known and explained in the KB-Article, that you can get
back fullscreen with either a XPDM-driver for the Windows XP display driver
model or to switch back to the default VGA video driver, which still
supports the old driver model.
Now the problem with a XPDM Display driver for Windows 7 is that it doesn't
support video accelleration on Windows 7, i.e. Window movement or scrolling
through websites in your browser can be a bit stuttering which isn't a
nice user experience.
As expained in the document of my CONHOST-Patch, Windows 7 thankfully has
the ability to enable and disable an active Video driver on-the-fly. When
disabling the WDDM driver, you fall back to the dafault Standard VGA display
driver which supports fullscreen textmode.
I presented a method that uses the utility DEVCON to disable and re-enable
the WDDM diplay driver in a batch file.
While this method works, it is a bit annoying to use, as one would have
to create a startup batchfile for every application that should work with
fullscreen. Additionally the "Start as fullscreen" in the PIF file still
doesn't work and you don't have the ability to switch from a windowed session
to fullscreen on-the-fly, like it used to be in Windows XP.
Additionally you need administrative rights to get the fullscreen switching
to occur. Running as Administrator gives you another environment than running
as user. And finally, you may also want your Win32 console in fullscreen,
not only DOS-applications.

So I had the idea to automate these tasks when either pressing ALT+ENTER or
when a console window wants so switch to fullscreen mode.

How it works
------------
The package is divided into multiple components:

* fullscrswitch service (with .dll file for eventlog messages)
* conhostfldr loader process, which is used in each session to
inject the conhostf.dll into the CONHOST.EXE process
* The conhostd.dll library which operates inside CONHOST.EXE
process to patch it accordingly for fullscreen operation
and communicate with the service.

First of all, disabling the WDDM driver is a privileged operation, so
administrative privileges are necessary for this.
Therefore it made sense to move this functionality to a Windows-service
which runs in the privileged context of the SYSTEM-user.
The service exposes its driver disable/enable services via a service
control code and also via a named pipe (.\pipe\fullscrswitch).
It is desirable that the WDDM driver stays disabled after switching
around between desktop and fullscreen console until all console windows
that use Fullscreen have closed. When all windows get closed (i.e. due
to an exit of the DOS application or the user just closing the
console window), the driver switches back to the accellerated
WDDM graphics mode.
So as long as you use Textmode fullscreen actively, you are limited to
the XPDM VGA driver and as soon as you do not need it anymore, you get
back your accelerated WDDM driver.
Due to the architecture of the new Windows console, every console has
a CONHOST.EXE process attached to it.
So the fullscreen service has to inject some loader code into every new
CONHOST.EXE process in order to capture ALT+RETURN keypresses or fullscreen
switch requests, then register the CONHOST.EXE process PID with the
fullscreen switching service and perform the WDDM driver disable task.
This is done by sending the PID of the CONHOST.EXE process to the named
pipe. The service registers the PID of the CONHOST in an internal list and
then waits on the process handle, until it gets signalled, which is the
case when the process terminates. As soon as all processes that registered
with the fullscreen switching service terminated, it is safe to switch
back to the WDDM driver, as there are no more processes depending
fullscreen operation.
The service writes back a BOOL TRUE on the named pipe to the caller in
order to signal that disabling driver succeeded and it can continue its
operation with fullscreen capabilities available now.

Now there needs to be a way to inject the conhostf.dll library into each
CONHOST.EXE process so that it can communicate with the service when needed
and modify its behaviour so that Fullscreen support gets available again.
For this, there is a nice facility in Windows: WinEvent hooks that get
called on various events, i.e. also console events. So you can get
notified when i.e. a new console application is starting. Additionally
you have the opportunity to get injected into the target process (to
do the patching), which is exactly what is needed.
Unfortunately there needs to be a "host" application that contains the
DLL to be injected which also needs to have a running message pump. This
is only possible in the context of the user that is currently connected
to the console.
As this is not possibe for a System service, a helper process is needed
which is called conhostfldr.exe that does the injection and acts as a
container for the loader DLL to be injected into CONHOST process.
This process needs high privileges in context of the user so that the
target DLL can also be injected into elevated console windows.
The service registers for logon/logoff notifications and therefore gets
notified when a user connects to the physical console. If the session
currently doesn't have the loader process running, it tries to start it
in the context of the user of the respective console session. It keeps
an internal list of the running instances and sessions.
When a user logs off or the service has to terminate, the loader process
for the sessions need to be terminated and the hook DLL needs to get
unregistered. To do this, and also to prevent being launched twice within
a session, the loader creates an Event named "conhostfldr" and checks
for it in its main message loop. As soon as this event gets signalled, it
terminates.
As the events are unique per session, the service is able to find the
event in the \Sessions namespace for the respective session and can set
the event causing the loader process to terminate properly and unregister
the hook libraray from the console window.

The injected library needs to adjust some internal functions of CONHOST.
As symbols and locations for these functions are not public, it is using
Microsoft Symbol Server to resolve them by name.
Symbol Server keeps debug information for every version of Microsoft
libraries and can download the appropriate symbol file via the Internet
(there are plenty of CONHOST.EXE releases for Windows 7 with different
offsets each, therefore this seems to be the only viable solution).
One problem is that conhost.exe checks for a fullscreen capable VGA
display driver during startup in internal function InitializeFullScreen().
Now if you start up a console with WDDM driver enabled the appropriate
values are no initalized. When you start a DOS application in console,
the NTVDM registers itself with a call to RegisterConsoleVDM() also
supplying event handles to events that are needed during Fullscreen
negotiation. Unfortunately the conhost.exe server part of this function
ignores these handles if the fullscreen flag (0x10000000) is not set
in gConsoleInformation.Flags. This flag normally gets set after
successful fullscreen initialization in InitializeFullScreen() function.
Now if you fake fullscreen initiaization, RegisterConsoleVDM saves the
handles, but it also requests the size of the state buffer from the
VGA driver with a call to GDI function
GdiFullscreenControl(FullscreenControlRegisterVdm, ...).
As at this time there is no VGA driver available, the function then fails
preventing a startup of the DOS application.
Fortunately, the value it requests there is always static for VGA cards,
so the loader DLL can simply hook the GdiFullscreenControl function and
fake the return value. Then the loader can pretend that fullscreen is
available during console startup by setting above mentioned flag.
If the user then really requests fullscreen operation, InitializeFullScreen()
can be called after disabling the WDDM driver as at this point the function
will then succeed ensuring correct operation.
The hook DLL has to monitor SrvSetConsoleDisplayMode call to check for
CONSOLE_FULLSCREEN_MODE call and the console window procedure to check
for ALT+RETURN keypress and then disable WDDM driver accordingly.

With all these 3 components in place, fullscreen switching should work.
Of course, it's not as fast as on Windows XP, because there is overhead
for disabling the driver, so if you can, using Windows XP is still the
preferred method, but with this patch you can at least partly restore
some of the lost functionality.

Prerequestites
--------------
All patches can be downloaded at http://www.waldbauer.com/tmp/reference.php

* CONHOST patch
The CONHOST.EXE on Windows 7 has a severe bug that causes it to hang
on switching back from Fullscreen mode to desktop. This patch fixes it.
* NTVDM transition timeout patch
There is a very large timeout of 5 seconds when switching back from
fullscreen to windowed mode. This is annoying, so with this patch you
can reduce this waiting time that occurs with some DOS applications.


Conditional prerequesites
-------------------------
If you have an Intel I3 or newer onboard graphics adapter and you
experience a startup delay from 5-10 seconds while starting a
DOS-application, there may be problem with the BIOS of the Intel
graphics adapter and you may need the
* NTVDM (Intel VGA BIOS patch)

If the video BIOS crashes on fullscreen or on mode switch, it is very
likely that the standard VGA driver doesn't know about the ports that
your video BIOS needs to route through to the NTVDM.
This is recommended for example for NVIDIA cards.
In this case, you can try this driver:
* http://www.rayer.g6.cz/download/videoprt.zip

If the driver above doesn't help or work and you have problems on
video mode switch of text modes, you can try this patch:
* NTVDM (NVIDIA GEFORCE VGA BIOS patch)

Recommended patches to enhance your DOS experience
--------------------------------------------------
Is Windows 7 doesn't work correctly with the PC speaker and instead
outputs BEEPS via the sine wave usermode beep agent, get back the
real PC speaker support with the
* BEEPx (SPKRFIX 32 bit)

The AltGR-Key is not handled correctly in NTVDM on Windows Vista or
above, so you need to install the
* ALTGR IAT FILTER HOOK

Then you can use the normal KB16.COM keyboard driver which you can
add to your AUTOEXEC.NT file in the SYSTEM32 Windows directory.

System Requirements
-------------------
Should work on any Windows 7 32bit machine.
It is advisable to have a running Internet connection on the first launch
of a console window on the patched system to enable symbol server fetching
the symbols required for proper operation of the patch. As soon as the
symbols got fetched, you don't need Internet connection anymore unless
you update your CONHOST.EXE process, i.e. by Windows update, in which
case the patcher will try to fetch the symbols again automatically.

How to Install
--------------
The installation doesn't work from a Network path, you need to run it from
a local directory. You need administrtive privileges to install.

1) Right-click on the conhostf.inf file in the bin\fullscrswitch
subdirectory and choose "Install".

If it works correctly, some files would have been copied and a
new service named fullscrswitch is started.

2) This step is not absolutely necessary and has the drawback of using more
diskspace than necessary, so this is optional:
Normally the loader tries to fetch the CONHOST.EXE symbols that it needs
for operation from Microsoft Symbol Server on first run, but lately the
symbols server sometimes is a bit unstable and fails to deliver the files
just in time. So you can optionally install all the conhost.exe symbols
that I know (which may not match your conhost.exe, but you can give
it a try anyway).
In case you want to install all the symbol files, just run opt\install.bat
and check if it copied the files successfully.

Now you can try to open a new console and see if ALT+RETURN works for
switching to fullscreen.
If the console hangs some time on first start, it tries to fetch the
symbols from symbol server. If it fails, it gives up after some time and
you get your console, but ALT+RETURN is not working. So as long as there
is some freeze on opening a new console, it tries to fetch the symbols and
you should try opening a new console (after freeze times out) as long as
this delay is still there.
If it doesn't work afterwards (even though it opens up fast), try to reboot
the machine once so that it gets ensured that the conhostdfldr.exe process
gets started correctly by the fullscrswitch service (you can check with
task manager).

If everything works fine, you should also be able to start your DOS
applications directly in fullscreen again.
However be aware that there are some conditions where it may hang your
graphics card (also depends a bit on your WDDM driver and how stable it is).
For example do not try to launch a DOS application fullscreen that
immediately exits, because the fast switching of the VGA driver may cause
a lockup. So when experimenting with it, be prepared that you may need to
reboot your machine if something goes wrong.

There also is a nasty issue with some Intel Onboard video drivers that
causes the disabling of the driver (to enable VGA) to block for approx.
10 seconds every second time you try, as it seems. I haven't analyzed this bug
in the Intel video driver yet as it seems to occur only with this cheap
onboard stuff (where you also need the Intel video fix patch from above).
So if possible better use a dedicated card.
As debugging kernel drivers is not so easy I don't know it if it's worth the
hassle, using a dedicated Graphics card is better anyway.
If this is really the only adapter you can use, maybe we can find a fix for
it together with Intel, just contact me.

When you use it and it switches to VGA mode, you may be set back to
640x480 resolution when you go back to the desktop, which is quite unpleasant.
Just use properties of display and switch to the maximum available resolution
that works with your monitor and VGA driver supports (i.e. if possible the
same resolution as with your normal video adapter driver) to get back normal
screen resolution in this mode. Windows will remember the settings on next
mode switch.

How to Uninstall
----------------
Go to control panel, Add/Remove programs and remove "Console Fullscreen
Patch".

Alternatively, you can run the following command on elevated command
prompt:

Code:
RunDll32 setupapi.dll,InstallHinfSection DefaultUninstall 132 conhostf.Inf
For further information, just contact me.
Angehängte Dateien
Dateityp: zip conhostf.zip‎ (1.38 MB, 13x aufgerufen)
leecher ist offline   Mit Zitat antworten