Windows 8.1 Remote Display Driver.

I have a ‘mirror’ driver that I wrote (MiniPort).
It works flawlessly under: Xp Sp3, Vista (x86,x64), Windows 7 (x86,x64).

I am now porting it to Windows 8.1.
I understand:
http://msdn.microsoft.com/en-us/library/windows/hardware/hh974665(v=vs.85).aspx

I have ported it and it works just fine UNTIL a Desktop switch occurs
(UAC Prompt, Ctrl+Alt+Del, …).

1.) I have a service running.
2.) My service fires up my user mode application.
3.) My user mode application initiates, connects
to my driver. Everything is working just fine.
4.) My service watches for desktop changes (Context switch).
5.) When a desktop change occurs my service shuts down the currently running
user mode application.
6.) My service then starts another instance of my user mode application within
the new desktop.

Here is a log from my user mode application (pertaining to the Remote Display Driver,
with some comment I put in) running under Windows 7 x64:

Class Starting
LoadDisplayDriver()
SetDisplayDriverAttachToDesktop(). Attaching:1
AlreadyAttached:0 ReallyUnloadDriver: 0
We Touched Attach To Desktop
// Here I Have Set My Registry Value For My Remote Display Driver
// Attach.ToDesktop To 1.
SetDisplayDriverAttachToDesktop() Done:0
ChangeDisplaySettingsEx() OK For (CDS_UPDATEREGISTRY|CDS_NORESET|CDS_GLOBAL)
// I Have ChangeDisplaySettingsEx() With The DEVMODE From The Primary Display
ChangeDisplaySettingsEx() OK For (NULL)
// I Have ChangeDisplaySettingsEx() to make The Changes Effective
LoadDisplayDriver() Done:0
ConnectDisplayDriver()
//
// Among Other things This is Where I
// (this->Dc=CreateDC(this->DriverInstanceName,(LPCWSTR)NULL,(LPCWSTR)NULL,(DEVMODE *)NULL)))
//
ConnectDisplayDriver() Done:0
GetDisplayDriverRects() NumberOfDriverRects:43
//
// All is working fine.
//
// Now my service has told the user mode application to unload
// (A desktop context switch has occurred, Specifically Ctrl+Alt+Del)
//
UnLoadDisplayDriver()
DisConnectDisplayDriver()
//
// Among Other Things I DeleteDC(this->Dc);
//
DisConnectDisplayDriver() Done:0
SetDisplayDriverAttachToDesktop(). Attaching:0
AlreadyAttached:1 ReallyUnloadDriver: 0
//
// Since My Driver Is Already Attached And I have Told Myself To NOT
// Unload The Driver (ReallyUnloadDriver: 0) I Leave Everything As is.
// I.e I Do Not Change The Current Attach.ToDesktop Registry Value.
//
SetDisplayDriverAttachToDesktop() Done:0
UnLoadDisplayDriver() Done:0
::~Display()
::~Display() Done.

// Now my service is loading a new instance of the user mode application.
// It will be running under the secure desktop
//
Class Starting
LoadDisplayDriver()
SetDisplayDriverAttachToDesktop(). Attaching:1
AlreadyAttached:1 ReallyUnloadDriver: 0
//
// Since My Driver Is Already Attached I Do Nothing
//
SetDisplayDriverAttachToDesktop() Done:0
LoadDisplayDriver() Done:0
ConnectDisplayDriver()
ConnectDisplayDriver() Done:0
GetDisplayDriverRects() NumberOfDriverRects:1
//
// It All Works
//
// Now my service has told the user mode application to unload
// (Specifically i have ‘Cancel’ From The Secure Desktop).
//
UnLoadDisplayDriver()
DisConnectDisplayDriver()
DisConnectDisplayDriver() Done:0
SetDisplayDriverAttachToDesktop(). Attaching:0
AlreadyAttached:1 ReallyUnloadDriver: 0
//
// Since My Driver Is Already Attached And I have Told Myself To NOT
// Unload The Driver (ReallyUnloadDriver: 0) I Leave Everything As is.
// I.e I Do Not Change The Current Attach.ToDesktop Registry Value.
//
SetDisplayDriverAttachToDesktop() Done:0
UnLoadDisplayDriver() Done:0
::~Display()
::~Display() Done.

// Now my service is loading a new instance of the user mode application.
// It will be running under the original desktop
//
Class Starting
LoadDisplayDriver()
SetDisplayDriverAttachToDesktop(). Attaching:1
AlreadyAttached:1 ReallyUnloadDriver: 0
//
// Since My Driver Is Already Attached I Do Nothing
//
SetDisplayDriverAttachToDesktop() Done:0
LoadDisplayDriver() Done:0
ConnectDisplayDriver()
ConnectDisplayDriver() Done:0
GetDisplayDriverRects() NumberOfDriverRects:1
//
// Its Working
//
// My service is shutting down. It has told the user mode
// application that it is going to be shut down and will not
// be re-started for a context switch, So ReallyUnloadDriver=1
//
UnLoadDisplayDriver()
DisConnectDisplayDriver()
DisConnectDisplayDriver() Done:0
SetDisplayDriverAttachToDesktop(). Attaching:0
AlreadyAttached:1 ReallyUnloadDriver: 1
//
// Since ReallyUnloadDriver=1 We Set The Registry Value
// Attach.ToDesktop To 0.
//
We Touched Attach To Desktop
SetDisplayDriverAttachToDesktop() Done:0
//
// Since we are really unloading the driver ReallyUnloadDriver: 1
// We
//
UnLoadDisplayDriver() Done:0
::~Display()
::~Display() Done.

Again, this all is working under Xp Xp3, Vista and Windows 7.

Under Windows 8.1 though it all works fine until the first desktop/context
switch occurs. Once the first context switch occurs I never get anything
from my remote display driver. The whole enable/disable and final unload
of the remote display driver works as it should but after the first context
switch occurs I never get any data (GetDisplayDriverRects() NumberOfDriverRects:x)
from the driver. So i assume that the driver is no longer being called by the operating
system for some reason.

Even when I switch back to the original desktop I still get nothing from the driver.

I have tried to completely unload the display driver between context switches but
when I am unloading and call ChangeDisplaySettingsEx() For (CDS_UPDATEREGISTRY|CDS_NORESET|CDS_GLOBAL)
with a DEVMODE of all members set to 0 and dmFields=(DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_POSITION)
I get a DISP_CHANGE_FAILED. Note that this works just fine when I am unloading the driver (when my service
is shutting down, meaning I am on the desktop that the driver was initially loaded under).

Any thoughts would be greatly appreciated.

xxxxx@Ameritech.net wrote:

I have a ‘mirror’ driver that I wrote (MiniPort).
It works flawlessly under: Xp Sp3, Vista (x86,x64), Windows 7 (x86,x64).

I am now porting it to Windows 8.1.

Under Windows 8.1 though it all works fine until the first desktop/context
switch occurs. Once the first context switch occurs I never get anything
from my remote display driver. The whole enable/disable and final unload
of the remote display driver works as it should but after the first context
switch occurs I never get any data (GetDisplayDriverRects() NumberOfDriverRects:x)
from the driver. So i assume that the driver is no longer being called by the operating
system for some reason.

Windows 8 kills the XDDM driver model completely. They have introduced
a “Desktop Duplication API” that allows an application to fetch the
desktop image, just as a mirror driver did in previous versions.

http://msdn.microsoft.com/en-us/library/windows/desktop/hh404487.aspx


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks Tim.

I am aware of the desktop duplication API.
When Windows 8 first came out that was the only option for a ‘mirror’ driver.
Since then it seems ‘Remote Display Drivers’ was added to this page:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff568315(v=vs.85).aspx

This is a seems to be a somewhat ‘new’ option for a ‘mirror’ driver (as I remember looking for
options when Windows 8 first came out):
http://msdn.microsoft.com/en-us/library/windows/hardware/hh974665(v=vs.85).aspx

So, to be clear my ‘Remote Display Driver’ (which is just a subset of the Windows 2000 ‘mirror’ driver) works perfectly well on a Windows 8.1 machine (Built with the Windows 8.1 WDK/Visual Studio 2013) UNTIL a context switch occurs.

So my question(s) still stand.
1.) Does anyone know why this is occurring?
2.) Has anyone had experience with the ‘Remote Display Driver’ and context switching?

I am trying to maintain a single set of source code for all operating systems.

Thanks again.