How to lock display detection on NVIDIA driver

F

Francesco

I'm using an NVIDIA Geforce 6600 based video board (dual monitor) on XPE, I
install the driver before the reseal phase using a standard windows
installation (I mean the drivers are not specific for XP embedded) and I set
a dual monitor configuration using the horizontal span feature to get a full
resolution of 2048x768 (1024x768) on each monitor.

Everyhing works well except when I start my device with only one monitor
attached. If this happens, the video boards (or XPE) detects that only one
monitor is connected and the video configuration automatically changes to
single video with 1024x768 resolution. No way to revert back to the original
configuration other than using the standard configuration panel.

If I restart the device this last configuration (single monitor) is active
even if I connect also the second monitor, I mean the configuration doesn't
revert automatically to horizontal span 2048x768.
This causes a major problem to me because the application I'm working on
will be used with two monitors and no input device (nor mouse nor keyboard)
and connecting to the device with an RDP client it does not allow me to
change the actual "hardware" configuration setting, so I must connect at
least a keyboard to be able to operate on video settings.

Any suggestion or ideas on how to avoid this "annoying" fact ?

Thanks
Francesco
 
D

dferencz

Francesco,

I have dealt with this dreaded behavior in nVidia drivers -- I'm using
"clone" mode to display output to both a DVI device and an S-video
display. I was able to force the S-video on (using the "force" option
on the nVidia control panel applet), but this created a new problem: if
the system was ever booted without the DVI cable attached, the driver
switched back to "single" display mode, with only the S-video output
enabled! Even if I rebooted with the DVI monitor again, it would no
longer display (even if it was the ONLY monitor!!)

I truly begrudge MS and nVidia for not providing an API to control
multi-monitor output!

Anyway, here was my solution (brace yourself, this isn't pretty): I
wrote a Windows service that runs at boot and rewrites all the driver's
registry settings to specific values, before the display driver loads.
(I do this by placing my service in the "Video Init" class.) So no
matter what the driver does to the settings, I force them to be correct
when the driver loads.

It's even uglier than it sounds, because the location in the registry
for a video driver is not fixed and typically contains an install-time
GUID (such as HKLM\CurrentControlSet\Control\Video\{GUID}\0000). So my
service does a "search-and-replace" for a specified key to locate the
driver of interest (e.g., I look for a subkey that contains the value
"Device Description" with the data "nVidia GeForceFX blah") and then
replace the entries.

Let me know if you want more details...

-- Don
 
F

Francesco

Thanks for your answer,
I guessed there was nothing "easy" or "standard" to do on this subject
Anyway, here was my solution (brace yourself, this isn't pretty): I
wrote a Windows service that runs at boot and rewrites all the driver's
registry settings to specific values, before the display driver loads.
(I do this by placing my service in the "Video Init" class.) So no
matter what the driver does to the settings, I force them to be correct
when the driver loads.
... cut ...
Let me know if you want more details...

Could you please deatil a little more about how to have a service which runs
before the display driver loads ?
I'm not much expert on this field and any help would be very appreciated.

After the registry replacement the service you wrote can stop ?

Thanks again for you answers
Francesco
 
D

dferencz

Writing the service is relatively easy - I copied the service sample
code from the MS SDK (located in the SDK directory Program
Files\Microsoft SDK\Samples\Windbase\Service.) You just customize the
ServiceStart() function in Simple.c to perform the registry fixes.
Technically the service should remain running until the service manager
tells it to stop. So, instead of exiting, you should sleep in
ServiceStart() until the hServerStopEvent is signalled.

To get your service to run prior to the video driver, you must have it
loaded as part of the "Video Init" group. To do this, make sure you
specify "Video Init" as the load order group in the call to
CreateService() (this is in the Service.c source file; in the sample
code, it is specified as NULL.) Note that for my XPE component, I
don't use the "install" method provided in the sample, but I created a
custom XPE component which has a resource of the "Service Data" type.
In this resource, set the following properties:

StartType = 2
StartName = "LocalSystem"
ServiceType = 16
ServiceName = "{Name of your service}" (should be the same as the
SZSERVICENAME in the sample Service.h)
ServiceBinary = "%11\{Your binary name}" (it gets installed in
WINDOWS\SYSTEM32)
LoadOrderGroup = "Video Init"

Make sure the custom component includes a file resource which gets
copied into %11 (which is your binary EXE).

One more caveat I forgot to mention -- with the nVidia drivers, I found
that the only way to get the right registry settings is to extract them
from an OFFLINE image (after the system has shutdown). So, you'll have
to boot your XPE image, adjust the video settings the way you want
them, then reboot (TWICE, just to make sure!). Then, load the registry
offline from an XP Pro system (attach the development HD, or load from
an alternate partition.) From regedit, select HKLM, then choose "Load
Hive..." from the file menu. Navigate to the XPE image in the
WINDOWS\SYSTEM32\CONFIG directory and load the SYSTEM hive. Give it a
name such as "XPE_SYSTEM". You'll find the nVidia driver parameters in
HKLM\XPE_SYSTEM\ControlSet001\Control\Video\{GUID}.

Sorry I'm not posting my direct results & code due to IP issues (my
company owns it), but hopefully this will give an outline of what you
need...

-- Don
 
F

Francesco

Sorry I'm not posting my direct results & code due to IP issues (my
company owns it), but hopefully this will give an outline of what you
need...

-- Don

Thanks Don,
your info is very valuable and put me directly on the right direction,
I appreciate your help and I was not expecting some source code, I
understand your devotion to the company you work for, that's correct.

Just to mention, yesterday I downloaded an SDK from Nvidia end they expose
some functions from a control panel library to get some info form the driver
and set some working modes.
Although I still have to read it carefully, it seems that the problem I was
looking for can be addressed also using some calls to this library.

You already solved the problem in a different way but may be others might be
interested to know.

Thanks again
Francesco
 
D

dferencz

Wow, thanks for the tip. nVidia did not provide the details of the
Control Panel DLL when I started my project (over 2 years ago). If I
had had that info, my life would have been much easier!

-- Don
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top