1

I am maintaining an old application that, among other things, displays tiny video feeds on screen. The application works fine unless you run it while viewing the desktop through RDP.

When we go to acquire the write pointer via IDirectDrawSurface7's Lock function:

DDSURFACEDESC2 dsd;
ZeroMemory(&dsd, sizeof(dsd));
dsd.dwSize = sizeof(dsd);
hr = m_pSurface->Lock(NULL, &dsd, DDLOCK_NOSYSLOCK|DDLOCK_WRITEONLY/*|DDLOCK_DONOTWAIT*/, NULL);

Everything works fine unless you are connected to the system via RDP. In that case the lock fails, with the HRESULT of DDERR_WASSTILLDRAWING.

The remarks on the MSDN Page state that this error should only occur, under "default conditions", when the flag DDLOCK_DONOTWAIT is used, which I have diagnostically commented out.

Is there any hope for getting this application working over RDP 8 / Windows 7 without a major redesign?

Both having the application open and connecting a new RDP session and launching the application through an existing RDP session cause this behavior.

sampathsris
  • 21,564
  • 12
  • 71
  • 98
Techrocket9
  • 2,026
  • 3
  • 22
  • 33
  • So basically you have an DirectX application that is working fine native but when you are using it remotely via Remote Desktop it's crashing. Am I right? I could try to help if this is the case but I should need the source code in order to compile and debug the binary. I have & can use IDA Pro to fix such problems which are often caused by closed-source code. I don't think someone could help you with this limited information as the problem looks very platform specific. –  Aug 07 '14 at 12:22
  • @sasho648 It doesn't crash. We detect the HRESULT of DDERR_WASSTILLDRAWING and in this instance we use another mechanism to draw a static image placeholder where we normally put the video feed and tell the user with a dialog box that their RDP session has caused the video feeds to stop. I started tracing that dialog box and determined that the failure to acquire a lock during the RDP session was the root trigger for that dialog box. – Techrocket9 Aug 07 '14 at 17:25
  • No, I just found the root of it. It's that attempting to lock a DDSURFACEDESC2 fails when running on an RDP session as described in my original post, and it is my hope that someone else has encountered this issue and has found a solution/workaround. – Techrocket9 Aug 07 '14 at 17:30
  • I wish you luck with that. However if you can post the source code or if you can't - only the binaries I could try to seek the failure with IDA. –  Aug 07 '14 at 17:36
  • 1
    You have to wait with `DDLOCK_WAIT` because a bit block transfer (bitblt) operation is in progress. – clover Aug 11 '14 at 17:22
  • Is this the case where the application was started while under remote desktop ? Or it was started on the native display and working fine, then when another PC made an RDP connection to view the actively running app, the Lock called started failing? If it's the latter, I suspect you may need to release and recreate the surface object. – selbie Aug 12 '14 at 03:22
  • Are you constantly getting DDERR_WASSTILLDRAWING? Im guessing in RDP its doing some kind of simulation of graphics which might cause the surface to be busy. Without seeing your code you could skip frames until its done with the surface and do another frame. Lastly, look at your unlock code, is it being called? – Rudolfwm Aug 12 '14 at 10:47
  • @selbie The same behavior occurs when connecting via RDP while the application is already running and when starting the application during an existing RDP session. – Techrocket9 Aug 12 '14 at 15:54
  • @Rudolfwm I altered the code to retry locking the surface continuously until DDERR_WASSTILLDRAWING does not occur. It always occurs, even after several seconds of attempts. – Techrocket9 Aug 12 '14 at 15:56
  • @clover With that flag set I get DDERR_SURFACELOST as the hresult. The end result is the same -- no video playback. – Techrocket9 Aug 12 '14 at 16:38
  • After some reading I found that apparently there is no hardware acceleration in RDP. You could fall back to using GDI? you could use the IDirectDrawSurface7::GetDC method and then use GDI from there on. – Rudolfwm Aug 12 '14 at 21:07

0 Answers0