Cannot capture DirectDraw graphics in a mirror driver

B

Boris Glick

Hello! In my project, I need to capture everything that shows up on a
primary monitor (in a dual-monitor system) and display parts of it on the
second monitor (I mean, continuously - not as a single-frame capture). I
wrote a mirror driver that sees all screen updates, and a user-mode
application that gets those updates from the driver and draws them on the
secondary monitor. It works fine for all GDI operations.

However, I have a problem with DirectX-based graphics and video. The driver
doesn't seem to see any of it. (The original version of the driver worked
on a single-monitor Windows 2000 system, and it could capture pretty much
everything we tried - though we didn't specifically try DirectX-based
graphics, but, for example, the video player worked).

Can a mirror driver capture the DirectX-related calls the same way it does
the GDI calls? I'm looking through the DirectX DDK documentation, but it
doesn't seem to support the "mirroring".

Should I start researching in a different direction?

If this makes a difference, I'm using the nVidea GeForce DVI video card.

Thank you so much for any hints!

Boris
 
F

Fadi

Boris Glick said:
Hello! In my project, I need to capture everything that shows
up on a
primary monitor (in a dual-monitor system) and display parts
of it on the
second monitor (I mean, continuously - not as a single-frame
capture). I
wrote a mirror driver that sees all screen updates, and a
user-mode
application that gets those updates from the driver and draws
them on the
secondary monitor. It works fine for all GDI operations.

However, I have a problem with DirectX-based graphics and
video. The driver
doesn't seem to see any of it. (The original version of the
driver worked
on a single-monitor Windows 2000 system, and it could capture
pretty much
everything we tried - though we didn't specifically try
DirectX-based
graphics, but, for example, the video player worked).

Can a mirror driver capture the DirectX-related calls the same
way it does
the GDI calls? I'm looking through the DirectX DDK
documentation, but it
doesn't seem to support the "mirroring".

Should I start researching in a different direction?

If this makes a difference, I'm using the nVidea GeForce DVI
video card.

Thank you so much for any hints!

Boris

Hi Boris,

I am afraid I can’t help you with your problem, and actually
I need help my self, and it seems that you are ahead of me so
I thought I ask you .

I am a studening trying working on a project that needs to capture
the screen changes done to the desktop (i.e just like Remote Desktop
does) using mirror driver approach.

I obtained and installed the DDK for winXP but i am stuck and don’t
know
what to do next. (i can’t even seem to try the sample cade that came
with it)

Any advice, thanks a million.

Fadi .K
 
B

Boris Glick

Hi Boris,

I am afraid I can't help you with your problem, and actually
I need help my self, and it seems that you are ahead of me so
I thought I ask you .

I am a studening trying working on a project that needs to capture
the screen changes done to the desktop (i.e just like Remote Desktop
does) using mirror driver approach.

I obtained and installed the DDK for winXP but i am stuck and don't
know
what to do next. (i can't even seem to try the sample cade that came
with it)

Any advice, thanks a million.

Fadi .K

--

Hi Fadi! Unfortunately, I can't share the code with you (it belongs to the
customer). However, I can try to offer some advice.

First off, I don't think I even tried building the DDK mirror sample, though
I did use it as a starting point.

As you probably know by now (and if not, you need to read a bit more DDK
documentation), display driver is actually two DLLs - a miniport driver and
a display driver. Each of these DLLs has a fixed entry point routine
(DriverEntry for the miniport and DrvEnableDriver for the display). The
main thing that the entry point routine does, it tells the operating system
what other routines are implemented in the DLL. You need to find out which
routines (in addition to the main entry points) you have to implement, and
what are their responsibilities.

After that, try to use a step-by-step approach. It works best when you are
trying to build a driver and don't have much experience. (A great book on
this approach is written by Art Baker, but he doesn't specifically cover
video drivers).

By step-by-step approach, I mean start with implementing a bare minimum of
the code: Get the driver to load/unload, get it to create/delete a surface,
and so forth. Then keep adding features one-by-one.

You also need to know general rules about drivers (that you can't have
global variables, can't use run time library, that all the instance-related
data has to rely in device extension, and so forth).

Instead of a run-time library, miniport driver has to use VideoPortxxx
functions, and display driver has to use Engxxx functions.

Here's a piece of documentation from DDK:

The requirements for a mirror driver miniport driver are minimal. The only
functions which must be implemented are DriverEntry, which is exported by
the miniport driver, and the following:



a.. HwVidFindAdapter
b.. HwVidInitialize
c.. HwVidStartIo

Hope this helps, and good luck!

Boris
 
M

Maxim S. Shatskih

I am a studening trying working on a project that needs to capture
the screen changes done to the desktop (i.e just like Remote Desktop
does) using mirror driver approach.

I don't think it is possible to capture DDraw. DDraw allows the app to map the
video memory to user addresses and then draw to it by usual memory accesses,
without any calls.
 
B

Boris Glick

Maxim S. Shatskih said:
I don't think it is possible to capture DDraw. DDraw allows the app to map
the
video memory to user addresses and then draw to it by usual memory
accesses,
without any calls.

Thanks a lot for your reply Maxim! I understand that you're right "in
general" - as in, it's impossible to capture *all* of screen changes caused
by DirectDraw (for example, when code is executing on a video card's CPU -
that's got to be hopeless). But I probably don't need 100% capture - or
rather, if I can't get 100%, I'll settle for 80%. The "capture" doesn't
have to be literal - all I need, is a notification that something on the
screen has changed, plus (if possible) the coordinates of the rectangle that
changed. I'm not after cutting-edge games, but video does need to be
captured.

Maybe I'll need to attack the problem from the user-mode API side. There are
quite a few DirectX API "spying" utilities out there - I'm researching that
avenue now. It seems that those "spies" work by replacing the DirectX dlls,
and then implementing the exported functions. I could go this route, but
from my experience, writing dll filters like this is risky and time
consuming (primarily because *all* the exported methods in a DLL have to be
mirrored, but not all of them will be documented. Also this will be very
dependent on the DirectX version).

So far, I found one workaround - if DirectX is disabled by turning off
hardware acceleration in dxdiag.exe, then all graphic is rerouted to GDI.

Boris
 
G

guilhermecox

Boris Glick said:
Thanks a lot for your reply Maxim! I understand that you're
right "in
general" - as in, it's impossible to capture *all* of screen
changes caused
by DirectDraw (for example, when code is executing on a video
card's CPU -
that's got to be hopeless). But I probably don't need 100%
capture - or
rather, if I can't get 100%, I'll settle for 80%. The
"capture" doesn't
have to be literal - all I need, is a notification that
something on the
screen has changed, plus (if possible) the coordinates of the
rectangle that
changed. I'm not after cutting-edge games, but video does
need to be
captured.

Maybe I'll need to attack the problem from the user-mode API
side. There are
quite a few DirectX API "spying" utilities out there - I'm
researching that
avenue now. It seems that those "spies" work by replacing the
DirectX dlls,
and then implementing the exported functions. I could go this
route, but
from my experience, writing dll filters like this is risky and
time
consuming (primarily because *all* the exported methods in a
DLL have to be
mirrored, but not all of them will be documented. Also this
will be very
dependent on the DirectX version).

So far, I found one workaround - if DirectX is disabled by
turning off
hardware acceleration in dxdiag.exe, then all graphic is
rerouted to GDI.

Boris

Boris,

I’d like to know how did you install your mirror driver to test it.

I developed one, very simple. I’d like to test the load/unload and to
see if the OS recognize it as a mirror driver.

I am asking it because I try to follow the DDK documantation, and the
sample that came with it and the sample didn’t work.

So, I am looking for a way to install the driver, like RDPDD, What are
the steps that I must know to install it correct and to the system see
the driver and can be enumarated in EnumDisplayDevices, etc etc..

Any help would be great.

About your problem, I had to implement some time ago a DirectShow
application that uses the Screen Capture filter. In my tests I could
capture DirectX Surfaces, It was not fast updated, but Its worked.
Maybe you can found some information in MSDN about details in Screen
Capture implementation/limitations..

Regards and sorry about my english.

cox
 
B

Boris Glick

Boris,
I'd like to know how did you install your mirror driver to test it.

I developed one, very simple. I'd like to test the load/unload and to
see if the OS recognize it as a mirror driver.

I am asking it because I try to follow the DDK documantation, and the
sample that came with it and the sample didn't work.

So, I am looking for a way to install the driver, like RDPDD, What are
the steps that I must know to install it correct and to the system see
the driver and can be enumarated in EnumDisplayDevices, etc etc..

Any help would be great.

About your problem, I had to implement some time ago a DirectShow
application that uses the Screen Capture filter. In my tests I could
capture DirectX Surfaces, It was not fast updated, but Its worked.
Maybe you can found some information in MSDN about details in Screen
Capture implementation/limitations..

Regards and sorry about my english.

cox

Hello Cox! First off, your English is just fine (it's not my first language
either).

Second - thanks a lot for the DirectDraw filter idea. This is not the first
time people mention filters, so it looks like I'll need to learn yet another
API - DirectDraw, that is.

Third - about installing the driver. First off, note that there are two
separate tasks: Installing it and starting it.
To install it, I wrote an .inf file. I started with an example from MSDN,
and added a few pieces of my own. To start it, I used EnumDisplayDevices to
obtain its DeviceName, and then called ChangeDisplaySettingsEx() to actually
start the driver.

Here's the .inf file that I wrote.
Note: I removed some unnecessary pieces from the .inf file, and renamed some
strings (my version of .inf file also installs and registers a user-mode dll
and a com server, and adds a menu shortcut - you didn't need any of that).
But in doing that, I could've messed up, so I'm not 100% that this file will
work - make sure to doublecheck everything.

After writing the file, I put it into the same directory with the binaries,
and then used "Add hardware / Display Adapter" from Hardware manager.

Hope this helps!

Boris

;***********************************************************************
; MyMirrorDriver.inf
;
; Installation inf for MyMirrorDriver 2 driver
;
;
; Copyright (c) 2005 MyClientCompany, Inc.
;
;***********************************************************************

[Version]
Signature="$CHICAGO$"
Provider=%MyClientCompany%
ClassGUID={4D36E968-E325-11CE-BFC1-08002BE10318}
Class=Display
DriverVer=2/16/2005,1.1

[DestinationDirs]
DefaultDestDir = 11
MyMirrorDriver.Miniport = 12 ; drivers
MyMirrorDriver.Display = 11 ; system32

;
; Driver information
;

;
; Manufacturer section (list model sections)
;
[Manufacturer]
%MyClientCompany% = MyClientCompany.Mfg

;
; Models section (list install sections)
;
[MyClientCompany.Mfg]
%MyClientCompany.DeviceDesc0% = MyMirrorDriver, MyMirrorDriver

;
; General installation section
;

[MyMirrorDriver]
CopyFiles=MyMirrorDriver.Miniport, MyMirrorDriver.Display

;
; File sections
;

[MyMirrorDriver.Miniport]
MyMirrorDriver.sys

[MyMirrorDriver.Display]
MyMirrorDriver.dll

;
; Service Installation
;

[MyMirrorDriver.Services]
AddService = MyMirrorDriver, 0x00000002, MyMirrorDriver_Service_Inst,
MyMirrorDriver_EventLog_Inst

[MyMirrorDriver_Service_Inst]
DisplayName = %MyMirrorDriver.SvcDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 1 ; SERVICE_SYSTEM_START
ErrorControl = 0 ; SERVICE_ERROR_IGNORE
LoadOrderGroup = Video
ServiceBinary = %12%\MyMirrorDriver.sys

[MyMirrorDriver_EventLog_Inst]
AddReg = MyMirrorDriver_EventLog_AddReg

[MyMirrorDriver_EventLog_AddReg]
HKR,,EventMessageFile,0x00020000,"%SystemRoot%\System32\IoLogMsg.dll;%SystemRoot%\System32\drivers\MyMirrorDriver.sys"
HKR,,TypesSupported,0x00010001,7

;
; Software Installation
;

[MyMirrorDriver.SoftwareSettings]
AddReg = MyMirrorDriver_SoftwareDeviceSettings

;
; Driver parameters go here
;
[MyMirrorDriver_SoftwareDeviceSettings]
HKR,, MirrorDriver, %REG_DWORD%, 1
HKR,, InstalledDisplayDrivers, %REG_MULTI_SZ%, MyMirrorDriver
HKR,, VgaCompatible, %REG_DWORD%, 0
HKR,, Attach.ToDesktop, %REG_DWORD%, 1

;-----------------------------------------------------------------------
; Display driver startup configuration data
;-----------------------------------------------------------------------

;
HKR,, MyDriverParameter, %REG_DWORD%, 0


[MyMirrorDriver.GeneralConfigData]
MaximumNumberOfDevices = 1
KeepExistingDriverEnabled = 1

;
;-----------------------------------------------------------------------
; Source file information
;-----------------------------------------------------------------------
[SourceDisksNames]
1 = %DiskId%,,,""

[SourceDisksFiles]
MyMirrorDriver.sys = 1
MyMirrorDriver.dll = 1

[Strings]

;
; Non-Localizable Strings
;

REG_SZ = 0x00000000
REG_MULTI_SZ = 0x00010000
REG_EXPAND_SZ = 0x00020000
REG_BINARY = 0x00000001
REG_DWORD = 0x00010001
serviceroot = System\CurrentControlSet\Services
RunKey = "Software\Microsoft\Windows\CurrentVersion\Run"

;
; Localizable Strings
;

DiskId="MyMirrorDriver Software Installation Disk"

MyClientCompany = "My Client Company, Inc."
MyClientCompany.DeviceDesc0 = "My display capture driver"
MyMirrorDriver.SvcDesc="MyMirrorDriver"
 

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