Re: Rendering on the system console from a remote terminal-server session

Maxim,
thanks for your reply.
I’m not sure I understand though - the problem I see is that I can’t
share window handlers between TS sessions.
Is there a way to do that or this is what you meant - 'no ways…"?
Thanks,
Jacky

Maxim S. Shatskih wrote:

No ways. Run the helper app on the local console, communicate to it from
another app running in TS session.

“Jacky Romano” wrote in message news:xxxxx@ntdev…

> > From an application launched from a remote session, I need to render
> > graphics on the local server graphics.
> > Rendering I mean initially GDI but eventually I would like to be able to
> > render hardware accelerated opengl and direct3D.
> > While the task seems to be embarrassingly simple so far I couldn’t find
> > a way to achieve that… and desperately need help.
> >
> > Here are some details:
> > First I need to admit that I’m new to Windows Display driver
> > architecture so hopefully I’m not too naive with my comments and
> > assumptions on the windows kernel.
> > During climbing my learning curve and experimenting I learned that the
> > display driver is swapped by the TS service by RDPDD which redirect
> > the rendering calls to the client. This is reflected through
> > EnumDisplayDevices(…) which hides the real device that I need to use.
> >
> > My question is - What is the way (if there is any) to access the local
> > display device and create a DC to be used for GDI drawing?
> > A rephrase to that question would be if there is a way to share window
> > handlers between sessions. If there was a way, I could open a window in
> > session0 (by an helper service) and have the remotely launched process
> > to render to this window.
> >
> > If there isn’t an off-the-box API way to access the local device, would
> > it make sense to write a display driver would replace RDPDD and pass
> > through/mirror the calls its get to RDPDD and the local driver as
> > required ?
> >
> > Thanks in advance for any guidance, pointers or help in general
> > Jacky
> >
> >
> >
> >
>

Jacky Romano wrote:

I’m not sure I understand though - the problem I see is that I can’t
share window handlers between TS sessions.
Is there a way to do that or this is what you meant - 'no ways…"?

What he said is to run a helper application on the local console. Not
in the TS session, but on the local machine itself. If you want to draw
on the local console screen, then you are requiring that someone be
logged in to the local console, and that means they can run an
application, from Programs->Startup if nothing else.

Once you have a helper application running, there are several ways for
you to communicate with it from an app in a TS session. A shared file
or a named pipe would work. Let the helper app worry about the window
handles.


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

I now see where I was mis-speaking (and the source to my confusion) .
Eventually what I’m trying to achieve is that an opengl application
launched from a remote session will be able to use the local graphics
board hardware *transparently*. In order to make that happen, I’m
planning on intercepting the application call to
wglCreateContext(HDC,…) and hand it with a device context of the real
gfx board display driver instead of the one the application has from
the TS display device.
To make that happen, I’m looking for a way to create a DC by the helper
application and use it by the application running under the remote
session.
As an alternative, if I could find a way to access the local
display-driver and create a DC of it directly (using CreateDC(…)) that
would solve my problem too.
is that explains ?
Thanks,
Jacky

Tim Roberts wrote:

Jacky Romano wrote:

> I’m not sure I understand though - the problem I see is that I can’t
> share window handlers between TS sessions.
> Is there a way to do that or this is what you meant - 'no ways…"?
>

What he said is to run a helper application on the local console. Not
in the TS session, but on the local machine itself. If you want to draw
on the local console screen, then you are requiring that someone be
logged in to the local console, and that means they can run an
application, from Programs->Startup if nothing else.

Once you have a helper application running, there are several ways for
you to communicate with it from an app in a TS session. A shared file
or a named pipe would work. Let the helper app worry about the window
handles.

Jacky Romano wrote:

I now see where I was mis-speaking (and the source to my confusion) .
Eventually what I’m trying to achieve is that an opengl application
launched from a remote session will be able to use the local graphics
board hardware *transparently*.

What’s the point? The remote user won’t be able to see it, and whoever
is sitting at the physical console is going to be surprised as heck to
see drawing happen without any action on his part.

Are you hoping to use the graphics hardware to render the OpenGL into a
bitmap, and then display the bitmap in the remote session? Kind of a
back-door means of supporting OpenGL in Terminal Services session? I’ll
wager you would be more successful with just about the same performance
by using MESA with a software OpenGL implementation.

In order to make that happen, I’m planning on intercepting the
application call to wglCreateContext(HDC,…) and hand it with a
device context of the real gfx board display driver instead of the
one the application has from the TS display device.
To make that happen, I’m looking for a way to create a DC by the
helper application and use it by the application running under the
remote session.
As an alternative, if I could find a way to access the local
display-driver and create a DC of it directly (using CreateDC(…))
that would solve my problem too.

You can’t do this transparently. The system is designed to prevent you
from doing this.


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

> I’m not sure I understand though - the problem I see is that I can’t

share window handlers between TS sessions.
Is there a way to do that or this is what you meant - 'no ways…"?

No ways, you need 2 apps - one running under console session, another running
under the local session. Then use some kind of IPC - like RPC/DCOM - between
them.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Tim Roberts wrote:

Jacky Romano wrote:

> I now see where I was mis-speaking (and the source to my confusion) .
> Eventually what I’m trying to achieve is that an opengl application
> launched from a remote session will be able to use the local graphics
> board hardware *transparently*.
>

Are you hoping to use the graphics hardware to render the OpenGL into a
bitmap, and then display the bitmap in the remote session? Kind of a
back-door means of supporting OpenGL in Terminal Services session?
Yep, this is the goal.
I’ll wager you would be more successful with just about the same performance
by using MESA with a software OpenGL implementation.

That I doubt. Typically software implementation would be orders of
magnitude slower for non trivial scenes.

> In order to make that happen, I’m planning on intercepting the
> application call to wglCreateContext(HDC,…) and hand it with a
> device context of the real gfx board display driver instead of the
> one the application has from the TS display device.
> To make that happen, I’m looking for a way to create a DC by the
> helper application and use it by the application running under the
> remote session.
> As an alternative, if I could find a way to access the local
> display-driver and create a DC of it directly (using CreateDC(…))
> that would solve my problem too.
>

You can’t do this transparently. The system is designed to prevent you
from doing this.

Thanks - I hear you. this is the decisiveness I was looking for.
Could you please elaborate about the reason or point me to some
documentation I can read about this ?

Jacky Romano wrote:

Tim Roberts wrote:
> I’ll wager you would be more successful with just about the same performance
> by using MESA with a software OpenGL implementation.
>
That I doubt. Typically software implementation would be orders of
magnitude slower for non trivial scenes.

One order of magnitude, perhaps. Mesa is pretty darned good these days.

However, when you consider that you will have to copy each frame to
system memory, transmit it over the network, and then copy it back into
your client frame buffer, I’ll wager real money that the overall
performance difference will be less than 2x. You’re up against Amdahl’s
Law here: you’re optimizing the path that is not necessarily the
bottleneck. It doesn’t matter how fast you make the remote rendering –
you’re never going to get anything like a local console frame rate.

And when I said “more successful”, I meant “more likely to create a
workable solution”. You could have Mesa working in small integer days.
Your backdoor OpenGL solution is going to require many months, if it can
be made to work at all.

Microsoft learned this lesson with their “smart console” concept. The
idea was that you’d have a flat panel running Windows CE with a wireless
adapter, that basically used Terminal Services to allow you to carry
your PC’s monitor with you around the house. The initial version let
the PC render MPEG movies using the PC’s MPEG acceleration hardware, and
transmitted the decompressed frames to the remote. That sucked, badly.
They invented a “back channel” to pump the uncompressed MPEG over to the
CE device, to do MPEG decoding in software. It was a much better
experience.

> You can’t do this transparently. The system is designed to prevent you
> from doing this.
>
Thanks - I hear you. this is the decisiveness I was looking for.
Could you please elaborate about the reason or point me to some
documentation I can read about this ?

I’m not sure there is any documentation at this level of detail, save
perhaps some white papers from when the original Terminal Services stuff
came over from Citrix. I Googled for “terminal services white papers”
and came up with some possibilities.

A Terminal Services client has its own instance of win32k.sys (that is,
GDI and USER) talking to its own display driver, separate from all of
the other display drivers, protected by the “window station”
separation. A TS client simply cannot break out of that box. A DC in
your window station refers to a separate set of data structures from a
DC in the main console’s window station. More than just another DC,
it’s a DC from another DC pool.

Allow me to make a suggestion. Go to the list of Terminal Server MVPs at

http://mvp.support.microsoft.com/communities/mvp.aspx?product=1&competency=Windows+Server+-+Terminal+Server
You should be able to find contact information for a couple of them.
They may be able to provide more information.


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

> I’m not sure there is any documentation at this level of detail, save

perhaps some white papers from when the original Terminal Services stuff
came over from Citrix. I Googled for “terminal services white papers”
and came up with some possibilities.

A Terminal Services client has its own instance of win32k.sys (that is,
GDI and USER) talking to its own display driver, separate from all of
the other display drivers, protected by the “window station”
separation. A TS client simply cannot break out of that box. A DC in
your window station refers to a separate set of data structures from a
DC in the main console’s window station. More than just another DC,
it’s a DC from another DC pool.

Allow me to make a suggestion. Go to the list of Terminal Server MVPs at

http://mvp.support.microsoft.com/communities/mvp.aspx?product=1&competency=Windows+Server+-+Terminal+Server
You should be able to find contact information for a couple of them.
They may be able to provide more information.

Thanks for the help and the references.
I’ll go and check those out.

many thanks,
Jacky