From: Andrey on
I have studied the specs for RDP (which are open and available for
download from microsoft website) - and it seems that there is a
virtual possibility to workaround the well-known problem of minimizing
RDP window (which might cause application failures due to the fact
that server secures remote desktop state disallowing Input-related
APIs like GetCursorPos - actually I think it's just a bug, minimizing
client windows must not have negative impact on remote session).

From protocol description in MS-RDPBCGR.pdf and from rdesktop sources
it seems that when client window minimizes mstsc.exe sends window
update control message to server to say that it is not interested in
screen updates - this is called "output suppression". In this case
server becomes silent unless client window restores and output
suppression is disabled. My guess is that output suppression
implementation on server somehow changes desktop (impact is similar to
screen-lock) and that causes some APIs to stop working for
applications in this session. So, disabling output suppression
capability (either on client, or on the server) might be the cure.

Server defines a set of capabilities - and "Output Suppression" is one
of them. I think that mstsc reads them during session initialization.
Thus theoretically if server exposes that capability to be configured
- disabling it might be a workaround.

I searched through Terminal Services config in gpedit.msc, WMI and
registry but was not able to find this setting.Does anyone know
whether such setting exists and how to access it? Maybe
programatically?

And there is a registry value HKEY_LOCAL_MACHINE\SYSTEM
\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\CfgDll
that is set to RDPCFGEX.DLL. This library exports the following
methods:

1 0 000012B7 ExGetCfgVersionInfo
2 1 000012C2 ExtEncryptionLevels
3 2 0000115A ExtEnd
4 3 000012DC ExtGetCapabilities
5 4 000011B6 ExtGetEncryptionLevelAndDescrEx
6 5 00001160 ExtGetEncryptionLevelDescr
7 6 0000139E ExtGetSecurityLayerDescrString
8 7 00001308 ExtGetSecurityLayerName
9 8 000012E5 ExtSecurityLayers
10 9 00001152 ExtStart

I though this might be used to control caps, but it is not documented.

-- Andrey
From: jolteroli on
"Andrey" <andrey.fedyashov(a)gmail.com> schrieb im Newsbeitrag
news:205f891d-ae0e-4f7e-afa0-b038757158b7(a)h20g2000yqn.googlegroups.com...
>I have studied the specs for RDP (which are open and available for
> download from microsoft website) - and it seems that there is a
> virtual possibility to workaround the well-known problem of minimizing
> RDP window (which might cause application failures due to the fact
> that server secures remote desktop state disallowing Input-related
> APIs like GetCursorPos - actually I think it's just a bug, minimizing
> client windows must not have negative impact on remote session).

Just curious: Does GetCursorPos return false in a "minimized session"?

> From protocol description in MS-RDPBCGR.pdf and from rdesktop sources
> it seems that when client window minimizes mstsc.exe sends window
> update control message to server to say that it is not interested in
> screen updates - this is called "output suppression". In this case
> server becomes silent unless client window restores and output
> suppression is disabled. My guess is that output suppression
> implementation on server somehow changes desktop (impact is similar to
> screen-lock) and that causes some APIs to stop working for
> applications in this session. So, disabling output suppression
> capability (either on client, or on the server) might be the cure.
>
> Server defines a set of capabilities - and "Output Suppression" is one
> of them. I think that mstsc reads them during session initialization.
> Thus theoretically if server exposes that capability to be configured
> - disabling it might be a workaround.
>
> I searched through Terminal Services config in gpedit.msc, WMI and
> registry but was not able to find this setting.Does anyone know
> whether such setting exists and how to access it? Maybe
> programatically?
>
> And there is a registry value HKEY_LOCAL_MACHINE\SYSTEM
> \CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\CfgDll
> that is set to RDPCFGEX.DLL. This library exports the following
> methods:
>
> 1 0 000012B7 ExGetCfgVersionInfo
> 2 1 000012C2 ExtEncryptionLevels
> 3 2 0000115A ExtEnd
> 4 3 000012DC ExtGetCapabilities


unsigned long ExtGetCapabilities()
{
return 0x7F;
}

> 5 4 000011B6 ExtGetEncryptionLevelAndDescrEx
> 6 5 00001160 ExtGetEncryptionLevelDescr
> 7 6 0000139E ExtGetSecurityLayerDescrString
> 8 7 00001308 ExtGetSecurityLayerName
> 9 8 000012E5 ExtSecurityLayers
> 10 9 00001152 ExtStart
>
> I though this might be used to control caps, but it is not documented.

The capabilities are well known when compiling the terminal server component
binaries, so I guess they are builtin.
Also, the exports seem to Get the configuration, not to Set them. No file in
the system32 contains the string "rdpcfgex.dll". Hence the library isn't use
(anymore). Guess it's there for a legacy reason still.

strings -f -a -e S * | grep rdpcfgex.dll

But hey, rdesktop is gpl'ed, you could comment off the calls to
rdp_send_client_window_status in rdesktop-1.6.0/xwin.c:2549:

case MapNotify:
if (!g_seamless_active)
rdp_send_client_window_status(1);
break;
case UnmapNotify:
if (!g_seamless_active)
rdp_send_client_window_status(0);
break;

so the RDP_DATA_PDU_CLIENT_WINDOW_STATUS isn't send. Test the application
behaviour with this new rdesktop.

-jolt

From: Andrey on
On Nov 27, 11:26 pm, "jolteroli" <jolt1...(a)gmx.net> wrote:
> "Andrey" <andrey.fedyas...(a)gmail.com> schrieb im Newsbeitragnews:205f891d-ae0e-4f7e-afa0-b038757158b7(a)h20g2000yqn.googlegroups.com...
>
> >I have studied the specs for RDP (which are open and available for
> > download from microsoft website) - and it seems that there is a
> > virtual possibility to workaround the well-known problem of minimizing
> > RDP window (which might cause application failures due to the fact
> > that server secures remote desktop state disallowing Input-related
> > APIs like GetCursorPos - actually I think it's just a bug, minimizing
> > client windows must not have negative impact on remote session).
>
> Just curious: Does GetCursorPos return false in a "minimized session"?
>

Yes, it does; and GetLastError() is 0.
In general - remote session's behavior in case of mstsc's minimization
is similar to as if the desktop became locked. Any idea why TS server
does so?
On a locked session those APIs also do not work - and the
justification is that winlogon desktop takes over which is protected
(weird thing is that SetCursorPos works under lock; so what is the
difference between SetCursorPos and GetCursorPos from security point
of view?)

Discussion groups have many posts related to this RDP minimization
issue:
http://rubyforge.org/pipermail/wtr-general/2006-December/008472.html
http://groups.google.com/group/microsoft.public.win2000.termserv.clients/browse_thread/thread/45252f2b81ed3dd8?hl=ru&q=RDP+minimize
http://groups.google.com/group/watir-general/browse_thread/thread/8e3b4af91a667683?hl=ru&q=RDP+minimize
http://groups.google.com/group/microsoft.public.dotnet.framework.windowsforms/browse_thread/thread/189b4f58aa2bbc82?hl=ru&q=RDP+minimize

Currently, I personally met with two APIs that stop doing their job:
GetCursorPos and mouse_event.

>
>
> > From protocol description in MS-RDPBCGR.pdf and from rdesktop sources
> > it seems that when client window minimizes mstsc.exe sends window
> > update control message to server to say that it is not interested in
> > screen updates - this is called "output suppression". In this case
> > server becomes silent unless client window restores and output
> > suppression is disabled. My guess is that output suppression
> > implementation on server somehow changes desktop (impact is similar to
> > screen-lock) and that causes some APIs to stop working for
> > applications in this session. So, disabling output suppression
> > capability (either on client, or on the server) might be the cure.
>
> > Server defines a set of capabilities - and "Output Suppression" is one
> > of them. I think that mstsc reads them during session initialization.
> > Thus theoretically if server exposes that capability to be configured
> > - disabling it might be a workaround.
>
> > I searched through Terminal Services config in gpedit.msc, WMI and
> > registry but was not able to find this setting.Does anyone know
> > whether such setting exists and how to access it? Maybe
> > programatically?
>
> > And there is a registry value HKEY_LOCAL_MACHINE\SYSTEM
> > \CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\CfgDll
> > that is set to RDPCFGEX.DLL. This library exports the following
> > methods:
>
> >          1    0 000012B7 ExGetCfgVersionInfo
> >          2    1 000012C2 ExtEncryptionLevels
> >          3    2 0000115A ExtEnd
> >          4    3 000012DC ExtGetCapabilities
>
>     unsigned long ExtGetCapabilities()
>     {
>         return 0x7F;
>     }
>
> >          5    4 000011B6 ExtGetEncryptionLevelAndDescrEx
> >          6    5 00001160 ExtGetEncryptionLevelDescr
> >          7    6 0000139E ExtGetSecurityLayerDescrString
> >          8    7 00001308 ExtGetSecurityLayerName
> >          9    8 000012E5 ExtSecurityLayers
> >         10    9 00001152 ExtStart
>
> > I though this might be used to control caps, but it is not documented.
>
> The capabilities are well known when compiling the terminal server component
> binaries, so I guess they are builtin.
> Also, the exports seem to Get the configuration, not to Set them. No file in
> the system32 contains the string "rdpcfgex.dll". Hence the library isn't use
> (anymore). Guess it's there for a legacy reason still.
>
>     strings -f -a -e S * | grep rdpcfgex.dll
>

Possibly, it is loaded dynamically. After posting my question I did
some investigation about this DLL
and understood that it is not what I wanted. Thanks for clarifying it
further.

> But hey, rdesktop is gpl'ed, you could comment off the calls to
> rdp_send_client_window_status in rdesktop-1.6.0/xwin.c:2549:
>
>     case MapNotify:
>         if (!g_seamless_active)
>             rdp_send_client_window_status(1);
>         break;
>     case UnmapNotify:
>         if (!g_seamless_active)
>             rdp_send_client_window_status(0);
>         break;
>
> so the RDP_DATA_PDU_CLIENT_WINDOW_STATUS isn't send. Test the application
> behaviour with this new rdesktop.
>
> -jolt

Sure, you are right. Others were already doing similar changes:
http://osdir.com/ml/network.rdesktop.devel/2007-10/msg00000.html
This is a very good alternative (and the only thing I can do in this
circumstances); but in the first place we are interested in having
similar possibility in MSTSC.
I also tried to workaround it in code (avoid using GetCursorPos, try
GetCursorInfo instead) - but it is rather difficult as there is no
list of functions that do not work.

-- Andrey
From: jolteroli on
Im not sure, but i think GetCursorPos fails, because the Terminalserver
maintains 3 desktops:

1.) Logon
2.) Interactive Desktop
3.) Disconnected Desktop

For sure when disconnected and perhaps when output suppression is active,
the server switches to the "disconnected desktop".

Have a look here:
http://www.microsoft.com/msj/1298/terminalserver/terminalserver.aspx
(Windowstations and Desktops )

Again curious: What kinda application does use Get/SetCursorPos? In my early
days, we have coded4fun with the Glide API for the 3Dfx Voodoo Cards. We
have hidden the cursor and got the mouse dx/dy only by the Get/Set calls, so
we had the free look with the mouse, like in Quake3 and such games.

Shouldn't workarounding the "bug" this way work?

// current and center coordinates.
// where mpt is already set to the center and is updated on WM_RESIZE
msgs.
POINT pt, mpt;

if (!GetCursorPos(pt)) {
// Error means no mouse movement happend!
dx = dy = 0;
} else {
// Get deltas'n'update
dx = pt.x - mpt.x;
dy = pt.y - mpt.y;
// set cursor back into the center for next delta.
SetCursorPos(mpt);
}

// Go on with dx,dy...

-jolt

From: Andrey on
On Nov 28, 7:06 pm, "jolteroli" <jolt1...(a)gmx.net> wrote:
> Im not sure, but i think GetCursorPos fails, because the Terminalserver
> maintains 3 desktops:
>
> 1.) Logon
> 2.) Interactive Desktop
> 3.) Disconnected Desktop
>
> For sure when disconnected and perhaps when output suppression is active,
> the server switches to the "disconnected desktop".
>

I think that if this is something that breaks applications running in
this session - then server shouldn't have done that. Why would apps
have to depend on whether remote user has minimized his client screen
or disconnected?

> Have a look here:http://www.microsoft.com/msj/1298/terminalserver/terminalserver.aspx
> (Windowstations and Desktops )
>
> Again curious: What kinda application does use Get/SetCursorPos? In my early
> days, we have coded4fun with the Glide API for the 3Dfx Voodoo Cards. We
> have hidden the cursor and got the mouse dx/dy only by the Get/Set calls, so
> we had the free look with the mouse, like in Quake3 and such games.

I think the answer is quite simple - GetCursorPos is an easy to use
function that tells the cursor position on the screen.
Also I can add that it is a must have function for applications
performing mouse and keyboard input generation (like for example
automated functional/UI testing tools).
I am trying to see whether GetCursorInfo can be used as a workaround -
but not sure whether it works reliably in the same conditions.

>
> Shouldn't workarounding the "bug" this way work?
>
>     // current and center coordinates.
>     // where mpt is already set to the center and is updated on WM_RESIZE
> msgs.
>     POINT pt, mpt;
>
>     if (!GetCursorPos(pt)) {
>         // Error means no mouse movement happend!
>         dx = dy = 0;
>     } else {
>         // Get deltas'n'update
>         dx = pt.x - mpt.x;
>         dy = pt.y - mpt.y;
>         // set cursor back into the center for next delta.
>         SetCursorPos(mpt);
>     }
>
>     // Go on with dx,dy...
>
> -jolt

I didn't quite understand this workaround.. You assume that
GetCursorPos failure indicates that there was no mouse movement? Why?