Write an RDP client that dumps the pixels of the screen

烈酒焚心 提交于 2019-12-03 03:29:38

Well you could try to this (disclaimer untested pseudo code):

HGDI_DC memDC = gdi_CreateCompatibleDC ( hDC );
HGDI_BITMAP memBM = gdi_CreateCompatibleBitmap ( hDC, screenWidth, screenHeight );
gdi_SelectObject ( memDC, memBM );
gdi_BitBlt(memDC, 0, 0, screenWidth, screenHeight, hDC, 0, 0, GDI_SRCCOPY);

Now you should have in memBM->data the complete array of pixel data. memBM->data has the following size: memBM->width * memBM->height * memBM->bytesPerPixel

Hope that this helps you at least somewhat.

This should be fairly easy to do in a very efficient way using libfreerdp-gdi. FreeRDP can render everything to a software buffer which you can then dump to a file, and you can do this entirely in memory, without an X11 environment, if you wish. Since Linux is mentioned, one quick way to get started would be to use xfreerdp with the /gdi:sw option to make use of libfreerdp-gdi (the default is to use an X11-based implementation) and to then dump the pixels as updates come in. You can hook yourself in xf_sw_end_paint, which is called at the end of an array of updates. You have access to the invalid region and the pixel buffer (all under the rdpGdi* gdi structure). Important fields are gdi->primary_buffer, gdi->dstBpp, gdi->bytesPerPixel, gdi->width and gdi->height. In most cases you will get an XRGB32 buffer, which is easy to deal with. In doubt, take a look at gdi_init() for the initialization of the internal buffer.

If you run a VNC X server and start the RDP client fullscreen inside it (with no window manager etc.), the drawing sequence should be something like:

  1. RDP client receives an update from the remote session
  2. RDP client translates update into X11 messages, most likely sent over the shared memory transport
  3. VNC server receives X11 requests and uses them to render a bitmap

so the overhead should just be the X11 protocol, which is admittedly clunky but should at least be sent through a shared memory segment.

Honestly, I'd try this zero coding approach first, and see if performance is really a problem.

WebRTC may have some code you can look at to help, like the screen capturer or window capturer.

The desktop capturer is more complicated because it does (1) diffing to capture minimal contents, and (2) captures the mouse as well. Since the desktop is just a special "window", as retrieved with ::GetDesktopWindow(), and its DC can be retrieved with that window or just GetDC(NULL), you can use the window capturer and ignore the more complicated bits. Check the window capturer's Capture function for the details, as well as some helpful hints around handling Aero and other compositing/offscreen issues.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!