From 4e8ad76edb2079aa885ccf6730bcb8cf4e11ed38 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Wed, 30 Nov 2016 10:07:58 +0000 Subject: [PATCH] New upstream version 2.0.0~gite60d0d5 --- CMakeLists.txt | 164 +- ChangeLog | 2438 +++++++ channels/CMakeLists.txt | 12 +- channels/audin/client/CMakeLists.txt | 2 +- channels/audin/client/alsa/audin_alsa.c | 271 +- channels/audin/client/audin_main.c | 34 +- channels/audin/client/audin_main.h | 4 +- channels/audin/client/mac/audin_mac.c | 13 +- .../audin/client/opensles/audin_opensl_es.c | 8 +- channels/audin/client/opensles/opensl_io.c | 421 +- channels/audin/client/opensles/opensl_io.h | 76 +- channels/audin/client/oss/audin_oss.c | 152 +- channels/audin/client/pulse/audin_pulse.c | 6 +- channels/audin/client/winmm/CMakeLists.txt | 4 +- channels/audin/client/winmm/audin_winmm.c | 4 +- channels/audin/server/audin.c | 194 +- channels/client/CMakeLists.txt | 4 +- channels/client/addin.c | 24 + channels/cliprdr/client/CMakeLists.txt | 2 +- channels/cliprdr/client/cliprdr_format.c | 6 +- channels/cliprdr/client/cliprdr_main.c | 582 +- channels/cliprdr/client/cliprdr_main.h | 9 +- channels/cliprdr/server/cliprdr_main.c | 512 +- channels/disp/client/CMakeLists.txt | 2 +- channels/disp/client/disp_main.c | 6 +- channels/drdynvc/client/CMakeLists.txt | 4 +- channels/drdynvc/client/drdynvc_main.c | 549 +- channels/drdynvc/client/drdynvc_main.h | 3 +- channels/drdynvc/server/drdynvc_main.c | 37 +- channels/drive/client/CMakeLists.txt | 2 +- channels/drive/client/dirent.h | 4 +- channels/drive/client/drive_file.c | 9 +- channels/drive/client/drive_main.c | 177 +- channels/echo/client/CMakeLists.txt | 2 +- channels/echo/client/echo_main.c | 2 +- channels/echo/client/echo_main.h | 4 +- channels/echo/server/echo_main.c | 115 +- channels/encomsp/client/CMakeLists.txt | 2 +- channels/encomsp/client/encomsp_main.c | 477 +- channels/encomsp/client/encomsp_main.h | 2 +- channels/encomsp/server/encomsp_main.c | 99 +- channels/parallel/client/CMakeLists.txt | 2 +- channels/parallel/client/parallel_main.c | 73 +- channels/printer/client/CMakeLists.txt | 4 +- channels/printer/client/printer_main.c | 124 +- channels/printer/client/printer_win.h | 4 +- channels/rail/client/CMakeLists.txt | 2 +- channels/rail/client/rail_main.c | 387 +- channels/rail/client/rail_main.h | 2 +- channels/rail/client/rail_orders.c | 66 +- channels/rdpdr/client/CMakeLists.txt | 2 +- channels/rdpdr/client/rdpdr_main.c | 814 ++- channels/rdpdr/client/rdpdr_main.h | 2 +- channels/rdpdr/server/rdpdr_main.c | 931 +-- channels/rdpei/client/CMakeLists.txt | 2 +- channels/rdpei/client/rdpei_main.c | 235 +- channels/rdpei/client/rdpei_main.h | 4 +- channels/rdpei/server/rdpei_main.c | 16 +- channels/rdpgfx/CMakeLists.txt | 3 + channels/rdpgfx/client/CMakeLists.txt | 6 +- channels/rdpgfx/client/rdpgfx_codec.c | 20 +- channels/rdpgfx/client/rdpgfx_codec.h | 3 +- channels/rdpgfx/client/rdpgfx_main.c | 521 +- channels/rdpgfx/{client => }/rdpgfx_common.c | 21 +- channels/rdpgfx/{client => }/rdpgfx_common.h | 21 +- channels/rdpgfx/server/CMakeLists.txt | 34 + channels/rdpgfx/server/rdpgfx_main.c | 1666 +++++ channels/rdpgfx/server/rdpgfx_main.h | 40 + channels/rdpsnd/client/CMakeLists.txt | 2 +- channels/rdpsnd/client/alsa/rdpsnd_alsa.c | 4 +- channels/rdpsnd/client/ios/rdpsnd_ios.c | 2 +- channels/rdpsnd/client/mac/rdpsnd_mac.c | 7 +- channels/rdpsnd/client/opensles/opensl_io.c | 419 +- channels/rdpsnd/client/opensles/opensl_io.h | 123 +- .../rdpsnd/client/opensles/rdpsnd_opensles.c | 147 +- channels/rdpsnd/client/oss/rdpsnd_oss.c | 2 +- channels/rdpsnd/client/pulse/rdpsnd_pulse.c | 4 +- channels/rdpsnd/client/rdpsnd_main.c | 568 +- channels/rdpsnd/client/rdpsnd_main.h | 4 +- channels/rdpsnd/client/winmm/CMakeLists.txt | 2 +- channels/rdpsnd/client/winmm/rdpsnd_winmm.c | 5 +- channels/rdpsnd/server/rdpsnd_main.c | 346 +- channels/rdpsnd/server/rdpsnd_main.h | 1 + channels/remdesk/client/CMakeLists.txt | 2 +- channels/remdesk/client/remdesk_main.c | 406 +- channels/remdesk/client/remdesk_main.h | 2 +- channels/remdesk/server/remdesk_main.c | 214 +- channels/serial/client/CMakeLists.txt | 2 +- channels/serial/client/serial_main.c | 339 +- channels/server/channels.c | 3 + channels/smartcard/client/smartcard_main.c | 142 +- .../smartcard/client/smartcard_operations.c | 111 +- channels/smartcard/client/smartcard_pack.c | 126 +- channels/tsmf/client/CMakeLists.txt | 2 +- channels/tsmf/client/alsa/tsmf_alsa.c | 2 +- channels/tsmf/client/ffmpeg/CMakeLists.txt | 2 +- channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c | 2 +- .../tsmf/client/gstreamer/tsmf_gstreamer.c | 2 +- channels/tsmf/client/oss/tsmf_oss.c | 2 +- channels/tsmf/client/pulse/tsmf_pulse.c | 2 +- channels/tsmf/client/tsmf_ifman.c | 4 +- channels/tsmf/client/tsmf_main.c | 2 +- channels/tsmf/client/tsmf_media.c | 340 +- channels/tsmf/client/tsmf_types.h | 6 +- channels/urbdrc/CMakeLists.txt | 5 + channels/urbdrc/client/CMakeLists.txt | 2 +- channels/urbdrc/client/libusb/CMakeLists.txt | 2 +- .../urbdrc/client/libusb/libusb_udevman.c | 2 +- channels/urbdrc/client/urbdrc_main.c | 18 +- channels/urbdrc/client/urbdrc_types.h | 50 +- ci/cmake-preloads/config-linux-all.txt | 3 +- ci/cmake-preloads/config-windows.txt | 2 +- client/CMakeLists.txt | 4 +- client/DirectFB/dfreerdp.c | 126 +- client/Sample/freerdp.c | 53 +- client/Wayland/CMakeLists.txt | 2 + client/Wayland/wlf_channels.c | 118 + client/Wayland/wlf_channels.h | 42 + client/Wayland/wlf_input.h | 15 +- client/Wayland/wlfreerdp.c | 373 +- client/Wayland/wlfreerdp.h | 13 +- client/X11/.gitignore | 2 +- client/X11/CMakeLists.txt | 9 +- client/X11/generate_argument_docbook.c | 26 +- client/X11/xf_client.c | 742 +- client/X11/xf_cliprdr.c | 413 +- client/X11/xf_event.c | 279 +- client/X11/xf_gdi.c | 931 +-- client/X11/xf_gdi.h | 4 +- client/X11/xf_gfx.c | 1142 +-- client/X11/xf_gfx.h | 23 +- client/X11/xf_graphics.c | 390 +- client/X11/xf_graphics.h | 5 + client/X11/xf_input.c | 105 +- client/X11/xf_keyboard.c | 75 +- client/X11/xf_monitor.c | 101 +- client/X11/xf_rail.c | 228 +- client/X11/xf_window.c | 346 +- client/X11/xfreerdp-envvar.1.xml | 15 + client/X11/xfreerdp.1.xml.in | 3 + client/X11/xfreerdp.h | 19 +- client/common/CMakeLists.txt | 3 - client/common/client.c | 134 +- client/common/cmdline.c | 577 +- client/freerdp-client.pc.in | 2 +- cmake/AndroidToolchain.cmake | 907 +-- cmake/ConfigOptions.cmake | 16 +- cmake/ConfigOptionsiOS.cmake | 1 + cmake/FindOpenSLES.cmake | 4 - cmake/FindUUID.cmake | 182 +- config.h.in | 3 +- docs/Doxyfile | 2 +- docs/README.android | 10 +- include/freerdp/addin.h | 16 +- include/freerdp/altsec.h | 36 +- include/freerdp/api.h | 52 +- include/freerdp/build-config.h.in | 2 +- include/freerdp/cache/bitmap.h | 5 - include/freerdp/cache/brush.h | 6 +- include/freerdp/cache/cache.h | 4 - include/freerdp/cache/glyph.h | 6 - include/freerdp/cache/nine_grid.h | 3 - include/freerdp/cache/offscreen.h | 5 +- include/freerdp/cache/palette.h | 3 - include/freerdp/cache/pointer.h | 3 - include/freerdp/channels/channels.h | 30 +- include/freerdp/channels/rdpdr.h | 14 +- include/freerdp/channels/rdpgfx.h | 43 +- include/freerdp/channels/wtsvc.h | 9 + include/freerdp/client/rdpgfx.h | 67 +- include/freerdp/codec/clear.h | 22 +- include/freerdp/codec/color.h | 1237 ++-- include/freerdp/codec/interleaved.h | 31 +- include/freerdp/codec/nsc.h | 48 +- include/freerdp/codec/planar.h | 47 +- include/freerdp/codec/progressive.h | 46 +- include/freerdp/codec/region.h | 44 +- include/freerdp/codec/rfx.h | 47 +- include/freerdp/codec/zgfx.h | 13 +- include/freerdp/codecs.h | 3 +- include/freerdp/constants.h | 17 +- include/freerdp/crypto/crypto.h | 2 +- include/freerdp/freerdp.h | 81 +- include/freerdp/gdi/16bpp.h | 44 - include/freerdp/gdi/32bpp.h | 44 - include/freerdp/gdi/8bpp.h | 44 - include/freerdp/gdi/bitmap.h | 44 +- include/freerdp/gdi/dc.h | 4 +- include/freerdp/gdi/gdi.h | 426 +- include/freerdp/gdi/gfx.h | 6 +- include/freerdp/gdi/pen.h | 7 +- include/freerdp/gdi/region.h | 43 +- include/freerdp/gdi/shape.h | 20 +- include/freerdp/graphics.h | 67 +- include/freerdp/peer.h | 53 +- include/freerdp/pointer.h | 15 +- include/freerdp/primary.h | 54 +- include/freerdp/primitives.h | 229 +- include/freerdp/secondary.h | 21 +- include/freerdp/server/rdpgfx.h | 100 + include/freerdp/server/rdpsnd.h | 3 + include/freerdp/server/shadow.h | 108 +- include/freerdp/settings.h | 28 +- include/freerdp/svc.h | 22 +- include/freerdp/update.h | 22 +- include/freerdp/utils/signal.h | 10 +- libfreerdp/CMakeLists.txt | 2 - libfreerdp/cache/bitmap.c | 252 +- libfreerdp/cache/brush.c | 17 +- libfreerdp/cache/cache.c | 47 +- libfreerdp/cache/glyph.c | 674 +- libfreerdp/cache/nine_grid.c | 10 +- libfreerdp/cache/offscreen.c | 52 +- libfreerdp/cache/palette.c | 6 +- libfreerdp/cache/pointer.c | 165 +- libfreerdp/codec/clear.c | 1550 +++-- libfreerdp/codec/color.c | 3873 +--------- libfreerdp/codec/h264.c | 743 +- libfreerdp/codec/include/bitmap.c | 132 +- libfreerdp/codec/interleaved.c | 251 +- libfreerdp/codec/nsc.c | 183 +- libfreerdp/codec/nsc_encode.c | 245 +- libfreerdp/codec/nsc_encode.h | 7 +- libfreerdp/codec/nsc_sse2.c | 298 +- libfreerdp/codec/nsc_sse2.h | 9 +- libfreerdp/codec/planar.c | 676 +- libfreerdp/codec/progressive.c | 718 +- libfreerdp/codec/region.c | 42 +- libfreerdp/codec/rfx.c | 594 +- libfreerdp/codec/rfx_decode.c | 125 +- libfreerdp/codec/rfx_decode.h | 4 +- libfreerdp/codec/rfx_differential.h | 5 +- libfreerdp/codec/rfx_dwt.h | 5 +- libfreerdp/codec/rfx_encode.c | 159 +- libfreerdp/codec/rfx_encode.h | 3 +- libfreerdp/codec/rfx_neon.h | 9 +- libfreerdp/codec/rfx_quantization.h | 10 +- libfreerdp/codec/rfx_rlgr.c | 12 +- libfreerdp/codec/rfx_rlgr.h | 7 +- libfreerdp/codec/rfx_sse2.h | 9 +- libfreerdp/codec/rfx_types.h | 6 +- libfreerdp/codec/test/TestFreeRDPCodecClear.c | 174 +- .../codec/test/TestFreeRDPCodecPlanar.c | 6199 ++++++++--------- .../codec/test/TestFreeRDPCodecProgressive.c | 397 +- libfreerdp/codec/test/TestFreeRDPCodecZGfx.c | 209 +- libfreerdp/codec/test/TestFreeRDPRegion.c | 90 +- libfreerdp/codec/xcrush.c | 28 +- libfreerdp/codec/zgfx.c | 120 +- libfreerdp/common/addin.c | 238 +- libfreerdp/common/assistance.c | 50 +- libfreerdp/common/settings.c | 21 + libfreerdp/core/activation.h | 45 +- libfreerdp/core/autodetect.c | 2 +- libfreerdp/core/autodetect.h | 24 +- libfreerdp/core/bulk.h | 17 +- libfreerdp/core/capabilities.c | 1263 ++-- libfreerdp/core/capabilities.h | 16 +- libfreerdp/core/certificate.c | 25 +- libfreerdp/core/certificate.h | 36 +- libfreerdp/core/channels.c | 20 +- libfreerdp/core/channels.h | 10 +- libfreerdp/core/client.c | 605 +- libfreerdp/core/client.h | 21 +- libfreerdp/core/codecs.c | 17 +- libfreerdp/core/connection.c | 30 +- libfreerdp/core/connection.h | 44 +- libfreerdp/core/errinfo.h | 3 +- libfreerdp/core/fastpath.h | 36 +- libfreerdp/core/freerdp.c | 284 +- libfreerdp/core/gateway/http.c | 47 +- libfreerdp/core/gateway/http.h | 56 +- libfreerdp/core/gateway/ncacn_http.h | 17 +- libfreerdp/core/gateway/ntlm.c | 12 +- libfreerdp/core/gateway/ntlm.h | 17 +- libfreerdp/core/gateway/rdg.c | 47 +- libfreerdp/core/gateway/rdg.h | 13 +- libfreerdp/core/gateway/rpc.h | 53 +- libfreerdp/core/gateway/rpc_bind.h | 14 +- libfreerdp/core/gateway/rpc_client.h | 26 +- libfreerdp/core/gateway/rpc_fault.h | 5 +- libfreerdp/core/gateway/rts.h | 115 +- libfreerdp/core/gateway/rts_signature.h | 114 +- libfreerdp/core/gateway/tsg.c | 47 +- libfreerdp/core/gateway/tsg.h | 32 +- libfreerdp/core/gcc.c | 442 +- libfreerdp/core/gcc.h | 94 +- libfreerdp/core/graphics.c | 168 +- .../prim_YUV.h => core/graphics.h} | 18 +- libfreerdp/core/heartbeat.h | 5 +- libfreerdp/core/info.c | 53 +- libfreerdp/core/info.h | 26 +- libfreerdp/core/input.c | 103 +- libfreerdp/core/input.h | 40 +- libfreerdp/core/license.c | 7 +- libfreerdp/core/license.h | 74 +- libfreerdp/core/listener.c | 30 - libfreerdp/core/mcs.h | 60 +- libfreerdp/core/message.c | 162 +- libfreerdp/core/message.h | 24 +- libfreerdp/core/multitransport.h | 7 +- libfreerdp/core/nego.c | 31 +- libfreerdp/core/nego.h | 77 +- libfreerdp/core/nla.c | 62 +- libfreerdp/core/nla.h | 17 +- libfreerdp/core/orders.c | 1582 ++--- libfreerdp/core/orders.h | 235 +- libfreerdp/core/peer.c | 142 +- libfreerdp/core/rdp.c | 43 +- libfreerdp/core/rdp.h | 79 +- libfreerdp/core/redirection.c | 4 +- libfreerdp/core/redirection.h | 14 +- libfreerdp/core/security.c | 436 +- libfreerdp/core/security.h | 43 +- libfreerdp/core/server.c | 439 +- libfreerdp/core/server.h | 242 +- libfreerdp/core/settings.c | 689 +- libfreerdp/core/surface.c | 8 +- libfreerdp/core/surface.h | 10 +- libfreerdp/core/tcp.c | 160 +- libfreerdp/core/tcp.h | 10 +- libfreerdp/core/test/TestConnect.c | 96 +- libfreerdp/core/timezone.h | 10 +- libfreerdp/core/tpdu.h | 19 +- libfreerdp/core/tpkt.h | 7 +- libfreerdp/core/transport.c | 208 +- libfreerdp/core/transport.h | 64 +- libfreerdp/core/update.c | 693 +- libfreerdp/core/update.h | 57 +- libfreerdp/core/window.h | 8 +- libfreerdp/crypto/CMakeLists.txt | 3 +- libfreerdp/crypto/certificate.c | 4 +- libfreerdp/crypto/crypto.c | 49 +- libfreerdp/crypto/opensslcompat.c | 44 + libfreerdp/crypto/opensslcompat.h | 65 + libfreerdp/crypto/tls.c | 491 +- libfreerdp/gdi/16bpp.c | 1152 --- libfreerdp/gdi/32bpp.c | 1253 ---- libfreerdp/gdi/8bpp.c | 1068 --- libfreerdp/gdi/CMakeLists.txt | 4 - libfreerdp/gdi/bitmap.c | 449 +- libfreerdp/gdi/brush.c | 849 ++- {include/freerdp => libfreerdp}/gdi/brush.h | 25 +- libfreerdp/gdi/clipping.c | 36 +- .../freerdp => libfreerdp}/gdi/clipping.h | 16 +- libfreerdp/gdi/dc.c | 56 +- libfreerdp/gdi/drawing.c | 28 +- {include/freerdp => libfreerdp}/gdi/drawing.h | 20 +- libfreerdp/gdi/gdi.c | 1161 ++- libfreerdp/gdi/gdi.h | 71 +- libfreerdp/gdi/gfx.c | 757 +- libfreerdp/gdi/graphics.c | 364 +- libfreerdp/gdi/graphics.h | 14 +- libfreerdp/gdi/include/line.c | 118 - libfreerdp/gdi/line.c | 201 +- {include/freerdp => libfreerdp}/gdi/line.h | 20 +- libfreerdp/gdi/palette.c | 130 - libfreerdp/gdi/pen.c | 27 +- libfreerdp/gdi/region.c | 106 +- libfreerdp/gdi/shape.c | 248 +- libfreerdp/gdi/test/CMakeLists.txt | 7 +- libfreerdp/gdi/test/TestGdiBitBlt.c | 1578 +---- libfreerdp/gdi/test/TestGdiClip.c | 81 +- libfreerdp/gdi/test/TestGdiCreate.c | 253 +- libfreerdp/gdi/test/TestGdiEllipse.c | 170 +- libfreerdp/gdi/test/TestGdiLine.c | 787 +-- libfreerdp/gdi/test/TestGdiRect.c | 62 +- libfreerdp/gdi/test/TestGdiRop3.c | 37 +- libfreerdp/gdi/test/helpers.c | 141 + libfreerdp/gdi/test/helpers.h | 39 + libfreerdp/locale/keyboard_sun.h | 4 +- libfreerdp/locale/keyboard_x11.h | 5 +- libfreerdp/locale/keyboard_xkbfile.h | 10 +- libfreerdp/locale/liblocale.h | 8 +- libfreerdp/locale/locale.c | 18 +- libfreerdp/locale/xkb_layout_ids.h | 4 +- libfreerdp/primitives/prim_16to32bpp.c | 137 - libfreerdp/primitives/prim_16to32bpp.h | 36 - libfreerdp/primitives/prim_16to32bpp_opt.c | 280 - libfreerdp/primitives/prim_YCoCg.c | 182 +- libfreerdp/primitives/prim_YCoCg.h | 31 - libfreerdp/primitives/prim_YCoCg_opt.c | 305 +- libfreerdp/primitives/prim_YUV.c | 326 +- libfreerdp/primitives/prim_YUV_opt.c | 440 +- libfreerdp/primitives/prim_add.c | 29 +- libfreerdp/primitives/prim_add.h | 30 - libfreerdp/primitives/prim_add_opt.c | 16 +- libfreerdp/primitives/prim_alphaComp.c | 48 +- libfreerdp/primitives/prim_alphaComp.h | 30 - libfreerdp/primitives/prim_alphaComp_opt.c | 84 +- libfreerdp/primitives/prim_andor.c | 33 +- libfreerdp/primitives/prim_andor.h | 31 - libfreerdp/primitives/prim_andor_opt.c | 19 +- libfreerdp/primitives/prim_colors.c | 226 +- libfreerdp/primitives/prim_colors.h | 33 - libfreerdp/primitives/prim_colors_opt.c | 329 +- libfreerdp/primitives/prim_copy.c | 92 +- libfreerdp/primitives/prim_internal.h | 57 +- libfreerdp/primitives/prim_set.c | 66 +- libfreerdp/primitives/prim_set.h | 34 - libfreerdp/primitives/prim_set_opt.c | 169 +- libfreerdp/primitives/prim_shift.c | 99 +- libfreerdp/primitives/prim_shift.h | 35 - libfreerdp/primitives/prim_shift_opt.c | 26 +- libfreerdp/primitives/prim_sign.c | 21 +- libfreerdp/primitives/prim_sign.h | 30 - libfreerdp/primitives/prim_sign_opt.c | 83 +- libfreerdp/primitives/prim_templates.h | 720 +- libfreerdp/primitives/primitives.c | 81 +- libfreerdp/primitives/test/CMakeLists.txt | 1 - .../primitives/test/TestPrimitives16to32bpp.c | 211 - .../primitives/test/TestPrimitivesAdd.c | 137 +- .../primitives/test/TestPrimitivesAlphaComp.c | 276 +- .../primitives/test/TestPrimitivesAndOr.c | 281 +- .../primitives/test/TestPrimitivesColors.c | 236 +- .../primitives/test/TestPrimitivesCopy.c | 89 +- .../primitives/test/TestPrimitivesSet.c | 468 +- .../primitives/test/TestPrimitivesShift.c | 468 +- .../primitives/test/TestPrimitivesSign.c | 130 +- .../primitives/test/TestPrimitivesYCbCr.c | 77 +- .../primitives/test/TestPrimitivesYCoCg.c | 135 +- .../primitives/test/TestPrimitivesYUV.c | 186 +- libfreerdp/primitives/test/measure.h | 106 +- libfreerdp/primitives/test/prim_test.c | 105 +- libfreerdp/primitives/test/prim_test.h | 201 +- libfreerdp/utils/msusb.c | 173 +- libfreerdp/utils/ringbuffer.c | 52 +- libfreerdp/utils/signal.c | 21 +- .../freerdp-nightly/freerdp-nightly.install | 1 + packaging/deb/freerdp-nightly/rules | 2 +- packaging/rpm/freerdp-nightly.spec | 3 +- rdtk/librdtk/rdtk_nine_patch.c | 2 +- rdtk/librdtk/test/TestRdTkNinePatch.c | 48 +- scripts/0001-64bit-architecture-support.patch | 26 + scripts/LECHash.c | 140 +- scripts/LOMHash.c | 102 +- scripts/android-build-common.sh | 5 + scripts/android-build-freerdp.sh | 10 +- scripts/android-build-openssl.sh | 7 +- scripts/android-build.conf | 19 +- scripts/autoformat.sh | 2 +- scripts/format_code.sh | 11 +- scripts/regenerate_jni_headers.sh.cmake | 6 - server/Mac/mf_mountain_lion.c | 2 - server/Mac/mf_peer.c | 163 +- server/Sample/sfreerdp.c | 183 +- server/Windows/wf_update.c | 20 +- server/shadow/CMakeLists.txt | 2 + server/shadow/Mac/mac_shadow.c | 392 +- server/shadow/Win/win_dxgi.c | 5 +- server/shadow/Win/win_rdp.c | 108 +- server/shadow/Win/win_shadow.c | 129 +- server/shadow/X11/x11_shadow.c | 430 +- server/shadow/X11/x11_shadow.h | 1 + server/shadow/shadow.c | 10 +- server/shadow/shadow_channels.c | 10 + server/shadow/shadow_channels.h | 1 + server/shadow/shadow_client.c | 1347 ++-- server/shadow/shadow_client.h | 2 +- server/shadow/shadow_encoder.c | 185 +- server/shadow/shadow_encoder.h | 1 + server/shadow/shadow_rdpgfx.c | 53 + .../shadow/shadow_rdpgfx.h | 23 +- server/shadow/shadow_rdpsnd.c | 1 - server/shadow/shadow_server.c | 87 + server/shadow/shadow_subsystem.c | 5 - server/shadow/shadow_surface.c | 27 +- uwac/libuwac/uwac-display.c | 407 +- uwac/libuwac/uwac-input.c | 22 +- uwac/libuwac/uwac-window.c | 431 +- uwac/protocols/xdg-shell.xml | 12 +- winpr/CMakeLists.txt | 24 +- winpr/include/winpr/bitstream.h | 16 +- winpr/include/winpr/crypto.h | 267 +- winpr/include/winpr/debug.h | 1 + winpr/include/winpr/dsparse.h | 2 +- winpr/include/winpr/endian.h | 80 +- winpr/include/winpr/environment.h | 36 +- winpr/include/winpr/file.h | 56 + winpr/include/winpr/ini.h | 1 + winpr/include/winpr/interlocked.h | 112 +- winpr/include/winpr/io.h | 31 + winpr/include/winpr/library.h | 42 +- winpr/include/winpr/nt.h | 27 +- winpr/include/winpr/path.h | 18 +- winpr/include/winpr/platform.h | 1 - winpr/include/winpr/pool.h | 204 +- winpr/include/winpr/print.h | 4 +- winpr/include/winpr/registry.h | 6 +- winpr/include/winpr/rpc.h | 386 +- winpr/include/winpr/sam.h | 4 +- winpr/include/winpr/schannel.h | 2 +- winpr/include/winpr/security.h | 68 +- winpr/include/winpr/sspi.h | 25 +- winpr/include/winpr/string.h | 52 +- winpr/include/winpr/synch.h | 58 +- winpr/include/winpr/sysinfo.h | 81 +- winpr/include/winpr/thread.h | 14 + winpr/include/winpr/user.h | 61 +- winpr/include/winpr/winhttp.h | 2 +- winpr/include/winpr/winpr.h | 54 +- winpr/include/winpr/winsock.h | 7 +- winpr/include/winpr/wlog.h | 99 +- winpr/include/winpr/wtsapi.h | 541 +- winpr/include/winpr/wtypes.h.in | 6 +- winpr/libwinpr/CMakeLists.txt | 2 + winpr/libwinpr/bcrypt/CMakeLists.txt | 1 - winpr/libwinpr/clipboard/clipboard.c | 99 +- winpr/libwinpr/clipboard/clipboard.h | 2 +- winpr/libwinpr/clipboard/synthetic.c | 1 + .../clipboard/test/TestClipboardFormats.c | 23 +- winpr/libwinpr/comm/comm.c | 398 +- winpr/libwinpr/comm/comm.h | 5 +- winpr/libwinpr/comm/comm_io.c | 182 +- winpr/libwinpr/comm/comm_ioctl.c | 8 +- winpr/libwinpr/crt/string.c | 70 +- winpr/libwinpr/crt/test/TestString.c | 18 + .../libwinpr/crt/test/TestUnicodeConversion.c | 16 +- winpr/libwinpr/crt/unicode.c | 4 +- winpr/libwinpr/crt/utf.c | 38 +- winpr/libwinpr/crypto/CMakeLists.txt | 10 + winpr/libwinpr/crypto/cipher.c | 135 +- winpr/libwinpr/crypto/crypto.c | 2 +- winpr/libwinpr/crypto/hash.c | 449 +- winpr/libwinpr/crypto/test/TestCryptoCipher.c | 126 +- winpr/libwinpr/crypto/test/TestCryptoHash.c | 174 +- winpr/libwinpr/dsparse/dsparse.c | 6 +- winpr/libwinpr/environment/environment.c | 75 +- .../TestEnvironmentGetEnvironmentStrings.c | 2 +- winpr/libwinpr/file/file.c | 313 +- winpr/libwinpr/file/generic.c | 2 +- winpr/libwinpr/file/namedPipeClient.c | 7 + winpr/libwinpr/interlocked/interlocked.c | 120 +- .../interlocked/test/TestInterlockedAccess.c | 28 +- .../interlocked/test/TestInterlockedDList.c | 8 +- .../interlocked/test/TestInterlockedSList.c | 10 +- winpr/libwinpr/io/io.c | 104 +- winpr/libwinpr/library/library.c | 68 +- winpr/libwinpr/library/test/CMakeLists.txt | 6 +- .../library/test/TestLibraryA/CMakeLists.txt | 8 +- .../library/test/TestLibraryA/TestLibraryA.c | 11 +- .../library/test/TestLibraryAddDllDirectory.c | 12 - .../library/test/TestLibraryB/CMakeLists.txt | 8 +- .../library/test/TestLibraryB/TestLibraryB.c | 11 +- .../library/test/TestLibraryFreeLibrary.c | 66 - .../test/TestLibraryGetModuleFileName.c | 39 +- .../library/test/TestLibraryGetProcAddress.c | 84 +- .../library/test/TestLibraryLoadLibrary.c | 61 +- .../test/TestLibraryRemoveDllDirectory.c | 12 - .../TestLibrarySetDefaultDllDirectories.c | 12 - winpr/libwinpr/nt/nt.c | 152 +- winpr/libwinpr/nt/test/TestNtCreateFile.c | 46 +- winpr/libwinpr/path/CMakeLists.txt | 4 + .../libwinpr/path/include/PathAllocCombine.c | 4 +- winpr/libwinpr/path/path.c | 3 +- winpr/libwinpr/path/shell.c | 147 +- winpr/libwinpr/path/shell_ios.h | 8 + winpr/libwinpr/path/shell_ios.m | 40 + .../path/test/TestPathCchFindExtension.c | 8 +- winpr/libwinpr/pipe/pipe.c | 56 +- .../pipe/test/TestPipeCreateNamedPipe.c | 43 +- .../test/TestPipeCreateNamedPipeOverlapped.c | 357 +- winpr/libwinpr/pool/CMakeLists.txt | 1 - winpr/libwinpr/pool/callback.c | 49 +- winpr/libwinpr/pool/callback_cleanup.c | 91 +- winpr/libwinpr/pool/callback_environment.c | 203 - winpr/libwinpr/pool/cleanup_group.c | 68 +- winpr/libwinpr/pool/io.c | 12 +- winpr/libwinpr/pool/pool.c | 95 +- winpr/libwinpr/pool/pool.h | 7 +- winpr/libwinpr/pool/synch.c | 8 +- winpr/libwinpr/pool/test/TestPoolWork.c | 13 +- winpr/libwinpr/pool/timer.c | 10 +- winpr/libwinpr/pool/work.c | 129 +- winpr/libwinpr/registry/registry.c | 6 +- winpr/libwinpr/rpc/ndr_private.h | 8 +- winpr/libwinpr/rpc/ndr_simple.c | 29 +- winpr/libwinpr/rpc/ndr_simple.h | 18 +- winpr/libwinpr/rpc/rpc.c | 300 +- winpr/libwinpr/smartcard/smartcard_pcsc.c | 8 + winpr/libwinpr/sspi/NTLM/ntlm.c | 77 +- winpr/libwinpr/sspi/NTLM/ntlm.h | 1 + winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c | 95 +- winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.h | 17 + winpr/libwinpr/sspi/NTLM/ntlm_compute.c | 42 +- winpr/libwinpr/sspi/NTLM/ntlm_message.c | 4 +- winpr/libwinpr/sspi/Negotiate/negotiate.c | 2 +- .../sspi/test/TestEnumerateSecurityPackages.c | 5 +- .../sspi/test/TestQuerySecurityPackageInfo.c | 5 +- winpr/libwinpr/synch/barrier.c | 189 +- winpr/libwinpr/synch/critical.c | 45 - winpr/libwinpr/synch/event.c | 2 + winpr/libwinpr/synch/init.c | 8 +- winpr/libwinpr/synch/mutex.c | 46 +- winpr/libwinpr/synch/semaphore.c | 2 +- winpr/libwinpr/synch/synch.h | 9 - winpr/libwinpr/synch/test/TestSynchBarrier.c | 265 +- winpr/libwinpr/synch/test/TestSynchMutex.c | 245 +- .../libwinpr/synch/test/TestSynchTimerQueue.c | 72 +- .../synch/test/TestSynchWaitableTimer.c | 36 +- .../synch/test/TestSynchWaitableTimerAPC.c | 44 +- winpr/libwinpr/synch/timer.c | 50 +- winpr/libwinpr/synch/wait.c | 38 +- winpr/libwinpr/sysinfo/sysinfo.c | 283 +- winpr/libwinpr/thread/argv.c | 12 +- .../thread/test/TestThreadCreateProcess.c | 73 +- winpr/libwinpr/thread/thread.c | 124 +- winpr/libwinpr/timezone/timezone.c | 1082 +-- winpr/libwinpr/utils/cmdline.c | 8 +- winpr/libwinpr/utils/collections/ArrayList.c | 2 +- winpr/libwinpr/utils/collections/BipBuffer.c | 8 +- winpr/libwinpr/utils/collections/BitStream.c | 2 +- winpr/libwinpr/utils/debug.c | 126 +- winpr/libwinpr/utils/ini.c | 76 +- winpr/libwinpr/utils/lodepng/lodepng.c | 2 +- winpr/libwinpr/utils/ntlm.c | 18 +- winpr/libwinpr/utils/print.c | 8 +- winpr/libwinpr/utils/sam.c | 49 +- winpr/libwinpr/utils/ssl.c | 25 +- winpr/libwinpr/utils/test/TestBacktrace.c | 2 +- winpr/libwinpr/utils/test/TestImage.c | 6 +- winpr/libwinpr/utils/test/TestStream.c | 6 +- winpr/libwinpr/utils/test/TestWLog.c | 26 +- winpr/libwinpr/utils/test/TestWLogCallback.c | 2 +- winpr/libwinpr/utils/wlog/BinaryAppender.c | 6 +- winpr/libwinpr/utils/wlog/CallbackAppender.c | 17 +- winpr/libwinpr/utils/wlog/UdpAppender.c | 4 +- winpr/libwinpr/utils/wlog/wlog.c | 196 +- winpr/libwinpr/winsock/winsock.c | 25 +- winpr/libwinpr/wtsapi/CMakeLists.txt | 3 +- .../test/TestWtsApiEnumerateProcesses.c | 26 +- .../wtsapi/test/TestWtsApiEnumerateSessions.c | 21 +- .../wtsapi/test/TestWtsApiExtraSendMessage.c | 2 +- .../TestWtsApiExtraStartRemoteSessionEx.c | 2 +- .../test/TestWtsApiQuerySessionInformation.c | 54 +- .../test/TestWtsApiSessionNotification.c | 36 +- .../wtsapi/test/TestWtsApiShutdownSystem.c | 12 +- .../wtsapi/test/TestWtsApiWaitSystemEvent.c | 11 +- winpr/libwinpr/wtsapi/wtsapi.c | 91 +- winpr/libwinpr/wtsapi/wtsapi.h | 44 - winpr/libwinpr/wtsapi/wtsapi_win32.c | 76 +- winpr/libwinpr/wtsapi/wtsapi_win32.h | 2 +- winpr/wlog.1 | 149 + 642 files changed, 45074 insertions(+), 44090 deletions(-) mode change 100644 => 100755 channels/disp/client/disp_main.c rename channels/rdpgfx/{client => }/rdpgfx_common.c (98%) rename channels/rdpgfx/{client => }/rdpgfx_common.h (58%) create mode 100644 channels/rdpgfx/server/CMakeLists.txt create mode 100644 channels/rdpgfx/server/rdpgfx_main.c create mode 100644 channels/rdpgfx/server/rdpgfx_main.h create mode 100644 client/Wayland/wlf_channels.c create mode 100644 client/Wayland/wlf_channels.h create mode 100644 client/X11/xfreerdp-envvar.1.xml delete mode 100644 include/freerdp/gdi/16bpp.h delete mode 100644 include/freerdp/gdi/32bpp.h delete mode 100644 include/freerdp/gdi/8bpp.h create mode 100644 include/freerdp/server/rdpgfx.h rename libfreerdp/{primitives/prim_YUV.h => core/graphics.h} (58%) create mode 100644 libfreerdp/crypto/opensslcompat.c create mode 100644 libfreerdp/crypto/opensslcompat.h delete mode 100644 libfreerdp/gdi/16bpp.c delete mode 100644 libfreerdp/gdi/32bpp.c delete mode 100644 libfreerdp/gdi/8bpp.c rename {include/freerdp => libfreerdp}/gdi/brush.h (64%) rename {include/freerdp => libfreerdp}/gdi/clipping.h (64%) rename {include/freerdp => libfreerdp}/gdi/drawing.h (63%) delete mode 100644 libfreerdp/gdi/include/line.c rename {include/freerdp => libfreerdp}/gdi/line.h (60%) delete mode 100644 libfreerdp/gdi/palette.c create mode 100644 libfreerdp/gdi/test/helpers.c create mode 100644 libfreerdp/gdi/test/helpers.h delete mode 100644 libfreerdp/primitives/prim_16to32bpp.c delete mode 100644 libfreerdp/primitives/prim_16to32bpp.h delete mode 100644 libfreerdp/primitives/prim_16to32bpp_opt.c delete mode 100644 libfreerdp/primitives/prim_YCoCg.h delete mode 100644 libfreerdp/primitives/prim_add.h delete mode 100644 libfreerdp/primitives/prim_alphaComp.h delete mode 100644 libfreerdp/primitives/prim_andor.h delete mode 100644 libfreerdp/primitives/prim_colors.h delete mode 100644 libfreerdp/primitives/prim_set.h delete mode 100644 libfreerdp/primitives/prim_shift.h delete mode 100644 libfreerdp/primitives/prim_sign.h delete mode 100644 libfreerdp/primitives/test/TestPrimitives16to32bpp.c create mode 100644 scripts/0001-64bit-architecture-support.patch delete mode 100755 scripts/regenerate_jni_headers.sh.cmake create mode 100644 server/shadow/shadow_rdpgfx.c rename include/freerdp/gdi/palette.h => server/shadow/shadow_rdpgfx.h (63%) delete mode 100644 winpr/libwinpr/library/test/TestLibraryAddDllDirectory.c delete mode 100644 winpr/libwinpr/library/test/TestLibraryFreeLibrary.c delete mode 100644 winpr/libwinpr/library/test/TestLibraryRemoveDllDirectory.c delete mode 100644 winpr/libwinpr/library/test/TestLibrarySetDefaultDllDirectories.c create mode 100644 winpr/libwinpr/path/shell_ios.h create mode 100644 winpr/libwinpr/path/shell_ios.m delete mode 100644 winpr/libwinpr/pool/callback_environment.c delete mode 100644 winpr/libwinpr/wtsapi/wtsapi.h create mode 100644 winpr/wlog.1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 8330721..c4334f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,12 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Include our extra modules set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) +if((CMAKE_SYSTEM_NAME MATCHES "WindowsStore") AND (CMAKE_SYSTEM_VERSION MATCHES "10.0")) + set(UWP 1) + add_definitions("-D_UWP") + set(CMAKE_WINDOWS_VERSION "WIN10") +endif() + # Check for cmake compatibility (enable/disable features) include(CheckCmakeCompat) @@ -65,7 +71,7 @@ include(CMakePackageConfigHelpers) # Soname versioning set(BUILD_NUMBER 0) if ($ENV{BUILD_NUMBER}) - set(BUILD_NUMBER $ENV{BUILD_NUMBER}) + set(BUILD_NUMBER $ENV{BUILD_NUMBER}) endif() set(WITH_LIBRARY_VERSIONING "ON") set(FREERDP_VERSION_MAJOR "2") @@ -81,6 +87,12 @@ else() endif() set(FREERDP_INCLUDE_DIR "include/freerdp${FREERDP_VERSION_MAJOR}/") +# Compatibility options +if(DEFINED STATIC_CHANNELS) + message(WARNING "STATIC_CHANNELS is obsolete, please use BUILTIN_CHANNELS instead") + set(BUILTIN_CHANNELS ${STATIC_CHANNELS} CACHE BOOL "" FORCE) +endif() + # Make paths absolute if (CMAKE_INSTALL_PREFIX) get_filename_component(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" ABSOLUTE) @@ -90,9 +102,9 @@ if (FREERDP_EXTERNAL_PATH) endif() # Allow to search the host machine for git -if(ANDROID OR IOS) +if(CMAKE_CROSSCOMPILING) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) -endif(ANDROID OR IOS) +endif(CMAKE_CROSSCOMPILING) include(GetGitRevisionDescription) git_get_exact_tag(GIT_REVISION --tags --always) @@ -100,9 +112,9 @@ git_get_exact_tag(GIT_REVISION --tags --always) if (${GIT_REVISION} STREQUAL "n/a") git_rev_parse (GIT_REVISION --short) endif() -if(ANDROID OR IOS) +if(CMAKE_CROSSCOMPILING) SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) -endif(ANDROID OR IOS) +endif(CMAKE_CROSSCOMPILING) message(STATUS "Git Revision ${GIT_REVISION}") @@ -123,11 +135,16 @@ if(NOT DEFINED BUILD_SHARED_LIBS) endif() if(BUILD_TESTING) - set(EXPORT_ALL_SYMBOLS TRUE) + set(EXPORT_ALL_SYMBOLS TRUE) elseif(NOT DEFINED EXPORT_ALL_SYMBOLS) - set(EXPORT_ALL_SYMBOLS FALSE) + set(EXPORT_ALL_SYMBOLS FALSE) endif() +if (EXPORT_ALL_SYMBOLS) +# set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + add_definitions(-DFREERDP_TEST_EXPORTS -DBUILD_TESTING) +endif(EXPORT_ALL_SYMBOLS) + # BSD if(${CMAKE_SYSTEM_NAME} MATCHES "BSD") set(BSD TRUE) @@ -145,7 +162,10 @@ if(MSVC) if(NOT DEFINED MSVC_RUNTIME) set(MSVC_RUNTIME "dynamic") endif() - if(${MSVC_RUNTIME} STREQUAL "static") + if(MSVC_RUNTIME STREQUAL "static") + if(BUILD_SHARED_LIBS) + message(FATAL_ERROR "Static CRT is only supported in a fully static build") + endif() message(STATUS "Use the MSVC static runtime option carefully!") message(STATUS "OpenSSL uses /MD by default, and is very picky") message(STATUS "Random freeing errors are a common sign of runtime issues") @@ -215,20 +235,7 @@ if(CMAKE_COMPILER_IS_GNUCC) endif() endif() if(CMAKE_BUILD_TYPE STREQUAL "Release") - set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG") - - CHECK_C_COMPILER_FLAG (-Wno-builtin-macro-redefined Wno-builtin-macro-redefined) - if(Wno-builtin-macro-redefined) - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-builtin-macro-redefined") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D__FILE__='\"$(subst ${CMAKE_BINARY_DIR}/,,$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<)))\"'") - endif() - - CHECK_CXX_COMPILER_FLAG (-Wno-builtin-macro-redefined Wno-builtin-macro-redefinedCXX) - if(Wno-builtin-macro-redefinedCXX) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wno-builtin-macro-redefined") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D__FILE__='\"$(subst ${CMAKE_BINARY_DIR}/,,$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<)))\"'") - endif() + add_definitions(-DNDEBUG) else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") @@ -238,6 +245,23 @@ if(CMAKE_COMPILER_IS_GNUCC) endif() endif() +# When building with Unix Makefiles and doing any release builds +# try to set __FILE__ to relative paths via a make specific macro +if (CMAKE_GENERATOR MATCHES "Unix Makefile*") + if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + string(TOUPPER ${CMAKE_BUILD_TYPE} UPPER_BUILD_TYPE) + CHECK_C_COMPILER_FLAG (-Wno-builtin-macro-redefined Wno-builtin-macro-redefined) + if(Wno-builtin-macro-redefined) + set(CMAKE_C_FLAGS_${UPPER_BUILD_TYPE} "${CMAKE_C_FLAGS_${UPPER_BUILD_TYPE}} -Wno-builtin-macro-redefined -D__FILE__='\"$(subst ${CMAKE_BINARY_DIR}/,,$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<)))\"'") + endif() + + CHECK_CXX_COMPILER_FLAG (-Wno-builtin-macro-redefined Wno-builtin-macro-redefinedCXX) + if(Wno-builtin-macro-redefinedCXX) + set(CMAKE_CXX_FLAGS_${UPPER_BUILD_TYPE} "${CMAKE_CXX_FLAGS_${UPPER_BUILD_TYPE}} -Wno-builtin-macro-redefined -D__FILE__='\"$(subst ${CMAKE_BINARY_DIR}/,,$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<)))\"'") + endif() + endif() +endif() + if(${CMAKE_C_COMPILER_ID} STREQUAL "Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-macros -Wno-padded") @@ -272,11 +296,31 @@ if(${CMAKE_C_COMPILER_ID} STREQUAL "Clang" OR CMAKE_COMPILER_IS_GNUCC) unset(CMAKE_REQUIRED_FLAGS) endif() + CHECK_C_COMPILER_FLAG ("-fno-omit-frame-pointer" fno-omit-frame-pointer) + if(fno-omit-frame-pointer) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer") + endif() + elseif(WITH_SANITIZE_LEAK) + if (DEFINED CMAKE_REQUIRED_FLAGS) + set(SAVE_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + endif() + set(CMAKE_REQUIRED_FLAGS "-fsanitize=leak") + CHECK_C_COMPILER_FLAG ("-fsanitize=leak" fsanitize-leak) + if(fsanitize-leak) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=leak") + endif() + if (DEFINED SAVE_CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_FLAGS ${SAVE_CMAKE_REQUIRED_FLAGS}) + else() + unset(CMAKE_REQUIRED_FLAGS) + endif() + CHECK_C_COMPILER_FLAG ("-fno-omit-frame-pointer" fno-omit-frame-pointer) if(fno-omit-frame-pointer) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer") endif() endif() + if (WITH_NO_UNDEFINED) if (DEFINED CMAKE_REQUIRED_FLAGS) set(SAVE_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) @@ -315,9 +359,9 @@ if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3") if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_AMD64_") + add_definitions(-D_AMD64_) else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_") + add_definitions(-D_X86_) endif() set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}) @@ -332,9 +376,10 @@ if(MSVC) endif() if(WIN32) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUNICODE -D_UNICODE") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN") + add_definitions(-DUNICODE -D_UNICODE) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + add_definitions(-DWIN32_LEAN_AND_MEAN) + add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS) set(CMAKE_USE_RELATIVE_PATH ON) if (${CMAKE_GENERATOR} MATCHES "NMake Makefile*") @@ -358,14 +403,13 @@ if(WIN32) endif() if(CMAKE_WINDOWS_VERSION STREQUAL "WINXP") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINVER=0x0501 -DWIN32_WINNT=0x0501") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINVER=0x0501 -DWIN32_WINNT=0x0501") + add_definitions(-DWINVER=0x0501 -D_WIN32_WINNT=0x0501) elseif(CMAKE_WINDOWS_VERSION STREQUAL "WIN7") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINVER=0x0601 -DWIN32_WINNT=0x0601") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINVER=0x0601 -DWIN32_WINNT=0x0601") + add_definitions(-DWINVER=0x0601 -D_WIN32_WINNT=0x0601) elseif(CMAKE_WINDOWS_VERSION STREQUAL "WIN8") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINVER=0x0602 -DWIN32_WINNT=0x0602") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINVER=0x0602 -DWIN32_WINNT=0x0602") + add_definitions(-DWINVER=0x0602 -D_WIN32_WINNT=0x0602) + elseif(CMAKE_WINDOWS_VERSION STREQUAL "WIN10") + add_definitions(-DWINVER=0x0A00 -D_WIN32_WINNT=0x0A00) endif() if (FREERDP_EXTERNAL_SSL_PATH) @@ -377,8 +421,7 @@ if(IOS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isysroot ${CMAKE_IOS_SDK_ROOT} -g") endif() -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS -DFREERDP_EXPORTS") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINPR_EXPORTS -DFREERDP_EXPORTS") +add_definitions(-DWINPR_EXPORTS -DFREERDP_EXPORTS) # Include files if(NOT IOS) @@ -449,6 +492,8 @@ endif() if(ANDROID) set(WITH_LIBRARY_VERSIONING "OFF") + set_property( GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ${ANDROID_LIBRARY_USE_LIB64_PATHS} ) + if (${ANDROID_ABI} STREQUAL "armeabi") set (WITH_NEON OFF) endif() @@ -484,12 +529,22 @@ endif() set(CMAKE_THREAD_PREFER_PTHREAD TRUE) -if(NOT IOS AND NOT ANDROID) +if(NOT IOS) find_package(Threads REQUIRED) endif() if(NOT WIN32) - check_library_exists(pthread pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK) + CHECK_SYMBOL_EXISTS(pthread_mutex_timedlock pthread.h HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL) + if (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL) + CHECK_LIBRARY_EXISTS(pthread pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB) + endif (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL) + if (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB) + CHECK_LIBRARY_EXISTS(pthreads pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS) + endif (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB) + + if (HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS) + set(HAVE_PTHREAD_MUTEX_TIMEDLOCK ON) + endif (HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS) endif() if(WITH_VALGRIND_MEMCHECK) @@ -701,6 +756,7 @@ endif() if(OPENSSL_FOUND) add_definitions("-DWITH_OPENSSL") + message(STATUS "Using OpenSSL Version: ${OPENSSL_VERSION}") endif() if(MBEDTLS_FOUND) @@ -711,15 +767,21 @@ if (TARGET_ARCH MATCHES "sparc") set(HAVE_ALIGNED_REQUIRED 1) endif() -# Path to put FreeRDP data -set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp${FREERDP_VERSION_MAJOR}") - -# Path to put plugins - -set(FREERDP_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}") - -set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}") -set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}") +# Android expects all libraries to be loadable +# without paths. +if (ANDROID) + set(FREERDP_DATA_PATH "share") + set(FREERDP_INSTALL_PREFIX ".") + set(FREERDP_LIBRARY_PATH ".") + set(FREERDP_PLUGIN_PATH ".") + set(FREERDP_ADDIN_PATH ".") +else (ANDROID) + set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp${FREERDP_VERSION_MAJOR}") + set(FREERDP_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + set(FREERDP_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}") + set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}") + set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}") +endif(ANDROID) # Path to put extensions set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp${FREERDP_VERSION_MAJOR}/extensions") @@ -758,8 +820,6 @@ endif() include(CTest) if(BUILD_TESTING) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_TEST_EXPORTS") - enable_testing() if(MSVC) @@ -812,7 +872,7 @@ include_directories("${CMAKE_BINARY_DIR}/rdtk/include") add_subdirectory(rdtk) if(WAYLAND_FOUND) - add_subdirectory(uwac) + add_subdirectory(uwac) endif() if(BSD) @@ -858,9 +918,9 @@ include(${CMAKE_CPACK_INCLUDE_FILE}) set(FREERDP_BUILD_CONFIG_LIST "") GET_CMAKE_PROPERTY(res VARIABLES) FOREACH(var ${res}) - IF (var MATCHES "^WITH_*|^BUILD_TESTING|^STATIC_CHANNELS|^HAVE_*") - LIST(APPEND FREERDP_BUILD_CONFIG_LIST "${var}=${${var}}") - ENDIF() + IF (var MATCHES "^WITH_*|^BUILD_TESTING|^BUILTIN_CHANNELS|^HAVE_*") + LIST(APPEND FREERDP_BUILD_CONFIG_LIST "${var}=${${var}}") + ENDIF() ENDFOREACH() string(REPLACE ";" " " FREERDP_BUILD_CONFIG "${FREERDP_BUILD_CONFIG_LIST}") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/buildflags.h.in ${CMAKE_CURRENT_BINARY_DIR}/buildflags.h) diff --git a/ChangeLog b/ChangeLog index 67bad0a..26533a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,2353 @@ +2016-11-28 10:01:15 +0100 MartinHaimberger (e60d0d5) + + * Merge pull request #3629 from nfedera/fix-wlog-format-and-arguments + +2016-11-25 12:40:11 +0100 Norbert Federa (c6e6b44) + + * countless WLog/printf format specifier fixes + +2016-11-25 13:44:23 +0100 akallabeth (215fbe8) + + * Merge pull request #3613 from mfleisz/rlgr_api_revamp + +2016-11-25 13:41:07 +0100 Martin Fleisz (9e474b4) + + * Merge pull request #3623 from akallabeth/mouse_wheel_event_check + +2016-11-25 12:06:52 +0100 Bernhard Miklautz (90c02ad) + + * Merge pull request #3625 from mfleisz/hash_comp_fix + +2016-11-25 11:50:28 +0100 Martin Fleisz (971c853) + + * winpr: Fix compile error after #3615 + +2016-11-25 11:49:16 +0100 Bernhard Miklautz (e0382e0) + + * Merge pull request #3614 from mfleisz/warning_fixes + +2016-11-25 11:12:10 +0100 akallabeth (3e6c54f) + + * Merge pull request #3624 from mfleisz/comp_fix + +2016-11-25 11:07:58 +0100 akallabeth (f234879) + + * Merge pull request #3615 from nfedera/openssl_1.1.0 + +2016-11-25 10:47:00 +0100 Martin Fleisz (cf4b8a1) + + * primitives: Fix compiler error + +2016-11-25 10:39:20 +0100 Norbert Federa (b2ad980) + + * disable ERR_remove_thread_state if not required + +2016-11-25 10:38:56 +0100 Martin Fleisz (506aa78) + + * Merge pull request #3619 from akallabeth/image_copy_ignore_alpha + +2016-11-25 10:21:26 +0100 Martin Fleisz (b16df59) + + * Merge pull request #3618 from akallabeth/x11_scanline_full_fix + +2016-11-24 14:53:19 +0100 Norbert Federa (53bd988) + + * winpr/crypt api changes and memory leak fixes + +2016-11-21 17:28:54 +0100 Norbert Federa (7befab8) + + * Support for OpenSSL 1.1.0 + +2016-11-24 15:45:23 +0100 Martin Fleisz (2a6dbab) + + * Merge pull request #3591 from + akallabeth/android_load_library_workaround + +2016-11-10 10:18:55 +0100 Armin Novak (3f6bd60) + + * Fixed addin loader, prefer system library paths. + +2016-11-24 13:18:41 +0100 Armin Novak (a0fed88) + + * Check hwheel capability before sending mouse event. + +2016-11-24 12:59:30 +0100 Martin Fleisz (0febd9c) + + * Merge pull request #3563 from akallabeth/android_update + +2016-11-24 12:09:35 +0100 Bernhard Miklautz (fa230ce) + + * Merge pull request #3621 from akallabeth/optimized_tests + +2016-11-24 11:58:01 +0100 Bernhard Miklautz (3550d0c) + + * Merge pull request #3620 from mfleisz/wtsapi_fix + +2016-11-24 10:50:16 +0100 Armin Novak (9818ed3) + + * Reduced number of test runs. Fixes 3617. + +2016-11-24 10:37:21 +0100 Armin Novak (b9072bf) + + * Added optimized write functions. + +2016-11-24 10:36:57 +0100 Armin Novak (4cc2918) + + * Added optimized write functions. + +2016-11-24 10:35:36 +0100 Martin Fleisz (d30a138) + + * wtsapi: Fix issue with setting custom API table + +2016-11-24 10:01:45 +0100 Armin Novak (d1e2dd3) + + * Moved format size calculation out of loop. + +2016-11-24 09:42:30 +0100 akallabeth (aaae190) + + * Merge pull request #3610 from FreeRDP/mh-channels-new-api + +2016-11-24 09:27:19 +0100 Armin Novak (1c4c578) + + * Ignore alpha channel in freerdp_image_copy + +2016-11-24 09:02:06 +0100 Armin Novak (3c25ffb) + + * Unified scanline padding function. + +2016-11-23 17:57:47 +0100 Norbert Federa (812def3) + + * Merge pull request #3612 from akallabeth/align_fix + +2016-11-23 17:11:05 +0100 Martin Fleisz (4f1e3d0) + + * codec: Fix some warnings on VC2010 (and probably others too) + +2016-11-23 15:47:32 +0100 Martin Fleisz (faefe54) + + * Merge pull request #3603 from realjiangms/fix_shadow_resize + +2016-11-23 14:22:42 +0100 Martin Fleisz (c112111) + + * codec: Use context functions for rfx decoding + +2016-11-23 04:22:03 -0800 Martin Haimberger (778767c) + + * fixed error + +2016-11-23 13:21:59 +0100 Martin Fleisz (6c9df44) + + * codec: Revamp of rfx rlgr API This PR contains following changes: - + Give rlgr encode/decode APIs a similar interface - Make + rlgr encode API accessible again - Make it possible to + exchange rlgr functions - Make use of RLGR1/3 defines + instead of 0/1 in decoding + +2016-11-23 04:17:56 -0800 Martin Haimberger (7fe28a8) + + * virtualChannel: removed static variable usage from + +2016-11-23 12:54:20 +0100 Armin Novak (61a1c8c) + + * Fixed broken scanline alignment. + +2016-11-22 05:47:20 -0800 Martin Haimberger (d29848f) + + * rdpsnd: using new VirtualChannelEx api + +2016-11-22 03:33:41 -0800 Martin Haimberger (088a04f) + + * rdpdr: using new VirtualChannelEx api + +2016-11-22 03:27:05 -0800 Martin Haimberger (41b1790) + + * remdesk: Using new VirtualChannelEx api + +2016-11-22 03:18:38 -0800 Martin Haimberger (5c4fb88) + + * rail: using new VirtualChannelEx api + +2016-11-22 03:08:33 -0800 Martin Haimberger (2273a15) + + * encomsp: using new VirtualChannelEx api + +2016-11-22 14:00:08 +0100 Martin Fleisz (3f39dc4) + + * Merge pull request #3608 from mfleisz/msvc10_fixes + +2016-11-22 12:12:08 +0100 Martin Fleisz (e45c300) + + * codec: Fix compilation with VS2010 + +2016-11-22 02:33:23 -0800 Martin Haimberger (3daf4f6) + + * cliprdr: using new VirtualChannelEx api + +2016-11-18 12:46:14 +0100 Martin Fleisz (06d4753) + + * Merge pull request #3594 from akallabeth/line_draw_color_format + +2016-11-17 15:41:17 +0100 Martin Fleisz (f8bcd70) + + * Merge pull request #3581 from akallabeth/alignment_fix + +2016-11-17 14:36:02 +0800 zihao.jiang (e3506bf) + + * X11/client: call gdi resize on hw desktop resize. The gdi primary + buffer is used in client/X11/xf_gdi.c, it should be big + enough to hold the full screen update + +2016-11-16 19:27:55 +0100 akallabeth (1571669) + + * Merge pull request #3593 from ccpp/gateway-http-bugfix + +2016-11-16 11:37:14 -0500 Marc-André Moreau (128ce8a) + + * Merge pull request #3597 from awakecoding/tls_channel_fix + +2016-11-16 09:52:24 -0500 Marc-André Moreau (36db0cc) + + * channels: properly handle VirtualChannelEntryEx in static virtual + channel loading + +2016-11-15 12:37:50 -0500 Marc-André Moreau (f74380b) + + * channels/drdynvc: fix channel entry point name + +2016-11-15 11:41:01 -0500 Marc-André Moreau (dee7661) + + * channels: remove thread-local storage usage + +2016-11-15 10:58:38 -0500 Marc-André Moreau (2cce8e9) + + * channels: migrate drdynvc to extended virtual channel API + +2016-11-15 09:09:30 -0500 Marc-André Moreau (2259e91) + + * channels: prepare virtual channel system for extended virtual + channel API + +2016-11-14 16:44:45 -0500 Marc-André Moreau (23eae31) + + * channels: start working on extended virtual channel API + +2016-11-14 15:23:05 -0500 Marc-André Moreau (70c4646) + + * channels: restore global tables for initHandle, openHandle mappings + instead of thread local storage + +2016-11-14 09:36:16 +0100 Armin Novak (1203315) + + * Fixed line drawing color format #3592 + +2016-11-13 03:26:01 +0100 Christian Plattner (b6e97cb) + + * Bugfix in RDP Gateway HTTP: read/skip full HTTP body for non-RPC + responses + +2016-11-10 08:56:34 +0100 akallabeth (f910bbe) + + * Merge pull request #3572 from rjcorrig/maclogin + +2016-11-03 22:50:08 +0100 David Fort (ea24c1f) + + * Merge pull request #3578 from + realjiangms/fix_server_for_limit_frames + +2016-11-03 15:57:35 +0100 Bernhard Miklautz (2ceab37) + + * Merge pull request #3584 from awakecoding/master + +2016-11-03 10:12:48 -0400 Marc-André Moreau (e8004d5) + + * drdynvc: ignore some messages sent for invalid channel ids with MMR + and Windows Server 2012 R2, fix issue #3422 + +2016-11-02 17:58:47 +0100 Martin Fleisz (50c5b40) + + * Merge pull request #3577 from + akallabeth/error_message_channel_thread + +2016-10-31 07:56:10 +0100 Armin Novak (95a3144) + + * Scanline alignment for GFX cache. + +2016-10-29 13:18:17 +0800 zihao.jiang (7676b29) + + * cleanup unnecessary code per comments + +2016-10-29 00:28:10 +0800 zihao.jiang (b58ee58) + + * keeping the old callback and adding the new one at the end of the + struct, so that it can be potentially binary compatible. + +2016-10-27 22:59:16 +0200 Armin Novak (f62d004) + + * Fixed surface alignment. + +2016-10-27 23:43:09 +0800 zihao.jiang (ddc326d) + + * Fix server side code to be aware of rereadEvent + +2016-10-27 14:41:05 +0200 Armin Novak (5bc691c) + + * Improved error handling if channel is missing. + +2016-10-27 14:36:48 +0200 Armin Novak (6276f3d) + + * Added log messages for invalid function call. + +2016-10-21 09:29:51 +0200 David Fort (043243f) + + * Merge pull request #3560 from akallabeth/gfx_10_2 + +2016-10-20 11:22:08 -0400 Robert Corrigan (405e7eb) + + * Code style fixes + +2016-10-20 12:53:23 +0200 akallabeth (a6f4117) + + * Merge pull request #3364 from hardening/limit_frames + +2016-10-20 09:59:54 +0200 Armin Novak (97cbc42) + + * Added reference to capability specifications + +2016-10-14 18:24:14 -0400 Robert Corrigan (91e6255) + + * Run password dialog as a modal sheet and set window title to + server:port + +2016-10-19 15:45:17 +0200 Martin Fleisz (f5a6645) + + * Merge pull request #3571 from akallabeth/clang_fixes + +2016-10-19 13:31:54 +0200 Martin Fleisz (f2abcaa) + + * Merge pull request #3554 from akallabeth/color_refactor + +2016-10-19 12:41:43 +0200 Armin Novak (e9b5b55) + + * directly using FREERDP_PIXEL_FORMAT. + +2016-10-19 11:10:35 +0200 Armin Novak (5211bc0) + + * Fixed NULL dereferences. + +2016-10-19 11:06:47 +0200 Armin Novak (4ceda8a) + + * Fixed uninitialized return. + +2016-10-19 11:06:25 +0200 Armin Novak (5c446dd) + + * Fixed missing NULL checks. + +2016-10-19 11:05:12 +0200 Armin Novak (ab733d7) + + * Fixed NULL pointer dereferences. + +2016-10-19 10:26:01 +0200 Martin Fleisz (92befb0) + + * Merge pull request #3570 from rjcorrig/tz201610 + +2016-10-18 15:28:44 -0400 Robert Corrigan (2973b9c) + + * Updates time zone data to October 2016 + +2016-10-18 17:06:41 +0200 Martin Fleisz (5f90656) + + * Merge pull request #3568 from hardening/wayland_fixes + +2016-10-18 15:45:15 +0200 Martin Fleisz (fc3bda8) + + * Merge pull request #3569 from akallabeth/gdi_resize_fix + +2016-10-18 15:16:58 +0200 Armin Novak (30b5b01) + + * Fixed invalid arguments for gdi_resize_ex + +2016-10-17 18:56:52 +0200 David Fort (02b4b5b) + + * Added a command line parameter to set the time passed in packet + loop + +2016-10-17 11:27:10 +0200 David Fort (237451d) + + * Implement callbacks for version 5 of wl_pointer + +2016-10-17 15:34:17 +0200 David Fort (20344f2) + + * Merge pull request #3567 from mfleisz/file_mode_fix + +2016-10-17 14:49:26 +0200 Martin Fleisz (e8fbdf5) + + * crypto: Remove unneeded update (+) flag from file open mode + +2016-10-17 10:24:30 +0200 Armin Novak (43755c2) + + * Android: fixed visibility, reformatted + +2016-10-17 10:21:05 +0200 Armin Novak (6ca5a13) + + * Android: fixed warnings, reformatted. + +2016-10-17 09:05:54 +0200 Armin Novak (4dfdf83) + + * Updated symbol visibility of GFX channel. + +2016-10-16 15:08:47 +0200 Armin Novak (b6907aa) + + * Deactivated unsupported operations. + +2016-10-16 10:28:06 +0200 Armin Novak (39b624a) + + * GFX: support 10.2 stack. + +2016-10-13 22:02:25 +0200 David Fort (f92860d) + + * Applied astyle formatting + +2016-10-13 22:01:53 +0200 David Fort (9a25538) + + * Updated the astyle formatting + +2016-10-09 22:36:04 +0200 David Fort (60cffef) + + * Release the reread event on transport_free + +2016-10-08 22:37:31 +0200 David Fort (fd7ebdc) + + * Took in account comment remarks + +2016-07-06 18:31:22 +0200 David Fort (03abf19) + + * test-connect: use a random port instead of always 3389 + +2016-07-06 18:30:12 +0200 David Fort (5b08035) + + * sample-server: add a "local only" option to just listen on an UNIX + socket + +2016-05-03 17:24:07 +0200 David Fort (71fd5cc) + + * Limit the time passed in transport check loop + +2016-10-14 12:50:04 +0200 Armin Novak (8ef1808) + + * Adjusted non X11 implementations. + +2016-10-14 10:01:02 +0200 Armin Novak (9c50e1a) + + * Replaced _VF formats with copy flags. + +2016-10-14 10:12:27 +0200 akallabeth (9adc132) + + * Merge pull request #3497 from realjiangms/fix_gfx_win10 + +2016-10-14 10:10:45 +0200 Bernhard Miklautz (da56839) + + * Merge pull request #3544 from akallabeth/multi_warn_fixes + +2016-10-12 11:24:29 +0200 Bernhard Miklautz (d7582b1) + + * Adapt makefile specific file paths + +2016-10-11 11:21:13 +0200 Armin Novak (8fbc885) + + * Removed unused variable. + +2016-10-11 11:20:54 +0200 Armin Novak (d1a28c5) + + * Fixed uninitialized variable. + +2016-10-11 11:20:26 +0200 Armin Novak (99ade05) + + * Fixed uninitialized variable. + +2016-10-11 11:17:22 +0200 Armin Novak (ae56897) + + * Fixed uninitialized variables. + +2016-10-11 11:14:49 +0200 Armin Novak (85e17ad) + + * Fixed uninitialized arguments, WLog tag. + +2016-10-11 11:13:54 +0200 Armin Novak (12aae50) + + * Properly escaping __FILE__ replacement. + +2016-10-13 13:01:53 +0200 Bernhard Miklautz (5a5f091) + + * Merge pull request #3545 from akallabeth/legacy_rfx_fixes + +2016-10-13 10:28:57 +0200 Bernhard Miklautz (de44204) + + * Merge pull request #3537 from akallabeth/gdi_speedup + +2016-10-11 16:13:19 +0200 Armin Novak (79e8a6d) + + * Reverted NSC format, decoded data is always BGRA! + +2016-10-12 17:35:10 +0200 Martin Fleisz (75b5571) + + * Merge pull request #3547 from + realjiangms/fix_after_color_conversion_nsc_server + +2016-10-12 09:32:59 +0200 Armin Novak (714e704) + + * Color format for surface bits unified. + +2016-10-12 09:32:05 +0200 Armin Novak (25c7372) + + * Fixed offset and stride for X11 surface bits. + +2016-10-12 09:21:21 +0200 Armin Novak (985ca17) + + * Respecting tile offsets. + +2016-10-11 18:44:50 +0200 Armin Novak (8286fa4) + + * Fixed format flip and offsets for GDI. + +2016-10-11 23:31:12 +0800 zihao.jiang (5e1f745) + + * Fix nsc server side after color conversion. We use new color format + system and PIXEL_FORMAT_BGRX32 is the unified buffer color + format. Add support for PIXEL_FORMAT_BGRX32 in nsc + +2016-10-11 15:47:32 +0200 Bernhard Miklautz (bd1ec5f) + + * Merge pull request #3538 from akallabeth/mac_server_fix + +2016-10-11 13:10:54 +0200 Armin Novak (c3058ba) + + * Optimized ROP for GDI_SRCCOPY and GDI_DSTCOPY. + +2016-10-11 12:14:52 +0200 Armin Novak (c2787d7) + + * Optimized gdi_FillRect + +2016-10-10 11:25:47 +0200 Armin Novak (c405e15) + + * Inlined heavily used function. + +2016-10-10 11:09:06 +0200 Armin Novak (94c6473) + + * Inlined heavily used functions. + +2016-10-11 14:34:07 +0200 Armin Novak (404ae7d) + + * Fixed Windows 7 RFX issues. + +2016-10-11 13:15:13 +0200 akallabeth (1d03fd3) + + * Merge pull request #3470 from untoldone/master + +2016-10-11 09:44:53 +0200 Bernhard Miklautz (4085d45) + + * Merge pull request #3531 from rjcorrig/macdialogfix + +2016-10-11 09:29:49 +0200 Martin Fleisz (9afc0cc) + + * Merge pull request #3536 from akallabeth/memory_leak_fixes + +2016-10-11 09:25:43 +0200 akallabeth (1b783fd) + + * Merge pull request #3540 from + realjiangms/fix_after_color_conversion_gfx_h264 + +2016-10-11 09:25:19 +0200 akallabeth (1ea2481) + + * Merge pull request #3541 from + realjiangms/fix_after_color_conversion_nsc + +2016-09-09 15:31:21 +0800 zihao.jiang (3fb92ae) + + * server/shadow: Fix black screen with win10 Request full screen + update on RDPGFX_CAPS_ADVERTISE_PDU. Win10 client seems to + clean the screen after gfx channel opened. If there + happens to be no screen update from server, we will get + black screen in mstsc client. + +2016-10-11 01:39:08 +0800 zihao.jiang (34b4bca) + + * Fix nsc client after after color conversion huge fix nsc codec + client doesn't work: 1. We should mark invalid region for + software gdi 2. Checked the code before color conversion + fix, the correct color format should be + PIXEL_FORMAT_BGRX32_VF (corresponds to old + PIXEL_FORMAT_XRGB32_VF) 3. For gdi:hw: xfc->bitmap_buffer + is never used/initialized. However gdi->primary_buffer is + always maintained. So use primary_buffer to hold the + decoded bitmap data + +2016-10-11 00:23:48 +0800 zihao.jiang (ac08f6a) + + * Regression fix: The usage of RDPGFX_SURFACE_COMMAND::format is + changed after color conversion huge fix. Fix server side + rdpgfx code to match the change. + +2016-10-10 16:04:09 +0200 Bernhard Miklautz (aa67398) + + * Merge pull request #3533 from akallabeth/glyph_cache_disable + +2016-10-10 13:34:57 +0200 Armin Novak (c6ae62f) + + * Fixed memory leak in certificate check. + +2016-10-10 12:23:57 +0200 Martin Fleisz (38f9d0f) + + * Merge pull request #3529 from akallabeth/warning_fixes + +2016-10-10 12:10:29 +0200 Armin Novak (cf2ec62) + + * Reformatted file. + +2016-10-10 12:07:27 +0200 Armin Novak (bc39f28) + + * Fixed regression from rebase. + +2016-10-10 11:33:31 +0200 Armin Novak (fa71427) + + * Removed unused function. + +2016-10-10 11:31:57 +0200 Martin Fleisz (06a04a0) + + * Merge pull request #3534 from akallabeth/x11_pointer_color + +2016-10-10 11:28:45 +0200 Martin Fleisz (071b79a) + + * Merge pull request #3535 from akallabeth/leak_check + +2016-10-10 10:38:54 +0200 Armin Novak (eecc4b1) + + * Fixed leak in bitmap handling. + +2016-10-10 10:26:54 +0200 Armin Novak (bc69730) + + * Fixed memory leak in pointer free. + +2016-10-10 09:29:09 +0200 Armin Novak (930045e) + + * Added leak detector option, made conflicting options exclusive. + +2016-10-10 09:19:43 +0200 Armin Novak (249bb12) + + * Fixed pointer color mapping. + +2016-10-10 09:07:28 +0200 Armin Novak (8f75516) + + * Deactivated glyph cache. + +2016-10-10 09:06:05 +0200 Armin Novak (afc4408) + + * Reformatted file. + +2016-10-08 01:39:07 -0400 Robert Corrigan (ecf9eed) + + * Runs Mac password dialog on main UI thread + +2016-10-07 14:11:04 +0200 Armin Novak (7709542) + + * Using C99 compatible variadic macros. + +2016-10-07 14:09:42 +0200 Armin Novak (6fdc872) + + * Fixed comma at end of enum + +2016-10-07 14:08:54 +0200 Armin Novak (1122627) + + * Fixed function argument and variable types. + +2016-10-07 14:08:33 +0200 Armin Novak (fb1dcf2) + + * Fixed invalid const type. + +2016-10-07 14:07:51 +0200 Armin Novak (edacd7c) + + * Thread using proper function pointer type. + +2016-10-07 14:06:46 +0200 Armin Novak (14fcfbb) + + * Addin loader using proper function pointer defines. + +2016-10-07 14:04:40 +0200 Armin Novak (943e295) + + * WLog using C99 compatible variadic macros. + +2016-10-06 16:18:19 +0200 Martin Fleisz (267dea9) + + * Merge pull request #3524 from bmiklautz/cleanup_3381 + +2016-10-06 15:40:11 +0200 Bernhard Miklautz (e54c504) + + * winpr/wait: add missing parameters + +2016-10-06 14:56:26 +0200 Martin Fleisz (38c88d4) + + * Merge pull request #3500 from akallabeth/color_conversion_fix_v6 + +2016-10-06 13:41:52 +0200 Armin Novak (649d270) + + * Fixed GDI_RGN->null initialization. + +2016-10-06 13:31:25 +0200 Armin Novak (8f1adf6) + + * Refactored ClipboardSetData. + +2016-10-06 13:06:20 +0200 Armin Novak (2db0473) + + * Fixed memory leak. + +2016-10-06 13:04:06 +0200 Armin Novak (9d0f753) + + * Fixed use after free. + +2016-10-06 11:05:31 +0200 Armin Novak (cba6766) + + * Added documentation, removed unused function. + +2016-10-06 10:21:00 +0200 Armin Novak (0e2b518) + + * Added color format documentation. + +2016-10-04 17:07:49 +0200 Armin Novak (376dc21) + + * Fixed uninitialized value. + +2016-10-04 16:54:11 +0200 Armin Novak (9a1c608) + + * Unified RFX server color format. + +2016-10-04 16:04:20 +0200 Bernhard Miklautz (ddced3f) + + * Fix compiler warnings + +2016-10-04 15:12:11 +0200 Bernhard Miklautz (143b875) + + * wtsvc: add missing DRDYNVC_STATE_FAILED + +2016-10-04 14:14:39 +0200 Armin Novak (97e8f9e) + + * Fixed broken return check. + +2016-10-04 14:14:01 +0200 Armin Novak (70f3d43) + + * Removed broken return check. + +2016-10-04 14:12:51 +0200 Armin Novak (4fa2bd2) + + * Fixed memory leak and argument checks. + +2016-10-04 10:31:04 +0200 Armin Novak (b03e471) + + * Fixed NULL pointer checks. + +2016-10-04 10:06:27 +0200 Armin Novak (ded84b1) + + * Fixed error message. + +2016-10-04 10:05:27 +0200 Armin Novak (b0b6dce) + + * Fixed NULL pointer checks. + +2016-10-04 09:57:52 +0200 Armin Novak (2cf5f1b) + + * Fixed missing NULL pointer checks. + +2016-10-04 09:00:01 +0200 Armin Novak (0c81f4a) + + * Reformatted file. + +2016-10-04 09:00:01 +0200 Armin Novak (b372d63) + + * Reformatted file. + +2016-10-04 09:00:01 +0200 Armin Novak (86d414b) + + * Reformatted file. + +2016-10-04 09:00:01 +0200 Armin Novak (8e12f0f) + + * Reformatted file. + +2016-10-04 09:00:01 +0200 Armin Novak (1a22cb3) + + * Reformatted file. + +2016-10-04 09:00:01 +0200 Armin Novak (9a34e43) + + * Reformatted file. + +2016-10-04 09:00:01 +0200 Armin Novak (032b59f) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (994fed8) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (d8751a3) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (ec26629) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (5ba9f82) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (3b9c74e) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (dec268d) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (ab231f8) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (569c6a5) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (a4014b4) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (14ed774) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (226ee43) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (6cd2a43) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (377b955) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (b1c5461) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (4d179fd) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (b0b3273) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (1b6cf57) + + * Reformatted file. + +2016-10-04 09:00:00 +0200 Armin Novak (07010e6) + + * Reformatted file. + +2016-10-04 08:54:42 +0200 Armin Novak (dd676c7) + + * Fixed missing NULL checks. + +2016-10-03 13:18:21 +0200 Armin Novak (5a2c249) + + * Disabled glyph-cache + +2016-09-26 12:12:37 +0200 Armin Novak (9f5da48) + + * Reformatted files touched in last 2 commits. + +2016-09-26 12:12:14 +0200 Armin Novak (64590e7) + + * Set pEntryPointsEx->ppInterface NULL on error. + +2016-09-26 12:02:33 +0200 Armin Novak (88a3b8d) + + * Initializing channel context in each thread. + +2016-09-20 09:50:44 +0200 Armin Novak (d55690d) + + * Fixed RFX encoding. + +2016-09-20 09:25:13 +0200 Armin Novak (9ab0471) + + * Fixed shadow server color encoding. + +2016-09-20 08:58:04 +0200 Armin Novak (f5fff76) + + * Made some functions static. + +2016-09-13 13:42:42 +0200 Armin Novak (3220b15) + + * Added missing event handle. + +2016-09-13 09:53:16 +0200 Armin Novak (f2d7766) + + * Moved common async input handling to core library. + +2016-09-06 14:20:07 +0200 Armin Novak (b8b8447) + + * Fixed post disconnect hook. + +2016-09-09 08:58:26 +0200 Armin Novak (4e11883) + + * Fixed X11 cursor decoding. + +2016-08-29 09:40:53 +0200 Armin Novak (83c6a79) + + * Removed broken X11 command. + +2016-08-25 09:47:50 +0200 Armin Novak (f2bb83e) + + * Fixed rebase related issues. + +2016-08-18 11:54:29 +0200 Armin Novak (296bc02) + + * Fixed ellipse test. + +2016-08-18 10:03:28 +0200 Armin Novak (399c318) + + * Fixed test loop. + +2016-08-18 10:01:12 +0200 Armin Novak (196386f) + + * Android client support script fixes. + +2016-08-17 09:26:59 +0200 Armin Novak (161685b) + + * Fixed some more glyph chache bugs. + +2016-08-17 09:01:27 +0200 Armin Novak (dbab3dd) + + * Fixed tests and not intialized values. + +2016-08-16 14:30:18 +0200 Armin Novak (0c57065) + + * GlyphCache: Erasing destination if not redundant. + +2016-08-16 11:27:27 +0200 Armin Novak (b7f3235) + + * Fixed pattern checks. + +2016-08-11 09:36:06 +0200 Armin Novak (823b1ec) + + * Added proper brush support to fill rect. + +2016-08-11 13:40:22 +0200 Armin Novak (9471f82) + + * Fixed missing include preventing symbol export. + +2016-08-10 18:11:36 +0200 Armin Novak (ad4f6d8) + + * Fixed MacOS includes. + +2016-08-10 18:05:00 +0200 Armin Novak (739d45e) + + * Fixed includes for iOS + +2016-08-10 17:57:21 +0200 Armin Novak (e23a7e2) + + * Removed obsolete code. + +2016-08-10 17:01:54 +0200 Armin Novak (c242467) + + * Fixed some X11 functions. + +2016-08-10 14:53:03 +0200 Armin Novak (50c509e) + + * Fixed barrier test. + +2016-08-10 14:45:55 +0200 Armin Novak (b320e3c) + + * windows fixes. + +2016-08-10 13:44:55 +0200 Armin Novak (416801a) + + * Fixed warning. + +2016-08-10 13:33:34 +0200 Armin Novak (22ddec8) + + * Moved pre and post channel hooks. + +2016-08-10 13:12:54 +0200 Armin Novak (2e76529) + + * Updated Order support. + +2016-08-10 12:49:36 +0200 Armin Novak (4b3d3cd) + + * Warning fixes. + +2016-08-10 12:49:36 +0200 Armin Novak (44b8756) + + * Warning fixes. + +2016-08-10 12:42:57 +0200 Armin Novak (a3fd9bf) + + * Fixed warnings. + +2016-08-10 12:39:26 +0200 Armin Novak (1454400) + + * Fixed windows defines for *LIST* + +2016-08-10 11:06:34 +0200 Armin Novak (9c64e77) + + * Disabled thread local storage on iOS. + +2016-08-10 11:03:13 +0200 Armin Novak (35bf9e6) + + * Fixed missing mac server symbols. + +2016-08-10 10:50:10 +0200 Armin Novak (14dc629) + + * Fixed expressions. + +2016-08-10 10:46:01 +0200 Armin Novak (4f62d84) + + * Refactored interlocked typedefs, avoid namespace collisions. + +2016-08-10 10:29:59 +0200 Armin Novak (64c5d78) + + * Fixed clang warnings. + +2016-08-10 10:29:02 +0200 Armin Novak (ada4abc) + + * Using add_definitions for symbols now. + +2016-08-10 09:37:34 +0200 Armin Novak (0c55180) + + * Fixed gdi_init for windows server. + +2016-08-10 09:12:55 +0200 Armin Novak (c7448c0) + + * Added FREERDP_LOCAL + +2016-08-09 22:51:58 +0200 Armin Novak (6d6b991) + + * Fixed BitBlt function for overlapping areas. + +2016-08-09 22:37:32 +0200 Armin Novak (5554d80) + + * Code cleanup. + +2016-08-09 22:37:02 +0200 Armin Novak (122f25e) + + * Fixed channel cleanup. + +2016-08-09 16:48:02 +0200 Armin Novak (d35823c) + + * Moved channel init code to core library. + +2016-08-09 12:04:06 +0200 Armin Novak (dadc526) + + * Removed static channel variables. + +2016-08-08 15:15:55 +0200 Armin Novak (2e40c9c) + + * Windows GDI color decoding. + +2016-08-08 09:29:36 +0200 Armin Novak (f16ffae) + + * Fixed glyph cache issues. + +2016-08-06 15:37:50 +0200 Armin Novak (0d56de5) + + * Glyph offset fix. + +2016-08-05 19:38:46 +0200 Armin Novak (b765374) + + * Refactored BitBlt, implementing everything now. + +2016-08-05 14:10:53 +0200 Armin Novak (f17f147) + + * Fixed font drawing. + +2016-08-05 13:14:55 +0200 Armin Novak (f086410) + + * Updated iOS client. + +2016-08-05 12:05:08 +0200 Armin Novak (081b579) + + * Added ios home and temp dir support. + +2016-08-04 16:58:07 +0200 Armin Novak (dd9354d) + + * Added argument checks. + +2016-08-04 16:57:27 +0200 Armin Novak (9fcfc38) + + * Fixed planar decoding. + +2016-08-04 16:28:38 +0200 Armin Novak (0acfc64) + + * Fixed log message. + +2016-08-04 16:14:12 +0200 Armin Novak (844f7b7) + + * Made logging less verbose. + +2016-08-04 16:13:37 +0200 Armin Novak (0f9ab81) + + * Fixed command line setting. + +2016-08-04 14:50:53 +0200 Armin Novak (b888059) + + * Fixed color conversion issues. + +2016-08-04 14:37:19 +0200 Armin Novak (c8d4438) + + * Fixed android settings. + +2016-08-04 13:25:52 +0200 Armin Novak (c3e6240) + + * Fixed android client. + +2016-08-04 13:25:12 +0200 Armin Novak (4027a1d) + + * Added error checks. + +2016-08-04 13:24:53 +0200 Armin Novak (04846ca) + + * Added missing API export. + +2016-08-04 13:24:35 +0200 Armin Novak (a978ccc) + + * Added argument checks. + +2016-08-04 13:24:11 +0200 Armin Novak (ab4725d) + + * Fixed error message parameter. + +2016-08-04 13:23:50 +0200 Armin Novak (fb36121) + + * Added signal handler for android. + +2016-08-04 09:16:54 +0200 Armin Novak (fddf710) + + * Fixed OpenSSL build headers. + +2016-08-04 09:02:40 +0200 Armin Novak (7b5d0d5) + + * Updated build script error checking. + +2016-08-03 21:22:06 +0200 Armin Novak (3b21209) + + * Fixed xfreerdp GDI color order. + +2016-08-03 18:44:38 +0200 Armin Novak (8898980) + + * Removed obsolete generation script. + +2016-08-03 18:44:26 +0200 Armin Novak (346515a) + + * Wayland client overhaul. + +2016-08-03 18:44:15 +0200 Armin Novak (543631d) + + * Added better argument checks. + +2016-08-03 18:42:49 +0200 Armin Novak (3820c91) + + * Added wayland OS minor version. + +2016-08-03 15:29:24 +0200 Armin Novak (376f6a4) + + * Fixed OS X client. + +2016-08-03 15:29:12 +0200 Armin Novak (896f500) + + * Fixed h264 dummy init. + +2016-08-03 14:22:55 +0200 Armin Novak (90cd2a8) + + * Fixed color pointer. + +2016-08-03 14:16:20 +0200 Armin Novak (c8a7065) + + * Refactored xfContext. + +2016-08-03 12:37:40 +0200 Armin Novak (fbdb00a) + + * Simplified windows context. + +2016-08-03 12:09:24 +0200 Armin Novak (71a7306) + + * Reformatted client code. + +2016-08-03 11:31:42 +0200 Armin Novak (bc5aa1b) + + * Added more GDI orders. + +2016-08-03 10:54:50 +0200 Armin Novak (9af71b9) + + * Fixed color conversion from order. + +2016-08-03 09:55:19 +0200 Armin Novak (a76b0df) + + * Fixed reading of colors from order. + +2016-08-02 17:11:27 +0200 Armin Novak (60ac638) + + * 32bpp cursor fix. + +2016-08-02 15:21:28 +0200 Armin Novak (c00fc57) + + * Cursor color decoding fixes. + +2016-08-02 14:16:49 +0200 Armin Novak (984bec7) + + * Simplified gdi_patblt + +2016-08-02 11:46:11 +0200 Armin Novak (00890c2) + + * Exporting all symbols from DLL for test builds on windows. + +2016-08-02 11:39:25 +0200 Armin Novak (0b6c7a3) + + * Fixed windows color cursor. + +2016-08-02 11:20:57 +0200 Armin Novak (d1a3362) + + * Fixed windows software GDI issues. + +2016-08-02 10:23:04 +0200 Armin Novak (66cf000) + + * Fixed broken test. + +2016-08-02 10:03:18 +0200 Armin Novak (e3b43b9) + + * Fixed some bitblt issues. + +2016-08-02 09:30:50 +0200 Armin Novak (5fa9344) + + * Deactivated broken tests. + +2016-08-02 08:43:26 +0200 Armin Novak (9034867) + + * Added brush helper function to retrieve style. + +2016-08-01 18:14:17 +0200 Armin Novak (cd65c49) + + * Fixed mac compile errors. + +2016-08-01 17:31:59 +0200 Armin Novak (b505220) + + * Fixed Get/SetPixel function tests. + +2016-08-01 17:08:35 +0200 Armin Novak (f3d9e8d) + + * Fixed (some) planar codec tests. + +2016-08-01 16:37:26 +0200 Armin Novak (e4d8906) + + * Fixed splitting of color planes. + +2016-08-01 16:36:32 +0200 Armin Novak (c7f8d00) + + * Fixed RGBX32 format split color mixup. + +2016-08-01 13:13:04 +0200 Armin Novak (d3538fc) + + * Fixed gdi LineTo and tests. + +2016-08-01 10:15:21 +0200 Armin Novak (ebfe4fb) + + * Fixed compile issues. + +2016-08-01 09:41:41 +0200 Armin Novak (88be64f) + + * Fixed apple file times. + +2016-07-21 16:51:42 +0200 Armin Novak (35f1347) + + * Fixed warnings and mac build. + +2016-07-21 16:10:41 +0200 Armin Novak (aad0a5c) + + * Updated mac build script. + +2016-07-21 15:36:15 +0200 Armin Novak (7818ca1) + + * Fixed windows compile. + +2016-07-21 15:36:01 +0200 Armin Novak (d0f09c8) + + * Fixed warnings and stride default. + +2016-07-21 13:00:57 +0200 Armin Novak (7dbeeb2) + + * Fixed hardware GDI. + +2016-07-21 12:53:44 +0200 Armin Novak (a372009) + + * Internal functions static. + +2016-07-21 12:42:23 +0200 Armin Novak (a06ceb6) + + * Fixed duplicate setting of callback. + +2016-07-21 12:41:55 +0200 Armin Novak (0e1b385) + + * Internal functions static. + +2016-07-21 11:57:51 +0200 Armin Novak (9d82c47) + + * Removed duplicate code. + +2016-07-21 10:07:42 +0200 Armin Novak (8675280) + + * Simplified bitmap drawing. + +2016-07-21 09:24:09 +0200 Armin Novak (ec0d68b) + + * Fixed bitmap update decoding. + +2016-07-20 16:50:20 +0200 Armin Novak (c22d16b) + + * Reverted bitmap update changes. + +2016-07-20 16:03:08 +0200 Armin Novak (3898b56) + + * Fixed drawing orders. + +2016-07-20 15:58:05 +0200 Armin Novak (e3f88ad) + + * Fixed BitBlt_PSDPxax + +2016-07-20 15:34:06 +0200 Armin Novak (032bdef) + + * Unified bitmap drawing. + +2016-07-20 11:40:30 +0200 Armin Novak (b8ff3cb) + + * Fixed (a lot of) GDI drawing issues. + +2016-07-20 10:31:07 +0200 Armin Novak (bb82d48) + + * Fixed part of font cache issue. + +2016-07-20 10:06:45 +0200 Armin Novak (3f90966) + + * Bug fixes. + +2016-07-19 16:15:38 +0200 Armin Novak (85bbe2a) + + * API refactoring. + +2016-07-19 13:18:30 +0200 Armin Novak (f680b62) + + * Fixed PATINVERT. + +2016-07-19 13:02:08 +0200 Armin Novak (e650fdb) + + * Bugfixes. + +2016-07-19 12:15:01 +0200 Armin Novak (b719178) + + * Removed obsolete DEBUG_GDI + +2016-07-18 17:45:30 +0200 Armin Novak (17fd552) + + * Cleanups. + +2016-07-18 16:15:52 +0200 Armin Novak (bc49c16) + + * Removed obsolete options. + +2016-07-18 14:42:55 +0200 Armin Novak (7a20ff5) + + * Refactored bitmap API. + +2016-07-18 14:30:26 +0200 Armin Novak (8b69b16) + + * Refactored Glyph API. + +2016-07-18 14:16:13 +0200 Armin Novak (9d5ca34) + + * Fixed pointer initialisation for X11. + +2016-07-18 12:36:22 +0200 Armin Novak (04fb4e4) + + * Fixed rectangle clipping and warnings. + +2016-07-18 12:33:42 +0200 Armin Novak (3c8d0bb) + + * Added address sanitizer to options. + +2016-07-18 11:16:36 +0200 Armin Novak (c229a19) + + * Updated codec API, unified drawing order color decoding. + +2016-07-18 11:11:59 +0200 Armin Novak (e32ed83) + + * Updated interleaved and planar API. + +2016-07-15 16:45:36 +0200 Armin Novak (bc8217e) + + * Removed palette, using GDI one. + +2016-07-15 16:45:26 +0200 Armin Novak (6525a56) + + * Fixed 24bit color format. + +2016-07-15 16:34:51 +0200 Armin Novak (39d6ad3) + + * Fixed source format for bitmap decompress. + +2016-07-15 16:23:00 +0200 Armin Novak (f9a89ae) + + * Bug fixes, refactoring. + +2016-07-15 16:22:09 +0200 Armin Novak (960bc26) + + * Further refactored tests. + +2016-07-15 15:51:08 +0200 Armin Novak (9f0a9c3) + + * Refactored GDI. + +2016-07-15 12:14:14 +0200 Armin Novak (c5b6e7e) + + * Fixed GDI tests. + +2016-07-14 17:55:53 +0200 Armin Novak (2594262) + + * Fixed progressive decoding. + +2016-07-14 17:39:39 +0200 Armin Novak (1608799) + + * Cleaned up clear codec. + +2016-07-14 16:08:06 +0200 Armin Novak (8fffda5) + + * Fixed clearcodec and codecs reset. + +2016-07-14 12:44:17 +0200 Armin Novak (dc12641) + + * Fixed a windows 8.1 issue. + +2016-07-14 12:42:24 +0200 Armin Novak (5e9c9f9) + + * Code refactoring. + +2016-07-13 17:33:23 +0200 Armin Novak (e6e8f2d) + + * Added ROP to string function. + +2016-07-13 16:06:59 +0200 Armin Novak (9fc8dc6) + + * Removed gdi->codecs, unused. + +2016-07-13 15:15:41 +0200 Armin Novak (076b92d) + + * Fixed primitives misuse. + +2016-07-13 14:58:11 +0200 Armin Novak (a6cef5c) + + * Fixed GFX related issues. + +2016-07-13 14:04:48 +0200 Armin Novak (99c4187) + + * Updated primitives API and tests. + +2016-07-13 13:13:28 +0200 Armin Novak (e860fde) + + * Fixed function arguments. + +2016-07-13 13:12:27 +0200 Armin Novak (7d01fe1) + + * Fixed planar tests, deactivated them for clear + +2016-07-11 11:52:56 +0200 Armin Novak (03907c8) + + * Fixed issues. + +2016-07-11 11:29:26 +0200 Armin Novak (d986770) + + * Fixed warnings. + +2016-07-11 11:05:38 +0200 Armin Novak (bbae42d) + + * Compile fix + +2016-04-25 09:42:59 +0200 Armin Novak (5039a82) + + * GDI fixes. + +2016-04-23 11:25:55 +0200 Armin Novak (e1c3adf) + + * freerdp_image_copy fixes, 8bit color improvements. + +2016-04-20 09:57:42 +0200 Armin Novak (c12c5dd) + + * Added overlapped copy support. + +2016-04-19 22:11:12 +0200 Armin Novak (716c5c5) + + * 256 color support. + +2016-04-19 21:30:28 +0200 Armin Novak (48d1b4e) + + * Fixed color ordering for GDI. + +2016-04-13 23:37:23 +0200 Armin Novak (016f3a4) + + * xxx. + +2016-04-13 23:18:55 +0200 Armin Novak (b668b0d) + + * Api update. + +2016-04-13 23:13:04 +0200 Armin Novak (ac8c722) + + * Api update. + +2016-04-13 23:10:08 +0200 Armin Novak (0e7bb50) + + * Bitmaps now remember their format. + +2016-04-13 23:06:33 +0200 Armin Novak (bb92655) + + * Fixed clear codec. + +2016-04-13 12:32:51 +0200 Armin Novak (5633f52) + + * Fixed crashes. + +2016-04-11 17:30:29 +0200 Armin Novak (da956e0) + + * ... + +2016-04-11 14:14:17 +0200 Armin Novak (24599af) + + * More color fixes. + +2016-04-05 17:07:45 +0200 Armin Novak (df35c13) + + * Fixed color conversion, unified GFX and updated API. + +2016-10-06 12:19:57 +0200 Bernhard Miklautz (bfdab0e) + + * Merge pull request #3523 from rjcorrig/tz201609 + +2016-10-05 09:21:11 -0400 Marc-André Moreau (1d06087) + + * Merge pull request #3515 from akallabeth/apple_time_fix + +2016-10-05 13:14:06 +0200 Bernhard Miklautz (1acd6c4) + + * Merge pull request #3522 from ondrejholy/fix-pulse-asserts + +2016-10-04 09:50:37 -0400 Robert Corrigan (fc7378f) + + * Updated time zone definitions to Sept 2016 + +2015-06-11 13:25:35 +0200 Ondrej Holy (2fec57f) + + * rdpsnd/pulse: Fix crashes in pulseaudio + +2016-10-03 22:40:28 +0200 David Fort (425942d) + + * Merge pull request #3511 from + nonamed108/fix_for_xcode8_clock_gettime + +2016-09-30 09:32:52 +0200 David Fort (dbb353d) + + * Merge pull request #3501 from DavBfr/fix-few-memory-leaks + +2016-09-27 13:28:39 +0200 Armin Novak (3eb136d) + + * Fixed SetFileTime for mac. + +2016-09-27 12:33:44 +0200 akallabeth (3a9cc2c) + + * Merge pull request #3512 from nathankidd/redundant-rfx-conversion + +2016-09-23 19:07:09 -0400 Nathan Kidd (24aa71e) + + * client/X11: Only upconvert < 24 bit RFX tiles + +2016-09-22 15:42:43 -0500 ed.velez (ed697fa) + + * fix_for_xcode8_clock_gettime + +2016-09-01 11:34:38 -0700 David PHAM-VAN (d5dc5b4) + + * Fix smartcard channel disconnect + +2016-07-06 12:12:40 -0700 David PHAM-VAN (f5f3913) + + * Fix Memory Leaks in Printer Redirection + +2016-06-28 14:39:29 -0700 David PHAM-VAN (fe2e426) + + * Fix Memory Leaks in RdpSnd + +2016-06-28 14:39:14 -0700 David PHAM-VAN (4265177) + + * Fix Memory Leaks in RdpDR + +2016-06-28 14:39:01 -0700 David PHAM-VAN (1bca1e7) + + * Fix Memory Leaks in Disp channel + +2016-09-09 11:16:29 +0200 David Fort (1855e36) + + * Merge pull request #3482 from realjiangms/fix_gfx_win8 + +2016-08-27 21:51:29 +0800 zihao.jiang (2c00240) + + * server/shadow: Fix regression with rdp8.0 Shadow server crash with + rdp8.0 with gfx enabled. Root Cause: rdp8.0 is not support + in shadow gfx and rdpgfx_caps_advertise returns an error. + However setChannelError crashs because + context->errorDescription is NULL 1. Fix shadow gfx to + handle rdp8.0 2. Initialize context->errorDescription for + server side new-context + +2016-08-25 09:00:56 +0200 Martin Fleisz (3586e33) + + * Merge pull request #3435 from akallabeth/uuid_find_fix + +2016-08-25 08:17:52 +0200 Martin Fleisz (71765b7) + + * Merge pull request #3284 from ondrejholy/endianness + +2016-08-24 11:08:00 +0200 David Fort (5394a04) + + * Merge pull request #3316 from realjiangms/server_gfx + +2016-08-24 10:40:31 +0200 akallabeth (4c9782d) + + * Merge pull request #3476 from FreeRDP/mh-fix-transport + +2016-08-22 02:17:11 -0700 Martin Haimberger (e9e0764) + + * libfreerdp/core: transport_write unchecked parameters + +2016-08-21 01:02:13 +0800 zihao.jiang (92ca985) + + * rdpgfx/server: Fix for windows10 clients 1. Fix order of gfx reset + and new-surface. Windows10 client will show black screen + with this issue(FreeRDP itself is dramatically immune to + this issue) 2. Handle RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU for + FPS control + +2016-08-20 01:36:37 +0800 zihao.jiang (5d4e9a2) + + * rdpgfx/server: More minor fix + +2016-08-16 14:49:56 +0800 zihao.jiang (7d0fa79) + + * rdpgfx/server: More minor fix according to comments: Not use sizeof + on packet memory structure for stream length + check/estimating and use number directly. Most of the + packet size could be obviously calculated/verified from + code and comments in same function. Macro is defined for + those were referenced multiple times. + +2016-08-13 18:27:19 -0700 Michael M. Wasser (75a483d) + + * mac BUILD_SHARED_LIBS=ON fix + +2016-06-03 02:33:31 +0800 zihao.jiang (a15b8ff) + + * rdpgfx/server: Minor fix: allow configurable codec parameter + +2016-05-28 13:43:33 +0800 zihao.jiang (26c98e4) + + * rdpgfx/server: Minor fix: use switch for pdu length estimation + +2016-05-27 02:11:52 +0800 zihao.jiang (992e0e9) + + * rdpgfx: more minor changes 1. Fix style for + channels/rdpgfx/server/rdpgfx_main.c according to + scripts/format_code.sh 2. Refactor and introduce APIs to + allow rdpgfx server channel running in existing thread + (similar to rdpsnd) + +2016-05-04 00:48:59 +0800 zihao.jiang (2b6bd26) + + * rdpgfx: various fixes according to comments 1. Fix stream leak in + rdpgfx 2. Make src data const in zgfx. Harden zgfx to be + independent to byte order 3. Fix written bytes return + value in channel write 4. Add check for return value in + shadow_client.c 5. Add gfx callback to send surface + command with frame marker pdu. 6. Check remain length for + recv subroutine 7. Fix compile errors + +2016-04-24 01:49:10 +0800 zihao.jiang (746a754) + + * rdpgfx: Implementation for server side channel server/shadow: + support h264 codec with gfx channel + +2016-07-22 09:34:49 -0400 Marc-André Moreau (5b2455f) + + * Merge pull request #3451 from awakecoding/nla_server_fix + +2016-07-22 09:06:07 -0400 Marc-André Moreau (14cb6d3) + + * freerdp: make modifications to NLA server-side fixes according to + PR comments + +2016-07-21 18:58:24 -0400 Marc-André Moreau (801dc0f) + + * freerdp: add configurable NTLM SAM file option for server-side NLA + +2016-07-21 17:53:20 -0400 Marc-André Moreau (1ffbd77) + + * freerdp: fix sending of TLS alert on NLA failure, add better + handling of server-side NLA in shadow server + +2016-07-20 09:26:04 -0400 Marc-André Moreau (9ef863b) + + * Merge pull request #3449 from awakecoding/android_toolchain_fix + +2016-07-19 21:53:23 -0400 Marc-André Moreau (a04f324) + + * cmake: fix Android toolchain missing usage of CMAKE_PREFIX_PATH + +2016-07-18 14:53:53 +0200 Bernhard Miklautz (05d63c6) + + * Merge pull request #3445 from lanoxx/master + +2016-07-18 13:23:00 +0200 akallabeth (cd9bdd5) + + * Merge pull request #3447 from bmiklautz/package_updates + +2016-07-18 12:33:44 +0200 Bernhard Miklautz (add4db4) + + * pkg: update packages + +2016-07-17 22:29:09 +0200 Sebastian Geiger (d1c7843) + + * docs: Make doxygen silent + +2016-07-08 11:14:25 +0200 Martin Fleisz (5d7027a) + + * Merge pull request #3438 from akallabeth/android_build_paths + +2016-07-07 12:41:34 +0000 Bernhard Miklautz (c4e3db0) + + * Merge pull request #3436 from akallabeth/openh264_1_6_support + +2016-07-07 10:38:51 +0200 akallabeth (79a360b) + + * Merge pull request #3405 from hardening/wlog_man + +2016-07-06 17:21:46 +0200 Armin Novak (40bfc17) + + * Added gradle.properties to extend heap size. + +2016-07-06 17:17:39 +0200 Armin Novak (48b4c5b) + + * Fixed android libfreerdp install paths. + +2016-07-06 13:58:10 +0200 Norbert Federa (89c2527) + + * Merge pull request #3384 from akallabeth/android64_build + +2016-07-06 13:02:35 +0200 Armin Novak (d5b7c19) + + * Updated gradle. + +2016-07-06 11:59:08 +0200 Armin Novak (f5fef88) + + * Disabled OpenH264 build for pull request tester. + +2016-07-06 11:50:53 +0200 Armin Novak (730ff20) + + * Using android build-tools 24 (23 is broken) + +2016-07-05 15:35:41 +0200 David Fort (070b2c6) + + * Merge pull request #3402 from doughdemon/master + +2016-07-05 15:15:19 +0200 David Fort (4a67ba8) + + * Merge pull request #3433 from akallabeth/wlog_callbac_init_fix + +2016-07-05 13:22:28 +0200 Armin Novak (2ceb38a) + + * Proper wLogMessage initialisation. + +2016-07-05 13:00:54 +0200 Armin Novak (d96fbd1) + + * Initialise WLog PrefixString for each message type. + +2016-07-04 12:33:52 +0200 Armin Novak (44fc5b5) + + * Added support for OpenH264 1.6 + +2016-06-30 22:43:05 +0200 David Fort (a132545) + + * Merge pull request #3428 from + nfedera/fix-getcomputernameex-lentgh-calculation + +2016-06-30 17:15:40 +0200 Norbert Federa (333a111) + + * winpr/sspi/ntlm: fix computer name len calculation + +2016-06-27 15:28:22 +0200 Bernhard Miklautz (c42d2ef) + + * Merge pull request #3426 from nfedera/fix-read-extended-info-packet + +2016-06-27 10:56:40 +0200 Norbert Federa (ae9460f) + + * protocol violation: rdp_read_extended_info_packet + +2016-06-27 10:11:19 +0200 Armin Novak (b7f8dc3) + + * Fixed UUID find. + +2016-06-22 15:32:11 +0200 Martin Fleisz (0d7a6b5) + + * Merge pull request #3418 from llyzs/rdpsnd_server_latency + +2016-06-21 15:10:09 +0200 David Fort (1fdcae9) + + * Add an environment variables section to the man + +2016-06-21 14:05:29 +0800 Vic Lee (019a569) + + * rdpsnd/server: decrease audio latency and make it configurable. + +2016-06-15 22:39:03 +0200 David Fort (0905cc2) + + * man pages needed love + +2016-06-13 22:16:36 +0200 David Fort (db6efd0) + + * Add a dedicated man page for wLog + +2016-06-16 16:16:37 +0200 Bernhard Miklautz (e86f7c2) + + * Merge pull request #3408 from hendwolt/master + +2016-06-16 14:46:27 +0200 Martin Fleisz (f166f5d) + + * Merge pull request #3410 from nfedera/fix-symbols + +2016-06-16 11:47:33 +0200 Norbert Federa (27c4396) + + * winpr: fix win32 linking issues + +2016-06-15 18:01:38 +0200 Norbert Federa (6a3b48d) + + * freerdp: remove static inet_ntop + +2016-06-15 13:54:31 +0200 Norbert Federa (7a68eeb) + + * cmake: remove some void statements and fix winpr source group + +2016-06-15 13:36:27 +0200 Norbert Federa (90cdfa7) + + * cmake: replaced STATIC_CHANNELS with BUILTIN_CHANNELS + +2016-06-15 13:30:38 +0200 Norbert Federa (0ed98c4) + + * channels/audin/client/winmm: requires winpr + +2016-06-14 20:43:35 +0200 Hendrik Woltersdorf (8ea61fe) + + * fix errors in xdg-shell-xml for protocol creation + +2016-06-14 13:57:00 +0200 Bernhard Miklautz (50649ac) + + * Merge pull request #3407 from nfedera/enable-tests-on-windows + +2016-06-14 12:57:30 +0200 Norbert Federa (675ea70) + + * ci: build tests on windows from now on + +2016-06-14 12:54:01 +0200 Bernhard Miklautz (0cb37b0) + + * Merge pull request #3406 from nfedera/fix-winpr-ntlm + +2016-06-14 12:37:37 +0200 Norbert Federa (26ed09a) + + * winpr/sspi/ntlm: fix GetComputerNameExA parameters + +2016-06-14 10:20:52 +0200 akallabeth (f0bdd62) + + * Merge pull request #3404 from nfedera/fix-pathmakepath + +2016-06-13 19:19:28 +0200 Norbert Federa (62d73dc) + + * winpr: fix PathMakePathA and TestWLog + +2016-06-13 10:06:51 +0200 Bernhard Miklautz (ee4d118) + + * Merge pull request #3403 from TingPing/freerdp-client.pc + +2016-06-12 22:10:00 -0400 TingPing (9fe5da8) + + * Fix include path in freerdp-client.pc + +2016-06-12 17:54:52 +0200 Felix Janda (cd581cf) + + * Make iOS workaround iOS specific + +2016-06-08 11:43:11 +0200 Ondrej Holy (b8f33aa) + + * winpr/crt: Make TestString endian-independent + +2016-06-08 11:42:27 +0200 Ondrej Holy (bbcc047) + + * winpr/crt: Fix endianness in string utils + +2016-06-10 15:08:49 +0200 Bernhard Miklautz (f818bab) + + * Merge pull request #3399 from nfedera/fix-winpr-library2 + +2016-06-10 13:10:39 +0200 Norbert Federa (581c000) + + * winpr/library: fix GetModuleFileName and tests + +2016-06-08 11:03:40 -0400 Marc-André Moreau (0c8af43) + + * Merge pull request #3397 from awakecoding/master + +2016-06-08 10:51:58 -0400 Marc-André Moreau (f905861) + + * wayk-now: add missing inet_pton implementation on Windows + +2016-06-08 11:50:43 +0200 Bernhard Miklautz (b71f60c) + + * Merge pull request #3393 from nfedera/fix-winpr-library-wtimer-test + +2016-06-08 08:21:13 +0200 Hardening (a0520f8) + + * Merge pull request #3394 from nfedera/fix-client-x11-locked-mutex + +2016-06-07 18:57:27 +0200 Norbert Federa (374f97a) + + * client/x11: don't close locked mutex + +2016-06-07 17:20:56 +0200 Norbert Federa (f2c825b) + + * winpr: fix some tests + +2016-06-07 15:33:49 +0200 MartinHaimberger (0abb285) + + * Merge pull request #3392 from nfedera/fix-winpr-barrier-deadlock + +2016-06-07 13:06:50 +0200 Norbert Federa (f969e60) + + * winpr/synch: fix barrier deadlock in release build + +2016-06-07 09:34:12 +0200 Bernhard Miklautz (aa15327) + + * Merge pull request #3391 from + nfedera/fix-initializewaitabletimer-result + +2016-06-06 23:06:12 +0200 Norbert Federa (a35a1e3) + + * winpr/synch: fix InitializeWaitableTimer result + +2016-06-06 16:21:39 +0200 Norbert Federa (6e15931) + + * Merge pull request #3390 from nfedera/fix-winpr-barrier2 + +2016-06-06 15:33:16 +0200 Norbert Federa (131ffaa) + + * winpr/synch: improve barrier test + +2016-06-06 13:54:39 +0200 Bernhard Miklautz (bd71b36) + + * Merge pull request #3388 from nfedera/fix-winpr-pool-synch + +2016-06-06 13:44:48 +0200 Bernhard Miklautz (11ecda2) + + * Merge pull request #3386 from nfedera/fix-winpr-barrier + +2016-06-06 13:39:36 +0200 Bernhard Miklautz (a24d1fd) + + * Merge pull request #3389 from + nfedera/fix-winpr-synch-timer-queue-segfault + +2016-06-06 13:18:00 +0200 Norbert Federa (e35049c) + + * winpr/synch: fix timerqueue segfault + +2016-06-06 11:32:25 +0200 Armin Novak (8e552e2) + + * Updated readme for android. + +2016-06-06 09:23:41 +0200 akallabeth (8c4f3ba) + + * Merge pull request #3387 from + nfedera/fix-wfreerdp-verify-cert-callback + +2016-06-04 17:13:07 +0200 Norbert Federa (882f593) + + * wfreerdp: fix invalid VerifyCertificate callback + +2016-06-04 17:04:12 +0200 Norbert Federa (c16bee7) + + * winpr: several pool and synch fixes + +2016-06-04 13:40:01 +0200 Norbert Federa (2dba082) + + * winpr/synch/barrier: fix return value and test + +2016-06-04 00:55:27 +0200 Norbert Federa (85f4426) + + * winpr/synch: add spinning support to barrier + +2016-06-03 18:56:36 +0200 Norbert Federa (341eed1) + + * winpr/synch: rewrite barrier implementation & test + +2016-06-03 18:53:14 +0200 Bernhard Miklautz (8ea8b7c) + + * Merge pull request #3381 from nfedera/fix-winpr-misc + +2016-06-03 14:23:06 +0200 Armin Novak (dd9cb25) + + * Fixed defined symbols for function check. + +2016-06-03 13:02:30 +0200 Armin Novak (de662b9) + + * Setting lib64 preference now. + +2016-06-03 13:02:13 +0200 Armin Novak (20568af) + + * Updated toolchain file, added new variable for lib64 detection. + +2016-06-03 13:01:59 +0200 Armin Novak (10460d3) + + * Fixed android library detection. + +2016-06-03 09:39:48 +0200 Armin Novak (be33a11) + + * Fixed missing arch. + +2016-06-02 15:38:57 +0200 Norbert Federa (458f606) + + * winpr/thread: fix SwitchToThread + +2016-06-02 15:33:00 +0200 Armin Novak (e405464) + + * Fixed pthread_mutex_timedlock detection. + +2016-06-02 14:25:13 +0200 Armin Novak (fc2f43e) + + * Added android64 support. + +2016-06-02 08:32:12 +0200 Ondrej Holy (1903537) + + * winpr/crt: Make TestUnicodeConversion endian-independent + +2016-06-02 10:49:42 +0200 Bernhard Miklautz (215e7b5) + + * Merge pull request #3382 from giox069/master + +2016-06-02 10:23:28 +0200 Giovanni Panozzo (01a8db2) + + * Fix some memory leaks in freerdp_settings_free() + +2016-06-01 16:26:26 +0200 Norbert Federa (e718fb3) + + * fix race conditions, tests and some invalid return values + +2016-05-31 16:04:16 +0200 Ondrej Holy (44ce6b0) + + * winpr/stream: Make TestStream endian-independent + +2016-05-31 09:41:09 +0200 Norbert Federa (42d2b69) + + * Merge pull request #3379 from nfedera/fix-winpr-wtsapi + +2016-05-31 09:37:31 +0200 akallabeth (345478b) + + * Merge pull request #3376 from realjiangms/fix_client_gfx + +2016-05-30 19:25:20 +0200 Bernhard Miklautz (9daf129) + + * Merge pull request #3371 from realjiangms/fix_x11_shadow_race + +2016-05-30 17:54:59 +0200 Norbert Federa (c6aeba6) + + * winpr/wtsapi: fixed race conditions and tests + +2016-05-30 14:59:34 +0200 MartinHaimberger (69f738f) + + * Merge pull request #3377 from nfedera/fix-channel-name-parsing + +2016-05-30 14:40:23 +0200 Norbert Federa (7a42a8d) + + * freerdp/core/gcc: channel name hardening + +2016-04-27 13:43:16 +0200 Ondrej Holy (0e353cc) + + * winpr/ntlm: Fix endianness in NTLM authentication + +2016-04-22 14:43:40 +0200 Ondrej Holy (95a1b53) + + * winpr/ntlm: Fix endianness in ntlm_av_pair_list + +2016-04-27 13:35:09 +0200 Ondrej Holy (8d468ea) + + * winpr/crt: Fix endianness in WCHAR case conversions + +2016-04-13 16:26:42 +0200 Ondrej Holy (f722dc5) + + * winpr/crt: Fix endianness in unicode conversions + +2016-04-11 11:05:21 +0200 Ondrej Holy (e326e43) + + * codec/xcrush: Fix endianness in compression + +2016-04-06 17:02:23 +0200 Ondrej Holy (250998e) + + * winpr: Be sure data points to BYTE in endian.h + +2016-04-06 16:49:37 +0200 Ondrej Holy (11221e7) + + * winpr: Fix Data_Read_UINT16 + +2016-04-22 15:31:01 +0200 Ondrej Holy (6d2ab9c) + + * winpr: Fix 64-bit architecture detection + +2016-05-30 13:00:32 +0200 Bernhard Miklautz (ca03b51) + + * Merge pull request #3375 from nfedera/fix-sizet-format-segfaults + +2016-05-29 02:13:47 +0800 zihao.jiang (e7d9e91) + + * channels/rdpgfx: Make freerdp_client_codecs_prepare calls codec + reset. It fix broken h264 client from #3328. Also it + doesn't make sense that we don't need width and height for + codec initialization while we need them for codec reset + +2016-05-27 15:53:49 +0200 Norbert Federa (e8c4910) + + * fix segfaults casused by size_t format specifier + +2016-05-27 14:53:12 +0200 Hardening (00dd6f8) + + * Merge pull request #3372 from nfedera/fix-winpr-test-library + +2016-05-26 12:19:36 +0200 Norbert Federa (d2b2a92) + + * winpr/library: fix win32 test and some cleanup + +2016-05-27 11:19:50 +0200 Hardening (9f37f46) + + * Merge pull request #3374 from nfedera/fix-winpr-path + +2016-05-26 18:36:02 +0200 Norbert Federa (a45ac8d) + + * winpr/path: fix PathCchFindExtensionA and more + +2016-05-26 14:07:48 +0200 Hardening (ef1ddff) + + * Merge pull request #3373 from nfedera/fix-winpr-test-pipe + +2016-05-26 13:52:30 +0200 Norbert Federa (9370d98) + + * winpr/pipe: fix CreateNamedPipe test + +2016-05-26 00:20:37 +0800 zihao.jiang (4227983) + + * Server/shadow: Protect X operations on shared subystem X11 display + with X11 display lock + +2016-05-25 17:25:07 +0200 Bernhard Miklautz (17c125d) + + * Merge pull request #3369 from realjiangms/fix_mouseback_2796 + +2016-05-25 17:24:30 +0800 zihao.jiang (9f4465e) + + * Server/shadow: Fix issue 2796. Mouse cursor draw back issue + +2016-05-25 16:39:22 +0200 Bernhard Miklautz (8aec19d) + + * Merge pull request #3370 from + nfedera/fix-winpr-test-thread-createprocess + +2016-05-25 15:47:58 +0200 Norbert Federa (1b231f9) + + * winpr/thread: fix TestThreadCreateProcess + +2016-05-25 11:08:31 +0200 MartinHaimberger (9bfe3a6) + + * Merge pull request #3365 from nfedera/fix-winpr-synch-tests + +2016-05-24 22:33:27 +0200 Norbert Federa (aded51f) + + * winpr/synch: fix tests + +2016-05-24 15:41:45 +0200 akallabeth (53de4b8) + + * Merge pull request #3363 from nfedera/fix-mutex-implementation + +2016-05-24 13:35:11 +0200 Norbert Federa (386d290) + + * winpr/synch: fix mutex implementation + +2016-05-23 16:21:49 +0200 akallabeth (cf127eb) + + * Merge pull request #3357 from realjiangms/fix_rdpsnd_race + +2016-05-23 13:38:18 +0200 Martin Fleisz (a722fbf) + + * Merge pull request #3359 from bmiklautz/eventfd_leak + +2016-05-23 13:22:33 +0200 akallabeth (21e3515) + + * Merge pull request #3349 from byteboon/master + +2016-05-23 13:04:44 +0200 Bernhard Miklautz (5d03053) + + * winpr/event: fix file descriptor leak + +2016-05-20 01:02:08 +0800 zihao.jiang (444b678) + + * shadow/rdpsnd: Fix race condition in rdpsnd channel server. The + output buffer and format parameters are not protected. + This cause some data inconsistence if rdpsnd has own + thread + +2016-05-19 23:39:49 +0200 Hardening (aeabb95) + + * Merge pull request #3356 from rinov/master + +2016-05-20 01:17:49 +0900 rinov (c42edd9) + + * Update mf_mountain_lion.c + +2016-05-18 17:30:25 +0200 Norbert Federa (ca53e8b) + + * Merge pull request #3353 from bmiklautz/no_shared_libs + +2016-05-18 17:13:45 +0200 Bernhard Miklautz (41298d6) + + * build: fix builds with -DBUILD_SHARED_LIBS=OFF + +2016-05-16 09:53:38 -0700 byteboon (158be3a) + + * fixed kerberos authentication + +2016-05-13 11:32:48 +0200 Hardening (4e66df7) + + * Merge pull request #3333 from akallabeth/memleak_fixes + +2016-05-13 09:41:42 +0200 Bernhard Miklautz (9e3695f) + + * Merge pull request #3340 from rjcorrig/kb3153731 + +2016-05-12 14:38:23 -0400 Marc-André Moreau (1b97593) + + * Merge pull request #3341 from awakecoding/xcrush_fix + +2016-05-12 14:24:53 -0400 Marc-André Moreau (a75d89d) + + * libfreerdp-codec: make proper xcrush context reset fix + +2016-05-12 13:12:24 -0400 Robert Corrigan (73e13b0) + + * KB3153731: May 2016 DST update for Azerbaijan, Chile, Haiti and + Morocco + +2016-05-12 17:48:40 +0200 Martin Fleisz (eadc9e1) + + * Merge pull request #3335 from bmiklautz/wfreerdp_naming + +2016-05-12 09:41:57 -0400 Marc-André Moreau (ed326f6) + + * Merge pull request #3339 from awakecoding/xcrush_fix + +2016-05-12 09:22:24 -0400 Marc-André Moreau (892531d) + + * libfreerdp-codec: fix xcrush decompression, revert remote control + fix + +2016-05-12 11:47:10 +0200 Bernhard Miklautz (1ea3d4d) + + * wfreerdp: fix name build without client interface + +2016-05-12 10:01:30 +0200 Armin Novak (eacf2b5) + + * Fixed memory leaks. + +2016-05-12 09:28:12 +0200 Armin Novak (704d69d) + + * Fixed NULL pointer access. + +2016-05-11 17:00:35 -0400 Marc-André Moreau (9b7c53c) + + * Merge pull request #3329 from awakecoding/hv_fix + +2016-05-11 16:47:50 -0400 Marc-André Moreau (b24df90) + + * Merge pull request #3330 from awakecoding/xcrush_fix + +2016-05-11 16:35:20 -0400 Marc-André Moreau (a0630de) + + * libfreerdp-codec: fix xcrush context flush + +2016-05-11 15:52:36 -0400 Marc-André Moreau (e4714f3) + + * freerdp: fix Hyper-V connectivity, fix issues #2421 and #3325 + +2016-05-11 14:15:07 -0400 Marc-André Moreau (5b9b86d) + + * Merge pull request #3328 from awakecoding/gfx_fix + +2016-05-11 13:53:34 -0400 Marc-André Moreau (56f9b18) + + * libfreerdp-codec: fix error on empty RFX tileset, which can + sometimes happen + +2016-05-11 13:42:54 -0400 Marc-André Moreau (54cdd6a) + + * channels/rdpgfx: fix resetting of codec contexts + +2016-05-11 13:27:45 -0400 Marc-André Moreau (171198b) + + * Merge pull request #3260 from awakecoding/master + +2016-05-11 13:13:02 -0400 Marc-André Moreau (6b73757) + + * Merge branch 'master' of github.com:awakecoding/FreeRDP + +2016-05-11 13:12:44 -0400 Marc-André Moreau (d4c809c) + + * winpr: fix definitions of synchronization barrier and interlocked + functions + +2016-05-11 11:05:17 -0400 Marc-André Moreau (915b9a1) + + * Merge branch 'master' of github.com:FreeRDP/FreeRDP + +2016-05-11 09:44:26 +0200 akallabeth (c5940d8) + + * Merge pull request #3318 from bmiklautz/multilayoutpdu + +2016-05-11 09:40:18 +0200 akallabeth (6abdd4c) + + * Merge pull request #3321 from bmiklautz/client_interface + +2016-05-09 10:25:31 +0200 Bernhard Miklautz (2c0e73b) + + * client: disable the client interface per default + +2016-05-04 09:47:23 +0200 Bernhard Miklautz (a61a642) + + * core: don't advertise multi layout PDUs + 2016-05-03 17:04:45 +0200 Bernhard Miklautz (f828595) * Merge pull request #3282 from akallabeth/input_arg_checks @@ -166,10 +2516,30 @@ * Cleaned up empty if. +2016-03-30 10:58:36 -0400 Marc-André Moreau (a192967) + + * libwinpr-path: fix missing shlwapi.lib import + +2016-03-30 10:47:01 -0400 Marc-André Moreau (8fcc2aa) + + * Merge branch 'master' of github.com:awakecoding/FreeRDP + +2016-03-30 10:31:34 -0400 Marc-André Moreau (0d15539) + + * wfreerdp: fix Windows XP clipboard missing imports + 2016-03-30 15:20:53 +0200 akallabeth (445059b) * Merge pull request #3259 from bmiklautz/overlinking +2016-03-29 20:34:52 -0400 Marc-André Moreau (cedf6d9) + + * freerdp: more UWP porting + +2016-03-29 16:03:15 -0400 Marc-André Moreau (4d629a7) + + * freerdp: UWP porting + 2016-03-29 15:10:00 +0200 Bernhard Miklautz (bafe1aa) * usbdrc: remove unused dependencies @@ -182,6 +2552,10 @@ * winpr/TestFileGetStdHandle: rename variable stdout +2016-03-25 12:20:51 -0400 Marc-André Moreau (2201ac5) + + * winpr: fix PathFileExists on UWP + 2016-03-24 16:25:22 +0100 Armin Novak (50873be) * Added advanced gfx command line options. @@ -298,6 +2672,10 @@ * Merge pull request #3214 from hardening/fix_systemd_appender +2016-03-15 20:19:15 -0400 Marc-André Moreau (9211f44) + + * Merge branch 'master' of github.com:FreeRDP/FreeRDP + 2016-03-15 09:25:50 +0100 akallabeth (b35f306) * Merge pull request #3225 from mfleisz/fix_set_err_info @@ -362,6 +2740,10 @@ * Merge pull request #3213 from akallabeth/android_build_fixes +2016-03-11 14:42:16 -0500 Marc-André Moreau (3cbd7c0) + + * freerdp: fix freerdp_connect possible incorrect status code + 2016-03-11 11:22:59 +0100 Martin Fleisz (66ae3f2) * Merge pull request #3177 from akallabeth/codec_reset_fix @@ -444,6 +2826,18 @@ * Merge pull request #3181 from akallabeth/wlog_filter_fix +2016-03-07 21:21:17 -0500 Marc-André Moreau (c78a142) + + * Merge branch 'master' of github.com:awakecoding/FreeRDP + +2016-03-07 21:21:06 -0500 Marc-André Moreau (d61c2d4) + + * winpr: fix ini utils leak + +2016-03-07 10:19:50 -0500 Marc-André Moreau (ceefc4b) + + * Merge branch 'master' of github.com:FreeRDP/FreeRDP + 2016-03-07 15:39:59 +0100 Bernhard Miklautz (9f8baf3) * Merge pull request #3206 from akallabeth/openssl_unification @@ -1080,6 +3474,10 @@ * Mutualize definitions for the printer channel +2016-02-16 13:42:08 -0500 Marc-André Moreau (8fa25aa) + + * mfreerdp: fix build on 32-bit with mac audio + 2016-02-16 17:39:22 +0100 Bernhard Miklautz (12bd0ec) * winpr: BUMP the API version to 1.2 @@ -1124,6 +3522,10 @@ * Update BookmarkDB.java +2016-02-10 10:51:27 -0500 Marc-André Moreau (0547a31) + + * winpr: fix ini loader on Windows + 2016-02-10 11:17:34 +0100 Hardening (8bbbbf3) * Merge pull request #3116 from akallabeth/win_unicode_arg_fix @@ -1132,6 +3534,10 @@ * Printing help on invalid command line again. +2016-02-08 10:19:36 -0500 Marc-André Moreau (2f568aa) + + * winpr: fix GetComputerNameEx for UWP + 2016-02-08 14:36:31 +0100 Armin Novak (d67614a) * Reading unicode from command line. @@ -1140,10 +3546,18 @@ * Merge pull request #3111 from colemickens/hidpi-cli +2016-02-05 16:28:45 -0500 Marc-André Moreau (d0f413d) + + * winpr: initial port to Universal Windows Platform (UWP) + 2015-03-04 09:37:25 -0500 Isaac Richter (1f6ba79) * Enable display scaling in client +2016-02-05 11:39:45 -0500 Marc-André Moreau (bfca674) + + * Merge branch 'master' of github.com:FreeRDP/FreeRDP + 2016-02-05 11:52:07 +0100 Armin Novak (f456829) * Fixed API for old openssl versions < 1.0.0 @@ -1947,6 +4361,10 @@ * Fix compilation error under Visual Studio 2010 +2015-11-26 09:43:23 -0500 Marc-André Moreau (8cc799f) + + * libwinpr-synch: fix non-Win32 build + 2015-11-26 09:56:19 +0100 Hardening (3375865) * Merge pull request #2983 from nitomartinez/master @@ -1956,6 +4374,18 @@ * Fix formatting: else if in its own line and no brackets for single statements +2015-11-25 14:41:32 -0500 Marc-André Moreau (c0c9c93) + + * winpr: more Win32 fixes + +2015-11-25 13:46:25 -0500 Marc-André Moreau (c6eacd4) + + * Merge branch 'master' of github.com:awakecoding/FreeRDP + +2015-11-25 13:46:10 -0500 Marc-André Moreau (2f5d159) + + * winpr: fix WinXP backwards compatibility + 2015-11-25 08:36:49 +0100 Nito Martinez (89d8a68) * Disable setting socket options for preexisting socket like: @@ -2151,6 +4581,10 @@ * winpr/argv: fix CommandLineToArgvA memory access +2015-11-05 11:57:47 -0500 Marc-André Moreau (5350d8e) + + * mfreerdp: fix dynamic desktop resize + 2015-11-04 18:11:19 +0100 David FORT (5fbf26a) * Add an UDP appender to wLog @@ -2313,6 +4747,10 @@ * Merge pull request #2927 from MartinHaimberger/mh-log-returnvalues +2015-10-21 11:36:37 -0400 Marc-André Moreau (1b5f574) + + * winpr: fix OpenSSL includes + 2015-10-21 12:57:12 +0200 MartinHaimberger (16069e6) * Merge pull request #2939 from nfedera/fix-x11-clip-id diff --git a/channels/CMakeLists.txt b/channels/CMakeLists.txt index a395697..76a5716 100644 --- a/channels/CMakeLists.txt +++ b/channels/CMakeLists.txt @@ -167,7 +167,7 @@ macro(client_channel_install _targets _destination) endmacro(client_channel_install) macro(add_channel_client_library _module_prefix _module_name _channel_name _dynamic _entry) - if(${_dynamic} AND (NOT STATIC_CHANNELS)) + if(${_dynamic} AND (NOT BUILTIN_CHANNELS)) # On windows create dll version information. # Vendor, product and year are already set in top level CMakeLists.txt if (WIN32) @@ -193,14 +193,14 @@ macro(add_channel_client_library _module_prefix _module_name _channel_name _dyna set(${_module_prefix}_CHANNEL ${_channel_name} PARENT_SCOPE) set(${_module_prefix}_ENTRY ${_entry} PARENT_SCOPE) add_library(${_module_name} STATIC ${${_module_prefix}_SRCS}) - if (${CMAKE_VERSION} VERSION_LESS 2.8.12) + if (${CMAKE_VERSION} VERSION_LESS 2.8.12 OR NOT BUILD_SHARED_LIBS) client_channel_install(${_module_name} ${FREERDP_ADDIN_PATH}) endif() endif() endmacro(add_channel_client_library) macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_name _type _dynamic _entry) - if(${_dynamic} AND (NOT STATIC_CHANNELS)) + if(${_dynamic} AND (NOT BUILTIN_CHANNELS)) # On windows create dll version information. # Vendor, product and year are already set in top level CMakeLists.txt if (WIN32) @@ -225,14 +225,14 @@ macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_ set(${_module_prefix}_NAME ${_module_name} PARENT_SCOPE) set(${_module_prefix}_TYPE ${_type} PARENT_SCOPE) add_library(${_module_name} STATIC ${${_module_prefix}_SRCS}) - if (${CMAKE_VERSION} VERSION_LESS 2.8.12) + if (${CMAKE_VERSION} VERSION_LESS 2.8.12 OR NOT BUILD_SHARED_LIBS) client_channel_install(${_module_name} ${FREERDP_ADDIN_PATH}) endif() endif() endmacro(add_channel_client_subsystem_library) macro(add_channel_server_library _module_prefix _module_name _channel_name _dynamic _entry) - if(${_dynamic} AND (NOT STATIC_CHANNELS)) + if(${_dynamic} AND (NOT BUILTIN_CHANNELS)) # On windows create dll version information. # Vendor, product and year are already set in top level CMakeLists.txt if (WIN32) @@ -257,7 +257,7 @@ macro(add_channel_server_library _module_prefix _module_name _channel_name _dyna set(${_module_prefix}_CHANNEL ${_channel_name} PARENT_SCOPE) set(${_module_prefix}_ENTRY ${_entry} PARENT_SCOPE) add_library(${_module_name} STATIC ${${_module_prefix}_SRCS}) - if (${CMAKE_VERSION} VERSION_LESS 2.8.12) + if (${CMAKE_VERSION} VERSION_LESS 2.8.12 OR NOT BUILD_SHARED_LIBS) server_channel_install(${_module_name} ${FREERDP_ADDIN_PATH}) endif() endif() diff --git a/channels/audin/client/CMakeLists.txt b/channels/audin/client/CMakeLists.txt index 9e2f47b..0c2e393 100644 --- a/channels/audin/client/CMakeLists.txt +++ b/channels/audin/client/CMakeLists.txt @@ -27,7 +27,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE target_link_libraries(${MODULE_NAME} freerdp winpr) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/audin/client/alsa/audin_alsa.c b/channels/audin/client/alsa/audin_alsa.c index e49a1cc..cca9b37 100644 --- a/channels/audin/client/alsa/audin_alsa.c +++ b/channels/audin/client/alsa/audin_alsa.c @@ -69,7 +69,8 @@ typedef struct _AudinALSADevice rdpContext* rdpcontext; } AudinALSADevice; -static BOOL audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_handle) +static BOOL audin_alsa_set_params(AudinALSADevice* alsa, + snd_pcm_t* capture_handle) { int error; snd_pcm_hw_params_t* hw_params; @@ -77,26 +78,29 @@ static BOOL audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_hand if ((error = snd_pcm_hw_params_malloc(&hw_params)) < 0) { WLog_ERR(TAG, "snd_pcm_hw_params_malloc (%s)", - snd_strerror(error)); + snd_strerror(error)); return FALSE; } snd_pcm_hw_params_any(capture_handle, hw_params); - snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); + snd_pcm_hw_params_set_access(capture_handle, hw_params, + SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(capture_handle, hw_params, alsa->format); - snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &alsa->actual_rate, NULL); - snd_pcm_hw_params_set_channels_near(capture_handle, hw_params, &alsa->actual_channels); + snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &alsa->actual_rate, + NULL); + snd_pcm_hw_params_set_channels_near(capture_handle, hw_params, + &alsa->actual_channels); snd_pcm_hw_params(capture_handle, hw_params); snd_pcm_hw_params_free(hw_params); snd_pcm_prepare(capture_handle); if ((alsa->actual_rate != alsa->target_rate) || - (alsa->actual_channels != alsa->target_channels)) + (alsa->actual_channels != alsa->target_channels)) { DEBUG_DVC("actual rate %d / channel %d is " - "different from target rate %d / channel %d, resampling required.", - alsa->actual_rate, alsa->actual_channels, - alsa->target_rate, alsa->target_channels); + "different from target rate %d / channel %d, resampling required.", + alsa->actual_rate, alsa->actual_channels, + alsa->target_rate, alsa->target_channels); } return TRUE; @@ -107,7 +111,8 @@ static BOOL audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_hand * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size) +static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, + int size) { int frames; int cframes; @@ -116,38 +121,37 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size BYTE* encoded_data; int rbytes_per_frame; int tbytes_per_frame; - int status; - + int status; rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel; if ((alsa->target_rate == alsa->actual_rate) && - (alsa->target_channels == alsa->actual_channels)) + (alsa->target_channels == alsa->actual_channels)) { frames = size / rbytes_per_frame; } else { alsa->dsp_context->resample(alsa->dsp_context, src, alsa->bytes_per_channel, - alsa->actual_channels, alsa->actual_rate, size / rbytes_per_frame, - alsa->target_channels, alsa->target_rate); + alsa->actual_channels, alsa->actual_rate, size / rbytes_per_frame, + alsa->target_channels, alsa->target_rate); frames = alsa->dsp_context->resampled_frames; DEBUG_DVC("resampled %d frames at %d to %d frames at %d", - size / rbytes_per_frame, alsa->actual_rate, frames, alsa->target_rate); + size / rbytes_per_frame, alsa->actual_rate, frames, alsa->target_rate); size = frames * tbytes_per_frame; src = alsa->dsp_context->resampled_buffer; } while (frames > 0) { - status = WaitForSingleObject(alsa->stopEvent, 0); + status = WaitForSingleObject(alsa->stopEvent, 0); - if (status == WAIT_FAILED) - { - ret = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", ret); - break; - } + if (status == WAIT_FAILED) + { + ret = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", ret); + break; + } if (status == WAIT_OBJECT_0) break; @@ -157,8 +161,8 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size if (cframes > frames) cframes = frames; - CopyMemory(alsa->buffer + alsa->buffer_frames * tbytes_per_frame, src, cframes * tbytes_per_frame); - + CopyMemory(alsa->buffer + alsa->buffer_frames * tbytes_per_frame, src, + cframes * tbytes_per_frame); alsa->buffer_frames += cframes; if (alsa->buffer_frames >= alsa->frames_per_packet) @@ -166,8 +170,8 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size if (alsa->wformat == WAVE_FORMAT_DVI_ADPCM) { if (!alsa->dsp_context->encode_ima_adpcm(alsa->dsp_context, - alsa->buffer, alsa->buffer_frames * tbytes_per_frame, - alsa->target_channels, alsa->block_size)) + alsa->buffer, alsa->buffer_frames * tbytes_per_frame, + alsa->target_channels, alsa->block_size)) { ret = ERROR_INTERNAL_ERROR; break; @@ -175,9 +179,8 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size encoded_data = alsa->dsp_context->adpcm_buffer; encoded_size = alsa->dsp_context->adpcm_size; - DEBUG_DVC("encoded %d to %d", - alsa->buffer_frames * tbytes_per_frame, encoded_size); + alsa->buffer_frames * tbytes_per_frame, encoded_size); } else { @@ -185,22 +188,22 @@ static UINT audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size encoded_size = alsa->buffer_frames * tbytes_per_frame; } - status = WaitForSingleObject(alsa->stopEvent, 0); + status = WaitForSingleObject(alsa->stopEvent, 0); - if (status == WAIT_FAILED) - { - ret = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", ret); - break; - } + if (status == WAIT_FAILED) + { + ret = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", ret); + break; + } - if (status == WAIT_OBJECT_0) + if (status == WAIT_OBJECT_0) break; else { DEBUG_DVC("encoded %d [%d] to %d [%X]", alsa->buffer_frames, - tbytes_per_frame, encoded_size, - alsa->wformat); + tbytes_per_frame, encoded_size, + alsa->wformat); ret = alsa->receive(encoded_data, encoded_size, alsa->user_data); } @@ -225,81 +228,83 @@ static void* audin_alsa_thread_func(void* arg) int tbytes_per_frame; snd_pcm_t* capture_handle = NULL; AudinALSADevice* alsa = (AudinALSADevice*) arg; - DWORD status; - + DWORD status; DEBUG_DVC("in"); rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel; buffer = (BYTE*) calloc(1, rbytes_per_frame * alsa->frames_per_packet); + if (!buffer) { WLog_ERR(TAG, "calloc failed!"); - error = CHANNEL_RC_NO_MEMORY; - if (alsa->rdpcontext) - setChannelError(alsa->rdpcontext, error, "calloc failed!"); - goto out; + error = CHANNEL_RC_NO_MEMORY; + goto out; } freerdp_dsp_context_reset_adpcm(alsa->dsp_context); - if ((error = snd_pcm_open(&capture_handle, alsa->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0) - { - WLog_ERR(TAG, "snd_pcm_open (%s)", snd_strerror(error)); - goto out; - } + if ((error = snd_pcm_open(&capture_handle, alsa->device_name, + SND_PCM_STREAM_CAPTURE, 0)) < 0) + { + WLog_ERR(TAG, "snd_pcm_open (%s)", snd_strerror(error)); + error = CHANNEL_RC_INITIALIZATION_ERROR; + goto out; + } - if (!audin_alsa_set_params(alsa, capture_handle)) - { - WLog_ERR(TAG, "audin_alsa_set_params failed"); - goto out; - } + if (!audin_alsa_set_params(alsa, capture_handle)) + { + WLog_ERR(TAG, "audin_alsa_set_params failed"); + goto out; + } - while(1) - { - status = WaitForSingleObject(alsa->stopEvent, 0); + while (1) + { + status = WaitForSingleObject(alsa->stopEvent, 0); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %ld!", error); + break; + } - if (status == WAIT_OBJECT_0) - break; + if (status == WAIT_OBJECT_0) + break; - error = snd_pcm_readi(capture_handle, buffer, alsa->frames_per_packet); + error = snd_pcm_readi(capture_handle, buffer, alsa->frames_per_packet); - if (error == -EPIPE) - { - snd_pcm_recover(capture_handle, error, 0); - continue; - } - else if (error < 0) - { - WLog_ERR(TAG, "snd_pcm_readi (%s)", snd_strerror(error)); - break; - } + if (error == -EPIPE) + { + snd_pcm_recover(capture_handle, error, 0); + continue; + } + else if (error < 0) + { + WLog_ERR(TAG, "snd_pcm_readi (%s)", snd_strerror(error)); + break; + } - if ((error = audin_alsa_thread_receive(alsa, buffer, error * rbytes_per_frame))) - { - WLog_ERR(TAG, "audin_alsa_thread_receive failed with error %lu", error); - break; - } - - } + if ((error = audin_alsa_thread_receive(alsa, buffer, error * rbytes_per_frame))) + { + WLog_ERR(TAG, "audin_alsa_thread_receive failed with error %ld", error); + break; + } + } free(buffer); if (capture_handle) snd_pcm_close(capture_handle); + out: DEBUG_DVC("out"); - if (error && alsa->rdpcontext) - setChannelError(alsa->rdpcontext, error, "audin_alsa_thread_func reported an error"); - ExitThread((DWORD)error); + if (error && alsa->rdpcontext) + setChannelError(alsa->rdpcontext, error, + "audin_alsa_thread_func reported an error"); + + ExitThread((DWORD)error); return NULL; } @@ -311,36 +316,36 @@ out: static UINT audin_alsa_free(IAudinDevice* device) { AudinALSADevice* alsa = (AudinALSADevice*) device; - freerdp_dsp_context_free(alsa->dsp_context); - free(alsa->device_name); - free(alsa); return CHANNEL_RC_OK; } -static BOOL audin_alsa_format_supported(IAudinDevice* device, audinFormat* format) +static BOOL audin_alsa_format_supported(IAudinDevice* device, + audinFormat* format) { switch (format->wFormatTag) { case WAVE_FORMAT_PCM: if (format->cbSize == 0 && - (format->nSamplesPerSec <= 48000) && - (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && - (format->nChannels == 1 || format->nChannels == 2)) + (format->nSamplesPerSec <= 48000) && + (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && + (format->nChannels == 1 || format->nChannels == 2)) { return TRUE; } + break; case WAVE_FORMAT_DVI_ADPCM: if ((format->nSamplesPerSec <= 48000) && - (format->wBitsPerSample == 4) && - (format->nChannels == 1 || format->nChannels == 2)) + (format->wBitsPerSample == 4) && + (format->nChannels == 1 || format->nChannels == 2)) { return TRUE; } + break; } @@ -352,11 +357,11 @@ static BOOL audin_alsa_format_supported(IAudinDevice* device, audinFormat* forma * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UINT32 FramesPerPacket) +static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format, + UINT32 FramesPerPacket) { int bs; AudinALSADevice* alsa = (AudinALSADevice*) device; - alsa->target_rate = format->nSamplesPerSec; alsa->actual_rate = format->nSamplesPerSec; alsa->target_channels = format->nChannels; @@ -371,11 +376,13 @@ static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN alsa->format = SND_PCM_FORMAT_S8; alsa->bytes_per_channel = 1; break; + case 16: alsa->format = SND_PCM_FORMAT_S16_LE; alsa->bytes_per_channel = 2; break; } + break; case WAVE_FORMAT_DVI_ADPCM: @@ -383,9 +390,9 @@ static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN alsa->bytes_per_channel = 2; bs = (format->nBlockAlign - 4 * format->nChannels) * 4; alsa->frames_per_packet = (alsa->frames_per_packet * format->nChannels * 2 / - bs + 1) * bs / (format->nChannels * 2); + bs + 1) * bs / (format->nChannels * 2); DEBUG_DVC("aligned FramesPerPacket=%d", - alsa->frames_per_packet); + alsa->frames_per_packet); break; } @@ -399,34 +406,37 @@ static UINT audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_alsa_open(IAudinDevice* device, AudinReceive receive, void* user_data) +static UINT audin_alsa_open(IAudinDevice* device, AudinReceive receive, + void* user_data) { int tbytes_per_frame; AudinALSADevice* alsa = (AudinALSADevice*) device; - alsa->receive = receive; alsa->user_data = user_data; - tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel; alsa->buffer = (BYTE*) calloc(1, tbytes_per_frame * alsa->frames_per_packet); + if (!alsa->buffer) { WLog_ERR(TAG, "calloc failed!"); return ERROR_NOT_ENOUGH_MEMORY; } + alsa->buffer_frames = 0; - + if (!(alsa->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { WLog_ERR(TAG, "CreateEvent failed!"); goto error_out; } + if (!(alsa->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) audin_alsa_thread_func, alsa, 0, NULL))) + (LPTHREAD_START_ROUTINE) audin_alsa_thread_func, alsa, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); goto error_out; } + return CHANNEL_RC_OK; error_out: free(alsa->buffer); @@ -443,32 +453,30 @@ error_out: */ static UINT audin_alsa_close(IAudinDevice* device) { - UINT error = CHANNEL_RC_OK; + UINT error = CHANNEL_RC_OK; AudinALSADevice* alsa = (AudinALSADevice*) device; if (alsa->stopEvent) { SetEvent(alsa->stopEvent); + if (WaitForSingleObject(alsa->thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + return error; + } CloseHandle(alsa->stopEvent); alsa->stopEvent = NULL; - CloseHandle(alsa->thread); alsa->thread = NULL; } free(alsa->buffer); alsa->buffer = NULL; - alsa->receive = NULL; alsa->user_data = NULL; - return error; } @@ -483,17 +491,17 @@ COMMAND_LINE_ARGUMENT_A audin_alsa_args[] = * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* args) +static UINT audin_alsa_parse_addin_args(AudinALSADevice* device, + ADDIN_ARGV* args) { int status; DWORD flags; COMMAND_LINE_ARGUMENT_A* arg; AudinALSADevice* alsa = (AudinALSADevice*) device; - - flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD; - - status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_alsa_args, flags, alsa, NULL, NULL); - + flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | + COMMAND_LINE_IGN_UNKNOWN_KEYWORD; + status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, + audin_alsa_args, flags, alsa, NULL, NULL); arg = audin_alsa_args; do @@ -502,17 +510,16 @@ static UINT audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* arg continue; CommandLineSwitchStart(arg) - CommandLineSwitchCase(arg, "dev") { alsa->device_name = _strdup(arg->Value); - if(!alsa->device_name) + + if (!alsa->device_name) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } } - CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); @@ -520,7 +527,7 @@ static UINT audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* arg return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_audin_client_subsystem_entry alsa_freerdp_audin_client_subsystem_entry #else #define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry @@ -531,13 +538,14 @@ static UINT audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* arg * * @return 0 on success, otherwise a Win32 error code */ -UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) +UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS + pEntryPoints) { ADDIN_ARGV* args; AudinALSADevice* alsa; UINT error; - alsa = (AudinALSADevice*) calloc(1, sizeof(AudinALSADevice)); + if (!alsa) { WLog_ERR(TAG, "calloc failed!"); @@ -550,18 +558,18 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn alsa->iface.Close = audin_alsa_close; alsa->iface.Free = audin_alsa_free; alsa->rdpcontext = pEntryPoints->rdpcontext; - args = pEntryPoints->args; if ((error = audin_alsa_parse_addin_args(alsa, args))) { - WLog_ERR(TAG, "audin_alsa_parse_addin_args failed with errorcode %lu!", error); + WLog_ERR(TAG, "audin_alsa_parse_addin_args failed with errorcode %u!", error); goto error_out; } if (!alsa->device_name) { alsa->device_name = _strdup("default"); + if (!alsa->device_name) { WLog_ERR(TAG, "_strdup failed!"); @@ -577,8 +585,8 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn alsa->target_channels = 2; alsa->actual_channels = 2; alsa->bytes_per_channel = 2; - alsa->dsp_context = freerdp_dsp_context_new(); + if (!alsa->dsp_context) { WLog_ERR(TAG, "freerdp_dsp_context_new failed!"); @@ -586,9 +594,10 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn goto error_out; } - if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) alsa))) + if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, + (IAudinDevice*) alsa))) { - WLog_ERR(TAG, "RegisterAudinDevice failed with error %lu!", error); + WLog_ERR(TAG, "RegisterAudinDevice failed with error %u!", error); goto error_out; } diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 737c828..b97d94c 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -374,13 +374,13 @@ static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wSt IFCALLRET(audin->device->SetFormat, error, audin->device, format, FramesPerPacket); if (error != CHANNEL_RC_OK) { - WLog_ERR(TAG, "SetFormat failed with errorcode %lu", error); + WLog_ERR(TAG, "SetFormat failed with errorcode %u", error); return error; } IFCALLRET(audin->device->Open, error, audin->device, audin_receive_wave_data, callback); if (error != CHANNEL_RC_OK) { - WLog_ERR(TAG, "Open failed with errorcode %lu", error); + WLog_ERR(TAG, "Open failed with errorcode %u", error); return error; } } @@ -428,19 +428,19 @@ static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCall IFCALLRET(audin->device->Close, error, audin->device); if (error != CHANNEL_RC_OK) { - WLog_ERR(TAG, "Close failed with errorcode %lu", error); + WLog_ERR(TAG, "Close failed with errorcode %u", error); return error; } IFCALLRET(audin->device->SetFormat, error, audin->device, format, 0); if (error != CHANNEL_RC_OK) { - WLog_ERR(TAG, "SetFormat failed with errorcode %lu", error); + WLog_ERR(TAG, "SetFormat failed with errorcode %u", error); return error; } IFCALLRET(audin->device->Open, error, audin->device, audin_receive_wave_data, callback); if (error != CHANNEL_RC_OK) { - WLog_ERR(TAG, "Open failed with errorcode %lu", error); + WLog_ERR(TAG, "Open failed with errorcode %u", error); return error; } } @@ -509,7 +509,7 @@ static UINT audin_on_close(IWTSVirtualChannelCallback* pChannelCallback) { IFCALLRET(audin->device->Close, error, audin->device); if (error != CHANNEL_RC_OK) - WLog_ERR(TAG, "Close failed with errorcode %lu", error); + WLog_ERR(TAG, "Close failed with errorcode %u", error); } free(callback->formats); @@ -593,7 +593,7 @@ static UINT audin_plugin_terminated(IWTSPlugin* pPlugin) IFCALLRET(audin->device->Free, error, audin->device); if (error != CHANNEL_RC_OK) { - WLog_ERR(TAG, "Free failed with errorcode %lu", error); + WLog_ERR(TAG, "Free failed with errorcode %u", error); // dont stop on error } audin->device = NULL; @@ -662,7 +662,7 @@ static UINT audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, ADDI if ((error = entry(&entryPoints))) { - WLog_ERR(TAG, "%s entry returned error %lu.", name, error); + WLog_ERR(TAG, "%s entry returned error %u.", name, error); return error; } @@ -721,10 +721,8 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args) COMMAND_LINE_ARGUMENT_A* arg; UINT error; - if (args->argc == 1) - { + if (!args || args->argc == 1) return TRUE; - } flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD; @@ -746,7 +744,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args) { if ((error = audin_set_subsystem(audin, arg->Value))) { - WLog_ERR(TAG, "audin_set_subsystem failed with error %lu!", error); + WLog_ERR(TAG, "audin_set_subsystem failed with error %u!", error); return FALSE; } } @@ -754,7 +752,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args) { if ((error = audin_set_device_name(audin, arg->Value))) { - WLog_ERR(TAG, "audin_set_device_name failed with error %lu!", error); + WLog_ERR(TAG, "audin_set_device_name failed with error %u!", error); return FALSE; } } @@ -782,7 +780,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args) return TRUE; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DVCPluginEntry audin_DVCPluginEntry #else #define DVCPluginEntry FREERDP_API DVCPluginEntry @@ -860,7 +858,7 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { if ((error = audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args))) { - WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %lu!", + WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %u!", audin->subsystem, error); goto out; } @@ -871,17 +869,17 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { if ((error = audin_set_subsystem(audin, entry->subsystem))) { - WLog_ERR(TAG, "audin_set_subsystem for %s failed with error %lu!", + WLog_ERR(TAG, "audin_set_subsystem for %s failed with error %u!", entry->subsystem, error); } else if ((error = audin_set_device_name(audin, entry->device))) { - WLog_ERR(TAG, "audin_set_device_name for %s failed with error %lu!", + WLog_ERR(TAG, "audin_set_device_name for %s failed with error %u!", entry->subsystem, error); } else if ((error = audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args))) { - WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %lu!", + WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %u!", entry->subsystem, error); } diff --git a/channels/audin/client/audin_main.h b/channels/audin/client/audin_main.h index 05dd637..50a0b6c 100644 --- a/channels/audin/client/audin_main.h +++ b/channels/audin/client/audin_main.h @@ -33,9 +33,9 @@ #define TAG CHANNELS_TAG("audin.client") #ifdef WITH_DEBUG_DVC -#define DEBUG_DVC(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__) +#define DEBUG_DVC(...) WLog_DBG(TAG, __VA_ARGS__) #else -#define DEBUG_DVC(fmt, ...) do { } while (0) +#define DEBUG_DVC(...) do { } while (0) #endif #endif /* FREERDP_AUDIN_CLIENT_MAIN_H */ diff --git a/channels/audin/client/mac/audin_mac.c b/channels/audin/client/mac/audin_mac.c index d7d8db8..83bc6ec 100644 --- a/channels/audin/client/mac/audin_mac.c +++ b/channels/audin/client/mac/audin_mac.c @@ -33,6 +33,9 @@ #include #include +#define __COREFOUNDATION_CFPLUGINCOM__ 1 +#define IUNKNOWN_C_GUTS void *_reserved; void* QueryInterface; void* AddRef; void* Release + #include #include #include @@ -171,7 +174,7 @@ static void mac_audio_queue_input_cb(void *aqData, { AudinMacDevice* mac = (AudinMacDevice*)aqData; UINT error; - int encoded_size; + int encoded_size = 0; const BYTE *encoded_data; BYTE *buffer = inBuffer->mAudioData; int buffer_size = inBuffer->mAudioDataByteSize; @@ -212,7 +215,7 @@ static void mac_audio_queue_input_cb(void *aqData, if ((error = mac->receive(encoded_data, encoded_size, mac->user_data))) { - WLog_ERR(TAG, "mac->receive failed with error %lu", error); + WLog_ERR(TAG, "mac->receive failed with error %u", error); SetLastError(ERROR_INTERNAL_ERROR); return; } @@ -400,7 +403,7 @@ static UINT audin_mac_parse_addin_args(AudinMacDevice *device, ADDIN_ARGV *args) return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_audin_client_subsystem_entry mac_freerdp_audin_client_subsystem_entry #else #define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry @@ -435,7 +438,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn if ((error = audin_mac_parse_addin_args(mac, args))) { - WLog_ERR(TAG, "audin_mac_parse_addin_args failed with %lu!", error); + WLog_ERR(TAG, "audin_mac_parse_addin_args failed with %u!", error); goto error_out; } @@ -449,7 +452,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) mac))) { - WLog_ERR(TAG, "RegisterAudinDevice failed with error %lu!", error); + WLog_ERR(TAG, "RegisterAudinDevice failed with error %u!", error); goto error_out; } diff --git a/channels/audin/client/opensles/audin_opensl_es.c b/channels/audin/client/opensles/audin_opensl_es.c index cd0d399..0b1470b 100644 --- a/channels/audin/client/opensles/audin_opensl_es.c +++ b/channels/audin/client/opensles/audin_opensl_es.c @@ -112,7 +112,7 @@ static void* audin_opensles_thread_func(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); break; } @@ -125,7 +125,7 @@ static void* audin_opensles_thread_func(void* arg) rc = android_RecIn(opensles->stream, buffer.s, raw_size); if (rc < 0) { - WLog_ERR(TAG, "android_RecIn %lu", rc); + WLog_ERR(TAG, "android_RecIn %d", rc); continue; } @@ -401,7 +401,7 @@ static UINT audin_opensles_close(IAudinDevice* device) if (WaitForSingleObject(opensles->thread, INFINITE) == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); return error; } CloseHandle(opensles->stopEvent); @@ -473,7 +473,7 @@ static UINT audin_opensles_parse_addin_args(AudinOpenSLESDevice* device, return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_audin_client_subsystem_entry \ opensles_freerdp_audin_client_subsystem_entry #else diff --git a/channels/audin/client/opensles/opensl_io.c b/channels/audin/client/opensles/opensl_io.c index d9e684f..4792d33 100644 --- a/channels/audin/client/opensles/opensl_io.c +++ b/channels/audin/client/opensles/opensl_io.c @@ -6,14 +6,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -34,114 +34,132 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define CONV16BIT 32768 #define CONVMYFLT (1./32768.) -static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context); +static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void* context); // creates the OpenSL ES audio engine -static SLresult openSLCreateEngine(OPENSL_STREAM *p) +static SLresult openSLCreateEngine(OPENSL_STREAM* p) { - SLresult result; - // create engine - result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); + SLresult result; + // create engine + result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); DEBUG_DVC("engineObject=%p", p->engineObject); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // realize the engine - result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // realize the engine + result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); DEBUG_DVC("Realize=%d", result); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // get the engine interface, which is needed in order to create other objects - result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine)); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // get the engine interface, which is needed in order to create other objects + result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, + &(p->engineEngine)); DEBUG_DVC("engineEngine=%p", p->engineEngine); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // get the volume interface - important, this is optional! - result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_DEVICEVOLUME, &(p->deviceVolume)); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // get the volume interface - important, this is optional! + result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_DEVICEVOLUME, + &(p->deviceVolume)); DEBUG_DVC("deviceVolume=%p", p->deviceVolume); - if(result != SL_RESULT_SUCCESS) + + if (result != SL_RESULT_SUCCESS) { p->deviceVolume = NULL; result = SL_RESULT_SUCCESS; } - engine_end: +engine_end: assert(SL_RESULT_SUCCESS == result); - return result; + return result; } // Open the OpenSL ES device for input -static SLresult openSLRecOpen(OPENSL_STREAM *p){ - - SLresult result; - SLuint32 sr = p->sr; - SLuint32 channels = p->inchannels; - +static SLresult openSLRecOpen(OPENSL_STREAM* p) +{ + SLresult result; + SLuint32 sr = p->sr; + SLuint32 channels = p->inchannels; assert(!p->recorderObject); - if(channels){ + if (channels) + { + switch (sr) + { + case 8000: + sr = SL_SAMPLINGRATE_8; + break; - switch(sr){ + case 11025: + sr = SL_SAMPLINGRATE_11_025; + break; - case 8000: - sr = SL_SAMPLINGRATE_8; - break; - case 11025: - sr = SL_SAMPLINGRATE_11_025; - break; - case 16000: - sr = SL_SAMPLINGRATE_16; - break; - case 22050: - sr = SL_SAMPLINGRATE_22_05; - break; - case 24000: - sr = SL_SAMPLINGRATE_24; - break; - case 32000: - sr = SL_SAMPLINGRATE_32; - break; - case 44100: - sr = SL_SAMPLINGRATE_44_1; - break; - case 48000: - sr = SL_SAMPLINGRATE_48; - break; - case 64000: - sr = SL_SAMPLINGRATE_64; - break; - case 88200: - sr = SL_SAMPLINGRATE_88_2; - break; - case 96000: - sr = SL_SAMPLINGRATE_96; - break; - case 192000: - sr = SL_SAMPLINGRATE_192; - break; - default: - return -1; - } - - // configure audio source - SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, - SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; - SLDataSource audioSrc = {&loc_dev, NULL}; + case 16000: + sr = SL_SAMPLINGRATE_16; + break; - // configure audio sink - int speakers; - if(channels > 1) - speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; - else + case 22050: + sr = SL_SAMPLINGRATE_22_05; + break; + + case 24000: + sr = SL_SAMPLINGRATE_24; + break; + + case 32000: + sr = SL_SAMPLINGRATE_32; + break; + + case 44100: + sr = SL_SAMPLINGRATE_44_1; + break; + + case 48000: + sr = SL_SAMPLINGRATE_48; + break; + + case 64000: + sr = SL_SAMPLINGRATE_64; + break; + + case 88200: + sr = SL_SAMPLINGRATE_88_2; + break; + + case 96000: + sr = SL_SAMPLINGRATE_96; + break; + + case 192000: + sr = SL_SAMPLINGRATE_192; + break; + + default: + return -1; + } + + // configure audio source + SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, + SL_DEFAULTDEVICEID_AUDIOINPUT, NULL + }; + SLDataSource audioSrc = {&loc_dev, NULL}; + // configure audio sink + int speakers; + + if (channels > 1) + speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; + else speakers = SL_SPEAKER_FRONT_CENTER; - SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; - SLDataFormat_PCM format_pcm; - + + SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; + SLDataFormat_PCM format_pcm; format_pcm.formatType = SL_DATAFORMAT_PCM; format_pcm.numChannels = channels; format_pcm.samplesPerSec = sr; format_pcm.channelMask = speakers; - format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; - + format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; + if (16 == p->bits_per_sample) { format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; @@ -155,131 +173,135 @@ static SLresult openSLRecOpen(OPENSL_STREAM *p){ else assert(0); - SLDataSink audioSnk = {&loc_bq, &format_pcm}; - - // create audio recorder - // (requires the RECORD_AUDIO permission) - const SLInterfaceID id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; - const SLboolean req[] = {SL_BOOLEAN_TRUE}; - result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine, - &(p->recorderObject), &audioSrc, &audioSnk, 1, id, req); + SLDataSink audioSnk = {&loc_bq, &format_pcm}; + // create audio recorder + // (requires the RECORD_AUDIO permission) + const SLInterfaceID id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; + const SLboolean req[] = {SL_BOOLEAN_TRUE}; + result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine, + &(p->recorderObject), &audioSrc, &audioSnk, 1, id, req); DEBUG_DVC("p->recorderObject=%p", p->recorderObject); assert(!result); - if (SL_RESULT_SUCCESS != result) goto end_recopen; - // realize the audio recorder - result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // realize the audio recorder + result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE); DEBUG_DVC("Realize=%d", result); assert(!result); - if (SL_RESULT_SUCCESS != result) goto end_recopen; - // get the record interface - result = (*p->recorderObject)->GetInterface(p->recorderObject, - SL_IID_RECORD, &(p->recorderRecord)); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // get the record interface + result = (*p->recorderObject)->GetInterface(p->recorderObject, + SL_IID_RECORD, &(p->recorderRecord)); DEBUG_DVC("p->recorderRecord=%p", p->recorderRecord); assert(!result); - if (SL_RESULT_SUCCESS != result) goto end_recopen; - - // get the buffer queue interface - result = (*p->recorderObject)->GetInterface(p->recorderObject, - SL_IID_ANDROIDSIMPLEBUFFERQUEUE, - &(p->recorderBufferQueue)); - DEBUG_DVC("p->recorderBufferQueue=%p", p->recorderBufferQueue); - assert(!result); - if (SL_RESULT_SUCCESS != result) goto end_recopen; - // register callback on the buffer queue - result = (*p->recorderBufferQueue)->RegisterCallback(p->recorderBufferQueue, - bqRecorderCallback, p); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // get the buffer queue interface + result = (*p->recorderObject)->GetInterface(p->recorderObject, + SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &(p->recorderBufferQueue)); DEBUG_DVC("p->recorderBufferQueue=%p", p->recorderBufferQueue); assert(!result); - if (SL_RESULT_SUCCESS != result) + + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // register callback on the buffer queue + result = (*p->recorderBufferQueue)->RegisterCallback(p->recorderBufferQueue, + bqRecorderCallback, p); + DEBUG_DVC("p->recorderBufferQueue=%p", p->recorderBufferQueue); + assert(!result); + + if (SL_RESULT_SUCCESS != result) goto end_recopen; - end_recopen: - return result; - } - else return SL_RESULT_SUCCESS; - - + end_recopen: + return result; + } + else return SL_RESULT_SUCCESS; } // close the OpenSL IO and destroy the audio engine -static void openSLDestroyEngine(OPENSL_STREAM *p) +static void openSLDestroyEngine(OPENSL_STREAM* p) { DEBUG_DVC("p=%p", p); - // destroy audio recorder object, and invalidate all associated interfaces - if (p->recorderObject != NULL) { - (*p->recorderObject)->Destroy(p->recorderObject); - p->recorderObject = NULL; - p->recorderRecord = NULL; - p->recorderBufferQueue = NULL; - } - - // destroy engine object, and invalidate all associated interfaces - if (p->engineObject != NULL) { - (*p->engineObject)->Destroy(p->engineObject); - p->engineObject = NULL; - p->engineEngine = NULL; - } + // destroy audio recorder object, and invalidate all associated interfaces + if (p->recorderObject != NULL) + { + (*p->recorderObject)->Destroy(p->recorderObject); + p->recorderObject = NULL; + p->recorderRecord = NULL; + p->recorderBufferQueue = NULL; + } + // destroy engine object, and invalidate all associated interfaces + if (p->engineObject != NULL) + { + (*p->engineObject)->Destroy(p->engineObject); + p->engineObject = NULL; + p->engineEngine = NULL; + } } -// open the android audio device for input -OPENSL_STREAM *android_OpenRecDevice(char *name, int sr, int inchannels, - int bufferframes, int bits_per_sample) +// open the android audio device for input +OPENSL_STREAM* android_OpenRecDevice(char* name, int sr, int inchannels, + int bufferframes, int bits_per_sample) { - - OPENSL_STREAM *p; - p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM),1); - if (!p) - return NULL; + OPENSL_STREAM* p; + p = (OPENSL_STREAM*) calloc(sizeof(OPENSL_STREAM), 1); - p->inchannels = inchannels; - p->sr = sr; + if (!p) + return NULL; + + p->inchannels = inchannels; + p->sr = sr; p->queue = Queue_New(TRUE, -1, -1); p->buffersize = bufferframes; p->bits_per_sample = bits_per_sample; if ((p->bits_per_sample != 8) && (p->bits_per_sample != 16)) { - android_CloseRecDevice(p); + android_CloseRecDevice(p); return NULL; } - - if(openSLCreateEngine(p) != SL_RESULT_SUCCESS) - { - android_CloseRecDevice(p); - return NULL; - } - if(openSLRecOpen(p) != SL_RESULT_SUCCESS) + if (openSLCreateEngine(p) != SL_RESULT_SUCCESS) { - android_CloseRecDevice(p); - return NULL; - } + android_CloseRecDevice(p); + return NULL; + } - return p; + if (openSLRecOpen(p) != SL_RESULT_SUCCESS) + { + android_CloseRecDevice(p); + return NULL; + } + + return p; } // close the android audio device -void android_CloseRecDevice(OPENSL_STREAM *p) +void android_CloseRecDevice(OPENSL_STREAM* p) { DEBUG_DVC("p=%p", p); - if (p == NULL) - return; + if (p == NULL) + return; if (p->queue) { while (Queue_Count(p->queue) > 0) { - queue_element *e = Queue_Dequeue(p->queue); + queue_element* e = Queue_Dequeue(p->queue); free(e->data); free(e); } + Queue_Free(p->queue); } @@ -295,52 +317,47 @@ void android_CloseRecDevice(OPENSL_STREAM *p) free(p->prep); } - openSLDestroyEngine(p); - - free(p); + openSLDestroyEngine(p); + free(p); } // this callback handler is called every time a buffer finishes recording -void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) +static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void* context) { - queue_element *e; - - OPENSL_STREAM *p = (OPENSL_STREAM *) context; - + queue_element* e; + OPENSL_STREAM* p = (OPENSL_STREAM*) context; DEBUG_DVC("p=%p", p); - assert(p); assert(p->next); assert(p->prep); assert(p->queue); - e = calloc(1, sizeof(queue_element)); + if (!e) return; + e->data = calloc(p->buffersize, p->bits_per_sample / 8); + if (!e->data) { free(e); return; } - e->size = p->buffersize * p->bits_per_sample / 8; + e->size = p->buffersize * p->bits_per_sample / 8; Queue_Enqueue(p->queue, p->next); p->next = p->prep; p->prep = e; - - (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, - e->data, e->size); - + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + e->data, e->size); } - -// gets a buffer of size samples from the device -int android_RecIn(OPENSL_STREAM *p,short *buffer,int size) -{ - queue_element *e; - int rc; - DWORD status; +// gets a buffer of size samples from the device +int android_RecIn(OPENSL_STREAM* p, short* buffer, int size) +{ + queue_element* e; + int rc; + DWORD status; assert(p); assert(buffer); assert(size > 0); @@ -349,35 +366,33 @@ int android_RecIn(OPENSL_STREAM *p,short *buffer,int size) if (!p->prep) { p->prep = calloc(1, sizeof(queue_element)); - p->prep->data = calloc(p->buffersize, p->bits_per_sample / 8); p->prep->size = p->buffersize * p->bits_per_sample / 8; - p->next = calloc(1, sizeof(queue_element)); p->next->data = calloc(p->buffersize, p->bits_per_sample / 8); p->next->size = p->buffersize * p->bits_per_sample / 8; - - (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, - p->next->data, p->next->size); - (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, - p->prep->data, p->prep->size); - - (*p->recorderRecord)->SetRecordState(p->recorderRecord, SL_RECORDSTATE_RECORDING); + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + p->next->data, p->next->size); + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + p->prep->data, p->prep->size); + (*p->recorderRecord)->SetRecordState(p->recorderRecord, + SL_RECORDSTATE_RECORDING); } /* Wait for queue to be filled... */ if (!Queue_Count(p->queue)) - { - status = WaitForSingleObject(p->queue->event, INFINITE); - if (status == WAIT_FAILED) - { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", GetLastError()); - return -1; - } - } + { + status = WaitForSingleObject(p->queue->event, INFINITE); + if (status == WAIT_FAILED) + { + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", (unsigned long)GetLastError()); + return -1; + } + } e = Queue_Dequeue(p->queue); + if (!e) { WLog_ERR(TAG, "[ERROR] got e=%p from queue", e); @@ -387,11 +402,9 @@ int android_RecIn(OPENSL_STREAM *p,short *buffer,int size) rc = (e->size < size) ? e->size : size; assert(size == e->size); assert(p->buffersize * p->bits_per_sample / 8 == size); - memcpy(buffer, e->data, rc); free(e->data); free(e); - - return rc; + return rc; } diff --git a/channels/audin/client/opensles/opensl_io.h b/channels/audin/client/opensles/opensl_io.h index e76cd06..7d8d33f 100644 --- a/channels/audin/client/opensles/opensl_io.h +++ b/channels/audin/client/opensles/opensl_io.h @@ -6,14 +6,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -36,6 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include + #include #ifdef __cplusplus @@ -45,46 +47,48 @@ extern "C" { typedef struct { size_t size; - void *data; + void* data; } queue_element; -typedef struct opensl_stream { - // engine interfaces - SLObjectItf engineObject; - SLEngineItf engineEngine; +typedef struct opensl_stream +{ + // engine interfaces + SLObjectItf engineObject; + SLEngineItf engineEngine; // device interfaces SLDeviceVolumeItf deviceVolume; - // recorder interfaces - SLObjectItf recorderObject; - SLRecordItf recorderRecord; - SLAndroidSimpleBufferQueueItf recorderBufferQueue; + // recorder interfaces + SLObjectItf recorderObject; + SLRecordItf recorderRecord; + SLAndroidSimpleBufferQueueItf recorderBufferQueue; - unsigned int inchannels; - unsigned int sr; + unsigned int inchannels; + unsigned int sr; unsigned int buffersize; unsigned int bits_per_sample; - wQueue *queue; - queue_element *prep; - queue_element *next; + wQueue* queue; + queue_element* prep; + queue_element* next; } OPENSL_STREAM; - /* - Open the audio device with a given sampling rate (sr), input and output channels and IO buffer size - in frames. Returns a handle to the OpenSL stream - */ - OPENSL_STREAM* android_OpenRecDevice(char *name, int sr, int inchannels, - int bufferframes, int bits_per_sample); - /* - Close the audio device - */ - void android_CloseRecDevice(OPENSL_STREAM *p); - /* - Read a buffer from the OpenSL stream *p, of size samples. Returns the number of samples read. - */ - int android_RecIn(OPENSL_STREAM *p, short *buffer,int size); +/* +Open the audio device with a given sampling rate (sr), input and output channels and IO buffer size +in frames. Returns a handle to the OpenSL stream +*/ +FREERDP_LOCAL OPENSL_STREAM* android_OpenRecDevice(char* name, int sr, + int inchannels, + int bufferframes, int bits_per_sample); +/* +Close the audio device +*/ +FREERDP_LOCAL void android_CloseRecDevice(OPENSL_STREAM* p); +/* +Read a buffer from the OpenSL stream *p, of size samples. Returns the number of samples read. +*/ +FREERDP_LOCAL int android_RecIn(OPENSL_STREAM* p, short* buffer, int size); #ifdef __cplusplus }; #endif diff --git a/channels/audin/client/oss/audin_oss.c b/channels/audin/client/oss/audin_oss.c index 753298b..4b0e8e0 100644 --- a/channels/audin/client/oss/audin_oss.c +++ b/channels/audin/client/oss/audin_oss.c @@ -81,22 +81,25 @@ static int audin_oss_get_format(audinFormat* format) switch (format->wFormatTag) { case WAVE_FORMAT_PCM: - switch (format->wBitsPerSample) { case 8: return AFMT_S8; + case 16: return AFMT_S16_LE; } break; + case WAVE_FORMAT_ALAW: return AFMT_A_LAW; #if 0 /* This does not work on my desktop. */ + case WAVE_FORMAT_MULAW: return AFMT_MU_LAW; #endif + case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_DVI_ADPCM: return AFMT_S16_LE; @@ -105,7 +108,8 @@ static int audin_oss_get_format(audinFormat* format) return 0; } -static BOOL audin_oss_format_supported(IAudinDevice* device, audinFormat* format) +static BOOL audin_oss_format_supported(IAudinDevice* device, + audinFormat* format) { int req_fmt = 0; @@ -115,20 +119,19 @@ static BOOL audin_oss_format_supported(IAudinDevice* device, audinFormat* format switch (format->wFormatTag) { case WAVE_FORMAT_PCM: - if (format->cbSize != 0 || - format->nSamplesPerSec > 48000 || - (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || - (format->nChannels != 1 && format->nChannels != 2)) + format->nSamplesPerSec > 48000 || + (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || + (format->nChannels != 1 && format->nChannels != 2)) return FALSE; break; + case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_DVI_ADPCM: - if (format->nSamplesPerSec > 48000 || - format->wBitsPerSample != 4 || - (format->nChannels != 1 && format->nChannels != 2)) + format->wBitsPerSample != 4 || + (format->nChannels != 1 && format->nChannels != 2)) return FALSE; break; @@ -147,7 +150,8 @@ static BOOL audin_oss_format_supported(IAudinDevice* device, audinFormat* format * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_oss_set_format(IAudinDevice* device, audinFormat* format, UINT32 FramesPerPacket) +static UINT audin_oss_set_format(IAudinDevice* device, audinFormat* format, + UINT32 FramesPerPacket) { AudinOSSDevice* oss = (AudinOSSDevice*)device; @@ -165,6 +169,7 @@ static UINT audin_oss_set_format(IAudinDevice* device, audinFormat* format, UINT oss->format.wBitsPerSample *= 4; break; } + return CHANNEL_RC_OK; } @@ -255,7 +260,8 @@ static void* audin_oss_thread_func(void* arg) if (ioctl(pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1) OSS_LOG_ERR("SNDCTL_DSP_SETFRAGMENT failed", errno); - buffer_size = (oss->FramesPerPacket * oss->format.nChannels * (oss->format.wBitsPerSample / 8)); + buffer_size = (oss->FramesPerPacket * oss->format.nChannels * + (oss->format.wBitsPerSample / 8)); buffer = (BYTE*)calloc((buffer_size + sizeof(void*)), sizeof(BYTE)); if (NULL == buffer) @@ -274,7 +280,7 @@ static void* audin_oss_thread_func(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); goto err_out; } @@ -294,44 +300,50 @@ static void* audin_oss_thread_func(void* arg) continue; /* Process. */ - switch (oss->format.wFormatTag) { - case WAVE_FORMAT_ADPCM: - if (!oss->dsp_context->encode_ms_adpcm(oss->dsp_context, - buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign)) - { - error = ERROR_INTERNAL_ERROR; - goto err_out; - } - encoded_data = oss->dsp_context->adpcm_buffer; - encoded_size = oss->dsp_context->adpcm_size; - break; - case WAVE_FORMAT_DVI_ADPCM: - if (!oss->dsp_context->encode_ima_adpcm(oss->dsp_context, - buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign)) - { - error = ERROR_INTERNAL_ERROR; - goto err_out; - } - encoded_data = oss->dsp_context->adpcm_buffer; - encoded_size = oss->dsp_context->adpcm_size; - break; - default: - encoded_data = buffer; - encoded_size = buffer_size; - break; - } - if ((error = oss->receive(encoded_data, encoded_size, oss->user_data))) + switch (oss->format.wFormatTag) { - WLog_ERR(TAG, "oss->receive failed with error %lu", error); - break; + case WAVE_FORMAT_ADPCM: + if (!oss->dsp_context->encode_ms_adpcm(oss->dsp_context, + buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign)) + { + error = ERROR_INTERNAL_ERROR; + goto err_out; + } + + encoded_data = oss->dsp_context->adpcm_buffer; + encoded_size = oss->dsp_context->adpcm_size; + break; + + case WAVE_FORMAT_DVI_ADPCM: + if (!oss->dsp_context->encode_ima_adpcm(oss->dsp_context, + buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign)) + { + error = ERROR_INTERNAL_ERROR; + goto err_out; + } + + encoded_data = oss->dsp_context->adpcm_buffer; + encoded_size = oss->dsp_context->adpcm_size; + break; + + default: + encoded_data = buffer; + encoded_size = buffer_size; + break; } + if ((error = oss->receive(encoded_data, encoded_size, oss->user_data))) + { + WLog_ERR(TAG, "oss->receive failed with error %u", error); + break; + } } err_out: if (error && oss->rdpcontext) - setChannelError(oss->rdpcontext, error, "audin_oss_thread_func reported an error"); + setChannelError(oss->rdpcontext, error, + "audin_oss_thread_func reported an error"); if (pcm_handle != -1) { @@ -349,9 +361,10 @@ err_out: * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_oss_open(IAudinDevice *device, AudinReceive receive, void *user_data) { - AudinOSSDevice *oss = (AudinOSSDevice*)device; - +static UINT audin_oss_open(IAudinDevice* device, AudinReceive receive, + void* user_data) +{ + AudinOSSDevice* oss = (AudinOSSDevice*)device; oss->receive = receive; oss->user_data = user_data; @@ -360,8 +373,9 @@ static UINT audin_oss_open(IAudinDevice *device, AudinReceive receive, void *use WLog_ERR(TAG, "CreateEvent failed!"); return ERROR_INTERNAL_ERROR; } + if (!(oss->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE)audin_oss_thread_func, oss, 0, NULL))) + (LPTHREAD_START_ROUTINE)audin_oss_thread_func, oss, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); CloseHandle(oss->stopEvent); @@ -377,10 +391,10 @@ static UINT audin_oss_open(IAudinDevice *device, AudinReceive receive, void *use * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_oss_close(IAudinDevice *device) +static UINT audin_oss_close(IAudinDevice* device) { UINT error; - AudinOSSDevice *oss = (AudinOSSDevice*)device; + AudinOSSDevice* oss = (AudinOSSDevice*)device; if (device == NULL) return ERROR_INVALID_PARAMETER; @@ -388,12 +402,14 @@ static UINT audin_oss_close(IAudinDevice *device) if (oss->stopEvent != NULL) { SetEvent(oss->stopEvent); + if (WaitForSingleObject(oss->thread, INFINITE) == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); return error; } + CloseHandle(oss->stopEvent); oss->stopEvent = NULL; CloseHandle(oss->thread); @@ -402,7 +418,6 @@ static UINT audin_oss_close(IAudinDevice *device) oss->receive = NULL; oss->user_data = NULL; - return CHANNEL_RC_OK; } @@ -413,8 +428,7 @@ static UINT audin_oss_close(IAudinDevice *device) */ static UINT audin_oss_free(IAudinDevice* device) { - AudinOSSDevice *oss = (AudinOSSDevice*)device; - + AudinOSSDevice* oss = (AudinOSSDevice*)device; int error; if (device == NULL) @@ -424,9 +438,9 @@ static UINT audin_oss_free(IAudinDevice* device) { WLog_ERR(TAG, "audin_oss_close failed with error code %d!", error); } + freerdp_dsp_context_free(oss->dsp_context); free(oss); - return CHANNEL_RC_OK; } @@ -441,15 +455,17 @@ COMMAND_LINE_ARGUMENT_A audin_oss_args[] = * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args) +static UINT audin_oss_parse_addin_args(AudinOSSDevice* device, ADDIN_ARGV* args) { int status; char* str_num, *eptr; DWORD flags; COMMAND_LINE_ARGUMENT_A* arg; AudinOSSDevice* oss = (AudinOSSDevice*)device; - flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD; - status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv, audin_oss_args, flags, oss, NULL, NULL); + flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | + COMMAND_LINE_IGN_UNKNOWN_KEYWORD; + status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv, + audin_oss_args, flags, oss, NULL, NULL); if (status < 0) return ERROR_INVALID_PARAMETER; @@ -465,11 +481,13 @@ static UINT audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args) CommandLineSwitchCase(arg, "dev") { str_num = _strdup(arg->Value); + if (!str_num) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } + oss->dev_unit = strtol(str_num, &eptr, 10); if (oss->dev_unit < 0 || *eptr != '\0') @@ -480,10 +498,11 @@ static UINT audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args) CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); + return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_audin_client_subsystem_entry oss_freerdp_audin_client_subsystem_entry #else #define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry @@ -494,13 +513,14 @@ static UINT audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args) * * @return 0 on success, otherwise a Win32 error code */ -UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) +UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS + pEntryPoints) { - ADDIN_ARGV *args; - AudinOSSDevice *oss; + ADDIN_ARGV* args; + AudinOSSDevice* oss; UINT error; - oss = (AudinOSSDevice*)calloc(1, sizeof(AudinOSSDevice)); + if (!oss) { WLog_ERR(TAG, "calloc failed!"); @@ -513,17 +533,17 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn oss->iface.Close = audin_oss_close; oss->iface.Free = audin_oss_free; oss->rdpcontext = pEntryPoints->rdpcontext; - oss->dev_unit = -1; args = pEntryPoints->args; if ((error = audin_oss_parse_addin_args(oss, args))) { - WLog_ERR(TAG, "audin_oss_parse_addin_args failed with errorcode %lu!", error); + WLog_ERR(TAG, "audin_oss_parse_addin_args failed with errorcode %u!", error); goto error_out; } oss->dsp_context = freerdp_dsp_context_new(); + if (!oss->dsp_context) { WLog_ERR(TAG, "freerdp_dsp_context_new failed!"); @@ -531,9 +551,10 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn goto error_out; } - if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) oss))) + if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, + (IAudinDevice*) oss))) { - WLog_ERR(TAG, "RegisterAudinDevice failed with error %lu!", error); + WLog_ERR(TAG, "RegisterAudinDevice failed with error %u!", error); goto error_out; } @@ -542,5 +563,4 @@ error_out: freerdp_dsp_context_free(oss->dsp_context); free(oss); return error; - } diff --git a/channels/audin/client/pulse/audin_pulse.c b/channels/audin/client/pulse/audin_pulse.c index ad2f480..dd7104c 100644 --- a/channels/audin/client/pulse/audin_pulse.c +++ b/channels/audin/client/pulse/audin_pulse.c @@ -523,7 +523,7 @@ static UINT audin_pulse_parse_addin_args(AudinPulseDevice* device, ADDIN_ARGV* a return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_audin_client_subsystem_entry pulse_freerdp_audin_client_subsystem_entry #else #define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry @@ -558,7 +558,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn if ((error = audin_pulse_parse_addin_args(pulse, args))) { - WLog_ERR(TAG, "audin_pulse_parse_addin_args failed with error %lu!", error); + WLog_ERR(TAG, "audin_pulse_parse_addin_args failed with error %u!", error); goto error_out; } @@ -598,7 +598,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) pulse))) { - WLog_ERR(TAG, "RegisterAudinDevice failed with error %lu!", error); + WLog_ERR(TAG, "RegisterAudinDevice failed with error %u!", error); goto error_out; } diff --git a/channels/audin/client/winmm/CMakeLists.txt b/channels/audin/client/winmm/CMakeLists.txt index c7d3e2b..2eddb8e 100644 --- a/channels/audin/client/winmm/CMakeLists.txt +++ b/channels/audin/client/winmm/CMakeLists.txt @@ -26,12 +26,12 @@ add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_N -set(${MODULE_PREFIX}_LIBS freerdp winmm.lib) +set(${MODULE_PREFIX}_LIBS freerdp winpr winmm.lib) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/audin/client/winmm/audin_winmm.c b/channels/audin/client/winmm/audin_winmm.c index e59a84e..5090dd8 100644 --- a/channels/audin/client/winmm/audin_winmm.c +++ b/channels/audin/client/winmm/audin_winmm.c @@ -230,7 +230,7 @@ static UINT audin_winmm_close(IAudinDevice* device) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); return error; } @@ -391,7 +391,7 @@ static UINT audin_winmm_parse_addin_args(AudinWinmmDevice* device, ADDIN_ARGV* a return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_audin_client_subsystem_entry winmm_freerdp_audin_client_subsystem_entry #else #define freerdp_audin_client_subsystem_entry FREERDP_API freerdp_audin_client_subsystem_entry diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index 621af83..69926f3 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -69,13 +69,15 @@ typedef struct _audin_server * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_server_select_format(audin_server_context* context, int client_format_index) +static UINT audin_server_select_format(audin_server_context* context, + int client_format_index) { audin_server* audin = (audin_server*) context; if (client_format_index >= context->num_client_formats) { - WLog_ERR(TAG, "error in protocol: client_format_index >= context->num_client_formats!"); + WLog_ERR(TAG, + "error in protocol: client_format_index >= context->num_client_formats!"); return ERROR_INVALID_DATA; } @@ -85,6 +87,7 @@ static UINT audin_server_select_format(audin_server_context* context, int client { /* TODO: send MSG_SNDIN_FORMATCHANGE */ } + return CHANNEL_RC_OK; } @@ -96,14 +99,16 @@ static UINT audin_server_select_format(audin_server_context* context, int client static UINT audin_server_send_version(audin_server* audin, wStream* s) { ULONG written; - Stream_Write_UINT8(s, MSG_SNDIN_VERSION); Stream_Write_UINT32(s, 1); /* Version (4 bytes) */ - if (!WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written)) + + if (!WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), + Stream_GetPosition(s), &written)) { WLog_ERR(TAG, "WTSVirtualChannelWrite failed!"); return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -112,13 +117,15 @@ static UINT audin_server_send_version(audin_server* audin, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_server_recv_version(audin_server* audin, wStream* s, UINT32 length) +static UINT audin_server_recv_version(audin_server* audin, wStream* s, + UINT32 length) { UINT32 Version; if (length < 4) { - WLog_ERR(TAG, "error parsing version info: expected at least 4 bytes, got %d", length); + WLog_ERR(TAG, "error parsing version info: expected at least 4 bytes, got %d", + length); return ERROR_INVALID_DATA; } @@ -143,17 +150,18 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s) int i; UINT32 nAvgBytesPerSec; ULONG written; - Stream_SetPosition(s, 0); Stream_Write_UINT8(s, MSG_SNDIN_FORMATS); - Stream_Write_UINT32(s, audin->context.num_server_formats); /* NumFormats (4 bytes) */ - Stream_Write_UINT32(s, 0); /* cbSizeFormatsPacket (4 bytes), client-to-server only */ + Stream_Write_UINT32(s, + audin->context.num_server_formats); /* NumFormats (4 bytes) */ + Stream_Write_UINT32(s, + 0); /* cbSizeFormatsPacket (4 bytes), client-to-server only */ for (i = 0; i < audin->context.num_server_formats; i++) { nAvgBytesPerSec = audin->context.server_formats[i].nSamplesPerSec * - audin->context.server_formats[i].nChannels * - audin->context.server_formats[i].wBitsPerSample / 8; + audin->context.server_formats[i].nChannels * + audin->context.server_formats[i].wBitsPerSample / 8; if (!Stream_EnsureRemainingCapacity(s, 18)) { @@ -178,11 +186,12 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s) } Stream_Write(s, audin->context.server_formats[i].data, - audin->context.server_formats[i].cbSize); + audin->context.server_formats[i].cbSize); } } - return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; + return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), + Stream_GetPosition(s), &written) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } /** @@ -190,29 +199,36 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 length) +static UINT audin_server_recv_formats(audin_server* audin, wStream* s, + UINT32 length) { int i; UINT success = CHANNEL_RC_OK; if (length < 8) { - WLog_ERR(TAG, "error parsing rec formats: expected at least 8 bytes, got %d", length); + WLog_ERR(TAG, "error parsing rec formats: expected at least 8 bytes, got %d", + length); return ERROR_INVALID_DATA; } - Stream_Read_UINT32(s, audin->context.num_client_formats); /* NumFormats (4 bytes) */ + Stream_Read_UINT32(s, + audin->context.num_client_formats); /* NumFormats (4 bytes) */ Stream_Seek_UINT32(s); /* cbSizeFormatsPacket (4 bytes) */ length -= 8; if (audin->context.num_client_formats <= 0) { - WLog_ERR(TAG, "num_client_formats expected > 0 but got %d", audin->context.num_client_formats); + WLog_ERR(TAG, "num_client_formats expected > 0 but got %d", + audin->context.num_client_formats); return ERROR_INVALID_DATA; } - audin->context.client_formats = malloc(audin->context.num_client_formats * sizeof(AUDIO_FORMAT)); - ZeroMemory(audin->context.client_formats, audin->context.num_client_formats * sizeof(AUDIO_FORMAT)); + audin->context.client_formats = calloc(audin->context.num_client_formats, + sizeof(AUDIO_FORMAT)); + + if (!audin->context.client_formats) + return ERROR_NOT_ENOUGH_MEMORY; for (i = 0; i < audin->context.num_client_formats; i++) { @@ -239,8 +255,10 @@ static UINT audin_server_recv_formats(audin_server* audin, wStream* s, UINT32 le } IFCALLRET(audin->context.Opening, success, &audin->context); - if (success) - WLog_ERR(TAG, "context.Opening failed with error %lu", success); + + if (success) + WLog_ERR(TAG, "context.Opening failed with error %u", success); + return success; } @@ -256,16 +274,17 @@ static UINT audin_server_send_open(audin_server* audin, wStream* s) if (audin->context.selected_client_format < 0) { WLog_ERR(TAG, "audin->context.selected_client_format = %d", - audin->context.selected_client_format); + audin->context.selected_client_format); return ERROR_INVALID_DATA; } audin->opened = TRUE; - Stream_SetPosition(s, 0); Stream_Write_UINT8(s, MSG_SNDIN_OPEN); - Stream_Write_UINT32(s, audin->context.frames_per_packet); /* FramesPerPacket (4 bytes) */ - Stream_Write_UINT32(s, audin->context.selected_client_format); /* initialFormat (4 bytes) */ + Stream_Write_UINT32(s, + audin->context.frames_per_packet); /* FramesPerPacket (4 bytes) */ + Stream_Write_UINT32(s, + audin->context.selected_client_format); /* initialFormat (4 bytes) */ /* * [MS-RDPEAI] 3.2.5.1.6 * The second format specify the format that SHOULD be used to capture data from @@ -278,8 +297,8 @@ static UINT audin_server_send_open(audin_server* audin, wStream* s) Stream_Write_UINT16(s, 4); /* nBlockAlign */ Stream_Write_UINT16(s, 16); /* wBitsPerSample */ Stream_Write_UINT16(s, 0); /* cbSize */ - - return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; + return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), + Stream_GetPosition(s), &written) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } /** @@ -287,24 +306,24 @@ static UINT audin_server_send_open(audin_server* audin, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_server_recv_open_reply(audin_server* audin, wStream* s, UINT32 length) +static UINT audin_server_recv_open_reply(audin_server* audin, wStream* s, + UINT32 length) { - UINT32 Result; UINT success = CHANNEL_RC_OK; if (length < 4) { - WLog_ERR(TAG, "error parsing version info: expected at least 4 bytes, got %d", length); + WLog_ERR(TAG, "error parsing version info: expected at least 4 bytes, got %d", + length); return ERROR_INVALID_DATA; } Stream_Read_UINT32(s, Result); - IFCALLRET(audin->context.OpenResult, success, &audin->context, Result); - if (success) - WLog_ERR(TAG, "context.OpenResult failed with error %lu", success); + if (success) + WLog_ERR(TAG, "context.OpenResult failed with error %u", success); return success; } @@ -314,7 +333,8 @@ static UINT audin_server_recv_open_reply(audin_server* audin, wStream* s, UINT32 * * @return 0 on success, otherwise a Win32 error code */ -static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 length) +static UINT audin_server_recv_data(audin_server* audin, wStream* s, + UINT32 length) { AUDIO_FORMAT* format; int sbytes_per_sample; @@ -327,7 +347,7 @@ static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt if (audin->context.selected_client_format < 0) { WLog_ERR(TAG, "audin->context.selected_client_format = %d", - audin->context.selected_client_format); + audin->context.selected_client_format); return ERROR_INVALID_DATA; } @@ -336,7 +356,7 @@ static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt if (format->wFormatTag == WAVE_FORMAT_ADPCM) { audin->dsp_context->decode_ms_adpcm(audin->dsp_context, - Stream_Pointer(s), length, format->nChannels, format->nBlockAlign); + Stream_Pointer(s), length, format->nChannels, format->nBlockAlign); size = audin->dsp_context->adpcm_size; src = audin->dsp_context->adpcm_buffer; sbytes_per_sample = 2; @@ -345,7 +365,7 @@ static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt else if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM) { audin->dsp_context->decode_ima_adpcm(audin->dsp_context, - Stream_Pointer(s), length, format->nChannels, format->nBlockAlign); + Stream_Pointer(s), length, format->nChannels, format->nBlockAlign); size = audin->dsp_context->adpcm_size; src = audin->dsp_context->adpcm_buffer; sbytes_per_sample = 2; @@ -359,25 +379,26 @@ static UINT audin_server_recv_data(audin_server* audin, wStream* s, UINT32 lengt sbytes_per_frame = format->nChannels * sbytes_per_sample; } - if (format->nSamplesPerSec == audin->context.dst_format.nSamplesPerSec && format->nChannels == audin->context.dst_format.nChannels) + if (format->nSamplesPerSec == audin->context.dst_format.nSamplesPerSec + && format->nChannels == audin->context.dst_format.nChannels) { frames = size / sbytes_per_frame; } else { audin->dsp_context->resample(audin->dsp_context, src, sbytes_per_sample, - format->nChannels, format->nSamplesPerSec, size / sbytes_per_frame, - audin->context.dst_format.nChannels, audin->context.dst_format.nSamplesPerSec); + format->nChannels, format->nSamplesPerSec, size / sbytes_per_frame, + audin->context.dst_format.nChannels, audin->context.dst_format.nSamplesPerSec); frames = audin->dsp_context->resampled_frames; src = audin->dsp_context->resampled_buffer; } IFCALLRET(audin->context.ReceiveSamples, success, &audin->context, src, frames); - if (success) - WLog_ERR(TAG, "context.ReceiveSamples failed with error %lu", success); + if (success) + WLog_ERR(TAG, "context.ReceiveSamples failed with error %u", success); - return success; + return success; } static void* audin_server_thread_func(void* arg) @@ -393,12 +414,12 @@ static void* audin_server_thread_func(void* arg) audin_server* audin = (audin_server*) arg; UINT error = CHANNEL_RC_OK; DWORD status; - buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; - if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, + &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); @@ -420,17 +441,19 @@ static void* audin_server_thread_func(void* arg) while (1) { - if ((status = WaitForMultipleObjects(nCount, events, FALSE, 100)) == WAIT_OBJECT_0) + if ((status = WaitForMultipleObjects(nCount, events, FALSE, + 100)) == WAIT_OBJECT_0) goto out; if (status == WAIT_FAILED) { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error); goto out; } - if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) + if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, + &buffer, &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); error = ERROR_INTERNAL_ERROR; @@ -438,7 +461,6 @@ static void* audin_server_thread_func(void* arg) } ready = *((BOOL*) buffer); - WTSFreeMemory(buffer); if (ready) @@ -446,6 +468,7 @@ static void* audin_server_thread_func(void* arg) } s = Stream_New(NULL, 4096); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -453,26 +476,26 @@ static void* audin_server_thread_func(void* arg) goto out; } - if (ready) { if ((error = audin_server_send_version(audin, s))) { - WLog_ERR(TAG, "audin_server_send_version failed with error %lu!", error); + WLog_ERR(TAG, "audin_server_send_version failed with error %u!", error); goto out_capacity; } } while (ready) { - if ((status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE)) == WAIT_OBJECT_0) + if ((status = WaitForMultipleObjects(nCount, events, FALSE, + INFINITE)) == WAIT_OBJECT_0) break; if (status == WAIT_FAILED) { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); - goto out; + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error); + goto out; } Stream_SetPosition(s, 0); @@ -483,12 +506,15 @@ static void* audin_server_thread_func(void* arg) error = ERROR_INTERNAL_ERROR; break; } + if (BytesReturned < 1) continue; + if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) break; + if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s), - Stream_Capacity(s), &BytesReturned) == FALSE) + Stream_Capacity(s), &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; @@ -503,35 +529,40 @@ static void* audin_server_thread_func(void* arg) case MSG_SNDIN_VERSION: if ((error = audin_server_recv_version(audin, s, BytesReturned))) { - WLog_ERR(TAG, "audin_server_recv_version failed with error %lu!", error); - goto out_capacity; - } - if ((error = audin_server_send_formats(audin, s))) - { - WLog_ERR(TAG, "audin_server_send_formats failed with error %lu!", error); + WLog_ERR(TAG, "audin_server_recv_version failed with error %u!", error); goto out_capacity; } + + if ((error = audin_server_send_formats(audin, s))) + { + WLog_ERR(TAG, "audin_server_send_formats failed with error %u!", error); + goto out_capacity; + } + break; case MSG_SNDIN_FORMATS: if ((error = audin_server_recv_formats(audin, s, BytesReturned))) { - WLog_ERR(TAG, "audin_server_recv_formats failed with error %lu!", error); + WLog_ERR(TAG, "audin_server_recv_formats failed with error %u!", error); goto out_capacity; } + if ((error = audin_server_send_open(audin, s))) { - WLog_ERR(TAG, "audin_server_send_open failed with error %lu!", error); + WLog_ERR(TAG, "audin_server_send_open failed with error %u!", error); goto out_capacity; } + break; case MSG_SNDIN_OPEN_REPLY: if ((error = audin_server_recv_open_reply(audin, s, BytesReturned))) { - WLog_ERR(TAG, "audin_server_recv_open_reply failed with error %lu!", error); + WLog_ERR(TAG, "audin_server_recv_open_reply failed with error %u!", error); goto out_capacity; } + break; case MSG_SNDIN_DATA_INCOMING: @@ -540,9 +571,10 @@ static void* audin_server_thread_func(void* arg) case MSG_SNDIN_DATA: if ((error = audin_server_recv_data(audin, s, BytesReturned))) { - WLog_ERR(TAG, "audin_server_recv_data failed with error %lu!", error); + WLog_ERR(TAG, "audin_server_recv_data failed with error %u!", error); goto out_capacity; }; + break; case MSG_SNDIN_FORMATCHANGE: @@ -559,8 +591,10 @@ out_capacity: out: WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; + if (error && audin->context.rdpcontext) - setChannelError(audin->context.rdpcontext, error, "audin_server_thread_func reported an error"); + setChannelError(audin->context.rdpcontext, error, + "audin_server_thread_func reported an error"); ExitThread((DWORD)error); return NULL; @@ -574,18 +608,17 @@ static BOOL audin_server_open(audin_server_context* context) { PULONG pSessionId = NULL; DWORD BytesReturned = 0; - audin->SessionId = WTS_CURRENT_SESSION; if (WTSQuerySessionInformationA(context->vcm, WTS_CURRENT_SESSION, - WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned)) + WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned)) { - audin->SessionId = (DWORD) *pSessionId; + audin->SessionId = (DWORD) * pSessionId; WTSFreeMemory(pSessionId); } audin->audin_channel = WTSVirtualChannelOpenEx(audin->SessionId, - "AUDIO_INPUT", WTS_CHANNEL_OPTION_DYNAMIC); + "AUDIO_INPUT", WTS_CHANNEL_OPTION_DYNAMIC); if (!audin->audin_channel) { @@ -600,7 +633,7 @@ static BOOL audin_server_open(audin_server_context* context) } if (!(audin->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) audin_server_thread_func, (void*) audin, 0, NULL))) + (LPTHREAD_START_ROUTINE) audin_server_thread_func, (void*) audin, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); CloseHandle(audin->stopEvent); @@ -610,6 +643,7 @@ static BOOL audin_server_open(audin_server_context* context) return TRUE; } + WLog_ERR(TAG, "thread already running!"); return FALSE; } @@ -621,11 +655,12 @@ static BOOL audin_server_close(audin_server_context* context) if (audin->thread) { SetEvent(audin->stopEvent); + if (WaitForSingleObject(audin->thread, INFINITE) == WAIT_FAILED) - { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", GetLastError()); - return FALSE; - } + { + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", (unsigned long)GetLastError()); + return FALSE; + } CloseHandle(audin->thread); CloseHandle(audin->stopEvent); @@ -640,15 +675,14 @@ static BOOL audin_server_close(audin_server_context* context) } audin->context.selected_client_format = -1; - return TRUE; } audin_server_context* audin_server_context_new(HANDLE vcm) { audin_server* audin; + audin = (audin_server*)calloc(1, sizeof(audin_server)); - audin = (audin_server *)calloc(1, sizeof(audin_server)); if (!audin) { WLog_ERR(TAG, "calloc failed!"); @@ -661,7 +695,6 @@ audin_server_context* audin_server_context_new(HANDLE vcm) audin->context.SelectFormat = audin_server_select_format; audin->context.Open = audin_server_open; audin->context.Close = audin_server_close; - audin->dsp_context = freerdp_dsp_context_new(); if (!audin->dsp_context) @@ -677,7 +710,6 @@ audin_server_context* audin_server_context_new(HANDLE vcm) void audin_server_context_free(audin_server_context* context) { audin_server* audin = (audin_server*) context; - audin_server_close(context); if (audin->dsp_context) diff --git a/channels/client/CMakeLists.txt b/channels/client/CMakeLists.txt index 1b20dfe..f27940e 100644 --- a/channels/client/CMakeLists.txt +++ b/channels/client/CMakeLists.txt @@ -25,7 +25,7 @@ set(${MODULE_PREFIX}_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/addin.h) if(CHANNEL_STATIC_CLIENT_ENTRIES) -list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES) + list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES) endif() foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES}) @@ -38,6 +38,8 @@ foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES}) set(ENTRY_POINT_NAME "${STATIC_MODULE_CHANNEL}_${${STATIC_MODULE}_CLIENT_ENTRY}") if(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntry") set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS);") + elseif(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntryEx") + set(ENTRY_POINT_IMPORT "extern BOOL VCAPITYPE ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS,PVOID);") else() set(ENTRY_POINT_IMPORT "extern UINT ${ENTRY_POINT_NAME}();") endif() diff --git a/channels/client/addin.c b/channels/client/addin.c index a2d6880..ba28e2c 100644 --- a/channels/client/addin.c +++ b/channels/client/addin.c @@ -349,6 +349,24 @@ void freerdp_channels_addin_list_free(FREERDP_ADDIN** ppAddins) free(ppAddins); } +extern const STATIC_ENTRY CLIENT_VirtualChannelEntryEx_TABLE[]; + +BOOL freerdp_channels_is_virtual_channel_entry_ex(LPCSTR pszName) +{ + int i; + STATIC_ENTRY* entry; + + for (i = 0; CLIENT_VirtualChannelEntryEx_TABLE[i].name != NULL; i++) + { + entry = (STATIC_ENTRY*) &CLIENT_VirtualChannelEntryEx_TABLE[i]; + + if (!strcmp(entry->name, pszName)) + return TRUE; + } + + return FALSE; +} + void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags) { int i, j; @@ -380,6 +398,12 @@ void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsyste } else { + if (dwFlags & FREERDP_ADDIN_CHANNEL_ENTRYEX) + { + if (!freerdp_channels_is_virtual_channel_entry_ex(pszName)) + return NULL; + } + return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry; } } diff --git a/channels/cliprdr/client/CMakeLists.txt b/channels/cliprdr/client/CMakeLists.txt index c8ca544..6081bee 100644 --- a/channels/cliprdr/client/CMakeLists.txt +++ b/channels/cliprdr/client/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS cliprdr_main.c cliprdr_main.h) -add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") +add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx") set(${MODULE_PREFIX}_LIBS freerdp winpr) diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c index a7afae5..4748afb 100644 --- a/channels/cliprdr/client/cliprdr_format.c +++ b/channels/cliprdr/client/cliprdr_format.c @@ -265,7 +265,7 @@ UINT cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UI IFCALLRET(context->ServerFormatListResponse, error, context, &formatListResponse); if (error) - WLog_ERR(TAG, "ServerFormatListResponse failed with error %lu!", error); + WLog_ERR(TAG, "ServerFormatListResponse failed with error %u!", error); return error; } @@ -298,7 +298,7 @@ UINT cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UIN IFCALLRET(context->ServerFormatDataRequest, error, context, &formatDataRequest); if (error) - WLog_ERR(TAG, "ServerFormatDataRequest failed with error %lu!", error); + WLog_ERR(TAG, "ServerFormatDataRequest failed with error %u!", error); return error; } @@ -332,7 +332,7 @@ UINT cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UI IFCALLRET(context->ServerFormatDataResponse, error, context, &formatDataResponse); if (error) - WLog_ERR(TAG, "ServerFormatDataResponse failed with error %lu!", error); + WLog_ERR(TAG, "ServerFormatDataResponse failed with error %u!", error); return error; } diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 7ca0c94..0725b89 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -34,7 +34,7 @@ #include "cliprdr_main.h" #include "cliprdr_format.h" -const char* const CB_MSG_TYPE_STRINGS[] = +static const char* const CB_MSG_TYPE_STRINGS[] = { "", "CB_MONITOR_READY", @@ -53,16 +53,18 @@ const char* const CB_MSG_TYPE_STRINGS[] = CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr) { CliprdrClientContext* pInterface; + if (!cliprdr) return NULL; + pInterface = (CliprdrClientContext*) cliprdr->channelEntryPoints.pInterface; return pInterface; } -wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) +static wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, + UINT32 dataLen) { wStream* s; - s = Stream_New(NULL, dataLen + 8); if (!s) @@ -73,10 +75,8 @@ wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) Stream_Write_UINT16(s, msgType); Stream_Write_UINT16(s, msgFlags); - /* Write actual length after the entire packet has been constructed. */ Stream_Seek(s, 4); - return s; } @@ -85,20 +85,16 @@ wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) +static UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) { UINT32 pos; UINT32 dataLen; UINT status = CHANNEL_RC_OK; - pos = Stream_GetPosition(s); - dataLen = pos - 8; - Stream_SetPosition(s, 4); Stream_Write_UINT32(s, dataLen); Stream_SetPosition(s, pos); - #ifdef WITH_DEBUG_CLIPRDR WLog_DBG(TAG, "Cliprdr Sending (%d bytes)", dataLen + 8); winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8); @@ -110,18 +106,19 @@ UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) } else { - status = cliprdr->channelEntryPoints.pVirtualChannelWrite(cliprdr->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + status = cliprdr->channelEntryPoints.pVirtualChannelWriteEx(cliprdr->InitHandle, + cliprdr->OpenHandle, + Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } if (status != CHANNEL_RC_OK) WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); return status; } -void cliprdr_print_general_capability_flags(UINT32 flags) +static void cliprdr_print_general_capability_flags(UINT32 flags) { WLog_INFO(TAG, "generalFlags (0x%08X) {", flags); @@ -145,7 +142,8 @@ void cliprdr_print_general_capability_flags(UINT32 flags) * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s) +static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, + wStream* s) { UINT32 version; UINT32 generalFlags; @@ -162,20 +160,22 @@ static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* Stream_Read_UINT32(s, version); /* version (4 bytes) */ Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */ - DEBUG_CLIPRDR("Version: %d", version); #ifdef WITH_DEBUG_CLIPRDR cliprdr_print_general_capability_flags(generalFlags); #endif if (cliprdr->useLongFormatNames) - cliprdr->useLongFormatNames = (generalFlags & CB_USE_LONG_FORMAT_NAMES) ? TRUE : FALSE; + cliprdr->useLongFormatNames = (generalFlags & CB_USE_LONG_FORMAT_NAMES) ? TRUE : + FALSE; if (cliprdr->streamFileClipEnabled) - cliprdr->streamFileClipEnabled = (generalFlags & CB_STREAM_FILECLIP_ENABLED) ? TRUE : FALSE; + cliprdr->streamFileClipEnabled = (generalFlags & CB_STREAM_FILECLIP_ENABLED) ? + TRUE : FALSE; if (cliprdr->fileClipNoFilePaths) - cliprdr->fileClipNoFilePaths = (generalFlags & CB_FILECLIP_NO_FILE_PATHS) ? TRUE : FALSE; + cliprdr->fileClipNoFilePaths = (generalFlags & CB_FILECLIP_NO_FILE_PATHS) ? + TRUE : FALSE; if (cliprdr->canLockClipData) cliprdr->canLockClipData = (generalFlags & CB_CAN_LOCK_CLIPDATA) ? TRUE : FALSE; @@ -189,16 +189,16 @@ static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* } capabilities.cCapabilitiesSets = 1; - capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &(generalCapabilitySet); + capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) & + (generalCapabilitySet); generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL; generalCapabilitySet.capabilitySetLength = 12; generalCapabilitySet.version = version; generalCapabilitySet.generalFlags = generalFlags; - - IFCALLRET(context->ServerCapabilities, error, context, &capabilities); + if (error) - WLog_ERR(TAG, "ServerCapabilities failed with error %lu!", error); + WLog_ERR(TAG, "ServerCapabilities failed with error %u!", error); return error; } @@ -208,17 +208,16 @@ static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags) +static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, + UINT16 length, UINT16 flags) { UINT16 index; UINT16 lengthCapability; UINT16 cCapabilitiesSets; UINT16 capabilitySetType; UINT error = CHANNEL_RC_OK; - Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ Stream_Seek_UINT16(s); /* pad1 (2 bytes) */ - WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerCapabilities"); for (index = 0; index < cCapabilitiesSets; index++) @@ -231,9 +230,11 @@ static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 case CB_CAPSTYPE_GENERAL: if ((error = cliprdr_process_general_capability(cliprdr, s))) { - WLog_ERR(TAG, "cliprdr_process_general_capability failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_process_general_capability failed with error %u!", + error); return error; } + break; default: @@ -251,12 +252,12 @@ static UINT cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UINT16 length, UINT16 flags) +static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, + UINT16 length, UINT16 flags) { CLIPRDR_MONITOR_READY monitorReady; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "MonitorReady"); if (!context->custom) @@ -273,7 +274,6 @@ static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI * When the server capabilities pdu is not used, default capabilities * corresponding to a generalFlags field set to zero are assumed. */ - cliprdr->useLongFormatNames = FALSE; cliprdr->streamFileClipEnabled = FALSE; cliprdr->fileClipNoFilePaths = TRUE; @@ -283,10 +283,10 @@ static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI monitorReady.msgType = CB_MONITOR_READY; monitorReady.msgFlags = flags; monitorReady.dataLen = length; - IFCALLRET(context->MonitorReady, error, context, &monitorReady); + if (error) - WLog_ERR(TAG, "MonitorReady failed with error %lu!", error); + WLog_ERR(TAG, "MonitorReady failed with error %u!", error); return error; } @@ -296,12 +296,12 @@ static UINT cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags) +static UINT cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, + wStream* s, UINT32 length, UINT16 flags) { CLIPRDR_FILE_CONTENTS_REQUEST request; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsRequest"); if (!context->custom) @@ -319,22 +319,22 @@ static UINT cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream request.msgType = CB_FILECONTENTS_REQUEST; request.msgFlags = flags; request.dataLen = length; - Stream_Read_UINT32(s, request.streamId); /* streamId (4 bytes) */ Stream_Read_UINT32(s, request.listIndex); /* listIndex (4 bytes) */ Stream_Read_UINT32(s, request.dwFlags); /* dwFlags (4 bytes) */ Stream_Read_UINT32(s, request.nPositionLow); /* nPositionLow (4 bytes) */ Stream_Read_UINT32(s, request.nPositionHigh); /* nPositionHigh (4 bytes) */ Stream_Read_UINT32(s, request.cbRequested); /* cbRequested (4 bytes) */ + if (Stream_GetRemainingLength(s) >= 4) Stream_Read_UINT32(s, request.clipDataId); /* clipDataId (4 bytes) */ else request.clipDataId = 0; - IFCALLRET(context->ServerFileContentsRequest, error, context, &request); + if (error) - WLog_ERR(TAG, "ServerFileContentsRequest failed with error %lu!", error); + WLog_ERR(TAG, "ServerFileContentsRequest failed with error %u!", error); return error; } @@ -344,12 +344,12 @@ static UINT cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags) +static UINT cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, + wStream* s, UINT32 length, UINT16 flags) { CLIPRDR_FILE_CONTENTS_RESPONSE response; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsResponse"); if (!context->custom) @@ -367,16 +367,13 @@ static UINT cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStrea response.msgType = CB_FILECONTENTS_RESPONSE; response.msgFlags = flags; response.dataLen = length; - Stream_Read_UINT32(s, response.streamId); /* streamId (4 bytes) */ - response.cbRequested = length - 4; response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */ - - IFCALLRET(context->ServerFileContentsResponse, error, context, &response); + if (error) - WLog_ERR(TAG, "ServerFileContentsResponse failed with error %lu!", error); + WLog_ERR(TAG, "ServerFileContentsResponse failed with error %u!", error); return error; } @@ -386,12 +383,12 @@ static UINT cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStrea * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags) +static UINT cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, + UINT32 length, UINT16 flags) { CLIPRDR_LOCK_CLIPBOARD_DATA lockClipboardData; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "LockClipData"); if (!context->custom) @@ -409,12 +406,11 @@ static UINT cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UI lockClipboardData.msgType = CB_LOCK_CLIPDATA; lockClipboardData.msgFlags = flags; lockClipboardData.dataLen = length; - Stream_Read_UINT32(s, lockClipboardData.clipDataId); /* clipDataId (4 bytes) */ - IFCALLRET(context->ServerLockClipboardData, error, context, &lockClipboardData); + if (error) - WLog_ERR(TAG, "ServerLockClipboardData failed with error %lu!", error); + WLog_ERR(TAG, "ServerLockClipboardData failed with error %u!", error); return error; } @@ -424,12 +420,12 @@ static UINT cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UI * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags) +static UINT cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, + UINT32 length, UINT16 flags) { CLIPRDR_UNLOCK_CLIPBOARD_DATA unlockClipboardData; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; - WLog_Print(cliprdr->log, WLOG_DEBUG, "UnlockClipData"); if (!context->custom) @@ -447,13 +443,13 @@ static UINT cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, unlockClipboardData.msgType = CB_UNLOCK_CLIPDATA; unlockClipboardData.msgFlags = flags; unlockClipboardData.dataLen = length; + Stream_Read_UINT32(s, + unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */ + IFCALLRET(context->ServerUnlockClipboardData, error, context, + &unlockClipboardData); - Stream_Read_UINT32(s, unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */ - - - IFCALLRET(context->ServerUnlockClipboardData, error, context, &unlockClipboardData); if (error) - WLog_ERR(TAG, "ServerUnlockClipboardData failed with error %lu!", error); + WLog_ERR(TAG, "ServerUnlockClipboardData failed with error %u!", error); return error; } @@ -469,14 +465,12 @@ static UINT cliprdr_order_recv(cliprdrPlugin* cliprdr, wStream* s) UINT16 msgFlags; UINT32 dataLen; UINT error; - Stream_Read_UINT16(s, msgType); /* msgType (2 bytes) */ Stream_Read_UINT16(s, msgFlags); /* msgFlags (2 bytes) */ Stream_Read_UINT32(s, dataLen); /* dataLen (4 bytes) */ - #ifdef WITH_DEBUG_CLIPRDR WLog_DBG(TAG, "msgType: %s (%d), msgFlags: %d dataLen: %d", - CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); + CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8); #endif @@ -484,52 +478,72 @@ static UINT cliprdr_order_recv(cliprdrPlugin* cliprdr, wStream* s) { case CB_CLIP_CAPS: if ((error = cliprdr_process_clip_caps(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_clip_caps failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_process_clip_caps failed with error %u!", error); + break; case CB_MONITOR_READY: if ((error = cliprdr_process_monitor_ready(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_monitor_ready failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_process_monitor_ready failed with error %u!", error); + break; case CB_FORMAT_LIST: if ((error = cliprdr_process_format_list(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_format_list failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_process_format_list failed with error %u!", error); + break; case CB_FORMAT_LIST_RESPONSE: - if ((error = cliprdr_process_format_list_response(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_format_list_response failed with error %lu!", error); + if ((error = cliprdr_process_format_list_response(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_format_list_response failed with error %u!", + error); + break; case CB_FORMAT_DATA_REQUEST: - if ((error = cliprdr_process_format_data_request(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_format_data_request failed with error %lu!", error); + if ((error = cliprdr_process_format_data_request(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_format_data_request failed with error %u!", + error); + break; case CB_FORMAT_DATA_RESPONSE: - if ((error = cliprdr_process_format_data_response(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_format_data_response failed with error %lu!", error); + if ((error = cliprdr_process_format_data_response(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_format_data_response failed with error %u!", + error); + break; case CB_FILECONTENTS_REQUEST: - if ((error = cliprdr_process_filecontents_request(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_filecontents_request failed with error %lu!", error); + if ((error = cliprdr_process_filecontents_request(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_filecontents_request failed with error %u!", + error); + break; case CB_FILECONTENTS_RESPONSE: - if ((error = cliprdr_process_filecontents_response(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_filecontents_response failed with error %lu!", error); + if ((error = cliprdr_process_filecontents_response(cliprdr, s, dataLen, + msgFlags))) + WLog_ERR(TAG, "cliprdr_process_filecontents_response failed with error %u!", + error); + break; case CB_LOCK_CLIPDATA: if ((error = cliprdr_process_lock_clipdata(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_lock_clipdata failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_process_lock_clipdata failed with error %u!", error); + break; case CB_UNLOCK_CLIPDATA: if ((error = cliprdr_process_unlock_clipdata(cliprdr, s, dataLen, msgFlags))) - WLog_ERR(TAG, "cliprdr_process_lock_clipdata failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_process_lock_clipdata failed with error %u!", error); + break; default: @@ -551,12 +565,12 @@ static UINT cliprdr_order_recv(cliprdrPlugin* cliprdr, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILITIES* capabilities) +static UINT cliprdr_client_capabilities(CliprdrClientContext* context, + CLIPRDR_CAPABILITIES* capabilities) { wStream* s; CLIPRDR_GENERAL_CAPABILITY_SET* generalCapabilitySet; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN); if (!s) @@ -567,13 +581,14 @@ UINT cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILI Stream_Write_UINT16(s, 1); /* cCapabilitiesSets */ Stream_Write_UINT16(s, 0); /* pad1 */ - - generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) capabilities->capabilitySets; - Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetType); /* capabilitySetType */ - Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetLength); /* lengthCapability */ + generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) + capabilities->capabilitySets; + Stream_Write_UINT16(s, + generalCapabilitySet->capabilitySetType); /* capabilitySetType */ + Stream_Write_UINT16(s, + generalCapabilitySet->capabilitySetLength); /* lengthCapability */ Stream_Write_UINT32(s, generalCapabilitySet->version); /* version */ Stream_Write_UINT32(s, generalCapabilitySet->generalFlags); /* generalFlags */ - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientCapabilities"); return cliprdr_packet_send(cliprdr, s); } @@ -583,13 +598,13 @@ UINT cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILI * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTORY* tempDirectory) +static UINT cliprdr_temp_directory(CliprdrClientContext* context, + CLIPRDR_TEMP_DIRECTORY* tempDirectory) { int length; wStream* s; WCHAR* wszTempDir = NULL; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_TEMP_DIRECTORY, 0, 520 * 2); if (!s) @@ -598,7 +613,8 @@ UINT cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTOR return ERROR_INTERNAL_ERROR; } - length = ConvertToUnicode(CP_UTF8, 0, tempDirectory->szTempDir, -1, &wszTempDir, 0); + length = ConvertToUnicode(CP_UTF8, 0, tempDirectory->szTempDir, -1, &wszTempDir, + 0); if (length < 0) return ERROR_INTERNAL_ERROR; @@ -608,12 +624,9 @@ UINT cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTOR Stream_Write(s, wszTempDir, length * 2); Stream_Zero(s, (520 - length) * 2); - free(wszTempDir); - WLog_Print(cliprdr->log, WLOG_DEBUG, "TempDirectory: %s", - tempDirectory->szTempDir); - + tempDirectory->szTempDir); return cliprdr_packet_send(cliprdr, s); } @@ -622,7 +635,8 @@ UINT cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTOR * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList) +static UINT cliprdr_client_format_list(CliprdrClientContext* context, + CLIPRDR_FORMAT_LIST* formatList) { wStream* s; UINT32 index; @@ -640,7 +654,6 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI if (!cliprdr->useLongFormatNames) { length = formatList->numFormats * 36; - s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length); if (!s) @@ -651,13 +664,10 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI for (index = 0; index < formatList->numFormats; index++) { - format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); - + format = (CLIPRDR_FORMAT*) & (formatList->formats[index]); Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */ - formatNameSize = 0; formatNameLength = 0; - szFormatName = format->formatName; if (asciiNames) @@ -676,7 +686,8 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI wszFormatName = NULL; if (szFormatName) - formatNameSize = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName, 0); + formatNameSize = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName, + 0); if (formatNameSize > 15) formatNameSize = 15; @@ -685,7 +696,6 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI Stream_Write(s, wszFormatName, formatNameSize * 2); Stream_Zero(s, 32 - (formatNameSize * 2)); - free(wszFormatName); } } @@ -694,12 +704,13 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI { for (index = 0; index < formatList->numFormats; index++) { - format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); + format = (CLIPRDR_FORMAT*) & (formatList->formats[index]); length += 4; formatNameSize = 2; if (format->formatName) - formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, 0) * 2; + formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, + 0) * 2; length += formatNameSize; } @@ -714,7 +725,7 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI for (index = 0; index < formatList->numFormats; index++) { - format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); + format = (CLIPRDR_FORMAT*) & (formatList->formats[index]); Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */ if (format->formatName) @@ -722,7 +733,7 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI lpWideCharStr = (LPWSTR) Stream_Pointer(s); cchWideChar = (Stream_Capacity(s) - Stream_GetPosition(s)) / 2; formatNameSize = MultiByteToWideChar(CP_UTF8, 0, - format->formatName, -1, lpWideCharStr, cchWideChar) * 2; + format->formatName, -1, lpWideCharStr, cchWideChar) * 2; Stream_Seek(s, formatNameSize); } else @@ -733,8 +744,7 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI } WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatList: numFormats: %d", - formatList->numFormats); - + formatList->numFormats); return cliprdr_packet_send(cliprdr, s); } @@ -743,15 +753,15 @@ UINT cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LI * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_format_list_response(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse) +static UINT cliprdr_client_format_list_response(CliprdrClientContext* context, + CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - formatListResponse->msgType = CB_FORMAT_LIST_RESPONSE; formatListResponse->dataLen = 0; - - s = cliprdr_packet_new(formatListResponse->msgType, formatListResponse->msgFlags, formatListResponse->dataLen); + s = cliprdr_packet_new(formatListResponse->msgType, + formatListResponse->msgFlags, formatListResponse->dataLen); if (!s) { @@ -768,11 +778,11 @@ UINT cliprdr_client_format_list_response(CliprdrClientContext* context, CLIPRDR_ * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData) +static UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, + CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4); if (!s) @@ -781,11 +791,11 @@ UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, CLIPRDR_L return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, lockClipboardData->clipDataId); /* clipDataId (4 bytes) */ - - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientLockClipboardData: clipDataId: 0x%04X", - lockClipboardData->clipDataId); - + Stream_Write_UINT32(s, + lockClipboardData->clipDataId); /* clipDataId (4 bytes) */ + WLog_Print(cliprdr->log, WLOG_DEBUG, + "ClientLockClipboardData: clipDataId: 0x%04X", + lockClipboardData->clipDataId); return cliprdr_packet_send(cliprdr, s);; } @@ -794,23 +804,24 @@ UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, CLIPRDR_L * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) +static UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context, + CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_UNLOCK_CLIPDATA, 0, 4); - if (!s) { + if (!s) + { WLog_ERR(TAG, "cliprdr_packet_new failed!"); return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */ - - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientUnlockClipboardData: clipDataId: 0x%04X", - unlockClipboardData->clipDataId); - + Stream_Write_UINT32(s, + unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */ + WLog_Print(cliprdr->log, WLOG_DEBUG, + "ClientUnlockClipboardData: clipDataId: 0x%04X", + unlockClipboardData->clipDataId); return cliprdr_packet_send(cliprdr, s); } @@ -819,16 +830,16 @@ UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context, CLIPRDR * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) +static UINT cliprdr_client_format_data_request(CliprdrClientContext* context, + CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - formatDataRequest->msgType = CB_FORMAT_DATA_REQUEST; formatDataRequest->msgFlags = 0; formatDataRequest->dataLen = 4; - - s = cliprdr_packet_new(formatDataRequest->msgType, formatDataRequest->msgFlags, formatDataRequest->dataLen); + s = cliprdr_packet_new(formatDataRequest->msgType, formatDataRequest->msgFlags, + formatDataRequest->dataLen); if (!s) { @@ -836,8 +847,8 @@ UINT cliprdr_client_format_data_request(CliprdrClientContext* context, CLIPRDR_F return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */ - + Stream_Write_UINT32(s, + formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */ WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatDataRequest"); return cliprdr_packet_send(cliprdr, s); } @@ -847,14 +858,14 @@ UINT cliprdr_client_format_data_request(CliprdrClientContext* context, CLIPRDR_F * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_format_data_response(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) +static UINT cliprdr_client_format_data_response(CliprdrClientContext* context, + CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - formatDataResponse->msgType = CB_FORMAT_DATA_RESPONSE; - - s = cliprdr_packet_new(formatDataResponse->msgType, formatDataResponse->msgFlags, formatDataResponse->dataLen); + s = cliprdr_packet_new(formatDataResponse->msgType, + formatDataResponse->msgFlags, formatDataResponse->dataLen); if (!s) { @@ -862,8 +873,8 @@ UINT cliprdr_client_format_data_response(CliprdrClientContext* context, CLIPRDR_ return ERROR_INTERNAL_ERROR; } - Stream_Write(s, formatDataResponse->requestedFormatData, formatDataResponse->dataLen); - + Stream_Write(s, formatDataResponse->requestedFormatData, + formatDataResponse->dataLen); WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatDataResponse"); return cliprdr_packet_send(cliprdr, s); } @@ -873,11 +884,11 @@ UINT cliprdr_client_format_data_response(CliprdrClientContext* context, CLIPRDR_ * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_file_contents_request(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest) +static UINT cliprdr_client_file_contents_request(CliprdrClientContext* context, + CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; - s = cliprdr_packet_new(CB_FILECONTENTS_REQUEST, 0, 28); if (!s) @@ -887,16 +898,20 @@ UINT cliprdr_client_file_contents_request(CliprdrClientContext* context, CLIPRDR } Stream_Write_UINT32(s, fileContentsRequest->streamId); /* streamId (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->listIndex); /* listIndex (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->listIndex); /* listIndex (4 bytes) */ Stream_Write_UINT32(s, fileContentsRequest->dwFlags); /* dwFlags (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->nPositionLow); /* nPositionLow (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->nPositionHigh); /* nPositionHigh (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->cbRequested); /* cbRequested (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->clipDataId); /* clipDataId (4 bytes) */ - - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFileContentsRequest: streamId: 0x%04X", - fileContentsRequest->streamId); - + Stream_Write_UINT32(s, + fileContentsRequest->nPositionLow); /* nPositionLow (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->nPositionHigh); /* nPositionHigh (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->cbRequested); /* cbRequested (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->clipDataId); /* clipDataId (4 bytes) */ + WLog_Print(cliprdr->log, WLOG_DEBUG, + "ClientFileContentsRequest: streamId: 0x%04X", + fileContentsRequest->streamId); return cliprdr_packet_send(cliprdr, s); } @@ -905,7 +920,8 @@ UINT cliprdr_client_file_contents_request(CliprdrClientContext* context, CLIPRDR * * @return 0 on success, otherwise a Win32 error code */ -UINT cliprdr_client_file_contents_response(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse) +static UINT cliprdr_client_file_contents_response(CliprdrClientContext* context, + CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse) { wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; @@ -914,7 +930,7 @@ UINT cliprdr_client_file_contents_response(CliprdrClientContext* context, CLIPRD fileContentsResponse->cbRequested = sizeof(UINT64); s = cliprdr_packet_new(CB_FILECONTENTS_RESPONSE, fileContentsResponse->msgFlags, - 4 + fileContentsResponse->cbRequested); + 4 + fileContentsResponse->cbRequested); if (!s) { @@ -923,120 +939,26 @@ UINT cliprdr_client_file_contents_response(CliprdrClientContext* context, CLIPRD } Stream_Write_UINT32(s, fileContentsResponse->streamId); /* streamId (4 bytes) */ - /** * requestedFileContentsData: * FILECONTENTS_SIZE: file size as UINT64 * FILECONTENTS_RANGE: file data from requested range */ - - Stream_Write(s, fileContentsResponse->requestedData, fileContentsResponse->cbRequested); - - WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFileContentsResponse: streamId: 0x%04X", - fileContentsResponse->streamId); - + Stream_Write(s, fileContentsResponse->requestedData, + fileContentsResponse->cbRequested); + WLog_Print(cliprdr->log, WLOG_DEBUG, + "ClientFileContentsResponse: streamId: 0x%04X", + fileContentsResponse->streamId); return cliprdr_packet_send(cliprdr, s); } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT cliprdr_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - g_InitHandles = ListDictionary_New(TRUE); - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return ERROR_NOT_ENOUGH_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* cliprdr_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void cliprdr_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT cliprdr_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - g_OpenHandles = ListDictionary_New(TRUE); - - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return ERROR_NOT_ENOUGH_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - - return CHANNEL_RC_OK; -} - -void* cliprdr_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void cliprdr_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT cliprdr_virtual_channel_event_data_received(cliprdrPlugin* cliprdr, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -1059,7 +981,6 @@ static UINT cliprdr_virtual_channel_event_data_received(cliprdrPlugin* cliprdr, return CHANNEL_RC_NO_MEMORY; } - if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) { Stream_Free(cliprdr->data_in, TRUE); @@ -1087,27 +1008,30 @@ static UINT cliprdr_virtual_channel_event_data_received(cliprdrPlugin* cliprdr, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE cliprdr_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE cliprdr_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - cliprdrPlugin* cliprdr; UINT error = CHANNEL_RC_OK; + cliprdrPlugin* cliprdr = (cliprdrPlugin*) lpUserParam; - cliprdr = (cliprdrPlugin*) cliprdr_get_open_handle_data(openHandle); - - if (!cliprdr) + if (!cliprdr || (cliprdr->OpenHandle != openHandle)) { - WLog_ERR(TAG, "cliprdr_virtual_channel_open_event: error no match"); + WLog_ERR(TAG, "error no match"); return; } switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - error = cliprdr_virtual_channel_event_data_received(cliprdr, pData, dataLength, totalLength, dataFlags); + if ((error = cliprdr_virtual_channel_event_data_received(cliprdr, pData, dataLength, + totalLength, dataFlags))) + WLog_ERR(TAG, "failed with error %u", error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -1119,8 +1043,8 @@ static VOID VCAPITYPE cliprdr_virtual_channel_open_event(DWORD openHandle, UINT } if (error && cliprdr->context->rdpcontext) - setChannelError(cliprdr->context->rdpcontext, error, "cliprdr_virtual_channel_open_event reported an error"); - + setChannelError(cliprdr->context->rdpcontext, error, + "cliprdr_virtual_channel_open_event_ex reported an error"); } static void* cliprdr_virtual_channel_client_thread(void* arg) @@ -1145,22 +1069,25 @@ static void* cliprdr_virtual_channel_client_thread(void* arg) error = ERROR_INTERNAL_ERROR; break; } + if (message.id == WMQ_QUIT) break; if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = cliprdr_order_recv(cliprdr, data))) { - WLog_ERR(TAG, "cliprdr_order_recv failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_order_recv failed with error %u!", error); break; } } } if (error && cliprdr->context->rdpcontext) - setChannelError(cliprdr->context->rdpcontext, error, "cliprdr_virtual_channel_client_thread reported an error"); + setChannelError(cliprdr->context->rdpcontext, error, + "cliprdr_virtual_channel_client_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -1171,28 +1098,23 @@ static void* cliprdr_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_virtual_channel_event_connected(cliprdrPlugin* cliprdr, LPVOID pData, UINT32 dataLength) +static UINT cliprdr_virtual_channel_event_connected(cliprdrPlugin* cliprdr, + LPVOID pData, UINT32 dataLength) { UINT32 status; - UINT error; - - status = cliprdr->channelEntryPoints.pVirtualChannelOpen(cliprdr->InitHandle, - &cliprdr->OpenHandle, cliprdr->channelDef.name, cliprdr_virtual_channel_open_event); + status = cliprdr->channelEntryPoints.pVirtualChannelOpenEx(cliprdr->InitHandle, + &cliprdr->OpenHandle, cliprdr->channelDef.name, + cliprdr_virtual_channel_open_event_ex); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); return status; } - if ((error = cliprdr_add_open_handle_data(cliprdr->OpenHandle, cliprdr))) - { - WLog_ERR(TAG, "cliprdr_add_open_handle_data failed with error %lu", error); - return error; - } - cliprdr->queue = MessageQueue_New(NULL); + if (!cliprdr->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -1200,13 +1122,15 @@ static UINT cliprdr_virtual_channel_event_connected(cliprdrPlugin* cliprdr, LPVO } if (!(cliprdr->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) cliprdr_virtual_channel_client_thread, (void*) cliprdr, 0, NULL))) + (LPTHREAD_START_ROUTINE) cliprdr_virtual_channel_client_thread, (void*) cliprdr, + 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); MessageQueue_Free(cliprdr->queue); cliprdr->queue = NULL; return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -1219,31 +1143,33 @@ static UINT cliprdr_virtual_channel_event_disconnected(cliprdrPlugin* cliprdr) { UINT rc; - if (MessageQueue_PostQuit(cliprdr->queue, 0) && (WaitForSingleObject(cliprdr->thread, INFINITE) == WAIT_FAILED)) - { - rc = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); - return rc; - } + if (MessageQueue_PostQuit(cliprdr->queue, 0) + && (WaitForSingleObject(cliprdr->thread, INFINITE) == WAIT_FAILED)) + { + rc = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", rc); + return rc; + } MessageQueue_Free(cliprdr->queue); CloseHandle(cliprdr->thread); + rc = cliprdr->channelEntryPoints.pVirtualChannelCloseEx(cliprdr->InitHandle, cliprdr->OpenHandle); - rc = cliprdr->channelEntryPoints.pVirtualChannelClose(cliprdr->OpenHandle); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); return rc; } + cliprdr->OpenHandle = 0; + if (cliprdr->data_in) { Stream_Free(cliprdr->data_in, TRUE); cliprdr->data_in = NULL; } - cliprdr_remove_open_handle_data(cliprdr->OpenHandle); return CHANNEL_RC_OK; } @@ -1254,22 +1180,18 @@ static UINT cliprdr_virtual_channel_event_disconnected(cliprdrPlugin* cliprdr) */ static UINT cliprdr_virtual_channel_event_terminated(cliprdrPlugin* cliprdr) { - cliprdr_remove_init_handle_data(cliprdr->InitHandle); - + cliprdr->InitHandle = 0; free(cliprdr); return CHANNEL_RC_OK; } -static VOID VCAPITYPE cliprdr_virtual_channel_init_event(LPVOID pInitHandle, - UINT event, LPVOID pData, - UINT dataLength) +static VOID VCAPITYPE cliprdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle, + UINT event, LPVOID pData, UINT dataLength) { - cliprdrPlugin* cliprdr; UINT error = CHANNEL_RC_OK; + cliprdrPlugin* cliprdr = (cliprdrPlugin*) lpUserParam; - cliprdr = (cliprdrPlugin*) cliprdr_get_init_handle_data(pInitHandle); - - if (!cliprdr) + if (!cliprdr || (cliprdr->InitHandle != pInitHandle)) { WLog_ERR(TAG, "error no match"); return; @@ -1278,37 +1200,44 @@ static VOID VCAPITYPE cliprdr_virtual_channel_init_event(LPVOID pInitHandle, switch (event) { case CHANNEL_EVENT_CONNECTED: - if ((error = cliprdr_virtual_channel_event_connected(cliprdr, pData, dataLength))) - WLog_ERR(TAG, "cliprdr_virtual_channel_event_connected failed with error %lu!", error); + if ((error = cliprdr_virtual_channel_event_connected(cliprdr, pData, + dataLength))) + WLog_ERR(TAG, "cliprdr_virtual_channel_event_connected failed with error %u!", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = cliprdr_virtual_channel_event_disconnected(cliprdr))) - WLog_ERR(TAG, "cliprdr_virtual_channel_event_disconnected failed with error %lu!", error); + WLog_ERR(TAG, + "cliprdr_virtual_channel_event_disconnected failed with error %u!", error); + break; case CHANNEL_EVENT_TERMINATED: if ((error = cliprdr_virtual_channel_event_terminated(cliprdr))) - WLog_ERR(TAG, "cliprdr_virtual_channel_event_terminated failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_virtual_channel_event_terminated failed with error %u!", + error); + break; } + if (error && cliprdr->context->rdpcontext) - setChannelError(cliprdr->context->rdpcontext, error, "cliprdr_virtual_channel_init_event reported an error"); + setChannelError(cliprdr->context->rdpcontext, error, + "cliprdr_virtual_channel_init_event reported an error"); } /* cliprdr is always built-in */ -#define VirtualChannelEntry cliprdr_VirtualChannelEntry +#define VirtualChannelEntryEx cliprdr_VirtualChannelEntryEx -BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle) { UINT rc; - int error; - cliprdrPlugin* cliprdr; - CliprdrClientContext* context; - CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; - + CliprdrClientContext* context = NULL; + CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx; cliprdr = (cliprdrPlugin*) calloc(1, sizeof(cliprdrPlugin)); + if (!cliprdr) { WLog_ERR(TAG, "calloc failed!"); @@ -1316,19 +1245,18 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } cliprdr->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP | - CHANNEL_OPTION_SHOW_PROTOCOL; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; strcpy(cliprdr->channelDef.name, "cliprdr"); + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints; - pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; - - if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && - (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) && + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { context = (CliprdrClientContext*) calloc(1, sizeof(CliprdrClientContext)); + if (!context) { free(cliprdr); @@ -1338,7 +1266,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->handle = (void*) cliprdr; context->custom = NULL; - context->ClientCapabilities = cliprdr_client_capabilities; context->TempDirectory = cliprdr_temp_directory; context->ClientFormatList = cliprdr_client_format_list; @@ -1349,45 +1276,32 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->ClientFormatDataResponse = cliprdr_client_format_data_response; context->ClientFileContentsRequest = cliprdr_client_file_contents_request; context->ClientFileContentsResponse = cliprdr_client_file_contents_response; - - *(pEntryPointsEx->ppInterface) = (void*) context; cliprdr->context = context; context->rdpcontext = pEntryPointsEx->context; } cliprdr->log = WLog_Get("com.freerdp.channels.cliprdr.client"); - cliprdr->useLongFormatNames = TRUE; cliprdr->streamFileClipEnabled = FALSE; cliprdr->fileClipNoFilePaths = TRUE; cliprdr->canLockClipData = FALSE; - - WLog_Print(cliprdr->log, WLOG_DEBUG, "VirtualChannelEntry"); - - CopyMemory(&(cliprdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - - rc = cliprdr->channelEntryPoints.pVirtualChannelInit(&cliprdr->InitHandle, - &cliprdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, cliprdr_virtual_channel_init_event); + WLog_Print(cliprdr->log, WLOG_DEBUG, "VirtualChannelEntryEx"); + CopyMemory(&(cliprdr->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); + cliprdr->InitHandle = pInitHandle; + rc = cliprdr->channelEntryPoints.pVirtualChannelInitEx(cliprdr, context, pInitHandle, + &cliprdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + cliprdr_virtual_channel_init_event_ex); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); - free(cliprdr->context); - free(cliprdr); - return FALSE; - } - - cliprdr->channelEntryPoints.pInterface = *(cliprdr->channelEntryPoints.ppInterface); - cliprdr->channelEntryPoints.ppInterface = &(cliprdr->channelEntryPoints.pInterface); - - if ((error = cliprdr_add_init_handle_data(cliprdr->InitHandle, (void*) cliprdr))) - { - WLog_ERR(TAG, "cliprdr_add_init_handle_data failed with error %lu", error); + WTSErrorToString(rc), rc); free(cliprdr->context); free(cliprdr); return FALSE; } + cliprdr->channelEntryPoints.pInterface = context; return TRUE; } diff --git a/channels/cliprdr/client/cliprdr_main.h b/channels/cliprdr/client/cliprdr_main.h index e801413..e994f38 100644 --- a/channels/cliprdr/client/cliprdr_main.h +++ b/channels/cliprdr/client/cliprdr_main.h @@ -33,7 +33,7 @@ struct cliprdr_plugin { CHANNEL_DEF channelDef; - CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; + CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints; CliprdrClientContext* context; @@ -52,15 +52,12 @@ struct cliprdr_plugin }; typedef struct cliprdr_plugin cliprdrPlugin; -wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen); -UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* data_out); - CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr); #ifdef WITH_DEBUG_CLIPRDR -#define DEBUG_CLIPRDR(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__) +#define DEBUG_CLIPRDR(...) WLog_DBG(TAG, __VA_ARGS__) #else -#define DEBUG_CLIPRDR(fmt, ...) do { } while (0) +#define DEBUG_CLIPRDR(...) do { } while (0) #endif #endif /* __CLIPRDR_MAIN_H */ diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index 3baa905..761ee97 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -65,13 +65,13 @@ * */ -wStream* cliprdr_server_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) +wStream* cliprdr_server_packet_new(UINT16 msgType, UINT16 msgFlags, + UINT32 dataLen) { wStream* s; - s = Stream_New(NULL, dataLen + 8); - if(!s) + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return NULL; @@ -79,10 +79,8 @@ wStream* cliprdr_server_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataL Stream_Write_UINT16(s, msgType); Stream_Write_UINT16(s, msgFlags); - /* Write actual length after the entire packet has been constructed. */ Stream_Seek(s, 4); - return s; } @@ -97,19 +95,14 @@ UINT cliprdr_server_packet_send(CliprdrServerPrivate* cliprdr, wStream* s) BOOL status; UINT32 dataLen; UINT32 written; - pos = Stream_GetPosition(s); - dataLen = pos - 8; - Stream_SetPosition(s, 4); Stream_Write_UINT32(s, dataLen); Stream_SetPosition(s, pos); - - status = WTSVirtualChannelWrite(cliprdr->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(cliprdr->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); - return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -118,16 +111,16 @@ UINT cliprdr_server_packet_send(CliprdrServerPrivate* cliprdr, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_capabilities(CliprdrServerContext* context, CLIPRDR_CAPABILITIES* capabilities) +static UINT cliprdr_server_capabilities(CliprdrServerContext* context, + CLIPRDR_CAPABILITIES* capabilities) { wStream* s; CLIPRDR_GENERAL_CAPABILITY_SET* generalCapabilitySet; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; - capabilities->msgType = CB_CLIP_CAPS; capabilities->msgFlags = 0; - s = cliprdr_server_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN); + if (!s) { WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); @@ -136,13 +129,15 @@ static UINT cliprdr_server_capabilities(CliprdrServerContext* context, CLIPRDR_C Stream_Write_UINT16(s, 1); /* cCapabilitiesSets (2 bytes) */ Stream_Write_UINT16(s, 0); /* pad1 (2 bytes) */ - - generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) capabilities->capabilitySets; - Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetType); /* capabilitySetType (2 bytes) */ - Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetLength); /* lengthCapability (2 bytes) */ + generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) + capabilities->capabilitySets; + Stream_Write_UINT16(s, + generalCapabilitySet->capabilitySetType); /* capabilitySetType (2 bytes) */ + Stream_Write_UINT16(s, + generalCapabilitySet->capabilitySetLength); /* lengthCapability (2 bytes) */ Stream_Write_UINT32(s, generalCapabilitySet->version); /* version (4 bytes) */ - Stream_Write_UINT32(s, generalCapabilitySet->generalFlags); /* generalFlags (4 bytes) */ - + Stream_Write_UINT32(s, + generalCapabilitySet->generalFlags); /* generalFlags (4 bytes) */ WLog_DBG(TAG, "ServerCapabilities"); return cliprdr_server_packet_send(cliprdr, s); } @@ -152,17 +147,17 @@ static UINT cliprdr_server_capabilities(CliprdrServerContext* context, CLIPRDR_C * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_monitor_ready(CliprdrServerContext* context, CLIPRDR_MONITOR_READY* monitorReady) +static UINT cliprdr_server_monitor_ready(CliprdrServerContext* context, + CLIPRDR_MONITOR_READY* monitorReady) { wStream* s; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; - monitorReady->msgType = CB_MONITOR_READY; monitorReady->msgFlags = 0; monitorReady->dataLen = 0; - s = cliprdr_server_packet_new(monitorReady->msgType, - monitorReady->msgFlags, monitorReady->dataLen); + monitorReady->msgFlags, monitorReady->dataLen); + if (!s) { WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); @@ -178,7 +173,8 @@ static UINT cliprdr_server_monitor_ready(CliprdrServerContext* context, CLIPRDR_ * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FORMAT_LIST* formatList) +static UINT cliprdr_server_format_list(CliprdrServerContext* context, + CLIPRDR_FORMAT_LIST* formatList) { wStream* s; UINT32 index; @@ -196,8 +192,8 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FO if (!context->useLongFormatNames) { length = formatList->numFormats * 36; - s = cliprdr_server_packet_new(CB_FORMAT_LIST, 0, length); + if (!s) { WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); @@ -206,13 +202,10 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FO for (index = 0; index < formatList->numFormats; index++) { - format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); - + format = (CLIPRDR_FORMAT*) & (formatList->formats[index]); Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */ - formatNameSize = 0; formatNameLength = 0; - szFormatName = format->formatName; if (asciiNames) @@ -231,7 +224,8 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FO wszFormatName = NULL; if (szFormatName) - formatNameSize = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName, 0); + formatNameSize = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName, + 0); if (formatNameSize > 15) formatNameSize = 15; @@ -240,7 +234,6 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FO Stream_Write(s, wszFormatName, formatNameSize * 2); Stream_Zero(s, 32 - (formatNameSize * 2)); - free(wszFormatName); } } @@ -249,12 +242,13 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FO { for (index = 0; index < formatList->numFormats; index++) { - format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); + format = (CLIPRDR_FORMAT*) & (formatList->formats[index]); length += 4; formatNameSize = 2; if (format->formatName) - formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, 0) * 2; + formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, + 0) * 2; length += formatNameSize; } @@ -269,7 +263,7 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FO for (index = 0; index < formatList->numFormats; index++) { - format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); + format = (CLIPRDR_FORMAT*) & (formatList->formats[index]); Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */ if (format->formatName) @@ -277,7 +271,7 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FO lpWideCharStr = (LPWSTR) Stream_Pointer(s); cchWideChar = (Stream_Capacity(s) - Stream_GetPosition(s)) / 2; formatNameSize = MultiByteToWideChar(CP_UTF8, 0, - format->formatName, -1, lpWideCharStr, cchWideChar) * 2; + format->formatName, -1, lpWideCharStr, cchWideChar) * 2; Stream_Seek(s, formatNameSize); } else @@ -288,8 +282,7 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FO } WLog_DBG(TAG, "ServerFormatList: numFormats: %d", - formatList->numFormats); - + formatList->numFormats); return cliprdr_server_packet_send(cliprdr, s); } @@ -298,16 +291,15 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FO * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_format_list_response(CliprdrServerContext* context, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse) +static UINT cliprdr_server_format_list_response(CliprdrServerContext* context, + CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse) { wStream* s; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; - formatListResponse->msgType = CB_FORMAT_LIST_RESPONSE; formatListResponse->dataLen = 0; - s = cliprdr_server_packet_new(formatListResponse->msgType, - formatListResponse->msgFlags, formatListResponse->dataLen); + formatListResponse->msgFlags, formatListResponse->dataLen); if (!s) { @@ -324,11 +316,11 @@ static UINT cliprdr_server_format_list_response(CliprdrServerContext* context, C * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_lock_clipboard_data(CliprdrServerContext* context, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData) +static UINT cliprdr_server_lock_clipboard_data(CliprdrServerContext* context, + CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData) { wStream* s; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; - s = cliprdr_server_packet_new(CB_LOCK_CLIPDATA, 0, 4); if (!s) @@ -337,11 +329,10 @@ static UINT cliprdr_server_lock_clipboard_data(CliprdrServerContext* context, CL return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, lockClipboardData->clipDataId); /* clipDataId (4 bytes) */ - + Stream_Write_UINT32(s, + lockClipboardData->clipDataId); /* clipDataId (4 bytes) */ WLog_DBG(TAG, "ServerLockClipboardData: clipDataId: 0x%04X", - lockClipboardData->clipDataId); - + lockClipboardData->clipDataId); return cliprdr_server_packet_send(cliprdr, s); } @@ -350,11 +341,11 @@ static UINT cliprdr_server_lock_clipboard_data(CliprdrServerContext* context, CL * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_unlock_clipboard_data(CliprdrServerContext* context, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) +static UINT cliprdr_server_unlock_clipboard_data(CliprdrServerContext* context, + CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) { wStream* s; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; - s = cliprdr_server_packet_new(CB_UNLOCK_CLIPDATA, 0, 4); if (!s) @@ -363,11 +354,10 @@ static UINT cliprdr_server_unlock_clipboard_data(CliprdrServerContext* context, return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */ - + Stream_Write_UINT32(s, + unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */ WLog_DBG(TAG, "ServerUnlockClipboardData: clipDataId: 0x%04X", - unlockClipboardData->clipDataId); - + unlockClipboardData->clipDataId); return cliprdr_server_packet_send(cliprdr, s); } @@ -376,16 +366,16 @@ static UINT cliprdr_server_unlock_clipboard_data(CliprdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_format_data_request(CliprdrServerContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) +static UINT cliprdr_server_format_data_request(CliprdrServerContext* context, + CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) { wStream* s; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; - formatDataRequest->msgType = CB_FORMAT_DATA_REQUEST; formatDataRequest->msgFlags = 0; formatDataRequest->dataLen = 4; - - s = cliprdr_server_packet_new(formatDataRequest->msgType, formatDataRequest->msgFlags, formatDataRequest->dataLen); + s = cliprdr_server_packet_new(formatDataRequest->msgType, + formatDataRequest->msgFlags, formatDataRequest->dataLen); if (!s) { @@ -393,8 +383,8 @@ static UINT cliprdr_server_format_data_request(CliprdrServerContext* context, CL return ERROR_INTERNAL_ERROR; } - Stream_Write_UINT32(s, formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */ - + Stream_Write_UINT32(s, + formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */ WLog_DBG(TAG, "ClientFormatDataRequest"); return cliprdr_server_packet_send(cliprdr, s); } @@ -404,14 +394,14 @@ static UINT cliprdr_server_format_data_request(CliprdrServerContext* context, CL * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_format_data_response(CliprdrServerContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) +static UINT cliprdr_server_format_data_response(CliprdrServerContext* context, + CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) { wStream* s; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; - formatDataResponse->msgType = CB_FORMAT_DATA_RESPONSE; - - s = cliprdr_server_packet_new(formatDataResponse->msgType, formatDataResponse->msgFlags, formatDataResponse->dataLen); + s = cliprdr_server_packet_new(formatDataResponse->msgType, + formatDataResponse->msgFlags, formatDataResponse->dataLen); if (!s) { @@ -419,8 +409,8 @@ static UINT cliprdr_server_format_data_response(CliprdrServerContext* context, C return ERROR_INTERNAL_ERROR; } - Stream_Write(s, formatDataResponse->requestedFormatData, formatDataResponse->dataLen); - + Stream_Write(s, formatDataResponse->requestedFormatData, + formatDataResponse->dataLen); WLog_DBG(TAG, "ServerFormatDataResponse"); return cliprdr_server_packet_send(cliprdr, s); } @@ -430,11 +420,11 @@ static UINT cliprdr_server_format_data_response(CliprdrServerContext* context, C * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_file_contents_request(CliprdrServerContext* context, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest) +static UINT cliprdr_server_file_contents_request(CliprdrServerContext* context, + CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest) { wStream* s; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; - s = cliprdr_server_packet_new(CB_FILECONTENTS_REQUEST, 0, 28); if (!s) @@ -444,16 +434,19 @@ static UINT cliprdr_server_file_contents_request(CliprdrServerContext* context, } Stream_Write_UINT32(s, fileContentsRequest->streamId); /* streamId (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->listIndex); /* listIndex (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->listIndex); /* listIndex (4 bytes) */ Stream_Write_UINT32(s, fileContentsRequest->dwFlags); /* dwFlags (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->nPositionLow); /* nPositionLow (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->nPositionHigh); /* nPositionHigh (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->cbRequested); /* cbRequested (4 bytes) */ - Stream_Write_UINT32(s, fileContentsRequest->clipDataId); /* clipDataId (4 bytes) */ - + Stream_Write_UINT32(s, + fileContentsRequest->nPositionLow); /* nPositionLow (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->nPositionHigh); /* nPositionHigh (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->cbRequested); /* cbRequested (4 bytes) */ + Stream_Write_UINT32(s, + fileContentsRequest->clipDataId); /* clipDataId (4 bytes) */ WLog_DBG(TAG, "ServerFileContentsRequest: streamId: 0x%04X", - fileContentsRequest->streamId); - + fileContentsRequest->streamId); return cliprdr_server_packet_send(cliprdr, s); } @@ -462,7 +455,8 @@ static UINT cliprdr_server_file_contents_request(CliprdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_file_contents_response(CliprdrServerContext* context, CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse) +static UINT cliprdr_server_file_contents_response(CliprdrServerContext* context, + CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse) { wStream* s; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; @@ -470,8 +464,9 @@ static UINT cliprdr_server_file_contents_response(CliprdrServerContext* context, if (fileContentsResponse->dwFlags & FILECONTENTS_SIZE) fileContentsResponse->cbRequested = sizeof(UINT64); - s = cliprdr_server_packet_new(CB_FILECONTENTS_RESPONSE, fileContentsResponse->msgFlags, - 4 + fileContentsResponse->cbRequested); + s = cliprdr_server_packet_new(CB_FILECONTENTS_RESPONSE, + fileContentsResponse->msgFlags, + 4 + fileContentsResponse->cbRequested); if (!s) { @@ -480,18 +475,15 @@ static UINT cliprdr_server_file_contents_response(CliprdrServerContext* context, } Stream_Write_UINT32(s, fileContentsResponse->streamId); /* streamId (4 bytes) */ - /** * requestedFileContentsData: * FILECONTENTS_SIZE: file size as UINT64 * FILECONTENTS_RANGE: file data from requested range */ - - Stream_Write(s, fileContentsResponse->requestedData, fileContentsResponse->cbRequested); - + Stream_Write(s, fileContentsResponse->requestedData, + fileContentsResponse->cbRequested); WLog_DBG(TAG, "ServerFileContentsResponse: streamId: 0x%04X", - fileContentsResponse->streamId); - + fileContentsResponse->streamId); return cliprdr_server_packet_send(cliprdr, s); } @@ -500,22 +492,25 @@ static UINT cliprdr_server_file_contents_response(CliprdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_general_capability(CliprdrServerContext* context, wStream* s) +static UINT cliprdr_server_receive_general_capability(CliprdrServerContext* + context, wStream* s) { UINT32 version; UINT32 generalFlags; - Stream_Read_UINT32(s, version); /* version (4 bytes) */ Stream_Read_UINT32(s, generalFlags); /* generalFlags (4 bytes) */ if (context->useLongFormatNames) - context->useLongFormatNames = (generalFlags & CB_USE_LONG_FORMAT_NAMES) ? TRUE : FALSE; + context->useLongFormatNames = (generalFlags & CB_USE_LONG_FORMAT_NAMES) ? TRUE : + FALSE; if (context->streamFileClipEnabled) - context->streamFileClipEnabled = (generalFlags & CB_STREAM_FILECLIP_ENABLED) ? TRUE : FALSE; + context->streamFileClipEnabled = (generalFlags & CB_STREAM_FILECLIP_ENABLED) ? + TRUE : FALSE; if (context->fileClipNoFilePaths) - context->fileClipNoFilePaths = (generalFlags & CB_FILECLIP_NO_FILE_PATHS) ? TRUE : FALSE; + context->fileClipNoFilePaths = (generalFlags & CB_FILECLIP_NO_FILE_PATHS) ? + TRUE : FALSE; if (context->canLockClipData) context->canLockClipData = (generalFlags & CB_CAN_LOCK_CLIPDATA) ? TRUE : FALSE; @@ -528,16 +523,15 @@ static UINT cliprdr_server_receive_general_capability(CliprdrServerContext* cont * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, + wStream* s, CLIPRDR_HEADER* header) { UINT16 index; UINT16 cCapabilitiesSets; UINT16 capabilitySetType; UINT16 lengthCapability; UINT error; - WLog_DBG(TAG, "CliprdrClientCapabilities"); - Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ Stream_Seek_UINT16(s); /* pad1 (2 bytes) */ @@ -551,9 +545,11 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w case CB_CAPSTYPE_GENERAL: if ((error = cliprdr_server_receive_general_capability(context, s))) { - WLog_ERR(TAG, "cliprdr_server_receive_general_capability failed with error %lu", error); + WLog_ERR(TAG, "cliprdr_server_receive_general_capability failed with error %u", + error); return error; } + break; default: @@ -571,7 +567,8 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_temporary_directory(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_temporary_directory(CliprdrServerContext* + context, wStream* s, CLIPRDR_HEADER* header) { int length; WCHAR* wszTempDir; @@ -582,7 +579,8 @@ static UINT cliprdr_server_receive_temporary_directory(CliprdrServerContext* con if ((slength = Stream_GetRemainingLength(s)) < 520) { - WLog_ERR(TAG, "Stream_GetRemainingLength returned %d but should at least be 520", slength); + WLog_ERR(TAG, + "Stream_GetRemainingLength returned %lu but should at least be 520", (unsigned long) slength); return CHANNEL_RC_NO_MEMORY; } @@ -598,7 +596,7 @@ static UINT cliprdr_server_receive_temporary_directory(CliprdrServerContext* con cliprdr->temporaryDirectory = NULL; if (ConvertFromUnicode(CP_UTF8, 0, wszTempDir, -1, - &(cliprdr->temporaryDirectory), 0, NULL, NULL) < 1) + &(cliprdr->temporaryDirectory), 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert temporary directory name"); return ERROR_INVALID_DATA; @@ -611,12 +609,11 @@ static UINT cliprdr_server_receive_temporary_directory(CliprdrServerContext* con CopyMemory(tempDirectory.szTempDir, cliprdr->temporaryDirectory, length); tempDirectory.szTempDir[length] = '\0'; - WLog_DBG(TAG, "CliprdrTemporaryDirectory: %s", cliprdr->temporaryDirectory); - IFCALLRET(context->TempDirectory, error, context, &tempDirectory); + if (error) - WLog_ERR(TAG, "TempDirectory failed with error %lu!", error); + WLog_ERR(TAG, "TempDirectory failed with error %u!", error); return error; } @@ -626,7 +623,8 @@ static UINT cliprdr_server_receive_temporary_directory(CliprdrServerContext* con * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, + wStream* s, CLIPRDR_HEADER* header) { UINT32 index; UINT32 dataLen; @@ -638,14 +636,11 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS CLIPRDR_FORMAT* formats = NULL; CLIPRDR_FORMAT_LIST formatList; UINT error = CHANNEL_RC_OK; - dataLen = header->dataLen; asciiNames = (header->msgFlags & CB_ASCII_NAMES) ? TRUE : FALSE; - formatList.msgType = CB_FORMAT_LIST; formatList.msgFlags = header->msgFlags; formatList.dataLen = header->dataLen; - index = 0; formatList.numFormats = 0; position = Stream_GetPosition(s); @@ -667,7 +662,8 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS } if (formatList.numFormats) - formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT)); + formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, + sizeof(CLIPRDR_FORMAT)); if (!formats) { @@ -681,7 +677,6 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS { Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */ dataLen -= 4; - formats[index].formatName = NULL; /* According to MS-RDPECLIP 2.2.3.1.1.1 formatName is "a 32-byte block containing @@ -714,7 +709,7 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS * string on success, even if the source string isn't. */ if (ConvertFromUnicode(CP_UTF8, 0, wszFormatName, 16, - &(formats[index].formatName), 0, NULL, NULL) < 1) + &(formats[index].formatName), 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert short clipboard format name"); error = ERROR_INVALID_DATA; @@ -734,7 +729,6 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS { Stream_Seek(s, 4); /* formatId (4 bytes) */ dataLen -= 4; - wszFormatName = (WCHAR*) Stream_Pointer(s); if (!wszFormatName[0]) @@ -744,7 +738,6 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS Stream_Seek(s, (formatNameLength + 1) * 2); dataLen -= ((formatNameLength + 1) * 2); - formatList.numFormats++; } @@ -752,7 +745,8 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS Stream_SetPosition(s, position); if (formatList.numFormats) - formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT)); + formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, + sizeof(CLIPRDR_FORMAT)); if (!formats) { @@ -766,9 +760,7 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS { Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */ dataLen -= 4; - formats[index].formatName = NULL; - wszFormatName = (WCHAR*) Stream_Pointer(s); if (!wszFormatName[0]) @@ -779,7 +771,7 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS if (formatNameLength) { if (ConvertFromUnicode(CP_UTF8, 0, wszFormatName, -1, - &(formats[index].formatName), 0, NULL, NULL) < 1) + &(formats[index].formatName), 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert long clipboard format name"); error = ERROR_INVALID_DATA; @@ -789,26 +781,25 @@ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wS Stream_Seek(s, (formatNameLength + 1) * 2); dataLen -= ((formatNameLength + 1) * 2); - index++; } } WLog_DBG(TAG, "ClientFormatList: numFormats: %d", - formatList.numFormats); - + formatList.numFormats); IFCALLRET(context->ClientFormatList, error, context, &formatList); + if (error) - WLog_ERR(TAG, "ClientFormatList failed with error %lu!", error); + WLog_ERR(TAG, "ClientFormatList failed with error %u!", error); out: + for (index = 0; index < formatList.numFormats; index++) { free(formatList.formats[index].formatName); } free(formatList.formats); - return error; } @@ -817,20 +808,20 @@ out: * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_format_list_response(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_format_list_response( + CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { CLIPRDR_FORMAT_LIST_RESPONSE formatListResponse; UINT error = CHANNEL_RC_OK; - WLog_DBG(TAG, "CliprdrClientFormatListResponse"); - formatListResponse.msgType = CB_FORMAT_LIST_RESPONSE; formatListResponse.msgFlags = header->msgFlags; formatListResponse.dataLen = header->dataLen; + IFCALLRET(context->ClientFormatListResponse, error, context, + &formatListResponse); - IFCALLRET(context->ClientFormatListResponse, error, context, &formatListResponse); if (error) - WLog_ERR(TAG, "ClientFormatListResponse failed with error %lu!", error); + WLog_ERR(TAG, "ClientFormatListResponse failed with error %u!", error); return error; } @@ -840,11 +831,11 @@ static UINT cliprdr_server_receive_format_list_response(CliprdrServerContext* co * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_lock_clipdata(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_lock_clipdata(CliprdrServerContext* context, + wStream* s, CLIPRDR_HEADER* header) { CLIPRDR_LOCK_CLIPBOARD_DATA lockClipboardData; UINT error = CHANNEL_RC_OK; - WLog_DBG(TAG, "CliprdrClientLockClipData"); if (Stream_GetRemainingLength(s) < 4) @@ -856,12 +847,11 @@ static UINT cliprdr_server_receive_lock_clipdata(CliprdrServerContext* context, lockClipboardData.msgType = CB_LOCK_CLIPDATA; lockClipboardData.msgFlags = header->msgFlags; lockClipboardData.dataLen = header->dataLen; - Stream_Read_UINT32(s, lockClipboardData.clipDataId); /* clipDataId (4 bytes) */ - IFCALLRET(context->ClientLockClipboardData, error, context, &lockClipboardData); + if (error) - WLog_ERR(TAG, "ClientLockClipboardData failed with error %lu!", error); + WLog_ERR(TAG, "ClientLockClipboardData failed with error %u!", error); return error; } @@ -871,13 +861,12 @@ static UINT cliprdr_server_receive_lock_clipdata(CliprdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_unlock_clipdata(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_unlock_clipdata(CliprdrServerContext* + context, wStream* s, CLIPRDR_HEADER* header) { CLIPRDR_UNLOCK_CLIPBOARD_DATA unlockClipboardData; UINT error = CHANNEL_RC_OK; - WLog_DBG(TAG, "CliprdrClientUnlockClipData"); - unlockClipboardData.msgType = CB_UNLOCK_CLIPDATA; unlockClipboardData.msgFlags = header->msgFlags; unlockClipboardData.dataLen = header->dataLen; @@ -888,11 +877,13 @@ static UINT cliprdr_server_receive_unlock_clipdata(CliprdrServerContext* context return ERROR_INVALID_DATA; } - Stream_Read_UINT32(s, unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */ + Stream_Read_UINT32(s, + unlockClipboardData.clipDataId); /* clipDataId (4 bytes) */ + IFCALLRET(context->ClientUnlockClipboardData, error, context, + &unlockClipboardData); - IFCALLRET(context->ClientUnlockClipboardData, error, context, &unlockClipboardData); if (error) - WLog_ERR(TAG, "ClientUnlockClipboardData failed with error %lu!", error); + WLog_ERR(TAG, "ClientUnlockClipboardData failed with error %u!", error); return error; } @@ -902,13 +893,12 @@ static UINT cliprdr_server_receive_unlock_clipdata(CliprdrServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_format_data_request(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_format_data_request(CliprdrServerContext* + context, wStream* s, CLIPRDR_HEADER* header) { CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest; UINT error = CHANNEL_RC_OK; - WLog_DBG(TAG, "CliprdrClientFormatDataRequest"); - formatDataRequest.msgType = CB_FORMAT_DATA_REQUEST; formatDataRequest.msgFlags = header->msgFlags; formatDataRequest.dataLen = header->dataLen; @@ -919,11 +909,12 @@ static UINT cliprdr_server_receive_format_data_request(CliprdrServerContext* con return ERROR_INVALID_DATA; } - Stream_Read_UINT32(s, formatDataRequest.requestedFormatId); /* requestedFormatId (4 bytes) */ - + Stream_Read_UINT32(s, + formatDataRequest.requestedFormatId); /* requestedFormatId (4 bytes) */ IFCALLRET(context->ClientFormatDataRequest, error, context, &formatDataRequest); + if (error) - WLog_ERR(TAG, "ClientFormatDataRequest failed with error %lu!", error); + WLog_ERR(TAG, "ClientFormatDataRequest failed with error %u!", error); return error; } @@ -933,13 +924,12 @@ static UINT cliprdr_server_receive_format_data_request(CliprdrServerContext* con * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_format_data_response(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_format_data_response( + CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { CLIPRDR_FORMAT_DATA_RESPONSE formatDataResponse; UINT error = CHANNEL_RC_OK; - WLog_DBG(TAG, "CliprdrClientFormatDataResponse"); - formatDataResponse.msgType = CB_FORMAT_DATA_RESPONSE; formatDataResponse.msgFlags = header->msgFlags; formatDataResponse.dataLen = header->dataLen; @@ -957,12 +947,13 @@ static UINT cliprdr_server_receive_format_data_response(CliprdrServerContext* co Stream_Read(s, formatDataResponse.requestedFormatData, header->dataLen); } - IFCALLRET(context->ClientFormatDataResponse, error, context, &formatDataResponse); + IFCALLRET(context->ClientFormatDataResponse, error, context, + &formatDataResponse); + if (error) - WLog_ERR(TAG, "ClientFormatDataResponse failed with error %lu!", error); + WLog_ERR(TAG, "ClientFormatDataResponse failed with error %u!", error); free(formatDataResponse.requestedFormatData); - return error; } @@ -971,13 +962,12 @@ static UINT cliprdr_server_receive_format_data_response(CliprdrServerContext* co * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_filecontents_request(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_filecontents_request( + CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { CLIPRDR_FILE_CONTENTS_REQUEST request; UINT error = CHANNEL_RC_OK; - WLog_DBG(TAG, "CliprdrClientFileContentsRequest"); - request.msgType = CB_FILECONTENTS_REQUEST; request.msgFlags = header->msgFlags; request.dataLen = header->dataLen; @@ -994,14 +984,16 @@ static UINT cliprdr_server_receive_filecontents_request(CliprdrServerContext* co Stream_Read_UINT32(s, request.nPositionLow); /* nPositionLow (4 bytes) */ Stream_Read_UINT32(s, request.nPositionHigh); /* nPositionHigh (4 bytes) */ Stream_Read_UINT32(s, request.cbRequested); /* cbRequested (4 bytes) */ + if (Stream_GetRemainingLength(s) < 4) /* clipDataId (4 bytes) optional */ request.clipDataId = 0; else Stream_Read_UINT32(s, request.clipDataId); IFCALLRET(context->ClientFileContentsRequest, error, context, &request); + if (error) - WLog_ERR(TAG, "ClientFileContentsRequest failed with error %lu!", error); + WLog_ERR(TAG, "ClientFileContentsRequest failed with error %u!", error); return error; } @@ -1011,13 +1003,12 @@ static UINT cliprdr_server_receive_filecontents_request(CliprdrServerContext* co * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_filecontents_response(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_filecontents_response( + CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { CLIPRDR_FILE_CONTENTS_RESPONSE response; UINT error = CHANNEL_RC_OK; - WLog_DBG(TAG, "CliprdrClientFileContentsResponse"); - response.msgType = CB_FILECONTENTS_RESPONSE; response.msgFlags = header->msgFlags; response.dataLen = header->dataLen; @@ -1029,13 +1020,12 @@ static UINT cliprdr_server_receive_filecontents_response(CliprdrServerContext* c } Stream_Read_UINT32(s, response.streamId); /* streamId (4 bytes) */ - response.cbRequested = header->dataLen - 4; response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */ - IFCALLRET(context->ClientFileContentsResponse, error, context, &response); + if (error) - WLog_ERR(TAG, "ClientFileContentsResponse failed with error %lu!", error); + WLog_ERR(TAG, "ClientFileContentsResponse failed with error %u!", error); return error; } @@ -1045,62 +1035,84 @@ static UINT cliprdr_server_receive_filecontents_response(CliprdrServerContext* c * * @return 0 on success, otherwise a Win32 error code */ -static UINT cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) +static UINT cliprdr_server_receive_pdu(CliprdrServerContext* context, + wStream* s, CLIPRDR_HEADER* header) { UINT error; - WLog_DBG(TAG, "CliprdrServerReceivePdu: msgType: %d msgFlags: 0x%08X dataLen: %d", - header->msgType, header->msgFlags, header->dataLen); + WLog_DBG(TAG, + "CliprdrServerReceivePdu: msgType: %d msgFlags: 0x%08X dataLen: %d", + header->msgType, header->msgFlags, header->dataLen); switch (header->msgType) { case CB_CLIP_CAPS: if ((error = cliprdr_server_receive_capabilities(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_capabilities failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_server_receive_capabilities failed with error %u!", + error); + break; case CB_TEMP_DIRECTORY: if ((error = cliprdr_server_receive_temporary_directory(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_temporary_directory failed with error %lu!", error); + WLog_ERR(TAG, + "cliprdr_server_receive_temporary_directory failed with error %u!", error); + break; case CB_FORMAT_LIST: if ((error = cliprdr_server_receive_format_list(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_format_list failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_server_receive_format_list failed with error %u!", + error); + break; case CB_FORMAT_LIST_RESPONSE: if ((error = cliprdr_server_receive_format_list_response(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_format_list_response failed with error %lu!", error); + WLog_ERR(TAG, + "cliprdr_server_receive_format_list_response failed with error %u!", error); + break; case CB_LOCK_CLIPDATA: if ((error = cliprdr_server_receive_lock_clipdata(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_lock_clipdata failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_server_receive_lock_clipdata failed with error %u!", + error); + break; case CB_UNLOCK_CLIPDATA: if ((error = cliprdr_server_receive_unlock_clipdata(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_unlock_clipdata failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_server_receive_unlock_clipdata failed with error %u!", + error); + break; case CB_FORMAT_DATA_REQUEST: if ((error = cliprdr_server_receive_format_data_request(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_format_data_request failed with error %lu!", error); + WLog_ERR(TAG, + "cliprdr_server_receive_format_data_request failed with error %u!", error); + break; case CB_FORMAT_DATA_RESPONSE: if ((error = cliprdr_server_receive_format_data_response(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_format_data_response failed with error %lu!", error); + WLog_ERR(TAG, + "cliprdr_server_receive_format_data_response failed with error %u!", error); + break; case CB_FILECONTENTS_REQUEST: if ((error = cliprdr_server_receive_filecontents_request(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_filecontents_request failed with error %lu!", error); + WLog_ERR(TAG, + "cliprdr_server_receive_filecontents_request failed with error %u!", error); + break; case CB_FILECONTENTS_RESPONSE: if ((error = cliprdr_server_receive_filecontents_response(context, s, header))) - WLog_ERR(TAG, "cliprdr_server_receive_filecontents_response failed with error %lu!", error); + WLog_ERR(TAG, + "cliprdr_server_receive_filecontents_response failed with error %u!", error); + break; default: @@ -1124,10 +1136,8 @@ static UINT cliprdr_server_init(CliprdrServerContext* context) CLIPRDR_MONITOR_READY monitorReady; CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet; UINT error; - ZeroMemory(&capabilities, sizeof(capabilities)); ZeroMemory(&monitorReady, sizeof(monitorReady)); - generalFlags = 0; if (context->useLongFormatNames) @@ -1145,10 +1155,8 @@ static UINT cliprdr_server_init(CliprdrServerContext* context) capabilities.msgType = CB_CLIP_CAPS; capabilities.msgFlags = 0; capabilities.dataLen = 4 + CB_CAPSTYPE_GENERAL_LEN; - capabilities.cCapabilitiesSets = 1; capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &generalCapabilitySet; - generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL; generalCapabilitySet.capabilitySetLength = CB_CAPSTYPE_GENERAL_LEN; generalCapabilitySet.version = CB_CAPS_VERSION_2; @@ -1156,12 +1164,13 @@ static UINT cliprdr_server_init(CliprdrServerContext* context) if ((error = context->ServerCapabilities(context, &capabilities))) { - WLog_ERR(TAG, "ServerCapabilities failed with error %lu!", error); + WLog_ERR(TAG, "ServerCapabilities failed with error %u!", error); return error; } + if ((error = context->MonitorReady(context, &monitorReady))) { - WLog_ERR(TAG, "MonitorReady failed with error %lu!", error); + WLog_ERR(TAG, "MonitorReady failed with error %u!", error); return error; } @@ -1182,29 +1191,27 @@ UINT cliprdr_server_read(CliprdrServerContext* context) CLIPRDR_HEADER header; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; UINT error; - DWORD status; - + DWORD status; s = cliprdr->s; if (Stream_GetPosition(s) < CLIPRDR_HEADER_LENGTH) { BytesReturned = 0; BytesToRead = CLIPRDR_HEADER_LENGTH - Stream_GetPosition(s); - - status = WaitForSingleObject(cliprdr->ChannelEvent, 0); + status = WaitForSingleObject(cliprdr->ChannelEvent, 0); if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + return error; + } - if (status == WAIT_TIMEOUT) - return CHANNEL_RC_OK; + if (status == WAIT_TIMEOUT) + return CHANNEL_RC_OK; if (!WTSVirtualChannelRead(cliprdr->ChannelHandle, 0, - (PCHAR) Stream_Pointer(s), BytesToRead, &BytesReturned)) + (PCHAR) Stream_Pointer(s), BytesToRead, &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); return ERROR_INTERNAL_ERROR; @@ -1217,7 +1224,6 @@ UINT cliprdr_server_read(CliprdrServerContext* context) { position = Stream_GetPosition(s); Stream_SetPosition(s, 0); - Stream_Read_UINT16(s, header.msgType); /* msgType (2 bytes) */ Stream_Read_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */ Stream_Read_UINT32(s, header.dataLen); /* dataLen (4 bytes) */ @@ -1234,21 +1240,20 @@ UINT cliprdr_server_read(CliprdrServerContext* context) { BytesReturned = 0; BytesToRead = (header.dataLen + CLIPRDR_HEADER_LENGTH) - Stream_GetPosition(s); + status = WaitForSingleObject(cliprdr->ChannelEvent, 0); - status = WaitForSingleObject(cliprdr->ChannelEvent, 0); + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + return error; + } - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } - - if (status == WAIT_TIMEOUT) - return CHANNEL_RC_OK; + if (status == WAIT_TIMEOUT) + return CHANNEL_RC_OK; if (!WTSVirtualChannelRead(cliprdr->ChannelHandle, 0, - (PCHAR) Stream_Pointer(s), BytesToRead, &BytesReturned)) + (PCHAR) Stream_Pointer(s), BytesToRead, &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); return ERROR_INTERNAL_ERROR; @@ -1265,31 +1270,29 @@ UINT cliprdr_server_read(CliprdrServerContext* context) if ((error = cliprdr_server_receive_pdu(context, s, &header))) { - WLog_ERR(TAG, "cliprdr_server_receive_pdu failed with error code %lu!", error); + WLog_ERR(TAG, "cliprdr_server_receive_pdu failed with error code %u!", error); return error; } Stream_SetPosition(s, 0); - /* check for trailing zero bytes */ + status = WaitForSingleObject(cliprdr->ChannelEvent, 0); - status = WaitForSingleObject(cliprdr->ChannelEvent, 0); + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + return error; + } - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } - - if (status == WAIT_TIMEOUT) - return CHANNEL_RC_OK; + if (status == WAIT_TIMEOUT) + return CHANNEL_RC_OK; BytesReturned = 0; BytesToRead = 4; if (!WTSVirtualChannelRead(cliprdr->ChannelHandle, 0, - (PCHAR) Stream_Pointer(s), BytesToRead, &BytesReturned)) + (PCHAR) Stream_Pointer(s), BytesToRead, &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); return ERROR_INTERNAL_ERROR; @@ -1327,14 +1330,13 @@ static void* cliprdr_server_thread(void* arg) UINT error; ChannelEvent = context->GetEventHandle(context); - nCount = 0; events[nCount++] = cliprdr->StopEvent; events[nCount++] = ChannelEvent; if ((error = cliprdr_server_init(context))) { - WLog_ERR(TAG, "cliprdr_server_init failed with error %lu!", error); + WLog_ERR(TAG, "cliprdr_server_init failed with error %u!", error); goto out; } @@ -1344,44 +1346,47 @@ static void* cliprdr_server_thread(void* arg) if (status == WAIT_FAILED) { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); - goto out; + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error); + goto out; } - status = WaitForSingleObject(cliprdr->StopEvent, 0); + status = WaitForSingleObject(cliprdr->StopEvent, 0); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - goto out; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + goto out; + } if (status == WAIT_OBJECT_0) break; - status = WaitForSingleObject(ChannelEvent, 0); + status = WaitForSingleObject(ChannelEvent, 0); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - goto out; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + goto out; + } if (status == WAIT_OBJECT_0) { if ((error = context->CheckEventHandle(context))) { - WLog_ERR(TAG, "CheckEventHandle failed with error %lu!", error); + WLog_ERR(TAG, "CheckEventHandle failed with error %u!", error); break; } } } + out: + if (error && context->rdpcontext) - setChannelError(context->rdpcontext, error, "cliprdr_server_thread reported an error"); + setChannelError(context->rdpcontext, error, + "cliprdr_server_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -1397,8 +1402,8 @@ static UINT cliprdr_server_open(CliprdrServerContext* context) void* buffer = NULL; DWORD BytesReturned = 0; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; - - cliprdr->ChannelHandle = WTSVirtualChannelOpen(cliprdr->vcm, WTS_CURRENT_SESSION, "cliprdr"); + cliprdr->ChannelHandle = WTSVirtualChannelOpen(cliprdr->vcm, + WTS_CURRENT_SESSION, "cliprdr"); if (!cliprdr->ChannelHandle) { @@ -1408,16 +1413,16 @@ static UINT cliprdr_server_open(CliprdrServerContext* context) cliprdr->ChannelEvent = NULL; - if (WTSVirtualChannelQuery(cliprdr->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned)) + if (WTSVirtualChannelQuery(cliprdr->ChannelHandle, WTSVirtualEventHandle, + &buffer, &BytesReturned)) { if (BytesReturned != sizeof(HANDLE)) { WLog_ERR(TAG, "BytesReturned has not size of HANDLE!"); return ERROR_INTERNAL_ERROR; } + CopyMemory(&(cliprdr->ChannelEvent), buffer, sizeof(HANDLE)); - - WTSFreeMemory(buffer); } @@ -1474,7 +1479,7 @@ static UINT cliprdr_server_start(CliprdrServerContext* context) } if (!(cliprdr->Thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) cliprdr_server_thread, (void*) context, 0, NULL))) + (LPTHREAD_START_ROUTINE) cliprdr_server_thread, (void*) context, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); CloseHandle(cliprdr->StopEvent); @@ -1492,18 +1497,20 @@ static UINT cliprdr_server_start(CliprdrServerContext* context) */ static UINT cliprdr_server_stop(CliprdrServerContext* context) { - UINT error = CHANNEL_RC_OK; + UINT error = CHANNEL_RC_OK; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; if (cliprdr->StopEvent) { SetEvent(cliprdr->StopEvent); + if (WaitForSingleObject(cliprdr->Thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + return error; + } + CloseHandle(cliprdr->Thread); CloseHandle(cliprdr->StopEvent); } @@ -1534,7 +1541,6 @@ CliprdrServerContext* cliprdr_server_context_new(HANDLE vcm) { CliprdrServerContext* context; CliprdrServerPrivate* cliprdr; - context = (CliprdrServerContext*) calloc(1, sizeof(CliprdrServerContext)); if (context) @@ -1545,7 +1551,6 @@ CliprdrServerContext* cliprdr_server_context_new(HANDLE vcm) context->Stop = cliprdr_server_stop; context->GetEventHandle = cliprdr_server_get_event_handle; context->CheckEventHandle = cliprdr_server_check_event_handle; - context->ServerCapabilities = cliprdr_server_capabilities; context->MonitorReady = cliprdr_server_monitor_ready; context->ServerFormatList = cliprdr_server_format_list; @@ -1556,23 +1561,24 @@ CliprdrServerContext* cliprdr_server_context_new(HANDLE vcm) context->ServerFormatDataResponse = cliprdr_server_format_data_response; context->ServerFileContentsRequest = cliprdr_server_file_contents_request; context->ServerFileContentsResponse = cliprdr_server_file_contents_response; - - cliprdr = context->handle = (CliprdrServerPrivate*) calloc(1, sizeof(CliprdrServerPrivate)); + cliprdr = context->handle = (CliprdrServerPrivate*) calloc(1, + sizeof(CliprdrServerPrivate)); if (cliprdr) { cliprdr->vcm = vcm; - cliprdr->s = Stream_New(NULL, 4096); - if(!cliprdr->s) + if (!cliprdr->s) { WLog_ERR(TAG, "Stream_New failed!"); free(context->handle); free(context); return NULL; } - } else { + } + else + { WLog_ERR(TAG, "calloc failed!"); free(context); return NULL; diff --git a/channels/disp/client/CMakeLists.txt b/channels/disp/client/CMakeLists.txt index d0bbaeb..1ec2c6f 100644 --- a/channels/disp/client/CMakeLists.txt +++ b/channels/disp/client/CMakeLists.txt @@ -32,7 +32,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c old mode 100644 new mode 100755 index fb23d8b..637632c --- a/channels/disp/client/disp_main.c +++ b/channels/disp/client/disp_main.c @@ -5,6 +5,7 @@ * Copyright 2013 Marc-Andre Moreau * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2016 David PHAM-VAN * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -317,6 +318,9 @@ static UINT disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage */ static UINT disp_plugin_terminated(IWTSPlugin* pPlugin) { + DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin; + free(disp->listener_callback); + free(disp->iface.pInterface); free(pPlugin); return CHANNEL_RC_OK; } @@ -338,7 +342,7 @@ UINT disp_send_monitor_layout(DispClientContext* context, UINT32 NumMonitors, DI return disp_send_display_control_monitor_layout_pdu(callback, NumMonitors, Monitors); } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DVCPluginEntry disp_DVCPluginEntry #else #define DVCPluginEntry FREERDP_API DVCPluginEntry diff --git a/channels/drdynvc/client/CMakeLists.txt b/channels/drdynvc/client/CMakeLists.txt index 244d198..abf9185 100644 --- a/channels/drdynvc/client/CMakeLists.txt +++ b/channels/drdynvc/client/CMakeLists.txt @@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS drdynvc_main.c drdynvc_main.h) -add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") - +add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx") set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client") + diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 03e71d9..46fc212 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -32,14 +32,15 @@ static void dvcman_channel_free(void* channel); static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, - const BYTE* data, UINT32 dataSize); + const BYTE* data, UINT32 dataSize); /** * Function description * * @return 0 on success, otherwise a Win32 error code */ -static UINT dvcman_get_configuration(IWTSListener* pListener, void** ppPropertyBag) +static UINT dvcman_get_configuration(IWTSListener* pListener, + void** ppPropertyBag) { *ppPropertyBag = NULL; return ERROR_INTERNAL_ERROR; @@ -51,8 +52,8 @@ static UINT dvcman_get_configuration(IWTSListener* pListener, void** ppPropertyB * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, - const char* pszChannelName, ULONG ulFlags, - IWTSListenerCallback* pListenerCallback, IWTSListener** ppListener) + const char* pszChannelName, ULONG ulFlags, + IWTSListenerCallback* pListenerCallback, IWTSListener** ppListener) { DVCMAN* dvcman = (DVCMAN*) pChannelMgr; DVCMAN_LISTENER* listener; @@ -60,7 +61,6 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, if (dvcman->num_listeners < MAX_PLUGINS) { WLog_DBG(TAG, "create_listener: %d.%s.", dvcman->num_listeners, pszChannelName); - listener = (DVCMAN_LISTENER*) calloc(1, sizeof(DVCMAN_LISTENER)); if (!listener) @@ -71,15 +71,16 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, listener->iface.GetConfiguration = dvcman_get_configuration; listener->iface.pInterface = NULL; - listener->dvcman = dvcman; listener->channel_name = _strdup(pszChannelName); + if (!listener->channel_name) { WLog_ERR(TAG, "_strdup failed!"); free(listener); return CHANNEL_RC_NO_MEMORY; } + listener->flags = ulFlags; listener->listener_callback = pListenerCallback; @@ -87,7 +88,6 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, *ppListener = (IWTSListener*) listener; dvcman->listeners[dvcman->num_listeners++] = (IWTSListener*) listener; - return CHANNEL_RC_OK; } else @@ -103,7 +103,7 @@ static UINT dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, - const char* name, IWTSPlugin* pPlugin) + const char* name, IWTSPlugin* pPlugin) { DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->dvcman; @@ -116,12 +116,14 @@ static UINT dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, } else { - WLog_ERR(TAG, "register_plugin: Maximum DVC plugin number %d reached.", MAX_PLUGINS); + WLog_ERR(TAG, "register_plugin: Maximum DVC plugin number %d reached.", + MAX_PLUGINS); return ERROR_INTERNAL_ERROR; } } -static IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* name) +static IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, + const char* name) { int i; DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->dvcman; @@ -129,7 +131,7 @@ static IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const for (i = 0; i < dvcman->num_plugins; i++) { if (dvcman->plugin_names[i] == name || - strcmp(dvcman->plugin_names[i], name) == 0) + strcmp(dvcman->plugin_names[i], name) == 0) { return dvcman->plugins[i]; } @@ -145,24 +147,23 @@ static ADDIN_ARGV* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints) static void* dvcman_get_rdp_settings(IDRDYNVC_ENTRY_POINTS* pEntryPoints) { - return (void*) ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->settings; + return (void*)((DVCMAN_ENTRY_POINTS*) pEntryPoints)->settings; } -static UINT32 dvcman_get_channel_id(IWTSVirtualChannel * channel) +static UINT32 dvcman_get_channel_id(IWTSVirtualChannel* channel) { return ((DVCMAN_CHANNEL*) channel)->channel_id; } -static IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId) +static IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* + pChannelMgr, + UINT32 ChannelId) { int index; BOOL found = FALSE; DVCMAN_CHANNEL* channel; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - ArrayList_Lock(dvcman->channels); - index = 0; channel = (DVCMAN_CHANNEL*) ArrayList_GetItem(dvcman->channels, index++); @@ -178,39 +179,14 @@ static IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* } ArrayList_Unlock(dvcman->channels); - return (found) ? ((IWTSVirtualChannel*) channel) : NULL; } -static void* dvcman_get_channel_interface_by_name(IWTSVirtualChannelManager* pChannelMgr, - const char* ChannelName) -{ - int i; - BOOL found = FALSE; - void* pInterface = NULL; - DVCMAN_LISTENER* listener; - DVCMAN* dvcman = (DVCMAN*) pChannelMgr; - - for (i = 0; i < dvcman->num_listeners; i++) - { - listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; - - if (strcmp(listener->channel_name, ChannelName) == 0) - { - pInterface = listener->iface.pInterface; - found = TRUE; - break; - } - } - - return (found) ? pInterface : NULL; -} - static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) { DVCMAN* dvcman; - dvcman = (DVCMAN*) calloc(1, sizeof(DVCMAN)); + if (!dvcman) { WLog_ERR(TAG, "calloc failed!"); @@ -222,14 +198,17 @@ static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) dvcman->iface.GetChannelId = dvcman_get_channel_id; dvcman->drdynvc = plugin; dvcman->channels = ArrayList_New(TRUE); + if (!dvcman->channels) { WLog_ERR(TAG, "ArrayList_New failed!"); free(dvcman); return NULL; } + dvcman->channels->object.fnObjectFree = dvcman_channel_free; dvcman->pool = StreamPool_New(TRUE, 10); + if (!dvcman->pool) { WLog_ERR(TAG, "StreamPool_New failed!"); @@ -246,16 +225,16 @@ static IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) * * @return 0 on success, otherwise a Win32 error code */ -static UINT dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args, - rdpSettings* settings) +static UINT dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, + ADDIN_ARGV* args, + rdpSettings* settings) { DVCMAN_ENTRY_POINTS entryPoints; PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL; - WLog_INFO(TAG, "Loading Dynamic Virtual Channel %s", args->argv[0]); - - pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0], - NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); + pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry( + args->argv[0], + NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); if (pDVCPluginEntry) { @@ -266,21 +245,22 @@ static UINT dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV entryPoints.dvcman = (DVCMAN*) pChannelMgr; entryPoints.args = args; entryPoints.settings = settings; - return pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints); } - return CHANNEL_RC_OK; + return ERROR_INVALID_FUNCTION; } -static DVCMAN_CHANNEL* dvcman_channel_new(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId, const char* ChannelName) +static DVCMAN_CHANNEL* dvcman_channel_new(IWTSVirtualChannelManager* + pChannelMgr, + UINT32 ChannelId, const char* ChannelName) { DVCMAN_CHANNEL* channel; if (dvcman_find_channel_by_id(pChannelMgr, ChannelId)) { - WLog_ERR(TAG, "Protocol error: Duplicated ChannelId %d (%s)!", ChannelId, ChannelName); + WLog_ERR(TAG, "Protocol error: Duplicated ChannelId %d (%s)!", ChannelId, + ChannelName); return NULL; } @@ -295,6 +275,7 @@ static DVCMAN_CHANNEL* dvcman_channel_new(IWTSVirtualChannelManager* pChannelMgr channel->dvcman = (DVCMAN*) pChannelMgr; channel->channel_id = ChannelId; channel->channel_name = _strdup(ChannelName); + if (!channel->channel_name) { WLog_ERR(TAG, "_strdup failed!"); @@ -302,7 +283,7 @@ static DVCMAN_CHANNEL* dvcman_channel_new(IWTSVirtualChannelManager* pChannelMgr return NULL; } - if (!InitializeCriticalSectionEx(&(channel->lock), 0 ,0)) + if (!InitializeCriticalSectionEx(&(channel->lock), 0 , 0)) { WLog_ERR(TAG, "InitializeCriticalSectionEx failed!"); free(channel->channel_name); @@ -347,7 +328,6 @@ static void dvcman_free(IWTSVirtualChannelManager* pChannelMgr) DVCMAN_LISTENER* listener; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; UINT error; - ArrayList_Free(dvcman->channels); for (i = 0; i < dvcman->num_listeners; i++) @@ -365,13 +345,11 @@ static void dvcman_free(IWTSVirtualChannelManager* pChannelMgr) if (pPlugin->Terminated) if ((error = pPlugin->Terminated(pPlugin))) - WLog_ERR(TAG, "Terminated failed with error %lu!", error); + WLog_ERR(TAG, "Terminated failed with error %u!", error); } dvcman->num_plugins = 0; - StreamPool_Free(dvcman->pool); - free(dvcman); } @@ -394,7 +372,7 @@ static UINT dvcman_init(IWTSVirtualChannelManager* pChannelMgr) if (pPlugin->Initialize) if ((error = pPlugin->Initialize(pPlugin, pChannelMgr))) { - WLog_ERR(TAG, "Initialize failed with error %lu!", error); + WLog_ERR(TAG, "Initialize failed with error %u!", error); return error; } } @@ -408,18 +386,14 @@ static UINT dvcman_init(IWTSVirtualChannelManager* pChannelMgr) * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_write_channel(IWTSVirtualChannel* pChannel, ULONG cbSize, - const BYTE* pBuffer, void* pReserved) + const BYTE* pBuffer, void* pReserved) { UINT status; DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; - EnterCriticalSection(&(channel->lock)); - status = drdynvc_write_data(channel->dvcman->drdynvc, - channel->channel_id, pBuffer, cbSize); - + channel->channel_id, pBuffer, cbSize); LeaveCriticalSection(&(channel->lock)); - return status; } @@ -431,9 +405,7 @@ static UINT dvcman_write_channel(IWTSVirtualChannel* pChannel, ULONG cbSize, static UINT dvcman_close_channel_iface(IWTSVirtualChannel* pChannel) { DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; - WLog_DBG(TAG, "close_channel_iface: id=%d", channel->channel_id); - return CHANNEL_RC_OK; } @@ -442,8 +414,8 @@ static UINT dvcman_close_channel_iface(IWTSVirtualChannel* pChannel) * * @return 0 on success, otherwise a Win32 error code */ -UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId, const char* ChannelName) +static UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, + UINT32 ChannelId, const char* ChannelName) { int i; BOOL bAccept; @@ -471,25 +443,25 @@ UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, { channel->iface.Write = dvcman_write_channel; channel->iface.Close = dvcman_close_channel_iface; - bAccept = TRUE; pCallback = NULL; - if ((error = listener->listener_callback->OnNewChannelConnection(listener->listener_callback, - (IWTSVirtualChannel*) channel, NULL, &bAccept, &pCallback)) == CHANNEL_RC_OK && bAccept) + if ((error = listener->listener_callback->OnNewChannelConnection( + listener->listener_callback, + (IWTSVirtualChannel*) channel, NULL, &bAccept, &pCallback)) == CHANNEL_RC_OK + && bAccept) { WLog_DBG(TAG, "listener %s created new channel %d", - listener->channel_name, channel->channel_id); - + listener->channel_name, channel->channel_id); channel->status = 0; channel->channel_callback = pCallback; channel->pInterface = listener->iface.pInterface; - context = dvcman->drdynvc->context; - IFCALLRET(context->OnChannelConnected, error, context, ChannelName, listener->iface.pInterface); + IFCALLRET(context->OnChannelConnected, error, context, ChannelName, + listener->iface.pInterface); - if (error) - WLog_ERR(TAG, "context.ReceiveSamples failed with error %lu", error); + if (error) + WLog_ERR(TAG, "context.ReceiveSamples failed with error %u", error); return error; } @@ -497,7 +469,7 @@ UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, { if (error) { - WLog_ERR(TAG, "OnNewChannelConnection failed with error %lu!", error); + WLog_ERR(TAG, "OnNewChannelConnection failed with error %u!", error); return error; } else @@ -518,12 +490,11 @@ UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_open_channel(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId) + UINT32 ChannelId) { DVCMAN_CHANNEL* channel; IWTSVirtualChannelCallback* pCallback; UINT error; - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) @@ -535,11 +506,13 @@ static UINT dvcman_open_channel(IWTSVirtualChannelManager* pChannelMgr, if (channel->status == CHANNEL_RC_OK) { pCallback = channel->channel_callback; + if ((pCallback->OnOpen) && (error = pCallback->OnOpen(pCallback))) { - WLog_ERR(TAG, "OnOpen failed with eror %lu!", error); + WLog_ERR(TAG, "OnOpen failed with eror %u!", error); return error; } + WLog_DBG(TAG, "open_channel: ChannelId %d", ChannelId); } @@ -552,14 +525,13 @@ static UINT dvcman_open_channel(IWTSVirtualChannelManager* pChannelMgr, * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId) + UINT32 ChannelId) { DVCMAN_CHANNEL* channel; IWTSVirtualChannel* ichannel; DrdynvcClientContext* context; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; UINT error = CHANNEL_RC_OK; - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) @@ -575,27 +547,26 @@ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, if (channel->status == CHANNEL_RC_OK) { context = dvcman->drdynvc->context; + IFCALLRET(context->OnChannelDisconnected, error, context, channel->channel_name, + channel->pInterface); - IFCALLRET(context->OnChannelDisconnected, error, context, channel->channel_name, channel->pInterface); if (error) { - WLog_ERR(TAG, "OnChannelDisconnected returned with error %lu!", error); + WLog_ERR(TAG, "OnChannelDisconnected returned with error %u!", error); return error; } WLog_DBG(TAG, "dvcman_close_channel: channel %d closed", ChannelId); - ichannel = (IWTSVirtualChannel*) channel; if ((ichannel->Close) && (error = ichannel->Close(ichannel))) { - WLog_ERR(TAG, "Close failed with eror %lu!", error); + WLog_ERR(TAG, "Close failed with eror %u!", error); return error; } } ArrayList_Remove(dvcman->channels, channel); - return CHANNEL_RC_OK; } @@ -604,17 +575,21 @@ static UINT dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, * * @return 0 on success, otherwise a Win32 error code */ -static UINT dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId, UINT32 length) +static UINT dvcman_receive_channel_data_first(IWTSVirtualChannelManager* + pChannelMgr, + UINT32 ChannelId, UINT32 length) { DVCMAN_CHANNEL* channel; - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) { + /** + * Windows Server 2012 R2 can send some messages over Microsoft::Windows::RDS::Geometry::v08.01 + * even if the dynamic virtual channel wasn't registered on our side. Ignoring it works. + */ WLog_ERR(TAG, "ChannelId %d not found!", ChannelId); - return ERROR_INTERNAL_ERROR; + return CHANNEL_RC_OK; } if (channel->dvc_data) @@ -627,8 +602,8 @@ static UINT dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChanne WLog_ERR(TAG, "StreamPool_Take failed!"); return CHANNEL_RC_NO_MEMORY; } - channel->dvc_data_length = length; + channel->dvc_data_length = length; return CHANNEL_RC_OK; } @@ -638,24 +613,26 @@ static UINT dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChanne * @return 0 on success, otherwise a Win32 error code */ static UINT dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, - UINT32 ChannelId, wStream* data) + UINT32 ChannelId, wStream* data) { UINT status = CHANNEL_RC_OK; DVCMAN_CHANNEL* channel; size_t dataSize = Stream_GetRemainingLength(data); - channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (!channel) { + /* Windows 8.1 tries to open channels not created. + * Ignore cases like this. */ WLog_ERR(TAG, "ChannelId %d not found!", ChannelId); - return ERROR_INTERNAL_ERROR; + return CHANNEL_RC_OK; } if (channel->dvc_data) { /* Fragmented data */ - if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Capacity(channel->dvc_data)) + if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Capacity( + channel->dvc_data)) { WLog_ERR(TAG, "data exceeding declared length!"); Stream_Release(channel->dvc_data); @@ -665,18 +642,21 @@ static UINT dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, Stream_Write(channel->dvc_data, Stream_Pointer(data), dataSize); - if (((size_t) Stream_GetPosition(channel->dvc_data)) >= channel->dvc_data_length) + if (((size_t) Stream_GetPosition(channel->dvc_data)) >= + channel->dvc_data_length) { Stream_SealLength(channel->dvc_data); Stream_SetPosition(channel->dvc_data, 0); - status = channel->channel_callback->OnDataReceived(channel->channel_callback, channel->dvc_data); + status = channel->channel_callback->OnDataReceived(channel->channel_callback, + channel->dvc_data); Stream_Release(channel->dvc_data); channel->dvc_data = NULL; } } else { - status = channel->channel_callback->OnDataReceived(channel->channel_callback, data); + status = channel->channel_callback->OnDataReceived(channel->channel_callback, + data); } return status; @@ -720,15 +700,14 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s) } else { - status = drdynvc->channelEntryPoints.pVirtualChannelWrite(drdynvc->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + status = drdynvc->channelEntryPoints.pVirtualChannelWriteEx(drdynvc->InitHandle, + drdynvc->OpenHandle, Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]", WTSErrorToString(status), status); } return status; @@ -739,8 +718,8 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, - const BYTE* data, UINT32 dataSize) +static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, + const BYTE* data, UINT32 dataSize) { wStream* data_out; unsigned long pos; @@ -748,9 +727,7 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, UINT32 cbLen; unsigned long chunkLength; UINT status; - WLog_DBG(TAG, "write_data: ChannelId=%d size=%d", ChannelId, dataSize); - data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); if (!data_out) @@ -761,14 +738,13 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); - pos = Stream_GetPosition(data_out); + if (dataSize == 0) { Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x40 | cbChId); Stream_SetPosition(data_out, pos); - status = drdynvc_send(drdynvc, data_out); } else if (dataSize <= CHANNEL_CHUNK_LENGTH - pos) @@ -777,7 +753,6 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); Stream_Write(data_out, data, dataSize); - status = drdynvc_send(drdynvc, data_out); } else @@ -788,19 +763,16 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x20 | cbChId | (cbLen << 2)); Stream_SetPosition(data_out, pos); - chunkLength = CHANNEL_CHUNK_LENGTH - pos; - Stream_Write(data_out, data, chunkLength); - data += chunkLength; dataSize -= chunkLength; - status = drdynvc_send(drdynvc, data_out); while (status == CHANNEL_RC_OK && dataSize > 0) { data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); + if (!data_out) { WLog_ERR(TAG, "Stream_New failed!"); @@ -809,30 +781,26 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); - pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); - chunkLength = dataSize; if (chunkLength > CHANNEL_CHUNK_LENGTH - pos) chunkLength = CHANNEL_CHUNK_LENGTH - pos; Stream_Write(data_out, data, chunkLength); - data += chunkLength; dataSize -= chunkLength; - status = drdynvc_send(drdynvc, data_out); } } if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); return status; } @@ -848,9 +816,7 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc) { UINT status; wStream* s; - WLog_DBG(TAG, "capability_response"); - s = Stream_New(NULL, 4); if (!s) @@ -859,15 +825,15 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc) return CHANNEL_RC_NO_MEMORY; } - Stream_Write_UINT16(s, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */ + Stream_Write_UINT16(s, + 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */ Stream_Write_UINT16(s, drdynvc->version); - status = drdynvc_send(drdynvc, s); if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); } return status; @@ -879,12 +845,10 @@ static UINT drdynvc_send_capability_response(drdynvcPlugin* drdynvc) * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, - int cbChId, wStream* s) + int cbChId, wStream* s) { UINT status; - WLog_DBG(TAG, "capability_request Sp=%d cbChId=%d", Sp, cbChId); - Stream_Seek(s, 1); /* pad */ Stream_Read_UINT16(s, drdynvc->version); @@ -900,9 +864,7 @@ static UINT drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, } status = drdynvc_send_capability_response(drdynvc); - drdynvc->state = DRDYNVC_STATE_READY; - return status; } @@ -934,7 +896,7 @@ static UINT32 drdynvc_read_variable_uint(wStream* s, int cbLen) * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, - int cbChId, wStream* s) + int cbChId, wStream* s) { unsigned long pos; UINT status; @@ -949,22 +911,23 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, * capabilities pdu as it should. When this happens, * send a capabilities response. */ - drdynvc->version = 3; + if ((status = drdynvc_send_capability_response(drdynvc))) { WLog_ERR(TAG, "drdynvc_send_capability_response failed!"); return status; } + drdynvc->state = DRDYNVC_STATE_READY; } ChannelId = drdynvc_read_variable_uint(s, cbChId); pos = Stream_GetPosition(s); - WLog_DBG(TAG, "process_create_request: ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s)); - - channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s)); - + WLog_DBG(TAG, "process_create_request: ChannelId=%d ChannelName=%s", ChannelId, + Stream_Pointer(s)); + channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, + (char*) Stream_Pointer(s)); data_out = Stream_New(NULL, pos + 4); if (!s) @@ -985,15 +948,16 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, else { WLog_DBG(TAG, "no listener"); - Stream_Write_UINT32(data_out, (UINT32) 0xC0000001); /* same code used by mstsc */ + Stream_Write_UINT32(data_out, + (UINT32) 0xC0000001); /* same code used by mstsc */ } status = drdynvc_send(drdynvc, data_out); if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); return status; } @@ -1001,14 +965,14 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, { if ((status = dvcman_open_channel(drdynvc->channel_mgr, ChannelId))) { - WLog_ERR(TAG, "dvcman_open_channel failed with error %lu!", status); + WLog_ERR(TAG, "dvcman_open_channel failed with error %u!", status); return status; } } else { if ((status = dvcman_close_channel(drdynvc->channel_mgr, ChannelId))) - WLog_ERR(TAG, "dvcman_close_channel failed with error %lu!", status); + WLog_ERR(TAG, "dvcman_close_channel failed with error %u!", status); } return status; @@ -1020,17 +984,17 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, - int cbChId, wStream* s) + int cbChId, wStream* s) { UINT status; UINT32 Length; UINT32 ChannelId; - ChannelId = drdynvc_read_variable_uint(s, cbChId); Length = drdynvc_read_variable_uint(s, Sp); - WLog_DBG(TAG, "process_data_first: Sp=%d cbChId=%d, ChannelId=%d Length=%d", Sp, cbChId, ChannelId, Length); - - status = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length); + WLog_DBG(TAG, "process_data_first: Sp=%d cbChId=%d, ChannelId=%d Length=%d", Sp, + cbChId, ChannelId, Length); + status = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, + Length); if (status) return status; @@ -1043,13 +1007,13 @@ static UINT drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, * * @return 0 on success, otherwise a Win32 error code */ -static UINT drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) +static UINT drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, + wStream* s) { UINT32 ChannelId; - ChannelId = drdynvc_read_variable_uint(s, cbChId); - WLog_DBG(TAG, "process_data: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, ChannelId); - + WLog_DBG(TAG, "process_data: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, + ChannelId); return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId, s); } @@ -1059,20 +1023,19 @@ static UINT drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, wSt * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, - int cbChId, wStream* s) + int cbChId, wStream* s) { int value; UINT error; UINT32 ChannelId; wStream* data_out; - ChannelId = drdynvc_read_variable_uint(s, cbChId); - - WLog_DBG(TAG, "process_close_request: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, ChannelId); + WLog_DBG(TAG, "process_close_request: Sp=%d cbChId=%d, ChannelId=%d", Sp, + cbChId, ChannelId); if ((error = dvcman_close_channel(drdynvc->channel_mgr, ChannelId))) { - WLog_ERR(TAG, "dvcman_close_channel failed with error %lu!", error); + WLog_ERR(TAG, "dvcman_close_channel failed with error %u!", error); return error; } @@ -1085,15 +1048,13 @@ static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, } value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x03); - Stream_Write_UINT8(data_out, value); drdynvc_write_variable_uint(data_out, ChannelId); - error = drdynvc_send(drdynvc, data_out); if (error) - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(error), error); + WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(error), error); return error; } @@ -1109,14 +1070,11 @@ static UINT drdynvc_order_recv(drdynvcPlugin* drdynvc, wStream* s) int Cmd; int Sp; int cbChId; - Stream_Read_UINT8(s, value); - Cmd = (value & 0xf0) >> 4; Sp = (value & 0x0c) >> 2; cbChId = (value & 0x03) >> 0; - - WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d, ChannelId=%d", Cmd, Sp, cbChId); + WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d", Cmd, Sp,cbChId); switch (Cmd) { @@ -1147,112 +1105,13 @@ static UINT drdynvc_order_recv(drdynvcPlugin* drdynvc, wStream* s) } } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT drdynvc_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - g_InitHandles = ListDictionary_New(TRUE); - - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return ERROR_INTERNAL_ERROR; - - } - return CHANNEL_RC_OK; -} - -static void* drdynvc_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -static void drdynvc_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT drdynvc_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - g_OpenHandles = ListDictionary_New(TRUE); - - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return ERROR_INTERNAL_ERROR; - - } - return CHANNEL_RC_OK; -} - -static void* drdynvc_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -static void drdynvc_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - return; - - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -1303,18 +1162,17 @@ static UINT drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static void VCAPITYPE drdynvc_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle, + UINT event, LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - drdynvcPlugin* drdynvc; UINT error = CHANNEL_RC_OK; + drdynvcPlugin* drdynvc = (drdynvcPlugin*) lpUserParam; - drdynvc = (drdynvcPlugin*) drdynvc_get_open_handle_data(openHandle); - - if (!drdynvc) + if (!drdynvc || (drdynvc->OpenHandle != openHandle)) { WLog_ERR(TAG, "drdynvc_virtual_channel_open_event: error no match"); return; @@ -1323,8 +1181,10 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, UINT switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = drdynvc_virtual_channel_event_data_received(drdynvc, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "drdynvc_virtual_channel_event_data_received failed with error %lu", error); + if ((error = drdynvc_virtual_channel_event_data_received(drdynvc, pData, dataLength, totalLength, + dataFlags))) + WLog_ERR(TAG, "drdynvc_virtual_channel_event_data_received failed with error %u", error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -1334,17 +1194,17 @@ static void VCAPITYPE drdynvc_virtual_channel_open_event(DWORD openHandle, UINT case CHANNEL_EVENT_USER: break; } + if (error && drdynvc->rdpcontext) setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_open_event reported an error"); - } static void* drdynvc_virtual_channel_client_thread(void* arg) { wStream* data; wMessage message; - drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg; UINT error = CHANNEL_RC_OK; + drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg; while (1) { @@ -1368,18 +1228,22 @@ static void* drdynvc_virtual_channel_client_thread(void* arg) if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = drdynvc_order_recv(drdynvc, data))) { Stream_Free(data, TRUE); - WLog_ERR(TAG, "drdynvc_order_recv failed with error %lu!", error); + WLog_ERR(TAG, "drdynvc_order_recv failed with error %u!", error); break; } + Stream_Free(data, TRUE); } } if (error && drdynvc->rdpcontext) - setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_client_thread reported an error"); + setChannelError(drdynvc->rdpcontext, error, + "drdynvc_virtual_channel_client_thread reported an error"); + ExitThread((DWORD) error); return NULL; } @@ -1389,32 +1253,26 @@ static void* drdynvc_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, - LPVOID pData, UINT32 dataLength) +static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, LPVOID pData, + UINT32 dataLength) { + UINT error; UINT32 status; UINT32 index; ADDIN_ARGV* args; rdpSettings* settings; - UINT error; - - status = drdynvc->channelEntryPoints.pVirtualChannelOpen(drdynvc->InitHandle, - &drdynvc->OpenHandle, drdynvc->channelDef.name, drdynvc_virtual_channel_open_event); + status = drdynvc->channelEntryPoints.pVirtualChannelOpenEx(drdynvc->InitHandle, + &drdynvc->OpenHandle, drdynvc->channelDef.name, drdynvc_virtual_channel_open_event_ex); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); return status; } - if ((error = drdynvc_add_open_handle_data(drdynvc->OpenHandle, drdynvc))) - { - WLog_ERR(TAG, "drdynvc_add_open_handle_data failed with error %lu!", error); - return error; - } - drdynvc->queue = MessageQueue_New(NULL); + if (!drdynvc->queue) { error = CHANNEL_RC_NO_MEMORY; @@ -1423,6 +1281,7 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, } drdynvc->channel_mgr = dvcman_new(drdynvc); + if (!drdynvc->channel_mgr) { error = CHANNEL_RC_NO_MEMORY; @@ -1436,30 +1295,29 @@ static UINT drdynvc_virtual_channel_event_connected(drdynvcPlugin* drdynvc, { args = settings->DynamicChannelArray[index]; error = dvcman_load_addin(drdynvc->channel_mgr, args, settings); + if (CHANNEL_RC_OK != error) goto error; } if ((error = dvcman_init(drdynvc->channel_mgr))) { - WLog_ERR(TAG, "dvcman_init failed with error %lu!", error); + WLog_ERR(TAG, "dvcman_init failed with error %u!", error); goto error; } drdynvc->state = DRDYNVC_STATE_CAPABILITIES; if (!(drdynvc->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) drdynvc_virtual_channel_client_thread, (void*) drdynvc, 0, NULL))) + (LPTHREAD_START_ROUTINE) drdynvc_virtual_channel_client_thread, (void*) drdynvc, + 0, NULL))) { error = ERROR_INTERNAL_ERROR; WLog_ERR(TAG, "CreateThread failed!"); goto error; } - return CHANNEL_RC_OK; - error: - drdynvc_remove_open_handle_data(drdynvc->OpenHandle); return error; } @@ -1476,24 +1334,25 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) (WaitForSingleObject(drdynvc->thread, INFINITE) == WAIT_FAILED)) { status = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", status); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", status); return status; } MessageQueue_Free(drdynvc->queue); CloseHandle(drdynvc->thread); - drdynvc->queue = NULL; drdynvc->thread = NULL; - - status = drdynvc->channelEntryPoints.pVirtualChannelClose(drdynvc->OpenHandle); + status = drdynvc->channelEntryPoints.pVirtualChannelCloseEx(drdynvc->InitHandle, + drdynvc->OpenHandle); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(status), status); + WTSErrorToString(status), status); } + drdynvc->OpenHandle = 0; + if (drdynvc->data_in) { Stream_Free(drdynvc->data_in, TRUE); @@ -1506,7 +1365,6 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) drdynvc->channel_mgr = NULL; } - drdynvc_remove_open_handle_data(drdynvc->OpenHandle); return status; } @@ -1517,21 +1375,18 @@ static UINT drdynvc_virtual_channel_event_disconnected(drdynvcPlugin* drdynvc) */ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc) { - drdynvc_remove_init_handle_data(drdynvc->InitHandle); + drdynvc->InitHandle = 0; free(drdynvc); return CHANNEL_RC_OK; } -static VOID VCAPITYPE drdynvc_virtual_channel_init_event(LPVOID pInitHandle, - UINT event, LPVOID pData, - UINT dataLength) +static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle, + UINT event, LPVOID pData, UINT dataLength) { - drdynvcPlugin* drdynvc; UINT error = CHANNEL_RC_OK; + drdynvcPlugin* drdynvc = (drdynvcPlugin*) lpUserParam; - drdynvc = (drdynvcPlugin*) drdynvc_get_init_handle_data(pInitHandle); - - if (!drdynvc) + if (!drdynvc || (drdynvc->InitHandle != pInitHandle)) { WLog_ERR(TAG, "drdynvc_virtual_channel_init_event: error no match"); return; @@ -1541,21 +1396,26 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event(LPVOID pInitHandle, { case CHANNEL_EVENT_CONNECTED: if ((error = drdynvc_virtual_channel_event_connected(drdynvc, pData, dataLength))) - WLog_ERR(TAG, "drdynvc_virtual_channel_event_connected failed with error %lu", error); + WLog_ERR(TAG, "drdynvc_virtual_channel_event_connected failed with error %u", error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = drdynvc_virtual_channel_event_disconnected(drdynvc))) - WLog_ERR(TAG, "drdynvc_virtual_channel_event_disconnected failed with error %lu", error); + WLog_ERR(TAG, "drdynvc_virtual_channel_event_disconnected failed with error %u", error); + break; case CHANNEL_EVENT_TERMINATED: if ((error = drdynvc_virtual_channel_event_terminated(drdynvc))) - WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %lu", error); + WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %u", error); + break; } + if (error && drdynvc->rdpcontext) - setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_init_event reported an error"); + setChannelError(drdynvc->rdpcontext, error, + "drdynvc_virtual_channel_init_event_ex reported an error"); } /** @@ -1569,16 +1429,14 @@ static int drdynvc_get_version(DrdynvcClientContext* context) } /* drdynvc is always built-in */ -#define VirtualChannelEntry drdynvc_VirtualChannelEntry +#define VirtualChannelEntryEx drdynvc_VirtualChannelEntryEx -BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX pEntryPoints, PVOID pInitHandle) { UINT rc; drdynvcPlugin* drdynvc; - DrdynvcClientContext* context; - CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; - UINT error; - + DrdynvcClientContext* context = NULL; + CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx; drdynvc = (drdynvcPlugin*) calloc(1, sizeof(drdynvcPlugin)); if (!drdynvc) @@ -1588,18 +1446,15 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } drdynvc->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP; strcpy(drdynvc->channelDef.name, "drdynvc"); - drdynvc->state = DRDYNVC_STATE_INITIAL; + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints; - pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; - - if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && - (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) && + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { context = (DrdynvcClientContext*) calloc(1, sizeof(DrdynvcClientContext)); @@ -1612,46 +1467,28 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->handle = (void*) drdynvc; context->custom = NULL; - drdynvc->context = context; - context->GetVersion = drdynvc_get_version; drdynvc->rdpcontext = pEntryPointsEx->context; - - *(pEntryPointsEx->ppInterface) = (void*) context; } drdynvc->log = WLog_Get("com.freerdp.channels.drdynvc.client"); - - WLog_Print(drdynvc->log, WLOG_DEBUG, "VirtualChannelEntry"); - - CopyMemory(&(drdynvc->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - - rc = drdynvc->channelEntryPoints.pVirtualChannelInit(&drdynvc->InitHandle, - &drdynvc->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, drdynvc_virtual_channel_init_event); + WLog_Print(drdynvc->log, WLOG_DEBUG, "VirtualChannelEntryEx"); + CopyMemory(&(drdynvc->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); + drdynvc->InitHandle = pInitHandle; + rc = drdynvc->channelEntryPoints.pVirtualChannelInitEx(drdynvc, context, pInitHandle, + &drdynvc->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, drdynvc_virtual_channel_init_event_ex); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); + free(drdynvc->context); free(drdynvc); - free(*(pEntryPointsEx->ppInterface)); - *(pEntryPointsEx->ppInterface) = NULL; - return FALSE; - } - - drdynvc->channelEntryPoints.pInterface = *(drdynvc->channelEntryPoints.ppInterface); - drdynvc->channelEntryPoints.ppInterface = &(drdynvc->channelEntryPoints.pInterface); - - if ((error = drdynvc_add_init_handle_data(drdynvc->InitHandle, (void*) drdynvc))) - { - WLog_ERR(TAG, "drdynvc_add_init_handle_data failed with error %lu!",error); - free(drdynvc); - free(*(pEntryPointsEx->ppInterface)); - *(pEntryPointsEx->ppInterface) = NULL; return FALSE; } + drdynvc->channelEntryPoints.pInterface = context; return TRUE; } diff --git a/channels/drdynvc/client/drdynvc_main.h b/channels/drdynvc/client/drdynvc_main.h index 6829745..261fcd8 100644 --- a/channels/drdynvc/client/drdynvc_main.h +++ b/channels/drdynvc/client/drdynvc_main.h @@ -115,7 +115,7 @@ typedef enum _DRDYNVC_STATE DRDYNVC_STATE; struct drdynvc_plugin { CHANNEL_DEF channelDef; - CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; + CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints; wLog* log; HANDLE thread; @@ -134,7 +134,6 @@ struct drdynvc_plugin int PriorityCharge3; rdpContext* rdpcontext; - IWTSVirtualChannelManager* channel_mgr; }; diff --git a/channels/drdynvc/server/drdynvc_main.c b/channels/drdynvc/server/drdynvc_main.c index c83c88a..d1b8a30 100644 --- a/channels/drdynvc/server/drdynvc_main.c +++ b/channels/drdynvc/server/drdynvc_main.c @@ -45,14 +45,13 @@ static void* drdynvc_server_thread(void* arg) DWORD BytesReturned; DrdynvcServerContext* context; UINT error = ERROR_INTERNAL_ERROR; - context = (DrdynvcServerContext*) arg; - buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; s = Stream_New(NULL, 4096); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -60,7 +59,8 @@ static void* drdynvc_server_thread(void* arg) return NULL; } - if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, + &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); @@ -82,13 +82,16 @@ static void* drdynvc_server_thread(void* arg) break; } - if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned)) + if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, + &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); break; } + if (BytesReturned < 1) continue; + if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); @@ -96,7 +99,7 @@ static void* drdynvc_server_thread(void* arg) } if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); break; @@ -118,7 +121,8 @@ static void* drdynvc_server_thread(void* arg) */ static UINT drdynvc_server_start(DrdynvcServerContext* context) { - context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "drdynvc"); + context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, + WTS_CURRENT_SESSION, "drdynvc"); if (!context->priv->ChannelHandle) { @@ -131,8 +135,9 @@ static UINT drdynvc_server_start(DrdynvcServerContext* context) WLog_ERR(TAG, "CreateEvent failed!"); return ERROR_INTERNAL_ERROR; } + if (!(context->priv->Thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) drdynvc_server_thread, (void*) context, 0, NULL))) + (LPTHREAD_START_ROUTINE) drdynvc_server_thread, (void*) context, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); CloseHandle(context->priv->StopEvent); @@ -150,34 +155,32 @@ static UINT drdynvc_server_start(DrdynvcServerContext* context) */ static UINT drdynvc_server_stop(DrdynvcServerContext* context) { - UINT error; + UINT error; SetEvent(context->priv->StopEvent); if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } - CloseHandle(context->priv->Thread); + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + return error; + } + CloseHandle(context->priv->Thread); return CHANNEL_RC_OK; } DrdynvcServerContext* drdynvc_server_context_new(HANDLE vcm) { DrdynvcServerContext* context; - context = (DrdynvcServerContext*) calloc(1, sizeof(DrdynvcServerContext)); if (context) { context->vcm = vcm; - context->Start = drdynvc_server_start; context->Stop = drdynvc_server_stop; - context->priv = (DrdynvcServerPrivate*) calloc(1, sizeof(DrdynvcServerPrivate)); + if (!context->priv) { WLog_ERR(TAG, "calloc failed!"); diff --git a/channels/drive/client/CMakeLists.txt b/channels/drive/client/CMakeLists.txt index 3d5afae..ba2d0f4 100644 --- a/channels/drive/client/CMakeLists.txt +++ b/channels/drive/client/CMakeLists.txt @@ -36,7 +36,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE target_link_libraries(${MODULE_NAME} winpr freerdp) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/drive/client/dirent.h b/channels/drive/client/dirent.h index d9efa36..7c61d6a 100644 --- a/channels/drive/client/dirent.h +++ b/channels/drive/client/dirent.h @@ -222,7 +222,7 @@ static DIR *opendir(const char *dirname) * allows rewinddir() to function correctly when the current working * directory is changed between opendir() and rewinddir(). */ - if (GetFullPathNameA (dirname, MAX_PATH, dirp->patt, NULL)) { + if (GetFullPathNameA(dirname, MAX_PATH, dirp->patt, NULL)) { char *p; /* append the search pattern "\\*\0" to the directory name */ @@ -234,7 +234,7 @@ static DIR *opendir(const char *dirname) *p = '\0'; /* open directory stream and retrieve the first entry */ - dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data); + dirp->search_handle = FindFirstFileA(dirp->patt, &dirp->find_data); if (dirp->search_handle != INVALID_HANDLE_VALUE) { /* a directory entry is now waiting in memory */ dirp->cached = 1; diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c index 128e8ba..c9c64be 100644 --- a/channels/drive/client/drive_file.c +++ b/channels/drive/client/drive_file.c @@ -43,6 +43,7 @@ #include #include +#include #include #include @@ -546,7 +547,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN hFd = CreateFileA(file->fullpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFd == INVALID_HANDLE_VALUE) { - WLog_ERR(TAG, "Unable to set file time %s to %d", file->fullpath); + WLog_ERR(TAG, "Unable to create file %s", file->fullpath); return FALSE; } if (liCreationTime.QuadPart != 0) @@ -575,7 +576,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN } if (!SetFileTime(hFd, pftCreationTime, pftLastAccessTime, pftLastWriteTime)) { - WLog_ERR(TAG, "Unable to set file time %s to %d", file->fullpath); + WLog_ERR(TAG, "Unable to set file time on %s", file->fullpath); CloseHandle(hFd); return FALSE; } @@ -591,13 +592,13 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN hFd = CreateFileA(file->fullpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFd == INVALID_HANDLE_VALUE) { - WLog_ERR(TAG, "Unable to truncate %s to %d", file->fullpath, size); + WLog_ERR(TAG, "Unable to truncate %s to %lld", file->fullpath, (long long) size); return FALSE; } liSize.QuadPart = size; if (SetFilePointer(hFd, liSize.LowPart, &liSize.HighPart, FILE_BEGIN) == 0) { - WLog_ERR(TAG, "Unable to truncate %s to %d", file->fullpath, size); + WLog_ERR(TAG, "Unable to truncate %s to %lld", file->fullpath, (long long) size); CloseHandle(hFd); return FALSE; } diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index 39ed054..3344cc9 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -38,10 +38,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -78,15 +80,19 @@ static UINT32 drive_map_posix_err(int fs_errno) case EACCES: rc = STATUS_ACCESS_DENIED; break; + case ENOENT: rc = STATUS_NO_SUCH_FILE; break; + case EBUSY: rc = STATUS_DEVICE_BUSY; break; + case EEXIST: rc = STATUS_OBJECT_NAME_COLLISION; break; + case EISDIR: rc = STATUS_FILE_IS_A_DIRECTORY; break; @@ -102,10 +108,8 @@ static UINT32 drive_map_posix_err(int fs_errno) static DRIVE_FILE* drive_get_file_by_id(DRIVE_DEVICE* drive, UINT32 id) { DRIVE_FILE* file = NULL; - void* key = (void*) (size_t) id; - + void* key = (void*)(size_t) id; file = (DRIVE_FILE*) ListDictionary_GetItemValue(drive->files, key); - return file; } @@ -126,19 +130,19 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp) UINT32 CreateOptions; UINT32 PathLength; char* path = NULL; - Stream_Read_UINT32(irp->input, DesiredAccess); - Stream_Seek(irp->input, 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */ + Stream_Seek(irp->input, + 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */ Stream_Read_UINT32(irp->input, CreateDisposition); Stream_Read_UINT32(irp->input, CreateOptions); Stream_Read_UINT32(irp->input, PathLength); - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input), - PathLength / 2, &path, 0, NULL, NULL); + PathLength / 2, &path, 0, NULL, NULL); if (status < 1) { path = (char*) calloc(1, 1); + if (!path) { WLog_ERR(TAG, "calloc failed!"); @@ -146,11 +150,9 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp) } } - FileId = irp->devman->id_sequence++; - file = drive_file_new(drive->path, path, FileId, - DesiredAccess, CreateDisposition, CreateOptions); + DesiredAccess, CreateDisposition, CreateOptions); if (!file) { @@ -162,14 +164,14 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp) { FileId = 0; Information = 0; - /* map errno to windows result */ irp->IoStatus = drive_map_posix_err(file->err); drive_file_free(file); } else { - key = (void*) (size_t) file->id; + key = (void*)(size_t) file->id; + if (!ListDictionary_Add(drive->files, key, file)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); @@ -185,12 +187,15 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp) case FILE_OVERWRITE: Information = FILE_SUPERSEDED; break; + case FILE_OPEN_IF: Information = FILE_OPENED; break; + case FILE_OVERWRITE_IF: Information = FILE_OVERWRITTEN; break; + default: Information = 0; break; @@ -199,9 +204,7 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp) Stream_Write_UINT32(irp->output, FileId); Stream_Write_UINT8(irp->output, Information); - free(path); - return irp->Complete(irp); } @@ -214,10 +217,8 @@ static UINT drive_process_irp_close(DRIVE_DEVICE* drive, IRP* irp) { void* key; DRIVE_FILE* file; - file = drive_get_file_by_id(drive, irp->FileId); - - key = (void*) (size_t) irp->FileId; + key = (void*)(size_t) irp->FileId; if (!file) { @@ -230,7 +231,6 @@ static UINT drive_process_irp_close(DRIVE_DEVICE* drive, IRP* irp) } Stream_Zero(irp->output, 5); /* Padding(5) */ - return irp->Complete(irp); } @@ -245,10 +245,8 @@ static UINT drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp) UINT32 Length; UINT64 Offset; BYTE* buffer = NULL; - Stream_Read_UINT32(irp->input, Length); Stream_Read_UINT64(irp->input, Offset); - file = drive_get_file_by_id(drive, irp->FileId); if (!file) @@ -264,6 +262,7 @@ static UINT drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp) else { buffer = (BYTE*) malloc(Length); + if (!buffer) { WLog_ERR(TAG, "malloc failed!"); @@ -288,11 +287,11 @@ static UINT drive_process_irp_read(DRIVE_DEVICE* drive, IRP* irp) WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return ERROR_INTERNAL_ERROR; } + Stream_Write(irp->output, buffer, Length); } free(buffer); - return irp->Complete(irp); } @@ -306,11 +305,9 @@ static UINT drive_process_irp_write(DRIVE_DEVICE* drive, IRP* irp) DRIVE_FILE* file; UINT32 Length; UINT64 Offset; - Stream_Read_UINT32(irp->input, Length); Stream_Read_UINT64(irp->input, Offset); Stream_Seek(irp->input, 20); /* Padding */ - file = drive_get_file_by_id(drive, irp->FileId); if (!file) @@ -331,7 +328,6 @@ static UINT drive_process_irp_write(DRIVE_DEVICE* drive, IRP* irp) Stream_Write_UINT32(irp->output, Length); Stream_Write_UINT8(irp->output, 0); /* Padding */ - return irp->Complete(irp); } @@ -344,9 +340,7 @@ static UINT drive_process_irp_query_information(DRIVE_DEVICE* drive, IRP* irp) { DRIVE_FILE* file; UINT32 FsInformationClass; - Stream_Read_UINT32(irp->input, FsInformationClass); - file = drive_get_file_by_id(drive, irp->FileId); if (!file) @@ -371,18 +365,17 @@ static UINT drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp) DRIVE_FILE* file; UINT32 FsInformationClass; UINT32 Length; - Stream_Read_UINT32(irp->input, FsInformationClass); Stream_Read_UINT32(irp->input, Length); Stream_Seek(irp->input, 24); /* Padding */ - file = drive_get_file_by_id(drive, irp->FileId); if (!file) { irp->IoStatus = STATUS_UNSUCCESSFUL; } - else if (!drive_file_set_information(file, FsInformationClass, Length, irp->input)) + else if (!drive_file_set_information(file, FsInformationClass, Length, + irp->input)) { irp->IoStatus = STATUS_UNSUCCESSFUL; } @@ -391,7 +384,6 @@ static UINT drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp) irp->IoStatus = STATUS_DIRECTORY_NOT_EMPTY; Stream_Write_UINT32(irp->output, Length); - return irp->Complete(irp); } @@ -400,7 +392,8 @@ static UINT drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp) * * @return 0 on success, otherwise a Win32 error code */ -static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* irp) +static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, + IRP* irp) { UINT32 FsInformationClass; wStream* output = irp->output; @@ -410,9 +403,7 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* char* diskType = {"FAT32"}; WCHAR* outStr = NULL; int length; - Stream_Read_UINT32(irp->input, FsInformationClass); - STATVFS(drive->path, &svfst); STAT(drive->path, &st); @@ -422,6 +413,7 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* /* http://msdn.microsoft.com/en-us/library/cc232108.aspx */ length = ConvertToUnicode(sys_code_page, 0, volumeLabel, -1, &outStr, 0) * 2; Stream_Write_UINT32(output, 17 + length); /* Length */ + if (!Stream_EnsureRemainingCapacity(output, 17 + length)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); @@ -429,7 +421,8 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* return CHANNEL_RC_NO_MEMORY; } - Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */ + Stream_Write_UINT64(output, + FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */ #ifdef ANDROID Stream_Write_UINT32(output, svfst.f_fsid.__val[0]); /* VolumeSerialNumber */ #else @@ -445,11 +438,13 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* case FileFsSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232107.aspx */ Stream_Write_UINT32(output, 24); /* Length */ + if (!Stream_EnsureRemainingCapacity(output, 24)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ Stream_Write_UINT64(output, svfst.f_bavail); /* AvailableAllocationUnits */ Stream_Write_UINT32(output, 1); /* SectorsPerAllocationUnit */ @@ -460,19 +455,22 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* /* http://msdn.microsoft.com/en-us/library/cc232101.aspx */ length = ConvertToUnicode(sys_code_page, 0, diskType, -1, &outStr, 0) * 2; Stream_Write_UINT32(output, 12 + length); /* Length */ + if (!Stream_EnsureRemainingCapacity(output, 12 + length)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT32(output, - FILE_CASE_SENSITIVE_SEARCH | - FILE_CASE_PRESERVED_NAMES | - FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ + FILE_CASE_SENSITIVE_SEARCH | + FILE_CASE_PRESERVED_NAMES | + FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ #ifdef ANDROID Stream_Write_UINT32(output, 255); /* MaximumComponentNameLength */ #else - Stream_Write_UINT32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */ + Stream_Write_UINT32(output, + svfst.f_namemax/*510*/); /* MaximumComponentNameLength */ #endif Stream_Write_UINT32(output, length); /* FileSystemNameLength */ Stream_Write(output, outStr, length); /* FileSystemName (Unicode) */ @@ -482,13 +480,16 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* case FileFsFullSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232104.aspx */ Stream_Write_UINT32(output, 32); /* Length */ + if (!Stream_EnsureRemainingCapacity(output, 32)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ - Stream_Write_UINT64(output, svfst.f_bavail); /* CallerAvailableAllocationUnits */ + Stream_Write_UINT64(output, + svfst.f_bavail); /* CallerAvailableAllocationUnits */ Stream_Write_UINT64(output, svfst.f_bfree); /* AvailableAllocationUnits */ Stream_Write_UINT32(output, 1); /* SectorsPerAllocationUnit */ Stream_Write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ @@ -497,11 +498,13 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* case FileFsDeviceInformation: /* http://msdn.microsoft.com/en-us/library/cc232109.aspx */ Stream_Write_UINT32(output, 8); /* Length */ + if (!Stream_EnsureRemainingCapacity(output, 8)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT32(output, FILE_DEVICE_DISK); /* DeviceType */ Stream_Write_UINT32(output, 0); /* Characteristics */ break; @@ -526,11 +529,8 @@ static UINT drive_process_irp_silent_ignore(DRIVE_DEVICE* drive, IRP* irp) { UINT32 FsInformationClass; wStream* output = irp->output; - Stream_Read_UINT32(irp->input, FsInformationClass); - Stream_Write_UINT32(output, 0); /* Length */ - return irp->Complete(irp); } @@ -547,14 +547,12 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp) BYTE InitialQuery; UINT32 PathLength; UINT32 FsInformationClass; - Stream_Read_UINT32(irp->input, FsInformationClass); Stream_Read_UINT8(irp->input, InitialQuery); Stream_Read_UINT32(irp->input, PathLength); Stream_Seek(irp->input, 23); /* Padding */ - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input), - PathLength / 2, &path, 0, NULL, NULL); + PathLength / 2, &path, 0, NULL, NULL); if (status < 1) if (!(path = (char*) calloc(1, 1))) @@ -570,13 +568,13 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp) irp->IoStatus = STATUS_UNSUCCESSFUL; Stream_Write_UINT32(irp->output, 0); /* Length */ } - else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path, irp->output)) + else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, + path, irp->output)) { irp->IoStatus = STATUS_NO_MORE_FILES; } free(path); - return irp->Complete(irp); } @@ -603,6 +601,7 @@ static UINT drive_process_irp_directory_control(DRIVE_DEVICE* drive, IRP* irp) return irp->Complete(irp); break; } + return CHANNEL_RC_OK; } @@ -625,7 +624,6 @@ static UINT drive_process_irp_device_control(DRIVE_DEVICE* drive, IRP* irp) static UINT drive_process_irp(DRIVE_DEVICE* drive, IRP* irp) { UINT error; - irp->IoStatus = STATUS_SUCCESS; switch (irp->MajorFunction) @@ -675,6 +673,7 @@ static UINT drive_process_irp(DRIVE_DEVICE* drive, IRP* irp) error = irp->Complete(irp); break; } + return error; } @@ -709,13 +708,15 @@ static void* drive_thread_func(void* arg) if (irp) if ((error = drive_process_irp(drive, irp))) { - WLog_ERR(TAG, "drive_process_irp failed with error %lu!", error); + WLog_ERR(TAG, "drive_process_irp failed with error %u!", error); break; } } if (error && drive->rdpcontext) - setChannelError(drive->rdpcontext, error, "drive_thread_func reported an error"); + setChannelError(drive->rdpcontext, error, + "drive_thread_func reported an error"); + ExitThread((DWORD)error); return NULL; } @@ -728,11 +729,13 @@ static void* drive_thread_func(void* arg) static UINT drive_irp_request(DEVICE* device, IRP* irp) { DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device; + if (!MessageQueue_Post(drive->IrpQueue, NULL, 0, (void*) irp, NULL)) { WLog_ERR(TAG, "MessageQueue_Post failed!"); return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -744,24 +747,22 @@ static UINT drive_irp_request(DEVICE* device, IRP* irp) static UINT drive_free(DEVICE* device) { DRIVE_DEVICE* drive = (DRIVE_DEVICE*) device; - UINT error = CHANNEL_RC_OK; + UINT error = CHANNEL_RC_OK; - if (MessageQueue_PostQuit(drive->IrpQueue, 0) && (WaitForSingleObject(drive->thread, INFINITE) == WAIT_FAILED)) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } + if (MessageQueue_PostQuit(drive->IrpQueue, 0) + && (WaitForSingleObject(drive->thread, INFINITE) == WAIT_FAILED)) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + return error; + } CloseHandle(drive->thread); - ListDictionary_Free(drive->files); MessageQueue_Free(drive->IrpQueue); - Stream_Free(drive->device.data, TRUE); - free(drive); - return error; + return error; } /** @@ -769,29 +770,32 @@ static UINT drive_free(DEVICE* device) * * @return 0 on success, otherwise a Win32 error code */ -UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* name, char* path) +UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, + char* name, char* path) { int i, length; DRIVE_DEVICE* drive; UINT error; - #ifdef WIN32 + /* * We cannot enter paths like c:\ because : is an arg separator * thus, paths are entered as c+\ and the + is substituted here */ if (path[1] == '+') { - if ((path[0]>='a' && path[0]<='z') || (path[0]>='A' && path[0]<='Z')) + if ((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z')) { path[1] = ':'; } } + #endif if (name[0] && path[0]) { drive = (DRIVE_DEVICE*) calloc(1, sizeof(DRIVE_DEVICE)); + if (!drive) { WLog_ERR(TAG, "calloc failed!"); @@ -803,9 +807,9 @@ UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* drive->device.IRPRequest = drive_irp_request; drive->device.Free = drive_free; drive->rdpcontext = pEntryPoints->rdpcontext; - length = (int) strlen(name); drive->device.data = Stream_New(NULL, length + 1); + if (!drive->device.data) { WLog_ERR(TAG, "Stream_New failed!"); @@ -817,17 +821,19 @@ UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* Stream_Write_UINT8(drive->device.data, name[i] < 0 ? '_' : name[i]); drive->path = path; - drive->files = ListDictionary_New(TRUE); + if (!drive->files) { WLog_ERR(TAG, "ListDictionary_New failed!"); error = CHANNEL_RC_NO_MEMORY; goto out_error; } - ListDictionary_ValueObject(drive->files)->fnObjectFree = (OBJECT_FREE_FN) drive_file_free; + ListDictionary_ValueObject(drive->files)->fnObjectFree = + (OBJECT_FREE_FN) drive_file_free; drive->IrpQueue = MessageQueue_New(NULL); + if (!drive->IrpQueue) { WLog_ERR(TAG, "ListDictionary_New failed!"); @@ -835,13 +841,15 @@ UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* goto out_error; } - if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) drive))) + if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, + (DEVICE*) drive))) { - WLog_ERR(TAG, "RegisterDevice failed with error %lu!", error); + WLog_ERR(TAG, "RegisterDevice failed with error %u!", error); goto out_error; } - if (!(drive->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL))) + if (!(drive->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); goto out_error; @@ -849,6 +857,7 @@ UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* ResumeThread(drive->thread); } + return CHANNEL_RC_OK; out_error: MessageQueue_Free(drive->IrpQueue); @@ -857,7 +866,7 @@ out_error: return error; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DeviceServiceEntry drive_DeviceServiceEntry #else #define DeviceServiceEntry FREERDP_API DeviceServiceEntry @@ -878,21 +887,19 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) char* dev; int len; char devlist[512], buf[512]; - char *bufdup; - char *devdup; + char* bufdup; + char* devdup; #endif - drive = (RDPDR_DRIVE*) pEntryPoints->device; - #ifndef WIN32 - sys_code_page = CP_UTF8; + if (strcmp(drive->Path, "*") == 0) { /* all drives */ - free(drive->Path); drive->Path = _strdup("/"); + if (!drive->Path) { WLog_ERR(TAG, "_strdup failed!"); @@ -902,15 +909,14 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) else if (strcmp(drive->Path, "%") == 0) { char* home_env = NULL; - /* home directory */ - home_env = getenv("HOME"); free(drive->Path); if (home_env) { drive->Path = _strdup(home_env); + if (!drive->Path) { WLog_ERR(TAG, "_strdup failed!"); @@ -920,6 +926,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) else { drive->Path = _strdup("/"); + if (!drive->Path) { WLog_ERR(TAG, "_strdup failed!"); @@ -929,27 +936,29 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path); - #else sys_code_page = GetACP(); + /* Special case: path[0] == '*' -> export all drives */ /* Special case: path[0] == '%' -> user home dir */ if (strcmp(drive->Path, "%") == 0) { - sprintf_s(buf, sizeof(buf), "%s\\", getenv("USERPROFILE")); + GetEnvironmentVariableA("USERPROFILE", buf, sizeof(buf)); + PathCchAddBackslashA(buf, sizeof(buf)); free(drive->Path); drive->Path = _strdup(buf); + if (!drive->Path) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } + error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path); } else if (strcmp(drive->Path, "*") == 0) { int i; - /* Enumerate all devices: */ GetLogicalDriveStringsA(sizeof(devlist) - 1, devlist); @@ -963,11 +972,13 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) buf[len + 1] = dev[0]; buf[len + 2] = 0; buf[len + 3] = 0; + if (!(bufdup = _strdup(buf))) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } + if (!(devdup = _strdup(dev))) { WLog_ERR(TAG, "_strdup failed!"); @@ -985,7 +996,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path); } -#endif +#endif return error; } diff --git a/channels/echo/client/CMakeLists.txt b/channels/echo/client/CMakeLists.txt index 29e45de..149fbbf 100644 --- a/channels/echo/client/CMakeLists.txt +++ b/channels/echo/client/CMakeLists.txt @@ -25,7 +25,7 @@ include_directories(..) add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry") -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/echo/client/echo_main.c b/channels/echo/client/echo_main.c index ba50aaa..a16089f 100644 --- a/channels/echo/client/echo_main.c +++ b/channels/echo/client/echo_main.c @@ -160,7 +160,7 @@ static UINT echo_plugin_terminated(IWTSPlugin* pPlugin) return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DVCPluginEntry echo_DVCPluginEntry #else #define DVCPluginEntry FREERDP_API DVCPluginEntry diff --git a/channels/echo/client/echo_main.h b/channels/echo/client/echo_main.h index 1ce6a1f..565142f 100644 --- a/channels/echo/client/echo_main.h +++ b/channels/echo/client/echo_main.h @@ -31,9 +31,9 @@ #define DVC_TAG CHANNELS_TAG("echo.client") #ifdef WITH_DEBUG_DVC -#define DEBUG_DVC(fmt, ...) WLog_DBG(DVC_TAG, fmt, ## __VA_ARGS__) +#define DEBUG_DVC(...) WLog_DBG(DVC_TAG, __VA_ARGS__) #else -#define DEBUG_DVC(fmt, ...) do { } while (0) +#define DEBUG_DVC(...) do { } while (0) #endif #endif /* __ECHO_MAIN_H */ diff --git a/channels/echo/server/echo_main.c b/channels/echo/server/echo_main.c index 8c7f921..1a2f6fd 100644 --- a/channels/echo/server/echo_main.c +++ b/channels/echo/server/echo_main.c @@ -67,34 +67,34 @@ static UINT echo_server_open_channel(echo_server* echo) PULONG pSessionId = NULL; if (WTSQuerySessionInformationA(echo->context.vcm, WTS_CURRENT_SESSION, - WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned) == FALSE) + WTSSessionId, (LPSTR*) &pSessionId, &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSQuerySessionInformationA failed!"); return ERROR_INTERNAL_ERROR; } - echo->SessionId = (DWORD) *pSessionId; + echo->SessionId = (DWORD) * pSessionId; WTSFreeMemory(pSessionId); - hEvent = WTSVirtualChannelManagerGetEventHandle(echo->context.vcm); StartTick = GetTickCount(); while (echo->echo_channel == NULL) { if (WaitForSingleObject(hEvent, 1000) == WAIT_FAILED) - { - Error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", Error); - return Error; - } + { + Error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long)Error); + return Error; + } echo->echo_channel = WTSVirtualChannelOpenEx(echo->SessionId, - "ECHO", WTS_CHANNEL_OPTION_DYNAMIC); + "ECHO", WTS_CHANNEL_OPTION_DYNAMIC); if (echo->echo_channel) break; Error = GetLastError(); + if (Error == ERROR_NOT_FOUND) break; @@ -121,10 +121,14 @@ static void* echo_server_thread_func(void* arg) if ((error = echo_server_open_channel(echo))) { UINT error2 = 0; - WLog_ERR(TAG, "echo_server_open_channel failed with error %lu!", error); - IFCALLRET(echo->context.OpenResult, error2, &echo->context, ECHO_SERVER_OPEN_RESULT_NOTSUPPORTED); + WLog_ERR(TAG, "echo_server_open_channel failed with error %u!", error); + IFCALLRET(echo->context.OpenResult, error2, &echo->context, + ECHO_SERVER_OPEN_RESULT_NOTSUPPORTED); + if (error2) - WLog_ERR(TAG, "echo server's OpenResult callback failed with error %lu", error2); + WLog_ERR(TAG, "echo server's OpenResult callback failed with error %u", + error2); + goto out; } @@ -132,7 +136,8 @@ static void* echo_server_thread_func(void* arg) BytesReturned = 0; ChannelEvent = NULL; - if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualEventHandle, &buffer, + &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); @@ -153,40 +158,50 @@ static void* echo_server_thread_func(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error); break; } if (status == WAIT_OBJECT_0) { - IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_CLOSED); + IFCALLRET(echo->context.OpenResult, error, &echo->context, + ECHO_SERVER_OPEN_RESULT_CLOSED); + if (error) - WLog_ERR(TAG, "OpenResult failed with error %lu!", error); + WLog_ERR(TAG, "OpenResult failed with error %u!", error); + break; } - if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE) + if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualChannelReady, &buffer, + &BytesReturned) == FALSE) { - IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_ERROR); + IFCALLRET(echo->context.OpenResult, error, &echo->context, + ECHO_SERVER_OPEN_RESULT_ERROR); + if (error) - WLog_ERR(TAG, "OpenResult failed with error %lu!", error); + WLog_ERR(TAG, "OpenResult failed with error %u!", error); + break; } ready = *((BOOL*) buffer); - WTSFreeMemory(buffer); if (ready) { - IFCALLRET(echo->context.OpenResult, error, &echo->context, ECHO_SERVER_OPEN_RESULT_OK); + IFCALLRET(echo->context.OpenResult, error, &echo->context, + ECHO_SERVER_OPEN_RESULT_OK); + if (error) - WLog_ERR(TAG, "OpenResult failed with error %lu!", error); + WLog_ERR(TAG, "OpenResult failed with error %u!", error); + break; } } s = Stream_New(NULL, 4096); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -197,23 +212,24 @@ static void* echo_server_thread_func(void* arg) while (ready) { - status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error); + break; + } - if (status == WAIT_OBJECT_0) + if (status == WAIT_OBJECT_0) break; Stream_SetPosition(s, 0); - WTSVirtualChannelRead(echo->echo_channel, 0, NULL, 0, &BytesReturned); + if (BytesReturned < 1) continue; + if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); @@ -222,26 +238,31 @@ static void* echo_server_thread_func(void* arg) } if (WTSVirtualChannelRead(echo->echo_channel, 0, (PCHAR) Stream_Buffer(s), - (ULONG) Stream_Capacity(s), &BytesReturned) == FALSE) + (ULONG) Stream_Capacity(s), &BytesReturned) == FALSE) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; break; } - IFCALLRET(echo->context.Response, error, &echo->context, (BYTE *) Stream_Buffer(s), BytesReturned); + IFCALLRET(echo->context.Response, error, &echo->context, + (BYTE*) Stream_Buffer(s), BytesReturned); + if (error) { - WLog_ERR(TAG, "Response failed with error %lu!", error); + WLog_ERR(TAG, "Response failed with error %u!", error); break; } } + Stream_Free(s, TRUE); WTSVirtualChannelClose(echo->echo_channel); echo->echo_channel = NULL; out: + if (error && echo->context.rdpcontext) - setChannelError(echo->context.rdpcontext, error, "echo_server_thread_func reported an error"); + setChannelError(echo->context.rdpcontext, error, + "echo_server_thread_func reported an error"); ExitThread((DWORD)error); return NULL; @@ -264,7 +285,8 @@ static UINT echo_server_open(echo_server_context* context) return ERROR_INTERNAL_ERROR; } - if (!(echo->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) echo_server_thread_func, (void*) echo, 0, NULL))) + if (!(echo->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) echo_server_thread_func, (void*) echo, 0, NULL))) { WLog_ERR(TAG, "CreateEvent failed!"); CloseHandle(echo->stopEvent); @@ -272,6 +294,7 @@ static UINT echo_server_open(echo_server_context* context) return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } @@ -282,7 +305,7 @@ static UINT echo_server_open(echo_server_context* context) */ static UINT echo_server_close(echo_server_context* context) { - UINT error = CHANNEL_RC_OK; + UINT error = CHANNEL_RC_OK; echo_server* echo = (echo_server*) context; if (echo->thread) @@ -290,31 +313,31 @@ static UINT echo_server_close(echo_server_context* context) SetEvent(echo->stopEvent); if (WaitForSingleObject(echo->thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + return error; + } CloseHandle(echo->thread); CloseHandle(echo->stopEvent); echo->thread = NULL; echo->stopEvent = NULL; } + return error; } -static BOOL echo_server_request(echo_server_context* context, const BYTE* buffer, UINT32 length) +static BOOL echo_server_request(echo_server_context* context, + const BYTE* buffer, UINT32 length) { echo_server* echo = (echo_server*) context; - return WTSVirtualChannelWrite(echo->echo_channel, (PCHAR) buffer, length, NULL); } echo_server_context* echo_server_context_new(HANDLE vcm) { echo_server* echo; - echo = (echo_server*) calloc(1, sizeof(echo_server)); if (echo) @@ -333,8 +356,6 @@ echo_server_context* echo_server_context_new(HANDLE vcm) void echo_server_context_free(echo_server_context* context) { echo_server* echo = (echo_server*) context; - echo_server_close(context); - free(echo); } diff --git a/channels/encomsp/client/CMakeLists.txt b/channels/encomsp/client/CMakeLists.txt index dd855b8..92ee1f8 100644 --- a/channels/encomsp/client/CMakeLists.txt +++ b/channels/encomsp/client/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS encomsp_main.c encomsp_main.h) -add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") +add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx") set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client") diff --git a/channels/encomsp/client/encomsp_main.c b/channels/encomsp/client/encomsp_main.c index 239954c..578085d 100644 --- a/channels/encomsp/client/encomsp_main.c +++ b/channels/encomsp/client/encomsp_main.c @@ -46,7 +46,6 @@ static UINT encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ - return CHANNEL_RC_OK; } @@ -59,7 +58,6 @@ static UINT encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header) { Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */ Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */ - return CHANNEL_RC_OK; } @@ -86,18 +84,18 @@ static UINT encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) return ERROR_INVALID_DATA; } - if (Stream_GetRemainingLength(s) < (size_t) (str->cchString * 2)) + if (Stream_GetRemainingLength(s) < (size_t)(str->cchString * 2)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; } Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ - return CHANNEL_RC_OK; } -EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp) +static EncomspClientContext* encomsp_get_client_interface( + encomspPlugin* encomsp) { EncomspClientContext* pInterface; pInterface = (EncomspClientContext*) encomsp->channelEntryPoints.pInterface; @@ -109,7 +107,7 @@ EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp) * * @return 0 on success, otherwise a Win32 error code */ -UINT encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) +static UINT encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) { UINT status; @@ -120,13 +118,13 @@ UINT encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) WLog_INFO(TAG, "EncomspWrite (%d)", Stream_Length(s)); winpr_HexDump(Stream_Buffer(s), Stream_Length(s)); #endif - - status = encomsp->channelEntryPoints.pVirtualChannelWrite(encomsp->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_Length(s), s); + status = encomsp->channelEntryPoints.pVirtualChannelWriteEx(encomsp->InitHandle, + encomsp->OpenHandle, + Stream_Buffer(s), (UINT32) Stream_Length(s), s); if (status != CHANNEL_RC_OK) - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); return status; } @@ -136,20 +134,19 @@ UINT encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, + ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_FILTER_UPDATED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 1) @@ -159,7 +156,6 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, } Stream_Read_UINT8(s, pdu.Flags); /* Flags (1 byte) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -170,7 +166,7 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -180,8 +176,9 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, } IFCALLRET(context->FilterUpdated, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->FilterUpdated failed with error %lu", error); + WLog_ERR(TAG, "context->FilterUpdated failed with error %u", error); return error; } @@ -191,20 +188,19 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_APPLICATION_CREATED_PDU pdu; UINT error; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 6) @@ -216,9 +212,9 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ Stream_Read_UINT32(s, pdu.AppId); /* AppId (4 bytes) */ - if ((error = encomsp_read_unicode_string(s, &(pdu.Name)) )) + if ((error = encomsp_read_unicode_string(s, &(pdu.Name)))) { - WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %lu", error); + WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %u", error); return error; } @@ -232,7 +228,7 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -242,8 +238,9 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream } IFCALLRET(context->ApplicationCreated, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->ApplicationCreated failed with error %lu", error); + WLog_ERR(TAG, "context->ApplicationCreated failed with error %u", error); return error; } @@ -253,20 +250,19 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_APPLICATION_REMOVED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 4) @@ -276,7 +272,6 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream } Stream_Read_UINT32(s, pdu.AppId); /* AppId (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -287,7 +282,7 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -297,8 +292,9 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream } IFCALLRET(context->ApplicationRemoved, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->ApplicationRemoved failed with error %lu", error); + WLog_ERR(TAG, "context->ApplicationRemoved failed with error %u", error); return error; } @@ -308,20 +304,19 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, + ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_WINDOW_CREATED_PDU pdu; UINT error; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 10) @@ -336,7 +331,7 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, if ((error = encomsp_read_unicode_string(s, &(pdu.Name)))) { - WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %lu", error); + WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %u", error); return error; } @@ -350,7 +345,7 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -360,8 +355,9 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, } IFCALLRET(context->WindowCreated, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->WindowCreated failed with error %lu", error); + WLog_ERR(TAG, "context->WindowCreated failed with error %u", error); return error; } @@ -371,20 +367,19 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, + ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_WINDOW_REMOVED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 4) @@ -394,7 +389,6 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, } Stream_Read_UINT32(s, pdu.WndId); /* WndId (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -405,7 +399,7 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -415,8 +409,9 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, } IFCALLRET(context->WindowRemoved, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->WindowRemoved failed with error %lu", error); + WLog_ERR(TAG, "context->WindowRemoved failed with error %u", error); return error; } @@ -426,20 +421,19 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, + ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_SHOW_WINDOW_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 4) @@ -449,7 +443,6 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENC } Stream_Read_UINT32(s, pdu.WndId); /* WndId (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -460,7 +453,7 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENC if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -470,8 +463,9 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENC } IFCALLRET(context->ShowWindow, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->ShowWindow failed with error %lu", error); + WLog_ERR(TAG, "context->ShowWindow failed with error %u", error); return error; } @@ -481,20 +475,19 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENC * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_PARTICIPANT_CREATED_PDU pdu; UINT error; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 10) @@ -507,10 +500,9 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream Stream_Read_UINT32(s, pdu.GroupId); /* GroupId (4 bytes) */ Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ - if ((error = encomsp_read_unicode_string(s, &(pdu.FriendlyName)))) { - WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %lu", error); + WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %u", error); return error; } @@ -524,7 +516,7 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -534,8 +526,9 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream } IFCALLRET(context->ParticipantCreated, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->ParticipantCreated failed with error %lu", error); + WLog_ERR(TAG, "context->ParticipantCreated failed with error %u", error); return error; } @@ -545,20 +538,19 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_PARTICIPANT_REMOVED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 12) @@ -570,7 +562,6 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ Stream_Read_UINT32(s, pdu.DiscType); /* DiscType (4 bytes) */ Stream_Read_UINT32(s, pdu.DiscCode); /* DiscCode (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -581,7 +572,7 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -591,8 +582,9 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream } IFCALLRET(context->ParticipantRemoved, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->ParticipantRemoved failed with error %lu", error); + WLog_ERR(TAG, "context->ParticipantRemoved failed with error %u", error); return error; } @@ -602,20 +594,19 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_change_participant_control_level_pdu( + encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 6) @@ -626,7 +617,6 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -637,7 +627,7 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -647,8 +637,10 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc } IFCALLRET(context->ChangeParticipantControlLevel, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %lu", error); + WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %u", + error); return error; } @@ -658,18 +650,18 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) +static UINT encomsp_send_change_participant_control_level_pdu( + EncomspClientContext* context, + ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) { wStream* s; encomspPlugin* encomsp; UINT error; - encomsp = (encomspPlugin*) context->handle; - pdu->Type = ODTYPE_PARTICIPANT_CTRL_CHANGED; pdu->Length = ENCOMSP_ORDER_HEADER_SIZE + 6; - s = Stream_New(NULL, pdu->Length); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -678,15 +670,13 @@ static UINT encomsp_send_change_participant_control_level_pdu(EncomspClientConte if ((error = encomsp_write_header(s, (ENCOMSP_ORDER_HEADER*) pdu))) { - WLog_ERR(TAG, "encomsp_write_header failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_write_header failed with error %u!", error); return error; } Stream_Write_UINT16(s, pdu->Flags); /* Flags (2 bytes) */ Stream_Write_UINT32(s, pdu->ParticipantId); /* ParticipantId (4 bytes) */ - Stream_SealLength(s); - return encomsp_virtual_channel_write(encomsp, s); } @@ -695,22 +685,20 @@ static UINT encomsp_send_change_participant_control_level_pdu(EncomspClientConte * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -721,7 +709,7 @@ static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStr if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -731,8 +719,9 @@ static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStr } IFCALLRET(context->GraphicsStreamPaused, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->GraphicsStreamPaused failed with error %lu", error); + WLog_ERR(TAG, "context->GraphicsStreamPaused failed with error %u", error); return error; } @@ -742,22 +731,20 @@ static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStr * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, + wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU pdu; UINT error = CHANNEL_RC_OK; - context = encomsp_get_client_interface(encomsp); if (!context) return ERROR_INVALID_HANDLE; beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -768,7 +755,7 @@ static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wSt if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t)((beg + header->Length) - end)) { WLog_ERR(TAG, "Not enought data!"); return ERROR_INVALID_DATA; @@ -778,8 +765,9 @@ static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wSt } IFCALLRET(context->GraphicsStreamResumed, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->GraphicsStreamResumed failed with error %lu", error); + WLog_ERR(TAG, "context->GraphicsStreamResumed failed with error %u", error); return error; } @@ -798,7 +786,7 @@ static UINT encomsp_process_receive(encomspPlugin* encomsp, wStream* s) { if ((error = encomsp_read_header(s, &header))) { - WLog_ERR(TAG, "encomsp_read_header failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_read_header failed with error %u!", error); return error; } @@ -809,89 +797,109 @@ static UINT encomsp_process_receive(encomspPlugin* encomsp, wStream* s) case ODTYPE_FILTER_STATE_UPDATED: if ((error = encomsp_recv_filter_updated_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_filter_updated_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_filter_updated_pdu failed with error %u!", error); return error; } + break; case ODTYPE_APP_REMOVED: if ((error = encomsp_recv_application_removed_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %u!", + error); return error; } + break; case ODTYPE_APP_CREATED: if ((error = encomsp_recv_application_created_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %u!", + error); return error; } + break; case ODTYPE_WND_REMOVED: if ((error = encomsp_recv_window_removed_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_window_removed_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_window_removed_pdu failed with error %u!", error); return error; } + break; case ODTYPE_WND_CREATED: if ((error = encomsp_recv_window_created_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_window_created_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_window_created_pdu failed with error %u!", error); return error; } + break; case ODTYPE_WND_SHOW: if ((error = encomsp_recv_show_window_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_show_window_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_show_window_pdu failed with error %u!", error); return error; } + break; case ODTYPE_PARTICIPANT_REMOVED: if ((error = encomsp_recv_participant_removed_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_participant_removed_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_participant_removed_pdu failed with error %u!", + error); return error; } + break; case ODTYPE_PARTICIPANT_CREATED: if ((error = encomsp_recv_participant_created_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_participant_created_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_participant_created_pdu failed with error %u!", + error); return error; } + break; case ODTYPE_PARTICIPANT_CTRL_CHANGED: - if ((error = encomsp_recv_change_participant_control_level_pdu(encomsp, s, &header))) + if ((error = encomsp_recv_change_participant_control_level_pdu(encomsp, s, + &header))) { - WLog_ERR(TAG, "encomsp_recv_change_participant_control_level_pdu failed with error %lu!", error); + WLog_ERR(TAG, + "encomsp_recv_change_participant_control_level_pdu failed with error %u!", + error); return error; } + break; case ODTYPE_GRAPHICS_STREAM_PAUSED: if ((error = encomsp_recv_graphics_stream_paused_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_graphics_stream_paused_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_graphics_stream_paused_pdu failed with error %u!", + error); return error; } + break; case ODTYPE_GRAPHICS_STREAM_RESUMED: if ((error = encomsp_recv_graphics_stream_resumed_pdu(encomsp, s, &header))) { - WLog_ERR(TAG, "encomsp_recv_graphics_stream_resumed_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_recv_graphics_stream_resumed_pdu failed with error %u!", + error); return error; } + break; default: @@ -899,111 +907,16 @@ static UINT encomsp_process_receive(encomspPlugin* encomsp, wStream* s) return ERROR_INVALID_DATA; break; } - } + return error; } static void encomsp_process_connect(encomspPlugin* encomsp) { - } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT encomsp_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - } - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* encomsp_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void encomsp_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT encomsp_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - } - - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* encomsp_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void encomsp_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - -int encomsp_send(encomspPlugin* encomsp, wStream* s) +static int encomsp_send(encomspPlugin* encomsp, wStream* s) { UINT32 status = 0; encomspPlugin* plugin = (encomspPlugin*) encomsp; @@ -1014,15 +927,15 @@ int encomsp_send(encomspPlugin* encomsp, wStream* s) } else { - status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + status = plugin->channelEntryPoints.pVirtualChannelWriteEx(plugin->InitHandle, plugin->OpenHandle, + Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); } return status; @@ -1034,7 +947,7 @@ int encomsp_send(encomspPlugin* encomsp, wStream* s) * @return 0 on success, otherwise a Win32 error code */ static UINT encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -1047,6 +960,7 @@ static UINT encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp, Stream_Free(encomsp->data_in, TRUE); encomsp->data_in = Stream_New(NULL, totalLength); + if (!encomsp->data_in) { WLog_ERR(TAG, "Stream_New failed!"); @@ -1055,11 +969,13 @@ static UINT encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp, } data_in = encomsp->data_in; + if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return ERROR_INTERNAL_ERROR; } + Stream_Write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) @@ -1080,28 +996,31 @@ static UINT encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE encomsp_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - encomspPlugin* encomsp; UINT error = CHANNEL_RC_OK; + encomspPlugin* encomsp = (encomspPlugin*) lpUserParam; - encomsp = (encomspPlugin*) encomsp_get_open_handle_data(openHandle); - - if (!encomsp) + if (!encomsp || (encomsp->OpenHandle != openHandle)) { - WLog_ERR(TAG, "encomsp_virtual_channel_open_event: error no match"); + WLog_ERR(TAG, "error no match"); return; } switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = encomsp_virtual_channel_event_data_received(encomsp, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "encomsp_virtual_channel_event_data_received failed with error %lu", error); + if ((error = encomsp_virtual_channel_event_data_received(encomsp, pData, + dataLength, totalLength, dataFlags))) + WLog_ERR(TAG, + "encomsp_virtual_channel_event_data_received failed with error %u", error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -1111,6 +1030,7 @@ static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, UINT case CHANNEL_EVENT_USER: break; } + if (error && encomsp->rdpcontext) setChannelError(encomsp->rdpcontext, error, "encomsp_virtual_channel_open_event reported an error"); @@ -1123,7 +1043,6 @@ static void* encomsp_virtual_channel_client_thread(void* arg) wMessage message; encomspPlugin* encomsp = (encomspPlugin*) arg; UINT error = CHANNEL_RC_OK; - encomsp_process_connect(encomsp); while (1) @@ -1148,16 +1067,18 @@ static void* encomsp_virtual_channel_client_thread(void* arg) if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = encomsp_process_receive(encomsp, data))) { - WLog_ERR(TAG, "encomsp_process_receive failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_process_receive failed with error %u!", error); break; } } } if (error && encomsp->rdpcontext) - setChannelError(encomsp->rdpcontext, error, "encomsp_virtual_channel_client_thread reported an error"); + setChannelError(encomsp->rdpcontext, error, + "encomsp_virtual_channel_client_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -1168,28 +1089,23 @@ static void* encomsp_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_virtual_channel_event_connected(encomspPlugin* encomsp, LPVOID pData, UINT32 dataLength) +static UINT encomsp_virtual_channel_event_connected(encomspPlugin* encomsp, + LPVOID pData, UINT32 dataLength) { UINT32 status; - UINT error; - - status = encomsp->channelEntryPoints.pVirtualChannelOpen(encomsp->InitHandle, - &encomsp->OpenHandle, encomsp->channelDef.name, encomsp_virtual_channel_open_event); + status = encomsp->channelEntryPoints.pVirtualChannelOpenEx(encomsp->InitHandle, + &encomsp->OpenHandle, encomsp->channelDef.name, + encomsp_virtual_channel_open_event_ex); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); - return status; - } - - if ((error = encomsp_add_open_handle_data(encomsp->OpenHandle, encomsp))) - { - WLog_ERR(TAG, "encomsp_process_receive failed with error %lu!", error); + WTSErrorToString(status), status); return status; } encomsp->queue = MessageQueue_New(NULL); + if (!encomsp->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -1197,12 +1113,14 @@ static UINT encomsp_virtual_channel_event_connected(encomspPlugin* encomsp, LPVO } if (!(encomsp->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) encomsp_virtual_channel_client_thread, (void*) encomsp, 0, NULL))) + (LPTHREAD_START_ROUTINE) encomsp_virtual_channel_client_thread, (void*) encomsp, + 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); MessageQueue_Free(encomsp->queue); return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -1215,34 +1133,35 @@ static UINT encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp) { UINT rc; - if (MessageQueue_PostQuit(encomsp->queue, 0) && (WaitForSingleObject(encomsp->thread, INFINITE) == WAIT_FAILED)) - { - rc = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); - return rc; - } + if (MessageQueue_PostQuit(encomsp->queue, 0) + && (WaitForSingleObject(encomsp->thread, INFINITE) == WAIT_FAILED)) + { + rc = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", rc); + return rc; + } MessageQueue_Free(encomsp->queue); CloseHandle(encomsp->thread); - encomsp->queue = NULL; encomsp->thread = NULL; + rc = encomsp->channelEntryPoints.pVirtualChannelCloseEx(encomsp->InitHandle, encomsp->OpenHandle); - rc = encomsp->channelEntryPoints.pVirtualChannelClose(encomsp->OpenHandle); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(rc), rc); + WTSErrorToString(rc), rc); return rc; } + encomsp->OpenHandle = 0; + if (encomsp->data_in) { Stream_Free(encomsp->data_in, TRUE); encomsp->data_in = NULL; } - encomsp_remove_open_handle_data(encomsp->OpenHandle); return CHANNEL_RC_OK; } @@ -1254,41 +1173,44 @@ static UINT encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp) */ static UINT encomsp_virtual_channel_event_terminated(encomspPlugin* encomsp) { - encomsp_remove_init_handle_data(encomsp->InitHandle); + encomsp->InitHandle = 0; free(encomsp); return CHANNEL_RC_OK; } -static VOID VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle, - UINT event, LPVOID pData, - UINT dataLength) +static VOID VCAPITYPE encomsp_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle, + UINT event, LPVOID pData, UINT dataLength) { - encomspPlugin* encomsp; UINT error = CHANNEL_RC_OK; + encomspPlugin* encomsp = (encomspPlugin*) lpUserParam; - encomsp = (encomspPlugin*) encomsp_get_init_handle_data(pInitHandle); - - if (!encomsp) + if (!encomsp || (encomsp->InitHandle != pInitHandle)) { - WLog_ERR(TAG, "encomsp_virtual_channel_init_event: error no match"); + WLog_ERR(TAG, "error no match"); return; } switch (event) { case CHANNEL_EVENT_CONNECTED: - if ((error = encomsp_virtual_channel_event_connected(encomsp, pData, dataLength))) - WLog_ERR(TAG, "encomsp_virtual_channel_event_connected failed with error %lu", error); + if ((error = encomsp_virtual_channel_event_connected(encomsp, pData, + dataLength))) + WLog_ERR(TAG, "encomsp_virtual_channel_event_connected failed with error %u", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = encomsp_virtual_channel_event_disconnected(encomsp))) - WLog_ERR(TAG, "encomsp_virtual_channel_event_disconnected failed with error %lu", error); + WLog_ERR(TAG, + "encomsp_virtual_channel_event_disconnected failed with error %u", error); + break; case CHANNEL_EVENT_TERMINATED: encomsp_virtual_channel_event_terminated(encomsp); break; + default: WLog_ERR(TAG, "Unhandled event type %d", event); } @@ -1298,18 +1220,17 @@ static VOID VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle, } /* encomsp is always built-in */ -#define VirtualChannelEntry encomsp_VirtualChannelEntry +#define VirtualChannelEntryEx encomsp_VirtualChannelEntryEx -BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX pEntryPoints, PVOID pInitHandle) { UINT rc; encomspPlugin* encomsp; - EncomspClientContext* context; - CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; + EncomspClientContext* context = NULL; + CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx; BOOL isFreerdp = FALSE; - UINT error; - encomsp = (encomspPlugin*) calloc(1, sizeof(encomspPlugin)); + if (!encomsp) { WLog_ERR(TAG, "calloc failed!"); @@ -1317,19 +1238,18 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } encomsp->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP | - CHANNEL_OPTION_SHOW_PROTOCOL; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; strcpy(encomsp->channelDef.name, "encomsp"); + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints; - pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; - - if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && - (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) && + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { context = (EncomspClientContext*) calloc(1, sizeof(EncomspClientContext)); + if (!context) { WLog_ERR(TAG, "calloc failed!"); @@ -1337,7 +1257,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } context->handle = (void*) encomsp; - context->FilterUpdated = NULL; context->ApplicationCreated = NULL; context->ApplicationRemoved = NULL; @@ -1346,40 +1265,36 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->ShowWindow = NULL; context->ParticipantCreated = NULL; context->ParticipantRemoved = NULL; - context->ChangeParticipantControlLevel = encomsp_send_change_participant_control_level_pdu; + context->ChangeParticipantControlLevel = + encomsp_send_change_participant_control_level_pdu; context->GraphicsStreamPaused = NULL; context->GraphicsStreamResumed = NULL; - - *(pEntryPointsEx->ppInterface) = (void*) context; encomsp->context = context; encomsp->rdpcontext = pEntryPointsEx->context; isFreerdp = TRUE; } - CopyMemory(&(encomsp->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); + CopyMemory(&(encomsp->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); + encomsp->InitHandle = pInitHandle; + rc = encomsp->channelEntryPoints.pVirtualChannelInitEx(encomsp, context, pInitHandle, + &encomsp->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + encomsp_virtual_channel_init_event_ex); - rc = encomsp->channelEntryPoints.pVirtualChannelInit(&encomsp->InitHandle, - &encomsp->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, encomsp_virtual_channel_init_event); if (CHANNEL_RC_OK != rc) { - WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); - goto error_out; - } - - encomsp->channelEntryPoints.pInterface = *(encomsp->channelEntryPoints.ppInterface); - encomsp->channelEntryPoints.ppInterface = &(encomsp->channelEntryPoints.pInterface); - - if ((error = encomsp_add_init_handle_data(encomsp->InitHandle, (void*) encomsp))) - { - WLog_ERR(TAG, "encomsp_add_init_handle_data failed with error %lu!", error); + WLog_ERR(TAG, "failed with %s [%08X]", + WTSErrorToString(rc), rc); goto error_out; } + encomsp->channelEntryPoints.pInterface = context; return TRUE; error_out: + if (isFreerdp) free(encomsp->context); + free(encomsp); return FALSE; } diff --git a/channels/encomsp/client/encomsp_main.h b/channels/encomsp/client/encomsp_main.h index e226d96..7b23ed1 100644 --- a/channels/encomsp/client/encomsp_main.h +++ b/channels/encomsp/client/encomsp_main.h @@ -40,7 +40,7 @@ struct encomsp_plugin { CHANNEL_DEF channelDef; - CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; + CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints; EncomspClientContext* context; diff --git a/channels/encomsp/server/encomsp_main.c b/channels/encomsp/server/encomsp_main.c index ce2ca6c..b9948b8 100644 --- a/channels/encomsp/server/encomsp_main.c +++ b/channels/encomsp/server/encomsp_main.c @@ -45,7 +45,6 @@ static UINT encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ - return CHANNEL_RC_OK; } @@ -55,7 +54,6 @@ static int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header) { Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */ Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */ - return 1; } @@ -75,7 +73,6 @@ static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) return -1; Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ - return 1; } @@ -86,14 +83,13 @@ static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerContext* context, wStream* s, ENCOMSP_ORDER_HEADER* header) +static UINT encomsp_recv_change_participant_control_level_pdu( + EncomspServerContext* context, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu; UINT error = CHANNEL_RC_OK; - beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; - CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); if (Stream_GetRemainingLength(s) < 6) @@ -104,7 +100,6 @@ static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerConte Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ - end = (int) Stream_GetPosition(s); if ((beg + header->Length) < end) @@ -125,8 +120,10 @@ static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerConte } IFCALLRET(context->ChangeParticipantControlLevel, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %lu", error); + WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %u", + error); return error; } @@ -136,7 +133,8 @@ static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerConte * * @return 0 on success, otherwise a Win32 error code */ -static UINT encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s) +static UINT encomsp_server_receive_pdu(EncomspServerContext* context, + wStream* s) { UINT error = CHANNEL_RC_OK; ENCOMSP_ORDER_HEADER header; @@ -145,18 +143,22 @@ static UINT encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s { if ((error = encomsp_read_header(s, &header))) { - WLog_ERR(TAG, "encomsp_read_header failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_read_header failed with error %u!", error); return error; } - WLog_INFO(TAG, "EncomspReceive: Type: %d Length: %d", header.Type, header.Length); + WLog_INFO(TAG, "EncomspReceive: Type: %d Length: %d", header.Type, + header.Length); switch (header.Type) { case ODTYPE_PARTICIPANT_CTRL_CHANGED: - if ((error = encomsp_recv_change_participant_control_level_pdu(context, s, &header))) + if ((error = encomsp_recv_change_participant_control_level_pdu(context, s, + &header))) { - WLog_ERR(TAG, "encomsp_recv_change_participant_control_level_pdu failed with error %lu!", error); + WLog_ERR(TAG, + "encomsp_recv_change_participant_control_level_pdu failed with error %u!", + error); return error; } @@ -183,15 +185,14 @@ static void* encomsp_server_thread(void* arg) ENCOMSP_ORDER_HEADER* header; EncomspServerContext* context; UINT error = CHANNEL_RC_OK; - DWORD status; - + DWORD status; context = (EncomspServerContext*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; - s = Stream_New(NULL, 4096); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -199,7 +200,8 @@ static void* encomsp_server_thread(void* arg) goto out; } - if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, + &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); @@ -213,23 +215,23 @@ static void* encomsp_server_thread(void* arg) while (1) { - status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error); + break; + } - status = WaitForSingleObject(context->priv->StopEvent, 0); + status = WaitForSingleObject(context->priv->StopEvent, 0); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + break; + } if (status == WAIT_OBJECT_0) { @@ -237,16 +239,19 @@ static void* encomsp_server_thread(void* arg) } WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned); + if (BytesReturned < 1) continue; + if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); error = CHANNEL_RC_NO_MEMORY; break; } + if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; @@ -261,11 +266,13 @@ static void* encomsp_server_thread(void* arg) { Stream_SealLength(s); Stream_SetPosition(s, 0); + if ((error = encomsp_server_receive_pdu(context, s))) { - WLog_ERR(TAG, "encomsp_server_receive_pdu failed with error %lu!", error); + WLog_ERR(TAG, "encomsp_server_receive_pdu failed with error %u!", error); break; } + Stream_SetPosition(s, 0); } } @@ -273,8 +280,10 @@ static void* encomsp_server_thread(void* arg) Stream_Free(s, TRUE); out: + if (error && context->rdpcontext) - setChannelError(context->rdpcontext, error, "encomsp_server_thread reported an error"); + setChannelError(context->rdpcontext, error, + "encomsp_server_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -287,7 +296,8 @@ out: */ static UINT encomsp_server_start(EncomspServerContext* context) { - context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "encomsp"); + context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, + WTS_CURRENT_SESSION, "encomsp"); if (!context->priv->ChannelHandle) return CHANNEL_RC_BAD_CHANNEL; @@ -299,7 +309,7 @@ static UINT encomsp_server_start(EncomspServerContext* context) } if (!(context->priv->Thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) encomsp_server_thread, (void*) context, 0, NULL))) + (LPTHREAD_START_ROUTINE) encomsp_server_thread, (void*) context, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); CloseHandle(context->priv->StopEvent); @@ -317,33 +327,30 @@ static UINT encomsp_server_start(EncomspServerContext* context) */ static UINT encomsp_server_stop(EncomspServerContext* context) { - UINT error = CHANNEL_RC_OK; + UINT error = CHANNEL_RC_OK; SetEvent(context->priv->StopEvent); if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } - CloseHandle(context->priv->Thread); + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + return error; + } + CloseHandle(context->priv->Thread); return error; } EncomspServerContext* encomsp_server_context_new(HANDLE vcm) { EncomspServerContext* context; - context = (EncomspServerContext*) calloc(1, sizeof(EncomspServerContext)); if (context) { context->vcm = vcm; - context->Start = encomsp_server_start; context->Stop = encomsp_server_stop; - context->priv = (EncomspServerPrivate*) calloc(1, sizeof(EncomspServerPrivate)); if (!context->priv) diff --git a/channels/parallel/client/CMakeLists.txt b/channels/parallel/client/CMakeLists.txt index 21f4a03..255435b 100644 --- a/channels/parallel/client/CMakeLists.txt +++ b/channels/parallel/client/CMakeLists.txt @@ -27,7 +27,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE target_link_libraries(${MODULE_NAME} freerdp winpr) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index 58bc9c2..0614ffc 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -84,14 +84,12 @@ static UINT parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) char* path = NULL; int status; UINT32 PathLength; - Stream_Seek(irp->input, 28); /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ /* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */ Stream_Read_UINT32(irp->input, PathLength); - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input), - PathLength / 2, &path, 0, NULL, NULL); + PathLength / 2, &path, 0, NULL, NULL); if (status < 1) if (!(path = (char*) calloc(1, 1))) @@ -113,15 +111,12 @@ static UINT parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) /* all read and write operations should be non-blocking */ if (fcntl(parallel->file, F_SETFL, O_NONBLOCK) == -1) { - } } Stream_Write_UINT32(irp->output, parallel->id); Stream_Write_UINT8(irp->output, 0); - free(path); - return irp->Complete(irp); } @@ -134,15 +129,12 @@ static UINT parallel_process_irp_close(PARALLEL_DEVICE* parallel, IRP* irp) { if (close(parallel->file) < 0) { - } else { - } Stream_Zero(irp->output, 5); /* Padding(5) */ - return irp->Complete(irp); } @@ -157,11 +149,10 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp) UINT64 Offset; ssize_t status; BYTE* buffer = NULL; - Stream_Read_UINT32(irp->input, Length); Stream_Read_UINT64(irp->input, Offset); - buffer = (BYTE*) malloc(Length); + if (!buffer) { WLog_ERR(TAG, "malloc failed!"); @@ -179,7 +170,6 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp) } else { - } Stream_Write_UINT32(irp->output, Length); @@ -192,11 +182,11 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp) free(buffer); return CHANNEL_RC_NO_MEMORY; } + Stream_Write(irp->output, buffer, Length); } free(buffer); - return irp->Complete(irp); } @@ -211,11 +201,9 @@ static UINT parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) UINT32 Length; UINT64 Offset; ssize_t status; - Stream_Read_UINT32(irp->input, Length); Stream_Read_UINT64(irp->input, Offset); Stream_Seek(irp->input, 20); /* Padding */ - len = Length; while (len > 0) @@ -235,7 +223,6 @@ static UINT parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) Stream_Write_UINT32(irp->output, Length); Stream_Write_UINT8(irp->output, 0); /* Padding */ - return irp->Complete(irp); } @@ -244,7 +231,8 @@ static UINT parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) * * @return 0 on success, otherwise a Win32 error code */ -static UINT parallel_process_irp_device_control(PARALLEL_DEVICE* parallel, IRP* irp) +static UINT parallel_process_irp_device_control(PARALLEL_DEVICE* parallel, + IRP* irp) { Stream_Write_UINT32(irp->output, 0); /* OutputBufferLength */ return irp->Complete(irp); @@ -267,6 +255,7 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp) WLog_ERR(TAG, "parallel_process_irp_create failed with error %d!", error); return error; } + break; case IRP_MJ_CLOSE: @@ -275,6 +264,7 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp) WLog_ERR(TAG, "parallel_process_irp_close failed with error %d!", error); return error; } + break; case IRP_MJ_READ: @@ -283,6 +273,7 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp) WLog_ERR(TAG, "parallel_process_irp_read failed with error %d!", error); return error; } + break; case IRP_MJ_WRITE: @@ -291,14 +282,17 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp) WLog_ERR(TAG, "parallel_process_irp_write failed with error %d!", error); return error; } + break; case IRP_MJ_DEVICE_CONTROL: if ((error = parallel_process_irp_device_control(parallel, irp))) { - WLog_ERR(TAG, "parallel_process_irp_device_control failed with error %d!", error); + WLog_ERR(TAG, "parallel_process_irp_device_control failed with error %d!", + error); return error; } + break; default: @@ -306,6 +300,7 @@ static UINT parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp) return irp->Complete(irp); break; } + return CHANNEL_RC_OK; } @@ -343,8 +338,10 @@ static void* parallel_thread_func(void* arg) break; } } + if (error && parallel->rdpcontext) - setChannelError(parallel->rdpcontext, error, "parallel_thread_func reported an error"); + setChannelError(parallel->rdpcontext, error, + "parallel_thread_func reported an error"); ExitThread((DWORD)error); return NULL; @@ -364,6 +361,7 @@ static UINT parallel_irp_request(DEVICE* device, IRP* irp) WLog_ERR(TAG, "MessageQueue_Post failed!"); return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -374,25 +372,25 @@ static UINT parallel_irp_request(DEVICE* device, IRP* irp) */ static UINT parallel_free(DEVICE* device) { - UINT error; + UINT error; PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) device; - if (MessageQueue_PostQuit(parallel->queue, 0) && (WaitForSingleObject(parallel->thread, INFINITE) == WAIT_FAILED)) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } - CloseHandle(parallel->thread); + if (MessageQueue_PostQuit(parallel->queue, 0) + && (WaitForSingleObject(parallel->thread, INFINITE) == WAIT_FAILED)) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + return error; + } + CloseHandle(parallel->thread); Stream_Free(parallel->device.data, TRUE); MessageQueue_Free(parallel->queue); - free(parallel); - return CHANNEL_RC_OK; + return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DeviceServiceEntry parallel_DeviceServiceEntry #else #define DeviceServiceEntry FREERDP_API DeviceServiceEntry @@ -412,7 +410,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) RDPDR_PARALLEL* device; PARALLEL_DEVICE* parallel; UINT error; - device = (RDPDR_PARALLEL*) pEntryPoints->device; name = device->Name; path = device->Path; @@ -426,6 +423,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) if (name[0] && path[0]) { parallel = (PARALLEL_DEVICE*) calloc(1, sizeof(PARALLEL_DEVICE)); + if (!parallel) { WLog_ERR(TAG, "calloc failed!"); @@ -437,9 +435,9 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) parallel->device.IRPRequest = parallel_irp_request; parallel->device.Free = parallel_free; parallel->rdpcontext = pEntryPoints->rdpcontext; - length = strlen(name); parallel->device.data = Stream_New(NULL, length + 1); + if (!parallel->device.data) { WLog_ERR(TAG, "Stream_New failed!"); @@ -451,8 +449,8 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) Stream_Write_UINT8(parallel->device.data, name[i] < 0 ? '_' : name[i]); parallel->path = path; - parallel->queue = MessageQueue_New(NULL); + if (!parallel->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -460,14 +458,15 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) goto error_out; } - if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) parallel))) + if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, + (DEVICE*) parallel))) { - WLog_ERR(TAG, "RegisterDevice failed with error %lu!", error); + WLog_ERR(TAG, "RegisterDevice failed with error %u!", error); goto error_out; } - - if (!(parallel->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) parallel_thread_func, (void*) parallel, 0, NULL))) + if (!(parallel->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) parallel_thread_func, (void*) parallel, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); error = ERROR_INTERNAL_ERROR; diff --git a/channels/printer/client/CMakeLists.txt b/channels/printer/client/CMakeLists.txt index b433d8a..ea2f0df 100644 --- a/channels/printer/client/CMakeLists.txt +++ b/channels/printer/client/CMakeLists.txt @@ -30,7 +30,7 @@ if(WITH_CUPS) add_definitions(-DWITH_CUPS) endif() -if(WIN32) +if(WIN32 AND NOT UWP) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} printer_win.c printer_win.h) @@ -49,7 +49,7 @@ endif() target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index 18d4db8..6d1b3e1 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -6,6 +6,7 @@ * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger * Copyright 2016 Armin Novak + * Copyright 2016 David PHAM-VAN * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,7 +46,7 @@ #include "printer_main.h" -#ifdef WIN32 +#if defined(_WIN32) && !defined(_UWP) #include "printer_win.h" #endif @@ -60,7 +61,7 @@ struct _PRINTER_DEVICE rdpPrinter* printer; - PSLIST_HEADER pIrpList; + WINPR_PSLIST_HEADER pIrpList; HANDLE event; HANDLE stopEvent; @@ -79,7 +80,8 @@ static UINT printer_process_irp_create(PRINTER_DEVICE* printer_dev, IRP* irp) rdpPrintJob* printjob = NULL; if (printer_dev->printer) - printjob = printer_dev->printer->CreatePrintJob(printer_dev->printer, irp->devman->id_sequence++); + printjob = printer_dev->printer->CreatePrintJob(printer_dev->printer, + irp->devman->id_sequence++); if (printjob) { @@ -104,7 +106,8 @@ static UINT printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp) rdpPrintJob* printjob = NULL; if (printer_dev->printer) - printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId); + printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, + irp->FileId); if (!printjob) { @@ -116,7 +119,6 @@ static UINT printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp) } Stream_Zero(irp->output, 4); /* Padding(4) */ - return irp->Complete(irp); } @@ -131,13 +133,13 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) UINT64 Offset; rdpPrintJob* printjob = NULL; UINT error = CHANNEL_RC_OK; - Stream_Read_UINT32(irp->input, Length); Stream_Read_UINT64(irp->input, Offset); Stream_Seek(irp->input, 20); /* Padding */ if (printer_dev->printer) - printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId); + printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, + irp->FileId); if (!printjob) { @@ -151,13 +153,12 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) if (error) { - WLog_ERR(TAG, "printjob->Write failed with error %lu!", error); + WLog_ERR(TAG, "printjob->Write failed with error %u!", error); return error; } Stream_Write_UINT32(irp->output, Length); Stream_Write_UINT8(irp->output, 0); /* Padding */ - return irp->Complete(irp); } @@ -166,7 +167,8 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) * * @return 0 on success, otherwise a Win32 error code */ -static UINT printer_process_irp_device_control(PRINTER_DEVICE* printer_dev, IRP* irp) +static UINT printer_process_irp_device_control(PRINTER_DEVICE* printer_dev, + IRP* irp) { Stream_Write_UINT32(irp->output, 0); /* OutputBufferLength */ return irp->Complete(irp); @@ -180,38 +182,44 @@ static UINT printer_process_irp_device_control(PRINTER_DEVICE* printer_dev, IRP* static UINT printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) { UINT error; + switch (irp->MajorFunction) { case IRP_MJ_CREATE: if ((error = printer_process_irp_create(printer_dev, irp))) { - WLog_ERR(TAG, "printer_process_irp_create failed with error %lu!", error); + WLog_ERR(TAG, "printer_process_irp_create failed with error %u!", error); return error; } + break; case IRP_MJ_CLOSE: if ((error = printer_process_irp_close(printer_dev, irp))) { - WLog_ERR(TAG, "printer_process_irp_close failed with error %lu!", error); + WLog_ERR(TAG, "printer_process_irp_close failed with error %u!", error); return error; } + break; case IRP_MJ_WRITE: if ((error = printer_process_irp_write(printer_dev, irp))) { - WLog_ERR(TAG, "printer_process_irp_write failed with error %lu!", error); + WLog_ERR(TAG, "printer_process_irp_write failed with error %u!", error); return error; } + break; case IRP_MJ_DEVICE_CONTROL: if ((error = printer_process_irp_device_control(printer_dev, irp))) { - WLog_ERR(TAG, "printer_process_irp_device_control failed with error %lu!", error); + WLog_ERR(TAG, "printer_process_irp_device_control failed with error %u!", + error); return error; } + break; default: @@ -219,6 +227,7 @@ static UINT printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) return irp->Complete(irp); break; } + return CHANNEL_RC_OK; } @@ -232,20 +241,20 @@ static void* printer_thread_func(void* arg) while (1) { DWORD rc = WaitForMultipleObjects(2, obj, FALSE, INFINITE); - if (rc == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); - break; - } + + if (rc == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error); + break; + } if (rc == WAIT_OBJECT_0 + 1) break; - else if( rc != WAIT_OBJECT_0 ) + else if (rc != WAIT_OBJECT_0) continue; ResetEvent(printer_dev->event); - irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList); if (irp == NULL) @@ -261,11 +270,12 @@ static void* printer_thread_func(void* arg) break; } } + if (error && printer_dev->rdpcontext) - setChannelError(printer_dev->rdpcontext, error, "printer_thread_func reported an error"); + setChannelError(printer_dev->rdpcontext, error, + "printer_thread_func reported an error"); ExitThread((DWORD) error); - return NULL; } @@ -277,9 +287,7 @@ static void* printer_thread_func(void* arg) static UINT printer_irp_request(DEVICE* device, IRP* irp) { PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device; - InterlockedPushEntrySList(printer_dev->pIrpList, &(irp->ItemEntry)); - SetEvent(printer_dev->event); return CHANNEL_RC_OK; } @@ -293,15 +301,15 @@ static UINT printer_free(DEVICE* device) { IRP* irp; PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device; - UINT error; - + UINT error; SetEvent(printer_dev->stopEvent); + if (WaitForSingleObject(printer_dev->thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + return error; + } while ((irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList)) != NULL) irp->Discard(irp); @@ -309,16 +317,15 @@ static UINT printer_free(DEVICE* device) CloseHandle(printer_dev->thread); CloseHandle(printer_dev->stopEvent); CloseHandle(printer_dev->event); - _aligned_free(printer_dev->pIrpList); if (printer_dev->printer) printer_dev->printer->Free(printer_dev->printer); free(printer_dev->device.name); - + Stream_Free(printer_dev->device.data, TRUE); free(printer_dev); - return CHANNEL_RC_OK; + return CHANNEL_RC_OK; } /** @@ -326,7 +333,8 @@ static UINT printer_free(DEVICE* device) * * @return 0 on success, otherwise a Win32 error code */ -UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* printer) +UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, + rdpPrinter* printer) { char* port; UINT32 Flags; @@ -338,16 +346,17 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri BYTE* CachedPrinterConfigData; PRINTER_DEVICE* printer_dev; UINT error; - port = malloc(10); + if (!port) { WLog_ERR(TAG, "malloc failed!"); return CHANNEL_RC_NO_MEMORY; } - sprintf_s(port, 10, "PRN%d", printer->id); + sprintf_s(port, 10, "PRN%d", printer->id); printer_dev = (PRINTER_DEVICE*) calloc(1, sizeof(PRINTER_DEVICE)); + if (!printer_dev) { WLog_ERR(TAG, "calloc failed!"); @@ -360,21 +369,21 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri printer_dev->device.IRPRequest = printer_irp_request; printer_dev->device.Free = printer_free; printer_dev->rdpcontext = pEntryPoints->rdpcontext; - printer_dev->printer = printer; - CachedFieldsLen = 0; CachedPrinterConfigData = NULL; - Flags = 0; if (printer->is_default) Flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER; - DriverNameLen = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &DriverName, 0) * 2; - PrintNameLen = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &PrintName, 0) * 2; + DriverNameLen = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &DriverName, + 0) * 2; + PrintNameLen = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &PrintName, + 0) * 2; + printer_dev->device.data = Stream_New(NULL, + 28 + DriverNameLen + PrintNameLen + CachedFieldsLen); - printer_dev->device.data = Stream_New(NULL, 28 + DriverNameLen + PrintNameLen + CachedFieldsLen); if (!printer_dev->device.data) { WLog_ERR(TAG, "calloc failed!"); @@ -397,19 +406,22 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri if (CachedFieldsLen > 0) { - Stream_Write(printer_dev->device.data, CachedPrinterConfigData, CachedFieldsLen); + Stream_Write(printer_dev->device.data, CachedPrinterConfigData, + CachedFieldsLen); } free(DriverName); free(PrintName); + printer_dev->pIrpList = (WINPR_PSLIST_HEADER) _aligned_malloc(sizeof( + WINPR_SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); - printer_dev->pIrpList = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); if (!printer_dev->pIrpList) { WLog_ERR(TAG, "_aligned_malloc failed!"); error = CHANNEL_RC_NO_MEMORY; goto error_out; } + InitializeSListHead(printer_dev->pIrpList); if (!(printer_dev->event = CreateEvent(NULL, TRUE, FALSE, NULL))) @@ -418,6 +430,7 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri error = ERROR_INTERNAL_ERROR; goto error_out; } + if (!(printer_dev->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { WLog_ERR(TAG, "CreateEvent failed!"); @@ -425,14 +438,15 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri goto error_out; } - if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) printer_dev))) + if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, + (DEVICE*) printer_dev))) { WLog_ERR(TAG, "RegisterDevice failed with error %d!", error); goto error_out; } if (!(printer_dev->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) printer_thread_func, (void*) printer_dev, 0, NULL))) + (LPTHREAD_START_ROUTINE) printer_thread_func, (void*) printer_dev, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); error = ERROR_INTERNAL_ERROR; @@ -450,7 +464,7 @@ error_out: return error; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DeviceServiceEntry printer_DeviceServiceEntry #else #define DeviceServiceEntry FREERDP_API DeviceServiceEntry @@ -471,12 +485,10 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) RDPDR_PRINTER* device; rdpPrinterDriver* driver = NULL; UINT error; - #ifdef WITH_CUPS driver = printer_cups_get_driver(); #endif - -#ifdef WIN32 +#if defined(_WIN32) && !defined(_UWP) driver = printer_win_get_driver(); #endif @@ -502,7 +514,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) if ((error = printer_register(pEntryPoints, printer))) { - WLog_ERR(TAG, "printer_register failed with error %lu!", error); + WLog_ERR(TAG, "printer_register failed with error %u!", error); return error; } } @@ -513,12 +525,12 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) for (i = 0; printers[i]; i++) { printer = printers[i]; + if ((error = printer_register(pEntryPoints, printer))) { - WLog_ERR(TAG, "printer_register failed with error %lu!", error); + WLog_ERR(TAG, "printer_register failed with error %u!", error); free(printers); return error; - } } diff --git a/channels/printer/client/printer_win.h b/channels/printer/client/printer_win.h index fbd1dbc..c0a0420 100644 --- a/channels/printer/client/printer_win.h +++ b/channels/printer/client/printer_win.h @@ -26,9 +26,9 @@ rdpPrinterDriver* printer_win_get_driver(void); #define PRINTER_TAG CHANNELS_TAG("printer.client") #ifdef WITH_DEBUG_WINPR -#define DEBUG_WINPR(fmt, ...) WLog_DBG(PRINTER_TAG, fmt, ## __VA_ARGS__) +#define DEBUG_WINPR(...) WLog_DBG(PRINTER_TAG, __VA_ARGS__) #else -#define DEBUG_WINPR(fmt, ...) do { } while (0) +#define DEBUG_WINPR(...) do { } while (0) #endif #endif diff --git a/channels/rail/client/CMakeLists.txt b/channels/rail/client/CMakeLists.txt index a4653e0..c87fd2f 100644 --- a/channels/rail/client/CMakeLists.txt +++ b/channels/rail/client/CMakeLists.txt @@ -25,7 +25,7 @@ set(${MODULE_PREFIX}_SRCS rail_orders.c rail_orders.h) -add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") +add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx") diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c index 618227b..2025e35 100644 --- a/channels/rail/client/rail_main.c +++ b/channels/rail/client/rail_main.c @@ -45,7 +45,7 @@ RailClientContext* rail_get_client_interface(railPlugin* rail) * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send(railPlugin* rail, wStream* s) +static UINT rail_send(railPlugin* rail, wStream* s) { UINT status; @@ -55,15 +55,15 @@ UINT rail_send(railPlugin* rail, wStream* s) } else { - status = rail->channelEntryPoints.pVirtualChannelWrite(rail->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + status = rail->channelEntryPoints.pVirtualChannelWriteEx(rail->InitHandle, rail->OpenHandle, + Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); } return status; @@ -77,15 +77,15 @@ UINT rail_send(railPlugin* rail, wStream* s) UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length) { wStream* s = NULL; - s = Stream_New(NULL, length); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } - Stream_Write(s, data, length); + Stream_Write(s, data, length); return rail_send(rail, s); } @@ -98,11 +98,11 @@ UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length) * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec) +static UINT rail_client_execute(RailClientContext* context, + RAIL_EXEC_ORDER* exec) { char* exeOrFile; railPlugin* rail = (railPlugin*) context->handle; - exeOrFile = exec->RemoteApplicationProgram; if (!exeOrFile) @@ -114,10 +114,12 @@ UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec) exec->flags |= RAIL_EXEC_FLAG_FILE; } - rail_string_to_unicode_string(exec->RemoteApplicationProgram, &exec->exeOrFile); /* RemoteApplicationProgram */ - rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir, &exec->workingDir); /* ShellWorkingDirectory */ - rail_string_to_unicode_string(exec->RemoteApplicationArguments, &exec->arguments); /* RemoteApplicationCmdLine */ - + rail_string_to_unicode_string(exec->RemoteApplicationProgram, + &exec->exeOrFile); /* RemoteApplicationProgram */ + rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir, + &exec->workingDir); /* ShellWorkingDirectory */ + rail_string_to_unicode_string(exec->RemoteApplicationArguments, + &exec->arguments); /* RemoteApplicationCmdLine */ return rail_send_client_exec_order(rail, exec); } @@ -126,10 +128,10 @@ UINT rail_client_execute(RailClientContext* context, RAIL_EXEC_ORDER* exec) * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_activate(RailClientContext* context, RAIL_ACTIVATE_ORDER* activate) +static UINT rail_client_activate(RailClientContext* context, + RAIL_ACTIVATE_ORDER* activate) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_activate_order(rail, activate); } @@ -138,13 +140,13 @@ UINT rail_client_activate(RailClientContext* context, RAIL_ACTIVATE_ORDER* activ * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam) +static UINT rail_send_client_sysparam(RailClientContext* context, + RAIL_SYSPARAM_ORDER* sysparam) { wStream* s; int length; railPlugin* rail = (railPlugin*) context->handle; UINT error; - length = RAIL_SYSPARAM_ORDER_LENGTH; switch (sysparam->param) @@ -168,6 +170,7 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* } s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8); + if (!s) { WLog_ERR(TAG, "rail_pdu_init failed!"); @@ -176,14 +179,14 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* if ((error = rail_write_client_sysparam_order(s, sysparam))) { - WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %u!", error); Stream_Free(s, TRUE); return error; } if ((error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSPARAM))) { - WLog_ERR(TAG, "rail_send_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_pdu failed with error %u!", error); } Stream_Free(s, TRUE); @@ -195,16 +198,18 @@ UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_ORDER* * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam) +static UINT rail_client_system_param(RailClientContext* context, + RAIL_SYSPARAM_ORDER* sysparam) { UINT error = CHANNEL_RC_OK; if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST) { sysparam->param = SPI_SET_HIGH_CONTRAST; + if ((error = rail_send_client_sysparam(context, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error); return error; } } @@ -212,9 +217,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_TASKBAR_POS) { sysparam->param = SPI_TASKBAR_POS; + if ((error = rail_send_client_sysparam(context, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error); return error; } } @@ -222,9 +228,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP) { sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP; + if ((error = rail_send_client_sysparam(context, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error); return error; } } @@ -232,9 +239,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF) { sysparam->param = SPI_SET_KEYBOARD_PREF; + if ((error = rail_send_client_sysparam(context, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error); return error; } } @@ -242,9 +250,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS) { sysparam->param = SPI_SET_DRAG_FULL_WINDOWS; + if ((error = rail_send_client_sysparam(context, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error); return error; } } @@ -252,9 +261,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES) { sysparam->param = SPI_SET_KEYBOARD_CUES; + if ((error = rail_send_client_sysparam(context, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error); return error; } } @@ -262,9 +272,10 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s if (sysparam->params & SPI_MASK_SET_WORK_AREA) { sysparam->param = SPI_SET_WORK_AREA; + if ((error = rail_send_client_sysparam(context, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam failed with error %u!", error); return error; } } @@ -277,7 +288,8 @@ UINT rail_client_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam) +static UINT rail_server_system_param(RailClientContext* context, + RAIL_SYSPARAM_ORDER* sysparam) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -287,10 +299,10 @@ UINT rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* s * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_system_command(RailClientContext* context, RAIL_SYSCOMMAND_ORDER* syscommand) +static UINT rail_client_system_command(RailClientContext* context, + RAIL_SYSCOMMAND_ORDER* syscommand) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_syscommand_order(rail, syscommand); } @@ -299,10 +311,10 @@ UINT rail_client_system_command(RailClientContext* context, RAIL_SYSCOMMAND_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake) +static UINT rail_client_handshake(RailClientContext* context, + RAIL_HANDSHAKE_ORDER* handshake) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_handshake_order(rail, handshake); } @@ -311,7 +323,8 @@ UINT rail_client_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* han * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake) +static UINT rail_server_handshake(RailClientContext* context, + RAIL_HANDSHAKE_ORDER* handshake) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -321,10 +334,10 @@ UINT rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* han * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx) +static UINT rail_client_handshake_ex(RailClientContext* context, + RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_handshake_ex_order(rail, handshakeEx); } @@ -333,7 +346,8 @@ UINT rail_client_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx) +static UINT rail_server_handshake_ex(RailClientContext* context, + RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -343,10 +357,10 @@ UINT rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_notify_event(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDER* notifyEvent) +static UINT rail_client_notify_event(RailClientContext* context, + RAIL_NOTIFY_EVENT_ORDER* notifyEvent) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_notify_event_order(rail, notifyEvent); } @@ -355,10 +369,10 @@ UINT rail_client_notify_event(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_window_move(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER* windowMove) +static UINT rail_client_window_move(RailClientContext* context, + RAIL_WINDOW_MOVE_ORDER* windowMove) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_window_move_order(rail, windowMove); } @@ -367,7 +381,8 @@ UINT rail_client_window_move(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER* * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize) +static UINT rail_server_local_move_size(RailClientContext* context, + RAIL_LOCALMOVESIZE_ORDER* localMoveSize) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -377,7 +392,8 @@ UINT rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* minMaxInfo) +static UINT rail_server_min_max_info(RailClientContext* context, + RAIL_MINMAXINFO_ORDER* minMaxInfo) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -387,10 +403,10 @@ UINT rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_information(RailClientContext* context, RAIL_CLIENT_STATUS_ORDER* clientStatus) +static UINT rail_client_information(RailClientContext* context, + RAIL_CLIENT_STATUS_ORDER* clientStatus) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_status_order(rail, clientStatus); } @@ -399,10 +415,10 @@ UINT rail_client_information(RailClientContext* context, RAIL_CLIENT_STATUS_ORDE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_system_menu(RailClientContext* context, RAIL_SYSMENU_ORDER* sysmenu) +static UINT rail_client_system_menu(RailClientContext* context, + RAIL_SYSMENU_ORDER* sysmenu) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_sysmenu_order(rail, sysmenu); } @@ -411,10 +427,10 @@ UINT rail_client_system_menu(RailClientContext* context, RAIL_SYSMENU_ORDER* sys * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo) +static UINT rail_client_language_bar_info(RailClientContext* context, + RAIL_LANGBAR_INFO_ORDER* langBarInfo) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_langbar_info_order(rail, langBarInfo); } @@ -423,7 +439,8 @@ UINT rail_client_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo) +static UINT rail_server_language_bar_info(RailClientContext* context, + RAIL_LANGBAR_INFO_ORDER* langBarInfo) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -433,7 +450,8 @@ UINT rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORDER* execResult) +static UINT rail_server_execute_result(RailClientContext* context, + RAIL_EXEC_RESULT_ORDER* execResult) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } @@ -443,10 +461,10 @@ UINT rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORD * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_client_get_appid_request(RailClientContext* context, RAIL_GET_APPID_REQ_ORDER* getAppIdReq) +static UINT rail_client_get_appid_request(RailClientContext* context, + RAIL_GET_APPID_REQ_ORDER* getAppIdReq) { railPlugin* rail = (railPlugin*) context->handle; - return rail_send_client_get_appid_req_order(rail, getAppIdReq); } @@ -455,111 +473,19 @@ UINT rail_client_get_appid_request(RailClientContext* context, RAIL_GET_APPID_RE * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_server_get_appid_response(RailClientContext* context, RAIL_GET_APPID_RESP_ORDER* getAppIdResp) +static UINT rail_server_get_appid_response(RailClientContext* context, + RAIL_GET_APPID_RESP_ORDER* getAppIdResp) { return CHANNEL_RC_OK; /* stub - should be registered by client */ } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT rail_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - } - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* rail_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void rail_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT rail_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - } - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* rail_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void rail_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rail_virtual_channel_event_data_received(railPlugin* rail, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -574,6 +500,7 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail, Stream_Free(rail->data_in, TRUE); rail->data_in = Stream_New(NULL, totalLength); + if (!rail->data_in) { WLog_ERR(TAG, "Stream_New failed!"); @@ -582,11 +509,13 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail, } data_in = rail->data_in; + if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) @@ -607,28 +536,31 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE rail_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - railPlugin* rail; UINT error = CHANNEL_RC_OK; + railPlugin* rail = (railPlugin*) lpUserParam; - rail = (railPlugin*) rail_get_open_handle_data(openHandle); - - if (!rail) + if (!rail || (rail->OpenHandle != openHandle)) { - WLog_ERR(TAG, "rail_virtual_channel_open_event: error no match"); + WLog_ERR(TAG, "error no match"); return; } switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = rail_virtual_channel_event_data_received(rail, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "rail_virtual_channel_event_data_received failed with error %lu!", error); + if ((error = rail_virtual_channel_event_data_received(rail, pData, dataLength, + totalLength, dataFlags))) + WLog_ERR(TAG, "rail_virtual_channel_event_data_received failed with error %u!", + error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -640,7 +572,8 @@ static VOID VCAPITYPE rail_virtual_channel_open_event(DWORD openHandle, UINT eve } if (error && rail->rdpcontext) - setChannelError(rail->rdpcontext, error, "rail_virtual_channel_open_event reported an error"); + setChannelError(rail->rdpcontext, error, + "rail_virtual_channel_open_event reported an error"); return; } @@ -667,12 +600,14 @@ static void* rail_virtual_channel_client_thread(void* arg) error = ERROR_INTERNAL_ERROR; break; } + if (message.id == WMQ_QUIT) break; if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = rail_order_recv(rail, data))) { WLog_ERR(TAG, "rail_order_recv failed with error %d!", error); @@ -682,7 +617,8 @@ static void* rail_virtual_channel_client_thread(void* arg) } if (error && rail->rdpcontext) - setChannelError(rail->rdpcontext, error, "rail_virtual_channel_client_thread reported an error"); + setChannelError(rail->rdpcontext, error, + "rail_virtual_channel_client_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -693,27 +629,22 @@ static void* rail_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, UINT32 dataLength) +static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, + UINT32 dataLength) { UINT status; - - status = rail->channelEntryPoints.pVirtualChannelOpen(rail->InitHandle, - &rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event); + status = rail->channelEntryPoints.pVirtualChannelOpenEx(rail->InitHandle, + &rail->OpenHandle, rail->channelDef.name, rail_virtual_channel_open_event_ex); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); - return status; - } - - if ((status = rail_add_open_handle_data(rail->OpenHandle, rail))) - { - WLog_ERR(TAG, "rail_add_open_handle_data failed with error %lu!", status); + WTSErrorToString(status), status); return status; } rail->queue = MessageQueue_New(NULL); + if (!rail->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -721,13 +652,15 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, } if (!(rail->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rail_virtual_channel_client_thread, (void*) rail, 0, NULL))) + (LPTHREAD_START_ROUTINE) rail_virtual_channel_client_thread, (void*) rail, 0, + NULL))) { WLog_ERR(TAG, "CreateThread failed!"); MessageQueue_Free(rail->queue); rail->queue = NULL; return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -739,53 +672,54 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, static UINT rail_virtual_channel_event_disconnected(railPlugin* rail) { UINT rc; - if (MessageQueue_PostQuit(rail->queue, 0) && (WaitForSingleObject(rail->thread, INFINITE) == WAIT_FAILED)) - { - rc = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); - return rc; - } + + if (MessageQueue_PostQuit(rail->queue, 0) + && (WaitForSingleObject(rail->thread, INFINITE) == WAIT_FAILED)) + { + rc = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", rc); + return rc; + } MessageQueue_Free(rail->queue); CloseHandle(rail->thread); - rail->queue = NULL; rail->thread = NULL; + rc = rail->channelEntryPoints.pVirtualChannelCloseEx(rail->InitHandle, rail->OpenHandle); - rc = rail->channelEntryPoints.pVirtualChannelClose(rail->OpenHandle); if (CHANNEL_RC_OK != rc) { - WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(rc), rc); - return rc; + WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]", + WTSErrorToString(rc), rc); + return rc; } + rail->OpenHandle = 0; + if (rail->data_in) { Stream_Free(rail->data_in, TRUE); rail->data_in = NULL; } - rail_remove_open_handle_data(rail->OpenHandle); - return CHANNEL_RC_OK; + return CHANNEL_RC_OK; } static void rail_virtual_channel_event_terminated(railPlugin* rail) { - rail_remove_init_handle_data(rail->InitHandle); + rail->InitHandle = 0; free(rail); } -static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) +static VOID VCAPITYPE rail_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle, + UINT event, LPVOID pData, UINT dataLength) { - railPlugin* rail; UINT error = CHANNEL_RC_OK; + railPlugin* rail = (railPlugin*) lpUserParam; - rail = (railPlugin*) rail_get_init_handle_data(pInitHandle); - - if (!rail) + if (!rail || (rail->InitHandle != pInitHandle)) { - WLog_ERR(TAG, "rail_virtual_channel_init_event: error no match"); + WLog_ERR(TAG, "error no match"); return; } @@ -793,12 +727,16 @@ static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT e { case CHANNEL_EVENT_CONNECTED: if ((error = rail_virtual_channel_event_connected(rail, pData, dataLength))) - WLog_ERR(TAG, "rail_virtual_channel_event_connected failed with error %lu!", error); + WLog_ERR(TAG, "rail_virtual_channel_event_connected failed with error %u!", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = rail_virtual_channel_event_disconnected(rail))) - WLog_ERR(TAG, "rail_virtual_channel_event_disconnected failed with error %lu!", error); + WLog_ERR(TAG, "rail_virtual_channel_event_disconnected failed with error %u!", + error); + break; case CHANNEL_EVENT_TERMINATED: @@ -806,23 +744,22 @@ static VOID VCAPITYPE rail_virtual_channel_init_event(LPVOID pInitHandle, UINT e break; } - if(error && rail->rdpcontext) - setChannelError(rail->rdpcontext, error, "rail_virtual_channel_init_event reported an error"); + if (error && rail->rdpcontext) + setChannelError(rail->rdpcontext, error, "rail_virtual_channel_init_event_ex reported an error"); } /* rail is always built-in */ -#define VirtualChannelEntry rail_VirtualChannelEntry +#define VirtualChannelEntryEx rail_VirtualChannelEntryEx -BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle) { UINT rc; railPlugin* rail; - RailClientContext* context; - CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; + RailClientContext* context = NULL; + CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx; BOOL isFreerdp = FALSE; - UINT error; - rail = (railPlugin*) calloc(1, sizeof(railPlugin)); + if (!rail) { WLog_ERR(TAG, "calloc failed!"); @@ -830,19 +767,18 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } rail->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP | - CHANNEL_OPTION_SHOW_PROTOCOL; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; strcpy(rail->channelDef.name, "rail"); + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints; - pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; - - if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && - (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) && + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { context = (RailClientContext*) calloc(1, sizeof(RailClientContext)); + if (!context) { WLog_ERR(TAG, "calloc failed!"); @@ -852,7 +788,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->handle = (void*) rail; context->custom = NULL; - context->ClientExecute = rail_client_execute; context->ClientActivate = rail_client_activate; context->ClientSystemParam = rail_client_system_param; @@ -874,42 +809,34 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) context->ClientGetAppIdRequest = rail_client_get_appid_request; context->ServerGetAppIdResponse = rail_server_get_appid_response; rail->rdpcontext = pEntryPointsEx->context; - - *(pEntryPointsEx->ppInterface) = (void*) context; rail->context = context; isFreerdp = TRUE; } WLog_Init(); rail->log = WLog_Get("com.freerdp.channels.rail.client"); - - WLog_Print(rail->log, WLOG_DEBUG, "VirtualChannelEntry"); - - CopyMemory(&(rail->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - - rc = rail->channelEntryPoints.pVirtualChannelInit(&rail->InitHandle, - &rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rail_virtual_channel_init_event); + WLog_Print(rail->log, WLOG_DEBUG, "VirtualChannelEntryEx"); + CopyMemory(&(rail->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); + rail->InitHandle = pInitHandle; + rc = rail->channelEntryPoints.pVirtualChannelInitEx(rail, context, pInitHandle, + &rail->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + rail_virtual_channel_init_event_ex); if (CHANNEL_RC_OK != rc) { - WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); - goto error_out; - } - - rail->channelEntryPoints.pInterface = *(rail->channelEntryPoints.ppInterface); - rail->channelEntryPoints.ppInterface = &(rail->channelEntryPoints.pInterface); - - if ((error = rail_add_init_handle_data(rail->InitHandle, (void*) rail))) - { - WLog_ERR(TAG, "rail_add_init_handle_data failed with error %lu!", error); + WLog_ERR(TAG, "failed with %s [%08X]", + WTSErrorToString(rc), rc); goto error_out; } + rail->channelEntryPoints.pInterface = context; return TRUE; error_out: + if (isFreerdp) free(rail->context); + free(rail); return FALSE; } diff --git a/channels/rail/client/rail_main.h b/channels/rail/client/rail_main.h index ff82386..e581a38 100644 --- a/channels/rail/client/rail_main.h +++ b/channels/rail/client/rail_main.h @@ -39,7 +39,7 @@ struct rail_plugin { CHANNEL_DEF channelDef; - CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; + CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints; RailClientContext* context; diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index 570740e..d8729cc 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -268,17 +268,17 @@ UINT rail_write_client_exec_order(wStream* s, RAIL_EXEC_ORDER* exec) Stream_Write_UINT16(s, exec->arguments.length); /* argumentsLength (2 bytes) */ if ((error = rail_write_unicode_string_value(s, &exec->exeOrFile))) { - WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %lu", error); + WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %u", error); return error; } if ((error = rail_write_unicode_string_value(s, &exec->workingDir))) { - WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %lu", error); + WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %u", error); return error; } if ((error = rail_write_unicode_string_value(s, &exec->arguments))) { - WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %lu", error); + WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %u", error); return error; } return error; @@ -408,7 +408,7 @@ UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake if ((error = rail_read_handshake_order(s, handshake))) { - WLog_ERR(TAG, "rail_read_handshake_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_read_handshake_order failed with error %u!", error); return error; } @@ -416,7 +416,7 @@ UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake { IFCALLRET(context->ServerHandshake, error, context, handshake); if (error) - WLog_ERR(TAG, "context.ServerHandshake failed with error %lu", error); + WLog_ERR(TAG, "context.ServerHandshake failed with error %u", error); } return error; @@ -434,7 +434,7 @@ UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* han if ((error = rail_read_handshake_ex_order(s, handshakeEx))) { - WLog_ERR(TAG, "rail_read_handshake_ex_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_read_handshake_ex_order failed with error %u!", error); return error; } @@ -442,7 +442,7 @@ UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* han { IFCALLRET(context->ClientHandshakeEx, error, context, handshakeEx); if (error) - WLog_ERR(TAG, "context.ClientHandshakeEx failed with error %lu", error); + WLog_ERR(TAG, "context.ClientHandshakeEx failed with error %u", error); } @@ -463,7 +463,7 @@ UINT rail_recv_exec_result_order(railPlugin* rail, RAIL_EXEC_RESULT_ORDER* execR if ((error = rail_read_server_exec_result_order(s, execResult))) { - WLog_ERR(TAG, "rail_read_server_exec_result_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_read_server_exec_result_order failed with error %u!", error); return error; } @@ -471,7 +471,7 @@ UINT rail_recv_exec_result_order(railPlugin* rail, RAIL_EXEC_RESULT_ORDER* execR { IFCALLRET(context->ServerExecuteResult, error, context, execResult); if (error) - WLog_ERR(TAG, "context.ServerExecuteResult failed with error %lu", error); + WLog_ERR(TAG, "context.ServerExecuteResult failed with error %u", error); } @@ -490,7 +490,7 @@ UINT rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp if ((error = rail_read_server_sysparam_order(s, sysparam))) { - WLog_ERR(TAG, "rail_read_server_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_read_server_sysparam_order failed with error %u!", error); return error; } @@ -498,7 +498,7 @@ UINT rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp { IFCALLRET(context->ServerSystemParam, error, context, sysparam); if (error) - WLog_ERR(TAG, "context.ServerSystemParam failed with error %lu", error); + WLog_ERR(TAG, "context.ServerSystemParam failed with error %u", error); } return error; @@ -516,7 +516,7 @@ UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER* if ((error = rail_read_server_minmaxinfo_order(s, minMaxInfo))) { - WLog_ERR(TAG, "rail_read_server_minmaxinfo_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_read_server_minmaxinfo_order failed with error %u!", error); return error; } @@ -524,7 +524,7 @@ UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER* { IFCALLRET(context->ServerMinMaxInfo, error, context, minMaxInfo); if (error) - WLog_ERR(TAG, "context.ServerMinMaxInfo failed with error %lu", error); + WLog_ERR(TAG, "context.ServerMinMaxInfo failed with error %u", error); } return error; @@ -542,7 +542,7 @@ UINT rail_recv_server_localmovesize_order(railPlugin* rail, RAIL_LOCALMOVESIZE_O if ((error = rail_read_server_localmovesize_order(s, localMoveSize))) { - WLog_ERR(TAG, "rail_read_server_localmovesize_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_read_server_localmovesize_order failed with error %u!", error); return error; } @@ -550,7 +550,7 @@ UINT rail_recv_server_localmovesize_order(railPlugin* rail, RAIL_LOCALMOVESIZE_O { IFCALLRET(context->ServerLocalMoveSize, error, context, localMoveSize); if (error) - WLog_ERR(TAG, "context.ServerLocalMoveSize failed with error %lu", error); + WLog_ERR(TAG, "context.ServerLocalMoveSize failed with error %u", error); } return error; @@ -568,7 +568,7 @@ UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, RAIL_GET_APPID_RESP if ((error = rail_read_server_get_appid_resp_order(s, getAppIdResp))) { - WLog_ERR(TAG, "rail_read_server_get_appid_resp_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_read_server_get_appid_resp_order failed with error %u!", error); return error; } @@ -576,7 +576,7 @@ UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, RAIL_GET_APPID_RESP { IFCALLRET(context->ServerGetAppIdResponse, error, context, getAppIdResp); if (error) - WLog_ERR(TAG, "context.ServerGetAppIdResponse failed with error %lu", error); + WLog_ERR(TAG, "context.ServerGetAppIdResponse failed with error %u", error); } return error; @@ -594,7 +594,7 @@ UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* lan if ((error = rail_read_langbar_info_order(s, langBarInfo))) { - WLog_ERR(TAG, "rail_read_langbar_info_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_read_langbar_info_order failed with error %u!", error); return error; } @@ -602,7 +602,7 @@ UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* lan { IFCALLRET(context->ServerLanguageBarInfo, error, context, langBarInfo); if (error) - WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %lu", error); + WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %u", error); } return error; @@ -621,12 +621,12 @@ UINT rail_order_recv(railPlugin* rail, wStream* s) if ((error = rail_read_pdu_header(s, &orderType, &orderLength))) { - WLog_ERR(TAG, "rail_read_pdu_header failed with error %lu!", error); + WLog_ERR(TAG, "rail_read_pdu_header failed with error %u!", error); return error; } - WLog_Print(rail->log, WLOG_DEBUG, "Received %s PDU, length:%lu", - RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength); + WLog_Print(rail->log, WLOG_DEBUG, "Received %s PDU, length:%u", + RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], (unsigned)orderLength); switch (orderType) { @@ -780,12 +780,12 @@ UINT rail_send_client_exec_order(railPlugin* rail, RAIL_EXEC_ORDER* exec) if ((error = rail_write_client_exec_order(s, exec))) { - WLog_ERR(TAG, "rail_write_client_exec_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_write_client_exec_order failed with error %u!", error); return error; } if ((error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_EXEC))) { - WLog_ERR(TAG, "rail_send_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_pdu failed with error %u!", error); return error; } Stream_Free(s, TRUE); @@ -834,13 +834,13 @@ UINT rail_send_client_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysp if ((error = rail_write_client_sysparam_order(s, sysparam))) { - WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %u!", error); return error; } if ((error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSPARAM))) { - WLog_ERR(TAG, "rail_send_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_pdu failed with error %u!", error); return error; } @@ -862,7 +862,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys sysparam->param = SPI_SET_HIGH_CONTRAST; if ((error = rail_send_client_sysparam_order(rail, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error); return error; } } @@ -872,7 +872,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys sysparam->param = SPI_TASKBAR_POS; if ((error = rail_send_client_sysparam_order(rail, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error); return error; } } @@ -882,7 +882,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP; if ((error = rail_send_client_sysparam_order(rail, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error); return error; } } @@ -892,7 +892,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys sysparam->param = SPI_SET_KEYBOARD_PREF; if ((error = rail_send_client_sysparam_order(rail, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error); return error; } } @@ -902,7 +902,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys sysparam->param = SPI_SET_DRAG_FULL_WINDOWS; if ((error = rail_send_client_sysparam_order(rail, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error); return error; } } @@ -912,7 +912,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys sysparam->param = SPI_SET_KEYBOARD_CUES; if ((error = rail_send_client_sysparam_order(rail, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error); return error; } } @@ -922,7 +922,7 @@ UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sys sysparam->param = SPI_SET_WORK_AREA; if ((error = rail_send_client_sysparam_order(rail, sysparam))) { - WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %lu!", error); + WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %u!", error); return error; } } diff --git a/channels/rdpdr/client/CMakeLists.txt b/channels/rdpdr/client/CMakeLists.txt index 4074eb6..e41cc3c 100644 --- a/channels/rdpdr/client/CMakeLists.txt +++ b/channels/rdpdr/client/CMakeLists.txt @@ -29,7 +29,7 @@ set(${MODULE_PREFIX}_SRCS rdpdr_capabilities.c rdpdr_capabilities.h) -add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") +add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx") diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index cf41c7c..2b227d9 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -7,6 +7,7 @@ * Copyright 2015-2016 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger * Copyright 2016 Armin Novak + * Copyright 2016 David PHAM-VAN * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,19 +80,21 @@ struct _DEVICE_DRIVE_EXT * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL userLoggedOn); +static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, + BOOL userLoggedOn); /** * Function description * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_send_device_list_remove_request(rdpdrPlugin* rdpdr, UINT32 count, UINT32 ids[]) +static UINT rdpdr_send_device_list_remove_request(rdpdrPlugin* rdpdr, + UINT32 count, UINT32 ids[]) { UINT32 i; wStream* s; - s = Stream_New(NULL, count * sizeof(UINT32) + 8); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -106,25 +109,41 @@ static UINT rdpdr_send_device_list_remove_request(rdpdrPlugin* rdpdr, UINT32 cou Stream_Write_UINT32(s, ids[i]); Stream_SealLength(s); - return rdpdr_send(rdpdr, s); } -#ifdef _WIN32 +#ifdef _UWP + +void first_hotplug(rdpdrPlugin* rdpdr) +{ +} + +static void* drive_hotplug_thread_func(void* arg) +{ + return NULL; +} + +static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr) +{ + return CHANNEL_RC_OK; +} + +#elif _WIN32 BOOL check_path(char* path) { UINT type = GetDriveTypeA(path); + if (!(type == DRIVE_REMOVABLE || type == DRIVE_CDROM || type == DRIVE_REMOTE)) return FALSE; + return GetVolumeInformationA(path, NULL, 0, NULL, NULL, NULL, NULL, 0); } -void first_hotplug(rdpdrPlugin *rdpdr) +void first_hotplug(rdpdrPlugin* rdpdr) { int i; char drive_path[5] = { 'c', ':', '\\', '\0' }; - DWORD unitmask = GetLogicalDrives(); for (i = 0; i < 26; i++) @@ -132,7 +151,6 @@ void first_hotplug(rdpdrPlugin *rdpdr) if (unitmask & 0x01) { RDPDR_DRIVE* drive; - drive_path[0] = 'A' + i; drive_path[1] = ':'; @@ -144,22 +162,23 @@ void first_hotplug(rdpdrPlugin *rdpdr) drive->Path = _strdup(drive_path); drive_path[1] = '\0'; drive->Name = _strdup(drive_path); - devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE *)drive, rdpdr->rdpcontext); + devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE*)drive, + rdpdr->rdpcontext); } } + unitmask = unitmask >> 1; } } LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { - rdpdrPlugin *rdpdr; + rdpdrPlugin* rdpdr; PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam; UINT error; + rdpdr = (rdpdrPlugin*)GetWindowLongPtr(hWnd, GWLP_USERDATA); - rdpdr = (rdpdrPlugin *)GetWindowLongPtr(hWnd, GWLP_USERDATA); - - switch(Msg) + switch (Msg) { case WM_DEVICECHANGE: switch (wParam) @@ -177,7 +196,6 @@ LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) if (unitmask & 0x01) { RDPDR_DRIVE* drive; - drive_path[0] = 'A' + i; drive_path[1] = ':'; @@ -185,19 +203,20 @@ LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { drive = (RDPDR_DRIVE*) malloc(sizeof(RDPDR_DRIVE)); ZeroMemory(drive, sizeof(RDPDR_DRIVE)); - drive->Type = RDPDR_DTYP_FILESYSTEM; - drive->Path = _strdup(drive_path); drive_path[1] = '\0'; drive->Name = _strdup(drive_path); - devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE *)drive, rdpdr->rdpcontext); + devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE*)drive, + rdpdr->rdpcontext); rdpdr_send_device_list_announce_request(rdpdr, TRUE); } } + unitmask = unitmask >> 1; } } + break; case DBT_DEVICEREMOVECOMPLETE: @@ -207,9 +226,8 @@ LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) DWORD unitmask = lpdbv->dbcv_unitmask; int i, j, count; char drive_name_upper, drive_name_lower; - - ULONG_PTR *keys; - DEVICE_DRIVE_EXT *device_ext; + ULONG_PTR* keys; + DEVICE_DRIVE_EXT* device_ext; UINT32 ids[1]; for (i = 0; i < 26; i++) @@ -218,53 +236,60 @@ LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { drive_name_upper = 'A' + i; drive_name_lower = 'a' + i; - count = ListDictionary_GetKeys(rdpdr->devman->devices, &keys); for (j = 0; j < count; j++) { - device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]); - if (device_ext->path[0] == drive_name_upper || device_ext->path[0] == drive_name_lower) + device_ext = (DEVICE_DRIVE_EXT*)ListDictionary_GetItemValue( + rdpdr->devman->devices, (void*)keys[j]); + + if (device_ext->path[0] == drive_name_upper + || device_ext->path[0] == drive_name_lower) { - devman_unregister_device(rdpdr->devman, (void *)keys[j]); + devman_unregister_device(rdpdr->devman, (void*)keys[j]); ids[0] = keys[j]; + if ((error = rdpdr_send_device_list_remove_request(rdpdr, 1, ids))) { // dont end on error, just report ? - WLog_ERR(TAG, "rdpdr_send_device_list_remove_request failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_send_device_list_remove_request failed with error %u!", + error); } + break; } } } + unitmask = unitmask >> 1; } } + break; default: break; } + break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } + return DefWindowProc(hWnd, Msg, wParam, lParam); } static void* drive_hotplug_thread_func(void* arg) { - rdpdrPlugin *rdpdr; + rdpdrPlugin* rdpdr; WNDCLASSEX wnd_cls; HWND hwnd; MSG msg; BOOL bRet; DEV_BROADCAST_HANDLE NotificationFilter; HDEVNOTIFY hDevNotify; - - rdpdr = (rdpdrPlugin *)arg; - + rdpdr = (rdpdrPlugin*)arg; /* init windows class */ wnd_cls.cbSize = sizeof(WNDCLASSEX); wnd_cls.style = CS_HREDRAW | CS_VREDRAW; @@ -279,18 +304,17 @@ static void* drive_hotplug_thread_func(void* arg) wnd_cls.hInstance = NULL; wnd_cls.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wnd_cls); - /* create window */ hwnd = CreateWindowEx(0, L"DRIVE_HOTPLUG", NULL, - 0, 0, 0, 0, 0, - NULL, NULL, NULL, NULL); + 0, 0, 0, 0, 0, + NULL, NULL, NULL, NULL); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)rdpdr); - rdpdr->hotplug_wnd = hwnd; /* register device interface to hwnd */ NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE); NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE; - hDevNotify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); + hDevNotify = RegisterDeviceNotification(hwnd, &NotificationFilter, + DEVICE_NOTIFY_WINDOW_HANDLE); /* message loop */ while ((bRet = GetMessage(&msg, 0, 0, 0)) != 0) @@ -307,7 +331,6 @@ static void* drive_hotplug_thread_func(void* arg) } UnregisterDeviceNotification(hDevNotify); - return NULL; } @@ -319,11 +342,13 @@ static void* drive_hotplug_thread_func(void* arg) static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr) { UINT error = CHANNEL_RC_OK; + if (rdpdr->hotplug_wnd && !PostMessage(rdpdr->hotplug_wnd, WM_QUIT, 0, 0)) { error = GetLastError(); - WLog_ERR(TAG, "PostMessage failed with error %lu", error); + WLog_ERR(TAG, "PostMessage failed with error %u", error); } + return error; } @@ -345,24 +370,24 @@ typedef struct _hotplug_dev */ static UINT handle_hotplug(rdpdrPlugin* rdpdr) { - struct dirent *pDirent; - DIR *pDir; + struct dirent* pDirent; + DIR* pDir; char fullpath[PATH_MAX]; char* szdir = (char*)"/Volumes"; struct stat buf; hotplug_dev dev_array[MAX_USB_DEVICES]; int count; - DEVICE_DRIVE_EXT *device_ext; - ULONG_PTR *keys; + DEVICE_DRIVE_EXT* device_ext; + ULONG_PTR* keys; int i, j; int size = 0; UINT error; UINT32 ids[1]; + pDir = opendir(szdir); - pDir = opendir (szdir); if (pDir == NULL) { - printf ("Cannot open directory\n"); + printf("Cannot open directory\n"); return ERROR_OPEN_FAILED; } @@ -372,29 +397,33 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) { sprintf(fullpath, "%s/%s", szdir, pDirent->d_name); lstat(fullpath, &buf); - if(S_ISDIR(buf.st_mode)) + + if (S_ISDIR(buf.st_mode)) { dev_array[size].path = _strdup(fullpath); + if (!dev_array[size].path) { - closedir (pDir); + closedir(pDir); error = CHANNEL_RC_NO_MEMORY; goto cleanup; } + dev_array[size++].to_add = TRUE; } } } - closedir (pDir); + closedir(pDir); /* delete removed devices */ count = ListDictionary_GetKeys(rdpdr->devman->devices, &keys); for (j = 0; j < count; j++) { BOOL dev_found = FALSE; + device_ext = (DEVICE_DRIVE_EXT*)ListDictionary_GetItemValue( + rdpdr->devman->devices, (void*)keys[j]); - device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]); if (!device_ext) continue; @@ -417,11 +446,13 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) if (!dev_found) { - devman_unregister_device(rdpdr->devman, (void *)keys[j]); + devman_unregister_device(rdpdr->devman, (void*)keys[j]); ids[0] = keys[j]; + if ((error = rdpdr_send_device_list_remove_request(rdpdr, 1, ids))) { - WLog_ERR(TAG, "rdpdr_send_device_list_remove_request failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_send_device_list_remove_request failed with error %u!", + error); goto cleanup; } } @@ -435,8 +466,8 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) if (dev_array[i].to_add) { char* name; - drive = (RDPDR_DRIVE*) calloc(1, sizeof(RDPDR_DRIVE)); + if (!drive) { WLog_ERR(TAG, "calloc failed!"); @@ -445,12 +476,11 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) } drive->Type = RDPDR_DTYP_FILESYSTEM; - drive->Path = dev_array[i].path; dev_array[i].path = NULL; - name = strrchr(drive->Path, '/') + 1; drive->Name = _strdup(name); + if (!drive->Name) { WLog_ERR(TAG, "_strdup failed!"); @@ -459,7 +489,9 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) error = CHANNEL_RC_NO_MEMORY; goto cleanup; } - if ((error = devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE *)drive, rdpdr->rdpcontext))) + + if ((error = devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE*)drive, + rdpdr->rdpcontext))) { WLog_ERR(TAG, "devman_load_device_service failed!"); free(drive->Path); @@ -472,45 +504,48 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) } cleanup: + for (i = 0; i < size; i++) - free (dev_array[i].path); + free(dev_array[i].path); return error; - } +} -static void drive_hotplug_fsevent_callback(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, - size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIds[]) +static void drive_hotplug_fsevent_callback(ConstFSEventStreamRef streamRef, + void* clientCallBackInfo, + size_t numEvents, void* eventPaths, const FSEventStreamEventFlags eventFlags[], + const FSEventStreamEventId eventIds[]) { rdpdrPlugin* rdpdr; int i; UINT error; - char **paths = (char**)eventPaths; - + char** paths = (char**)eventPaths; rdpdr = (rdpdrPlugin*) clientCallBackInfo; - for (i=0; irunLoop = CFRunLoopGetCurrent(); FSEventStreamScheduleWithRunLoop(fsev, rdpdr->runLoop, kCFRunLoopDefaultMode); FSEventStreamStart(fsev); CFRunLoopRun(); FSEventStreamStop(fsev); FSEventStreamRelease(fsev); - ExitThread(CHANNEL_RC_OK); return NULL; } @@ -548,6 +582,7 @@ static void* drive_hotplug_thread_func(void* arg) static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr) { UINT error; + if (rdpdr->hotplugThread) { CFRunLoopStop(rdpdr->runLoop); @@ -555,11 +590,13 @@ static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr) if (WaitForSingleObject(rdpdr->hotplugThread, INFINITE) == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); return error; } + rdpdr->hotplugThread = NULL; } + return CHANNEL_RC_OK; } @@ -567,7 +604,8 @@ static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr) #define MAX_USB_DEVICES 100 -typedef struct _hotplug_dev { +typedef struct _hotplug_dev +{ char* path; BOOL to_add; } hotplug_dev; @@ -579,7 +617,6 @@ static char* next_line(FILE* fd, size_t* len) char* newbuf; char* lrbuf; int lrsiz; - *len = 0; lrsiz = 0; lrbuf = NULL; @@ -588,6 +625,7 @@ static char* next_line(FILE* fd, size_t* len) for (;;) { c = fgetc(fd); + if (ferror(fd)) return NULL; @@ -607,11 +645,14 @@ static char* next_line(FILE* fd, size_t* len) { newsiz = lrsiz + 4096; newbuf = realloc(lrbuf, newsiz); + if (newbuf == NULL) return NULL; + lrbuf = newbuf; lrsiz = newsiz; } + lrbuf[(*len)] = c; if (c == '\n') @@ -666,25 +707,22 @@ static char* get_word(char* str, unsigned int* offset) */ static UINT handle_hotplug(rdpdrPlugin* rdpdr) { - FILE *f; + FILE* f; size_t len; - char *line; - char *word; + char* line; + char* word; unsigned int wlen; - hotplug_dev dev_array[MAX_USB_DEVICES]; int i, j; int size = 0; - int count; - DEVICE_DRIVE_EXT *device_ext; - ULONG_PTR *keys; + DEVICE_DRIVE_EXT* device_ext; + ULONG_PTR* keys; UINT32 ids[1]; UINT error = 0; - memset(dev_array, 0, sizeof(dev_array)); - f = fopen("/proc/mounts", "r"); + if (f == NULL) { WLog_ERR(TAG, "fopen failed!"); @@ -694,6 +732,7 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) while ((line = next_line(f, &len))) { wlen = 0; + while ((word = get_word(line, &wlen))) { /* copy hotpluged device mount point to the dev_array */ @@ -703,26 +742,28 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) dev_array[size++].to_add = TRUE; } else - free (word); + free(word); } + free(line); } fclose(f); - /* delete removed devices */ count = ListDictionary_GetKeys(rdpdr->devman->devices, &keys); for (j = 0; j < count; j++) { BOOL dev_found = FALSE; + device_ext = (DEVICE_DRIVE_EXT*)ListDictionary_GetItemValue( + rdpdr->devman->devices, (void*)keys[j]); - device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]); if (!device_ext || !device_ext->path) continue; /* not plugable device */ - if (strstr(device_ext->path, "/mnt/") == NULL && strstr(device_ext->path, "/media/") == NULL) + if (strstr(device_ext->path, "/mnt/") == NULL + && strstr(device_ext->path, "/media/") == NULL) continue; for (i = 0; i < size; i++) @@ -737,11 +778,13 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) if (!dev_found) { - devman_unregister_device(rdpdr->devman, (void *)keys[j]); + devman_unregister_device(rdpdr->devman, (void*)keys[j]); ids[0] = keys[j]; + if ((error = rdpdr_send_device_list_remove_request(rdpdr, 1, ids))) { - WLog_ERR(TAG, "rdpdr_send_device_list_remove_request failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_send_device_list_remove_request failed with error %u!", + error); goto cleanup; } } @@ -755,8 +798,8 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) if (dev_array[i].to_add) { char* name; - drive = (RDPDR_DRIVE*) calloc(1, sizeof(RDPDR_DRIVE)); + if (!drive) { WLog_ERR(TAG, "calloc failed!"); @@ -765,12 +808,11 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) } drive->Type = RDPDR_DTYP_FILESYSTEM; - drive->Path = dev_array[i].path; dev_array[i].path = NULL; - name = strrchr(drive->Path, '/') + 1; drive->Name = _strdup(name); + if (!drive->Name) { WLog_ERR(TAG, "_strdup failed!"); @@ -779,7 +821,9 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) error = CHANNEL_RC_NO_MEMORY; goto cleanup; } - if ((error = devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE *)drive, rdpdr->rdpcontext))) + + if ((error = devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE*)drive, + rdpdr->rdpcontext))) { WLog_ERR(TAG, "devman_load_device_service failed!"); free(drive->Path); @@ -791,18 +835,20 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) } cleanup: + for (i = 0; i < size; i++) - free (dev_array[i].path); + free(dev_array[i].path); return error; } -void first_hotplug(rdpdrPlugin *rdpdr) +static void first_hotplug(rdpdrPlugin* rdpdr) { UINT error; + if ((error = handle_hotplug(rdpdr))) { - WLog_ERR(TAG, "handle_hotplug failed with error %lu!", error); + WLog_ERR(TAG, "handle_hotplug failed with error %u!", error); } } @@ -815,7 +861,6 @@ static void* drive_hotplug_thread_func(void* arg) int rv; UINT error = 0; DWORD status; - rdpdr = (rdpdrPlugin*) arg; if (!(rdpdr->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) @@ -839,15 +884,17 @@ static void* drive_hotplug_thread_func(void* arg) tv.tv_sec = 1; tv.tv_usec = 0; - while ((rv = select(mfd+1, NULL, NULL, &rfds, &tv)) >= 0) + while ((rv = select(mfd + 1, NULL, NULL, &rfds, &tv)) >= 0) { status = WaitForSingleObject(rdpdr->stopEvent, 0); + if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); goto out; } + if (status == WAIT_OBJECT_0) break; @@ -856,7 +903,7 @@ static void* drive_hotplug_thread_func(void* arg) /* file /proc/mounts changed, handle this */ if ((error = handle_hotplug(rdpdr))) { - WLog_ERR(TAG, "handle_hotplug failed with error %lu!", error); + WLog_ERR(TAG, "handle_hotplug failed with error %u!", error); goto out; } else @@ -870,9 +917,12 @@ static void* drive_hotplug_thread_func(void* arg) } out: - if (error && rdpdr->rdpcontext) - setChannelError(rdpdr->rdpcontext, error, "drive_hotplug_thread_func reported an error"); + if (error && rdpdr->rdpcontext) + setChannelError(rdpdr->rdpcontext, error, + "drive_hotplug_thread_func reported an error"); + + CloseHandle(rdpdr->stopEvent); ExitThread((DWORD)error); return NULL; } @@ -894,11 +944,13 @@ static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr) if (WaitForSingleObject(rdpdr->hotplugThread, INFINITE) == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); return error; } + rdpdr->hotplugThread = NULL; } + return CHANNEL_RC_OK; } @@ -916,8 +968,8 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr) RDPDR_DEVICE* device; rdpSettings* settings; UINT error = CHANNEL_RC_OK; - rdpdr->devman = devman_new(rdpdr); + if (!rdpdr->devman) { WLog_ERR(TAG, "devman_new failed!"); @@ -925,10 +977,13 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr) } settings = (rdpSettings*) rdpdr->channelEntryPoints.pExtendedData; + if (settings->ClientHostname) - strncpy(rdpdr->computerName, settings->ClientHostname, sizeof(rdpdr->computerName) - 1); + strncpy(rdpdr->computerName, settings->ClientHostname, + sizeof(rdpdr->computerName) - 1); else - strncpy(rdpdr->computerName, settings->ComputerName, sizeof(rdpdr->computerName) - 1); + strncpy(rdpdr->computerName, settings->ComputerName, + sizeof(rdpdr->computerName) - 1); for (index = 0; index < settings->DeviceCount; index++) { @@ -937,8 +992,9 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr) if (device->Name && (strcmp(device->Name, "*") == 0)) { first_hotplug(rdpdr); + if (!(rdpdr->hotplugThread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) drive_hotplug_thread_func, rdpdr, 0, NULL))) + (LPTHREAD_START_ROUTINE) drive_hotplug_thread_func, rdpdr, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); return ERROR_INTERNAL_ERROR; @@ -947,16 +1003,19 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr) continue; } - if ((error = devman_load_device_service(rdpdr->devman, device, rdpdr->rdpcontext))) + if ((error = devman_load_device_service(rdpdr->devman, device, + rdpdr->rdpcontext))) { - WLog_ERR(TAG, "devman_load_device_service failed with error %lu!", error); + WLog_ERR(TAG, "devman_load_device_service failed with error %u!", error); return error; } } + return error; } -static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s) +static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, + wStream* s) { if (Stream_GetRemainingLength(s) < 8) return ERROR_INVALID_DATA; @@ -964,9 +1023,7 @@ static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s Stream_Read_UINT16(s, rdpdr->versionMajor); Stream_Read_UINT16(s, rdpdr->versionMinor); Stream_Read_UINT32(s, rdpdr->clientID); - rdpdr->sequenceId++; - return CHANNEL_RC_OK; } @@ -978,8 +1035,8 @@ static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s static UINT rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr) { wStream* s; - s = Stream_New(NULL, 12); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -988,11 +1045,9 @@ static UINT rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr) Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */ Stream_Write_UINT16(s, PAKID_CORE_CLIENTID_CONFIRM); /* PacketId (2 bytes) */ - Stream_Write_UINT16(s, rdpdr->versionMajor); Stream_Write_UINT16(s, rdpdr->versionMinor); Stream_Write_UINT32(s, (UINT32) rdpdr->clientID); - return rdpdr_send(rdpdr, s); } @@ -1010,9 +1065,10 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) if (!rdpdr->computerName[0]) gethostname(rdpdr->computerName, sizeof(rdpdr->computerName) - 1); - computerNameLenW = ConvertToUnicode(CP_UTF8, 0, rdpdr->computerName, -1, &computerNameW, 0) * 2; - + computerNameLenW = ConvertToUnicode(CP_UTF8, 0, rdpdr->computerName, -1, + &computerNameW, 0) * 2; s = Stream_New(NULL, 16 + computerNameLenW + 2); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -1021,19 +1077,18 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */ Stream_Write_UINT16(s, PAKID_CORE_CLIENT_NAME); /* PacketId (2 bytes) */ - Stream_Write_UINT32(s, 1); /* unicodeFlag, 0 for ASCII and 1 for Unicode */ Stream_Write_UINT32(s, 0); /* codePage, must be set to zero */ - Stream_Write_UINT32(s, computerNameLenW + 2); /* computerNameLen, including null terminator */ + Stream_Write_UINT32(s, computerNameLenW + + 2); /* computerNameLen, including null terminator */ Stream_Write(s, computerNameW, computerNameLenW); Stream_Write_UINT16(s, 0); /* null terminator */ - free(computerNameW); - return rdpdr_send(rdpdr, s); } -static UINT rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s) +static UINT rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, + wStream* s) { UINT16 versionMajor; UINT16 versionMinor; @@ -1063,7 +1118,8 @@ static UINT rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL userLoggedOn) +static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, + BOOL userLoggedOn) { int i; BYTE c; @@ -1076,8 +1132,8 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use DEVICE* device; int keyCount; ULONG_PTR* pKeys; - s = Stream_New(NULL, 256); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -1086,18 +1142,16 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */ Stream_Write_UINT16(s, PAKID_CORE_DEVICELIST_ANNOUNCE); /* PacketId (2 bytes) */ - count_pos = (int) Stream_GetPosition(s); count = 0; - Stream_Seek_UINT32(s); /* deviceCount */ - pKeys = NULL; keyCount = ListDictionary_GetKeys(rdpdr->devman->devices, &pKeys); for (index = 0; index < keyCount; index++) { - device = (DEVICE*) ListDictionary_GetItemValue(rdpdr->devman->devices, (void*) pKeys[index]); + device = (DEVICE*) ListDictionary_GetItemValue(rdpdr->devman->devices, + (void*) pKeys[index]); /** * 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON @@ -1107,9 +1161,10 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use */ if ((rdpdr->versionMinor == 0x0005) || - (device->type == RDPDR_DTYP_SMARTCARD) || userLoggedOn) + (device->type == RDPDR_DTYP_SMARTCARD) || userLoggedOn) { - data_len = (int) (device->data == NULL ? 0 : Stream_GetPosition(device->data)); + data_len = (int)(device->data == NULL ? 0 : Stream_GetPosition(device->data)); + if (!Stream_EnsureRemainingCapacity(s, 20 + data_len)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); @@ -1137,18 +1192,16 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use count++; WLog_INFO(TAG, "registered device #%d: %s (type=%d id=%d)", - count, device->name, device->type, device->id); + count, device->name, device->type, device->id); } } free(pKeys); - pos = (int) Stream_GetPosition(s); Stream_SetPosition(s, count_pos); Stream_Write_UINT32(s, count); Stream_SetPosition(s, pos); Stream_SealLength(s); - return rdpdr_send(rdpdr, s); } @@ -1161,19 +1214,18 @@ static UINT rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s) { IRP* irp; UINT error = CHANNEL_RC_OK; - irp = irp_new(rdpdr->devman, s, &error); if (!irp) { - WLog_ERR(TAG, "irp_new failed with %lu!", error); + WLog_ERR(TAG, "irp_new failed with %u!", error); return error; } IFCALLRET(irp->device->IRPRequest, error, irp->device, irp); if (error) - WLog_ERR(TAG, "device->IRPRequest failed with error %lu", error); + WLog_ERR(TAG, "device->IRPRequest failed with error %u", error); return error; } @@ -1190,15 +1242,15 @@ static UINT rdpdr_process_init(rdpdrPlugin* rdpdr) DEVICE* device; ULONG_PTR* pKeys; UINT error = CHANNEL_RC_OK; - pKeys = NULL; keyCount = ListDictionary_GetKeys(rdpdr->devman->devices, &pKeys); for (index = 0; index < keyCount; index++) { - device = (DEVICE*) ListDictionary_GetItemValue(rdpdr->devman->devices, (void*) pKeys[index]); - + device = (DEVICE*) ListDictionary_GetItemValue(rdpdr->devman->devices, + (void*) pKeys[index]); IFCALLRET(device->Init, error, device); + if (error != CHANNEL_RC_OK) { WLog_ERR(TAG, "Init failed!"); @@ -1237,107 +1289,121 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s) { switch (packetId) { - case PAKID_CORE_SERVER_ANNOUNCE: - if ((error = rdpdr_process_server_announce_request(rdpdr, s))) - return error; - if ((error = rdpdr_send_client_announce_reply(rdpdr))) - { - WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %lu", error); - return error; - } - if ((error = rdpdr_send_client_name_request(rdpdr))) - { - WLog_ERR(TAG, "rdpdr_send_client_name_request failed with error %lu", error); - return error; - } - if ((error = rdpdr_process_init(rdpdr))) - { - WLog_ERR(TAG, "rdpdr_process_init failed with error %lu", error); - return error; - } - break; + case PAKID_CORE_SERVER_ANNOUNCE: + if ((error = rdpdr_process_server_announce_request(rdpdr, s))) + return error; - case PAKID_CORE_SERVER_CAPABILITY: - if ((error = rdpdr_process_capability_request(rdpdr, s))) - return error; - if ((error = rdpdr_send_capability_response(rdpdr))) - { - WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %lu", error); - return error; - } - break; + if ((error = rdpdr_send_client_announce_reply(rdpdr))) + { + WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %u", error); + return error; + } - case PAKID_CORE_CLIENTID_CONFIRM: - if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s))) - return error; + if ((error = rdpdr_send_client_name_request(rdpdr))) + { + WLog_ERR(TAG, "rdpdr_send_client_name_request failed with error %u", error); + return error; + } - if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE))) - { - WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error); - return error; - } - break; + if ((error = rdpdr_process_init(rdpdr))) + { + WLog_ERR(TAG, "rdpdr_process_init failed with error %u", error); + return error; + } - case PAKID_CORE_USER_LOGGEDON: - if ((error = rdpdr_send_device_list_announce_request(rdpdr, TRUE))) - { - WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error); - return error; - } - break; + break; - case PAKID_CORE_DEVICE_REPLY: - /* connect to a specific resource */ - if (Stream_GetRemainingLength(s) < 8) + case PAKID_CORE_SERVER_CAPABILITY: + if ((error = rdpdr_process_capability_request(rdpdr, s))) + return error; + + if ((error = rdpdr_send_capability_response(rdpdr))) + { + WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %u", error); + return error; + } + + break; + + case PAKID_CORE_CLIENTID_CONFIRM: + if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s))) + return error; + + if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE))) + { + WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %u", + error); + return error; + } + + break; + + case PAKID_CORE_USER_LOGGEDON: + if ((error = rdpdr_send_device_list_announce_request(rdpdr, TRUE))) + { + WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %u", + error); + return error; + } + + break; + + case PAKID_CORE_DEVICE_REPLY: + + /* connect to a specific resource */ + if (Stream_GetRemainingLength(s) < 8) + return ERROR_INVALID_DATA; + + Stream_Read_UINT32(s, deviceId); + Stream_Read_UINT32(s, status); + break; + + case PAKID_CORE_DEVICE_IOREQUEST: + if ((error = rdpdr_process_irp(rdpdr, s))) + { + WLog_ERR(TAG, "rdpdr_process_irp failed with error %u", error); + return error; + } + + s = NULL; + break; + + default: + WLog_ERR(TAG, "RDPDR_CTYP_CORE unknown PacketId: 0x%04X", packetId); return ERROR_INVALID_DATA; - - Stream_Read_UINT32(s, deviceId); - Stream_Read_UINT32(s, status); - break; - - case PAKID_CORE_DEVICE_IOREQUEST: - if ((error = rdpdr_process_irp(rdpdr, s))) - { - WLog_ERR(TAG, "rdpdr_process_irp failed with error %lu", error); - return error; - } - s = NULL; - break; - - default: - WLog_ERR(TAG, "RDPDR_CTYP_CORE unknown PacketId: 0x%04X", packetId); - return ERROR_INVALID_DATA; - break; - + break; } } else if (component == RDPDR_CTYP_PRN) { switch (packetId) { - case PAKID_PRN_CACHE_DATA: - { - UINT32 eventID; - if (Stream_GetRemainingLength(s) < 4) + case PAKID_PRN_CACHE_DATA: + { + UINT32 eventID; + + if (Stream_GetRemainingLength(s) < 4) + return ERROR_INVALID_DATA; + + Stream_Read_UINT32(s, eventID); + WLog_ERR(TAG, + "Ignoring unhandled message PAKID_PRN_CACHE_DATA (EventID: 0x%04X)", eventID); + } + break; + + case PAKID_PRN_USING_XPS: + WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_USING_XPS"); + break; + + default: + WLog_ERR(TAG, "Unknown printing component packetID: 0x%04X", packetId); return ERROR_INVALID_DATA; - - Stream_Read_UINT32(s, eventID); - WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_CACHE_DATA (EventID: 0x%04X)", eventID); - } - break; - - case PAKID_PRN_USING_XPS: - WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_USING_XPS"); - break; - - default: - WLog_ERR(TAG, "Unknown printing component packetID: 0x%04X", packetId); - return ERROR_INVALID_DATA; } } else { - WLog_ERR(TAG, "Unknown message: Component: 0x%04X PacketId: 0x%04X", component, packetId); + WLog_ERR(TAG, "Unknown message: Component: 0x%04X PacketId: 0x%04X", component, + packetId); return ERROR_INVALID_DATA; } @@ -1345,102 +1411,6 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s) return CHANNEL_RC_OK; } - -/****************************************************************************************/ - - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT rdpdr_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - } - if (!g_InitHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* rdpdr_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void rdpdr_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT rdpdr_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - } - - if (!g_OpenHandles) - { - WLog_ERR(TAG, "ListDictionary_New failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData)) - { - WLog_ERR(TAG, "ListDictionary_Add failed!"); - return ERROR_INTERNAL_ERROR; - } - return CHANNEL_RC_OK; -} - -void* rdpdr_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void rdpdr_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * @@ -1458,15 +1428,15 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s) status = CHANNEL_RC_BAD_INIT_HANDLE; else { - status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + status = plugin->channelEntryPoints.pVirtualChannelWriteEx(plugin->InitHandle, plugin->OpenHandle, + Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); } return status; @@ -1478,7 +1448,7 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s) * @return 0 on success, otherwise a Win32 error code */ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -1499,6 +1469,7 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, Stream_Free(rdpdr->data_in, TRUE); rdpdr->data_in = Stream_New(NULL, totalLength); + if (!rdpdr->data_in) { WLog_ERR(TAG, "Stream_New failed!"); @@ -1507,11 +1478,13 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, } data_in = rdpdr->data_in; + if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return ERROR_INVALID_DATA; } + Stream_Write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) @@ -1532,39 +1505,44 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE rdpdr_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - rdpdrPlugin* rdpdr; UINT error = CHANNEL_RC_OK; + rdpdrPlugin* rdpdr = (rdpdrPlugin*) lpUserParam; - rdpdr = (rdpdrPlugin*) rdpdr_get_open_handle_data(openHandle); - - if (!rdpdr || !pData) + if (!rdpdr || !pData || (rdpdr->OpenHandle != openHandle)) { - WLog_ERR(TAG, "rdpdr_virtual_channel_open_event: error no match"); + WLog_ERR(TAG, "error no match"); return; } switch (event) { - case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = rdpdr_virtual_channel_event_data_received(rdpdr, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "rdpdr_virtual_channel_event_data_received failed with error %lu!", error ); - break; + case CHANNEL_EVENT_DATA_RECEIVED: + if ((error = rdpdr_virtual_channel_event_data_received(rdpdr, pData, + dataLength, totalLength, dataFlags))) + WLog_ERR(TAG, + "rdpdr_virtual_channel_event_data_received failed with error %u!", error); - case CHANNEL_EVENT_WRITE_COMPLETE: - Stream_Free((wStream*) pData, TRUE); - break; + break; - case CHANNEL_EVENT_USER: - break; + case CHANNEL_EVENT_WRITE_COMPLETE: + Stream_Free((wStream*) pData, TRUE); + break; + + case CHANNEL_EVENT_USER: + break; } + if (error && rdpdr->rdpcontext) - setChannelError(rdpdr->rdpcontext, error, "rdpdr_virtual_channel_open_event reported an error"); + setChannelError(rdpdr->rdpcontext, error, + "rdpdr_virtual_channel_open_event_ex reported an error"); return; } @@ -1584,9 +1562,12 @@ static void* rdpdr_virtual_channel_client_thread(void* arg) if ((error = rdpdr_process_connect(rdpdr))) { - WLog_ERR(TAG, "rdpdr_process_connect failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_process_connect failed with error %u!", error); + if (rdpdr->rdpcontext) - setChannelError(rdpdr->rdpcontext, error, "rdpdr_virtual_channel_client_thread reported an error"); + setChannelError(rdpdr->rdpcontext, error, + "rdpdr_virtual_channel_client_thread reported an error"); + ExitThread((DWORD) error); return NULL; } @@ -1604,11 +1585,15 @@ static void* rdpdr_virtual_channel_client_thread(void* arg) if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = rdpdr_process_receive(rdpdr, data))) { - WLog_ERR(TAG, "rdpdr_process_receive failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_process_receive failed with error %u!", error); + if (rdpdr->rdpcontext) - setChannelError(rdpdr->rdpcontext, error, "rdpdr_virtual_channel_client_thread reported an error"); + setChannelError(rdpdr->rdpcontext, error, + "rdpdr_virtual_channel_client_thread reported an error"); + ExitThread((DWORD) error); return NULL; } @@ -1625,28 +1610,22 @@ static void* rdpdr_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pData, UINT32 dataLength) +static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, + LPVOID pData, UINT32 dataLength) { UINT32 status; - UINT error; - - status = rdpdr->channelEntryPoints.pVirtualChannelOpen(rdpdr->InitHandle, - &rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event); + status = rdpdr->channelEntryPoints.pVirtualChannelOpenEx(rdpdr->InitHandle, + &rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event_ex); if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "pVirtualChannelOpenEx failed with %s [%08X]", + WTSErrorToString(status), status); return status; } - if ((error = rdpdr_add_open_handle_data(rdpdr->OpenHandle, rdpdr))) - { - WLog_ERR(TAG, "rdpdr_add_open_handle_data failed with error %lu!", error); - return error; - } - rdpdr->queue = MessageQueue_New(NULL); + if (!rdpdr->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -1654,11 +1633,13 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa } if (!(rdpdr->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rdpdr_virtual_channel_client_thread, (void*) rdpdr, 0, NULL))) + (LPTHREAD_START_ROUTINE) rdpdr_virtual_channel_client_thread, (void*) rdpdr, 0, + NULL))) { WLog_ERR(TAG, "CreateThread failed!"); return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -1671,32 +1652,35 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr) { UINT error; - if (MessageQueue_PostQuit(rdpdr->queue, 0) && (WaitForSingleObject(rdpdr->thread, INFINITE) == WAIT_FAILED)) + if (MessageQueue_PostQuit(rdpdr->queue, 0) + && (WaitForSingleObject(rdpdr->thread, INFINITE) == WAIT_FAILED)) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); return error; } MessageQueue_Free(rdpdr->queue); CloseHandle(rdpdr->thread); - rdpdr->queue = NULL; rdpdr->thread = NULL; if ((error = drive_hotplug_thread_terminate(rdpdr))) { - WLog_ERR(TAG, "drive_hotplug_thread_terminate failed with error %lu!", error); + WLog_ERR(TAG, "drive_hotplug_thread_terminate failed with error %u!", error); return error; } - error = rdpdr->channelEntryPoints.pVirtualChannelClose(rdpdr->OpenHandle); + error = rdpdr->channelEntryPoints.pVirtualChannelCloseEx(rdpdr->InitHandle, rdpdr->OpenHandle); + if (CHANNEL_RC_OK != error) { - WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(error), error); + WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]", + WTSErrorToString(error), error); } + rdpdr->OpenHandle = 0; + if (rdpdr->data_in) { Stream_Free(rdpdr->data_in, TRUE); @@ -1709,26 +1693,23 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr) rdpdr->devman = NULL; } - rdpdr_remove_open_handle_data(rdpdr->OpenHandle); return error; } static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr) { - rdpdr_remove_init_handle_data(rdpdr->InitHandle); - + rdpdr->InitHandle = 0; free(rdpdr); } -static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle, UINT event, - LPVOID pData, UINT dataLength) +static VOID VCAPITYPE rdpdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle, + UINT event, + LPVOID pData, UINT dataLength) { - rdpdrPlugin* rdpdr; UINT error = CHANNEL_RC_OK; + rdpdrPlugin* rdpdr = (rdpdrPlugin*) lpUserParam; - rdpdr = (rdpdrPlugin*) rdpdr_get_init_handle_data(pInitHandle); - - if (!rdpdr) + if (!rdpdr || (rdpdr->InitHandle != pInitHandle)) { WLog_ERR(TAG, "error no match"); return; @@ -1736,40 +1717,46 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle, UINT switch (event) { - case CHANNEL_EVENT_INITIALIZED: - break; - case CHANNEL_EVENT_CONNECTED: - if ((error = rdpdr_virtual_channel_event_connected(rdpdr, pData, dataLength))) - WLog_ERR(TAG, "rdpdr_virtual_channel_event_connected failed with error %lu!", error); - break; + case CHANNEL_EVENT_INITIALIZED: + break; - case CHANNEL_EVENT_DISCONNECTED: - if ((error = rdpdr_virtual_channel_event_disconnected(rdpdr))) - WLog_ERR(TAG, "rdpdr_virtual_channel_event_disconnected failed with error %lu!", error); - break; + case CHANNEL_EVENT_CONNECTED: + if ((error = rdpdr_virtual_channel_event_connected(rdpdr, pData, dataLength))) + WLog_ERR(TAG, "rdpdr_virtual_channel_event_connected failed with error %u!", + error); - case CHANNEL_EVENT_TERMINATED: - rdpdr_virtual_channel_event_terminated(rdpdr); - break; - default: - WLog_ERR(TAG, "unknown event %d!", event); - error = ERROR_INVALID_DATA; - break; + break; + + case CHANNEL_EVENT_DISCONNECTED: + if ((error = rdpdr_virtual_channel_event_disconnected(rdpdr))) + WLog_ERR(TAG, "rdpdr_virtual_channel_event_disconnected failed with error %u!", + error); + + break; + + case CHANNEL_EVENT_TERMINATED: + rdpdr_virtual_channel_event_terminated(rdpdr); + break; + + default: + WLog_ERR(TAG, "unknown event %d!", event); + error = ERROR_INVALID_DATA; + break; } if (error && rdpdr->rdpcontext) - setChannelError(rdpdr->rdpcontext, error, "rdpdr_virtual_channel_init_event reported an error"); + setChannelError(rdpdr->rdpcontext, error, + "rdpdr_virtual_channel_init_event_ex reported an error"); } /* rdpdr is always built-in */ -#define VirtualChannelEntry rdpdr_VirtualChannelEntry +#define VirtualChannelEntryEx rdpdr_VirtualChannelEntryEx -BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle) { UINT rc; rdpdrPlugin* rdpdr; - CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; - + CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx; rdpdr = (rdpdrPlugin*) calloc(1, sizeof(rdpdrPlugin)); if (!rdpdr) @@ -1779,39 +1766,30 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } rdpdr->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP; strcpy(rdpdr->channelDef.name, "rdpdr"); - rdpdr->sequenceId = 0; + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints; - pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; - - if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && - (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) && + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { - rdpdr->rdpcontext = pEntryPointsEx->context; } - CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - - rc = rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle, - &rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpdr_virtual_channel_init_event); + CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); + rdpdr->InitHandle = pInitHandle; + rc = rdpdr->channelEntryPoints.pVirtualChannelInitEx(rdpdr, NULL, pInitHandle, + &rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + rdpdr_virtual_channel_init_event_ex); if (CHANNEL_RC_OK != rc) { - WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); - free(rdpdr); - return FALSE; - } - - if ((rc = rdpdr_add_init_handle_data(rdpdr->InitHandle, (void*) rdpdr))) - { - WLog_ERR(TAG, "rdpdr_add_init_handle_data failed with error %lu!", rc); + WLog_ERR(TAG, "pVirtualChannelInitEx failed with %s [%08X]", + WTSErrorToString(rc), rc); free(rdpdr); return FALSE; } diff --git a/channels/rdpdr/client/rdpdr_main.h b/channels/rdpdr/client/rdpdr_main.h index 6ecb945..1cdd2ce 100644 --- a/channels/rdpdr/client/rdpdr_main.h +++ b/channels/rdpdr/client/rdpdr_main.h @@ -49,7 +49,7 @@ typedef struct rdpdr_plugin rdpdrPlugin; struct rdpdr_plugin { CHANNEL_DEF channelDef; - CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; + CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints; HANDLE thread; wStream* data_in; diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index b29182f..1bf112a 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -39,9 +39,7 @@ static UINT32 g_ClientId = 0; static RDPDR_IRP* rdpdr_server_irp_new() { RDPDR_IRP* irp; - irp = (RDPDR_IRP*) calloc(1, sizeof(RDPDR_IRP)); - return irp; } @@ -50,17 +48,19 @@ static void rdpdr_server_irp_free(RDPDR_IRP* irp) free(irp); } -static BOOL rdpdr_server_enqueue_irp(RdpdrServerContext* context, RDPDR_IRP* irp) +static BOOL rdpdr_server_enqueue_irp(RdpdrServerContext* context, + RDPDR_IRP* irp) { - return ListDictionary_Add(context->priv->IrpList, (void*) (size_t) irp->CompletionId, irp); + return ListDictionary_Add(context->priv->IrpList, + (void*)(size_t) irp->CompletionId, irp); } -static RDPDR_IRP* rdpdr_server_dequeue_irp(RdpdrServerContext* context, UINT32 completionId) +static RDPDR_IRP* rdpdr_server_dequeue_irp(RdpdrServerContext* context, + UINT32 completionId) { RDPDR_IRP* irp; - - irp = (RDPDR_IRP*) ListDictionary_Remove(context->priv->IrpList, (void*) (size_t) completionId); - + irp = (RDPDR_IRP*) ListDictionary_Remove(context->priv->IrpList, + (void*)(size_t) completionId); return irp; } @@ -75,30 +75,28 @@ static UINT rdpdr_server_send_announce_request(RdpdrServerContext* context) BOOL status; RDPDR_HEADER header; ULONG written; - WLog_DBG(TAG, "RdpdrServerSendAnnounceRequest"); - header.Component = RDPDR_CTYP_CORE; header.PacketId = PAKID_CORE_SERVER_ANNOUNCE; - s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 8); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */ Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ - Stream_Write_UINT16(s, context->priv->VersionMajor); /* VersionMajor (2 bytes) */ - Stream_Write_UINT16(s, context->priv->VersionMinor); /* VersionMinor (2 bytes) */ + Stream_Write_UINT16(s, + context->priv->VersionMajor); /* VersionMajor (2 bytes) */ + Stream_Write_UINT16(s, + context->priv->VersionMinor); /* VersionMinor (2 bytes) */ Stream_Write_UINT32(s, context->priv->ClientId); /* ClientId (4 bytes) */ - Stream_SealLength(s); - winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), Stream_Length(s)); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -108,7 +106,8 @@ static UINT rdpdr_server_send_announce_request(RdpdrServerContext* context) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_receive_announce_response(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +static UINT rdpdr_server_receive_announce_response(RdpdrServerContext* context, + wStream* s, RDPDR_HEADER* header) { UINT32 ClientId; UINT16 VersionMajor; @@ -123,10 +122,9 @@ static UINT rdpdr_server_receive_announce_response(RdpdrServerContext* context, Stream_Read_UINT16(s, VersionMajor); /* VersionMajor (2 bytes) */ Stream_Read_UINT16(s, VersionMinor); /* VersionMinor (2 bytes) */ Stream_Read_UINT32(s, ClientId); /* ClientId (4 bytes) */ - - WLog_DBG(TAG, "Client Announce Response: VersionMajor: 0x%04X VersionMinor: 0x%04X ClientId: 0x%04X", - VersionMajor, VersionMinor, ClientId); - + WLog_DBG(TAG, + "Client Announce Response: VersionMajor: 0x%04X VersionMinor: 0x%04X ClientId: 0x%04X", + VersionMajor, VersionMinor, ClientId); context->priv->ClientId = ClientId; return CHANNEL_RC_OK; } @@ -136,7 +134,8 @@ static UINT rdpdr_server_receive_announce_response(RdpdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* + context, wStream* s, RDPDR_HEADER* header) { UINT32 UnicodeFlag; UINT32 ComputerNameLen; @@ -147,19 +146,16 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context return ERROR_INVALID_DATA; } - Stream_Read_UINT32(s, UnicodeFlag); /* UnicodeFlag (4 bytes) */ Stream_Seek_UINT32(s); /* CodePage (4 bytes), MUST be set to zero */ Stream_Read_UINT32(s, ComputerNameLen); /* ComputerNameLen (4 bytes) */ - if (UnicodeFlag > 1) /* must be 0x00000000 or 0x00000001 */ { WLog_ERR(TAG, "invalid UnicodeFlag value: 0x%08X", UnicodeFlag); return ERROR_INVALID_DATA; } - /** * Caution: ComputerNameLen is given *bytes*, * not in characters, including the NULL terminator! @@ -190,14 +186,13 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context /* ComputerName must be null terminated, check if it really is */ - if (Stream_Pointer(s)[ComputerNameLen-1] || - (UnicodeFlag && Stream_Pointer(s)[ComputerNameLen-2])) + if (Stream_Pointer(s)[ComputerNameLen - 1] || + (UnicodeFlag && Stream_Pointer(s)[ComputerNameLen - 2])) { WLog_ERR(TAG, "computer name must be null terminated"); return ERROR_INVALID_DATA; } - if (context->priv->ClientComputerName) { free(context->priv->ClientComputerName); @@ -207,7 +202,7 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context if (UnicodeFlag) { if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), -1, - &(context->priv->ClientComputerName), 0, NULL, NULL) < 1) + &(context->priv->ClientComputerName), 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert client computer name"); return ERROR_INVALID_DATA; @@ -216,6 +211,7 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context else { context->priv->ClientComputerName = _strdup((char*) Stream_Pointer(s)); + if (!context->priv->ClientComputerName) { WLog_ERR(TAG, "failed to duplicate client computer name"); @@ -224,7 +220,6 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context } Stream_Seek(s, ComputerNameLen); - WLog_DBG(TAG, "ClientComputerName: %s", context->priv->ClientComputerName); return CHANNEL_RC_OK; } @@ -234,7 +229,8 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_read_capability_set_header(wStream* s, RDPDR_CAPABILITY_HEADER* header) +static UINT rdpdr_server_read_capability_set_header(wStream* s, + RDPDR_CAPABILITY_HEADER* header) { if (Stream_GetRemainingLength(s) < 8) { @@ -243,7 +239,8 @@ static UINT rdpdr_server_read_capability_set_header(wStream* s, RDPDR_CAPABILITY } Stream_Read_UINT16(s, header->CapabilityType); /* CapabilityType (2 bytes) */ - Stream_Read_UINT16(s, header->CapabilityLength); /* CapabilityLength (2 bytes) */ + Stream_Read_UINT16(s, + header->CapabilityLength); /* CapabilityLength (2 bytes) */ Stream_Read_UINT32(s, header->Version); /* Version (4 bytes) */ return CHANNEL_RC_OK; } @@ -253,7 +250,8 @@ static UINT rdpdr_server_read_capability_set_header(wStream* s, RDPDR_CAPABILITY * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_write_capability_set_header(wStream* s, RDPDR_CAPABILITY_HEADER* header) +static UINT rdpdr_server_write_capability_set_header(wStream* s, + RDPDR_CAPABILITY_HEADER* header) { if (!Stream_EnsureRemainingCapacity(s, 8)) { @@ -262,7 +260,8 @@ static UINT rdpdr_server_write_capability_set_header(wStream* s, RDPDR_CAPABILIT } Stream_Write_UINT16(s, header->CapabilityType); /* CapabilityType (2 bytes) */ - Stream_Write_UINT16(s, header->CapabilityLength); /* CapabilityLength (2 bytes) */ + Stream_Write_UINT16(s, + header->CapabilityLength); /* CapabilityLength (2 bytes) */ Stream_Write_UINT32(s, header->Version); /* Version (4 bytes) */ return CHANNEL_RC_OK; } @@ -272,7 +271,8 @@ static UINT rdpdr_server_write_capability_set_header(wStream* s, RDPDR_CAPABILIT * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_read_general_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +static UINT rdpdr_server_read_general_capability_set(RdpdrServerContext* + context, wStream* s, RDPDR_CAPABILITY_HEADER* header) { UINT32 ioCode1; UINT32 extraFlags1; @@ -292,10 +292,12 @@ static UINT rdpdr_server_read_general_capability_set(RdpdrServerContext* context Stream_Read_UINT16(s, VersionMajor); /* protocolMajorVersion (2 bytes) */ Stream_Read_UINT16(s, VersionMinor); /* protocolMinorVersion (2 bytes) */ Stream_Read_UINT32(s, ioCode1); /* ioCode1 (4 bytes) */ - Stream_Seek_UINT32(s); /* ioCode2 (4 bytes), must be set to zero, reserved for future use */ + Stream_Seek_UINT32( + s); /* ioCode2 (4 bytes), must be set to zero, reserved for future use */ Stream_Read_UINT32(s, extendedPdu); /* extendedPdu (4 bytes) */ Stream_Read_UINT32(s, extraFlags1); /* extraFlags1 (4 bytes) */ - Stream_Seek_UINT32(s); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */ + Stream_Seek_UINT32( + s); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */ if (header->Version == GENERAL_CAPABILITY_VERSION_02) { @@ -305,10 +307,12 @@ static UINT rdpdr_server_read_general_capability_set(RdpdrServerContext* context return ERROR_INVALID_DATA; } - Stream_Read_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */ + Stream_Read_UINT32(s, + SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */ } - context->priv->UserLoggedOnPdu = (extendedPdu & RDPDR_USER_LOGGEDON_PDU) ? TRUE : FALSE; + context->priv->UserLoggedOnPdu = (extendedPdu & RDPDR_USER_LOGGEDON_PDU) ? + TRUE : FALSE; return CHANNEL_RC_OK; } @@ -317,14 +321,14 @@ static UINT rdpdr_server_read_general_capability_set(RdpdrServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_write_general_capability_set(RdpdrServerContext* context, wStream* s) +static UINT rdpdr_server_write_general_capability_set(RdpdrServerContext* + context, wStream* s) { UINT32 ioCode1; UINT32 extendedPdu; UINT32 extraFlags1; UINT32 SpecialTypeDeviceCap; RDPDR_CAPABILITY_HEADER header; - header.CapabilityType = CAP_GENERAL_TYPE; header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH + 36; header.Version = GENERAL_CAPABILITY_VERSION_02; @@ -363,17 +367,22 @@ static UINT rdpdr_server_write_general_capability_set(RdpdrServerContext* contex } rdpdr_server_write_capability_set_header(s, &header); - Stream_Write_UINT32(s, 0); /* osType (4 bytes), ignored on receipt */ - Stream_Write_UINT32(s, 0); /* osVersion (4 bytes), unused and must be set to zero */ - Stream_Write_UINT16(s, context->priv->VersionMajor); /* protocolMajorVersion (2 bytes) */ - Stream_Write_UINT16(s, context->priv->VersionMinor); /* protocolMinorVersion (2 bytes) */ + Stream_Write_UINT32(s, + 0); /* osVersion (4 bytes), unused and must be set to zero */ + Stream_Write_UINT16(s, + context->priv->VersionMajor); /* protocolMajorVersion (2 bytes) */ + Stream_Write_UINT16(s, + context->priv->VersionMinor); /* protocolMinorVersion (2 bytes) */ Stream_Write_UINT32(s, ioCode1); /* ioCode1 (4 bytes) */ - Stream_Write_UINT32(s, 0); /* ioCode2 (4 bytes), must be set to zero, reserved for future use */ + Stream_Write_UINT32(s, + 0); /* ioCode2 (4 bytes), must be set to zero, reserved for future use */ Stream_Write_UINT32(s, extendedPdu); /* extendedPdu (4 bytes) */ Stream_Write_UINT32(s, extraFlags1); /* extraFlags1 (4 bytes) */ - Stream_Write_UINT32(s, 0); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */ - Stream_Write_UINT32(s, SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */ + Stream_Write_UINT32(s, + 0); /* extraFlags2 (4 bytes), must be set to zero, reserved for future use */ + Stream_Write_UINT32(s, + SpecialTypeDeviceCap); /* SpecialTypeDeviceCap (4 bytes) */ return CHANNEL_RC_OK; } @@ -382,7 +391,8 @@ static UINT rdpdr_server_write_general_capability_set(RdpdrServerContext* contex * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_read_printer_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +static UINT rdpdr_server_read_printer_capability_set(RdpdrServerContext* + context, wStream* s, RDPDR_CAPABILITY_HEADER* header) { return CHANNEL_RC_OK; } @@ -392,10 +402,10 @@ static UINT rdpdr_server_read_printer_capability_set(RdpdrServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_write_printer_capability_set(RdpdrServerContext* context, wStream* s) +static UINT rdpdr_server_write_printer_capability_set(RdpdrServerContext* + context, wStream* s) { RDPDR_CAPABILITY_HEADER header; - header.CapabilityType = CAP_PRINTER_TYPE; header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH; header.Version = PRINT_CAPABILITY_VERSION_01; @@ -405,6 +415,7 @@ static UINT rdpdr_server_write_printer_capability_set(RdpdrServerContext* contex WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + return rdpdr_server_write_capability_set_header(s, &header); } @@ -413,7 +424,8 @@ static UINT rdpdr_server_write_printer_capability_set(RdpdrServerContext* contex * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_read_port_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +static UINT rdpdr_server_read_port_capability_set(RdpdrServerContext* context, + wStream* s, RDPDR_CAPABILITY_HEADER* header) { return CHANNEL_RC_OK; } @@ -423,10 +435,10 @@ static UINT rdpdr_server_read_port_capability_set(RdpdrServerContext* context, w * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_write_port_capability_set(RdpdrServerContext* context, wStream* s) +static UINT rdpdr_server_write_port_capability_set(RdpdrServerContext* context, + wStream* s) { RDPDR_CAPABILITY_HEADER header; - header.CapabilityType = CAP_PORT_TYPE; header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH; header.Version = PORT_CAPABILITY_VERSION_01; @@ -436,6 +448,7 @@ static UINT rdpdr_server_write_port_capability_set(RdpdrServerContext* context, WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + return rdpdr_server_write_capability_set_header(s, &header); } @@ -444,7 +457,8 @@ static UINT rdpdr_server_write_port_capability_set(RdpdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_read_drive_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +static UINT rdpdr_server_read_drive_capability_set(RdpdrServerContext* context, + wStream* s, RDPDR_CAPABILITY_HEADER* header) { return CHANNEL_RC_OK; } @@ -454,10 +468,10 @@ static UINT rdpdr_server_read_drive_capability_set(RdpdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_write_drive_capability_set(RdpdrServerContext* context, wStream* s) +static UINT rdpdr_server_write_drive_capability_set(RdpdrServerContext* context, + wStream* s) { RDPDR_CAPABILITY_HEADER header; - header.CapabilityType = CAP_DRIVE_TYPE; header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH; header.Version = DRIVE_CAPABILITY_VERSION_02; @@ -467,6 +481,7 @@ static UINT rdpdr_server_write_drive_capability_set(RdpdrServerContext* context, WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + return rdpdr_server_write_capability_set_header(s, &header); } @@ -475,7 +490,8 @@ static UINT rdpdr_server_write_drive_capability_set(RdpdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_read_smartcard_capability_set(RdpdrServerContext* context, wStream* s, RDPDR_CAPABILITY_HEADER* header) +static UINT rdpdr_server_read_smartcard_capability_set(RdpdrServerContext* + context, wStream* s, RDPDR_CAPABILITY_HEADER* header) { return CHANNEL_RC_OK; } @@ -485,10 +501,10 @@ static UINT rdpdr_server_read_smartcard_capability_set(RdpdrServerContext* conte * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_write_smartcard_capability_set(RdpdrServerContext* context, wStream* s) +static UINT rdpdr_server_write_smartcard_capability_set( + RdpdrServerContext* context, wStream* s) { RDPDR_CAPABILITY_HEADER header; - header.CapabilityType = CAP_SMARTCARD_TYPE; header.CapabilityLength = RDPDR_CAPABILITY_HEADER_LENGTH; header.Version = SMARTCARD_CAPABILITY_VERSION_01; @@ -498,6 +514,7 @@ static UINT rdpdr_server_write_smartcard_capability_set(RdpdrServerContext* cont WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_OK; } + return rdpdr_server_write_capability_set_header(s, &header); } @@ -506,7 +523,8 @@ static UINT rdpdr_server_write_smartcard_capability_set(RdpdrServerContext* cont * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_send_core_capability_request(RdpdrServerContext* context) +static UINT rdpdr_server_send_core_capability_request(RdpdrServerContext* + context) { wStream* s; BOOL status; @@ -514,20 +532,20 @@ static UINT rdpdr_server_send_core_capability_request(RdpdrServerContext* contex UINT16 numCapabilities; ULONG written; UINT error; - WLog_DBG(TAG, "RdpdrServerSendCoreCapabilityRequest"); - header.Component = RDPDR_CTYP_CORE; header.PacketId = PAKID_CORE_SERVER_CAPABILITY; - numCapabilities = 1; if (context->supportsDrives) numCapabilities++; + if (context->supportsPorts) numCapabilities++; + if (context->supportsPrinters) numCapabilities++; + if (context->supportsSmartcards) numCapabilities++; @@ -538,6 +556,7 @@ static UINT rdpdr_server_send_core_capability_request(RdpdrServerContext* contex WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */ Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ Stream_Write_UINT16(s, numCapabilities); /* numCapabilities (2 bytes) */ @@ -545,16 +564,17 @@ static UINT rdpdr_server_send_core_capability_request(RdpdrServerContext* contex if ((error = rdpdr_server_write_general_capability_set(context, s))) { - WLog_ERR(TAG, "rdpdr_server_write_general_capability_set failed with error %lu!", error); + WLog_ERR(TAG, + "rdpdr_server_write_general_capability_set failed with error %u!", error); return error; } - if (context->supportsDrives) { if ((error = rdpdr_server_write_drive_capability_set(context, s))) { - WLog_ERR(TAG, "rdpdr_server_write_drive_capability_set failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_server_write_drive_capability_set failed with error %u!", + error); return error; } } @@ -563,7 +583,8 @@ static UINT rdpdr_server_send_core_capability_request(RdpdrServerContext* contex { if ((error = rdpdr_server_write_port_capability_set(context, s))) { - WLog_ERR(TAG, "rdpdr_server_write_port_capability_set failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_server_write_port_capability_set failed with error %u!", + error); return error; } } @@ -572,7 +593,8 @@ static UINT rdpdr_server_send_core_capability_request(RdpdrServerContext* contex { if ((error = rdpdr_server_write_printer_capability_set(context, s))) { - WLog_ERR(TAG, "rdpdr_server_write_printer_capability_set failed with error %lu!", error); + WLog_ERR(TAG, + "rdpdr_server_write_printer_capability_set failed with error %u!", error); return error; } } @@ -581,17 +603,16 @@ static UINT rdpdr_server_send_core_capability_request(RdpdrServerContext* contex { if ((error = rdpdr_server_write_smartcard_capability_set(context, s))) { - WLog_ERR(TAG, "rdpdr_server_write_printer_capability_set failed with error %lu!", error); + WLog_ERR(TAG, + "rdpdr_server_write_printer_capability_set failed with error %u!", error); return error; } } Stream_SealLength(s); - winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), Stream_Length(s)); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -601,7 +622,8 @@ static UINT rdpdr_server_send_core_capability_request(RdpdrServerContext* contex * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_receive_core_capability_response(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +static UINT rdpdr_server_receive_core_capability_response( + RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) { int i; UINT status; @@ -621,55 +643,72 @@ static UINT rdpdr_server_receive_core_capability_response(RdpdrServerContext* co { if ((status = rdpdr_server_read_capability_set_header(s, &capabilityHeader))) { - WLog_ERR(TAG, "rdpdr_server_read_capability_set_header failed with error %lu!", status); + WLog_ERR(TAG, "rdpdr_server_read_capability_set_header failed with error %u!", + status); return status; } switch (capabilityHeader.CapabilityType) { case CAP_GENERAL_TYPE: - if ((status = rdpdr_server_read_general_capability_set(context, s, &capabilityHeader))) + if ((status = rdpdr_server_read_general_capability_set(context, s, + &capabilityHeader))) { - WLog_ERR(TAG, "rdpdr_server_read_general_capability_set failed with error %lu!", status); + WLog_ERR(TAG, "rdpdr_server_read_general_capability_set failed with error %u!", + status); return status; } + break; case CAP_PRINTER_TYPE: - if ((status = rdpdr_server_read_printer_capability_set(context, s, &capabilityHeader))) + if ((status = rdpdr_server_read_printer_capability_set(context, s, + &capabilityHeader))) { - WLog_ERR(TAG, "rdpdr_server_read_printer_capability_set failed with error %lu!", status); + WLog_ERR(TAG, "rdpdr_server_read_printer_capability_set failed with error %u!", + status); return status; } + break; case CAP_PORT_TYPE: - if ((status = rdpdr_server_read_port_capability_set(context, s, &capabilityHeader))) + if ((status = rdpdr_server_read_port_capability_set(context, s, + &capabilityHeader))) { - WLog_ERR(TAG, "rdpdr_server_read_port_capability_set failed with error %lu!", status); + WLog_ERR(TAG, "rdpdr_server_read_port_capability_set failed with error %u!", + status); return status; } + break; case CAP_DRIVE_TYPE: - if ((status = rdpdr_server_read_drive_capability_set(context, s, &capabilityHeader))) + if ((status = rdpdr_server_read_drive_capability_set(context, s, + &capabilityHeader))) { - WLog_ERR(TAG, "rdpdr_server_read_drive_capability_set failed with error %lu!", status); + WLog_ERR(TAG, "rdpdr_server_read_drive_capability_set failed with error %u!", + status); return status; } + break; case CAP_SMARTCARD_TYPE: - if ((status = rdpdr_server_read_smartcard_capability_set(context, s, &capabilityHeader))) + if ((status = rdpdr_server_read_smartcard_capability_set(context, s, + &capabilityHeader))) { - WLog_ERR(TAG, "rdpdr_server_read_smartcard_capability_set failed with error %lu!", status); + WLog_ERR(TAG, + "rdpdr_server_read_smartcard_capability_set failed with error %u!", status); return status; } + break; default: WLog_DBG(TAG, "Unknown capabilityType %d", capabilityHeader.CapabilityType); - Stream_Seek(s, capabilityHeader.CapabilityLength - RDPDR_CAPABILITY_HEADER_LENGTH); + Stream_Seek(s, capabilityHeader.CapabilityLength - + RDPDR_CAPABILITY_HEADER_LENGTH); return ERROR_INVALID_DATA; break; } @@ -689,30 +728,28 @@ static UINT rdpdr_server_send_client_id_confirm(RdpdrServerContext* context) BOOL status; RDPDR_HEADER header; ULONG written; - WLog_DBG(TAG, "RdpdrServerSendClientIdConfirm"); - header.Component = RDPDR_CTYP_CORE; header.PacketId = PAKID_CORE_CLIENTID_CONFIRM; - s = Stream_New(NULL, RDPDR_HEADER_LENGTH + 8); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */ Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ - Stream_Write_UINT16(s, context->priv->VersionMajor); /* VersionMajor (2 bytes) */ - Stream_Write_UINT16(s, context->priv->VersionMinor); /* VersionMinor (2 bytes) */ + Stream_Write_UINT16(s, + context->priv->VersionMajor); /* VersionMajor (2 bytes) */ + Stream_Write_UINT16(s, + context->priv->VersionMinor); /* VersionMinor (2 bytes) */ Stream_Write_UINT32(s, context->priv->ClientId); /* ClientId (4 bytes) */ - Stream_SealLength(s); - winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), Stream_Length(s)); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -722,7 +759,8 @@ static UINT rdpdr_server_send_client_id_confirm(RdpdrServerContext* context) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +static UINT rdpdr_server_receive_device_list_announce_request( + RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) { int i; UINT32 DeviceCount; @@ -739,7 +777,6 @@ static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext } Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */ - WLog_DBG(TAG, "DeviceCount: %d", DeviceCount); for (i = 0; i < DeviceCount; i++) @@ -764,9 +801,8 @@ static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext } DeviceData = Stream_Pointer(s); - WLog_DBG(TAG, "Device %d Name: %s Id: 0x%04X DataLength: %d", - i, PreferredDosName, DeviceId, DeviceDataLength); + i, PreferredDosName, DeviceId, DeviceDataLength); switch (DeviceType) { @@ -775,6 +811,7 @@ static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext { IFCALL(context->OnDriveCreate, context, DeviceId, PreferredDosName); } + break; case RDPDR_DTYP_PRINT: @@ -782,6 +819,7 @@ static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext { IFCALL(context->OnPrinterCreate, context, DeviceId, PreferredDosName); } + break; case RDPDR_DTYP_SERIAL: @@ -790,6 +828,7 @@ static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext { IFCALL(context->OnPortCreate, context, DeviceId, PreferredDosName); } + break; case RDPDR_DTYP_SMARTCARD: @@ -797,6 +836,7 @@ static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext { IFCALL(context->OnSmartcardCreate, context, DeviceId, PreferredDosName); } + break; default: @@ -814,7 +854,8 @@ static UINT rdpdr_server_receive_device_list_announce_request(RdpdrServerContext * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +static UINT rdpdr_server_receive_device_list_remove_request( + RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) { int i; UINT32 DeviceCount; @@ -828,7 +869,6 @@ static UINT rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* } Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */ - WLog_DBG(TAG, "DeviceCount: %d", DeviceCount); for (i = 0; i < DeviceCount; i++) @@ -840,9 +880,7 @@ static UINT rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* } Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */ - WLog_DBG(TAG, "Device %d Id: 0x%04X", i, DeviceId); - DeviceType = 0; /* TODO: Save the device type on the announce request. */ switch (DeviceType) @@ -852,6 +890,7 @@ static UINT rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* { IFCALL(context->OnDriveDelete, context, DeviceId); } + break; case RDPDR_DTYP_PRINT: @@ -859,6 +898,7 @@ static UINT rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* { IFCALL(context->OnPrinterDelete, context, DeviceId); } + break; case RDPDR_DTYP_SERIAL: @@ -867,6 +907,7 @@ static UINT rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* { IFCALL(context->OnPortDelete, context, DeviceId); } + break; case RDPDR_DTYP_SMARTCARD: @@ -874,6 +915,7 @@ static UINT rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* { IFCALL(context->OnSmartcardDelete, context, DeviceId); } + break; default: @@ -889,7 +931,8 @@ static UINT rdpdr_server_receive_device_list_remove_request(RdpdrServerContext* * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_receive_device_io_completion(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +static UINT rdpdr_server_receive_device_io_completion(RdpdrServerContext* + context, wStream* s, RDPDR_HEADER* header) { UINT32 deviceId; UINT32 completionId; @@ -906,9 +949,8 @@ static UINT rdpdr_server_receive_device_io_completion(RdpdrServerContext* contex Stream_Read_UINT32(s, deviceId); Stream_Read_UINT32(s, completionId); Stream_Read_UINT32(s, ioStatus); - - WLog_DBG(TAG, "deviceId=%d, completionId=0x%x, ioStatus=0x%x", deviceId, completionId, ioStatus); - + WLog_DBG(TAG, "deviceId=%d, completionId=0x%x, ioStatus=0x%x", deviceId, + completionId, ioStatus); irp = rdpdr_server_dequeue_irp(context, completionId); if (!irp) @@ -922,6 +964,7 @@ static UINT rdpdr_server_receive_device_io_completion(RdpdrServerContext* contex { error = (*irp->Callback)(context, s, irp, deviceId, completionId, ioStatus); } + return error; } @@ -936,27 +979,23 @@ static UINT rdpdr_server_send_user_logged_on(RdpdrServerContext* context) BOOL status; RDPDR_HEADER header; ULONG written; - WLog_DBG(TAG, "RdpdrServerSendUserLoggedOn"); - header.Component = RDPDR_CTYP_CORE; header.PacketId = PAKID_CORE_USER_LOGGEDON; - s = Stream_New(NULL, RDPDR_HEADER_LENGTH); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT16(s, header.Component); /* Component (2 bytes) */ Stream_Write_UINT16(s, header.PacketId); /* PacketId (2 bytes) */ - Stream_SealLength(s); - winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), Stream_Length(s)); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -966,13 +1005,12 @@ static UINT rdpdr_server_send_user_logged_on(RdpdrServerContext* context) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) +static UINT rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, + RDPDR_HEADER* header) { UINT error = CHANNEL_RC_OK; - WLog_DBG(TAG, "RdpdrServerReceivePdu: Component: 0x%04X PacketId: 0x%04X", - header->Component, header->PacketId); - + header->Component, header->PacketId); winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), Stream_Length(s)); if (header->Component == RDPDR_CTYP_CORE) @@ -982,29 +1020,32 @@ static UINT rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RD case PAKID_CORE_CLIENTID_CONFIRM: if ((error = rdpdr_server_receive_announce_response(context, s, header))) { - WLog_ERR(TAG, "rdpdr_server_receive_announce_response failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_server_receive_announce_response failed with error %u!", + error); return error; } + break; case PAKID_CORE_CLIENT_NAME: if ((error = rdpdr_server_receive_client_name_request(context, s, header))) { - WLog_ERR(TAG, "rdpdr_server_receive_client_name_request failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_server_receive_client_name_request failed with error %u!", + error); return error; } - - if((error = rdpdr_server_send_core_capability_request(context))) + if ((error = rdpdr_server_send_core_capability_request(context))) { - WLog_ERR(TAG, "rdpdr_server_send_core_capability_request failed with error %lu!", error); + WLog_ERR(TAG, + "rdpdr_server_send_core_capability_request failed with error %u!", error); return error; } - if ((error = rdpdr_server_send_client_id_confirm(context))) { - WLog_ERR(TAG, "rdpdr_server_send_client_id_confirm failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_server_send_client_id_confirm failed with error %u!", + error); return error; } @@ -1013,24 +1054,30 @@ static UINT rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RD case PAKID_CORE_CLIENT_CAPABILITY: if ((error = rdpdr_server_receive_core_capability_response(context, s, header))) { - WLog_ERR(TAG, "rdpdr_server_receive_core_capability_response failed with error %lu!", error); + WLog_ERR(TAG, + "rdpdr_server_receive_core_capability_response failed with error %u!", error); return error; } if (context->priv->UserLoggedOnPdu) - if((error = rdpdr_server_send_user_logged_on(context))) + if ((error = rdpdr_server_send_user_logged_on(context))) { - WLog_ERR(TAG, "rdpdr_server_send_user_logged_on failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_server_send_user_logged_on failed with error %u!", error); return error; } + break; case PAKID_CORE_DEVICELIST_ANNOUNCE: - if ((error = rdpdr_server_receive_device_list_announce_request(context, s, header))) + if ((error = rdpdr_server_receive_device_list_announce_request(context, s, + header))) { - WLog_ERR(TAG, "rdpdr_server_receive_device_list_announce_request failed with error %lu!", error); + WLog_ERR(TAG, + "rdpdr_server_receive_device_list_announce_request failed with error %u!", + error); return error; } + break; case PAKID_CORE_DEVICE_REPLY: @@ -1042,17 +1089,22 @@ static UINT rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RD case PAKID_CORE_DEVICE_IOCOMPLETION: if ((error = rdpdr_server_receive_device_io_completion(context, s, header))) { - WLog_ERR(TAG, "rdpdr_server_receive_device_io_completion failed with error %lu!", error); + WLog_ERR(TAG, + "rdpdr_server_receive_device_io_completion failed with error %u!", error); return error; } + break; case PAKID_CORE_DEVICELIST_REMOVE: - if((error = rdpdr_server_receive_device_list_remove_request(context, s, header))) + if ((error = rdpdr_server_receive_device_list_remove_request(context, s, + header))) { - WLog_ERR(TAG, "rdpdr_server_receive_device_io_completion failed with error %lu!", error); + WLog_ERR(TAG, + "rdpdr_server_receive_device_io_completion failed with error %u!", error); return error; } + break; default: @@ -1095,13 +1147,13 @@ static void* rdpdr_server_thread(void* arg) DWORD BytesReturned; RdpdrServerContext* context; UINT error; - context = (RdpdrServerContext*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; s = Stream_New(NULL, 4096); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -1109,7 +1161,8 @@ static void* rdpdr_server_thread(void* arg) goto out; } - if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, + &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); @@ -1120,9 +1173,11 @@ static void* rdpdr_server_thread(void* arg) nCount = 0; events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; + if ((error = rdpdr_server_send_announce_request(context))) { - WLog_ERR(TAG, "rdpdr_server_send_announce_request failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_server_send_announce_request failed with error %u!", + error); goto out_stream; } @@ -1131,28 +1186,27 @@ static void* rdpdr_server_thread(void* arg) BytesReturned = 0; status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); - goto out_stream; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error); + goto out_stream; + } - status = WaitForSingleObject(context->priv->StopEvent, 0); + status = WaitForSingleObject(context->priv->StopEvent, 0); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - goto out_stream; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + goto out_stream; + } - - if (status == WAIT_OBJECT_0) + if (status == WAIT_OBJECT_0) break; if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); error = ERROR_INTERNAL_ERROR; @@ -1172,17 +1226,20 @@ static void* rdpdr_server_thread(void* arg) if ((error = rdpdr_server_receive_pdu(context, s, &header))) { - WLog_ERR(TAG, "rdpdr_server_receive_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpdr_server_receive_pdu failed with error %u!", error); goto out_stream; } } } } + out_stream: Stream_Free(s, TRUE); out: + if (error && context->rdpcontext) - setChannelError(context->rdpcontext, error, "rdpdr_server_thread reported an error"); + setChannelError(context->rdpcontext, error, + "rdpdr_server_thread reported an error"); ExitThread((DWORD) error); return NULL; @@ -1195,7 +1252,8 @@ out: */ static UINT rdpdr_server_start(RdpdrServerContext* context) { - context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "rdpdr"); + context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, + WTS_CURRENT_SESSION, "rdpdr"); if (!context->priv->ChannelHandle) { @@ -1208,14 +1266,16 @@ static UINT rdpdr_server_start(RdpdrServerContext* context) WLog_ERR(TAG, "CreateEvent failed!"); return ERROR_INTERNAL_ERROR; } + if (!(context->priv->Thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rdpdr_server_thread, (void*) context, 0, NULL))) + (LPTHREAD_START_ROUTINE) rdpdr_server_thread, (void*) context, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); CloseHandle(context->priv->StopEvent); context->priv->StopEvent = NULL; return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -1226,16 +1286,19 @@ static UINT rdpdr_server_start(RdpdrServerContext* context) */ static UINT rdpdr_server_stop(RdpdrServerContext* context) { - UINT error; + UINT error; + if (context->priv->StopEvent) { SetEvent(context->priv->StopEvent); + if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + return error; + } + CloseHandle(context->priv->Thread); context->priv->Thread = NULL; CloseHandle(context->priv->StopEvent); @@ -1246,12 +1309,12 @@ static UINT rdpdr_server_stop(RdpdrServerContext* context) } static void rdpdr_server_write_device_iorequest( - wStream* s, - UINT32 deviceId, - UINT32 fileId, - UINT32 completionId, - UINT32 majorFunction, - UINT32 minorFunction) + wStream* s, + UINT32 deviceId, + UINT32 fileId, + UINT32 completionId, + UINT32 majorFunction, + UINT32 minorFunction) { Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */ Stream_Write_UINT16(s, PAKID_CORE_DEVICE_IOREQUEST); /* PacketId (2 bytes) */ @@ -1267,10 +1330,10 @@ static void rdpdr_server_write_device_iorequest( * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_read_file_directory_information(wStream* s, FILE_DIRECTORY_INFORMATION* fdi) +static UINT rdpdr_server_read_file_directory_information(wStream* s, + FILE_DIRECTORY_INFORMATION* fdi) { UINT32 fileNameLength; - ZeroMemory(fdi, sizeof(FILE_DIRECTORY_INFORMATION)); if (Stream_GetRemainingLength(s) < 64) @@ -1296,9 +1359,9 @@ static UINT rdpdr_server_read_file_directory_information(wStream* s, FILE_DIRECT return ERROR_INVALID_DATA; } - WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) Stream_Pointer(s), fileNameLength / 2, fdi->FileName, sizeof(fdi->FileName), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) Stream_Pointer(s), fileNameLength / 2, + fdi->FileName, sizeof(fdi->FileName), NULL, NULL); Stream_Seek(s, fileNameLength); - return CHANNEL_RC_OK; } @@ -1308,25 +1371,23 @@ static UINT rdpdr_server_read_file_directory_information(wStream* s, FILE_DIRECT * @return 0 on success, otherwise a Win32 error code */ static UINT rdpdr_server_send_device_create_request( - RdpdrServerContext* context, - UINT32 deviceId, - UINT32 completionId, - const char* path, - UINT32 desiredAccess, - UINT32 createOptions, - UINT32 createDisposition) + RdpdrServerContext* context, + UINT32 deviceId, + UINT32 completionId, + const char* path, + UINT32 desiredAccess, + UINT32 createOptions, + UINT32 createDisposition) { UINT32 pathLength; ULONG written; BOOL status; wStream* s; - - WLog_DBG(TAG, "RdpdrServerSendDeviceCreateRequest: deviceId=%d, path=%s, desiredAccess=0x%x createOptions=0x%x createDisposition=0x%x", - deviceId, path, desiredAccess, createOptions, createDisposition); - + WLog_DBG(TAG, + "RdpdrServerSendDeviceCreateRequest: deviceId=%d, path=%s, desiredAccess=0x%x createOptions=0x%x createDisposition=0x%x", + deviceId, path, desiredAccess, createOptions, createDisposition); /* Compute the required Unicode size. */ pathLength = (strlen(path) + 1) * sizeof(WCHAR); - s = Stream_New(NULL, 256 + pathLength); if (!s) @@ -1335,8 +1396,8 @@ static UINT rdpdr_server_send_device_create_request( return CHANNEL_RC_NO_MEMORY; } - rdpdr_server_write_device_iorequest(s, deviceId, 0, completionId, IRP_MJ_CREATE, 0); - + rdpdr_server_write_device_iorequest(s, deviceId, 0, completionId, IRP_MJ_CREATE, + 0); Stream_Write_UINT32(s, desiredAccess); /* DesiredAccess (4 bytes) */ Stream_Write_UINT32(s, 0); /* AllocationSize (8 bytes) */ Stream_Write_UINT32(s, 0); @@ -1345,17 +1406,14 @@ static UINT rdpdr_server_send_device_create_request( Stream_Write_UINT32(s, createDisposition); /* CreateDisposition (4 bytes) */ Stream_Write_UINT32(s, createOptions); /* CreateOptions (4 bytes) */ Stream_Write_UINT32(s, pathLength); /* PathLength (4 bytes) */ - /* Convert the path to Unicode. */ - MultiByteToWideChar(CP_ACP, 0, path, -1, (LPWSTR) Stream_Pointer(s), pathLength); + MultiByteToWideChar(CP_ACP, 0, path, -1, (LPWSTR) Stream_Pointer(s), + pathLength); Stream_Seek(s, pathLength); - Stream_SealLength(s); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); - return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -1365,17 +1423,16 @@ static UINT rdpdr_server_send_device_create_request( * @return 0 on success, otherwise a Win32 error code */ static UINT rdpdr_server_send_device_close_request( - RdpdrServerContext* context, - UINT32 deviceId, - UINT32 fileId, - UINT32 completionId) + RdpdrServerContext* context, + UINT32 deviceId, + UINT32 fileId, + UINT32 completionId) { ULONG written; BOOL status; wStream* s; - - WLog_DBG(TAG, "RdpdrServerSendDeviceCloseRequest: deviceId=%d, fileId=%d", deviceId, fileId); - + WLog_DBG(TAG, "RdpdrServerSendDeviceCloseRequest: deviceId=%d, fileId=%d", + deviceId, fileId); s = Stream_New(NULL, 128); if (!s) @@ -1384,16 +1441,13 @@ static UINT rdpdr_server_send_device_close_request( return CHANNEL_RC_NO_MEMORY; } - rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, IRP_MJ_CLOSE, 0); - + rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, + IRP_MJ_CLOSE, 0); Stream_Zero(s, 32); /* Padding (32 bytes) */ - Stream_SealLength(s); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); - return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -1403,20 +1457,19 @@ static UINT rdpdr_server_send_device_close_request( * @return 0 on success, otherwise a Win32 error code */ static UINT rdpdr_server_send_device_read_request( - RdpdrServerContext* context, - UINT32 deviceId, - UINT32 fileId, - UINT32 completionId, - UINT32 length, - UINT32 offset) + RdpdrServerContext* context, + UINT32 deviceId, + UINT32 fileId, + UINT32 completionId, + UINT32 length, + UINT32 offset) { ULONG written; BOOL status; wStream* s; - - WLog_DBG(TAG, "RdpdrServerSendDeviceReadRequest: deviceId=%d, fileId=%d, length=%d, offset=%d", - deviceId, fileId, length, offset); - + WLog_DBG(TAG, + "RdpdrServerSendDeviceReadRequest: deviceId=%d, fileId=%d, length=%d, offset=%d", + deviceId, fileId, length, offset); s = Stream_New(NULL, 128); if (!s) @@ -1425,19 +1478,16 @@ static UINT rdpdr_server_send_device_read_request( return CHANNEL_RC_NO_MEMORY; } - rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, IRP_MJ_READ, 0); - + rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, + IRP_MJ_READ, 0); Stream_Write_UINT32(s, length); /* Length (4 bytes) */ Stream_Write_UINT32(s, offset); /* Offset (8 bytes) */ Stream_Write_UINT32(s, 0); Stream_Zero(s, 20); /* Padding (20 bytes) */ - Stream_SealLength(s); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); - return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -1447,21 +1497,20 @@ static UINT rdpdr_server_send_device_read_request( * @return 0 on success, otherwise a Win32 error code */ static UINT rdpdr_server_send_device_write_request( - RdpdrServerContext* context, - UINT32 deviceId, - UINT32 fileId, - UINT32 completionId, - const char* data, - UINT32 length, - UINT32 offset) + RdpdrServerContext* context, + UINT32 deviceId, + UINT32 fileId, + UINT32 completionId, + const char* data, + UINT32 length, + UINT32 offset) { ULONG written; BOOL status; wStream* s; - - WLog_DBG(TAG, "RdpdrServerSendDeviceWriteRequest: deviceId=%d, fileId=%d, length=%d, offset=%d", - deviceId, fileId, length, offset); - + WLog_DBG(TAG, + "RdpdrServerSendDeviceWriteRequest: deviceId=%d, fileId=%d, length=%d, offset=%d", + deviceId, fileId, length, offset); s = Stream_New(NULL, 64 + length); if (!s) @@ -1470,20 +1519,17 @@ static UINT rdpdr_server_send_device_write_request( return CHANNEL_RC_NO_MEMORY; } - rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, IRP_MJ_WRITE, 0); - + rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, + IRP_MJ_WRITE, 0); Stream_Write_UINT32(s, length); /* Length (4 bytes) */ Stream_Write_UINT32(s, offset); /* Offset (8 bytes) */ Stream_Write_UINT32(s, 0); Stream_Zero(s, 20); /* Padding (20 bytes) */ Stream_Write(s, data, length); /* WriteData (variable) */ - Stream_SealLength(s); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); - return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -1493,23 +1539,21 @@ static UINT rdpdr_server_send_device_write_request( * @return 0 on success, otherwise a Win32 error code */ static UINT rdpdr_server_send_device_query_directory_request( - RdpdrServerContext* context, - UINT32 deviceId, - UINT32 fileId, - UINT32 completionId, - const char* path) + RdpdrServerContext* context, + UINT32 deviceId, + UINT32 fileId, + UINT32 completionId, + const char* path) { UINT32 pathLength; ULONG written; BOOL status; wStream* s; - - WLog_DBG(TAG, "RdpdrServerSendDeviceQueryDirectoryRequest: deviceId=%d, fileId=%d, path=%s", - deviceId, fileId, path); - + WLog_DBG(TAG, + "RdpdrServerSendDeviceQueryDirectoryRequest: deviceId=%d, fileId=%d, path=%s", + deviceId, fileId, path); /* Compute the required Unicode size. */ pathLength = path ? (strlen(path) + 1) * sizeof(WCHAR) : 0; - s = Stream_New(NULL, 64 + pathLength); if (!s) @@ -1518,9 +1562,10 @@ static UINT rdpdr_server_send_device_query_directory_request( return CHANNEL_RC_NO_MEMORY; } - rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, IRP_MJ_DIRECTORY_CONTROL, IRP_MN_QUERY_DIRECTORY); - - Stream_Write_UINT32(s, FileDirectoryInformation); /* FsInformationClass (4 bytes) */ + rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, + IRP_MJ_DIRECTORY_CONTROL, IRP_MN_QUERY_DIRECTORY); + Stream_Write_UINT32(s, + FileDirectoryInformation); /* FsInformationClass (4 bytes) */ Stream_Write_UINT8(s, path ? 1 : 0); /* InitialQuery (1 byte) */ Stream_Write_UINT32(s, pathLength); /* PathLength (4 bytes) */ Stream_Zero(s, 23); /* Padding (23 bytes) */ @@ -1528,17 +1573,16 @@ static UINT rdpdr_server_send_device_query_directory_request( /* Convert the path to Unicode. */ if (pathLength > 0) { - MultiByteToWideChar(CP_ACP, 0, path, -1, (LPWSTR) Stream_Pointer(s), pathLength); + MultiByteToWideChar(CP_ACP, 0, path, -1, (LPWSTR) Stream_Pointer(s), + pathLength); Stream_Seek(s, pathLength); } Stream_SealLength(s); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); - - return status? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; + return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } /** @@ -1547,23 +1591,21 @@ static UINT rdpdr_server_send_device_query_directory_request( * @return 0 on success, otherwise a Win32 error code */ static UINT rdpdr_server_send_device_file_rename_request( - RdpdrServerContext* context, - UINT32 deviceId, - UINT32 fileId, - UINT32 completionId, - const char* path) + RdpdrServerContext* context, + UINT32 deviceId, + UINT32 fileId, + UINT32 completionId, + const char* path) { UINT32 pathLength; ULONG written; BOOL status; wStream* s; - - WLog_DBG(TAG, "RdpdrServerSendDeviceFileNameRequest: deviceId=%d, fileId=%d, path=%s", - deviceId, fileId, path); - + WLog_DBG(TAG, + "RdpdrServerSendDeviceFileNameRequest: deviceId=%d, fileId=%d, path=%s", + deviceId, fileId, path); /* Compute the required Unicode size. */ pathLength = path ? (strlen(path) + 1) * sizeof(WCHAR) : 0; - s = Stream_New(NULL, 64 + pathLength); if (!s) @@ -1572,12 +1614,12 @@ static UINT rdpdr_server_send_device_file_rename_request( return CHANNEL_RC_NO_MEMORY; } - rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, IRP_MJ_SET_INFORMATION, 0); - - Stream_Write_UINT32(s, FileRenameInformation); /* FsInformationClass (4 bytes) */ + rdpdr_server_write_device_iorequest(s, deviceId, fileId, completionId, + IRP_MJ_SET_INFORMATION, 0); + Stream_Write_UINT32(s, + FileRenameInformation); /* FsInformationClass (4 bytes) */ Stream_Write_UINT32(s, pathLength + 6); /* Length (4 bytes) */ Stream_Zero(s, 24); /* Padding (24 bytes) */ - /* RDP_FILE_RENAME_INFORMATION */ Stream_Write_UINT8(s, 0); /* ReplaceIfExists (1 byte) */ Stream_Write_UINT8(s, 0); /* RootDirectory (1 byte) */ @@ -1586,16 +1628,15 @@ static UINT rdpdr_server_send_device_file_rename_request( /* Convert the path to Unicode. */ if (pathLength > 0) { - MultiByteToWideChar(CP_ACP, 0, path, -1, (LPWSTR) Stream_Pointer(s), pathLength); + MultiByteToWideChar(CP_ACP, 0, path, -1, (LPWSTR) Stream_Pointer(s), + pathLength); Stream_Seek(s, pathLength); } Stream_SealLength(s); - - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); - + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &written); Stream_Free(s, TRUE); - return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -1619,17 +1660,17 @@ static void rdpdr_server_convert_slashes(char* path, int size) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_create_directory_callback2(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_create_directory_callback2( + RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, + UINT32 completionId, UINT32 ioStatus) { - WLog_DBG(TAG, "RdpdrServerDriveCreateDirectoryCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); - + WLog_DBG(TAG, + "RdpdrServerDriveCreateDirectoryCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); /* Invoke the create directory completion routine. */ context->OnDriveCreateDirectoryComplete(context, irp->CallbackData, ioStatus); - /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -1638,22 +1679,22 @@ static UINT rdpdr_server_drive_create_directory_callback2(RdpdrServerContext* co * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_create_directory_callback1(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_create_directory_callback1( + RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, + UINT32 completionId, UINT32 ioStatus) { UINT32 fileId; UINT8 information; - - WLog_DBG(TAG, "RdpdrServerDriveCreateDirectoryCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveCreateDirectoryCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (ioStatus != STATUS_SUCCESS) { /* Invoke the create directory completion routine. */ context->OnDriveCreateDirectoryComplete(context, irp->CallbackData, ioStatus); - /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -1665,7 +1706,6 @@ static UINT rdpdr_server_drive_create_directory_callback1(RdpdrServerContext* co Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ - /* Setup the IRP. */ irp->CompletionId = context->priv->NextCompletionId++; irp->Callback = rdpdr_server_drive_create_directory_callback2; @@ -1680,7 +1720,8 @@ static UINT rdpdr_server_drive_create_directory_callback1(RdpdrServerContext* co } /* Send a request to close the file */ - return rdpdr_server_send_device_close_request(context, deviceId, fileId, irp->CompletionId); + return rdpdr_server_send_device_close_request(context, deviceId, fileId, + irp->CompletionId); } /** @@ -1688,10 +1729,10 @@ static UINT rdpdr_server_drive_create_directory_callback1(RdpdrServerContext* co * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_create_directory(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path) +static UINT rdpdr_server_drive_create_directory(RdpdrServerContext* context, + void* callbackData, UINT32 deviceId, const char* path) { RDPDR_IRP* irp; - irp = rdpdr_server_irp_new(); if (!irp) @@ -1705,7 +1746,6 @@ static UINT rdpdr_server_drive_create_directory(RdpdrServerContext* context, voi irp->CallbackData = callbackData; irp->DeviceId = deviceId; strncpy(irp->PathName, path, sizeof(irp->PathName)); - rdpdr_server_convert_slashes(irp->PathName, sizeof(irp->PathName)); if (!rdpdr_server_enqueue_irp(context, irp)) @@ -1716,8 +1756,10 @@ static UINT rdpdr_server_drive_create_directory(RdpdrServerContext* context, voi } /* Send a request to open the file. */ - return rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName, - FILE_READ_DATA | SYNCHRONIZE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, FILE_CREATE); + return rdpdr_server_send_device_create_request(context, deviceId, + irp->CompletionId, irp->PathName, + FILE_READ_DATA | SYNCHRONIZE, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, FILE_CREATE); } /************************************************* @@ -1729,17 +1771,17 @@ static UINT rdpdr_server_drive_create_directory(RdpdrServerContext* context, voi * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_delete_directory_callback2(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_delete_directory_callback2( + RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, + UINT32 completionId, UINT32 ioStatus) { - WLog_DBG(TAG, "RdpdrServerDriveDeleteDirectoryCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); - + WLog_DBG(TAG, + "RdpdrServerDriveDeleteDirectoryCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); /* Invoke the delete directory completion routine. */ context->OnDriveDeleteDirectoryComplete(context, irp->CallbackData, ioStatus); - /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -1748,22 +1790,22 @@ static UINT rdpdr_server_drive_delete_directory_callback2(RdpdrServerContext* co * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_delete_directory_callback1(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_delete_directory_callback1( + RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, + UINT32 completionId, UINT32 ioStatus) { UINT32 fileId; UINT8 information; - - WLog_DBG(TAG, "RdpdrServerDriveDeleteDirectoryCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveDeleteDirectoryCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (ioStatus != STATUS_SUCCESS) { /* Invoke the delete directory completion routine. */ context->OnDriveDeleteFileComplete(context, irp->CallbackData, ioStatus); - /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -1775,7 +1817,6 @@ static UINT rdpdr_server_drive_delete_directory_callback1(RdpdrServerContext* co Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ - /* Setup the IRP. */ irp->CompletionId = context->priv->NextCompletionId++; irp->Callback = rdpdr_server_drive_delete_directory_callback2; @@ -1790,7 +1831,8 @@ static UINT rdpdr_server_drive_delete_directory_callback1(RdpdrServerContext* co } /* Send a request to close the file */ - return rdpdr_server_send_device_close_request(context, deviceId, fileId, irp->CompletionId); + return rdpdr_server_send_device_close_request(context, deviceId, fileId, + irp->CompletionId); } /** @@ -1798,10 +1840,10 @@ static UINT rdpdr_server_drive_delete_directory_callback1(RdpdrServerContext* co * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_delete_directory(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path) +static UINT rdpdr_server_drive_delete_directory(RdpdrServerContext* context, + void* callbackData, UINT32 deviceId, const char* path) { RDPDR_IRP* irp; - irp = rdpdr_server_irp_new(); if (!irp) @@ -1815,7 +1857,6 @@ static UINT rdpdr_server_drive_delete_directory(RdpdrServerContext* context, voi irp->CallbackData = callbackData; irp->DeviceId = deviceId; strncpy(irp->PathName, path, sizeof(irp->PathName)); - rdpdr_server_convert_slashes(irp->PathName, sizeof(irp->PathName)); if (!rdpdr_server_enqueue_irp(context, irp)) @@ -1826,8 +1867,10 @@ static UINT rdpdr_server_drive_delete_directory(RdpdrServerContext* context, voi } /* Send a request to open the file. */ - return rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName, - DELETE | SYNCHRONIZE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE | FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN); + return rdpdr_server_send_device_create_request(context, deviceId, + irp->CompletionId, irp->PathName, + DELETE | SYNCHRONIZE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE | + FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN); } /************************************************* @@ -1839,14 +1882,16 @@ static UINT rdpdr_server_drive_delete_directory(RdpdrServerContext* context, voi * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_query_directory_callback2(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_query_directory_callback2( + RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, + UINT32 completionId, UINT32 ioStatus) { UINT error; UINT32 length; FILE_DIRECTORY_INFORMATION fdi; - - WLog_DBG(TAG, "RdpdrServerDriveQueryDirectoryCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveQueryDirectoryCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (Stream_GetRemainingLength(s) < 4) { @@ -1860,7 +1905,8 @@ static UINT rdpdr_server_drive_query_directory_callback2(RdpdrServerContext* con { if ((error = rdpdr_server_read_file_directory_information(s, &fdi))) { - WLog_ERR(TAG, "rdpdr_server_read_file_directory_information failed with error %lu!", error); + WLog_ERR(TAG, + "rdpdr_server_read_file_directory_information failed with error %u!", error); return error; } } @@ -1878,8 +1924,8 @@ static UINT rdpdr_server_drive_query_directory_callback2(RdpdrServerContext* con if (ioStatus == STATUS_SUCCESS) { /* Invoke the query directory completion routine. */ - context->OnDriveQueryDirectoryComplete(context, irp->CallbackData, ioStatus, length > 0 ? &fdi : NULL); - + context->OnDriveQueryDirectoryComplete(context, irp->CallbackData, ioStatus, + length > 0 ? &fdi : NULL); /* Setup the IRP. */ irp->CompletionId = context->priv->NextCompletionId++; irp->Callback = rdpdr_server_drive_query_directory_callback2; @@ -1892,13 +1938,14 @@ static UINT rdpdr_server_drive_query_directory_callback2(RdpdrServerContext* con } /* Send a request to query the directory. */ - return rdpdr_server_send_device_query_directory_request(context, irp->DeviceId, irp->FileId, irp->CompletionId, NULL); + return rdpdr_server_send_device_query_directory_request(context, irp->DeviceId, + irp->FileId, irp->CompletionId, NULL); } else { /* Invoke the query directory completion routine. */ - context->OnDriveQueryDirectoryComplete(context, irp->CallbackData, ioStatus, NULL); - + context->OnDriveQueryDirectoryComplete(context, irp->CallbackData, ioStatus, + NULL); /* Destroy the IRP. */ rdpdr_server_irp_free(irp); } @@ -1911,21 +1958,22 @@ static UINT rdpdr_server_drive_query_directory_callback2(RdpdrServerContext* con * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_query_directory_callback1(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_query_directory_callback1( + RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, + UINT32 completionId, UINT32 ioStatus) { UINT32 fileId; - - WLog_DBG(TAG, "RdpdrServerDriveQueryDirectoryCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveQueryDirectoryCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (ioStatus != STATUS_SUCCESS) { /* Invoke the query directory completion routine. */ - context->OnDriveQueryDirectoryComplete(context, irp->CallbackData, ioStatus, NULL); - + context->OnDriveQueryDirectoryComplete(context, irp->CallbackData, ioStatus, + NULL); /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -1936,13 +1984,11 @@ static UINT rdpdr_server_drive_query_directory_callback1(RdpdrServerContext* con } Stream_Read_UINT32(s, fileId); - /* Setup the IRP. */ irp->CompletionId = context->priv->NextCompletionId++; irp->Callback = rdpdr_server_drive_query_directory_callback2; irp->DeviceId = deviceId; irp->FileId = fileId; - strcat(irp->PathName, "\\*.*"); if (!rdpdr_server_enqueue_irp(context, irp)) @@ -1953,7 +1999,8 @@ static UINT rdpdr_server_drive_query_directory_callback1(RdpdrServerContext* con } /* Send a request to query the directory. */ - return rdpdr_server_send_device_query_directory_request(context, deviceId, fileId, irp->CompletionId, irp->PathName); + return rdpdr_server_send_device_query_directory_request(context, deviceId, + fileId, irp->CompletionId, irp->PathName); } /** @@ -1961,10 +2008,10 @@ static UINT rdpdr_server_drive_query_directory_callback1(RdpdrServerContext* con * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_query_directory(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path) +static UINT rdpdr_server_drive_query_directory(RdpdrServerContext* context, + void* callbackData, UINT32 deviceId, const char* path) { RDPDR_IRP* irp; - irp = rdpdr_server_irp_new(); if (!irp) @@ -1978,7 +2025,6 @@ static UINT rdpdr_server_drive_query_directory(RdpdrServerContext* context, void irp->CallbackData = callbackData; irp->DeviceId = deviceId; strncpy(irp->PathName, path, sizeof(irp->PathName)); - rdpdr_server_convert_slashes(irp->PathName, sizeof(irp->PathName)); if (!rdpdr_server_enqueue_irp(context, irp)) @@ -1989,8 +2035,10 @@ static UINT rdpdr_server_drive_query_directory(RdpdrServerContext* context, void } /* Send a request to open the directory. */ - return rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName, - FILE_READ_DATA | SYNCHRONIZE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN); + return rdpdr_server_send_device_create_request(context, deviceId, + irp->CompletionId, irp->PathName, + FILE_READ_DATA | SYNCHRONIZE, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN); } /************************************************* @@ -2002,13 +2050,15 @@ static UINT rdpdr_server_drive_query_directory(RdpdrServerContext* context, void * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_open_file_callback(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_open_file_callback(RdpdrServerContext* context, + wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, + UINT32 ioStatus) { UINT32 fileId; UINT8 information; - - WLog_DBG(TAG, "RdpdrServerDriveOpenFileCallback: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveOpenFileCallback: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (Stream_GetRemainingLength(s) < 5) { @@ -2018,13 +2068,11 @@ static UINT rdpdr_server_drive_open_file_callback(RdpdrServerContext* context, w Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ - /* Invoke the open file completion routine. */ - context->OnDriveOpenFileComplete(context, irp->CallbackData, ioStatus, deviceId, fileId); - + context->OnDriveOpenFileComplete(context, irp->CallbackData, ioStatus, deviceId, + fileId); /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -2033,10 +2081,11 @@ static UINT rdpdr_server_drive_open_file_callback(RdpdrServerContext* context, w * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_open_file(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path, UINT32 desiredAccess, UINT32 createDisposition) +static UINT rdpdr_server_drive_open_file(RdpdrServerContext* context, + void* callbackData, UINT32 deviceId, const char* path, UINT32 desiredAccess, + UINT32 createDisposition) { RDPDR_IRP* irp; - irp = rdpdr_server_irp_new(); if (!irp) @@ -2050,7 +2099,6 @@ static UINT rdpdr_server_drive_open_file(RdpdrServerContext* context, void* call irp->CallbackData = callbackData; irp->DeviceId = deviceId; strncpy(irp->PathName, path, sizeof(irp->PathName)); - rdpdr_server_convert_slashes(irp->PathName, sizeof(irp->PathName)); if (!rdpdr_server_enqueue_irp(context, irp)) @@ -2061,8 +2109,9 @@ static UINT rdpdr_server_drive_open_file(RdpdrServerContext* context, void* call } /* Send a request to open the file. */ - return rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName, - desiredAccess | SYNCHRONIZE, FILE_SYNCHRONOUS_IO_NONALERT, createDisposition); + return rdpdr_server_send_device_create_request(context, deviceId, + irp->CompletionId, irp->PathName, + desiredAccess | SYNCHRONIZE, FILE_SYNCHRONOUS_IO_NONALERT, createDisposition); } /************************************************* @@ -2074,13 +2123,15 @@ static UINT rdpdr_server_drive_open_file(RdpdrServerContext* context, void* call * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_read_file_callback(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_read_file_callback(RdpdrServerContext* context, + wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, + UINT32 ioStatus) { UINT32 length; char* buffer = NULL; - - WLog_DBG(TAG, "RdpdrServerDriveReadFileCallback: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveReadFileCallback: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (Stream_GetRemainingLength(s) < 4) { @@ -2103,11 +2154,10 @@ static UINT rdpdr_server_drive_read_file_callback(RdpdrServerContext* context, w } /* Invoke the read file completion routine. */ - context->OnDriveReadFileComplete(context, irp->CallbackData, ioStatus, buffer, length); - + context->OnDriveReadFileComplete(context, irp->CallbackData, ioStatus, buffer, + length); /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -2116,10 +2166,11 @@ static UINT rdpdr_server_drive_read_file_callback(RdpdrServerContext* context, w * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_read_file(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, UINT32 fileId, UINT32 length, UINT32 offset) +static UINT rdpdr_server_drive_read_file(RdpdrServerContext* context, + void* callbackData, UINT32 deviceId, UINT32 fileId, UINT32 length, + UINT32 offset) { RDPDR_IRP* irp; - irp = rdpdr_server_irp_new(); if (!irp) @@ -2142,7 +2193,8 @@ static UINT rdpdr_server_drive_read_file(RdpdrServerContext* context, void* call } /* Send a request to open the directory. */ - return rdpdr_server_send_device_read_request(context, deviceId, fileId, irp->CompletionId, length, offset); + return rdpdr_server_send_device_read_request(context, deviceId, fileId, + irp->CompletionId, length, offset); } /************************************************* @@ -2154,12 +2206,14 @@ static UINT rdpdr_server_drive_read_file(RdpdrServerContext* context, void* call * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_write_file_callback(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_write_file_callback(RdpdrServerContext* context, + wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, + UINT32 ioStatus) { UINT32 length; - - WLog_DBG(TAG, "RdpdrServerDriveWriteFileCallback: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveWriteFileCallback: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (Stream_GetRemainingLength(s) < 5) { @@ -2178,10 +2232,8 @@ static UINT rdpdr_server_drive_write_file_callback(RdpdrServerContext* context, /* Invoke the write file completion routine. */ context->OnDriveWriteFileComplete(context, irp->CallbackData, ioStatus, length); - /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -2190,10 +2242,11 @@ static UINT rdpdr_server_drive_write_file_callback(RdpdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_write_file(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, UINT32 fileId, const char* buffer, UINT32 length, UINT32 offset) +static UINT rdpdr_server_drive_write_file(RdpdrServerContext* context, + void* callbackData, UINT32 deviceId, UINT32 fileId, const char* buffer, + UINT32 length, UINT32 offset) { RDPDR_IRP* irp; - irp = rdpdr_server_irp_new(); if (!irp) @@ -2216,7 +2269,8 @@ static UINT rdpdr_server_drive_write_file(RdpdrServerContext* context, void* cal } /* Send a request to open the directory. */ - return rdpdr_server_send_device_write_request(context, deviceId, fileId, irp->CompletionId, buffer, length, offset); + return rdpdr_server_send_device_write_request(context, deviceId, fileId, + irp->CompletionId, buffer, length, offset); } /************************************************* @@ -2228,17 +2282,17 @@ static UINT rdpdr_server_drive_write_file(RdpdrServerContext* context, void* cal * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_close_file_callback(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_close_file_callback(RdpdrServerContext* context, + wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, + UINT32 ioStatus) { - WLog_DBG(TAG, "RdpdrServerDriveCloseFileCallback: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); - + WLog_DBG(TAG, + "RdpdrServerDriveCloseFileCallback: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); /* Invoke the close file completion routine. */ context->OnDriveCloseFileComplete(context, irp->CallbackData, ioStatus); - /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -2247,10 +2301,10 @@ static UINT rdpdr_server_drive_close_file_callback(RdpdrServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_close_file(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, UINT32 fileId) +static UINT rdpdr_server_drive_close_file(RdpdrServerContext* context, + void* callbackData, UINT32 deviceId, UINT32 fileId) { RDPDR_IRP* irp; - irp = rdpdr_server_irp_new(); if (!irp) @@ -2273,7 +2327,8 @@ static UINT rdpdr_server_drive_close_file(RdpdrServerContext* context, void* cal } /* Send a request to open the directory. */ - return rdpdr_server_send_device_close_request(context, deviceId, fileId, irp->CompletionId); + return rdpdr_server_send_device_close_request(context, deviceId, fileId, + irp->CompletionId); } /************************************************* @@ -2285,17 +2340,17 @@ static UINT rdpdr_server_drive_close_file(RdpdrServerContext* context, void* cal * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_delete_file_callback2(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_delete_file_callback2(RdpdrServerContext* + context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, + UINT32 ioStatus) { - WLog_DBG(TAG, "RdpdrServerDriveDeleteFileCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); - + WLog_DBG(TAG, + "RdpdrServerDriveDeleteFileCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); /* Invoke the delete file completion routine. */ context->OnDriveDeleteFileComplete(context, irp->CallbackData, ioStatus); - /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -2304,22 +2359,22 @@ static UINT rdpdr_server_drive_delete_file_callback2(RdpdrServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_delete_file_callback1(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_delete_file_callback1(RdpdrServerContext* + context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, + UINT32 ioStatus) { UINT32 fileId; UINT8 information; - - WLog_DBG(TAG, "RdpdrServerDriveDeleteFileCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveDeleteFileCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (ioStatus != STATUS_SUCCESS) { /* Invoke the close file completion routine. */ context->OnDriveDeleteFileComplete(context, irp->CallbackData, ioStatus); - /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -2331,7 +2386,6 @@ static UINT rdpdr_server_drive_delete_file_callback1(RdpdrServerContext* context Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ - /* Setup the IRP. */ irp->CompletionId = context->priv->NextCompletionId++; irp->Callback = rdpdr_server_drive_delete_file_callback2; @@ -2346,7 +2400,8 @@ static UINT rdpdr_server_drive_delete_file_callback1(RdpdrServerContext* context } /* Send a request to close the file */ - return rdpdr_server_send_device_close_request(context, deviceId, fileId, irp->CompletionId); + return rdpdr_server_send_device_close_request(context, deviceId, fileId, + irp->CompletionId); } /** @@ -2354,10 +2409,10 @@ static UINT rdpdr_server_drive_delete_file_callback1(RdpdrServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_delete_file(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path) +static UINT rdpdr_server_drive_delete_file(RdpdrServerContext* context, + void* callbackData, UINT32 deviceId, const char* path) { RDPDR_IRP* irp; - irp = rdpdr_server_irp_new(); if (!irp) @@ -2371,7 +2426,6 @@ static UINT rdpdr_server_drive_delete_file(RdpdrServerContext* context, void* ca irp->CallbackData = callbackData; irp->DeviceId = deviceId; strncpy(irp->PathName, path, sizeof(irp->PathName)); - rdpdr_server_convert_slashes(irp->PathName, sizeof(irp->PathName)); if (!rdpdr_server_enqueue_irp(context, irp)) @@ -2382,9 +2436,10 @@ static UINT rdpdr_server_drive_delete_file(RdpdrServerContext* context, void* ca } /* Send a request to open the file. */ - return rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName, - FILE_READ_DATA | SYNCHRONIZE, FILE_DELETE_ON_CLOSE | FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN); - + return rdpdr_server_send_device_create_request(context, deviceId, + irp->CompletionId, irp->PathName, + FILE_READ_DATA | SYNCHRONIZE, + FILE_DELETE_ON_CLOSE | FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN); } /************************************************* @@ -2396,14 +2451,15 @@ static UINT rdpdr_server_drive_delete_file(RdpdrServerContext* context, void* ca * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_rename_file_callback3(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_rename_file_callback3(RdpdrServerContext* + context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, + UINT32 ioStatus) { - WLog_DBG(TAG, "RdpdrServerDriveRenameFileCallback3: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); - + WLog_DBG(TAG, + "RdpdrServerDriveRenameFileCallback3: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -2412,12 +2468,14 @@ static UINT rdpdr_server_drive_rename_file_callback3(RdpdrServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_rename_file_callback2(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_rename_file_callback2(RdpdrServerContext* + context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, + UINT32 ioStatus) { UINT32 length; - - WLog_DBG(TAG, "RdpdrServerDriveRenameFileCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveRenameFileCallback2: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (Stream_GetRemainingLength(s) < 5) { @@ -2427,10 +2485,8 @@ static UINT rdpdr_server_drive_rename_file_callback2(RdpdrServerContext* context Stream_Read_UINT32(s, length); /* Length (4 bytes) */ Stream_Seek(s, 1); /* Padding (1 byte) */ - /* Invoke the rename file completion routine. */ context->OnDriveRenameFileComplete(context, irp->CallbackData, ioStatus); - /* Setup the IRP. */ irp->CompletionId = context->priv->NextCompletionId++; irp->Callback = rdpdr_server_drive_rename_file_callback3; @@ -2444,7 +2500,8 @@ static UINT rdpdr_server_drive_rename_file_callback2(RdpdrServerContext* context } /* Send a request to close the file */ - return rdpdr_server_send_device_close_request(context, deviceId, irp->FileId, irp->CompletionId); + return rdpdr_server_send_device_close_request(context, deviceId, irp->FileId, + irp->CompletionId); } /** @@ -2452,22 +2509,22 @@ static UINT rdpdr_server_drive_rename_file_callback2(RdpdrServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_rename_file_callback1(RdpdrServerContext* context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus) +static UINT rdpdr_server_drive_rename_file_callback1(RdpdrServerContext* + context, wStream* s, RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, + UINT32 ioStatus) { UINT32 fileId; UINT8 information; - - WLog_DBG(TAG, "RdpdrServerDriveRenameFileCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", - deviceId, completionId, ioStatus); + WLog_DBG(TAG, + "RdpdrServerDriveRenameFileCallback1: deviceId=%d, completionId=%d, ioStatus=0x%x", + deviceId, completionId, ioStatus); if (ioStatus != STATUS_SUCCESS) { /* Invoke the rename file completion routine. */ context->OnDriveRenameFileComplete(context, irp->CallbackData, ioStatus); - /* Destroy the IRP. */ rdpdr_server_irp_free(irp); - return CHANNEL_RC_OK; } @@ -2479,7 +2536,6 @@ static UINT rdpdr_server_drive_rename_file_callback1(RdpdrServerContext* context Stream_Read_UINT32(s, fileId); /* FileId (4 bytes) */ Stream_Read_UINT8(s, information); /* Information (1 byte) */ - /* Setup the IRP. */ irp->CompletionId = context->priv->NextCompletionId++; irp->Callback = rdpdr_server_drive_rename_file_callback2; @@ -2494,7 +2550,8 @@ static UINT rdpdr_server_drive_rename_file_callback1(RdpdrServerContext* context } /* Send a request to rename the file */ - return rdpdr_server_send_device_file_rename_request(context, deviceId, fileId, irp->CompletionId, irp->ExtraBuffer); + return rdpdr_server_send_device_file_rename_request(context, deviceId, fileId, + irp->CompletionId, irp->ExtraBuffer); } /** @@ -2502,10 +2559,10 @@ static UINT rdpdr_server_drive_rename_file_callback1(RdpdrServerContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpdr_server_drive_rename_file(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* oldPath, const char* newPath) +static UINT rdpdr_server_drive_rename_file(RdpdrServerContext* context, + void* callbackData, UINT32 deviceId, const char* oldPath, const char* newPath) { RDPDR_IRP* irp; - irp = rdpdr_server_irp_new(); if (!irp) @@ -2520,7 +2577,6 @@ static UINT rdpdr_server_drive_rename_file(RdpdrServerContext* context, void* ca irp->DeviceId = deviceId; strncpy(irp->PathName, oldPath, sizeof(irp->PathName)); strncpy(irp->ExtraBuffer, newPath, sizeof(irp->ExtraBuffer)); - rdpdr_server_convert_slashes(irp->PathName, sizeof(irp->PathName)); rdpdr_server_convert_slashes(irp->ExtraBuffer, sizeof(irp->ExtraBuffer)); @@ -2532,23 +2588,21 @@ static UINT rdpdr_server_drive_rename_file(RdpdrServerContext* context, void* ca } /* Send a request to open the file. */ - return rdpdr_server_send_device_create_request(context, deviceId, irp->CompletionId, irp->PathName, - FILE_READ_DATA | SYNCHRONIZE, FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN); + return rdpdr_server_send_device_create_request(context, deviceId, + irp->CompletionId, irp->PathName, + FILE_READ_DATA | SYNCHRONIZE, FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN); } RdpdrServerContext* rdpdr_server_context_new(HANDLE vcm) { RdpdrServerContext* context; - context = (RdpdrServerContext*) calloc(1, sizeof(RdpdrServerContext)); if (context) { context->vcm = vcm; - context->Start = rdpdr_server_start; context->Stop = rdpdr_server_stop; - context->DriveCreateDirectory = rdpdr_server_drive_create_directory; context->DriveDeleteDirectory = rdpdr_server_drive_delete_directory; context->DriveQueryDirectory = rdpdr_server_drive_query_directory; @@ -2558,7 +2612,6 @@ RdpdrServerContext* rdpdr_server_context_new(HANDLE vcm) context->DriveCloseFile = rdpdr_server_drive_close_file; context->DriveDeleteFile = rdpdr_server_drive_delete_file; context->DriveRenameFile = rdpdr_server_drive_rename_file; - context->priv = (RdpdrServerPrivate*) calloc(1, sizeof(RdpdrServerPrivate)); if (!context->priv) @@ -2573,7 +2626,6 @@ RdpdrServerContext* rdpdr_server_context_new(HANDLE vcm) context->priv->ClientId = g_ClientId++; context->priv->UserLoggedOnPdu = TRUE; context->priv->NextCompletionId = 1; - context->priv->IrpList = ListDictionary_New(TRUE); if (!context->priv->IrpList) @@ -2599,7 +2651,6 @@ void rdpdr_server_context_free(RdpdrServerContext* context) if (context->priv) { ListDictionary_Free(context->priv->IrpList); - free(context->priv); } diff --git a/channels/rdpei/client/CMakeLists.txt b/channels/rdpei/client/CMakeLists.txt index 723cbc0..79cc5a1 100644 --- a/channels/rdpei/client/CMakeLists.txt +++ b/channels/rdpei/client/CMakeLists.txt @@ -31,7 +31,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE target_link_libraries(${MODULE_NAME} winpr freerdp) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 6acfcc7..559ab77 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -138,16 +138,16 @@ UINT rdpei_add_frame(RdpeiClientContext* context) int i; RDPINPUT_CONTACT_DATA* contact; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; - rdpei->frame.contactCount = 0; for (i = 0; i < rdpei->maxTouchContacts; i++) { - contact = (RDPINPUT_CONTACT_DATA*) &(rdpei->contactPoints[i].data); + contact = (RDPINPUT_CONTACT_DATA*) & (rdpei->contactPoints[i].data); if (rdpei->contactPoints[i].dirty) { - CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA)); + CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, + sizeof(RDPINPUT_CONTACT_DATA)); rdpei->contactPoints[i].dirty = FALSE; rdpei->frame.contactCount++; } @@ -160,7 +160,8 @@ UINT rdpei_add_frame(RdpeiClientContext* context) contact->contactFlags |= CONTACT_FLAG_INCONTACT; } - CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA)); + CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, + sizeof(RDPINPUT_CONTACT_DATA)); rdpei->frame.contactCount++; } } @@ -182,7 +183,6 @@ static void* rdpei_schedule_thread(void* arg) goto out; } - if (!context) { error = ERROR_INVALID_PARAMETER; @@ -193,12 +193,12 @@ static void* rdpei_schedule_thread(void* arg) { status = WaitForMultipleObjects(2, hdl, FALSE, 20); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error); + break; + } if (status == WAIT_OBJECT_0 + 1) break; @@ -207,7 +207,7 @@ static void* rdpei_schedule_thread(void* arg) if ((error = rdpei_add_frame(context))) { - WLog_ERR(TAG, "rdpei_add_frame failed with error %lu!", error); + WLog_ERR(TAG, "rdpei_add_frame failed with error %u!", error); break; } @@ -215,7 +215,7 @@ static void* rdpei_schedule_thread(void* arg) { if ((error = rdpei_send_frame(context))) { - WLog_ERR(TAG, "rdpei_send_frame failed with error %lu!", error); + WLog_ERR(TAG, "rdpei_send_frame failed with error %u!", error); break; } } @@ -227,11 +227,12 @@ static void* rdpei_schedule_thread(void* arg) } out: + if (error && rdpei->rdpcontext) - setChannelError(rdpei->rdpcontext, error, "rdpei_schedule_thread reported an error"); + setChannelError(rdpei->rdpcontext, error, + "rdpei_schedule_thread reported an error"); ExitThread(0); - return NULL; } @@ -240,22 +241,20 @@ out: * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, UINT32 pduLength) +UINT rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, + UINT16 eventId, UINT32 pduLength) { UINT status; - Stream_SetPosition(s, 0); Stream_Write_UINT16(s, eventId); /* eventId (2 bytes) */ Stream_Write_UINT32(s, pduLength); /* pduLength (4 bytes) */ Stream_SetPosition(s, Stream_Length(s)); - - status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); - + status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), + Stream_Buffer(s), NULL); #ifdef WITH_DEBUG_RDPEI WLog_DBG(TAG, "rdpei_send_pdu: eventId: %d (%s) length: %d status: %d", - eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength, status); + eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength, status); #endif - return status; } @@ -271,29 +270,26 @@ UINT rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback) UINT32 flags; UINT32 pduLength; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) callback->plugin; - flags = 0; flags |= READY_FLAGS_SHOW_TOUCH_VISUALS; //flags |= READY_FLAGS_DISABLE_TIMESTAMP_INJECTION; - pduLength = RDPINPUT_HEADER_LENGTH + 10; s = Stream_New(NULL, pduLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } - Stream_Seek(s, RDPINPUT_HEADER_LENGTH); + Stream_Seek(s, RDPINPUT_HEADER_LENGTH); Stream_Write_UINT32(s, flags); /* flags (4 bytes) */ Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V10); /* protocolVersion (4 bytes) */ - Stream_Write_UINT16(s, rdpei->maxTouchContacts); /* maxTouchContacts (2 bytes) */ - + Stream_Write_UINT16(s, + rdpei->maxTouchContacts); /* maxTouchContacts (2 bytes) */ Stream_SealLength(s); - status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength); Stream_Free(s, TRUE); - return status; } @@ -328,19 +324,18 @@ UINT rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) UINT32 index; int rectSize = 2; RDPINPUT_CONTACT_DATA* contact; - #ifdef WITH_DEBUG_RDPEI WLog_DBG(TAG, "contactCount: %d", frame->contactCount); WLog_DBG(TAG, "frameOffset: 0x%08X", (UINT32) frame->frameOffset); #endif - - rdpei_write_2byte_unsigned(s, frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */ - + rdpei_write_2byte_unsigned(s, + frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */ /** * the time offset from the previous frame (in microseconds). * If this is the first frame being transmitted then this field MUST be set to zero. */ - rdpei_write_8byte_unsigned(s, frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */ + rdpei_write_8byte_unsigned(s, + frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */ if (!Stream_EnsureRemainingCapacity(s, (size_t) frame->contactCount * 64)) { @@ -351,13 +346,11 @@ UINT rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) for (index = 0; index < frame->contactCount; index++) { contact = &frame->contacts[index]; - contact->fieldsPresent |= CONTACT_DATA_CONTACTRECT_PRESENT; contact->contactRectLeft = contact->x - rectSize; contact->contactRectTop = contact->y - rectSize; contact->contactRectRight = contact->x + rectSize; contact->contactRectBottom = contact->y + rectSize; - #ifdef WITH_DEBUG_RDPEI WLog_DBG(TAG, "contact[%d].contactId: %d", index, contact->contactId); WLog_DBG(TAG, "contact[%d].fieldsPresent: %d", index, contact->fieldsPresent); @@ -366,15 +359,11 @@ UINT rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) WLog_DBG(TAG, "contact[%d].contactFlags: 0x%04X", index, contact->contactFlags); rdpei_print_contact_flags(contact->contactFlags); #endif - Stream_Write_UINT8(s, contact->contactId); /* contactId (1 byte) */ - /* fieldsPresent (TWO_BYTE_UNSIGNED_INTEGER) */ rdpei_write_2byte_unsigned(s, contact->fieldsPresent); - rdpei_write_4byte_signed(s, contact->x); /* x (FOUR_BYTE_SIGNED_INTEGER) */ rdpei_write_4byte_signed(s, contact->y); /* y (FOUR_BYTE_SIGNED_INTEGER) */ - /* contactFlags (FOUR_BYTE_UNSIGNED_INTEGER) */ rdpei_write_4byte_unsigned(s, contact->contactFlags); @@ -411,43 +400,41 @@ UINT rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_FRAME* frame) +UINT rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, + RDPINPUT_TOUCH_FRAME* frame) { UINT status; wStream* s; UINT32 pduLength; - pduLength = 64 + (frame->contactCount * 64); - s = Stream_New(NULL, pduLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } - Stream_Seek(s, RDPINPUT_HEADER_LENGTH); + Stream_Seek(s, RDPINPUT_HEADER_LENGTH); /** * the time that has elapsed (in milliseconds) from when the oldest touch frame * was generated to when it was encoded for transmission by the client. */ - rdpei_write_4byte_unsigned(s, (UINT32) frame->frameOffset); /* encodeTime (FOUR_BYTE_UNSIGNED_INTEGER) */ - + rdpei_write_4byte_unsigned(s, + (UINT32) frame->frameOffset); /* encodeTime (FOUR_BYTE_UNSIGNED_INTEGER) */ rdpei_write_2byte_unsigned(s, 1); /* (frameCount) TWO_BYTE_UNSIGNED_INTEGER */ if ((status = rdpei_write_touch_frame(s, frame))) { - WLog_ERR(TAG, "rdpei_write_touch_frame failed with error %lu!", status); + WLog_ERR(TAG, "rdpei_write_touch_frame failed with error %u!", status); Stream_Free(s, TRUE); return status; } Stream_SealLength(s); pduLength = Stream_Length(s); - status = rdpei_send_pdu(callback, s, EVENTID_TOUCH, pduLength); Stream_Free(s, TRUE); - return status; } @@ -459,17 +446,16 @@ UINT rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH UINT rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) { UINT32 protocolVersion; - Stream_Read_UINT32(s, protocolVersion); /* protocolVersion (4 bytes) */ - #if 0 + if (protocolVersion != RDPINPUT_PROTOCOL_V10) { WLog_ERR(TAG, "Unknown [MS-RDPEI] protocolVersion: 0x%08X", protocolVersion); return -1; } -#endif +#endif return CHANNEL_RC_OK; } @@ -482,10 +468,10 @@ UINT rdpei_recv_suspend_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) { RdpeiClientContext* rdpei = (RdpeiClientContext*) callback->plugin->pInterface; UINT error = CHANNEL_RC_OK; - IFCALLRET(rdpei->SuspendTouch, error, rdpei); + if (error) - WLog_ERR(TAG, "rdpei->SuspendTouch failed with error %lu!", error); + WLog_ERR(TAG, "rdpei->SuspendTouch failed with error %u!", error); return error; } @@ -499,10 +485,10 @@ UINT rdpei_recv_resume_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) { RdpeiClientContext* rdpei = (RdpeiClientContext*) callback->plugin->pInterface; UINT error = CHANNEL_RC_OK; - IFCALLRET(rdpei->ResumeTouch, error, rdpei); + if (error) - WLog_ERR(TAG, "rdpei->ResumeTouch failed with error %lu!", error); + WLog_ERR(TAG, "rdpei->ResumeTouch failed with error %u!", error); return error; } @@ -517,13 +503,11 @@ UINT rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) UINT16 eventId; UINT32 pduLength; UINT error; - Stream_Read_UINT16(s, eventId); /* eventId (2 bytes) */ Stream_Read_UINT32(s, pduLength); /* pduLength (4 bytes) */ - #ifdef WITH_DEBUG_RDPEI WLog_DBG(TAG, "rdpei_recv_pdu: eventId: %d (%s) length: %d", - eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength); + eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength); #endif switch (eventId) @@ -531,30 +515,34 @@ UINT rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) case EVENTID_SC_READY: if ((error = rdpei_recv_sc_ready_pdu(callback, s))) { - WLog_ERR(TAG, "rdpei_recv_sc_ready_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpei_recv_sc_ready_pdu failed with error %u!", error); return error; } + if ((error = rdpei_send_cs_ready_pdu(callback))) { - WLog_ERR(TAG, "rdpei_send_cs_ready_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpei_send_cs_ready_pdu failed with error %u!", error); return error; } + break; case EVENTID_SUSPEND_TOUCH: if ((error = rdpei_recv_suspend_touch_pdu(callback, s))) { - WLog_ERR(TAG, "rdpei_recv_suspend_touch_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpei_recv_suspend_touch_pdu failed with error %u!", error); return error; } + break; case EVENTID_RESUME_TOUCH: if ((error = rdpei_recv_resume_touch_pdu(callback, s))) { - WLog_ERR(TAG, "rdpei_recv_resume_touch_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpei_recv_resume_touch_pdu failed with error %u!", error); return error; } + break; default: @@ -569,10 +557,10 @@ UINT rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream *data) +static UINT rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, + wStream* data) { RDPEI_CHANNEL_CALLBACK* callback = (RDPEI_CHANNEL_CALLBACK*) pChannelCallback; - return rdpei_recv_pdu(callback, data); } @@ -584,9 +572,7 @@ static UINT rdpei_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, static UINT rdpei_on_close(IWTSVirtualChannelCallback* pChannelCallback) { RDPEI_CHANNEL_CALLBACK* callback = (RDPEI_CHANNEL_CALLBACK*) pChannelCallback; - free(callback); - return CHANNEL_RC_OK; } @@ -595,17 +581,19 @@ static UINT rdpei_on_close(IWTSVirtualChannelCallback* pChannelCallback) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpei_on_new_channel_connection(IWTSListenerCallback* pListenerCallback, - IWTSVirtualChannel* pChannel, BYTE* Data, BOOL* pbAccept, - IWTSVirtualChannelCallback** ppCallback) +static UINT rdpei_on_new_channel_connection(IWTSListenerCallback* + pListenerCallback, + IWTSVirtualChannel* pChannel, BYTE* Data, BOOL* pbAccept, + IWTSVirtualChannelCallback** ppCallback) { RDPEI_CHANNEL_CALLBACK* callback; - RDPEI_LISTENER_CALLBACK* listener_callback = (RDPEI_LISTENER_CALLBACK*) pListenerCallback; - + RDPEI_LISTENER_CALLBACK* listener_callback = (RDPEI_LISTENER_CALLBACK*) + pListenerCallback; callback = (RDPEI_CHANNEL_CALLBACK*) calloc(1, sizeof(RDPEI_CHANNEL_CALLBACK)); + if (!callback) { - WLog_ERR(TAG,"calloc failed!"); + WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } @@ -615,9 +603,7 @@ static UINT rdpei_on_new_channel_connection(IWTSListenerCallback* pListenerCallb callback->channel_mgr = listener_callback->channel_mgr; callback->channel = pChannel; listener_callback->channel_callback = callback; - *ppCallback = (IWTSVirtualChannelCallback*) callback; - return CHANNEL_RC_OK; } @@ -626,52 +612,52 @@ static UINT rdpei_on_new_channel_connection(IWTSListenerCallback* pListenerCallb * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr) +static UINT rdpei_plugin_initialize(IWTSPlugin* pPlugin, + IWTSVirtualChannelManager* pChannelMgr) { UINT error; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) pPlugin; + rdpei->listener_callback = (RDPEI_LISTENER_CALLBACK*) calloc(1 , + sizeof(RDPEI_LISTENER_CALLBACK)); - rdpei->listener_callback = (RDPEI_LISTENER_CALLBACK*) calloc(1 ,sizeof(RDPEI_LISTENER_CALLBACK)); if (!rdpei->listener_callback) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } - rdpei->listener_callback->iface.OnNewChannelConnection = rdpei_on_new_channel_connection; + rdpei->listener_callback->iface.OnNewChannelConnection = + rdpei_on_new_channel_connection; rdpei->listener_callback->plugin = pPlugin; rdpei->listener_callback->channel_mgr = pChannelMgr; if ((error = pChannelMgr->CreateListener(pChannelMgr, RDPEI_DVC_CHANNEL_NAME, 0, - (IWTSListenerCallback*) rdpei->listener_callback, &(rdpei->listener)))) + (IWTSListenerCallback*) rdpei->listener_callback, &(rdpei->listener)))) { - WLog_ERR(TAG, "ChannelMgr->CreateListener failed with error %lu!", error); + WLog_ERR(TAG, "ChannelMgr->CreateListener failed with error %u!", error); goto error_out; } rdpei->listener->pInterface = rdpei->iface.pInterface; - InitializeCriticalSection(&rdpei->lock); + if (!(rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL))) { WLog_ERR(TAG, "CreateEvent failed!"); goto error_out; - } if (!(rdpei->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { WLog_ERR(TAG, "CreateEvent failed!"); goto error_out; - } if (!(rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) - rdpei_schedule_thread, (void*) rdpei, 0, NULL))) + rdpei_schedule_thread, (void*) rdpei, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); goto error_out; - } return error; @@ -690,7 +676,7 @@ error_out: static UINT rdpei_plugin_terminated(IWTSPlugin* pPlugin) { RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) pPlugin; - UINT error; + UINT error; if (!pPlugin) return ERROR_INVALID_PARAMETER; @@ -699,22 +685,19 @@ static UINT rdpei_plugin_terminated(IWTSPlugin* pPlugin) EnterCriticalSection(&rdpei->lock); if (WaitForSingleObject(rdpei->thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + return error; + } CloseHandle(rdpei->stopEvent); CloseHandle(rdpei->event); CloseHandle(rdpei->thread); - DeleteCriticalSection(&rdpei->lock); - free(rdpei->listener_callback); free(rdpei->context); free(rdpei); - return CHANNEL_RC_OK; } @@ -739,7 +722,6 @@ UINT rdpei_send_frame(RdpeiClientContext* context) RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; RDPEI_CHANNEL_CALLBACK* callback = rdpei->listener_callback->channel_callback; UINT error; - currentTime = GetTickCount64(); if (!rdpei->previousFrameTime && !rdpei->currentFrameTime) @@ -755,12 +737,12 @@ UINT rdpei_send_frame(RdpeiClientContext* context) if ((error = rdpei_send_touch_event_pdu(callback, &rdpei->frame))) { - WLog_ERR(TAG, "rdpei_send_touch_event_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpei_send_touch_event_pdu failed with error %u!", error); return error; } + rdpei->previousFrameTime = rdpei->currentFrameTime; rdpei->frame.contactCount = 0; - return error; } @@ -769,21 +751,18 @@ UINT rdpei_send_frame(RdpeiClientContext* context) * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact) +UINT rdpei_add_contact(RdpeiClientContext* context, + RDPINPUT_CONTACT_DATA* contact) { RDPINPUT_CONTACT_POINT* contactPoint; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; - EnterCriticalSection(&rdpei->lock); - - contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[contact->contactId]; + contactPoint = (RDPINPUT_CONTACT_POINT*) + &rdpei->contactPoints[contact->contactId]; CopyMemory(&(contactPoint->data), contact, sizeof(RDPINPUT_CONTACT_DATA)); contactPoint->dirty = TRUE; - SetEvent(rdpei->event); - LeaveCriticalSection(&rdpei->lock); - return CHANNEL_RC_OK; } @@ -792,7 +771,8 @@ UINT rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* conta * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x, int y, int* contactId) +UINT rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x, + int y, int* contactId) { unsigned int i; int contactIdlocal = -1; @@ -821,20 +801,17 @@ UINT rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x, int y if (contactIdlocal >= 0) { ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA)); - contactPoint->lastX = x; contactPoint->lastY = y; - contact.x = x; contact.y = y; contact.contactId = (UINT32) contactIdlocal; - contact.contactFlags |= CONTACT_FLAG_DOWN; contact.contactFlags |= CONTACT_FLAG_INRANGE; contact.contactFlags |= CONTACT_FLAG_INCONTACT; - error = context->AddContact(context, &contact); } + *contactId = contactIdlocal; return error; } @@ -844,7 +821,8 @@ UINT rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x, int y * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpei_touch_update(RdpeiClientContext* context, int externalId, int x, int y, int* contactId) +UINT rdpei_touch_update(RdpeiClientContext* context, int externalId, int x, + int y, int* contactId) { unsigned int i; int contactIdlocal = -1; @@ -870,23 +848,18 @@ UINT rdpei_touch_update(RdpeiClientContext* context, int externalId, int x, int if (contactIdlocal >= 0) { ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA)); - contactPoint->lastX = x; contactPoint->lastY = y; - contact.x = x; contact.y = y; contact.contactId = (UINT32) contactIdlocal; - contact.contactFlags |= CONTACT_FLAG_UPDATE; contact.contactFlags |= CONTACT_FLAG_INRANGE; contact.contactFlags |= CONTACT_FLAG_INCONTACT; - error = context->AddContact(context, &contact); } *contactId = contactIdlocal; - return error; } @@ -895,7 +868,8 @@ UINT rdpei_touch_update(RdpeiClientContext* context, int externalId, int x, int * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y, int* contactId) +UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y, + int* contactId) { unsigned int i; int contactIdlocal = -1; @@ -927,7 +901,7 @@ UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y, { if ((error = context->TouchUpdate(context, externalId, x, y, &tempvalue))) { - WLog_ERR(TAG, "context->TouchUpdate failed with error %lu!", error); + WLog_ERR(TAG, "context->TouchUpdate failed with error %u!", error); return error; } } @@ -935,12 +909,11 @@ UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y, contact.x = x; contact.y = y; contact.contactId = (UINT32) contactIdlocal; - contact.contactFlags |= CONTACT_FLAG_UP; if ((error = context->AddContact(context, &contact))) { - WLog_ERR(TAG, "context->AddContact failed with error %lu!", error); + WLog_ERR(TAG, "context->AddContact failed with error %u!", error); return error; } @@ -950,12 +923,12 @@ UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y, contactPoint->contactId = 0; contactPoint->state = RDPINPUT_CONTACT_STATE_OUT_OF_RANGE; } - *contactId = contactIdlocal; + *contactId = contactIdlocal; return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DVCPluginEntry rdpei_DVCPluginEntry #else #define DVCPluginEntry FREERDP_API DVCPluginEntry @@ -971,15 +944,14 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) UINT error; RDPEI_PLUGIN* rdpei = NULL; RdpeiClientContext* context = NULL; - rdpei = (RDPEI_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "rdpei"); if (!rdpei) { size_t size; - rdpei = (RDPEI_PLUGIN*) calloc(1, sizeof(RDPEI_PLUGIN)); - if(!rdpei) + + if (!rdpei) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; @@ -989,18 +961,15 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) rdpei->iface.Connected = NULL; rdpei->iface.Disconnected = NULL; rdpei->iface.Terminated = rdpei_plugin_terminated; - rdpei->version = 1; rdpei->currentFrameTime = 0; rdpei->previousFrameTime = 0; rdpei->frame.contacts = (RDPINPUT_CONTACT_DATA*) rdpei->contacts; - rdpei->maxTouchContacts = 10; size = rdpei->maxTouchContacts * sizeof(RDPINPUT_CONTACT_POINT); rdpei->contactPoints = (RDPINPUT_CONTACT_POINT*) calloc(1, size); - - rdpei->rdpcontext = ((freerdp*)((rdpSettings*) pEntryPoints->GetRdpSettings(pEntryPoints))->instance)->context; - + rdpei->rdpcontext = ((freerdp*)((rdpSettings*) pEntryPoints->GetRdpSettings( + pEntryPoints))->instance)->context; if (!rdpei->contactPoints) { @@ -1010,6 +979,7 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) } context = (RdpeiClientContext*) calloc(1, sizeof(RdpeiClientContext)); + if (!context) { WLog_ERR(TAG, "calloc failed!"); @@ -1020,16 +990,15 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) context->handle = (void*) rdpei; context->GetVersion = rdpei_get_version; context->AddContact = rdpei_add_contact; - context->TouchBegin = rdpei_touch_begin; context->TouchUpdate = rdpei_touch_update; context->TouchEnd = rdpei_touch_end; - rdpei->iface.pInterface = (void*) context; - if ((error = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpei", (IWTSPlugin*) rdpei))) + if ((error = pEntryPoints->RegisterPlugin(pEntryPoints, "rdpei", + (IWTSPlugin*) rdpei))) { - WLog_ERR(TAG, "EntryPoints->RegisterPlugin failed with error %lu!", error); + WLog_ERR(TAG, "EntryPoints->RegisterPlugin failed with error %u!", error); error = CHANNEL_RC_NO_MEMORY; goto error_out; } diff --git a/channels/rdpei/client/rdpei_main.h b/channels/rdpei/client/rdpei_main.h index bc7c63d..4dc4998 100644 --- a/channels/rdpei/client/rdpei_main.h +++ b/channels/rdpei/client/rdpei_main.h @@ -82,9 +82,9 @@ struct _RDPINPUT_CONTACT_POINT typedef struct _RDPINPUT_CONTACT_POINT RDPINPUT_CONTACT_POINT; #ifdef WITH_DEBUG_DVC -#define DEBUG_DVC(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__) +#define DEBUG_DVC(...) WLog_DBG(TAG, __VA_ARGS__) #else -#define DEBUG_DVC(fmt, ...) do { } while (0) +#define DEBUG_DVC(...) do { } while (0) #endif #endif /* FREERDP_CHANNEL_RDPEI_CLIENT_MAIN_H */ diff --git a/channels/rdpei/server/rdpei_main.c b/channels/rdpei/server/rdpei_main.c index cd17086..e015796 100644 --- a/channels/rdpei/server/rdpei_main.c +++ b/channels/rdpei/server/rdpei_main.c @@ -185,7 +185,7 @@ static UINT read_cs_ready_message(RdpeiServerContext *context, wStream *s) IFCALLRET(context->onClientReady, error, context); if (error) - WLog_ERR(TAG, "context->onClientReady failed with error %lu", error); + WLog_ERR(TAG, "context->onClientReady failed with error %u", error); return error; } @@ -271,7 +271,7 @@ static UINT read_touch_frame(RdpeiServerContext *context, wStream *s, RDPINPUT_T { if ((error = read_touch_contact_data(context, s, contact))) { - WLog_ERR(TAG, "read_touch_contact_data failed with error %lu!", error); + WLog_ERR(TAG, "read_touch_contact_data failed with error %u!", error); frame->contactCount = i; touch_frame_reset(frame); return error; @@ -311,7 +311,7 @@ static UINT read_touch_event(RdpeiServerContext *context, wStream *s) { if ((error = read_touch_frame(context, s, frame))) { - WLog_ERR(TAG, "read_touch_contact_data failed with error %lu!", error); + WLog_ERR(TAG, "read_touch_contact_data failed with error %u!", error); event->frameCount = i; goto out_cleanup; } @@ -320,7 +320,7 @@ static UINT read_touch_event(RdpeiServerContext *context, wStream *s) IFCALLRET(context->onTouchEvent, error, context, event); if (error) - WLog_ERR(TAG, "context->onTouchEvent failed with error %lu", error); + WLog_ERR(TAG, "context->onTouchEvent failed with error %u", error); out_cleanup: touch_event_reset(event); @@ -347,7 +347,7 @@ static UINT read_dismiss_hovering_contact(RdpeiServerContext *context, wStream * IFCALLRET(context->onTouchReleased, error, context, contactId); if (error) - WLog_ERR(TAG, "context->onTouchReleased failed with error %lu", error); + WLog_ERR(TAG, "context->onTouchReleased failed with error %u", error); return error; } @@ -420,7 +420,7 @@ UINT rdpei_server_handle_messages(RdpeiServerContext *context) { if ((error = read_cs_ready_message(context, s))) { - WLog_ERR(TAG, "read_cs_ready_message failed with error %lu", error); + WLog_ERR(TAG, "read_cs_ready_message failed with error %u", error); return error; } break; @@ -428,14 +428,14 @@ UINT rdpei_server_handle_messages(RdpeiServerContext *context) { case EVENTID_TOUCH: if ((error = read_touch_event(context, s))) { - WLog_ERR(TAG, "read_touch_event failed with error %lu", error); + WLog_ERR(TAG, "read_touch_event failed with error %u", error); return error; } break; case EVENTID_DISMISS_HOVERING_CONTACT: if ((error = read_dismiss_hovering_contact(context, s))) { - WLog_ERR(TAG, "read_dismiss_hovering_contact failed with error %lu", error); + WLog_ERR(TAG, "read_dismiss_hovering_contact failed with error %u", error); return error; } break; diff --git a/channels/rdpgfx/CMakeLists.txt b/channels/rdpgfx/CMakeLists.txt index acc50da..04820de 100644 --- a/channels/rdpgfx/CMakeLists.txt +++ b/channels/rdpgfx/CMakeLists.txt @@ -21,3 +21,6 @@ if(WITH_CLIENT_CHANNELS) add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME}) endif() +if(WITH_SERVER_CHANNELS) + add_channel_server(${MODULE_PREFIX} ${CHANNEL_NAME}) +endif() diff --git a/channels/rdpgfx/client/CMakeLists.txt b/channels/rdpgfx/client/CMakeLists.txt index 1dbf82f..0de358a 100644 --- a/channels/rdpgfx/client/CMakeLists.txt +++ b/channels/rdpgfx/client/CMakeLists.txt @@ -22,8 +22,8 @@ set(${MODULE_PREFIX}_SRCS rdpgfx_main.h rdpgfx_codec.c rdpgfx_codec.h - rdpgfx_common.c - rdpgfx_common.h) + ../rdpgfx_common.c + ../rdpgfx_common.h) include_directories(..) @@ -33,7 +33,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE target_link_libraries(${MODULE_NAME} winpr freerdp) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/rdpgfx/client/rdpgfx_codec.c b/channels/rdpgfx/client/rdpgfx_codec.c index bf28ddd..2f096e8 100644 --- a/channels/rdpgfx/client/rdpgfx_codec.c +++ b/channels/rdpgfx/client/rdpgfx_codec.c @@ -57,7 +57,7 @@ static UINT rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */ - if (Stream_GetRemainingLength(s) < (meta->numRegionRects * sizeof(RECTANGLE_16))) + if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 8)) { WLog_ERR(TAG, "not enough data!"); goto error_out; @@ -88,7 +88,7 @@ static UINT rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, regionRect = &(meta->regionRects[index]); if ((error = rdpgfx_read_rect16(s, regionRect))) { - WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %u!", error); goto error_out; } WLog_DBG(TAG, "regionRects[%d]: left: %d top: %d right: %d bottom: %d", @@ -146,7 +146,7 @@ static UINT rdpgfx_decode_AVC420(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.meta)))) { - WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %u!", error); return error; } @@ -161,7 +161,7 @@ static UINT rdpgfx_decode_AVC420(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd { IFCALLRET(context->SurfaceCommand, error, context, cmd); if (error) - WLog_ERR(TAG, "context->SurfaceCommand failed with error %lu", error); + WLog_ERR(TAG, "context->SurfaceCommand failed with error %u", error); } free(h264.meta.regionRects); @@ -205,7 +205,7 @@ static UINT rdpgfx_decode_AVC444(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd pos1 = Stream_GetPosition(s); if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.bitstream[0].meta)))) { - WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %u!", error); return error; } pos2 = Stream_GetPosition(s); @@ -223,7 +223,7 @@ static UINT rdpgfx_decode_AVC444(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd if ((error = rdpgfx_read_h264_metablock(gfx, s, &(h264.bitstream[1].meta)))) { - WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_h264_metablock failed with error %u!", error); return error; } @@ -244,7 +244,7 @@ static UINT rdpgfx_decode_AVC444(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd { IFCALLRET(context->SurfaceCommand, error, context, cmd); if (error) - WLog_ERR(TAG, "context->SurfaceCommand failed with error %lu", error); + WLog_ERR(TAG, "context->SurfaceCommand failed with error %u", error); } free(h264.bitstream[0].meta.regionRects); @@ -270,7 +270,7 @@ UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) case RDPGFX_CODECID_AVC420: if ((error = rdpgfx_decode_AVC420(gfx, cmd))) { - WLog_ERR(TAG, "rdpgfx_decode_AVC420 failed with error %lu", error); + WLog_ERR(TAG, "rdpgfx_decode_AVC420 failed with error %u", error); return error; } break; @@ -278,7 +278,7 @@ UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) case RDPGFX_CODECID_AVC444: if ((error = rdpgfx_decode_AVC444(gfx, cmd))) { - WLog_ERR(TAG, "rdpgfx_decode_AVC444 failed with error %lu", error); + WLog_ERR(TAG, "rdpgfx_decode_AVC444 failed with error %u", error); return error; } break; @@ -288,7 +288,7 @@ UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd) { IFCALLRET(context->SurfaceCommand, error, context, cmd); if (error) - WLog_ERR(TAG, "context->SurfaceCommand failed with error %lu", error); + WLog_ERR(TAG, "context->SurfaceCommand failed with error %u", error); } break; } diff --git a/channels/rdpgfx/client/rdpgfx_codec.h b/channels/rdpgfx/client/rdpgfx_codec.h index 45f7ef7..03d1bac 100644 --- a/channels/rdpgfx/client/rdpgfx_codec.h +++ b/channels/rdpgfx/client/rdpgfx_codec.h @@ -26,9 +26,10 @@ #include #include +#include #include "rdpgfx_main.h" -UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd); +FREERDP_LOCAL UINT rdpgfx_decode(RDPGFX_PLUGIN* gfx, RDPGFX_SURFACE_COMMAND* cmd); #endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_CODEC_H */ diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index 01e766f..703dce9 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -5,6 +5,8 @@ * Copyright 2013-2014 Marc-Andre Moreau * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2016 Thincast Technologies GmbH + * Copyright 2016 Armin Novak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,17 +60,13 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) RDPGFX_PLUGIN* gfx; RDPGFX_HEADER header; RDPGFX_CAPSET* capsSet; - RDPGFX_CAPSET capsSets[3]; + RDPGFX_CAPSET capsSets[RDPGFX_NUMBER_CAPSETS]; RDPGFX_CAPS_ADVERTISE_PDU pdu; - gfx = (RDPGFX_PLUGIN*) callback->plugin; - header.flags = 0; header.cmdId = RDPGFX_CMDID_CAPSADVERTISE; - pdu.capsSetCount = 0; pdu.capsSets = (RDPGFX_CAPSET*) capsSets; - capsSet = &capsSets[pdu.capsSetCount++]; capsSet->version = RDPGFX_CAPVERSION_8; capsSet->flags = 0; @@ -103,13 +101,16 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) if (!gfx->H264) capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED; + + capsSets[pdu.capsSetCount] = *capsSet; + capsSets[pdu.capsSetCount++].version = RDPGFX_CAPVERSION_102; } - header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount * RDPGFX_CAPSET_SIZE); - + header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount * + RDPGFX_CAPSET_SIZE); WLog_DBG(TAG, "SendCapsAdvertisePdu %d", pdu.capsSetCount); - s = Stream_New(NULL, header.pduLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -118,12 +119,11 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) if ((error = rdpgfx_write_header(s, &header))) { - WLog_ERR(TAG, "rdpgfx_write_header failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_write_header failed with error %u!", error); return error; } /* RDPGFX_CAPS_ADVERTISE_PDU */ - Stream_Write_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */ for (index = 0; index < pdu.capsSetCount; index++) @@ -135,11 +135,9 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) } Stream_SealLength(s); - - error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); - + error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), + Stream_Buffer(s), NULL); Stream_Free(s, TRUE); - return error; } @@ -148,27 +146,25 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_caps_confirm_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_caps_confirm_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_CAPSET capsSet; UINT32 capsDataLength; RDPGFX_CAPS_CONFIRM_PDU pdu; - pdu.capsSet = &capsSet; if (Stream_GetRemainingLength(s) < 12) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT32(s, capsSet.version); /* version (4 bytes) */ Stream_Read_UINT32(s, capsDataLength); /* capsDataLength (4 bytes) */ Stream_Read_UINT32(s, capsSet.flags); /* capsData (4 bytes) */ - WLog_DBG(TAG, "RecvCapsConfirmPdu: version: 0x%04X flags: 0x%04X", - capsSet.version, capsSet.flags); - + capsSet.version, capsSet.flags); return CHANNEL_RC_OK; } @@ -177,19 +173,18 @@ static UINT rdpgfx_recv_caps_confirm_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStr * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RDPGFX_FRAME_ACKNOWLEDGE_PDU* pdu) +static UINT rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + RDPGFX_FRAME_ACKNOWLEDGE_PDU* pdu) { UINT error; wStream* s; RDPGFX_HEADER header; - header.flags = 0; header.cmdId = RDPGFX_CMDID_FRAMEACKNOWLEDGE; header.pduLength = RDPGFX_HEADER_SIZE + 12; - WLog_DBG(TAG, "SendFrameAcknowledgePdu: %d", pdu->frameId); - s = Stream_New(NULL, header.pduLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -198,20 +193,18 @@ static UINT rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback, if ((error = rdpgfx_write_header(s, &header))) { - WLog_ERR(TAG, "rdpgfx_write_header failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_write_header failed with error %u!", error); return error; } /* RDPGFX_FRAME_ACKNOWLEDGE_PDU */ - Stream_Write_UINT32(s, pdu->queueDepth); /* queueDepth (4 bytes) */ Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */ - Stream_Write_UINT32(s, pdu->totalFramesDecoded); /* totalFramesDecoded (4 bytes) */ - - error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); - + Stream_Write_UINT32(s, + pdu->totalFramesDecoded); /* totalFramesDecoded (4 bytes) */ + error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), + Stream_Buffer(s), NULL); Stream_Free(s, TRUE); - return error; } @@ -220,7 +213,8 @@ static UINT rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { int pad; UINT32 index; @@ -232,7 +226,7 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS if (Stream_GetRemainingLength(s) < 12) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } @@ -242,11 +236,12 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS if (Stream_GetRemainingLength(s) < (pdu.monitorCount * 20)) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } - pdu.monitorDefArray = (MONITOR_DEF*) calloc(pdu.monitorCount, sizeof(MONITOR_DEF)); + pdu.monitorDefArray = (MONITOR_DEF*) calloc(pdu.monitorCount, + sizeof(MONITOR_DEF)); if (!pdu.monitorDefArray) { @@ -274,19 +269,18 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS } Stream_Seek(s, pad); /* pad (total size is 340 bytes) */ - WLog_DBG(TAG, "RecvResetGraphicsPdu: width: %d height: %d count: %d", - pdu.width, pdu.height, pdu.monitorCount); + pdu.width, pdu.height, pdu.monitorCount); if (context) { IFCALLRET(context->ResetGraphics, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->ResetGraphics failed with error %lu", error); + WLog_ERR(TAG, "context->ResetGraphics failed with error %u", error); } free(pdu.monitorDefArray); - return error; } @@ -295,7 +289,8 @@ static UINT rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_evict_cache_entry_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_evict_cache_entry_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_EVICT_CACHE_ENTRY_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; @@ -304,19 +299,19 @@ static UINT rdpgfx_recv_evict_cache_entry_pdu(RDPGFX_CHANNEL_CALLBACK* callback, if (Stream_GetRemainingLength(s) < 2) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */ - WLog_DBG(TAG, "RecvEvictCacheEntryPdu: cacheSlot: %d", pdu.cacheSlot); if (context) { IFCALLRET(context->EvictCacheEntry, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->EvictCacheEntry failed with error %lu", error); + WLog_ERR(TAG, "context->EvictCacheEntry failed with error %u", error); } return error; @@ -327,7 +322,8 @@ static UINT rdpgfx_recv_evict_cache_entry_pdu(RDPGFX_CHANNEL_CALLBACK* callback, * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { UINT16 index; RDPGFX_CACHE_IMPORT_REPLY_PDU pdu; @@ -337,15 +333,15 @@ UINT rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStre if (Stream_GetRemainingLength(s) < 2) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.importedEntriesCount); /* cacheSlot (2 bytes) */ - if (Stream_GetRemainingLength(s) < (size_t) (pdu.importedEntriesCount * 2)) + if (Stream_GetRemainingLength(s) < (size_t)(pdu.importedEntriesCount * 2)) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } @@ -363,17 +359,17 @@ UINT rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStre } WLog_DBG(TAG, "RecvCacheImportReplyPdu: importedEntriesCount: %d", - pdu.importedEntriesCount); + pdu.importedEntriesCount); if (context) { IFCALLRET(context->CacheImportReply, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->CacheImportReply failed with error %lu", error); + WLog_ERR(TAG, "context->CacheImportReply failed with error %u", error); } free(pdu.cacheSlots); - return error; } @@ -382,7 +378,8 @@ UINT rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStre * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_create_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_create_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_CREATE_SURFACE_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; @@ -391,7 +388,7 @@ static UINT rdpgfx_recv_create_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS if (Stream_GetRemainingLength(s) < 7) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } @@ -399,15 +396,16 @@ static UINT rdpgfx_recv_create_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS Stream_Read_UINT16(s, pdu.width); /* width (2 bytes) */ Stream_Read_UINT16(s, pdu.height); /* height (2 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* RDPGFX_PIXELFORMAT (1 byte) */ - - WLog_DBG(TAG, "RecvCreateSurfacePdu: surfaceId: %d width: %d height: %d pixelFormat: 0x%02X", - pdu.surfaceId, pdu.width, pdu.height, pdu.pixelFormat); + WLog_DBG(TAG, + "RecvCreateSurfacePdu: surfaceId: %d width: %d height: %d pixelFormat: 0x%02X", + pdu.surfaceId, pdu.width, pdu.height, pdu.pixelFormat); if (context) { IFCALLRET(context->CreateSurface, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->CreateSurface failed with error %lu", error); + WLog_ERR(TAG, "context->CreateSurface failed with error %u", error); } return error; @@ -418,7 +416,8 @@ static UINT rdpgfx_recv_create_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpgfx_recv_delete_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_delete_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_DELETE_SURFACE_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; @@ -427,19 +426,19 @@ UINT rdpgfx_recv_delete_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* if (Stream_GetRemainingLength(s) < 2) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ - WLog_DBG(TAG, "RecvDeleteSurfacePdu: surfaceId: %d", pdu.surfaceId); if (context) { IFCALLRET(context->DeleteSurface, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->DeleteSurface failed with error %lu", error); + WLog_ERR(TAG, "context->DeleteSurface failed with error %u", error); } return error; @@ -450,34 +449,34 @@ UINT rdpgfx_recv_delete_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_start_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_start_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_START_FRAME_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 8) + if (Stream_GetRemainingLength(s) < RDPGFX_START_FRAME_PDU_SIZE) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */ Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ - WLog_DBG(TAG, "RecvStartFramePdu: frameId: %d timestamp: 0x%04X", - pdu.frameId, pdu.timestamp); + pdu.frameId, pdu.timestamp); if (context) { IFCALLRET(context->StartFrame, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->StartFrame failed with error %lu", error); + WLog_ERR(TAG, "context->StartFrame failed with error %u", error); } gfx->UnacknowledgedFrames++; - return error; } @@ -486,7 +485,8 @@ static UINT rdpgfx_recv_start_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStre * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_END_FRAME_PDU pdu; RDPGFX_FRAME_ACKNOWLEDGE_PDU ack; @@ -494,29 +494,28 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 4) + if (Stream_GetRemainingLength(s) < RDPGFX_END_FRAME_PDU_SIZE) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ - - WLog_DBG(TAG, "RecvEndFramePdu: frameId: %d", pdu.frameId); + WLog_DBG(TAG, "RecvEndFramePdu: frameId: %lu", (unsigned long) pdu.frameId); if (context) { IFCALLRET(context->EndFrame, error, context, &pdu); + if (error) { - WLog_ERR(TAG, "context->EndFrame failed with error %lu", error); + WLog_ERR(TAG, "context->EndFrame failed with error %u", error); return error; } } gfx->UnacknowledgedFrames--; gfx->TotalDecodedFrames++; - ack.frameId = pdu.frameId; ack.totalFramesDecoded = gfx->TotalDecodedFrames; @@ -525,14 +524,15 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream ack.queueDepth = SUSPEND_FRAME_ACKNOWLEDGEMENT; if (gfx->TotalDecodedFrames == 1) - if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack))) - WLog_ERR(TAG, "rdpgfx_send_frame_acknowledge_pdu failed with error %lu", error); + if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack))) + WLog_ERR(TAG, "rdpgfx_send_frame_acknowledge_pdu failed with error %u", error); } else { ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE; + if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack))) - WLog_ERR(TAG, "rdpgfx_send_frame_acknowledge_pdu failed with error %lu", error); + WLog_ERR(TAG, "rdpgfx_send_frame_acknowledge_pdu failed with error %u", error); } return error; @@ -543,16 +543,17 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_1 pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; UINT error; - if (Stream_GetRemainingLength(s) < 17) + if (Stream_GetRemainingLength(s) < RDPGFX_WIRE_TO_SURFACE_PDU_1_SIZE) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } @@ -562,7 +563,7 @@ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, if ((error = rdpgfx_read_rect16(s, &(pdu.destRect)))) /* destRect (8 bytes) */ { - WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %lu", error); + WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %u", error); return error; } @@ -570,23 +571,38 @@ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, if (pdu.bitmapDataLength > Stream_GetRemainingLength(s)) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); - - WLog_DBG(TAG, "RecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X " - "destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d", - (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, - pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, - pdu.bitmapDataLength); - + WLog_DBG(TAG, + "RecvWireToSurface1Pdu: surfaceId: %lu codecId: %s (0x%04lX) pixelFormat: 0x%04lX " + "destRect: left: %lu top: %lu right: %lu bottom: %lu bitmapDataLength: %lu", + (unsigned long) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), + (unsigned long) pdu.codecId, (unsigned long) pdu.pixelFormat, + (unsigned long) pdu.destRect.left, (unsigned long) pdu.destRect.top, + (unsigned long) pdu.destRect.right, (unsigned long) pdu.destRect.bottom, + (unsigned long) pdu.bitmapDataLength); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = 0; - cmd.format = pdu.pixelFormat; + + switch (pdu.pixelFormat) + { + case GFX_PIXEL_FORMAT_XRGB_8888: + cmd.format = PIXEL_FORMAT_BGRX32; + break; + + case GFX_PIXEL_FORMAT_ARGB_8888: + cmd.format = PIXEL_FORMAT_BGRA32; + break; + + default: + return ERROR_INVALID_DATA; + } + cmd.left = pdu.destRect.left; cmd.top = pdu.destRect.top; cmd.right = pdu.destRect.right; @@ -597,7 +613,7 @@ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, cmd.data = pdu.bitmapData; if ((error = rdpgfx_decode(gfx, &cmd))) - WLog_ERR(TAG, "rdpgfx_decode failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_decode failed with error %u!", error); return error; } @@ -607,7 +623,8 @@ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_2 pdu; @@ -615,9 +632,9 @@ static UINT rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - if (Stream_GetRemainingLength(s) < 13) + if (Stream_GetRemainingLength(s) < RDPGFX_WIRE_TO_SURFACE_PDU_2_SIZE) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } @@ -625,17 +642,13 @@ static UINT rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ Stream_Read_UINT32(s, pdu.codecContextId); /* codecContextId (4 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ - Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ - pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); - WLog_DBG(TAG, "RecvWireToSurface2Pdu: surfaceId: %d codecId: %s (0x%04X) " - "codecContextId: %d pixelFormat: 0x%04X bitmapDataLength: %d", - (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, - pdu.codecContextId, pdu.pixelFormat, pdu.bitmapDataLength); - + "codecContextId: %d pixelFormat: 0x%04X bitmapDataLength: %d", + (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, + pdu.codecContextId, pdu.pixelFormat, pdu.bitmapDataLength); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = pdu.codecContextId; @@ -652,8 +665,9 @@ static UINT rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, if (context) { IFCALLRET(context->SurfaceCommand, error, context, &cmd); + if (error) - WLog_ERR(TAG, "context->SurfaceCommand failed with error %lu", error); + WLog_ERR(TAG, "context->SurfaceCommand failed with error %u", error); } return error; @@ -664,7 +678,8 @@ static UINT rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_delete_encoding_context_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_delete_encoding_context_pdu(RDPGFX_CHANNEL_CALLBACK* + callback, wStream* s) { RDPGFX_DELETE_ENCODING_CONTEXT_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; @@ -673,21 +688,21 @@ static UINT rdpgfx_recv_delete_encoding_context_pdu(RDPGFX_CHANNEL_CALLBACK* cal if (Stream_GetRemainingLength(s) < 6) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT32(s, pdu.codecContextId); /* codecContextId (4 bytes) */ - WLog_DBG(TAG, "RecvDeleteEncodingContextPdu: surfaceId: %d codecContextId: %d", - pdu.surfaceId, pdu.codecContextId); + pdu.surfaceId, pdu.codecContextId); if (context) { IFCALLRET(context->DeleteEncodingContext, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->DeleteEncodingContext failed with error %lu", error); + WLog_ERR(TAG, "context->DeleteEncodingContext failed with error %u", error); } return error; @@ -698,7 +713,7 @@ static UINT rdpgfx_recv_delete_encoding_context_pdu(RDPGFX_CHANNEL_CALLBACK* cal * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { UINT16 index; RECTANGLE_16* fillRect; @@ -709,21 +724,24 @@ UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) if (Stream_GetRemainingLength(s) < 8) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ - if ((error = rdpgfx_read_color32(s, &(pdu.fillPixel)))) /* fillPixel (4 bytes) */ + + if ((error = rdpgfx_read_color32(s, + &(pdu.fillPixel)))) /* fillPixel (4 bytes) */ { - WLog_ERR(TAG, "rdpgfx_read_color32 failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_color32 failed with error %u!", error); return error; } + Stream_Read_UINT16(s, pdu.fillRectCount); /* fillRectCount (2 bytes) */ - if (Stream_GetRemainingLength(s) < (size_t) (pdu.fillRectCount * 8)) + if (Stream_GetRemainingLength(s) < (size_t)(pdu.fillRectCount * 8)) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } @@ -738,26 +756,27 @@ UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) for (index = 0; index < pdu.fillRectCount; index++) { fillRect = &(pdu.fillRects[index]); + if ((error = rdpgfx_read_rect16(s, fillRect))) { - WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %u!", error); free(pdu.fillRects); return error; } } WLog_DBG(TAG, "RecvSolidFillPdu: surfaceId: %d fillRectCount: %d", - pdu.surfaceId, pdu.fillRectCount); + pdu.surfaceId, pdu.fillRectCount); if (context) { IFCALLRET(context->SolidFill, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->SolidFill failed with error %lu", error); + WLog_ERR(TAG, "context->SolidFill failed with error %u", error); } free(pdu.fillRects); - return error; } @@ -766,7 +785,8 @@ UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* + callback, wStream* s) { UINT16 index; RDPGFX_POINT16* destPt; @@ -777,27 +797,29 @@ static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback if (Stream_GetRemainingLength(s) < 14) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceIdSrc); /* surfaceIdSrc (2 bytes) */ Stream_Read_UINT16(s, pdu.surfaceIdDest); /* surfaceIdDest (2 bytes) */ + if ((error = rdpgfx_read_rect16(s, &(pdu.rectSrc)))) /* rectSrc (8 bytes ) */ { - WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %u!", error); return error; } Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ - if (Stream_GetRemainingLength(s) < (size_t) (pdu.destPtsCount * 4)) + if (Stream_GetRemainingLength(s) < (size_t)(pdu.destPtsCount * 4)) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } - pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); + pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, + sizeof(RDPGFX_POINT16)); if (!pdu.destPts) { @@ -808,29 +830,30 @@ static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback for (index = 0; index < pdu.destPtsCount; index++) { destPt = &(pdu.destPts[index]); + if ((error = rdpgfx_read_point16(s, destPt))) { - WLog_ERR(TAG, "rdpgfx_read_point16 failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_point16 failed with error %u!", error); free(pdu.destPts); return error; } } WLog_DBG(TAG, "RecvSurfaceToSurfacePdu: surfaceIdSrc: %d surfaceIdDest: %d " - "left: %d top: %d right: %d bottom: %d destPtsCount: %d", - pdu.surfaceIdSrc, pdu.surfaceIdDest, - pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom, - pdu.destPtsCount); + "left: %d top: %d right: %d bottom: %d destPtsCount: %d", + pdu.surfaceIdSrc, pdu.surfaceIdDest, + pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom, + pdu.destPtsCount); if (context) { IFCALLRET(context->SurfaceToSurface, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->SurfaceToSurface failed with error %lu", error); + WLog_ERR(TAG, "context->SurfaceToSurface failed with error %u", error); } free(pdu.destPts); - return error; } @@ -839,7 +862,8 @@ static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_SURFACE_TO_CACHE_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; @@ -848,30 +872,33 @@ static UINT rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback, if (Stream_GetRemainingLength(s) < 20) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT64(s, pdu.cacheKey); /* cacheKey (8 bytes) */ Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */ + if ((error = rdpgfx_read_rect16(s, &(pdu.rectSrc)))) /* rectSrc (8 bytes ) */ { - WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %u!", error); return error; } - WLog_DBG(TAG, "RecvSurfaceToCachePdu: surfaceId: %d cacheKey: 0x%08X cacheSlot: %d " - "left: %d top: %d right: %d bottom: %d", - pdu.surfaceId, (int) pdu.cacheKey, pdu.cacheSlot, - pdu.rectSrc.left, pdu.rectSrc.top, - pdu.rectSrc.right, pdu.rectSrc.bottom); + WLog_DBG(TAG, + "RecvSurfaceToCachePdu: surfaceId: %d cacheKey: 0x%08X cacheSlot: %d " + "left: %d top: %d right: %d bottom: %d", + pdu.surfaceId, (int) pdu.cacheKey, pdu.cacheSlot, + pdu.rectSrc.left, pdu.rectSrc.top, + pdu.rectSrc.right, pdu.rectSrc.bottom); if (context) { IFCALLRET(context->SurfaceToCache, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->SurfaceToCache failed with error %lu", error); + WLog_ERR(TAG, "context->SurfaceToCache failed with error %u", error); } return error; @@ -882,7 +909,8 @@ static UINT rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback, * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { UINT16 index; RDPGFX_POINT16* destPt; @@ -893,7 +921,7 @@ UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream if (Stream_GetRemainingLength(s) < 6) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } @@ -901,13 +929,14 @@ UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ - if (Stream_GetRemainingLength(s) < (size_t) (pdu.destPtsCount * 4)) + if (Stream_GetRemainingLength(s) < (size_t)(pdu.destPtsCount * 4)) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } - pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); + pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, + sizeof(RDPGFX_POINT16)); if (!pdu.destPts) { @@ -918,26 +947,28 @@ UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream for (index = 0; index < pdu.destPtsCount; index++) { destPt = &(pdu.destPts[index]); + if ((error = rdpgfx_read_point16(s, destPt))) { - WLog_ERR(TAG, "rdpgfx_read_point16 failed with error %lu", error); + WLog_ERR(TAG, "rdpgfx_read_point16 failed with error %u", error); free(pdu.destPts); return error; } } - WLog_DBG(TAG, "RdpGfxRecvCacheToSurfacePdu: cacheSlot: %d surfaceId: %d destPtsCount: %d", - pdu.cacheSlot, (int) pdu.surfaceId, pdu.destPtsCount); + WLog_DBG(TAG, + "RdpGfxRecvCacheToSurfacePdu: cacheSlot: %d surfaceId: %d destPtsCount: %d", + pdu.cacheSlot, (int) pdu.surfaceId, pdu.destPtsCount); if (context) { IFCALLRET(context->CacheToSurface, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->CacheToSurface failed with error %lu", error); + WLog_ERR(TAG, "context->CacheToSurface failed with error %u", error); } free(pdu.destPts); - return error; } @@ -946,7 +977,8 @@ UINT rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK* + callback, wStream* s) { RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; @@ -955,7 +987,7 @@ static UINT rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK* callb if (Stream_GetRemainingLength(s) < 12) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } @@ -963,15 +995,16 @@ static UINT rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK* callb Stream_Read_UINT16(s, pdu.reserved); /* reserved (2 bytes) */ Stream_Read_UINT32(s, pdu.outputOriginX); /* outputOriginX (4 bytes) */ Stream_Read_UINT32(s, pdu.outputOriginY); /* outputOriginY (4 bytes) */ - - WLog_DBG(TAG, "RecvMapSurfaceToOutputPdu: surfaceId: %d outputOriginX: %d outputOriginY: %d", - (int) pdu.surfaceId, pdu.outputOriginX, pdu.outputOriginY); + WLog_DBG(TAG, + "RecvMapSurfaceToOutputPdu: surfaceId: %d outputOriginX: %d outputOriginY: %d", + (int) pdu.surfaceId, pdu.outputOriginX, pdu.outputOriginY); if (context) { IFCALLRET(context->MapSurfaceToOutput, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->MapSurfaceToOutput failed with error %lu", error); + WLog_ERR(TAG, "context->MapSurfaceToOutput failed with error %u", error); } return error; @@ -982,7 +1015,8 @@ static UINT rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK* callb * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) +static UINT rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callback, + wStream* s) { RDPGFX_MAP_SURFACE_TO_WINDOW_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; @@ -991,7 +1025,7 @@ UINT rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS if (Stream_GetRemainingLength(s) < 18) { - WLog_ERR(TAG, "not enought data!"); + WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } @@ -999,15 +1033,16 @@ UINT rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wS Stream_Read_UINT64(s, pdu.windowId); /* windowId (8 bytes) */ Stream_Read_UINT32(s, pdu.mappedWidth); /* mappedWidth (4 bytes) */ Stream_Read_UINT32(s, pdu.mappedHeight); /* mappedHeight (4 bytes) */ - - WLog_DBG(TAG, "RecvMapSurfaceToWindowPdu: surfaceId: %d windowId: 0x%04X mappedWidth: %d mappedHeight: %d", - pdu.surfaceId, (int) pdu.windowId, pdu.mappedWidth, pdu.mappedHeight); + WLog_DBG(TAG, + "RecvMapSurfaceToWindowPdu: surfaceId: %d windowId: 0x%04X mappedWidth: %d mappedHeight: %d", + pdu.surfaceId, (int) pdu.windowId, pdu.mappedWidth, pdu.mappedHeight); if (context && context->MapSurfaceToWindow) { IFCALLRET(context->MapSurfaceToWindow, error, context, &pdu); + if (error) - WLog_ERR(TAG, "context->MapSurfaceToWindow failed with error %lu", error); + WLog_ERR(TAG, "context->MapSurfaceToWindow failed with error %u", error); } return error; @@ -1023,105 +1058,130 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) int beg, end; RDPGFX_HEADER header; UINT error; - beg = Stream_GetPosition(s); if ((error = rdpgfx_read_header(s, &header))) { - WLog_ERR(TAG, "rdpgfx_read_header failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_read_header failed with error %u!", error); return error; } #if 1 WLog_DBG(TAG, "cmdId: %s (0x%04X) flags: 0x%04X pduLength: %d", - rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags, header.pduLength); + rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags, + header.pduLength); #endif switch (header.cmdId) { case RDPGFX_CMDID_WIRETOSURFACE_1: if ((error = rdpgfx_recv_wire_to_surface_1_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_wire_to_surface_1_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_wire_to_surface_1_pdu failed with error %u!", + error); + break; case RDPGFX_CMDID_WIRETOSURFACE_2: if ((error = rdpgfx_recv_wire_to_surface_2_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_wire_to_surface_2_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_wire_to_surface_2_pdu failed with error %u!", + error); + break; case RDPGFX_CMDID_DELETEENCODINGCONTEXT: if ((error = rdpgfx_recv_delete_encoding_context_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_delete_encoding_context_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_delete_encoding_context_pdu failed with error %u!", + error); + break; case RDPGFX_CMDID_SOLIDFILL: if ((error = rdpgfx_recv_solid_fill_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_solid_fill_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_solid_fill_pdu failed with error %u!", error); + break; case RDPGFX_CMDID_SURFACETOSURFACE: if ((error = rdpgfx_recv_surface_to_surface_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_surface_to_surface_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_surface_to_surface_pdu failed with error %u!", + error); + break; case RDPGFX_CMDID_SURFACETOCACHE: if ((error = rdpgfx_recv_surface_to_cache_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_surface_to_cache_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_surface_to_cache_pdu failed with error %u!", error); + break; case RDPGFX_CMDID_CACHETOSURFACE: if ((error = rdpgfx_recv_cache_to_surface_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_cache_to_surface_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_cache_to_surface_pdu failed with error %u!", error); + break; case RDPGFX_CMDID_EVICTCACHEENTRY: if ((error = rdpgfx_recv_evict_cache_entry_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_evict_cache_entry_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_evict_cache_entry_pdu failed with error %u!", + error); + break; case RDPGFX_CMDID_CREATESURFACE: if ((error = rdpgfx_recv_create_surface_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_create_surface_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_create_surface_pdu failed with error %u!", error); + break; case RDPGFX_CMDID_DELETESURFACE: if ((error = rdpgfx_recv_delete_surface_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_delete_surface_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_delete_surface_pdu failed with error %u!", error); + break; case RDPGFX_CMDID_STARTFRAME: if ((error = rdpgfx_recv_start_frame_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_start_frame_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_start_frame_pdu failed with error %u!", error); + break; case RDPGFX_CMDID_ENDFRAME: if ((error = rdpgfx_recv_end_frame_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_end_frame_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_end_frame_pdu failed with error %u!", error); + break; case RDPGFX_CMDID_RESETGRAPHICS: if ((error = rdpgfx_recv_reset_graphics_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_reset_graphics_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_reset_graphics_pdu failed with error %u!", error); + break; case RDPGFX_CMDID_MAPSURFACETOOUTPUT: if ((error = rdpgfx_recv_map_surface_to_output_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_map_surface_to_output_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_map_surface_to_output_pdu failed with error %u!", + error); + break; case RDPGFX_CMDID_CACHEIMPORTREPLY: if ((error = rdpgfx_recv_cache_import_reply_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_cache_import_reply_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_cache_import_reply_pdu failed with error %u!", + error); + break; case RDPGFX_CMDID_CAPSCONFIRM: if ((error = rdpgfx_recv_caps_confirm_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_caps_confirm_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_caps_confirm_pdu failed with error %u!", error); + break; case RDPGFX_CMDID_MAPSURFACETOWINDOW: if ((error = rdpgfx_recv_map_surface_to_window_pdu(callback, s))) - WLog_ERR(TAG, "rdpgfx_recv_map_surface_to_window_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_map_surface_to_window_pdu failed with error %u!", + error); + break; default: @@ -1132,7 +1192,7 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) if (error) { WLog_ERR(TAG, "Error while parsing GFX cmdId: %s (0x%04X)", - rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId); + rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId); return error; } @@ -1141,7 +1201,7 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) if (end != (beg + header.pduLength)) { WLog_ERR(TAG, "Unexpected gfx pdu end: Actual: %d, Expected: %d", - end, (beg + header.pduLength)); + end, (beg + header.pduLength)); Stream_SetPosition(s, (beg + header.pduLength)); } @@ -1153,7 +1213,8 @@ static UINT rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream* data) +static UINT rdpgfx_on_data_received(IWTSVirtualChannelCallback* + pChannelCallback, wStream* data) { wStream* s; int status = 0; @@ -1162,8 +1223,8 @@ static UINT rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; UINT error = CHANNEL_RC_OK; - - status = zgfx_decompress(gfx->zgfx, Stream_Pointer(data), Stream_GetRemainingLength(data), &pDstData, &DstSize, 0); + status = zgfx_decompress(gfx->zgfx, Stream_Pointer(data), + Stream_GetRemainingLength(data), &pDstData, &DstSize, 0); if (status < 0) { @@ -1172,6 +1233,7 @@ static UINT rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback } s = Stream_New(pDstData, DstSize); + if (!s) { WLog_ERR(TAG, "calloc failed!"); @@ -1182,13 +1244,12 @@ static UINT rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback { if ((error = rdpgfx_recv_pdu(callback, s))) { - WLog_ERR(TAG, "rdpgfx_recv_pdu failed with error %lu!", error); + WLog_ERR(TAG, "rdpgfx_recv_pdu failed with error %u!", error); break; } } Stream_Free(s, TRUE); - return error; } @@ -1200,9 +1261,7 @@ static UINT rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback static UINT rdpgfx_on_open(IWTSVirtualChannelCallback* pChannelCallback) { RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback; - WLog_DBG(TAG, "OnOpen"); - return rdpgfx_send_caps_advertise_pdu(callback); } @@ -1219,11 +1278,8 @@ static UINT rdpgfx_on_close(IWTSVirtualChannelCallback* pChannelCallback) RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; - WLog_DBG(TAG, "OnClose"); - free(callback); - gfx->UnacknowledgedFrames = 0; gfx->TotalDecodedFrames = 0; @@ -1241,7 +1297,6 @@ static UINT rdpgfx_on_close(IWTSVirtualChannelCallback* pChannelCallback) for (index = 0; index < count; index++) { RDPGFX_DELETE_SURFACE_PDU pdu; - pdu.surfaceId = ((UINT16) pKeys[index]) - 1; if (context && context->DeleteSurface) @@ -1257,7 +1312,6 @@ static UINT rdpgfx_on_close(IWTSVirtualChannelCallback* pChannelCallback) if (gfx->CacheSlots[index]) { RDPGFX_EVICT_CACHE_ENTRY_PDU pdu; - pdu.cacheSlot = (UINT16) index; if (context && context->EvictCacheEntry) @@ -1277,14 +1331,16 @@ static UINT rdpgfx_on_close(IWTSVirtualChannelCallback* pChannelCallback) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_on_new_channel_connection(IWTSListenerCallback* pListenerCallback, - IWTSVirtualChannel* pChannel, BYTE* Data, BOOL* pbAccept, - IWTSVirtualChannelCallback** ppCallback) +static UINT rdpgfx_on_new_channel_connection(IWTSListenerCallback* + pListenerCallback, + IWTSVirtualChannel* pChannel, BYTE* Data, BOOL* pbAccept, + IWTSVirtualChannelCallback** ppCallback) { RDPGFX_CHANNEL_CALLBACK* callback; - RDPGFX_LISTENER_CALLBACK* listener_callback = (RDPGFX_LISTENER_CALLBACK*) pListenerCallback; - - callback = (RDPGFX_CHANNEL_CALLBACK*) calloc(1, sizeof(RDPGFX_CHANNEL_CALLBACK)); + RDPGFX_LISTENER_CALLBACK* listener_callback = (RDPGFX_LISTENER_CALLBACK*) + pListenerCallback; + callback = (RDPGFX_CHANNEL_CALLBACK*) calloc(1, + sizeof(RDPGFX_CHANNEL_CALLBACK)); if (!callback) { @@ -1299,9 +1355,7 @@ static UINT rdpgfx_on_new_channel_connection(IWTSListenerCallback* pListenerCall callback->channel_mgr = listener_callback->channel_mgr; callback->channel = pChannel; listener_callback->channel_callback = callback; - *ppCallback = (IWTSVirtualChannelCallback*) callback; - return CHANNEL_RC_OK; } @@ -1310,12 +1364,13 @@ static UINT rdpgfx_on_new_channel_connection(IWTSListenerCallback* pListenerCall * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr) +static UINT rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, + IWTSVirtualChannelManager* pChannelMgr) { UINT error; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) pPlugin; - - gfx->listener_callback = (RDPGFX_LISTENER_CALLBACK*) calloc(1, sizeof(RDPGFX_LISTENER_CALLBACK)); + gfx->listener_callback = (RDPGFX_LISTENER_CALLBACK*) calloc(1, + sizeof(RDPGFX_LISTENER_CALLBACK)); if (!gfx->listener_callback) { @@ -1323,17 +1378,14 @@ static UINT rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMana return CHANNEL_RC_NO_MEMORY; } - gfx->listener_callback->iface.OnNewChannelConnection = rdpgfx_on_new_channel_connection; + gfx->listener_callback->iface.OnNewChannelConnection = + rdpgfx_on_new_channel_connection; gfx->listener_callback->plugin = pPlugin; gfx->listener_callback->channel_mgr = pChannelMgr; - error = pChannelMgr->CreateListener(pChannelMgr, RDPGFX_DVC_CHANNEL_NAME, 0, - (IWTSListenerCallback*) gfx->listener_callback, &(gfx->listener)); - + (IWTSListenerCallback*) gfx->listener_callback, &(gfx->listener)); gfx->listener->pInterface = gfx->iface.pInterface; - WLog_DBG(TAG, "Initialize"); - return error; } @@ -1350,7 +1402,6 @@ static UINT rdpgfx_plugin_terminated(IWTSPlugin* pPlugin) RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) pPlugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; - WLog_DBG(TAG, "Terminated"); if (gfx->listener_callback) @@ -1370,15 +1421,15 @@ static UINT rdpgfx_plugin_terminated(IWTSPlugin* pPlugin) for (index = 0; index < count; index++) { RDPGFX_DELETE_SURFACE_PDU pdu; - pdu.surfaceId = ((UINT16) pKeys[index]) - 1; if (context) { IFCALLRET(context->DeleteSurface, error, context, &pdu); + if (error) { - WLog_ERR(TAG, "context->DeleteSurface failed with error %lu", error); + WLog_ERR(TAG, "context->DeleteSurface failed with error %u", error); free(pKeys); free(context); free(gfx); @@ -1388,7 +1439,6 @@ static UINT rdpgfx_plugin_terminated(IWTSPlugin* pPlugin) } free(pKeys); - HashTable_Free(gfx->SurfaceTable); for (index = 0; index < gfx->MaxCacheSlot; index++) @@ -1396,15 +1446,15 @@ static UINT rdpgfx_plugin_terminated(IWTSPlugin* pPlugin) if (gfx->CacheSlots[index]) { RDPGFX_EVICT_CACHE_ENTRY_PDU pdu; - pdu.cacheSlot = (UINT16) index; if (context) { IFCALLRET(context->EvictCacheEntry, error, context, &pdu); + if (error) { - WLog_ERR(TAG, "context->EvictCacheEntry failed with error %lu", error); + WLog_ERR(TAG, "context->EvictCacheEntry failed with error %u", error); free(context); free(gfx); return error; @@ -1416,9 +1466,7 @@ static UINT rdpgfx_plugin_terminated(IWTSPlugin* pPlugin) } free(context); - free(gfx); - return CHANNEL_RC_OK; } @@ -1427,11 +1475,11 @@ static UINT rdpgfx_plugin_terminated(IWTSPlugin* pPlugin) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_set_surface_data(RdpgfxClientContext* context, UINT16 surfaceId, void* pData) +static UINT rdpgfx_set_surface_data(RdpgfxClientContext* context, + UINT16 surfaceId, void* pData) { ULONG_PTR key; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle; - key = ((ULONG_PTR) surfaceId) + 1; if (pData) @@ -1447,14 +1495,14 @@ static UINT rdpgfx_set_surface_data(RdpgfxClientContext* context, UINT16 surface * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_get_surface_ids(RdpgfxClientContext* context, UINT16** ppSurfaceIds, UINT16* count_out) +static UINT rdpgfx_get_surface_ids(RdpgfxClientContext* context, + UINT16** ppSurfaceIds, UINT16* count_out) { int count; int index; UINT16* pSurfaceIds; ULONG_PTR* pKeys = NULL; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle; - count = HashTable_GetKeys(gfx->SurfaceTable, &pKeys); if (count < 1) @@ -1479,20 +1527,17 @@ static UINT rdpgfx_get_surface_ids(RdpgfxClientContext* context, UINT16** ppSurf free(pKeys); *ppSurfaceIds = pSurfaceIds; *count_out = (UINT16)count; - return CHANNEL_RC_OK; } -static void* rdpgfx_get_surface_data(RdpgfxClientContext* context, UINT16 surfaceId) +static void* rdpgfx_get_surface_data(RdpgfxClientContext* context, + UINT16 surfaceId) { ULONG_PTR key; void* pData = NULL; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle; - key = ((ULONG_PTR) surfaceId) + 1; - pData = HashTable_GetItemValue(gfx->SurfaceTable, (void*) key); - return pData; } @@ -1501,7 +1546,8 @@ static void* rdpgfx_get_surface_data(RdpgfxClientContext* context, UINT16 surfac * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpgfx_set_cache_slot_data(RdpgfxClientContext* context, UINT16 cacheSlot, void* pData) +static UINT rdpgfx_set_cache_slot_data(RdpgfxClientContext* context, + UINT16 cacheSlot, void* pData) { RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle; @@ -1509,11 +1555,10 @@ static UINT rdpgfx_set_cache_slot_data(RdpgfxClientContext* context, UINT16 cach return ERROR_INVALID_INDEX; gfx->CacheSlots[cacheSlot] = pData; - return CHANNEL_RC_OK; } -void* rdpgfx_get_cache_slot_data(RdpgfxClientContext* context, UINT16 cacheSlot) +static void* rdpgfx_get_cache_slot_data(RdpgfxClientContext* context, UINT16 cacheSlot) { void* pData = NULL; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle; @@ -1522,11 +1567,10 @@ void* rdpgfx_get_cache_slot_data(RdpgfxClientContext* context, UINT16 cacheSlot) return NULL; pData = gfx->CacheSlots[cacheSlot]; - return pData; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DVCPluginEntry rdpgfx_DVCPluginEntry #else #define DVCPluginEntry FREERDP_API DVCPluginEntry @@ -1542,7 +1586,6 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) UINT error = CHANNEL_RC_OK; RDPGFX_PLUGIN* gfx; RdpgfxClientContext* context; - gfx = (RDPGFX_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "rdpgfx"); if (!gfx) @@ -1556,17 +1599,15 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) } gfx->settings = (rdpSettings*) pEntryPoints->GetRdpSettings(pEntryPoints); - gfx->iface.Initialize = rdpgfx_plugin_initialize; gfx->iface.Connected = NULL; gfx->iface.Disconnected = NULL; gfx->iface.Terminated = rdpgfx_plugin_terminated; - gfx->SurfaceTable = HashTable_New(TRUE); if (!gfx->SurfaceTable) { - free (gfx); + free(gfx); WLog_ERR(TAG, "HashTable_New failed!"); return CHANNEL_RC_NO_MEMORY; } @@ -1585,7 +1626,6 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) gfx->ThinClient = FALSE; gfx->MaxCacheSlot = (gfx->ThinClient) ? 4096 : 25600; - context = (RdpgfxClientContext*) calloc(1, sizeof(RdpgfxClientContext)); if (!context) @@ -1596,15 +1636,12 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) } context->handle = (void*) gfx; - context->GetSurfaceIds = rdpgfx_get_surface_ids; context->SetSurfaceData = rdpgfx_set_surface_data; context->GetSurfaceData = rdpgfx_get_surface_data; context->SetCacheSlotData = rdpgfx_set_cache_slot_data; context->GetCacheSlotData = rdpgfx_get_cache_slot_data; - gfx->iface.pInterface = (void*) context; - gfx->zgfx = zgfx_context_new(FALSE); if (!gfx->zgfx) diff --git a/channels/rdpgfx/client/rdpgfx_common.c b/channels/rdpgfx/rdpgfx_common.c similarity index 98% rename from channels/rdpgfx/client/rdpgfx_common.c rename to channels/rdpgfx/rdpgfx_common.c index a7518a5..6e5dfa9 100644 --- a/channels/rdpgfx/client/rdpgfx_common.c +++ b/channels/rdpgfx/rdpgfx_common.c @@ -31,7 +31,7 @@ #include "rdpgfx_common.h" -const char* RDPGFX_CMDID_STRINGS[] = +static const char* RDPGFX_CMDID_STRINGS[] = { "RDPGFX_CMDID_UNUSED_0000", "RDPGFX_CMDID_WIRETOSURFACE_1", @@ -54,7 +54,8 @@ const char* RDPGFX_CMDID_STRINGS[] = "RDPGFX_CMDID_CAPSADVERTISE", "RDPGFX_CMDID_CAPSCONFIRM", "RDPGFX_CMDID_UNUSED_0014", - "RDPGFX_CMDID_MAPSURFACETOWINDOW" + "RDPGFX_CMDID_MAPSURFACETOWINDOW", + "RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE" }; const char* rdpgfx_get_cmd_id_string(UINT16 cmdId) @@ -71,20 +72,28 @@ const char* rdpgfx_get_codec_id_string(UINT16 codecId) { case RDPGFX_CODECID_UNCOMPRESSED: return "RDPGFX_CODECID_UNCOMPRESSED"; + case RDPGFX_CODECID_CAVIDEO: return "RDPGFX_CODECID_CAVIDEO"; + case RDPGFX_CODECID_CLEARCODEC: return "RDPGFX_CODECID_CLEARCODEC"; + case RDPGFX_CODECID_PLANAR: return "RDPGFX_CODECID_PLANAR"; + case RDPGFX_CODECID_AVC420: return "RDPGFX_CODECID_AVC420"; + case RDPGFX_CODECID_AVC444: return "RDPGFX_CODECID_AVC444"; + case RDPGFX_CODECID_ALPHA: return "RDPGFX_CODECID_ALPHA"; + case RDPGFX_CODECID_CAPROGRESSIVE: return "RDPGFX_CODECID_CAPROGRESSIVE"; + case RDPGFX_CODECID_CAPROGRESSIVE_V2: return "RDPGFX_CODECID_CAPROGRESSIVE_V2"; } @@ -108,7 +117,6 @@ UINT rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header) Stream_Read_UINT16(s, header->cmdId); /* cmdId (2 bytes) */ Stream_Read_UINT16(s, header->flags); /* flags (2 bytes) */ Stream_Read_UINT32(s, header->pduLength); /* pduLength (4 bytes) */ - return CHANNEL_RC_OK; } @@ -122,7 +130,6 @@ UINT rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header) Stream_Write_UINT16(s, header->cmdId); /* cmdId (2 bytes) */ Stream_Write_UINT16(s, header->flags); /* flags (2 bytes) */ Stream_Write_UINT32(s, header->pduLength); /* pduLength (4 bytes) */ - return CHANNEL_RC_OK; } @@ -141,7 +148,6 @@ UINT rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16) Stream_Read_UINT16(s, pt16->x); /* x (2 bytes) */ Stream_Read_UINT16(s, pt16->y); /* y (2 bytes) */ - return CHANNEL_RC_OK; } @@ -154,7 +160,6 @@ UINT rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16) { Stream_Write_UINT16(s, point16->x); /* x (2 bytes) */ Stream_Write_UINT16(s, point16->y); /* y (2 bytes) */ - return CHANNEL_RC_OK; } @@ -175,7 +180,6 @@ UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16) Stream_Read_UINT16(s, rect16->top); /* top (2 bytes) */ Stream_Read_UINT16(s, rect16->right); /* right (2 bytes) */ Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */ - return CHANNEL_RC_OK; } @@ -190,7 +194,6 @@ UINT rdpgfx_write_rect16(wStream* s, RECTANGLE_16* rect16) Stream_Write_UINT16(s, rect16->top); /* top (2 bytes) */ Stream_Write_UINT16(s, rect16->right); /* right (2 bytes) */ Stream_Write_UINT16(s, rect16->bottom); /* bottom (2 bytes) */ - return CHANNEL_RC_OK; } @@ -211,7 +214,6 @@ UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32) Stream_Read_UINT8(s, color32->G); /* G (1 byte) */ Stream_Read_UINT8(s, color32->R); /* R (1 byte) */ Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */ - return CHANNEL_RC_OK; } @@ -226,6 +228,5 @@ UINT rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32) Stream_Write_UINT8(s, color32->G); /* G (1 byte) */ Stream_Write_UINT8(s, color32->R); /* R (1 byte) */ Stream_Write_UINT8(s, color32->XA); /* XA (1 byte) */ - return CHANNEL_RC_OK; } diff --git a/channels/rdpgfx/client/rdpgfx_common.h b/channels/rdpgfx/rdpgfx_common.h similarity index 58% rename from channels/rdpgfx/client/rdpgfx_common.h rename to channels/rdpgfx/rdpgfx_common.h index 9d08205..161a1e2 100644 --- a/channels/rdpgfx/client/rdpgfx_common.h +++ b/channels/rdpgfx/rdpgfx_common.h @@ -26,21 +26,22 @@ #include #include +#include -const char* rdpgfx_get_cmd_id_string(UINT16 cmdId); -const char* rdpgfx_get_codec_id_string(UINT16 codecId); +FREERDP_LOCAL const char* rdpgfx_get_cmd_id_string(UINT16 cmdId); +FREERDP_LOCAL const char* rdpgfx_get_codec_id_string(UINT16 codecId); -UINT rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header); -UINT rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header); +FREERDP_LOCAL UINT rdpgfx_read_header(wStream* s, RDPGFX_HEADER* header); +FREERDP_LOCAL UINT rdpgfx_write_header(wStream* s, RDPGFX_HEADER* header); -UINT rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16); -UINT rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16); +FREERDP_LOCAL UINT rdpgfx_read_point16(wStream* s, RDPGFX_POINT16* pt16); +FREERDP_LOCAL UINT rdpgfx_write_point16(wStream* s, RDPGFX_POINT16* point16); -UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16); -UINT rdpgfx_write_rect16(wStream* s, RECTANGLE_16* rect16); +FREERDP_LOCAL UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16); +FREERDP_LOCAL UINT rdpgfx_write_rect16(wStream* s, RECTANGLE_16* rect16); -UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32); -UINT rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32); +FREERDP_LOCAL UINT rdpgfx_read_color32(wStream* s, RDPGFX_COLOR32* color32); +FREERDP_LOCAL UINT rdpgfx_write_color32(wStream* s, RDPGFX_COLOR32* color32); #endif /* FREERDP_CHANNEL_RDPGFX_CLIENT_COMMON_H */ diff --git a/channels/rdpgfx/server/CMakeLists.txt b/channels/rdpgfx/server/CMakeLists.txt new file mode 100644 index 0000000..1b1f48b --- /dev/null +++ b/channels/rdpgfx/server/CMakeLists.txt @@ -0,0 +1,34 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP cmake build script +# +# Copyright 2016 Jiang Zihao +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +define_channel_server("rdpgfx") + +set(${MODULE_PREFIX}_SRCS + rdpgfx_main.c + rdpgfx_main.h + ../rdpgfx_common.c + ../rdpgfx_common.h) + +include_directories(..) + +add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "DVCPluginEntry") + + + +target_link_libraries(${MODULE_NAME} freerdp) + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server") diff --git a/channels/rdpgfx/server/rdpgfx_main.c b/channels/rdpgfx/server/rdpgfx_main.c new file mode 100644 index 0000000..ca4c673 --- /dev/null +++ b/channels/rdpgfx/server/rdpgfx_main.c @@ -0,0 +1,1666 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Graphics Pipeline Extension + * + * Copyright 2016 Jiang Zihao + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "rdpgfx_common.h" +#include "rdpgfx_main.h" + +#define TAG CHANNELS_TAG("rdpgfx.server") +#define RDPGFX_RESET_GRAPHICS_PDU_SIZE 340 + +/** + * Function description + * Calculate packet size from data length. + * It would be data length + header. + * + * @param dataLen estimated data length without header + * + * @return new stream + */ +static INLINE UINT32 rdpgfx_pdu_length(UINT32 dataLen) +{ + return RDPGFX_HEADER_SIZE + dataLen; +} + +static INLINE UINT rdpgfx_server_packet_init_header(wStream* s, + UINT16 cmdId, UINT32 pduLength) +{ + RDPGFX_HEADER header; + header.flags = 0; + header.cmdId = cmdId; + header.pduLength = pduLength; + /* Write header. Note that actual length might be changed + * after the entire packet has been constructed. */ + return rdpgfx_write_header(s, &header); +} + +/** + * Function description + * Complete the rdpgfx packet header. + * + * @param s stream + * @param start saved start pos of the packet in the stream + */ +static INLINE void rdpgfx_server_packet_complete_header(wStream* s, + size_t start) +{ + size_t current = Stream_GetPosition(s); + /* Fill actual length */ + Stream_SetPosition(s, start + RDPGFX_HEADER_SIZE - sizeof(UINT32)); + Stream_Write_UINT32(s, current - start); /* pduLength (4 bytes) */ + Stream_SetPosition(s, current); +} + +/** + * Function description + * Send the stream for rdpgfx server packet. + * The packet would be compressed according to [MS-RDPEGFX]. + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_server_packet_send(RdpgfxServerContext* context, wStream* s) +{ + UINT error; + UINT32 flags = 0; + ULONG written; + BYTE* pSrcData = Stream_Buffer(s); + UINT32 SrcSize = Stream_GetPosition(s); + wStream* fs; + /* Allocate new stream with enough capacity. Additional overhead is + * descriptor (1 bytes) + segmentCount (2 bytes) + uncompressedSize (4 bytes) + * + segmentCount * size (4 bytes) */ + fs = Stream_New(NULL, SrcSize + 7 + + (SrcSize / ZGFX_SEGMENTED_MAXSIZE + 1) * 4); + + if (!fs) + { + WLog_ERR(TAG, "Stream_New failed!"); + error = CHANNEL_RC_NO_MEMORY; + goto out; + } + + if (zgfx_compress_to_stream(context->priv->zgfx, fs, pSrcData, + SrcSize, &flags) < 0) + { + WLog_ERR(TAG, "zgfx_compress_to_stream failed!"); + error = ERROR_INTERNAL_ERROR; + goto out; + } + + if (!WTSVirtualChannelWrite(context->priv->rdpgfx_channel, + (PCHAR) Stream_Buffer(fs), + Stream_GetPosition(fs), &written)) + { + WLog_ERR(TAG, "WTSVirtualChannelWrite failed!"); + error = ERROR_INTERNAL_ERROR; + goto out; + } + + if (written < Stream_GetPosition(fs)) + { + WLog_WARN(TAG, "Unexpected bytes written: %lu/%lu", + written, Stream_GetPosition(fs)); + } + + error = CHANNEL_RC_OK; +out: + Stream_Free(fs, TRUE); + Stream_Free(s, TRUE); + return error; +} + +/** + * Function description + * Create new stream for single rdpgfx packet. The new stream length + * would be required data length + header. The header will be written + * to the stream before return, but the pduLength field might be + * changed in rdpgfx_server_single_packet_send. + * + * @param cmdId + * @param dataLen estimated data length without header + * + * @return new stream + */ +static wStream* rdpgfx_server_single_packet_new(UINT16 cmdId, UINT32 dataLen) +{ + UINT error; + wStream* s; + UINT32 pduLength = rdpgfx_pdu_length(dataLen); + s = Stream_New(NULL, pduLength); + + if (!s) + { + WLog_ERR(TAG, "Stream_New failed!"); + goto error; + } + + if ((error = rdpgfx_server_packet_init_header(s, cmdId, pduLength))) + { + WLog_ERR(TAG, "Failed to init header with error %u!", error); + goto error; + } + + return s; +error: + Stream_Free(s, TRUE); + return NULL; +} + +/** + * Function description + * Send the stream for single rdpgfx packet. + * The header will be filled with actual length. + * The packet would be compressed according to [MS-RDPEGFX]. + * + * @return 0 on success, otherwise a Win32 error code + */ +static INLINE UINT rdpgfx_server_single_packet_send( + RdpgfxServerContext* context, wStream* s) +{ + /* Fill actual length */ + rdpgfx_server_packet_complete_header(s, 0); + return rdpgfx_server_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context, + RDPGFX_CAPS_CONFIRM_PDU* capsConfirm) +{ + RDPGFX_CAPSET* capsSet = capsConfirm->capsSet; + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_CAPSCONFIRM, RDPGFX_CAPSET_SIZE); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */ + Stream_Write_UINT32(s, 4); /* capsDataLength (4 bytes) */ + Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */ + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context, + RDPGFX_RESET_GRAPHICS_PDU* pdu) +{ + UINT32 index; + MONITOR_DEF* monitor; + wStream* s; + + /* Check monitorCount. This ensures total size within 340 bytes) */ + if (pdu->monitorCount >= 16) + { + WLog_ERR(TAG, "Monitor count MUST be less than or equal to 16: %lu", + (unsigned long) pdu->monitorCount); + return ERROR_INVALID_DATA; + } + + s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_RESETGRAPHICS, + RDPGFX_RESET_GRAPHICS_PDU_SIZE - RDPGFX_HEADER_SIZE); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT32(s, pdu->width); /* width (4 bytes) */ + Stream_Write_UINT32(s, pdu->height); /* height (4 bytes) */ + Stream_Write_UINT32(s, pdu->monitorCount); /* monitorCount (4 bytes) */ + + for (index = 0; index < pdu->monitorCount; index++) + { + monitor = &(pdu->monitorDefArray[index]); + Stream_Write_UINT32(s, monitor->left); /* left (4 bytes) */ + Stream_Write_UINT32(s, monitor->top); /* top (4 bytes) */ + Stream_Write_UINT32(s, monitor->right); /* right (4 bytes) */ + Stream_Write_UINT32(s, monitor->bottom); /* bottom (4 bytes) */ + Stream_Write_UINT32(s, monitor->flags); /* flags (4 bytes) */ + } + + /* pad (total size must be 340 bytes) */ + Stream_SetPosition(s, RDPGFX_RESET_GRAPHICS_PDU_SIZE); + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_evict_cache_entry_pdu(RdpgfxServerContext* context, + RDPGFX_EVICT_CACHE_ENTRY_PDU* pdu) +{ + wStream* s = rdpgfx_server_single_packet_new(RDPGFX_CMDID_EVICTCACHEENTRY, 2); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->cacheSlot); /* cacheSlot (2 bytes) */ + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_cache_import_reply_pdu(RdpgfxServerContext* context, + RDPGFX_CACHE_IMPORT_REPLY_PDU* pdu) +{ + UINT16 index; + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_CACHEIMPORTREPLY, + 2 + 2 * pdu->importedEntriesCount); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + /* importedEntriesCount (2 bytes) */ + Stream_Write_UINT16(s, pdu->importedEntriesCount); + + for (index = 0; index < pdu->importedEntriesCount; index++) + { + Stream_Write_UINT16(s, pdu->cacheSlots[index]); /* cacheSlot (2 bytes) */ + } + + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_create_surface_pdu(RdpgfxServerContext* context, + RDPGFX_CREATE_SURFACE_PDU* pdu) +{ + wStream* s = rdpgfx_server_single_packet_new(RDPGFX_CMDID_CREATESURFACE, 7); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ + Stream_Write_UINT16(s, pdu->width); /* width (2 bytes) */ + Stream_Write_UINT16(s, pdu->height); /* height (2 bytes) */ + Stream_Write_UINT8(s, pdu->pixelFormat); /* RDPGFX_PIXELFORMAT (1 byte) */ + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_delete_surface_pdu(RdpgfxServerContext* context, + RDPGFX_DELETE_SURFACE_PDU* pdu) +{ + wStream* s = rdpgfx_server_single_packet_new(RDPGFX_CMDID_DELETESURFACE, 2); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ + return rdpgfx_server_single_packet_send(context, s); +} + +static INLINE void rdpgfx_write_start_frame_pdu(wStream* s, + RDPGFX_START_FRAME_PDU* pdu) +{ + Stream_Write_UINT32(s, pdu->timestamp); /* timestamp (4 bytes) */ + Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */ +} + +static INLINE void rdpgfx_write_end_frame_pdu(wStream* s, + RDPGFX_END_FRAME_PDU* pdu) +{ + Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */ +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_start_frame_pdu(RdpgfxServerContext* context, + RDPGFX_START_FRAME_PDU* pdu) +{ + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_STARTFRAME, + RDPGFX_START_FRAME_PDU_SIZE); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + rdpgfx_write_start_frame_pdu(s, pdu); + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_end_frame_pdu(RdpgfxServerContext* context, + RDPGFX_END_FRAME_PDU* pdu) +{ + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_ENDFRAME, + RDPGFX_END_FRAME_PDU_SIZE); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + rdpgfx_write_end_frame_pdu(s, pdu); + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * Estimate RFX_AVC420_BITMAP_STREAM structure size in stream + * + * @return estimated size + */ +static INLINE UINT32 rdpgfx_estimate_h264_avc420( + RDPGFX_AVC420_BITMAP_STREAM* havc420) +{ + /* H264 metadata + H264 stream. See rdpgfx_write_h264_avc420 */ + return sizeof(UINT32) /* numRegionRects */ + + 10 /* regionRects + quantQualityVals */ + * havc420->meta.numRegionRects + + havc420->length; +} + +/** + * Function description + * Estimate surface command packet size in stream without header + * + * @return estimated size + */ +static INLINE UINT32 rdpgfx_estimate_surface_command(RDPGFX_SURFACE_COMMAND* + cmd) +{ + RDPGFX_AVC420_BITMAP_STREAM* havc420 = NULL; + RDPGFX_AVC444_BITMAP_STREAM* havc444 = NULL; + UINT32 h264Size = 0; + + /* Estimate stream size according to codec. */ + switch (cmd->codecId) + { + case RDPGFX_CODECID_CAPROGRESSIVE: + case RDPGFX_CODECID_CAPROGRESSIVE_V2: + return RDPGFX_WIRE_TO_SURFACE_PDU_2_SIZE + cmd->length; + + case RDPGFX_CODECID_AVC420: + havc420 = (RDPGFX_AVC420_BITMAP_STREAM*)cmd->extra; + h264Size = rdpgfx_estimate_h264_avc420(havc420); + return RDPGFX_WIRE_TO_SURFACE_PDU_1_SIZE + h264Size; + + case RDPGFX_CODECID_AVC444: + havc444 = (RDPGFX_AVC444_BITMAP_STREAM*)cmd->extra; + h264Size = sizeof(UINT32); /* cbAvc420EncodedBitstream1 */ + /* avc420EncodedBitstream1 */ + havc420 = &(havc444->bitstream[0]); + h264Size += rdpgfx_estimate_h264_avc420(havc420); + + /* avc420EncodedBitstream2 */ + if (havc444->LC == 0) + { + havc420 = &(havc444->bitstream[1]); + h264Size += rdpgfx_estimate_h264_avc420(havc420); + } + + return RDPGFX_WIRE_TO_SURFACE_PDU_1_SIZE + h264Size; + + default: + return RDPGFX_WIRE_TO_SURFACE_PDU_1_SIZE + cmd->length; + } +} + +/** + * Function description + * Resolve RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 + * according to codecId + * + * @return 0 on success, otherwise a Win32 error code + */ +static INLINE UINT16 rdpgfx_surface_command_cmdid(RDPGFX_SURFACE_COMMAND* cmd) +{ + if (cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE || + cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2) + { + return RDPGFX_CMDID_WIRETOSURFACE_2; + } + + return RDPGFX_CMDID_WIRETOSURFACE_1; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_write_h264_metablock(wStream* s, RDPGFX_H264_METABLOCK* meta) +{ + UINT32 index; + RECTANGLE_16* regionRect; + RDPGFX_H264_QUANT_QUALITY* quantQualityVal; + UINT error = CHANNEL_RC_OK; + Stream_Write_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */ + + for (index = 0; index < meta->numRegionRects; index++) + { + regionRect = &(meta->regionRects[index]); + + if ((error = rdpgfx_write_rect16(s, regionRect))) + { + WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %u!", error); + return error; + } + } + + for (index = 0; index < meta->numRegionRects; index++) + { + quantQualityVal = &(meta->quantQualityVals[index]); + Stream_Write_UINT8(s, quantQualityVal->qp + | (quantQualityVal->r << 6) + | (quantQualityVal->p << 7)); /* qpVal (1 byte) */ + /* qualityVal (1 byte) */ + Stream_Write_UINT8(s, quantQualityVal->qualityVal); + } + + return error; +} + +/** + * Function description + * Write RFX_AVC420_BITMAP_STREAM structure to stream + * + * @return 0 on success, otherwise a Win32 error code + */ +static INLINE UINT rdpgfx_write_h264_avc420(wStream* s, + RDPGFX_AVC420_BITMAP_STREAM* havc420) +{ + UINT error = CHANNEL_RC_OK; + + if ((error = rdpgfx_write_h264_metablock(s, &(havc420->meta)))) + { + WLog_ERR(TAG, "rdpgfx_write_h264_metablock failed with error %u!", + error); + return error; + } + + Stream_Write(s, havc420->data, havc420->length); + return error; +} + +/** + * Function description + * Write RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 + * to the stream according to RDPGFX_SURFACE_COMMAND message + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_write_surface_command(wStream* s, + RDPGFX_SURFACE_COMMAND* cmd) +{ + UINT error = CHANNEL_RC_OK; + RDPGFX_AVC420_BITMAP_STREAM* havc420 = NULL; + RDPGFX_AVC444_BITMAP_STREAM* havc444 = NULL; + UINT32 bitmapDataStart = 0; + UINT32 bitmapDataLength = 0; + UINT8 pixelFormat = 0; + + switch (cmd->format) + { + case PIXEL_FORMAT_BGRX32: + pixelFormat = GFX_PIXEL_FORMAT_XRGB_8888; + break; + + case PIXEL_FORMAT_BGRA32: + pixelFormat = GFX_PIXEL_FORMAT_ARGB_8888; + break; + + default: + WLog_ERR(TAG, "Format %s not supported!", GetColorFormatName(cmd->format)); + return ERROR_INVALID_DATA; + } + + if (cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE || + cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2) + { + /* Write RDPGFX_CMDID_WIRETOSURFACE_2 format for CAPROGRESSIVE */ + Stream_Write_UINT16(s, cmd->surfaceId); /* surfaceId (2 bytes) */ + Stream_Write_UINT16(s, cmd->codecId); /* codecId (2 bytes) */ + Stream_Write_UINT32(s, cmd->contextId); /* codecContextId (4 bytes) */ + Stream_Write_UINT8(s, pixelFormat); /* pixelFormat (1 byte) */ + Stream_Write_UINT32(s, cmd->length); /* bitmapDataLength (4 bytes) */ + Stream_Write(s, cmd->data, cmd->length); + } + else + { + /* Write RDPGFX_CMDID_WIRETOSURFACE_1 format for others */ + Stream_Write_UINT16(s, cmd->surfaceId); /* surfaceId (2 bytes) */ + Stream_Write_UINT16(s, cmd->codecId); /* codecId (2 bytes) */ + Stream_Write_UINT8(s, pixelFormat); /* pixelFormat (1 byte) */ + Stream_Write_UINT16(s, cmd->left); /* left (2 bytes) */ + Stream_Write_UINT16(s, cmd->top); /* top (2 bytes) */ + Stream_Write_UINT16(s, cmd->right); /* right (2 bytes) */ + Stream_Write_UINT16(s, cmd->bottom); /* bottom (2 bytes) */ + Stream_Write_UINT32(s, cmd->length); /* bitmapDataLength (4 bytes) */ + bitmapDataStart = Stream_GetPosition(s); + + if (cmd->codecId == RDPGFX_CODECID_AVC420) + { + havc420 = (RDPGFX_AVC420_BITMAP_STREAM*)cmd->extra; + error = rdpgfx_write_h264_avc420(s, havc420); + + if (error != CHANNEL_RC_OK) + { + WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!"); + return error; + } + } + else if (cmd->codecId == RDPGFX_CODECID_AVC444) + { + havc444 = (RDPGFX_AVC444_BITMAP_STREAM*)cmd->extra; + havc420 = &(havc444->bitstream[0]); + /* avc420EncodedBitstreamInfo (4 bytes) */ + Stream_Write_UINT32(s, havc420->length | (havc444->LC << 30UL)); + /* avc420EncodedBitstream1 */ + error = rdpgfx_write_h264_avc420(s, havc420); + + if (error != CHANNEL_RC_OK) + { + WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!"); + return error; + } + + /* avc420EncodedBitstream2 */ + if (havc444->LC == 0) + { + havc420 = &(havc444->bitstream[0]); + error = rdpgfx_write_h264_avc420(s, havc420); + + if (error != CHANNEL_RC_OK) + { + WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!"); + return error; + } + } + } + else + { + Stream_Write(s, cmd->data, cmd->length); + } + + assert(Stream_GetPosition(s) <= Stream_Capacity(s)); + /* Fill actual bitmap data length */ + bitmapDataLength = Stream_GetPosition(s) - bitmapDataStart; + Stream_SetPosition(s, bitmapDataStart - sizeof(UINT32)); + Stream_Write_UINT32(s, bitmapDataLength); /* bitmapDataLength (4 bytes) */ + Stream_Seek(s, bitmapDataLength); + } + + return error; +} + +/** + * Function description + * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 + * message according to codecId + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_surface_command(RdpgfxServerContext* context, + RDPGFX_SURFACE_COMMAND* cmd) +{ + UINT error = CHANNEL_RC_OK; + wStream* s; + s = rdpgfx_server_single_packet_new( + rdpgfx_surface_command_cmdid(cmd), + rdpgfx_estimate_surface_command(cmd)); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + error = rdpgfx_write_surface_command(s, cmd); + + if (error != CHANNEL_RC_OK) + { + WLog_ERR(TAG, "rdpgfx_write_surface_command failed!"); + goto error; + } + + return rdpgfx_server_single_packet_send(context, s); +error: + Stream_Free(s, TRUE); + return error; +} + +/** + * Function description + * Send RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 + * message according to codecId. + * Prepend/append start/end frame message in same packet if exists. + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_surface_frame_command(RdpgfxServerContext* context, + RDPGFX_SURFACE_COMMAND* cmd, RDPGFX_START_FRAME_PDU* startFrame, + RDPGFX_END_FRAME_PDU* endFrame) + +{ + UINT error = CHANNEL_RC_OK; + wStream* s; + UINT32 position = 0; + UINT32 size = rdpgfx_pdu_length(rdpgfx_estimate_surface_command(cmd)); + + if (startFrame) + { + size += rdpgfx_pdu_length(RDPGFX_START_FRAME_PDU_SIZE); + } + + if (endFrame) + { + size += rdpgfx_pdu_length(RDPGFX_END_FRAME_PDU_SIZE); + } + + s = Stream_New(NULL, size); + + if (!s) + { + WLog_ERR(TAG, "Stream_New failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + /* Write start frame if exists */ + if (startFrame) + { + position = Stream_GetPosition(s); + error = rdpgfx_server_packet_init_header(s, + RDPGFX_CMDID_STARTFRAME, 0); + + if (error != CHANNEL_RC_OK) + { + WLog_ERR(TAG, "Failed to init header with error %u!", error); + goto error; + } + + rdpgfx_write_start_frame_pdu(s, startFrame); + rdpgfx_server_packet_complete_header(s, position); + } + + /* Write RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2 */ + position = Stream_GetPosition(s); + error = rdpgfx_server_packet_init_header(s, + rdpgfx_surface_command_cmdid(cmd), + 0); // Actual length will be filled later + + if (error != CHANNEL_RC_OK) + { + WLog_ERR(TAG, "Failed to init header with error %u!", error); + goto error; + } + + error = rdpgfx_write_surface_command(s, cmd); + + if (error != CHANNEL_RC_OK) + { + WLog_ERR(TAG, "rdpgfx_write_surface_command failed!"); + goto error; + } + + rdpgfx_server_packet_complete_header(s, position); + + /* Write end frame if exists */ + if (endFrame) + { + position = Stream_GetPosition(s); + error = rdpgfx_server_packet_init_header(s, + RDPGFX_CMDID_ENDFRAME, 0); + + if (error != CHANNEL_RC_OK) + { + WLog_ERR(TAG, "Failed to init header with error %u!", error); + goto error; + } + + rdpgfx_write_end_frame_pdu(s, endFrame); + rdpgfx_server_packet_complete_header(s, position); + } + + return rdpgfx_server_packet_send(context, s); +error: + Stream_Free(s, TRUE); + return error; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_delete_encoding_context_pdu(RdpgfxServerContext* + context, + RDPGFX_DELETE_ENCODING_CONTEXT_PDU* pdu) +{ + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_DELETEENCODINGCONTEXT, 6); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ + Stream_Write_UINT32(s, pdu->codecContextId); /* codecContextId (4 bytes) */ + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_solid_fill_pdu(RdpgfxServerContext* context, + RDPGFX_SOLID_FILL_PDU* pdu) +{ + UINT error = CHANNEL_RC_OK; + UINT16 index; + RECTANGLE_16* fillRect; + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_SOLIDFILL, + 8 + 8 * pdu->fillRectCount); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ + + /* fillPixel (4 bytes) */ + if ((error = rdpgfx_write_color32(s, &(pdu->fillPixel)))) + { + WLog_ERR(TAG, "rdpgfx_write_color32 failed with error %u!", error); + goto error; + } + + Stream_Write_UINT16(s, pdu->fillRectCount); /* fillRectCount (2 bytes) */ + + for (index = 0; index < pdu->fillRectCount; index++) + { + fillRect = &(pdu->fillRects[index]); + + if ((error = rdpgfx_write_rect16(s, fillRect))) + { + WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %u!", error); + goto error; + } + } + + return rdpgfx_server_single_packet_send(context, s); +error: + Stream_Free(s, TRUE); + return error; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_surface_to_surface_pdu(RdpgfxServerContext* context, + RDPGFX_SURFACE_TO_SURFACE_PDU* pdu) +{ + UINT error = CHANNEL_RC_OK; + UINT16 index; + RDPGFX_POINT16* destPt; + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_SURFACETOSURFACE, + 14 + 4 * pdu->destPtsCount); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->surfaceIdSrc); /* surfaceIdSrc (2 bytes) */ + Stream_Write_UINT16(s, pdu->surfaceIdDest); /* surfaceIdDest (2 bytes) */ + + /* rectSrc (8 bytes ) */ + if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc)))) + { + WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %u!", error); + goto error; + } + + Stream_Write_UINT16(s, pdu->destPtsCount); /* destPtsCount (2 bytes) */ + + for (index = 0; index < pdu->destPtsCount; index++) + { + destPt = &(pdu->destPts[index]); + + if ((error = rdpgfx_write_point16(s, destPt))) + { + WLog_ERR(TAG, "rdpgfx_write_point16 failed with error %u!", error); + goto error; + } + } + + return rdpgfx_server_single_packet_send(context, s); +error: + Stream_Free(s, TRUE); + return error; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_surface_to_cache_pdu(RdpgfxServerContext* context, + RDPGFX_SURFACE_TO_CACHE_PDU* pdu) +{ + UINT error = CHANNEL_RC_OK; + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_SURFACETOCACHE, 20); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ + Stream_Write_UINT64(s, pdu->cacheKey); /* cacheKey (8 bytes) */ + Stream_Write_UINT16(s, pdu->cacheSlot); /* cacheSlot (2 bytes) */ + + /* rectSrc (8 bytes ) */ + if ((error = rdpgfx_write_rect16(s, &(pdu->rectSrc)))) + { + WLog_ERR(TAG, "rdpgfx_write_rect16 failed with error %u!", error); + goto error; + } + + return rdpgfx_server_single_packet_send(context, s); +error: + Stream_Free(s, TRUE); + return error; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_cache_to_surface_pdu(RdpgfxServerContext* context, + RDPGFX_CACHE_TO_SURFACE_PDU* pdu) +{ + UINT error = CHANNEL_RC_OK; + UINT16 index; + RDPGFX_POINT16* destPt; + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_CACHETOSURFACE, + 6 + 4 * pdu->destPtsCount); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->cacheSlot); /* cacheSlot (2 bytes) */ + Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ + Stream_Write_UINT16(s, pdu->destPtsCount); /* destPtsCount (2 bytes) */ + + for (index = 0; index < pdu->destPtsCount; index++) + { + destPt = &(pdu->destPts[index]); + + if ((error = rdpgfx_write_point16(s, destPt))) + { + WLog_ERR(TAG, "rdpgfx_write_point16 failed with error %u", error); + goto error; + } + } + + return rdpgfx_server_single_packet_send(context, s); +error: + Stream_Free(s, TRUE); + return error; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_map_surface_to_output_pdu(RdpgfxServerContext* context, + RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* pdu) +{ + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_MAPSURFACETOOUTPUT, 12); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ + Stream_Write_UINT16(s, 0); /* reserved (2 bytes). Must be 0 */ + Stream_Write_UINT32(s, pdu->outputOriginX); /* outputOriginX (4 bytes) */ + Stream_Write_UINT32(s, pdu->outputOriginY); /* outputOriginY (4 bytes) */ + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_send_map_surface_to_window_pdu(RdpgfxServerContext* context, + RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* pdu) +{ + wStream* s = rdpgfx_server_single_packet_new( + RDPGFX_CMDID_MAPSURFACETOWINDOW, 18); + + if (!s) + { + WLog_ERR(TAG, "rdpgfx_server_single_packet_new failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT16(s, pdu->surfaceId); /* surfaceId (2 bytes) */ + Stream_Write_UINT64(s, pdu->windowId); /* windowId (8 bytes) */ + Stream_Write_UINT32(s, pdu->mappedWidth); /* mappedWidth (4 bytes) */ + Stream_Write_UINT32(s, pdu->mappedHeight); /* mappedHeight (4 bytes) */ + return rdpgfx_server_single_packet_send(context, s); +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_recv_frame_acknowledge_pdu(RdpgfxServerContext* context, + wStream* s) +{ + RDPGFX_FRAME_ACKNOWLEDGE_PDU pdu; + UINT error = CHANNEL_RC_OK; + + if (Stream_GetRemainingLength(s) < 12) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT32(s, pdu.queueDepth); /* queueDepth (4 bytes) */ + Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ + /* totalFramesDecoded (4 bytes) */ + Stream_Read_UINT32(s, pdu.totalFramesDecoded); + + if (context) + { + IFCALLRET(context->FrameAcknowledge, error, context, &pdu); + + if (error) + WLog_ERR(TAG, "context->FrameAcknowledge failed with error %u", + error); + } + + return error; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_recv_cache_import_offer_pdu(RdpgfxServerContext* context, + wStream* s) +{ + UINT16 index; + RDPGFX_CACHE_IMPORT_OFFER_PDU pdu; + RDPGFX_CACHE_ENTRY_METADATA* cacheEntries; + UINT error = CHANNEL_RC_OK; + + if (Stream_GetRemainingLength(s) < 2) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } + + /* cacheEntriesCount (2 bytes) */ + Stream_Read_UINT16(s, pdu.cacheEntriesCount); + + if (pdu.cacheEntriesCount <= 0) + { + /* According to the latest spec, capsSetCount <= 3 */ + WLog_ERR(TAG, "Invalid cacheEntriesCount: %u", pdu.cacheEntriesCount); + return ERROR_INVALID_DATA; + } + + if (Stream_GetRemainingLength(s) < (pdu.cacheEntriesCount * 12)) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } + + pdu.cacheEntries = (RDPGFX_CACHE_ENTRY_METADATA*) + calloc(pdu.cacheEntriesCount, + sizeof(RDPGFX_CACHE_ENTRY_METADATA)); + + if (!pdu.cacheEntries) + { + WLog_ERR(TAG, "calloc failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + for (index = 0; index < pdu.cacheEntriesCount; index++) + { + cacheEntries = &(pdu.cacheEntries[index]); + Stream_Read_UINT64(s, cacheEntries->cacheKey); /* cacheKey (8 bytes) */ + /* bitmapLength (4 bytes) */ + Stream_Read_UINT32(s, cacheEntries->bitmapLength); + } + + if (context) + { + IFCALLRET(context->CacheImportOffer, error, context, &pdu); + + if (error) + WLog_ERR(TAG, "context->CacheImportOffer failed with error %u", + error); + } + + free(pdu.cacheEntries); + return error; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context, + wStream* s) +{ + UINT16 index; + RDPGFX_CAPSET* capsSets; + RDPGFX_CAPS_ADVERTISE_PDU pdu; + UINT error = CHANNEL_RC_OK; + UINT32 capsDataLength; + + if (Stream_GetRemainingLength(s) < 2) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */ + + if (Stream_GetRemainingLength(s) < (pdu.capsSetCount * RDPGFX_CAPSET_SIZE)) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } + + capsSets = calloc(pdu.capsSetCount, RDPGFX_CAPSET_SIZE); + + if (!capsSets) + return ERROR_OUTOFMEMORY; + + pdu.capsSets = (RDPGFX_CAPSET*) capsSets; + + for (index = 0; index < pdu.capsSetCount; index++) + { + RDPGFX_CAPSET* capsSet = &(pdu.capsSets[index]); + Stream_Read_UINT32(s, capsSet->version); /* version (4 bytes) */ + Stream_Read_UINT32(s, capsDataLength); /* capsDataLength (4 bytes) */ + + if (capsDataLength != 4) + { + WLog_ERR(TAG, "capsDataLength does not equal to 4: %u", + capsDataLength); + free(capsSets); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT32(s, capsSet->flags); /* capsData (4 bytes) */ + } + + if (context) + { + IFCALLRET(context->CapsAdvertise, error, context, &pdu); + + if (error) + WLog_ERR(TAG, "context->CapsAdvertise failed with error %u", error); + } + + free(capsSets); + return error; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_recv_qoe_frame_acknowledge_pdu(RdpgfxServerContext* context, + wStream* s) +{ + RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU pdu; + UINT error = CHANNEL_RC_OK; + + if (Stream_GetRemainingLength(s) < 12) + { + WLog_ERR(TAG, "not enough data!"); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ + Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */ + Stream_Read_UINT16(s, pdu.timeDiffSE); /* timeDiffSE (2 bytes) */ + Stream_Read_UINT16(s, pdu.timeDiffEDR); /* timeDiffEDR (2 bytes) */ + + if (context) + { + IFCALLRET(context->QoeFrameAcknowledge, error, context, &pdu); + + if (error) + WLog_ERR(TAG, "context->QoeFrameAcknowledge failed with error %u", + error); + } + + return error; +} + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT rdpgfx_server_receive_pdu(RdpgfxServerContext* context, wStream* s) +{ + int beg, end; + RDPGFX_HEADER header; + UINT error = CHANNEL_RC_OK; + beg = Stream_GetPosition(s); + + if ((error = rdpgfx_read_header(s, &header))) + { + WLog_ERR(TAG, "rdpgfx_read_header failed with error %u!", error); + return error; + } + + WLog_DBG(TAG, "cmdId: %s (0x%04X) flags: 0x%04X pduLength: %d", + rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, + header.flags, header.pduLength); + + switch (header.cmdId) + { + case RDPGFX_CMDID_FRAMEACKNOWLEDGE: + if ((error = rdpgfx_recv_frame_acknowledge_pdu(context, s))) + WLog_ERR(TAG, "rdpgfx_recv_frame_acknowledge_pdu " + "failed with error %u!", error); + + break; + + case RDPGFX_CMDID_CACHEIMPORTOFFER: + if ((error = rdpgfx_recv_cache_import_offer_pdu(context, s))) + WLog_ERR(TAG, "rdpgfx_recv_cache_import_offer_pdu " + "failed with error %u!", error); + + break; + + case RDPGFX_CMDID_CAPSADVERTISE: + if ((error = rdpgfx_recv_caps_advertise_pdu(context, s))) + WLog_ERR(TAG, "rdpgfx_recv_caps_advertise_pdu " + "failed with error %u!", error); + + break; + + case RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE: + if ((error = rdpgfx_recv_qoe_frame_acknowledge_pdu(context, s))) + WLog_ERR(TAG, "rdpgfx_recv_qoe_frame_acknowledge_pdu " + "failed with error %u!", error); + + break; + + default: + error = CHANNEL_RC_BAD_PROC; + break; + } + + if (error) + { + WLog_ERR(TAG, "Error while parsing GFX cmdId: %s (0x%04X)", + rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId); + return error; + } + + end = Stream_GetPosition(s); + + if (end != (beg + header.pduLength)) + { + WLog_ERR(TAG, "Unexpected gfx pdu end: Actual: %d, Expected: %d", + end, (beg + header.pduLength)); + Stream_SetPosition(s, (beg + header.pduLength)); + } + + return error; +} + +static void* rdpgfx_server_thread_func(void* arg) +{ + RdpgfxServerContext* context = (RdpgfxServerContext*) arg; + RdpgfxServerPrivate* priv = context->priv; + DWORD status; + DWORD nCount; + void* buffer; + HANDLE events[8]; + DWORD BytesReturned = 0; + UINT error = CHANNEL_RC_OK; + buffer = NULL; + BytesReturned = 0; + nCount = 0; + + events[nCount++] = priv->stopEvent; + events[nCount++] = priv->channelEvent; + + /* Main virtual channel loop. RDPGFX do not need version negotiation */ + while (TRUE) + { + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error); + break; + } + + /* Stop Event */ + if (status == WAIT_OBJECT_0) + break; + + if ((error = rdpgfx_server_handle_messages(context))) + { + WLog_ERR(TAG, "rdpgfx_server_handle_messages failed with error %u", + error); + break; + } + } + + if (error && context->rdpcontext) + setChannelError(context->rdpcontext, error, + "rdpgfx_server_thread_func reported an error"); + + ExitThread((DWORD)error); + return NULL; +} + +static BOOL rdpgfx_server_open(RdpgfxServerContext* context) +{ + RdpgfxServerPrivate* priv = (RdpgfxServerPrivate*) context->priv; + void* buffer = NULL; + + if (!priv->isOpened) + { + PULONG pSessionId = NULL; + DWORD BytesReturned = 0; + priv->SessionId = WTS_CURRENT_SESSION; + + if (WTSQuerySessionInformationA(context->vcm, WTS_CURRENT_SESSION, + WTSSessionId, (LPSTR*) &pSessionId, + &BytesReturned) == FALSE) + { + WLog_ERR(TAG, "WTSQuerySessionInformationA failed!"); + return FALSE; + } + + priv->SessionId = (DWORD) * pSessionId; + WTSFreeMemory(pSessionId); + priv->rdpgfx_channel = WTSVirtualChannelOpenEx(priv->SessionId, + RDPGFX_DVC_CHANNEL_NAME, + WTS_CHANNEL_OPTION_DYNAMIC); + + if (!priv->rdpgfx_channel) + { + WLog_ERR(TAG, "WTSVirtualChannelOpenEx failed!"); + return FALSE; + } + + /* Query for channel event handle */ + if (!WTSVirtualChannelQuery(priv->rdpgfx_channel, WTSVirtualEventHandle, + &buffer, &BytesReturned) + || (BytesReturned != sizeof(HANDLE))) + { + WLog_ERR(TAG, "WTSVirtualChannelQuery failed " + "or invalid returned size(%d)", + BytesReturned); + + if (buffer) + WTSFreeMemory(buffer); + + goto out_close; + } + + CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE)); + WTSFreeMemory(buffer); + + if (!(priv->zgfx = zgfx_context_new(TRUE))) + { + WLog_ERR(TAG, "Create zgfx context failed!"); + goto out_close; + } + + if (priv->ownThread) + { + if (!(priv->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + WLog_ERR(TAG, "CreateEvent failed!"); + goto out_zgfx; + } + + if (!(priv->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) + rdpgfx_server_thread_func, + (void*) context, 0, NULL))) + { + WLog_ERR(TAG, "CreateThread failed!"); + goto out_stopEvent; + } + } + + priv->isOpened = TRUE; + priv->isReady = FALSE; + return TRUE; + } + + WLog_ERR(TAG, "RDPGFX channel is already opened!"); + return FALSE; +out_stopEvent: + CloseHandle(priv->stopEvent); + priv->stopEvent = NULL; +out_zgfx: + zgfx_context_free(priv->zgfx); + priv->zgfx = NULL; +out_close: + WTSVirtualChannelClose(priv->rdpgfx_channel); + priv->rdpgfx_channel = NULL; + priv->channelEvent = NULL; + return FALSE; +} + +static BOOL rdpgfx_server_close(RdpgfxServerContext* context) +{ + RdpgfxServerPrivate* priv = (RdpgfxServerPrivate*) context->priv; + + if (priv->ownThread && priv->thread) + { + SetEvent(priv->stopEvent); + + if (WaitForSingleObject(priv->thread, INFINITE) == WAIT_FAILED) + { + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", + (unsigned long)GetLastError()); + return FALSE; + } + + CloseHandle(priv->thread); + CloseHandle(priv->stopEvent); + priv->thread = NULL; + priv->stopEvent = NULL; + } + + zgfx_context_free(priv->zgfx); + priv->zgfx = NULL; + + if (priv->rdpgfx_channel) + { + WTSVirtualChannelClose(priv->rdpgfx_channel); + priv->rdpgfx_channel = NULL; + } + + priv->channelEvent = NULL; + priv->isOpened = FALSE; + priv->isReady = FALSE; + return TRUE; +} + +RdpgfxServerContext* rdpgfx_server_context_new(HANDLE vcm) +{ + RdpgfxServerContext* context; + RdpgfxServerPrivate* priv; + context = (RdpgfxServerContext*)calloc(1, sizeof(RdpgfxServerContext)); + + if (!context) + { + WLog_ERR(TAG, "calloc failed!"); + return NULL; + } + + context->vcm = vcm; + context->Open = rdpgfx_server_open; + context->Close = rdpgfx_server_close; + context->ResetGraphics = rdpgfx_send_reset_graphics_pdu; + context->StartFrame = rdpgfx_send_start_frame_pdu; + context->EndFrame = rdpgfx_send_end_frame_pdu; + context->SurfaceCommand = rdpgfx_send_surface_command; + context->SurfaceFrameCommand = rdpgfx_send_surface_frame_command; + context->DeleteEncodingContext = rdpgfx_send_delete_encoding_context_pdu; + context->CreateSurface = rdpgfx_send_create_surface_pdu; + context->DeleteSurface = rdpgfx_send_delete_surface_pdu; + context->SolidFill = rdpgfx_send_solid_fill_pdu; + context->SurfaceToSurface = rdpgfx_send_surface_to_surface_pdu; + context->SurfaceToCache = rdpgfx_send_surface_to_cache_pdu; + context->CacheToSurface = rdpgfx_send_cache_to_surface_pdu; + context->CacheImportOffer = NULL; + context->CacheImportReply = rdpgfx_send_cache_import_reply_pdu; + context->EvictCacheEntry = rdpgfx_send_evict_cache_entry_pdu; + context->MapSurfaceToOutput = rdpgfx_send_map_surface_to_output_pdu; + context->MapSurfaceToWindow = rdpgfx_send_map_surface_to_window_pdu; + context->CapsAdvertise = NULL; + context->CapsConfirm = rdpgfx_send_caps_confirm_pdu; + context->FrameAcknowledge = NULL; + context->QoeFrameAcknowledge = NULL; + context->priv = priv = (RdpgfxServerPrivate*) + calloc(1, sizeof(RdpgfxServerPrivate)); + + if (!priv) + { + WLog_ERR(TAG, "calloc failed!"); + goto out_free; + } + + /* Create shared input stream */ + priv->input_stream = Stream_New(NULL, 4); + + if (!priv->input_stream) + { + WLog_ERR(TAG, "Stream_New failed!"); + goto out_free_priv; + } + + priv->isOpened = FALSE; + priv->isReady = FALSE; + priv->ownThread = TRUE; + return (RdpgfxServerContext*) context; +out_free_priv: + free(context->priv); +out_free: + free(context); + return NULL; +} + +void rdpgfx_server_context_free(RdpgfxServerContext* context) +{ + rdpgfx_server_close(context); + + if (context->priv) + Stream_Free(context->priv->input_stream, TRUE); + + free(context->priv); + free(context); +} + +HANDLE rdpgfx_server_get_event_handle(RdpgfxServerContext* context) +{ + return context->priv->channelEvent; +} + +/* + * Handle rpdgfx messages - server side + * + * @param Server side context + * + * @return 0 on success + * ERROR_NO_DATA if no data could be read this time + * otherwise a Win32 error code + */ +UINT rdpgfx_server_handle_messages(RdpgfxServerContext* context) +{ + DWORD BytesReturned; + void* buffer; + UINT ret = CHANNEL_RC_OK; + RdpgfxServerPrivate* priv = context->priv; + wStream* s = priv->input_stream; + + /* Check whether the dynamic channel is ready */ + if (!priv->isReady) + { + if (WTSVirtualChannelQuery(priv->rdpgfx_channel, + WTSVirtualChannelReady, + &buffer, &BytesReturned) == FALSE) + { + if (GetLastError() == ERROR_NO_DATA) + return ERROR_NO_DATA; + + WLog_ERR(TAG, "WTSVirtualChannelQuery failed"); + return ERROR_INTERNAL_ERROR; + } + + priv->isReady = *((BOOL*) buffer); + WTSFreeMemory(buffer); + } + + /* Consume channel event only after the gfx dynamic channel is ready */ + if (priv->isReady) + { + Stream_SetPosition(s, 0); + + if (!WTSVirtualChannelRead(priv->rdpgfx_channel, + 0, NULL, 0, &BytesReturned)) + { + if (GetLastError() == ERROR_NO_DATA) + return ERROR_NO_DATA; + + WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); + return ERROR_INTERNAL_ERROR; + } + + if (BytesReturned < 1) + return CHANNEL_RC_OK; + + if (!Stream_EnsureRemainingCapacity(s, BytesReturned)) + { + WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + if (WTSVirtualChannelRead(priv->rdpgfx_channel, 0, + (PCHAR) Stream_Buffer(s), + Stream_Capacity(s), &BytesReturned) == FALSE) + { + WLog_ERR(TAG, "WTSVirtualChannelRead failed!"); + return ERROR_INTERNAL_ERROR; + } + + Stream_SetLength(s, BytesReturned); + Stream_SetPosition(s, 0); + + while (((size_t) Stream_GetPosition(s)) < Stream_Length(s)) + { + if ((ret = rdpgfx_server_receive_pdu(context, s))) + { + WLog_ERR(TAG, "rdpgfx_server_receive_pdu " + "failed with error %u!", ret); + return ret; + } + } + } + + return ret; +} diff --git a/channels/rdpgfx/server/rdpgfx_main.h b/channels/rdpgfx/server/rdpgfx_main.h new file mode 100644 index 0000000..be29b76 --- /dev/null +++ b/channels/rdpgfx/server/rdpgfx_main.h @@ -0,0 +1,40 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Graphics Pipeline Extension + * + * Copyright 2016 Jiang Zihao + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H +#define FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H + +#include +#include + +struct _rdpgfx_server_private +{ + ZGFX_CONTEXT* zgfx; + BOOL ownThread; + HANDLE thread; + HANDLE stopEvent; + HANDLE channelEvent; + void* rdpgfx_channel; + DWORD SessionId; + wStream* input_stream; + BOOL isOpened; + BOOL isReady; +}; + +#endif /* FREERDP_CHANNEL_RDPGFX_SERVER_MAIN_H */ diff --git a/channels/rdpsnd/client/CMakeLists.txt b/channels/rdpsnd/client/CMakeLists.txt index fb5dae0..6e166b2 100644 --- a/channels/rdpsnd/client/CMakeLists.txt +++ b/channels/rdpsnd/client/CMakeLists.txt @@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS rdpsnd_main.c rdpsnd_main.h) -add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") +add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx") diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index ea4230d..49c766d 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -647,7 +647,7 @@ static UINT rdpsnd_alsa_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_rdpsnd_client_subsystem_entry alsa_freerdp_rdpsnd_client_subsystem_entry #else #define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry @@ -686,7 +686,7 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p { if ((error = rdpsnd_alsa_parse_addin_args((rdpsndDevicePlugin *) alsa, args))) { - WLog_ERR(TAG, "rdpsnd_alsa_parse_addin_args failed with error %lu", error); + WLog_ERR(TAG, "rdpsnd_alsa_parse_addin_args failed with error %u", error); goto error_parse_args; } } diff --git a/channels/rdpsnd/client/ios/rdpsnd_ios.c b/channels/rdpsnd/client/ios/rdpsnd_ios.c index 148c846..6108def 100644 --- a/channels/rdpsnd/client/ios/rdpsnd_ios.c +++ b/channels/rdpsnd/client/ios/rdpsnd_ios.c @@ -279,7 +279,7 @@ static void rdpsnd_ios_free(rdpsndDevicePlugin* device) free(p); } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_rdpsnd_client_subsystem_entry ios_freerdp_rdpsnd_client_subsystem_entry #else #define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry diff --git a/channels/rdpsnd/client/mac/rdpsnd_mac.c b/channels/rdpsnd/client/mac/rdpsnd_mac.c index a2162a2..a73f8ac 100644 --- a/channels/rdpsnd/client/mac/rdpsnd_mac.c +++ b/channels/rdpsnd/client/mac/rdpsnd_mac.c @@ -34,6 +34,9 @@ #include #include +#define __COREFOUNDATION_CFPLUGINCOM__ 1 +#define IUNKNOWN_C_GUTS void *_reserved; void* QueryInterface; void* AddRef; void* Release + #include #include @@ -324,6 +327,8 @@ static void rdpsnd_mac_waveplay(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) length = wave->length > audioBuffer->mAudioDataBytesCapacity ? audioBuffer->mAudioDataBytesCapacity : wave->length; CopyMemory(audioBuffer->mAudioData, wave->data, length); + free(wave->data); + wave->data = NULL; audioBuffer->mAudioDataByteSize = length; audioBuffer->mUserData = wave; @@ -343,7 +348,7 @@ static void rdpsnd_mac_waveplay(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) device->Start(device); } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_rdpsnd_client_subsystem_entry mac_freerdp_rdpsnd_client_subsystem_entry #else #define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry diff --git a/channels/rdpsnd/client/opensles/opensl_io.c b/channels/rdpsnd/client/opensles/opensl_io.c index 282268e..033232f 100644 --- a/channels/rdpsnd/client/opensles/opensl_io.c +++ b/channels/rdpsnd/client/opensles/opensl_io.c @@ -6,14 +6,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -34,203 +34,238 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define CONV16BIT 32768 #define CONVMYFLT (1./32768.) -static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context); +static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context); // creates the OpenSL ES audio engine -static SLresult openSLCreateEngine(OPENSL_STREAM *p) +static SLresult openSLCreateEngine(OPENSL_STREAM* p) { - SLresult result; - // create engine - result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); + SLresult result; + // create engine + result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); DEBUG_SND("engineObject=%p", p->engineObject); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // realize the engine - result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // realize the engine + result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); DEBUG_SND("Realize=%d", result); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // get the engine interface, which is needed in order to create other objects - result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine)); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // get the engine interface, which is needed in order to create other objects + result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, + &(p->engineEngine)); DEBUG_SND("engineEngine=%p", p->engineEngine); - if(result != SL_RESULT_SUCCESS) goto engine_end; - engine_end: - return result; + if (result != SL_RESULT_SUCCESS) goto engine_end; + +engine_end: + return result; } // opens the OpenSL ES device for output -static SLresult openSLPlayOpen(OPENSL_STREAM *p) +static SLresult openSLPlayOpen(OPENSL_STREAM* p) { - SLresult result; - SLuint32 sr = p->sr; - SLuint32 channels = p->outchannels; - + SLresult result; + SLuint32 sr = p->sr; + SLuint32 channels = p->outchannels; assert(p->engineObject); assert(p->engineEngine); - if(channels){ - // configure audio source - SLDataLocator_AndroidSimpleBufferQueue loc_bufq = + if (channels) + { + // configure audio source + SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, p->queuesize }; - switch(sr){ + switch (sr) + { + case 8000: + sr = SL_SAMPLINGRATE_8; + break; - case 8000: - sr = SL_SAMPLINGRATE_8; - break; - case 11025: - sr = SL_SAMPLINGRATE_11_025; - break; - case 16000: - sr = SL_SAMPLINGRATE_16; - break; - case 22050: - sr = SL_SAMPLINGRATE_22_05; - break; - case 24000: - sr = SL_SAMPLINGRATE_24; - break; - case 32000: - sr = SL_SAMPLINGRATE_32; - break; - case 44100: - sr = SL_SAMPLINGRATE_44_1; - break; - case 48000: - sr = SL_SAMPLINGRATE_48; - break; - case 64000: - sr = SL_SAMPLINGRATE_64; - break; - case 88200: - sr = SL_SAMPLINGRATE_88_2; - break; - case 96000: - sr = SL_SAMPLINGRATE_96; - break; - case 192000: - sr = SL_SAMPLINGRATE_192; - break; - default: - return -1; - } - - const SLInterfaceID ids[] = {SL_IID_VOLUME}; - const SLboolean req[] = {SL_BOOLEAN_FALSE}; - result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req); + case 11025: + sr = SL_SAMPLINGRATE_11_025; + break; + + case 16000: + sr = SL_SAMPLINGRATE_16; + break; + + case 22050: + sr = SL_SAMPLINGRATE_22_05; + break; + + case 24000: + sr = SL_SAMPLINGRATE_24; + break; + + case 32000: + sr = SL_SAMPLINGRATE_32; + break; + + case 44100: + sr = SL_SAMPLINGRATE_44_1; + break; + + case 48000: + sr = SL_SAMPLINGRATE_48; + break; + + case 64000: + sr = SL_SAMPLINGRATE_64; + break; + + case 88200: + sr = SL_SAMPLINGRATE_88_2; + break; + + case 96000: + sr = SL_SAMPLINGRATE_96; + break; + + case 192000: + sr = SL_SAMPLINGRATE_192; + break; + + default: + return -1; + } + + const SLInterfaceID ids[] = {SL_IID_VOLUME}; + const SLboolean req[] = {SL_BOOLEAN_FALSE}; + result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, + &(p->outputMixObject), 1, ids, req); DEBUG_SND("engineEngine=%p", p->engineEngine); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // realize the output mix - result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // realize the output mix + result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE); DEBUG_SND("Realize=%d", result); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - - int speakers; - if(channels > 1) - speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; - else speakers = SL_SPEAKER_FRONT_CENTER; - SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,channels, sr, - SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, - speakers, SL_BYTEORDER_LITTLEENDIAN}; - SLDataSource audioSrc = {&loc_bufq, &format_pcm}; + if (result != SL_RESULT_SUCCESS) goto end_openaudio; - // configure audio sink - SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject}; - SLDataSink audioSnk = {&loc_outmix, NULL}; + int speakers; - // create audio player - const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME}; - const SLboolean req1[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; - result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine, - &(p->bqPlayerObject), &audioSrc, &audioSnk, 2, ids1, req1); + if (channels > 1) + speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; + else speakers = SL_SPEAKER_FRONT_CENTER; + + SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channels, sr, + SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, + speakers, SL_BYTEORDER_LITTLEENDIAN + }; + SLDataSource audioSrc = {&loc_bufq, &format_pcm}; + // configure audio sink + SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject}; + SLDataSink audioSnk = {&loc_outmix, NULL}; + // create audio player + const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME}; + const SLboolean req1[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; + result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine, + &(p->bqPlayerObject), &audioSrc, &audioSnk, 2, ids1, req1); DEBUG_SND("bqPlayerObject=%p", p->bqPlayerObject); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // realize the player - result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // realize the player + result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE); DEBUG_SND("Realize=%d", result); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // get the play interface - result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, &(p->bqPlayerPlay)); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // get the play interface + result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, + &(p->bqPlayerPlay)); DEBUG_SND("bqPlayerPlay=%p", p->bqPlayerPlay); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // get the volume interface - result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_VOLUME, &(p->bqPlayerVolume)); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // get the volume interface + result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_VOLUME, + &(p->bqPlayerVolume)); DEBUG_SND("bqPlayerVolume=%p", p->bqPlayerVolume); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // get the buffer queue interface - result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, - &(p->bqPlayerBufferQueue)); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // get the buffer queue interface + result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, + SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &(p->bqPlayerBufferQueue)); DEBUG_SND("bqPlayerBufferQueue=%p", p->bqPlayerBufferQueue); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // register callback on the buffer queue - result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // register callback on the buffer queue + result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, + bqPlayerCallback, p); DEBUG_SND("bqPlayerCallback=%p", p->bqPlayerCallback); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // set the player's state to playing - result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, SL_PLAYSTATE_PLAYING); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // set the player's state to playing + result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, + SL_PLAYSTATE_PLAYING); DEBUG_SND("SetPlayState=%d", result); assert(!result); - - end_openaudio: + end_openaudio: assert(!result); - return result; - } - return SL_RESULT_SUCCESS; + return result; + } + + return SL_RESULT_SUCCESS; } // close the OpenSL IO and destroy the audio engine -static void openSLDestroyEngine(OPENSL_STREAM *p){ +static void openSLDestroyEngine(OPENSL_STREAM* p) +{ + // destroy buffer queue audio player object, and invalidate all associated interfaces + if (p->bqPlayerObject != NULL) + { + (*p->bqPlayerObject)->Destroy(p->bqPlayerObject); + p->bqPlayerObject = NULL; + p->bqPlayerVolume = NULL; + p->bqPlayerPlay = NULL; + p->bqPlayerBufferQueue = NULL; + p->bqPlayerEffectSend = NULL; + } - // destroy buffer queue audio player object, and invalidate all associated interfaces - if (p->bqPlayerObject != NULL) { - (*p->bqPlayerObject)->Destroy(p->bqPlayerObject); - p->bqPlayerObject = NULL; - p->bqPlayerVolume = NULL; - p->bqPlayerPlay = NULL; - p->bqPlayerBufferQueue = NULL; - p->bqPlayerEffectSend = NULL; - } - - // destroy output mix object, and invalidate all associated interfaces - if (p->outputMixObject != NULL) { - (*p->outputMixObject)->Destroy(p->outputMixObject); - p->outputMixObject = NULL; - } - - // destroy engine object, and invalidate all associated interfaces - if (p->engineObject != NULL) { - (*p->engineObject)->Destroy(p->engineObject); - p->engineObject = NULL; - p->engineEngine = NULL; - } + // destroy output mix object, and invalidate all associated interfaces + if (p->outputMixObject != NULL) + { + (*p->outputMixObject)->Destroy(p->outputMixObject); + p->outputMixObject = NULL; + } + // destroy engine object, and invalidate all associated interfaces + if (p->engineObject != NULL) + { + (*p->engineObject)->Destroy(p->engineObject); + p->engineObject = NULL; + p->engineEngine = NULL; + } } // open the android audio device for and/or output -OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes){ - OPENSL_STREAM *p; - p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM), 1); +OPENSL_STREAM* android_OpenAudioDevice(int sr, int outchannels, + int bufferframes) +{ + OPENSL_STREAM* p; + p = (OPENSL_STREAM*) calloc(sizeof(OPENSL_STREAM), 1); + if (!p) return NULL; @@ -238,19 +273,20 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes p->outchannels = outchannels; p->sr = sr; - if(openSLCreateEngine(p) != SL_RESULT_SUCCESS) + if (openSLCreateEngine(p) != SL_RESULT_SUCCESS) { android_CloseAudioDevice(p); return NULL; } - if(openSLPlayOpen(p) != SL_RESULT_SUCCESS) + if (openSLPlayOpen(p) != SL_RESULT_SUCCESS) { android_CloseAudioDevice(p); return NULL; } p->queue = Queue_New(TRUE, -1, -1); + if (!p->queue) { android_CloseAudioDevice(p); @@ -261,107 +297,120 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes } // close the android audio device -void android_CloseAudioDevice(OPENSL_STREAM *p){ +void android_CloseAudioDevice(OPENSL_STREAM* p) +{ + if (p == NULL) + return; - if (p == NULL) - return; + openSLDestroyEngine(p); - openSLDestroyEngine(p); if (p->queue) Queue_Free(p->queue); - free(p); + free(p); } // this callback handler is called every time a buffer finishes playing -void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) +static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context) { - OPENSL_STREAM *p = (OPENSL_STREAM *) context; - + OPENSL_STREAM* p = (OPENSL_STREAM*) context; assert(p); assert(p->queue); - - void *data = Queue_Dequeue(p->queue); + void* data = Queue_Dequeue(p->queue); free(data); } // puts a buffer of size samples to the device -int android_AudioOut(OPENSL_STREAM *p, const short *buffer,int size) +int android_AudioOut(OPENSL_STREAM* p, const short* buffer, int size) { assert(p); assert(buffer); assert(size > 0); /* Assure, that the queue is not full. */ - if (p->queuesize <= Queue_Count(p->queue) && WaitForSingleObject(p->queue->event, INFINITE) == WAIT_FAILED) - { - DEBUG_SND("WaitForSingleObject failed!"); - return -1; - } + if (p->queuesize <= Queue_Count(p->queue) + && WaitForSingleObject(p->queue->event, INFINITE) == WAIT_FAILED) + { + DEBUG_SND("WaitForSingleObject failed!"); + return -1; + } + + void* data = calloc(size, sizeof(short)); - void *data = calloc(size, sizeof(short)); if (!data) { DEBUG_SND("unable to allocate a buffer"); return -1; } + memcpy(data, buffer, size * sizeof(short)); Queue_Enqueue(p->queue, data); - (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, - data, sizeof(short) * size); - + (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, + data, sizeof(short) * size); return size; } -int android_GetOutputMute(OPENSL_STREAM *p) { +int android_GetOutputMute(OPENSL_STREAM* p) +{ SLboolean mute; - assert(p); assert(p->bqPlayerVolume); - SLresult rc = (*p->bqPlayerVolume)->GetMute(p->bqPlayerVolume, &mute); - assert(SL_RESULT_SUCCESS == rc); + + if (SL_RESULT_SUCCESS != rc) + return SL_BOOLEAN_FALSE; return mute; } -void android_SetOutputMute(OPENSL_STREAM *p, BOOL _mute) { +BOOL android_SetOutputMute(OPENSL_STREAM* p, BOOL _mute) +{ SLboolean mute = _mute; - assert(p); assert(p->bqPlayerVolume); - SLresult rc = (*p->bqPlayerVolume)->SetMute(p->bqPlayerVolume, mute); - assert(SL_RESULT_SUCCESS == rc); + + if (SL_RESULT_SUCCESS != rc) + return FALSE; + + return TRUE; } -int android_GetOutputVolume(OPENSL_STREAM *p){ +int android_GetOutputVolume(OPENSL_STREAM* p) +{ SLmillibel level; - assert(p); assert(p->bqPlayerVolume); - SLresult rc = (*p->bqPlayerVolume)->GetVolumeLevel(p->bqPlayerVolume, &level); - assert(SL_RESULT_SUCCESS == rc); + + if (SL_RESULT_SUCCESS != rc) + return 0; return level; } -int android_GetOutputVolumeMax(OPENSL_STREAM *p){ +int android_GetOutputVolumeMax(OPENSL_STREAM* p) +{ SLmillibel level; - assert(p); assert(p->bqPlayerVolume); + SLresult rc = (*p->bqPlayerVolume)->GetMaxVolumeLevel(p->bqPlayerVolume, + &level); - SLresult rc = (*p->bqPlayerVolume)->GetMaxVolumeLevel(p->bqPlayerVolume, &level); - assert(SL_RESULT_SUCCESS == rc); + if (SL_RESULT_SUCCESS != rc) + return 0; return level; } -void android_SetOutputVolume(OPENSL_STREAM *p, int level){ +BOOL android_SetOutputVolume(OPENSL_STREAM* p, int level) +{ SLresult rc = (*p->bqPlayerVolume)->SetVolumeLevel(p->bqPlayerVolume, level); - assert(SL_RESULT_SUCCESS == rc); + + if (SL_RESULT_SUCCESS != rc) + return FALSE; + + return TRUE; } diff --git a/channels/rdpsnd/client/opensles/opensl_io.h b/channels/rdpsnd/client/opensles/opensl_io.h index 3a6762f..00e4f12 100644 --- a/channels/rdpsnd/client/opensles/opensl_io.h +++ b/channels/rdpsnd/client/opensles/opensl_io.h @@ -6,14 +6,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -35,70 +35,75 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include + #ifdef __cplusplus extern "C" { #endif -typedef struct opensl_stream { - // engine interfaces - SLObjectItf engineObject; - SLEngineItf engineEngine; +typedef struct opensl_stream +{ + // engine interfaces + SLObjectItf engineObject; + SLEngineItf engineEngine; - // output mix interfaces - SLObjectItf outputMixObject; + // output mix interfaces + SLObjectItf outputMixObject; - // buffer queue player interfaces - SLObjectItf bqPlayerObject; - SLPlayItf bqPlayerPlay; + // buffer queue player interfaces + SLObjectItf bqPlayerObject; + SLPlayItf bqPlayerPlay; SLVolumeItf bqPlayerVolume; - SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; - SLEffectSendItf bqPlayerEffectSend; + SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; + SLEffectSendItf bqPlayerEffectSend; - unsigned int outchannels; - unsigned int sr; + unsigned int outchannels; + unsigned int sr; unsigned int queuesize; - wQueue *queue; + wQueue* queue; } OPENSL_STREAM; - /* - Open the audio device with a given sampling rate (sr), output channels and IO buffer size - in frames. Returns a handle to the OpenSL stream - */ - OPENSL_STREAM* android_OpenAudioDevice(int sr, int outchannels, int bufferframes); - /* - Close the audio device - */ - void android_CloseAudioDevice(OPENSL_STREAM *p); - /* - Write a buffer to the OpenSL stream *p, of size samples. Returns the number of samples written. - */ - int android_AudioOut(OPENSL_STREAM *p, const short *buffer, int size); - /* - * Set the volume input level. - */ - void android_SetInputVolume(OPENSL_STREAM *p, int level); - /* - * Get the current output mute setting. - */ - int android_GetOutputMute(OPENSL_STREAM *p); - /* - * Change the current output mute setting. - */ - void android_SetOutputMute(OPENSL_STREAM *p, BOOL mute); - /* - * Get the current output volume level. - */ - int android_GetOutputVolume(OPENSL_STREAM *p); - /* - * Get the maximum output volume level. - */ - int android_GetOutputVolumeMax(OPENSL_STREAM *p); +/* +Open the audio device with a given sampling rate (sr), output channels and IO buffer size +in frames. Returns a handle to the OpenSL stream +*/ +FREERDP_LOCAL OPENSL_STREAM* android_OpenAudioDevice(int sr, int outchannels, + int bufferframes); +/* +Close the audio device +*/ +FREERDP_LOCAL void android_CloseAudioDevice(OPENSL_STREAM* p); +/* +Write a buffer to the OpenSL stream *p, of size samples. Returns the number of samples written. +*/ +FREERDP_LOCAL int android_AudioOut(OPENSL_STREAM* p, const short* buffer, + int size); +/* + * Set the volume input level. + */ +FREERDP_LOCAL void android_SetInputVolume(OPENSL_STREAM* p, int level); +/* + * Get the current output mute setting. + */ +FREERDP_LOCAL int android_GetOutputMute(OPENSL_STREAM* p); +/* + * Change the current output mute setting. + */ +FREERDP_LOCAL BOOL android_SetOutputMute(OPENSL_STREAM* p, BOOL mute); +/* + * Get the current output volume level. + */ +FREERDP_LOCAL int android_GetOutputVolume(OPENSL_STREAM* p); +/* + * Get the maximum output volume level. + */ +FREERDP_LOCAL int android_GetOutputVolumeMax(OPENSL_STREAM* p); - /* - * Set the volume output level. - */ - void android_SetOutputVolume(OPENSL_STREAM *p, int level); +/* + * Set the volume output level. + */ +FREERDP_LOCAL BOOL android_SetOutputVolume(OPENSL_STREAM* p, int level); #ifdef __cplusplus }; #endif diff --git a/channels/rdpsnd/client/opensles/rdpsnd_opensles.c b/channels/rdpsnd/client/opensles/rdpsnd_opensles.c index 8c8b34e..bbc5de2 100644 --- a/channels/rdpsnd/client/opensles/rdpsnd_opensles.c +++ b/channels/rdpsnd/client/opensles/rdpsnd_opensles.c @@ -53,7 +53,7 @@ struct rdpsnd_opensles_plugin int block_size; char* device_name; - OPENSL_STREAM *stream; + OPENSL_STREAM* stream; UINT32 volume; @@ -68,10 +68,8 @@ static int rdpsnd_opensles_volume_to_millibel(unsigned short level, int max) const int min = SL_MILLIBEL_MIN; const int step = max - min; const int rc = (level * step / 0xFFFF) + min; - DEBUG_SND("level=%d, min=%d, max=%d, step=%d, result=%d", - level, min, max, step, rc); - + level, min, max, step, rc); return rc; } @@ -80,14 +78,12 @@ static unsigned short rdpsnd_opensles_millibel_to_volume(int millibel, int max) const int min = SL_MILLIBEL_MIN; const int range = max - min; const int rc = ((millibel - min) * 0xFFFF + range / 2 + 1) / range; - DEBUG_SND("millibel=%d, min=%d, max=%d, range=%d, result=%d", - millibel, min, max, range, rc); - + millibel, min, max, range, rc); return rc; } -static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin *hdl) +static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin* hdl) { bool rc = true; @@ -97,6 +93,7 @@ static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin *hdl) { if (!hdl->dsp_context) rc = false; + if (!hdl->stream) rc = false; } @@ -105,11 +102,12 @@ static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin *hdl) } static BOOL rdpsnd_opensles_set_volume(rdpsndDevicePlugin* device, - UINT32 volume); + UINT32 volume); static int rdpsnd_opensles_set_params(rdpsndopenslesPlugin* opensles) { DEBUG_SND("opensles=%p", opensles); + if (!rdpsnd_opensles_check_handle(opensles)) return 0; @@ -117,25 +115,22 @@ static int rdpsnd_opensles_set_params(rdpsndopenslesPlugin* opensles) android_CloseAudioDevice(opensles->stream); opensles->stream = android_OpenAudioDevice( - opensles->rate, opensles->channels, 20); - + opensles->rate, opensles->channels, 20); return 0; } static BOOL rdpsnd_opensles_set_format(rdpsndDevicePlugin* device, - AUDIO_FORMAT* format, int latency) + AUDIO_FORMAT* format, int latency) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; rdpsnd_opensles_check_handle(opensles); - DEBUG_SND("opensles=%p format=%p, latency=%d", opensles, format, latency); if (format) { DEBUG_SND("format=%d, cbsize=%d, samples=%d, bits=%d, channels=%d, align=%d", - format->wFormatTag, format->cbSize, format->nSamplesPerSec, - format->wBitsPerSample, format->nChannels, format->nBlockAlign); - + format->wFormatTag, format->cbSize, format->nSamplesPerSec, + format->wBitsPerSample, format->nChannels, format->nBlockAlign); opensles->rate = format->nSamplesPerSec; opensles->channels = format->nChannels; opensles->format = format->wFormatTag; @@ -144,22 +139,21 @@ static BOOL rdpsnd_opensles_set_format(rdpsndDevicePlugin* device, } opensles->latency = latency; - return (rdpsnd_opensles_set_params(opensles) == 0); } static BOOL rdpsnd_opensles_open(rdpsndDevicePlugin* device, - AUDIO_FORMAT* format, int latency) + AUDIO_FORMAT* format, int latency) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p format=%p, latency=%d, rate=%d", - opensles, format, latency, opensles->rate); - + opensles, format, latency, opensles->rate); + if (rdpsnd_opensles_check_handle(opensles)) return TRUE; - opensles->stream = android_OpenAudioDevice(opensles->rate, opensles->channels, 20); + opensles->stream = android_OpenAudioDevice(opensles->rate, opensles->channels, + 20); assert(opensles->stream); if (!opensles->stream) @@ -174,9 +168,9 @@ static BOOL rdpsnd_opensles_open(rdpsndDevicePlugin* device, static void rdpsnd_opensles_close(rdpsndDevicePlugin* device) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p", opensles); - if( !rdpsnd_opensles_check_handle(opensles)) + + if (!rdpsnd_opensles_check_handle(opensles)) return; android_CloseAudioDevice(opensles->stream); @@ -186,51 +180,46 @@ static void rdpsnd_opensles_close(rdpsndDevicePlugin* device) static void rdpsnd_opensles_free(rdpsndDevicePlugin* device) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p", opensles); assert(opensles); - assert(opensles->device_name); free(opensles->device_name); - assert(opensles->dsp_context); freerdp_dsp_context_free(opensles->dsp_context); - free(opensles); } static BOOL rdpsnd_opensles_format_supported(rdpsndDevicePlugin* device, - AUDIO_FORMAT* format) + AUDIO_FORMAT* format) { - rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("format=%d, cbsize=%d, samples=%d, bits=%d, channels=%d, align=%d", - format->wFormatTag, format->cbSize, format->nSamplesPerSec, - format->wBitsPerSample, format->nChannels, format->nBlockAlign); - - assert(opensles); + format->wFormatTag, format->cbSize, format->nSamplesPerSec, + format->wBitsPerSample, format->nChannels, format->nBlockAlign); + assert(device); assert(format); switch (format->wFormatTag) { case WAVE_FORMAT_PCM: if (format->cbSize == 0 && - format->nSamplesPerSec <= 48000 && - (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && - (format->nChannels == 1 || format->nChannels == 2)) + format->nSamplesPerSec <= 48000 && + (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && + (format->nChannels == 1 || format->nChannels == 2)) { return TRUE; } + break; case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_DVI_ADPCM: if (format->nSamplesPerSec <= 48000 && - format->wBitsPerSample == 4 && - (format->nChannels == 1 || format->nChannels == 2)) + format->wBitsPerSample == 4 && + (format->nChannels == 1 || format->nChannels == 2)) { return TRUE; } + break; case WAVE_FORMAT_ALAW: @@ -246,7 +235,6 @@ static BOOL rdpsnd_opensles_format_supported(rdpsndDevicePlugin* device, static UINT32 rdpsnd_opensles_get_volume(rdpsndDevicePlugin* device) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p", opensles); assert(opensles); @@ -263,31 +251,32 @@ static UINT32 rdpsnd_opensles_get_volume(rdpsndDevicePlugin* device) opensles->volume = (vol << 16) | (vol & 0xFFFF); } } - + return opensles->volume; } static BOOL rdpsnd_opensles_set_volume(rdpsndDevicePlugin* device, - UINT32 value) + UINT32 value) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p, value=%d", opensles, value); assert(opensles); - opensles->volume = value; if (opensles->stream) { if (0 == opensles->volume) - android_SetOutputMute(opensles->stream, true); + return android_SetOutputMute(opensles->stream, true); else { const int max = android_GetOutputVolumeMax(opensles->stream); const int vol = rdpsnd_opensles_volume_to_millibel(value & 0xFFFF, max); - android_SetOutputMute(opensles->stream, false); - android_SetOutputVolume(opensles->stream, vol); + if (!android_SetOutputMute(opensles->stream, false)) + return FALSE; + + if (!android_SetOutputVolume(opensles->stream, vol)) + return FALSE; } } @@ -295,53 +284,49 @@ static BOOL rdpsnd_opensles_set_volume(rdpsndDevicePlugin* device, } static void rdpsnd_opensles_play(rdpsndDevicePlugin* device, - BYTE *data, int size) + BYTE* data, int size) { union { - BYTE *b; - short *s; + BYTE* b; + short* s; } src; int ret; rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p, data=%p, size=%d", opensles, data, size); + if (!rdpsnd_opensles_check_handle(opensles)) return; if (opensles->format == WAVE_FORMAT_ADPCM) { DEBUG_SND("dsp_context=%p, channels=%d, block_size=%d", - opensles->dsp_context, opensles->channels, opensles->block_size); - + opensles->dsp_context, opensles->channels, opensles->block_size); opensles->dsp_context->decode_ms_adpcm(opensles->dsp_context, - data, size, opensles->channels, opensles->block_size); - + data, size, opensles->channels, opensles->block_size); size = opensles->dsp_context->adpcm_size; src.b = opensles->dsp_context->adpcm_buffer; } else if (opensles->format == WAVE_FORMAT_DVI_ADPCM) { DEBUG_SND("dsp_context=%p, channels=%d, block_size=%d", - opensles->dsp_context, opensles->channels, opensles->block_size); - + opensles->dsp_context, opensles->channels, opensles->block_size); opensles->dsp_context->decode_ima_adpcm(opensles->dsp_context, - data, size, opensles->channels, opensles->block_size); - + data, size, opensles->channels, opensles->block_size); size = opensles->dsp_context->adpcm_size; src.b = opensles->dsp_context->adpcm_buffer; } else - { + { src.b = data; - } + } DEBUG_SND("size=%d, src=%p", size, src.b); assert(0 == size % 2); assert(size > 0); assert(src.b); - ret = android_AudioOut(opensles->stream, src.s, size / 2); + if (ret < 0) WLog_ERR(TAG, "android_AudioOut failed (%d)", ret); } @@ -350,34 +335,33 @@ static void rdpsnd_opensles_start(rdpsndDevicePlugin* device) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; rdpsnd_opensles_check_handle(opensles); - DEBUG_SND("opensles=%p", opensles); } static COMMAND_LINE_ARGUMENT_A rdpsnd_opensles_args[] = { - { "dev", COMMAND_LINE_VALUE_REQUIRED, "", - NULL, NULL, -1, NULL, "device" }, + { + "dev", COMMAND_LINE_VALUE_REQUIRED, "", + NULL, NULL, -1, NULL, "device" + }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device, - ADDIN_ARGV* args) + ADDIN_ARGV* args) { int status; DWORD flags; COMMAND_LINE_ARGUMENT_A* arg; rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - assert(opensles); assert(args); - DEBUG_SND("opensles=%p, args=%p", opensles, args); - - flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD; - + flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | + COMMAND_LINE_IGN_UNKNOWN_KEYWORD; status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, - rdpsnd_opensles_args, flags, opensles, NULL, NULL); + rdpsnd_opensles_args, flags, opensles, NULL, NULL); + if (status < 0) return status; @@ -389,14 +373,13 @@ static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device, continue; CommandLineSwitchStart(arg) - CommandLineSwitchCase(arg, "dev") { opensles->device_name = _strdup(arg->Value); + if (!opensles->device_name) return ERROR_OUTOFMEMORY; } - CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); @@ -404,7 +387,7 @@ static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device, return status; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_rdpsnd_client_subsystem_entry \ opensles_freerdp_rdpsnd_client_subsystem_entry #else @@ -418,15 +401,14 @@ static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device, * @return 0 on success, otherwise a Win32 error code */ UINT freerdp_rdpsnd_client_subsystem_entry( - PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) + PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) { ADDIN_ARGV* args; rdpsndopenslesPlugin* opensles; UINT error; - DEBUG_SND("pEntryPoints=%p", pEntryPoints); - opensles = (rdpsndopenslesPlugin*) calloc(1, sizeof(rdpsndopenslesPlugin)); + if (!opensles) return CHANNEL_RC_NO_MEMORY; @@ -439,13 +421,13 @@ UINT freerdp_rdpsnd_client_subsystem_entry( opensles->device.Play = rdpsnd_opensles_play; opensles->device.Close = rdpsnd_opensles_close; opensles->device.Free = rdpsnd_opensles_free; - args = pEntryPoints->args; rdpsnd_opensles_parse_addin_args((rdpsndDevicePlugin*) opensles, args); if (!opensles->device_name) { opensles->device_name = _strdup("default"); + if (!opensles->device_name) { error = CHANNEL_RC_NO_MEMORY; @@ -456,8 +438,8 @@ UINT freerdp_rdpsnd_client_subsystem_entry( opensles->rate = 44100; opensles->channels = 2; opensles->format = WAVE_FORMAT_ADPCM; - opensles->dsp_context = freerdp_dsp_context_new(); + if (!opensles->dsp_context) { error = CHANNEL_RC_NO_MEMORY; @@ -465,8 +447,7 @@ UINT freerdp_rdpsnd_client_subsystem_entry( } pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, - (rdpsndDevicePlugin*) opensles); - + (rdpsndDevicePlugin*) opensles); DEBUG_SND("success"); return CHANNEL_RC_OK; out_dsp_new: diff --git a/channels/rdpsnd/client/oss/rdpsnd_oss.c b/channels/rdpsnd/client/oss/rdpsnd_oss.c index 2a6d365..5209969 100644 --- a/channels/rdpsnd/client/oss/rdpsnd_oss.c +++ b/channels/rdpsnd/client/oss/rdpsnd_oss.c @@ -475,7 +475,7 @@ static int rdpsnd_oss_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* a return status; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_rdpsnd_client_subsystem_entry oss_freerdp_rdpsnd_client_subsystem_entry #else #define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry diff --git a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c index 5181d0d..2f93c64 100644 --- a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c +++ b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c @@ -584,7 +584,9 @@ static void rdpsnd_pulse_start(rdpsndDevicePlugin* device) if (!pulse->stream) return; + pa_threaded_mainloop_lock(pulse->mainloop); pa_stream_trigger(pulse->stream, NULL, NULL); + pa_threaded_mainloop_unlock(pulse->mainloop); } COMMAND_LINE_ARGUMENT_A rdpsnd_pulse_args[] = @@ -634,7 +636,7 @@ static UINT rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_rdpsnd_client_subsystem_entry pulse_freerdp_rdpsnd_client_subsystem_entry #else #define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 2133339..5be9cab 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -7,6 +7,7 @@ * Copyright 2012-2013 Marc-Andre Moreau * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2016 David PHAM-VAN * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +52,7 @@ struct rdpsnd_plugin { CHANNEL_DEF channelDef; - CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; + CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints; HANDLE thread; wStream* data_in; @@ -109,46 +110,43 @@ static void* rdpsnd_schedule_thread(void* arg) rdpsndPlugin* rdpsnd = (rdpsndPlugin*) arg; HANDLE events[2]; UINT error = CHANNEL_RC_OK; - DWORD status; - + DWORD status; events[0] = MessageQueue_Event(rdpsnd->MsgPipe->Out); events[1] = rdpsnd->stopEvent; while (1) { - status = WaitForMultipleObjects(2, events, FALSE, INFINITE); + status = WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error); + break; + } - status = WaitForSingleObject(rdpsnd->stopEvent, 0); + status = WaitForSingleObject(rdpsnd->stopEvent, 0); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + break; + } - if (status == WAIT_OBJECT_0) - break; + if (status == WAIT_OBJECT_0) + break; + status = WaitForSingleObject(events[0], 0); - status = WaitForSingleObject(events[0], 0); + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + break; + } - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - break; - } - - - if (!MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE)) + if (!MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE)) { WLog_ERR(TAG, "MessageQueue_Peek failed!"); error = ERROR_INTERNAL_ERROR; @@ -179,7 +177,8 @@ static void* rdpsnd_schedule_thread(void* arg) } if (error && rdpsnd->rdpcontext) - setChannelError(rdpsnd->rdpcontext, error, "rdpsnd_schedule_thread reported an error"); + setChannelError(rdpsnd->rdpcontext, error, + "rdpsnd_schedule_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -190,24 +189,23 @@ static void* rdpsnd_schedule_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd) +static UINT rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd) { wStream* pdu; - pdu = Stream_New(NULL, 8); + if (!pdu) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write_UINT8(pdu, SNDC_QUALITYMODE); /* msgType */ Stream_Write_UINT8(pdu, 0); /* bPad */ Stream_Write_UINT16(pdu, 4); /* BodySize */ Stream_Write_UINT16(pdu, rdpsnd->wQualityMode); /* wQualityMode */ Stream_Write_UINT16(pdu, 0); /* Reserved */ - WLog_Print(rdpsnd->log, WLOG_DEBUG, "QualityMode: %d", rdpsnd->wQualityMode); - return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -216,7 +214,6 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) int index; AUDIO_FORMAT* serverFormat; AUDIO_FORMAT* clientFormat; - rdpsnd_free_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); rdpsnd->NumberOfClientFormats = 0; rdpsnd->ClientFormats = NULL; @@ -224,24 +221,32 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) if (!rdpsnd->NumberOfServerFormats) return; - rdpsnd->ClientFormats = (AUDIO_FORMAT*) malloc(sizeof(AUDIO_FORMAT) * rdpsnd->NumberOfServerFormats); + rdpsnd->ClientFormats = (AUDIO_FORMAT*) calloc(sizeof(AUDIO_FORMAT), + rdpsnd->NumberOfServerFormats); + + if (!rdpsnd->ClientFormats) + return; + for (index = 0; index < (int) rdpsnd->NumberOfServerFormats; index++) { serverFormat = &rdpsnd->ServerFormats[index]; - if (rdpsnd->fixedFormat > 0 && (rdpsnd->fixedFormat != serverFormat->wFormatTag)) + if (rdpsnd->fixedFormat > 0 + && (rdpsnd->fixedFormat != serverFormat->wFormatTag)) continue; - if (rdpsnd->fixedChannel > 0 && (rdpsnd->fixedChannel != serverFormat->nChannels)) + if (rdpsnd->fixedChannel > 0 + && (rdpsnd->fixedChannel != serverFormat->nChannels)) continue; - if (rdpsnd->fixedRate > 0 && (rdpsnd->fixedRate != serverFormat->nSamplesPerSec)) + if (rdpsnd->fixedRate > 0 + && (rdpsnd->fixedRate != serverFormat->nSamplesPerSec)) continue; - if (rdpsnd->device && rdpsnd->device->FormatSupported(rdpsnd->device, serverFormat)) + if (rdpsnd->device + && rdpsnd->device->FormatSupported(rdpsnd->device, serverFormat)) { clientFormat = &rdpsnd->ClientFormats[rdpsnd->NumberOfClientFormats++]; - CopyMemory(clientFormat, serverFormat, sizeof(AUDIO_FORMAT)); clientFormat->cbSize = 0; @@ -256,10 +261,12 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) #if 0 WLog_ERR(TAG, "Server "); - rdpsnd_print_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); + rdpsnd_print_audio_formats(rdpsnd->ServerFormats, + rdpsnd->NumberOfServerFormats); WLog_ERR(TAG, ""); WLog_ERR(TAG, "Client "); - rdpsnd_print_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); + rdpsnd_print_audio_formats(rdpsnd->ClientFormats, + rdpsnd->NumberOfClientFormats); WLog_ERR(TAG, ""); #endif } @@ -269,7 +276,7 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) +static UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) { int index; wStream* pdu; @@ -279,7 +286,6 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) UINT16 dwVolumeRight; UINT16 wNumberOfFormats; AUDIO_FORMAT* clientFormat; - dwVolumeLeft = ((50 * 0xFFFF) / 100); /* 50% */ dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */ dwVolume = (dwVolumeLeft << 16) | dwVolumeRight; @@ -291,13 +297,13 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) } wNumberOfFormats = rdpsnd->NumberOfClientFormats; - length = 4 + 20; for (index = 0; index < (int) wNumberOfFormats; index++) length += (18 + rdpsnd->ClientFormats[index].cbSize); pdu = Stream_New(NULL, length); + if (!pdu) { WLog_ERR(TAG, "Stream_New failed!"); @@ -307,7 +313,6 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) Stream_Write_UINT8(pdu, SNDC_FORMATS); /* msgType */ Stream_Write_UINT8(pdu, 0); /* bPad */ Stream_Write_UINT16(pdu, length - 4); /* BodySize */ - Stream_Write_UINT32(pdu, TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME); /* dwFlags */ Stream_Write_UINT32(pdu, dwVolume); /* dwVolume */ Stream_Write_UINT32(pdu, 0); /* dwPitch */ @@ -320,7 +325,6 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) for (index = 0; index < (int) wNumberOfFormats; index++) { clientFormat = &rdpsnd->ClientFormats[index]; - Stream_Write_UINT16(pdu, clientFormat->wFormatTag); Stream_Write_UINT16(pdu, clientFormat->nChannels); Stream_Write_UINT32(pdu, clientFormat->nSamplesPerSec); @@ -334,7 +338,6 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) } WLog_Print(rdpsnd->log, WLOG_DEBUG, "Client Audio Formats"); - return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -343,14 +346,14 @@ UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) +static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, + wStream* s) { int index; UINT16 wVersion; AUDIO_FORMAT* format; UINT16 wNumberOfFormats; UINT ret = ERROR_BAD_LENGTH; - rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); rdpsnd->NumberOfServerFormats = 0; rdpsnd->ServerFormats = NULL; @@ -367,12 +370,14 @@ UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) Stream_Read_UINT8(s, rdpsnd->cBlockNo); /* cLastBlockConfirmed */ Stream_Read_UINT16(s, wVersion); /* wVersion */ Stream_Seek_UINT8(s); /* bPad */ - rdpsnd->NumberOfServerFormats = wNumberOfFormats; + if (Stream_GetRemainingLength(s) / 14 < wNumberOfFormats) return ERROR_BAD_LENGTH; - rdpsnd->ServerFormats = (AUDIO_FORMAT*) calloc(wNumberOfFormats, sizeof(AUDIO_FORMAT)); + rdpsnd->ServerFormats = (AUDIO_FORMAT*) calloc(wNumberOfFormats, + sizeof(AUDIO_FORMAT)); + if (!rdpsnd->ServerFormats) return CHANNEL_RC_NO_MEMORY; @@ -382,6 +387,7 @@ UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) if (Stream_GetRemainingLength(s) < 14) goto out_fail; + Stream_Read_UINT16(s, format->wFormatTag); /* wFormatTag */ Stream_Read_UINT16(s, format->nChannels); /* nChannels */ Stream_Read_UINT32(s, format->nSamplesPerSec); /* nSamplesPerSec */ @@ -396,20 +402,21 @@ UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) goto out_fail; format->data = (BYTE*) malloc(format->cbSize); + if (!format->data) { ret = CHANNEL_RC_NO_MEMORY; goto out_fail; } + Stream_Read(s, format->data, format->cbSize); } } rdpsnd_select_supported_audio_formats(rdpsnd); - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Server Audio Formats"); - ret = rdpsnd_send_client_audio_formats(rdpsnd); + if (ret == CHANNEL_RC_OK) { if (wVersion >= 6) @@ -417,8 +424,8 @@ UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) } return ret; - out_fail: + for (index = 0; index < (int) wNumberOfFormats; index++) free(format->data); @@ -432,11 +439,12 @@ out_fail: * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, UINT16 wPackSize) +static UINT rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, + UINT16 wTimeStamp, UINT16 wPackSize) { wStream* pdu; - pdu = Stream_New(NULL, 8); + if (!pdu) { WLog_ERR(TAG, "Stream_New failed!"); @@ -448,10 +456,9 @@ UINT rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, U Stream_Write_UINT16(pdu, 4); /* BodySize */ Stream_Write_UINT16(pdu, wTimeStamp); Stream_Write_UINT16(pdu, wPackSize); - - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Training Response: wTimeStamp: %d wPackSize: %d", - wTimeStamp, wPackSize); - + WLog_Print(rdpsnd->log, WLOG_DEBUG, + "Training Response: wTimeStamp: %d wPackSize: %d", + wTimeStamp, wPackSize); return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -470,10 +477,9 @@ static UINT rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s) Stream_Read_UINT16(s, wTimeStamp); Stream_Read_UINT16(s, wPackSize); - - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Training Request: wTimeStamp: %d wPackSize: %d", - wTimeStamp, wPackSize); - + WLog_Print(rdpsnd->log, WLOG_DEBUG, + "Training Request: wTimeStamp: %d wPackSize: %d", + wTimeStamp, wPackSize); return rdpsnd_send_training_confirm_pdu(rdpsnd, wTimeStamp, wPackSize); } @@ -482,11 +488,11 @@ static UINT rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 BodySize) +static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, + UINT16 BodySize) { UINT16 wFormatNo; AUDIO_FORMAT* format; - rdpsnd->expectingWave = TRUE; if (Stream_GetRemainingLength(s) < 12) @@ -497,13 +503,10 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B Stream_Read_UINT8(s, rdpsnd->cBlockNo); Stream_Seek(s, 3); /* bPad */ Stream_Read(s, rdpsnd->waveData, 4); - rdpsnd->waveDataSize = BodySize - 8; - format = &rdpsnd->ClientFormats[wFormatNo]; - WLog_Print(rdpsnd->log, WLOG_DEBUG, "WaveInfo: cBlockNo: %d wFormatNo: %d", - rdpsnd->cBlockNo, wFormatNo); + rdpsnd->cBlockNo, wFormatNo); if (!rdpsnd->isOpen) { @@ -513,9 +516,9 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B //rdpsnd_print_audio_format(format); if (rdpsnd->device && rdpsnd->device->Open && - !rdpsnd->device->Open(rdpsnd->device, format, rdpsnd->latency)) + !rdpsnd->device->Open(rdpsnd->device, format, rdpsnd->latency)) { - return CHANNEL_RC_INITIALIZATION_ERROR; + return CHANNEL_RC_INITIALIZATION_ERROR; } } else if (wFormatNo != rdpsnd->wCurrentFormatNo) @@ -524,8 +527,9 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B if (rdpsnd->device) { - if(rdpsnd->device->SetFormat && !rdpsnd->device->SetFormat(rdpsnd->device, format, rdpsnd->latency)) - return CHANNEL_RC_INITIALIZATION_ERROR; + if (rdpsnd->device->SetFormat + && !rdpsnd->device->SetFormat(rdpsnd->device, format, rdpsnd->latency)) + return CHANNEL_RC_INITIALIZATION_ERROR; } } @@ -537,11 +541,12 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 B * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE cConfirmedBlockNo) +static UINT rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, + UINT16 wTimeStamp, BYTE cConfirmedBlockNo) { wStream* pdu; - pdu = Stream_New(NULL, 8); + if (!pdu) { WLog_ERR(TAG, "Stream_New failed!"); @@ -554,7 +559,6 @@ UINT rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE Stream_Write_UINT16(pdu, wTimeStamp); Stream_Write_UINT8(pdu, cConfirmedBlockNo); /* cConfirmedBlockNo */ Stream_Write_UINT8(pdu, 0); /* bPad */ - return rdpsnd_virtual_channel_write(rdpsnd, pdu); } @@ -563,11 +567,11 @@ UINT rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_confirm_wave(rdpsndPlugin* rdpsnd, RDPSND_WAVE* wave) +static UINT rdpsnd_confirm_wave(rdpsndPlugin* rdpsnd, RDPSND_WAVE* wave) { - WLog_Print(rdpsnd->log, WLOG_DEBUG, "WaveConfirm: cBlockNo: %d wTimeStamp: %d wTimeDiff: %d", - wave->cBlockNo, wave->wTimeStampB, wave->wTimeStampB - wave->wTimeStampA); - + WLog_Print(rdpsnd->log, WLOG_DEBUG, + "WaveConfirm: cBlockNo: %d wTimeStamp: %d wTimeDiff: %d", + wave->cBlockNo, wave->wTimeStampB, wave->wTimeStampB - wave->wTimeStampA); return rdpsnd_send_wave_confirm_pdu(rdpsnd, wave->wTimeStampB, wave->cBlockNo); } @@ -576,19 +580,20 @@ UINT rdpsnd_confirm_wave(rdpsndPlugin* rdpsnd, RDPSND_WAVE* wave) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) +static UINT rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, + RDPSND_WAVE* wave) { if (device->DisableConfirmThread) return rdpsnd_confirm_wave(device->rdpsnd, wave); - if (!MessageQueue_Post(device->rdpsnd->MsgPipe->Out, NULL, 0, (void*) wave, NULL)) + if (!MessageQueue_Post(device->rdpsnd->MsgPipe->Out, NULL, 0, (void*) wave, + NULL)) { WLog_ERR(TAG, "MessageQueue_Post failed!"); return ERROR_INTERNAL_ERROR; } return CHANNEL_RC_OK; - } /** @@ -603,22 +608,18 @@ static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) RDPSND_WAVE* wave; AUDIO_FORMAT* format; UINT status; - rdpsnd->expectingWave = FALSE; - /** * The Wave PDU is a special case: it is always sent after a Wave Info PDU, * and we do not process its header. Instead, the header is pad that needs * to be filled with the first four bytes of the audio sample data sent as * part of the preceding Wave Info PDU. */ - CopyMemory(Stream_Buffer(s), rdpsnd->waveData, 4); - data = Stream_Buffer(s); size = (int) Stream_Capacity(s); - wave = (RDPSND_WAVE*) calloc(1, sizeof(RDPSND_WAVE)); + if (!wave) { WLog_ERR(TAG, "calloc failed!"); @@ -629,16 +630,13 @@ static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) wave->wTimeStampA = rdpsnd->wTimeStamp; wave->wFormatNo = rdpsnd->wCurrentFormatNo; wave->cBlockNo = rdpsnd->cBlockNo; - wave->data = data; wave->length = size; wave->AutoConfirm = TRUE; - format = &rdpsnd->ClientFormats[rdpsnd->wCurrentFormatNo]; wave->wAudioLength = rdpsnd_compute_audio_time_length(format, size); - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Wave: cBlockNo: %d wTimeStamp: %d", - wave->cBlockNo, wave->wTimeStampA); + wave->cBlockNo, wave->wTimeStampA); if (!rdpsnd->device) { @@ -649,7 +647,8 @@ static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) return status; } - if (rdpsnd->device->WaveDecode && !rdpsnd->device->WaveDecode(rdpsnd->device, wave)) + if (rdpsnd->device->WaveDecode + && !rdpsnd->device->WaveDecode(rdpsnd->device, wave)) { free(wave); return CHANNEL_RC_NO_MEMORY; @@ -671,8 +670,10 @@ static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s) } status = CHANNEL_RC_OK; + if (wave->AutoConfirm) status = rdpsnd->device->WaveConfirm(rdpsnd->device, wave); + return status; } @@ -701,15 +702,15 @@ static UINT rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s) return ERROR_BAD_LENGTH; Stream_Read_UINT32(s, dwVolume); - WLog_Print(rdpsnd->log, WLOG_DEBUG, "Volume: 0x%04X", dwVolume); if (rdpsnd->device && rdpsnd->device->SetVolume && - !rdpsnd->device->SetVolume(rdpsnd->device, dwVolume)) + !rdpsnd->device->SetVolume(rdpsnd->device, dwVolume)) { WLog_ERR(TAG, "error setting volume"); return CHANNEL_RC_INITIALIZATION_ERROR; } + return CHANNEL_RC_OK; } @@ -774,7 +775,8 @@ out: return status; } -static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlugin* device) +static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, + rdpsndDevicePlugin* device) { if (rdpsnd->device) { @@ -784,7 +786,6 @@ static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlug rdpsnd->device = device; device->rdpsnd = rdpsnd; - device->WaveConfirm = rdpsnd_device_send_wave_confirm_pdu; } @@ -793,13 +794,14 @@ static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlug * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, ADDIN_ARGV* args) +static UINT rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, + ADDIN_ARGV* args) { PFREERDP_RDPSND_DEVICE_ENTRY entry; - FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints;\ + FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints; UINT error; - - entry = (PFREERDP_RDPSND_DEVICE_ENTRY) freerdp_load_channel_addin_entry("rdpsnd", (LPSTR) name, NULL, 0); + entry = (PFREERDP_RDPSND_DEVICE_ENTRY) + freerdp_load_channel_addin_entry("rdpsnd", (LPSTR) name, NULL, 0); if (!entry) return ERROR_INTERNAL_ERROR; @@ -809,13 +811,13 @@ static UINT rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, AD entryPoints.args = args; if ((error = entry(&entryPoints))) - WLog_ERR(TAG, "%s entry returns error %lu", name, error); + WLog_ERR(TAG, "%s entry returns error %u", name, error); WLog_INFO(TAG, "Loaded %s backend for rdpsnd", name); return error; } -BOOL rdpsnd_set_subsystem(rdpsndPlugin* rdpsnd, const char* subsystem) +static BOOL rdpsnd_set_subsystem(rdpsndPlugin* rdpsnd, const char* subsystem) { free(rdpsnd->subsystem); rdpsnd->subsystem = _strdup(subsystem); @@ -851,15 +853,13 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) int status; DWORD flags; COMMAND_LINE_ARGUMENT_A* arg; - rdpsnd->wQualityMode = HIGH_QUALITY; /* default quality mode */ - if (args->argc > 1) { flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON; - status = CommandLineParseArgumentsA(args->argc, (const char **) args->argv, - rdpsnd_args, flags, rdpsnd, NULL, NULL); + status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, + rdpsnd_args, flags, rdpsnd, NULL, NULL); if (status < 0) return CHANNEL_RC_INITIALIZATION_ERROR; @@ -872,7 +872,6 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) continue; CommandLineSwitchStart(arg) - CommandLineSwitchCase(arg, "sys") { if (!rdpsnd_set_subsystem(rdpsnd, arg->Value)) @@ -919,9 +918,7 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args) } CommandLineSwitchDefault(arg) { - } - CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); @@ -939,14 +936,14 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) { ADDIN_ARGV* args; UINT status = ERROR_INTERNAL_ERROR; - char *subsystem_name = NULL, *device_name = NULL; - + char* subsystem_name = NULL, *device_name = NULL; rdpsnd->latency = -1; - args = (ADDIN_ARGV*) rdpsnd->channelEntryPoints.pExtendedData; + if (args) { status = rdpsnd_process_addin_args(rdpsnd, args); + if (status != CHANNEL_RC_OK) return status; } @@ -958,88 +955,112 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) if ((status = rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args))) { - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", rdpsnd->subsystem, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %u", + rdpsnd->subsystem, status); return status; } } else { #if defined(WITH_IOSAUDIO) + if (!rdpsnd->device) { subsystem_name = "ios"; device_name = ""; - if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); - } -#endif + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %u", + subsystem_name, status); + } + +#endif #if defined(WITH_OPENSLES) + if (!rdpsnd->device) { subsystem_name = "opensles"; device_name = ""; - if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); - } -#endif + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %u", + subsystem_name, status); + } + +#endif #if defined(WITH_PULSE) + if (!rdpsnd->device) { subsystem_name = "pulse"; device_name = ""; - if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); - } -#endif + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %u", + subsystem_name, status); + } + +#endif #if defined(WITH_ALSA) + if (!rdpsnd->device) { subsystem_name = "alsa"; device_name = "default"; - if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); - } -#endif + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %u", + subsystem_name, status); + } + +#endif #if defined(WITH_OSS) + if (!rdpsnd->device) { subsystem_name = "oss"; device_name = ""; + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %u", + subsystem_name, status); } + #endif - - #if defined(WITH_MACAUDIO) + if (!rdpsnd->device) { subsystem_name = "mac"; device_name = "default"; - if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); - } -#endif + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %u", + subsystem_name, status); + } + +#endif #if defined(WITH_WINMM) + if (!rdpsnd->device) { subsystem_name = "winmm"; device_name = ""; + if ((status = rdpsnd_load_device_plugin(rdpsnd, subsystem_name, args))) - WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %lu", subsystem_name, status); + WLog_ERR(TAG, "unable to load the %s subsystem plugin because of error %u", + subsystem_name, status); } + #endif + if (status) return status; if (rdpsnd->device) { - if (!rdpsnd_set_subsystem(rdpsnd, subsystem_name) || !rdpsnd_set_device_name(rdpsnd, device_name)) + if (!rdpsnd_set_subsystem(rdpsnd, subsystem_name) + || !rdpsnd_set_device_name(rdpsnd, device_name)) return CHANNEL_RC_NO_MEMORY; } } @@ -1050,10 +1071,10 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) return CHANNEL_RC_INITIALIZATION_ERROR; } - if (!rdpsnd->device->DisableConfirmThread) { rdpsnd->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!rdpsnd->stopEvent) { WLog_ERR(TAG, "CreateEvent failed!"); @@ -1061,8 +1082,9 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsnd) } rdpsnd->ScheduleThread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread, - (void*) rdpsnd, 0, NULL); + (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread, + (void*) rdpsnd, 0, NULL); + if (!rdpsnd->ScheduleThread) { WLog_ERR(TAG, "CreateThread failed!"); @@ -1078,84 +1100,18 @@ static void rdpsnd_process_disconnect(rdpsndPlugin* rdpsnd) if (rdpsnd->ScheduleThread) { SetEvent(rdpsnd->stopEvent); + if (WaitForSingleObject(rdpsnd->ScheduleThread, INFINITE) == WAIT_FAILED) - { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); - return; - } + { + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) GetLastError()); + return; + } + CloseHandle(rdpsnd->ScheduleThread); CloseHandle(rdpsnd->stopEvent); } } -/****************************************************************************************/ - - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - -BOOL rdpsnd_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - if (!g_InitHandles) - return FALSE; - } - - return ListDictionary_Add(g_InitHandles, pInitHandle, pUserData); -} - -void* rdpsnd_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void rdpsnd_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -BOOL rdpsnd_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - if (!g_OpenHandles) - return FALSE; - } - - return ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData); -} - -void* rdpsnd_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void rdpsnd_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - /** * Function description * @@ -1171,15 +1127,15 @@ UINT rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s) } else { - status = rdpsnd->channelEntryPoints.pVirtualChannelWrite(rdpsnd->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + status = rdpsnd->channelEntryPoints.pVirtualChannelWriteEx(rdpsnd->InitHandle, rdpsnd->OpenHandle, + Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); } return status; @@ -1191,7 +1147,7 @@ UINT rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s) * @return 0 on success, otherwise a Win32 error code */ static UINT rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* s; @@ -1206,6 +1162,7 @@ static UINT rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin, Stream_Free(plugin->data_in, TRUE); plugin->data_in = Stream_New(NULL, totalLength); + if (!plugin->data_in) { WLog_ERR(TAG, "Stream_New failed!"); @@ -1241,28 +1198,31 @@ static UINT rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE rdpsnd_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - rdpsndPlugin* rdpsnd; UINT error = CHANNEL_RC_OK; + rdpsndPlugin* rdpsnd = (rdpsndPlugin*) lpUserParam; - rdpsnd = (rdpsndPlugin*) rdpsnd_get_open_handle_data(openHandle); - - if (!rdpsnd) + if (!rdpsnd || (rdpsnd->OpenHandle != openHandle)) { - WLog_ERR(TAG, "rdpsnd_virtual_channel_open_event: error no match"); + WLog_ERR(TAG, "error no match"); return; } switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = rdpsnd_virtual_channel_event_data_received(rdpsnd, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "rdpsnd_virtual_channel_event_data_received failed with error %lu", error); + if ((error = rdpsnd_virtual_channel_event_data_received(rdpsnd, pData, + dataLength, totalLength, dataFlags))) + WLog_ERR(TAG, + "rdpsnd_virtual_channel_event_data_received failed with error %u", error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -1272,9 +1232,10 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle, UINT e case CHANNEL_EVENT_USER: break; } - if (error && rdpsnd->rdpcontext) - setChannelError(rdpsnd->rdpcontext, error, "rdpsnd_virtual_channel_open_event reported an error"); + if (error && rdpsnd->rdpcontext) + setChannelError(rdpsnd->rdpcontext, error, + "rdpsnd_virtual_channel_open_event_ex reported an error"); } static void* rdpsnd_virtual_channel_client_thread(void* arg) @@ -1312,6 +1273,7 @@ static void* rdpsnd_virtual_channel_client_thread(void* arg) if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = rdpsnd_recv_pdu(rdpsnd, data))) { WLog_ERR(TAG, "error treating sound channel message"); @@ -1321,11 +1283,12 @@ static void* rdpsnd_virtual_channel_client_thread(void* arg) } out: + if (error && rdpsnd->rdpcontext) - setChannelError(rdpsnd->rdpcontext, error, "rdpsnd_virtual_channel_client_thread reported an error"); + setChannelError(rdpsnd->rdpcontext, error, + "rdpsnd_virtual_channel_client_thread reported an error"); rdpsnd_process_disconnect(rdpsnd); - ExitThread((DWORD)error); return NULL; } @@ -1335,40 +1298,38 @@ out: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, LPVOID pData, UINT32 dataLength) +static UINT rdpsnd_virtual_channel_event_connected(rdpsndPlugin* rdpsnd, + LPVOID pData, UINT32 dataLength) { UINT32 status; - - status = plugin->channelEntryPoints.pVirtualChannelOpen(plugin->InitHandle, - &plugin->OpenHandle, plugin->channelDef.name, rdpsnd_virtual_channel_open_event); + status = rdpsnd->channelEntryPoints.pVirtualChannelOpenEx(rdpsnd->InitHandle, + &rdpsnd->OpenHandle, rdpsnd->channelDef.name, + rdpsnd_virtual_channel_open_event_ex); if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "pVirtualChannelOpenEx failed with %s [%08X]", + WTSErrorToString(status), status); return status; } - if (!rdpsnd_add_open_handle_data(plugin->OpenHandle, plugin)) - { - WLog_ERR(TAG, "unable to register opened handle"); - return ERROR_INTERNAL_ERROR; - } + rdpsnd->MsgPipe = MessagePipe_New(); - plugin->MsgPipe = MessagePipe_New(); - if (!plugin->MsgPipe) + if (!rdpsnd->MsgPipe) { WLog_ERR(TAG, "unable to create message pipe"); return CHANNEL_RC_NO_MEMORY; } - plugin->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rdpsnd_virtual_channel_client_thread, (void*) plugin, 0, NULL); - if (!plugin->thread) + rdpsnd->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) rdpsnd_virtual_channel_client_thread, (void*) rdpsnd, + 0, NULL); + + if (!rdpsnd->thread) { WLog_ERR(TAG, "unable to create thread"); - MessagePipe_Free(plugin->MsgPipe); - plugin->MsgPipe = NULL; + MessagePipe_Free(rdpsnd->MsgPipe); + rdpsnd->MsgPipe = NULL; return ERROR_INTERNAL_ERROR; } @@ -1383,26 +1344,28 @@ static UINT rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, LPVOID static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd) { UINT error; - MessagePipe_PostQuit(rdpsnd->MsgPipe, 0); + if (WaitForSingleObject(rdpsnd->thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + return error; + } CloseHandle(rdpsnd->thread); rdpsnd->thread = NULL; + error = rdpsnd->channelEntryPoints.pVirtualChannelCloseEx(rdpsnd->InitHandle, rdpsnd->OpenHandle); - error = rdpsnd->channelEntryPoints.pVirtualChannelClose(rdpsnd->OpenHandle); if (CHANNEL_RC_OK != error) { - WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(error), error); + WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]", + WTSErrorToString(error), error); return error; } + rdpsnd->OpenHandle = 0; + if (rdpsnd->data_in) { Stream_Free(rdpsnd->data_in, TRUE); @@ -1411,11 +1374,9 @@ static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd) MessagePipe_Free(rdpsnd->MsgPipe); rdpsnd->MsgPipe = NULL; - rdpsnd_free_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); rdpsnd->NumberOfClientFormats = 0; rdpsnd->ClientFormats = NULL; - rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); rdpsnd->NumberOfServerFormats = 0; rdpsnd->ServerFormats = NULL; @@ -1438,28 +1399,24 @@ static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd) rdpsnd->device_name = NULL; } - rdpsnd_remove_open_handle_data(rdpsnd->OpenHandle); - return CHANNEL_RC_OK; } static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd) { - rdpsnd_remove_init_handle_data(rdpsnd->InitHandle); - + rdpsnd->InitHandle = 0; free(rdpsnd); } -static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength) +static VOID VCAPITYPE rdpsnd_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle, + UINT event, LPVOID pData, UINT dataLength) { - rdpsndPlugin* plugin; UINT error = CHANNEL_RC_OK; + rdpsndPlugin* plugin = (rdpsndPlugin*) lpUserParam; - plugin = (rdpsndPlugin*) rdpsnd_get_init_handle_data(pInitHandle); - - if (!plugin) + if (!plugin || (plugin->InitHandle != pInitHandle)) { - WLog_ERR(TAG, "rdpsnd_virtual_channel_init_event: error no match"); + WLog_ERR(TAG, "error no match"); return; } @@ -1467,34 +1424,50 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, UINT { case CHANNEL_EVENT_CONNECTED: if ((error = rdpsnd_virtual_channel_event_connected(plugin, pData, dataLength))) - WLog_ERR(TAG, "rdpsnd_virtual_channel_event_connected failed with error %lu!", error); + WLog_ERR(TAG, "rdpsnd_virtual_channel_event_connected failed with error %u!", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = rdpsnd_virtual_channel_event_disconnected(plugin))) - WLog_ERR(TAG, "rdpsnd_virtual_channel_event_disconnected failed with error %lu!", error); + WLog_ERR(TAG, + "rdpsnd_virtual_channel_event_disconnected failed with error %u!", error); + break; case CHANNEL_EVENT_TERMINATED: + if (plugin->thread != NULL) + if ((error = rdpsnd_virtual_channel_event_disconnected(plugin))) + WLog_ERR(TAG, + "rdpsnd_virtual_channel_event_disconnected failed with error %u!", error); + rdpsnd_virtual_channel_event_terminated(plugin); + plugin = NULL; break; } - if (error && plugin->rdpcontext) - setChannelError(plugin->rdpcontext, error, "rdpsnd_virtual_channel_init_event reported an error"); + + if (error && plugin && plugin->rdpcontext) + setChannelError(plugin->rdpcontext, error, + "rdpsnd_virtual_channel_init_event reported an error"); } /* rdpsnd is always built-in */ -#define VirtualChannelEntry rdpsnd_VirtualChannelEntry +#define VirtualChannelEntryEx rdpsnd_VirtualChannelEntryEx -BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle) { UINT rc; - rdpsndPlugin* rdpsnd; - CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; + CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx; + if (!pEntryPoints) + { + return FALSE; + } rdpsnd = (rdpsndPlugin*) calloc(1, sizeof(rdpsndPlugin)); + if (!rdpsnd) { WLog_ERR(TAG, "calloc failed!"); @@ -1509,34 +1482,35 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) pthread_sigmask(SIG_BLOCK, &mask, NULL); } #endif - rdpsnd->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP; strcpy(rdpsnd->channelDef.name, "rdpsnd"); + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints; - pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; - - if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && - (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) && + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { rdpsnd->rdpcontext = pEntryPointsEx->context; } - CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); - rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client"); + CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); + + rdpsnd->InitHandle = pInitHandle; + + rc = rdpsnd->channelEntryPoints.pVirtualChannelInitEx(rdpsnd, NULL, pInitHandle, + &rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + rdpsnd_virtual_channel_init_event_ex); - rc = rdpsnd->channelEntryPoints.pVirtualChannelInit(&rdpsnd->InitHandle, - &rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpsnd_virtual_channel_init_event); if (CHANNEL_RC_OK != rc) { - WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); + WLog_ERR(TAG, "pVirtualChannelInitEx failed with %s [%08X]", + WTSErrorToString(rc), rc); free(rdpsnd); return FALSE; } - return rdpsnd_add_init_handle_data(rdpsnd->InitHandle, (void*) rdpsnd); + return TRUE; } diff --git a/channels/rdpsnd/client/rdpsnd_main.h b/channels/rdpsnd/client/rdpsnd_main.h index cd6a152..dcd976f 100644 --- a/channels/rdpsnd/client/rdpsnd_main.h +++ b/channels/rdpsnd/client/rdpsnd_main.h @@ -30,9 +30,9 @@ #define TAG CHANNELS_TAG("rdpsnd.client") #if defined(WITH_DEBUG_SND) -#define DEBUG_SND(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__) +#define DEBUG_SND(...) WLog_DBG(TAG, __VA_ARGS__) #else -#define DEBUG_SND(fmt, ...) do { } while (0) +#define DEBUG_SND(...) do { } while (0) #endif UINT rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s); diff --git a/channels/rdpsnd/client/winmm/CMakeLists.txt b/channels/rdpsnd/client/winmm/CMakeLists.txt index 43c7257..b4a337d 100644 --- a/channels/rdpsnd/client/winmm/CMakeLists.txt +++ b/channels/rdpsnd/client/winmm/CMakeLists.txt @@ -32,7 +32,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_PDB_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/rdpsnd/client/winmm/rdpsnd_winmm.c b/channels/rdpsnd/client/winmm/rdpsnd_winmm.c index 7eb1a5f..aa9367f 100644 --- a/channels/rdpsnd/client/winmm/rdpsnd_winmm.c +++ b/channels/rdpsnd/client/winmm/rdpsnd_winmm.c @@ -6,6 +6,7 @@ * Copyright 2010-2012 Vic Lee * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2016 David PHAM-VAN * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -136,6 +137,7 @@ static void CALLBACK rdpsnd_winmm_callback_function(HWAVEOUT hwo, UINT uMsg, DWO winmm->device.WaveConfirm(&(winmm->device), wave); free(lpWaveHdr->lpData); + free(lpWaveHdr); free(wave); } @@ -330,6 +332,7 @@ void rdpsnd_winmm_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) { WLog_ERR(TAG, "waveOutWrite failure: %d", mmResult); waveOutUnprepareHeader(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); + free(lpWaveHdr); return; } } @@ -344,7 +347,7 @@ static void rdpsnd_winmm_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_rdpsnd_client_subsystem_entry winmm_freerdp_rdpsnd_client_subsystem_entry #else #define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry diff --git a/channels/rdpsnd/server/rdpsnd_main.c b/channels/rdpsnd/server/rdpsnd_main.c index 93b9fcf..83f6118 100644 --- a/channels/rdpsnd/server/rdpsnd_main.c +++ b/channels/rdpsnd/server/rdpsnd_main.c @@ -46,11 +46,9 @@ UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) UINT16 i; BOOL status; ULONG written; - Stream_Write_UINT8(s, SNDC_FORMATS); Stream_Write_UINT8(s, 0); Stream_Seek_UINT16(s); - Stream_Write_UINT32(s, 0); /* dwFlags */ Stream_Write_UINT32(s, 0); /* dwVolume */ Stream_Write_UINT32(s, 0); /* dwPitch */ @@ -59,24 +57,27 @@ UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) Stream_Write_UINT8(s, context->block_no); /* cLastBlockConfirmed */ Stream_Write_UINT16(s, 0x06); /* wVersion */ Stream_Write_UINT8(s, 0); /* bPad */ - + for (i = 0; i < context->num_server_formats; i++) { - Stream_Write_UINT16(s, context->server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */ + Stream_Write_UINT16(s, + context->server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */ Stream_Write_UINT16(s, context->server_formats[i].nChannels); /* nChannels */ - Stream_Write_UINT32(s, context->server_formats[i].nSamplesPerSec); /* nSamplesPerSec */ - + Stream_Write_UINT32(s, + context->server_formats[i].nSamplesPerSec); /* nSamplesPerSec */ Stream_Write_UINT32(s, context->server_formats[i].nSamplesPerSec * - context->server_formats[i].nChannels * - context->server_formats[i].wBitsPerSample / 8); /* nAvgBytesPerSec */ - - Stream_Write_UINT16(s, context->server_formats[i].nBlockAlign); /* nBlockAlign */ - Stream_Write_UINT16(s, context->server_formats[i].wBitsPerSample); /* wBitsPerSample */ + context->server_formats[i].nChannels * + context->server_formats[i].wBitsPerSample / 8); /* nAvgBytesPerSec */ + Stream_Write_UINT16(s, + context->server_formats[i].nBlockAlign); /* nBlockAlign */ + Stream_Write_UINT16(s, + context->server_formats[i].wBitsPerSample); /* wBitsPerSample */ Stream_Write_UINT16(s, context->server_formats[i].cbSize); /* cbSize */ if (context->server_formats[i].cbSize > 0) { - Stream_Write(s, context->server_formats[i].data, context->server_formats[i].cbSize); + Stream_Write(s, context->server_formats[i].data, + context->server_formats[i].cbSize); } } @@ -84,10 +85,10 @@ UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) Stream_SetPosition(s, 2); Stream_Write_UINT16(s, pos - 4); Stream_SetPosition(s, pos); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); Stream_SetPosition(s, 0); - - return status ? CHANNEL_RC_OK: ERROR_INTERNAL_ERROR; + return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } /** @@ -95,7 +96,8 @@ UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, wStream* s) +static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, + wStream* s) { UINT16 timestamp; BYTE confirmBlockNum; @@ -110,10 +112,10 @@ static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, wStream Stream_Read_UINT16(s, timestamp); Stream_Read_UINT8(s, confirmBlockNum); Stream_Seek_UINT8(s); - IFCALLRET(context->ConfirmBlock, error, context, confirmBlockNum, timestamp); + if (error) - WLog_ERR(TAG, "context->ConfirmBlock failed with error %lu", error); + WLog_ERR(TAG, "context->ConfirmBlock failed with error %u", error); return error; } @@ -123,10 +125,11 @@ static UINT rdpsnd_server_recv_waveconfirm(RdpsndServerContext* context, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_server_recv_quality_mode(RdpsndServerContext* context, wStream* s) +static UINT rdpsnd_server_recv_quality_mode(RdpsndServerContext* context, + wStream* s) { UINT16 quality; - + if (Stream_GetRemainingLength(s) < 4) { WLog_ERR(TAG, "not enought data in stream!"); @@ -180,7 +183,9 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) return ERROR_INTERNAL_ERROR; } - context->client_formats = (AUDIO_FORMAT *)calloc(context->num_client_formats, sizeof(AUDIO_FORMAT)); + context->client_formats = (AUDIO_FORMAT*)calloc(context->num_client_formats, + sizeof(AUDIO_FORMAT)); + if (!context->client_formats) { WLog_ERR(TAG, "calloc failed!"); @@ -196,7 +201,6 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) goto out_free; } - Stream_Read_UINT16(s, context->client_formats[i].wFormatTag); Stream_Read_UINT16(s, context->client_formats[i].nChannels); Stream_Read_UINT32(s, context->client_formats[i].nSamplesPerSec); @@ -213,7 +217,6 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) error = ERROR_INTERNAL_ERROR; goto out_free; } - } if (context->client_formats[i].wFormatTag != 0) @@ -231,7 +234,6 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) } return CHANNEL_RC_OK; - out_free: free(context->client_formats); return error; @@ -243,15 +245,15 @@ static void* rdpsnd_server_thread(void* arg) HANDLE events[8]; RdpsndServerContext* context; UINT error = CHANNEL_RC_OK; + context = (RdpsndServerContext*)arg; - context = (RdpsndServerContext *)arg; nCount = 0; events[nCount++] = context->priv->channelEvent; events[nCount++] = context->priv->StopEvent; if ((error = rdpsnd_server_send_formats(context, context->priv->rdpsnd_pdu))) { - WLog_ERR(TAG, "rdpsnd_server_send_formats failed with error %lu", error); + WLog_ERR(TAG, "rdpsnd_server_send_formats failed with error %u", error); goto out; } @@ -259,36 +261,38 @@ static void* rdpsnd_server_thread(void* arg) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error); + break; + } - status = WaitForSingleObject(context->priv->StopEvent, 0); - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - break; - } + status = WaitForSingleObject(context->priv->StopEvent, 0); + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + break; + } if (status == WAIT_OBJECT_0) break; if ((error = rdpsnd_server_handle_messages(context))) { - WLog_ERR(TAG, "rdpsnd_server_handle_messages failed with error %lu", error); + WLog_ERR(TAG, "rdpsnd_server_handle_messages failed with error %u", error); break; } } out: + if (error && context->rdpcontext) - setChannelError(context->rdpcontext, error, "rdpsnd_server_thread reported an error"); + setChannelError(context->rdpcontext, error, + "rdpsnd_server_thread reported an error"); + ExitThread((DWORD)error); return NULL; } @@ -298,7 +302,8 @@ out: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_server_initialize(RdpsndServerContext* context, BOOL ownThread) +static UINT rdpsnd_server_initialize(RdpsndServerContext* context, + BOOL ownThread) { context->priv->ownThread = ownThread; return context->Start(context); @@ -309,63 +314,79 @@ static UINT rdpsnd_server_initialize(RdpsndServerContext* context, BOOL ownThrea * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_server_select_format(RdpsndServerContext* context, int client_format_index) +static UINT rdpsnd_server_select_format(RdpsndServerContext* context, + int client_format_index) { int bs; int out_buffer_size; - AUDIO_FORMAT *format; + AUDIO_FORMAT* format; + UINT error = CHANNEL_RC_OK; - if (client_format_index < 0 || client_format_index >= context->num_client_formats) + if (client_format_index < 0 + || client_format_index >= context->num_client_formats) { WLog_ERR(TAG, "index %d is not correct.", client_format_index); return ERROR_INVALID_DATA; } - - context->priv->src_bytes_per_sample = context->src_format.wBitsPerSample / 8; - context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample * context->src_format.nChannels; + EnterCriticalSection(&context->priv->lock); + context->priv->src_bytes_per_sample = context->src_format.wBitsPerSample / 8; + context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample * + context->src_format.nChannels; context->selected_client_format = client_format_index; format = &context->client_formats[client_format_index]; - + if (format->nSamplesPerSec == 0) { WLog_ERR(TAG, "invalid Client Sound Format!!"); - return ERROR_INVALID_DATA; + error = ERROR_INVALID_DATA; + goto out; } - switch(format->wFormatTag) + if (context->latency <= 0) + context->latency = 50; + + context->priv->out_frames = context->src_format.nSamplesPerSec * + context->latency / 1000; + + if (context->priv->out_frames < 1) + context->priv->out_frames = 1; + + switch (format->wFormatTag) { case WAVE_FORMAT_DVI_ADPCM: bs = (format->nBlockAlign - 4 * format->nChannels) * 4; - context->priv->out_frames = (format->nBlockAlign * 4 * format->nChannels * 2 / bs + 1) * bs / (format->nChannels * 2); + context->priv->out_frames -= context->priv->out_frames % bs; + + if (context->priv->out_frames < bs) + context->priv->out_frames = bs; + break; case WAVE_FORMAT_ADPCM: bs = (format->nBlockAlign - 7 * format->nChannels) * 2 / format->nChannels + 2; - context->priv->out_frames = bs * 4; - break; - default: - context->priv->out_frames = 0x4000 / context->priv->src_bytes_per_frame; + context->priv->out_frames -= context->priv->out_frames % bs; + + if (context->priv->out_frames < bs) + context->priv->out_frames = bs; + break; } - if (format->nSamplesPerSec != context->src_format.nSamplesPerSec) - { - context->priv->out_frames = (context->priv->out_frames * context->src_format.nSamplesPerSec + format->nSamplesPerSec - 100) / format->nSamplesPerSec; - } context->priv->out_pending_frames = 0; + out_buffer_size = context->priv->out_frames * + context->priv->src_bytes_per_frame; - out_buffer_size = context->priv->out_frames * context->priv->src_bytes_per_frame; - if (context->priv->out_buffer_size < out_buffer_size) { - BYTE *newBuffer; + BYTE* newBuffer; + newBuffer = (BYTE*)realloc(context->priv->out_buffer, out_buffer_size); - newBuffer = (BYTE *)realloc(context->priv->out_buffer, out_buffer_size); if (!newBuffer) { WLog_ERR(TAG, "realloc failed!"); - return CHANNEL_RC_NO_MEMORY; + error = CHANNEL_RC_NO_MEMORY; + goto out; } context->priv->out_buffer = newBuffer; @@ -373,15 +394,19 @@ static UINT rdpsnd_server_select_format(RdpsndServerContext* context, int client } freerdp_dsp_context_reset_adpcm(context->priv->dsp_context); - return CHANNEL_RC_OK; +out: + LeaveCriticalSection(&context->priv->lock); + return error; } /** * Function description + * context->priv->lock should be obtained before calling this function * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, UINT16 wTimestamp) +static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, + UINT16 wTimestamp) { int size; BYTE* src; @@ -393,50 +418,51 @@ static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, UINT16 wT ULONG written; wStream* s = context->priv->rdpsnd_pdu; UINT error = CHANNEL_RC_OK; - format = &context->client_formats[context->selected_client_format]; tbytes_per_frame = format->nChannels * context->priv->src_bytes_per_sample; if ((format->nSamplesPerSec == context->src_format.nSamplesPerSec) && - (format->nChannels == context->src_format.nChannels)) + (format->nChannels == context->src_format.nChannels)) { src = context->priv->out_buffer; frames = context->priv->out_pending_frames; } else { - context->priv->dsp_context->resample(context->priv->dsp_context, context->priv->out_buffer, - context->priv->src_bytes_per_sample, context->src_format.nChannels, - context->src_format.nSamplesPerSec, context->priv->out_pending_frames, - format->nChannels, format->nSamplesPerSec); + context->priv->dsp_context->resample(context->priv->dsp_context, + context->priv->out_buffer, + context->priv->src_bytes_per_sample, context->src_format.nChannels, + context->src_format.nSamplesPerSec, context->priv->out_pending_frames, + format->nChannels, format->nSamplesPerSec); frames = context->priv->dsp_context->resampled_frames; src = context->priv->dsp_context->resampled_buffer; } + size = frames * tbytes_per_frame; if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM) { context->priv->dsp_context->encode_ima_adpcm(context->priv->dsp_context, - src, size, format->nChannels, format->nBlockAlign); + src, size, format->nChannels, format->nBlockAlign); src = context->priv->dsp_context->adpcm_buffer; size = context->priv->dsp_context->adpcm_size; } else if (format->wFormatTag == WAVE_FORMAT_ADPCM) { context->priv->dsp_context->encode_ms_adpcm(context->priv->dsp_context, - src, size, format->nChannels, format->nBlockAlign); + src, size, format->nChannels, format->nBlockAlign); src = context->priv->dsp_context->adpcm_buffer; size = context->priv->dsp_context->adpcm_size; } context->block_no = (context->block_no + 1) % 256; - /* Fill to nBlockAlign for the last audio packet */ - fill_size = 0; - if ((format->wFormatTag == WAVE_FORMAT_DVI_ADPCM || format->wFormatTag == WAVE_FORMAT_ADPCM) && - (context->priv->out_pending_frames < context->priv->out_frames) && ((size % format->nBlockAlign) != 0)) + if ((format->wFormatTag == WAVE_FORMAT_DVI_ADPCM + || format->wFormatTag == WAVE_FORMAT_ADPCM) && + (context->priv->out_pending_frames < context->priv->out_frames) + && ((size % format->nBlockAlign) != 0)) { fill_size = format->nBlockAlign - (size % format->nBlockAlign); } @@ -446,14 +472,14 @@ static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, UINT16 wT Stream_Write_UINT8(s, SNDC_WAVE); /* msgType */ Stream_Write_UINT8(s, 0); /* bPad */ Stream_Write_UINT16(s, size + fill_size + 8); /* BodySize */ - Stream_Write_UINT16(s, wTimestamp); /* wTimeStamp */ Stream_Write_UINT16(s, context->selected_client_format); /* wFormatNo */ Stream_Write_UINT8(s, context->block_no); /* cBlockNo */ Stream_Seek(s, 3); /* bPad */ Stream_Write(s, src, 4); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); if (!status) { WLog_ERR(TAG, "WTSVirtualChannelWrite failed!"); @@ -470,13 +496,15 @@ static UINT rdpsnd_server_send_audio_pdu(RdpsndServerContext* context, UINT16 wT error = CHANNEL_RC_NO_MEMORY; goto out; } + Stream_Write_UINT32(s, 0); /* bPad */ Stream_Write(s, src + 4, size - 4); if (fill_size > 0) Stream_Zero(s, fill_size); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); if (!status) { @@ -495,22 +523,30 @@ out: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_server_send_samples(RdpsndServerContext* context, const void* buf, int nframes, UINT16 wTimestamp) +static UINT rdpsnd_server_send_samples(RdpsndServerContext* context, + const void* buf, int nframes, UINT16 wTimestamp) { int cframes; int cframesize; UINT error = CHANNEL_RC_OK; + EnterCriticalSection(&context->priv->lock); if (context->selected_client_format < 0) - return ERROR_INVALID_DATA; + { + /* It's possible while format negotiation has not been done */ + WLog_WARN(TAG, "Drop samples because client format has not been negotiated."); + error = ERROR_NOT_READY; + goto out; + } while (nframes > 0) { - cframes = MIN(nframes, context->priv->out_frames - context->priv->out_pending_frames); + cframes = MIN(nframes, context->priv->out_frames - + context->priv->out_pending_frames); cframesize = cframes * context->priv->src_bytes_per_frame; - CopyMemory(context->priv->out_buffer + - (context->priv->out_pending_frames * context->priv->src_bytes_per_frame), buf, cframesize); + (context->priv->out_pending_frames * context->priv->src_bytes_per_frame), buf, + cframesize); buf = (BYTE*) buf + cframesize; nframes -= cframes; context->priv->out_pending_frames += cframes; @@ -518,11 +554,15 @@ static UINT rdpsnd_server_send_samples(RdpsndServerContext* context, const void* if (context->priv->out_pending_frames >= context->priv->out_frames) { if ((error = rdpsnd_server_send_audio_pdu(context, wTimestamp))) - WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %lu", error); - + { + WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %u", error); + break; + } } } +out: + LeaveCriticalSection(&context->priv->lock); return error; } @@ -531,27 +571,25 @@ static UINT rdpsnd_server_send_samples(RdpsndServerContext* context, const void* * * @return 0 on success, otherwise a Win32 error code */ -static UINT rdpsnd_server_set_volume(RdpsndServerContext* context, int left, int right) +static UINT rdpsnd_server_set_volume(RdpsndServerContext* context, int left, + int right) { int pos; BOOL status; ULONG written; wStream* s = context->priv->rdpsnd_pdu; - Stream_Write_UINT8(s, SNDC_SETVOLUME); Stream_Write_UINT8(s, 0); Stream_Seek_UINT16(s); - Stream_Write_UINT16(s, left); Stream_Write_UINT16(s, right); - pos = Stream_GetPosition(s); Stream_SetPosition(s, 2); Stream_Write_UINT16(s, pos - 4); Stream_SetPosition(s, pos); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); Stream_SetPosition(s, 0); - return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -567,32 +605,37 @@ static UINT rdpsnd_server_close(RdpsndServerContext* context) ULONG written; wStream* s = context->priv->rdpsnd_pdu; UINT error = CHANNEL_RC_OK; - - if (context->selected_client_format < 0) - return ERROR_INVALID_DATA; + EnterCriticalSection(&context->priv->lock); if (context->priv->out_pending_frames > 0) { - if ((error = rdpsnd_server_send_audio_pdu(context, 0))) + if (context->selected_client_format < 0) { - WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %lu", error); - return error; + WLog_ERR(TAG, "Pending audio frame exists while no format selected."); + error = ERROR_INVALID_DATA; + } + else if ((error = rdpsnd_server_send_audio_pdu(context, 0))) + { + WLog_ERR(TAG, "rdpsnd_server_send_audio_pdu failed with error %u", error); } } - context->selected_client_format = -1; + LeaveCriticalSection(&context->priv->lock); + if (error) + return error; + + context->selected_client_format = -1; Stream_Write_UINT8(s, SNDC_CLOSE); Stream_Write_UINT8(s, 0); Stream_Seek_UINT16(s); - pos = Stream_GetPosition(s); Stream_SetPosition(s, 2); Stream_Write_UINT16(s, pos - 4); Stream_SetPosition(s, pos); - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); Stream_SetPosition(s, 0); - return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -603,31 +646,36 @@ static UINT rdpsnd_server_close(RdpsndServerContext* context) */ static UINT rdpsnd_server_start(RdpsndServerContext* context) { - void *buffer = NULL; + void* buffer = NULL; DWORD bytesReturned; - RdpsndServerPrivate *priv = context->priv; + RdpsndServerPrivate* priv = context->priv; UINT error = ERROR_INTERNAL_ERROR; + priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, + "rdpsnd"); - priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "rdpsnd"); if (!priv->ChannelHandle) { WLog_ERR(TAG, "WTSVirtualChannelOpen failed!"); return ERROR_INTERNAL_ERROR; } - if (!WTSVirtualChannelQuery(priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &bytesReturned) || (bytesReturned != sizeof(HANDLE))) + if (!WTSVirtualChannelQuery(priv->ChannelHandle, WTSVirtualEventHandle, &buffer, + &bytesReturned) || (bytesReturned != sizeof(HANDLE))) { - WLog_ERR(TAG, "error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)", - bytesReturned); + WLog_ERR(TAG, + "error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)", + bytesReturned); if (buffer) WTSFreeMemory(buffer); + goto out_close; } + CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE)); WTSFreeMemory(buffer); - priv->rdpsnd_pdu = Stream_New(NULL, 4096); + if (!priv->rdpsnd_pdu) { WLog_ERR(TAG, "Stream_New failed!"); @@ -635,30 +683,38 @@ static UINT rdpsnd_server_start(RdpsndServerContext* context) goto out_close; } + if (!InitializeCriticalSectionEx(&context->priv->lock, 0, 0)) + { + WLog_ERR(TAG, "InitializeCriticalSectionEx failed!"); + goto out_pdu; + } + if (priv->ownThread) { context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!context->priv->StopEvent) { WLog_ERR(TAG, "CreateEvent failed!"); - goto out_pdu; + goto out_lock; } context->priv->Thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) rdpsnd_server_thread, (void*) context, 0, NULL); + (LPTHREAD_START_ROUTINE) rdpsnd_server_thread, (void*) context, 0, NULL); + if (!context->priv->Thread) { WLog_ERR(TAG, "CreateThread failed!"); goto out_stopEvent; } - } return CHANNEL_RC_OK; - out_stopEvent: CloseHandle(context->priv->StopEvent); context->priv->StopEvent = NULL; +out_lock: + DeleteCriticalSection(&context->priv->lock); out_pdu: Stream_Free(context->priv->rdpsnd_pdu, TRUE); context->priv->rdpsnd_pdu = NULL; @@ -675,7 +731,8 @@ out_close: */ static UINT rdpsnd_server_stop(RdpsndServerContext* context) { - UINT error = CHANNEL_RC_OK; + UINT error = CHANNEL_RC_OK; + if (context->priv->ownThread) { if (context->priv->StopEvent) @@ -683,16 +740,19 @@ static UINT rdpsnd_server_stop(RdpsndServerContext* context) SetEvent(context->priv->StopEvent); if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + return error; + } + CloseHandle(context->priv->Thread); CloseHandle(context->priv->StopEvent); } } + DeleteCriticalSection(&context->priv->lock); + if (context->priv->rdpsnd_pdu) Stream_Free(context->priv->rdpsnd_pdu, TRUE); @@ -702,9 +762,9 @@ static UINT rdpsnd_server_stop(RdpsndServerContext* context) RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm) { RdpsndServerContext* context; - RdpsndServerPrivate *priv; + RdpsndServerPrivate* priv; + context = (RdpsndServerContext*)calloc(1, sizeof(RdpsndServerContext)); - context = (RdpsndServerContext *)calloc(1, sizeof(RdpsndServerContext)); if (!context) { WLog_ERR(TAG, "calloc failed!"); @@ -712,18 +772,17 @@ RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm) } context->vcm = vcm; - context->Start = rdpsnd_server_start; context->Stop = rdpsnd_server_stop; - context->selected_client_format = -1; context->Initialize = rdpsnd_server_initialize; context->SelectFormat = rdpsnd_server_select_format; context->SendSamples = rdpsnd_server_send_samples; context->SetVolume = rdpsnd_server_set_volume; context->Close = rdpsnd_server_close; + context->priv = priv = (RdpsndServerPrivate*)calloc(1, + sizeof(RdpsndServerPrivate)); - context->priv = priv = (RdpsndServerPrivate *)calloc(1, sizeof(RdpsndServerPrivate)); if (!priv) { WLog_ERR(TAG, "calloc failed!"); @@ -731,6 +790,7 @@ RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm) } priv->dsp_context = freerdp_dsp_context_new(); + if (!priv->dsp_context) { WLog_ERR(TAG, "freerdp_dsp_context_new failed!"); @@ -738,6 +798,7 @@ RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm) } priv->input_stream = Stream_New(NULL, 4); + if (!priv->input_stream) { WLog_ERR(TAG, "Stream_New failed!"); @@ -748,7 +809,6 @@ RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm) priv->waitingHeader = TRUE; priv->ownThread = TRUE; return context; - out_free_dsp: freerdp_dsp_context_free(priv->dsp_context); out_free_priv: @@ -759,11 +819,10 @@ out_free: } -void rdpsnd_server_context_reset(RdpsndServerContext *context) +void rdpsnd_server_context_reset(RdpsndServerContext* context) { context->priv->expectedBytes = 4; context->priv->waitingHeader = TRUE; - Stream_SetPosition(context->priv->input_stream, 0); } @@ -781,13 +840,11 @@ void rdpsnd_server_context_free(RdpsndServerContext* context) Stream_Free(context->priv->input_stream, TRUE); free(context->client_formats); - free(context->priv); - free(context); } -HANDLE rdpsnd_server_get_event_handle(RdpsndServerContext *context) +HANDLE rdpsnd_server_get_event_handle(RdpsndServerContext* context) { return context->priv->channelEvent; } @@ -806,15 +863,15 @@ HANDLE rdpsnd_server_get_event_handle(RdpsndServerContext *context) * * @return 0 on success, otherwise a Win32 error code */ -UINT rdpsnd_server_handle_messages(RdpsndServerContext *context) +UINT rdpsnd_server_handle_messages(RdpsndServerContext* context) { DWORD bytesReturned; UINT ret = CHANNEL_RC_OK; + RdpsndServerPrivate* priv = context->priv; + wStream* s = priv->input_stream; - RdpsndServerPrivate *priv = context->priv; - wStream *s = priv->input_stream; - - if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s), priv->expectedBytes, &bytesReturned)) + if (!WTSVirtualChannelRead(priv->ChannelHandle, 0, (PCHAR)Stream_Pointer(s), + priv->expectedBytes, &bytesReturned)) { if (GetLastError() == ERROR_NO_DATA) return ERROR_NO_DATA; @@ -822,6 +879,7 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context) WLog_ERR(TAG, "channel connection closed"); return ERROR_INTERNAL_ERROR; } + priv->expectedBytes -= bytesReturned; Stream_Seek(s, bytesReturned); @@ -830,15 +888,16 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context) Stream_SealLength(s); Stream_SetPosition(s, 0); + if (priv->waitingHeader) { /* header case */ Stream_Read_UINT8(s, priv->msgType); Stream_Seek_UINT8(s); /* bPad */ Stream_Read_UINT16(s, priv->expectedBytes); - priv->waitingHeader = FALSE; Stream_SetPosition(s, 0); + if (priv->expectedBytes) { if (!Stream_EnsureCapacity(s, priv->expectedBytes)) @@ -846,6 +905,7 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context) WLog_ERR(TAG, "Stream_EnsureCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + return CHANNEL_RC_OK; } } @@ -873,10 +933,12 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context) case SNDC_QUALITYMODE: ret = rdpsnd_server_recv_quality_mode(context, s); - Stream_SetPosition(s, 0); /* in case the Activated callback tries to treat some messages */ + Stream_SetPosition(s, + 0); /* in case the Activated callback tries to treat some messages */ if ((ret == CHANNEL_RC_OK) && (context->clientVersion >= 6)) IFCALL(context->Activated, context); + break; default: @@ -884,7 +946,7 @@ UINT rdpsnd_server_handle_messages(RdpsndServerContext *context) ret = ERROR_INVALID_DATA; break; } - Stream_SetPosition(s, 0); + Stream_SetPosition(s, 0); return ret; } diff --git a/channels/rdpsnd/server/rdpsnd_main.h b/channels/rdpsnd/server/rdpsnd_main.h index 20ed42d..797eaaf 100644 --- a/channels/rdpsnd/server/rdpsnd_main.h +++ b/channels/rdpsnd/server/rdpsnd_main.h @@ -52,6 +52,7 @@ struct _rdpsnd_server_private UINT32 src_bytes_per_sample; UINT32 src_bytes_per_frame; FREERDP_DSP_CONTEXT* dsp_context; + CRITICAL_SECTION lock; /* Protect out_buffer and related parameters */ }; #endif /* FREERDP_CHANNEL_SERVER_RDPSND_MAIN_H */ diff --git a/channels/remdesk/client/CMakeLists.txt b/channels/remdesk/client/CMakeLists.txt index 1c289b9..bb66f6e 100644 --- a/channels/remdesk/client/CMakeLists.txt +++ b/channels/remdesk/client/CMakeLists.txt @@ -21,7 +21,7 @@ set(${MODULE_PREFIX}_SRCS remdesk_main.c remdesk_main.h) -add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntry") +add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx") diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c index 7e34d59..715f5a9 100644 --- a/channels/remdesk/client/remdesk_main.c +++ b/channels/remdesk/client/remdesk_main.c @@ -33,7 +33,8 @@ #include "remdesk_main.h" -RemdeskClientContext* remdesk_get_client_interface(remdeskPlugin* remdesk) +static RemdeskClientContext* remdesk_get_client_interface( + remdeskPlugin* remdesk) { RemdeskClientContext* pInterface; pInterface = (RemdeskClientContext*) remdesk->channelEntryPoints.pInterface; @@ -55,12 +56,13 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s) return CHANNEL_RC_INVALID_INSTANCE; } - status = remdesk->channelEntryPoints.pVirtualChannelWrite(remdesk->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_Length(s), s); + status = remdesk->channelEntryPoints.pVirtualChannelWriteEx(remdesk->InitHandle, + remdesk->OpenHandle, + Stream_Buffer(s), (UINT32) Stream_Length(s), s); if (status != CHANNEL_RC_OK) - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); return status; } @@ -70,7 +72,7 @@ static UINT remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) +static UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) { char* name; char* pass; @@ -97,7 +99,7 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) name = "Expert"; remdesk->EncryptedPassStub = freerdp_assistance_encrypt_pass_stub(password, - settings->RemoteAssistancePassStub, &(remdesk->EncryptedPassStubSize)); + settings->RemoteAssistancePassStub, &(remdesk->EncryptedPassStubSize)); if (!remdesk->EncryptedPassStub) { @@ -105,7 +107,8 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) return ERROR_INTERNAL_ERROR; } - pass = freerdp_assistance_bin_to_hex_string(remdesk->EncryptedPassStub, remdesk->EncryptedPassStubSize); + pass = freerdp_assistance_bin_to_hex_string(remdesk->EncryptedPassStub, + remdesk->EncryptedPassStubSize); if (!pass) { @@ -129,7 +132,8 @@ UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_read_channel_header(wStream* s, + REMDESK_CHANNEL_HEADER* header) { int status; UINT32 ChannelNameLen; @@ -152,7 +156,7 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head if ((ChannelNameLen % 2) != 0) { - WLog_ERR(TAG, "ChannelNameLen % 2) != 0 "); + WLog_ERR(TAG, "ChannelNameLen %% 2) != 0 "); return ERROR_INVALID_DATA; } @@ -163,11 +167,9 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head } ZeroMemory(header->ChannelName, sizeof(header->ChannelName)); - pChannelName = (char*) header->ChannelName; status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), - ChannelNameLen / 2, &pChannelName, 32, NULL, NULL); - + ChannelNameLen / 2, &pChannelName, 32, NULL, NULL); Stream_Seek(s, ChannelNameLen); if (status <= 0) @@ -184,12 +186,12 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_write_channel_header(wStream* s, + REMDESK_CHANNEL_HEADER* header) { int index; UINT32 ChannelNameLen; WCHAR ChannelNameW[32]; - ZeroMemory(ChannelNameW, sizeof(ChannelNameW)); for (index = 0; index < 32; index++) @@ -198,12 +200,9 @@ static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* hea } ChannelNameLen = (strlen(header->ChannelName) + 1) * 2; - Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */ Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */ - Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */ - return CHANNEL_RC_OK; } @@ -224,7 +223,8 @@ static UINT remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize) +static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, + UINT32 msgType, UINT32 msgSize) { ctlHeader->msgType = msgType; strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME); @@ -237,7 +237,8 @@ static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msg * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, + wStream* s, REMDESK_CHANNEL_HEADER* header) { return CHANNEL_RC_OK; } @@ -247,7 +248,8 @@ static UINT remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, + wStream* s, REMDESK_CHANNEL_HEADER* header) { UINT32 versionMajor; UINT32 versionMinor; @@ -260,9 +262,7 @@ static UINT remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */ Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */ - remdesk->Version = versionMajor; - return CHANNEL_RC_OK; } @@ -276,13 +276,11 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) wStream* s; REMDESK_CTL_VERSION_INFO_PDU pdu; UINT error; - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8); - pdu.versionMajor = 1; pdu.versionMinor = 2; - s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -290,17 +288,16 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */ Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */ - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(remdesk, s))) - WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error); if (error != CHANNEL_RC_OK) Stream_Free(s, TRUE); + return error; } @@ -309,7 +306,8 @@ static UINT remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult) +static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, + REMDESK_CHANNEL_HEADER* header, UINT32* pResult) { UINT32 result; @@ -320,7 +318,6 @@ static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMD } Stream_Read_UINT32(s, result); /* result (4 bytes) */ - *pResult = result; //WLog_DBG(TAG, "RemdeskRecvResult: 0x%04X", result); return CHANNEL_RC_OK; @@ -344,14 +341,14 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) if ((error = remdesk_generate_expert_blob(remdesk))) { - WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %lu", error); + WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %u", error); return error; } pdu.expertBlob = remdesk->ExpertBlob; pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket; - - status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0); + status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, + &raConnectionStringW, 0); if (status <= 0) { @@ -360,7 +357,6 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) } cbRaConnectionStringW = status * 2; - status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0); if (status <= 0) @@ -371,11 +367,10 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) } cbExpertBlobW = status * 2; - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_AUTHENTICATE, - cbRaConnectionStringW + cbExpertBlobW); - + cbRaConnectionStringW + cbExpertBlobW); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -384,18 +379,17 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW); Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW); - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(remdesk, s))) - WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error); out: free(raConnectionStringW); free(expertBlobW); + if (error != CHANNEL_RC_OK) Stream_Free(s, TRUE); @@ -415,10 +409,9 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) int cbRaConnectionStringW = 0; WCHAR* raConnectionStringW = NULL; REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu; - pdu.raConnectionString = remdesk->settings->RemoteAssistanceRCTicket; - - status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0); + status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, + &raConnectionStringW, 0); if (status <= 0) { @@ -427,10 +420,10 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) } cbRaConnectionStringW = status * 2; - - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_REMOTE_CONTROL_DESKTOP, cbRaConnectionStringW); - + remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_REMOTE_CONTROL_DESKTOP, + cbRaConnectionStringW); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -439,16 +432,15 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write(s, (BYTE*) raConnectionStringW, cbRaConnectionStringW); - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(remdesk, s))) - WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error); out: free(raConnectionStringW); + if (error != CHANNEL_RC_OK) Stream_Free(s, TRUE); @@ -471,12 +463,11 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) if ((error = remdesk_generate_expert_blob(remdesk))) { - WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %u!", error); return error; } pdu.expertBlob = remdesk->ExpertBlob; - status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0); if (status <= 0) @@ -486,10 +477,10 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) } cbExpertBlobW = status * 2; - - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERIFY_PASSWORD, cbExpertBlobW); - + remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERIFY_PASSWORD, + cbExpertBlobW); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -498,16 +489,15 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write(s, (BYTE*) expertBlobW, cbExpertBlobW); - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(remdesk, s))) - WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error); out: free(expertBlobW); + if (error != CHANNEL_RC_OK) Stream_Free(s, TRUE); @@ -527,17 +517,16 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk) if ((error = remdesk_generate_expert_blob(remdesk))) { - WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_generate_expert_blob failed with error %u!", error); return error; } pdu.EncryptedPasswordLength = remdesk->EncryptedPassStubSize; pdu.EncryptedPassword = remdesk->EncryptedPassStub; - remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_EXPERT_ON_VISTA, - pdu.EncryptedPasswordLength); - + pdu.EncryptedPasswordLength); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -545,11 +534,8 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk) } remdesk_write_ctl_header(s, &(pdu.ctlHeader)); - Stream_Write(s, pdu.EncryptedPassword, pdu.EncryptedPasswordLength); - Stream_SealLength(s); - return remdesk_virtual_channel_write(remdesk, s); } @@ -558,7 +544,8 @@ static UINT remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, + REMDESK_CHANNEL_HEADER* header) { UINT error = CHANNEL_RC_OK; UINT32 msgType = 0; @@ -581,7 +568,8 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA case REMDESK_CTL_RESULT: if ((error = remdesk_recv_ctl_result_pdu(remdesk, s, header, &result))) - WLog_ERR(TAG, "remdesk_recv_ctl_result_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_recv_ctl_result_pdu failed with error %u", error); + break; case REMDESK_CTL_AUTHENTICATE: @@ -589,7 +577,9 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA case REMDESK_CTL_SERVER_ANNOUNCE: if ((error = remdesk_recv_ctl_server_announce_pdu(remdesk, s, header))) - WLog_ERR(TAG, "remdesk_recv_ctl_server_announce_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_recv_ctl_server_announce_pdu failed with error %u", + error); + break; case REMDESK_CTL_DISCONNECT: @@ -598,7 +588,7 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA case REMDESK_CTL_VERSIONINFO: if ((error = remdesk_recv_ctl_version_info_pdu(remdesk, s, header))) { - WLog_ERR(TAG, "remdesk_recv_ctl_version_info_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_recv_ctl_version_info_pdu failed with error %u", error); break; } @@ -606,19 +596,20 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA { if ((error = remdesk_send_ctl_version_info_pdu(remdesk))) { - WLog_ERR(TAG, "remdesk_send_ctl_version_info_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_send_ctl_version_info_pdu failed with error %u", error); break; } if ((error = remdesk_send_ctl_authenticate_pdu(remdesk))) { - WLog_ERR(TAG, "remdesk_send_ctl_authenticate_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_send_ctl_authenticate_pdu failed with error %u", error); break; } if ((error = remdesk_send_ctl_remote_control_desktop_pdu(remdesk))) { - WLog_ERR(TAG, "remdesk_send_ctl_remote_control_desktop_pdu failed with error %lu", error); + WLog_ERR(TAG, + "remdesk_send_ctl_remote_control_desktop_pdu failed with error %u", error); break; } } @@ -626,13 +617,15 @@ static UINT remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHA { if ((error = remdesk_send_ctl_expert_on_vista_pdu(remdesk))) { - WLog_ERR(TAG, "remdesk_send_ctl_expert_on_vista_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_send_ctl_expert_on_vista_pdu failed with error %u", + error); break; } if ((error = remdesk_send_ctl_verify_password_pdu(remdesk))) { - WLog_ERR(TAG, "remdesk_send_ctl_verify_password_pdu failed with error %lu", error); + WLog_ERR(TAG, "remdesk_send_ctl_verify_password_pdu failed with error %u", + error); break; } } @@ -675,7 +668,6 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s) { UINT status; REMDESK_CHANNEL_HEADER header; - #if 0 WLog_DBG(TAG, "RemdeskReceive: %d", Stream_GetRemainingLength(s)); winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s)); @@ -683,7 +675,7 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s) if ((status = remdesk_read_channel_header(s, &header))) { - WLog_ERR(TAG, "remdesk_read_channel_header failed with error %lu", status); + WLog_ERR(TAG, "remdesk_read_channel_header failed with error %u", status); return status; } @@ -693,27 +685,21 @@ static UINT remdesk_process_receive(remdeskPlugin* remdesk, wStream* s) } else if (strcmp(header.ChannelName, "70") == 0) { - } else if (strcmp(header.ChannelName, "71") == 0) { - } else if (strcmp(header.ChannelName, ".") == 0) { - } else if (strcmp(header.ChannelName, "1000.") == 0) { - } else if (strcmp(header.ChannelName, "RA_FX") == 0) { - } else { - } return status; @@ -724,89 +710,12 @@ static void remdesk_process_connect(remdeskPlugin* remdesk) remdesk->settings = (rdpSettings*) remdesk->channelEntryPoints.pExtendedData; } -/****************************************************************************************/ - -static wListDictionary* g_InitHandles = NULL; -static wListDictionary* g_OpenHandles = NULL; - /** * Function description * * @return 0 on success, otherwise a Win32 error code */ -UINT remdesk_add_init_handle_data(void* pInitHandle, void* pUserData) -{ - if (!g_InitHandles) - { - g_InitHandles = ListDictionary_New(TRUE); - if (!g_InitHandles) - return CHANNEL_RC_NO_MEMORY; - } - - return ListDictionary_Add(g_InitHandles, pInitHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; -} - -void* remdesk_get_init_handle_data(void* pInitHandle) -{ - void* pUserData = NULL; - pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle); - return pUserData; -} - -void remdesk_remove_init_handle_data(void* pInitHandle) -{ - ListDictionary_Remove(g_InitHandles, pInitHandle); - if (ListDictionary_Count(g_InitHandles) < 1) - { - ListDictionary_Free(g_InitHandles); - g_InitHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT remdesk_add_open_handle_data(DWORD openHandle, void* pUserData) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - - if (!g_OpenHandles) - { - g_OpenHandles = ListDictionary_New(TRUE); - if (!g_OpenHandles) - return CHANNEL_RC_NO_MEMORY; - } - - return ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; -} - -void* remdesk_get_open_handle_data(DWORD openHandle) -{ - void* pUserData = NULL; - void* pOpenHandle = (void*) (size_t) openHandle; - pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle); - return pUserData; -} - -void remdesk_remove_open_handle_data(DWORD openHandle) -{ - void* pOpenHandle = (void*) (size_t) openHandle; - ListDictionary_Remove(g_OpenHandles, pOpenHandle); - if (ListDictionary_Count(g_OpenHandles) < 1) - { - ListDictionary_Free(g_OpenHandles); - g_OpenHandles = NULL; - } -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -UINT remdesk_send(remdeskPlugin* remdesk, wStream* s) +static UINT remdesk_send(remdeskPlugin* remdesk, wStream* s) { UINT status = 0; remdeskPlugin* plugin = (remdeskPlugin*) remdesk; @@ -817,15 +726,15 @@ UINT remdesk_send(remdeskPlugin* remdesk, wStream* s) } else { - status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle, - Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); + status = plugin->channelEntryPoints.pVirtualChannelWriteEx(plugin->InitHandle, plugin->OpenHandle, + Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08X]", + WTSErrorToString(status), status); } return status; @@ -837,7 +746,7 @@ UINT remdesk_send(remdeskPlugin* remdesk, wStream* s) * @return 0 on success, otherwise a Win32 error code */ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk, - void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) + void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; @@ -852,6 +761,7 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk, Stream_Free(remdesk->data_in, TRUE); remdesk->data_in = Stream_New(NULL, totalLength); + if (!remdesk->data_in) { WLog_ERR(TAG, "Stream_New failed!"); @@ -860,11 +770,13 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk, } data_in = remdesk->data_in; + if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } + Stream_Write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) @@ -885,18 +797,18 @@ static UINT remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk, return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } -static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT event, - LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) +static VOID VCAPITYPE remdesk_virtual_channel_open_event_ex(LPVOID lpUserParam, DWORD openHandle, + UINT event, + LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { - remdeskPlugin* remdesk; UINT error = CHANNEL_RC_OK; + remdeskPlugin* remdesk = (remdeskPlugin*) lpUserParam; - remdesk = (remdeskPlugin*) remdesk_get_open_handle_data(openHandle); - - if (!remdesk) + if (!remdesk || (remdesk->OpenHandle != openHandle)) { WLog_ERR(TAG, "error no match"); return; @@ -905,8 +817,11 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT switch (event) { case CHANNEL_EVENT_DATA_RECEIVED: - if ((error = remdesk_virtual_channel_event_data_received(remdesk, pData, dataLength, totalLength, dataFlags))) - WLog_ERR(TAG, "remdesk_virtual_channel_event_data_received failed with error %lu!", error); + if ((error = remdesk_virtual_channel_event_data_received(remdesk, pData, + dataLength, totalLength, dataFlags))) + WLog_ERR(TAG, + "remdesk_virtual_channel_event_data_received failed with error %u!", error); + break; case CHANNEL_EVENT_WRITE_COMPLETE: @@ -917,13 +832,13 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT break; default: - WLog_ERR(TAG, "unhandled event %lu!", event); + WLog_ERR(TAG, "unhandled event %u!", event); error = ERROR_INTERNAL_ERROR; - } - if (error && remdesk->rdpcontext) - setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_open_event reported an error"); + if (error && remdesk->rdpcontext) + setChannelError(remdesk->rdpcontext, error, + "remdesk_virtual_channel_open_event_ex reported an error"); } static void* remdesk_virtual_channel_client_thread(void* arg) @@ -932,7 +847,6 @@ static void* remdesk_virtual_channel_client_thread(void* arg) wMessage message; remdeskPlugin* remdesk = (remdeskPlugin*) arg; UINT error = CHANNEL_RC_OK; - remdesk_process_connect(remdesk); while (1) @@ -944,27 +858,31 @@ static void* remdesk_virtual_channel_client_thread(void* arg) break; } - if (!MessageQueue_Peek(remdesk->queue, &message, TRUE)) { + if (!MessageQueue_Peek(remdesk->queue, &message, TRUE)) + { WLog_ERR(TAG, "MessageQueue_Peek failed!"); error = ERROR_INTERNAL_ERROR; break; } + if (message.id == WMQ_QUIT) break; if (message.id == 0) { data = (wStream*) message.wParam; + if ((error = remdesk_process_receive(remdesk, data))) { - WLog_ERR(TAG, "remdesk_process_receive failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_process_receive failed with error %u!", error); break; } } } if (error && remdesk->rdpcontext) - setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_client_thread reported an error"); + setChannelError(remdesk->rdpcontext, error, + "remdesk_virtual_channel_client_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -975,28 +893,24 @@ static void* remdesk_virtual_channel_client_thread(void* arg) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, LPVOID pData, UINT32 dataLength) +static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, + LPVOID pData, UINT32 dataLength) { UINT32 status; UINT error; - - status = remdesk->channelEntryPoints.pVirtualChannelOpen(remdesk->InitHandle, - &remdesk->OpenHandle, remdesk->channelDef.name, remdesk_virtual_channel_open_event); + status = remdesk->channelEntryPoints.pVirtualChannelOpenEx(remdesk->InitHandle, + &remdesk->OpenHandle, remdesk->channelDef.name, + remdesk_virtual_channel_open_event_ex); if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]", - WTSErrorToString(status), status); + WLog_ERR(TAG, "pVirtualChannelOpenEx failed with %s [%08X]", + WTSErrorToString(status), status); return status; } - if ((error = remdesk_add_open_handle_data(remdesk->OpenHandle, remdesk))) - { - WLog_ERR(TAG, "remdesk_add_open_handle_data failed with error %lu", error); - return error; - } - remdesk->queue = MessageQueue_New(NULL); + if (!remdesk->queue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -1005,16 +919,18 @@ static UINT remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, LPVO } remdesk->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) remdesk_virtual_channel_client_thread, (void*) remdesk, 0, NULL); + (LPTHREAD_START_ROUTINE) remdesk_virtual_channel_client_thread, (void*) remdesk, + 0, NULL); + if (!remdesk->thread) { WLog_ERR(TAG, "CreateThread failed"); error = ERROR_INTERNAL_ERROR; goto error_out; } + return CHANNEL_RC_OK; error_out: - remdesk_remove_open_handle_data(remdesk->OpenHandle); MessageQueue_Free(remdesk->queue); remdesk->queue = NULL; return error; @@ -1029,53 +945,51 @@ static UINT remdesk_virtual_channel_event_disconnected(remdeskPlugin* remdesk) { UINT rc; - if (MessageQueue_PostQuit(remdesk->queue, 0) && (WaitForSingleObject(remdesk->thread, INFINITE) == WAIT_FAILED)) + if (MessageQueue_PostQuit(remdesk->queue, 0) + && (WaitForSingleObject(remdesk->thread, INFINITE) == WAIT_FAILED)) { rc = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", rc); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", rc); return rc; } MessageQueue_Free(remdesk->queue); CloseHandle(remdesk->thread); - remdesk->queue = NULL; remdesk->thread = NULL; + rc = remdesk->channelEntryPoints.pVirtualChannelCloseEx(remdesk->InitHandle, remdesk->OpenHandle); - rc = remdesk->channelEntryPoints.pVirtualChannelClose(remdesk->OpenHandle); if (CHANNEL_RC_OK != rc) { - WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]", - WTSErrorToString(rc), rc); + WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08X]", + WTSErrorToString(rc), rc); } + remdesk->OpenHandle = 0; + if (remdesk->data_in) { Stream_Free(remdesk->data_in, TRUE); remdesk->data_in = NULL; } - remdesk_remove_open_handle_data(remdesk->OpenHandle); return rc; } static void remdesk_virtual_channel_event_terminated(remdeskPlugin* remdesk) { - remdesk_remove_init_handle_data(remdesk->InitHandle); - + remdesk->InitHandle = 0; free(remdesk); } -static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle, - UINT event, LPVOID pData, - UINT dataLength) +static VOID VCAPITYPE remdesk_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle, + UINT event, LPVOID pData, + UINT dataLength) { - remdeskPlugin* remdesk; UINT error = CHANNEL_RC_OK; + remdeskPlugin* remdesk = (remdeskPlugin*) lpUserParam; - remdesk = (remdeskPlugin*) remdesk_get_init_handle_data(pInitHandle); - - if (!remdesk) + if (!remdesk || (remdesk->InitHandle != pInitHandle)) { WLog_ERR(TAG, "error no match"); return; @@ -1084,34 +998,44 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle, switch (event) { case CHANNEL_EVENT_CONNECTED: - if ((error = remdesk_virtual_channel_event_connected(remdesk, pData, dataLength))) - WLog_ERR(TAG, "remdesk_virtual_channel_event_connected failed with error %lu", error); + if ((error = remdesk_virtual_channel_event_connected(remdesk, pData, + dataLength))) + WLog_ERR(TAG, "remdesk_virtual_channel_event_connected failed with error %u", + error); + break; case CHANNEL_EVENT_DISCONNECTED: if ((error = remdesk_virtual_channel_event_disconnected(remdesk))) - WLog_ERR(TAG, "remdesk_virtual_channel_event_disconnected failed with error %lu", error); + WLog_ERR(TAG, + "remdesk_virtual_channel_event_disconnected failed with error %u", error); + break; case CHANNEL_EVENT_TERMINATED: remdesk_virtual_channel_event_terminated(remdesk); break; } + if (error && remdesk->rdpcontext) - setChannelError(remdesk->rdpcontext, error, "remdesk_virtual_channel_init_event reported an error"); + setChannelError(remdesk->rdpcontext, error, + "remdesk_virtual_channel_init_event reported an error"); } /* remdesk is always built-in */ -#define VirtualChannelEntry remdesk_VirtualChannelEntry +#define VirtualChannelEntryEx remdesk_VirtualChannelEntryEx -BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle) { UINT rc; - UINT error; - remdeskPlugin* remdesk; RemdeskClientContext* context = NULL; - CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; + CHANNEL_ENTRY_POINTS_FREERDP_EX* pEntryPointsEx; + + if (!pEntryPoints) + { + return FALSE; + } remdesk = (remdeskPlugin*) calloc(1, sizeof(remdeskPlugin)); @@ -1122,21 +1046,19 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } remdesk->channelDef.options = - CHANNEL_OPTION_INITIALIZED | - CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP | - CHANNEL_OPTION_SHOW_PROTOCOL; - + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | + CHANNEL_OPTION_SHOW_PROTOCOL; strcpy(remdesk->channelDef.name, "remdesk"); - remdesk->Version = 2; + pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*) pEntryPoints; - pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; - - if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && - (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) + if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) && + (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { context = (RemdeskClientContext*) calloc(1, sizeof(RemdeskClientContext)); + if (!context) { WLog_ERR(TAG, "calloc failed!"); @@ -1144,31 +1066,25 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) } context->handle = (void*) remdesk; - - *(pEntryPointsEx->ppInterface) = (void*) context; remdesk->context = context; remdesk->rdpcontext = pEntryPointsEx->context; } - CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); + CopyMemory(&(remdesk->channelEntryPoints), pEntryPoints, + sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)); + remdesk->InitHandle = pInitHandle; + rc = remdesk->channelEntryPoints.pVirtualChannelInitEx(remdesk, context, pInitHandle, + &remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + remdesk_virtual_channel_init_event_ex); - rc = remdesk->channelEntryPoints.pVirtualChannelInit(&remdesk->InitHandle, - &remdesk->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, remdesk_virtual_channel_init_event); if (CHANNEL_RC_OK != rc) { - WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", - WTSErrorToString(rc), rc); + WLog_ERR(TAG, "pVirtualChannelInitEx failed with %s [%08X]", + WTSErrorToString(rc), rc); goto error_out; } - remdesk->channelEntryPoints.pInterface = *(remdesk->channelEntryPoints.ppInterface); - remdesk->channelEntryPoints.ppInterface = &(remdesk->channelEntryPoints.pInterface); - - if ((error = remdesk_add_init_handle_data(remdesk->InitHandle, (void*) remdesk))) - { - WLog_ERR(TAG, "remdesk_add_init_handle_data failed with error %lu!", error); - goto error_out; - } + remdesk->channelEntryPoints.pInterface = context; return TRUE; error_out: free(remdesk); diff --git a/channels/remdesk/client/remdesk_main.h b/channels/remdesk/client/remdesk_main.h index 59e92ca..13ae5c7 100644 --- a/channels/remdesk/client/remdesk_main.h +++ b/channels/remdesk/client/remdesk_main.h @@ -41,7 +41,7 @@ struct remdesk_plugin { CHANNEL_DEF channelDef; - CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints; + CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints; RemdeskClientContext* context; diff --git a/channels/remdesk/server/remdesk_main.c b/channels/remdesk/server/remdesk_main.c index cf33f76..8ee8dc3 100644 --- a/channels/remdesk/server/remdesk_main.c +++ b/channels/remdesk/server/remdesk_main.c @@ -34,14 +34,13 @@ * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_virtual_channel_write(RemdeskServerContext* context, wStream* s) +static UINT remdesk_virtual_channel_write(RemdeskServerContext* context, + wStream* s) { BOOL status; ULONG BytesWritten = 0; - status = WTSVirtualChannelWrite(context->priv->ChannelHandle, - (PCHAR) Stream_Buffer(s), Stream_Length(s), &BytesWritten); - + (PCHAR) Stream_Buffer(s), Stream_Length(s), &BytesWritten); return (status) ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } @@ -50,7 +49,8 @@ static UINT remdesk_virtual_channel_write(RemdeskServerContext* context, wStream * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_read_channel_header(wStream* s, + REMDESK_CHANNEL_HEADER* header) { int status; UINT32 ChannelNameLen; @@ -73,7 +73,7 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head if ((ChannelNameLen % 2) != 0) { - WLog_ERR(TAG, "(ChannelNameLen % 2) != 0!"); + WLog_ERR(TAG, "(ChannelNameLen %% 2) != 0!"); return ERROR_INVALID_DATA; } @@ -84,11 +84,9 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head } ZeroMemory(header->ChannelName, sizeof(header->ChannelName)); - pChannelName = (char*) header->ChannelName; status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), - ChannelNameLen / 2, &pChannelName, 32, NULL, NULL); - + ChannelNameLen / 2, &pChannelName, 32, NULL, NULL); Stream_Seek(s, ChannelNameLen); if (status <= 0) @@ -105,12 +103,12 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_write_channel_header(wStream* s, + REMDESK_CHANNEL_HEADER* header) { int index; UINT32 ChannelNameLen; WCHAR ChannelNameW[32]; - ZeroMemory(ChannelNameW, sizeof(ChannelNameW)); for (index = 0; index < 32; index++) @@ -119,12 +117,9 @@ static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* hea } ChannelNameLen = (strlen(header->ChannelName) + 1) * 2; - Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */ Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */ - Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */ - return CHANNEL_RC_OK; } @@ -136,11 +131,14 @@ static UINT remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* hea static UINT remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader) { UINT error; - if ((error = remdesk_write_channel_header(s, (REMDESK_CHANNEL_HEADER*) ctlHeader))) + + if ((error = remdesk_write_channel_header(s, + (REMDESK_CHANNEL_HEADER*) ctlHeader))) { - WLog_ERR(TAG, "remdesk_write_channel_header failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_write_channel_header failed with error %u!", error); return error; } + Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */ return CHANNEL_RC_OK; } @@ -150,7 +148,8 @@ static UINT remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader) * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize) +static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, + UINT32 msgType, UINT32 msgSize) { ctlHeader->msgType = msgType; strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME); @@ -163,21 +162,23 @@ static UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msg * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_send_ctl_result_pdu(RemdeskServerContext* context, UINT32 result) +static UINT remdesk_send_ctl_result_pdu(RemdeskServerContext* context, + UINT32 result) { wStream* s; REMDESK_CTL_RESULT_PDU pdu; UINT error; - pdu.result = result; - if ((error = remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_RESULT, 4))) + if ((error = remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_RESULT, + 4))) { - WLog_ERR(TAG, "remdesk_prepare_ctl_header failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_prepare_ctl_header failed with error %u!", error); return error; } s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -186,20 +187,18 @@ static UINT remdesk_send_ctl_result_pdu(RemdeskServerContext* context, UINT32 re if ((error = remdesk_write_ctl_header(s, &(pdu.ctlHeader)))) { - WLog_ERR(TAG, "remdesk_write_ctl_header failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_write_ctl_header failed with error %u!", error); goto out; } - Stream_Write_UINT32(s, pdu.result); /* result (4 bytes) */ - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(context, s))) - WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error); + out: Stream_Free(s, TRUE); - return error; } @@ -214,16 +213,17 @@ static UINT remdesk_send_ctl_version_info_pdu(RemdeskServerContext* context) REMDESK_CTL_VERSION_INFO_PDU pdu; UINT error; - if ((error = remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8))) + if ((error = remdesk_prepare_ctl_header(&(pdu.ctlHeader), + REMDESK_CTL_VERSIONINFO, 8))) { - WLog_ERR(TAG, "remdesk_prepare_ctl_header failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_prepare_ctl_header failed with error %u!", error); return error; } pdu.versionMajor = 1; pdu.versionMinor = 2; - s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -232,20 +232,19 @@ static UINT remdesk_send_ctl_version_info_pdu(RemdeskServerContext* context) if ((error = remdesk_write_ctl_header(s, &(pdu.ctlHeader)))) { - WLog_ERR(TAG, "remdesk_write_ctl_header failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_write_ctl_header failed with error %u!", error); goto out; } Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */ Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */ - Stream_SealLength(s); if ((error = remdesk_virtual_channel_write(context, s))) - WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_virtual_channel_write failed with error %u!", error); + out: Stream_Free(s, TRUE); - return error; } @@ -254,7 +253,8 @@ out: * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, + wStream* s, REMDESK_CHANNEL_HEADER* header) { UINT32 versionMajor; UINT32 versionMinor; @@ -267,7 +267,6 @@ static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wSt Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */ Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */ - return CHANNEL_RC_OK; } @@ -276,7 +275,8 @@ static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wSt * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_remote_control_desktop_pdu( + RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) { int status; int cchStringW; @@ -286,9 +286,7 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co WCHAR* raConnectionStringW = NULL; REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu; UINT error; - msgLength = header->DataLength - 4; - pStringW = (WCHAR*) Stream_Pointer(s); raConnectionStringW = pStringW; cchStringW = 0; @@ -304,11 +302,9 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co cchStringW++; cbRaConnectionStringW = cchStringW * 2; - pdu.raConnectionString = NULL; - status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW, - cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL); + cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL); if (status <= 0) { @@ -317,11 +313,11 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co } WLog_INFO(TAG, "RaConnectionString: %s", - pdu.raConnectionString); + pdu.raConnectionString); free(pdu.raConnectionString); if ((error = remdesk_send_ctl_result_pdu(context, 0))) - WLog_ERR(TAG, "remdesk_send_ctl_result_pdu failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_send_ctl_result_pdu failed with error %u!", error); return error; } @@ -331,7 +327,8 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, + wStream* s, REMDESK_CHANNEL_HEADER* header) { int status; int cchStringW; @@ -342,9 +339,7 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt int cbRaConnectionStringW = 0; WCHAR* raConnectionStringW = NULL; REMDESK_CTL_AUTHENTICATE_PDU pdu; - msgLength = header->DataLength - 4; - pStringW = (WCHAR*) Stream_Pointer(s); raConnectionStringW = pStringW; cchStringW = 0; @@ -360,7 +355,6 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt cchStringW++; cbRaConnectionStringW = cchStringW * 2; - pStringW += cchStringW; expertBlobW = pStringW; cchStringW = 0; @@ -376,11 +370,9 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt cchStringW++; cbExpertBlobW = cchStringW * 2; - pdu.raConnectionString = NULL; - status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW, - cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL); + cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL); if (status <= 0) { @@ -389,9 +381,8 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt } pdu.expertBlob = NULL; - status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, - cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL); + cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL); if (status <= 0) { @@ -401,10 +392,9 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt } WLog_INFO(TAG, "RaConnectionString: %s ExpertBlob: %s", - pdu.raConnectionString, pdu.expertBlob); + pdu.raConnectionString, pdu.expertBlob); free(pdu.raConnectionString); free(pdu.expertBlob); - return CHANNEL_RC_OK; } @@ -413,7 +403,8 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, + wStream* s, REMDESK_CHANNEL_HEADER* header) { int status; int cbExpertBlobW = 0; @@ -430,8 +421,8 @@ static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, pdu.expertBlob = NULL; expertBlobW = (WCHAR*) Stream_Pointer(s); cbExpertBlobW = header->DataLength - 4; - - status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL); + status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, cbExpertBlobW / 2, + &pdu.expertBlob, 0, NULL, NULL); if (status <= 0) { @@ -440,8 +431,9 @@ static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, } WLog_INFO(TAG, "ExpertBlob: %s", pdu.expertBlob); + if ((error = remdesk_send_ctl_result_pdu(context, 0))) - WLog_ERR(TAG, "remdesk_send_ctl_result_pdu failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_send_ctl_result_pdu failed with error %u!", error); return error; } @@ -451,7 +443,8 @@ static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, + REMDESK_CHANNEL_HEADER* header) { UINT error = CHANNEL_RC_OK; UINT32 msgType = 0; @@ -470,28 +463,34 @@ static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMD case REMDESK_CTL_REMOTE_CONTROL_DESKTOP: if ((error = remdesk_recv_ctl_remote_control_desktop_pdu(context, s, header))) { - WLog_ERR(TAG, "remdesk_recv_ctl_remote_control_desktop_pdu failed with error %lu!", error); + WLog_ERR(TAG, + "remdesk_recv_ctl_remote_control_desktop_pdu failed with error %u!", error); return error; } + break; case REMDESK_CTL_AUTHENTICATE: if ((error = remdesk_recv_ctl_authenticate_pdu(context, s, header))) { - WLog_ERR(TAG, "remdesk_recv_ctl_authenticate_pdu failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_recv_ctl_authenticate_pdu failed with error %u!", + error); return error; } + break; case REMDESK_CTL_DISCONNECT: break; case REMDESK_CTL_VERSIONINFO: - if((error = remdesk_recv_ctl_version_info_pdu(context, s, header))) + if ((error = remdesk_recv_ctl_version_info_pdu(context, s, header))) { - WLog_ERR(TAG, "remdesk_recv_ctl_version_info_pdu failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_recv_ctl_version_info_pdu failed with error %u!", + error); return error; } + break; case REMDESK_CTL_ISCONNECTED: @@ -500,9 +499,11 @@ static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMD case REMDESK_CTL_VERIFY_PASSWORD: if ((error = remdesk_recv_ctl_verify_password_pdu(context, s, header))) { - WLog_ERR(TAG, "remdesk_recv_ctl_verify_password_pdu failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_recv_ctl_verify_password_pdu failed with error %u!", + error); return error; } + break; case REMDESK_CTL_EXPERT_ON_VISTA: @@ -531,11 +532,11 @@ static UINT remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMD * * @return 0 on success, otherwise a Win32 error code */ -static UINT remdesk_server_receive_pdu(RemdeskServerContext* context, wStream* s) +static UINT remdesk_server_receive_pdu(RemdeskServerContext* context, + wStream* s) { UINT error = CHANNEL_RC_OK; REMDESK_CHANNEL_HEADER header; - #if 0 WLog_INFO(TAG, "RemdeskReceive: %d", Stream_GetRemainingLength(s)); winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s)); @@ -543,42 +544,35 @@ static UINT remdesk_server_receive_pdu(RemdeskServerContext* context, wStream* s if ((error = remdesk_read_channel_header(s, &header))) { - WLog_ERR(TAG, "remdesk_read_channel_header failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_read_channel_header failed with error %u!", error); return error; } - if (strcmp(header.ChannelName, "RC_CTL") == 0) { if ((error = remdesk_recv_ctl_pdu(context, s, &header))) { - WLog_ERR(TAG, "remdesk_recv_ctl_pdu failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_recv_ctl_pdu failed with error %u!", error); return error; } } else if (strcmp(header.ChannelName, "70") == 0) { - } else if (strcmp(header.ChannelName, "71") == 0) { - } else if (strcmp(header.ChannelName, ".") == 0) { - } else if (strcmp(header.ChannelName, "1000.") == 0) { - } else if (strcmp(header.ChannelName, "RA_FX") == 0) { - } else { - } return error; @@ -597,14 +591,13 @@ static void* remdesk_server_thread(void* arg) DWORD BytesReturned; RemdeskServerContext* context; UINT error; - context = (RemdeskServerContext*) arg; buffer = NULL; BytesReturned = 0; ChannelEvent = NULL; - s = Stream_New(NULL, 4096); + if (!s) { WLog_ERR(TAG, "Stream_New failed!"); @@ -612,7 +605,8 @@ static void* remdesk_server_thread(void* arg) goto out; } - if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE) + if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, + &buffer, &BytesReturned) == TRUE) { if (BytesReturned == sizeof(HANDLE)) CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE)); @@ -632,7 +626,8 @@ static void* remdesk_server_thread(void* arg) if ((error = remdesk_send_ctl_version_info_pdu(context))) { - WLog_ERR(TAG, "remdesk_send_ctl_version_info_pdu failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_send_ctl_version_info_pdu failed with error %u!", + error); goto out; } @@ -640,22 +635,21 @@ static void* remdesk_server_thread(void* arg) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error); - break; - } + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error); + break; + } - status = WaitForSingleObject(context->priv->StopEvent, 0); - - if (status == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - break; - } + status = WaitForSingleObject(context->priv->StopEvent, 0); + if (status == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error); + break; + } if (status == WAIT_OBJECT_0) { @@ -663,7 +657,7 @@ static void* remdesk_server_thread(void* arg) } if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0, - (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) + (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned)) { if (BytesReturned) Stream_Seek(s, BytesReturned); @@ -687,11 +681,13 @@ static void* remdesk_server_thread(void* arg) { Stream_SealLength(s); Stream_SetPosition(s, 0); + if ((error = remdesk_server_receive_pdu(context, s))) { - WLog_ERR(TAG, "remdesk_server_receive_pdu failed with error %lu!", error); + WLog_ERR(TAG, "remdesk_server_receive_pdu failed with error %u!", error); break; } + Stream_SetPosition(s, 0); } } @@ -699,8 +695,10 @@ static void* remdesk_server_thread(void* arg) Stream_Free(s, TRUE); out: + if (error && context->rdpcontext) - setChannelError(context->rdpcontext, error, "remdesk_server_thread reported an error"); + setChannelError(context->rdpcontext, error, + "remdesk_server_thread reported an error"); ExitThread((DWORD)error); return NULL; @@ -713,7 +711,8 @@ out: */ static UINT remdesk_server_start(RemdeskServerContext* context) { - context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "remdesk"); + context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, + WTS_CURRENT_SESSION, "remdesk"); if (!context->priv->ChannelHandle) { @@ -728,7 +727,7 @@ static UINT remdesk_server_start(RemdeskServerContext* context) } if (!(context->priv->Thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) remdesk_server_thread, (void*) context, 0, NULL))) + (LPTHREAD_START_ROUTINE) remdesk_server_thread, (void*) context, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); CloseHandle(context->priv->StopEvent); @@ -746,34 +745,30 @@ static UINT remdesk_server_start(RemdeskServerContext* context) */ static UINT remdesk_server_stop(RemdeskServerContext* context) { - UINT error; - + UINT error; SetEvent(context->priv->StopEvent); if (WaitForSingleObject(context->priv->Thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } - CloseHandle(context->priv->Thread); + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + return error; + } + CloseHandle(context->priv->Thread); return CHANNEL_RC_OK; } RemdeskServerContext* remdesk_server_context_new(HANDLE vcm) { RemdeskServerContext* context; - context = (RemdeskServerContext*) calloc(1, sizeof(RemdeskServerContext)); if (context) { context->vcm = vcm; - context->Start = remdesk_server_start; context->Stop = remdesk_server_stop; - context->priv = (RemdeskServerPrivate*) calloc(1, sizeof(RemdeskServerPrivate)); if (!context->priv) @@ -781,6 +776,7 @@ RemdeskServerContext* remdesk_server_context_new(HANDLE vcm) free(context); return NULL; } + context->priv->Version = 1; } diff --git a/channels/serial/client/CMakeLists.txt b/channels/serial/client/CMakeLists.txt index 086e141..f16995b 100644 --- a/channels/serial/client/CMakeLists.txt +++ b/channels/serial/client/CMakeLists.txt @@ -27,7 +27,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE target_link_libraries(${MODULE_NAME} winpr freerdp) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index b9650a9..af5ad8d 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -47,7 +47,7 @@ /* TODO: all #ifdef __linux__ could be removed once only some generic * functions will be used. Replace CommReadFile by ReadFile, * CommWriteFile by WriteFile etc.. */ -#if defined __linux__ && !defined ANDROID +#if defined __linux__ && !defined ANDROID #define MAX_IRP_THREADS 5 @@ -65,7 +65,7 @@ struct _SERIAL_DEVICE wMessageQueue* MainIrpQueue; /* one thread per pending IRP and indexed according their CompletionId */ - wListDictionary *IrpThreads; + wListDictionary* IrpThreads; UINT32 IrpThreadToBeTerminatedCount; CRITICAL_SECTION TerminatingIrpThreadsLock; rdpContext* rdpcontext; @@ -75,15 +75,14 @@ typedef struct _IRP_THREAD_DATA IRP_THREAD_DATA; struct _IRP_THREAD_DATA { - SERIAL_DEVICE *serial; - IRP *irp; + SERIAL_DEVICE* serial; + IRP* irp; }; static UINT32 _GetLastErrorToIoStatus(SERIAL_DEVICE* serial) { /* http://msdn.microsoft.com/en-us/library/ff547466%28v=vs.85%29.aspx#generic_status_values_for_serial_device_control_requests */ - - switch(GetLastError()) + switch (GetLastError()) { case ERROR_BAD_DEVICE: return STATUS_INVALID_DEVICE_REQUEST; @@ -117,11 +116,11 @@ static UINT32 _GetLastErrorToIoStatus(SERIAL_DEVICE* serial) case ERROR_TIMEOUT: return STATUS_TIMEOUT; - - /* no default */ + /* no default */ } - WLog_Print(serial->log, WLOG_DEBUG, "unexpected last-error: 0x%lx", GetLastError()); + WLog_Print(serial->log, WLOG_DEBUG, "unexpected last-error: 0x%lx", + GetLastError()); return STATUS_UNSUCCESSFUL; } @@ -131,19 +130,16 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) DWORD SharedAccess; DWORD CreateDisposition; UINT32 PathLength; - Stream_Read_UINT32(irp->input, DesiredAccess); /* DesiredAccess (4 bytes) */ Stream_Seek_UINT64(irp->input); /* AllocationSize (8 bytes) */ Stream_Seek_UINT32(irp->input); /* FileAttributes (4 bytes) */ Stream_Read_UINT32(irp->input, SharedAccess); /* SharedAccess (4 bytes) */ - Stream_Read_UINT32(irp->input, CreateDisposition); /* CreateDisposition (4 bytes) */ + Stream_Read_UINT32(irp->input, + CreateDisposition); /* CreateDisposition (4 bytes) */ Stream_Seek_UINT32(irp->input); /* CreateOptions (4 bytes) */ Stream_Read_UINT32(irp->input, PathLength); /* PathLength (4 bytes) */ Stream_Seek(irp->input, PathLength); /* Path (variable) */ - assert(PathLength == 0); /* MS-RDPESP 2.2.2.2 */ - - #ifndef _WIN32 /* Windows 2012 server sends on a first call : * DesiredAccess = 0x00100080: SYNCHRONIZE | FILE_READ_ATTRIBUTES @@ -160,35 +156,32 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) * assert(CreateDisposition == OPEN_EXISTING); * */ - - WLog_Print(serial->log, WLOG_DEBUG, "DesiredAccess: 0x%lX, SharedAccess: 0x%lX, CreateDisposition: 0x%lX", DesiredAccess, SharedAccess, CreateDisposition); - + WLog_Print(serial->log, WLOG_DEBUG, + "DesiredAccess: 0x%lX, SharedAccess: 0x%lX, CreateDisposition: 0x%lX", + DesiredAccess, SharedAccess, CreateDisposition); /* FIXME: As of today only the flags below are supported by CommCreateFileA: */ DesiredAccess = GENERIC_READ | GENERIC_WRITE; SharedAccess = 0; CreateDisposition = OPEN_EXISTING; #endif - serial->hComm = CreateFile(serial->device.name, - DesiredAccess, - SharedAccess, - NULL, /* SecurityAttributes */ - CreateDisposition, - 0, /* FlagsAndAttributes */ - NULL); /* TemplateFile */ + DesiredAccess, + SharedAccess, + NULL, /* SecurityAttributes */ + CreateDisposition, + 0, /* FlagsAndAttributes */ + NULL); /* TemplateFile */ if (!serial->hComm || (serial->hComm == INVALID_HANDLE_VALUE)) { - WLog_Print(serial->log, WLOG_WARN, "CreateFile failure: %s last-error: 0x%lX\n", serial->device.name, GetLastError()); - + WLog_Print(serial->log, WLOG_WARN, "CreateFile failure: %s last-error: 0x%lX\n", + serial->device.name, GetLastError()); irp->IoStatus = STATUS_UNSUCCESSFUL; goto error_handle; } _comm_setServerSerialDriver(serial->hComm, serial->ServerSerialDriverId); - _comm_set_permissive(serial->hComm, serial->permissive); - /* NOTE: binary mode/raw mode required for the redirection. On * Linux, CommCreateFileA forces this setting. */ @@ -197,15 +190,13 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) /* GetCommState(serial->hComm, &dcb); */ /* dcb.fBinary = TRUE; */ /* SetCommState(serial->hComm, &dcb); */ - assert(irp->FileId == 0); - irp->FileId = irp->devman->id_sequence++; /* FIXME: why not ((WINPR_COMM*)hComm)->fd? */ - + irp->FileId = + irp->devman->id_sequence++; /* FIXME: why not ((WINPR_COMM*)hComm)->fd? */ irp->IoStatus = STATUS_SUCCESS; - - WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %d, FileId: %d) created.", serial->device.name, irp->device->id, irp->FileId); - - error_handle: + WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %d, FileId: %d) created.", + serial->device.name, irp->device->id, irp->FileId); +error_handle: Stream_Write_UINT32(irp->output, irp->FileId); /* FileId (4 bytes) */ Stream_Write_UINT8(irp->output, 0); /* Information (1 byte) */ } @@ -216,17 +207,17 @@ static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) if (!CloseHandle(serial->hComm)) { - WLog_Print(serial->log, WLOG_WARN, "CloseHandle failure: %s (%d) closed.", serial->device.name, irp->device->id); + WLog_Print(serial->log, WLOG_WARN, "CloseHandle failure: %s (%d) closed.", + serial->device.name, irp->device->id); irp->IoStatus = STATUS_UNSUCCESSFUL; goto error_handle; } - WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %d, FileId: %d) closed.", serial->device.name, irp->device->id, irp->FileId); - + WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %d, FileId: %d) closed.", + serial->device.name, irp->device->id, irp->FileId); serial->hComm = NULL; irp->IoStatus = STATUS_SUCCESS; - - error_handle: +error_handle: Stream_Zero(irp->output, 5); /* Padding (5 bytes) */ } @@ -241,26 +232,22 @@ static UINT serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp) UINT64 Offset; BYTE* buffer = NULL; DWORD nbRead = 0; - Stream_Read_UINT32(irp->input, Length); /* Length (4 bytes) */ Stream_Read_UINT64(irp->input, Offset); /* Offset (8 bytes) */ Stream_Seek(irp->input, 20); /* Padding (20 bytes) */ - - buffer = (BYTE*)calloc(Length, sizeof(BYTE)); + if (buffer == NULL) { irp->IoStatus = STATUS_NO_MEMORY; goto error_handle; } - /* MS-RDPESP 3.2.5.1.4: If the Offset field is not set to 0, the value MUST be ignored * assert(Offset == 0); */ - - - WLog_Print(serial->log, WLOG_DEBUG, "reading %d bytes from %s", Length, serial->device.name); + WLog_Print(serial->log, WLOG_DEBUG, "reading %d bytes from %s", Length, + serial->device.name); /* FIXME: CommReadFile to be replaced by ReadFile */ if (CommReadFile(serial->hComm, buffer, Length, &nbRead, NULL)) @@ -269,15 +256,15 @@ static UINT serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp) } else { - WLog_Print(serial->log, WLOG_DEBUG, "read failure to %s, nbRead=%ld, last-error: 0x%lX", serial->device.name, nbRead, GetLastError()); - + WLog_Print(serial->log, WLOG_DEBUG, + "read failure to %s, nbRead=%ld, last-error: 0x%lX", serial->device.name, + nbRead, GetLastError()); irp->IoStatus = _GetLastErrorToIoStatus(serial); } - WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes read from %s", nbRead, serial->device.name); - - error_handle: - + WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes read from %s", nbRead, + serial->device.name); +error_handle: Stream_Write_UINT32(irp->output, nbRead); /* Length (4 bytes) */ if (nbRead > 0) @@ -288,6 +275,7 @@ static UINT serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp) free(buffer); return CHANNEL_RC_NO_MEMORY; } + Stream_Write(irp->output, buffer, nbRead); /* ReadData */ } @@ -300,34 +288,34 @@ static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp) UINT32 Length; UINT64 Offset; DWORD nbWritten = 0; - Stream_Read_UINT32(irp->input, Length); /* Length (4 bytes) */ Stream_Read_UINT64(irp->input, Offset); /* Offset (8 bytes) */ Stream_Seek(irp->input, 20); /* Padding (20 bytes) */ - /* MS-RDPESP 3.2.5.1.5: The Offset field is ignored * assert(Offset == 0); * * Using a serial printer, noticed though this field could be * set. */ - - WLog_Print(serial->log, WLOG_DEBUG, "writing %d bytes to %s", Length, serial->device.name); + WLog_Print(serial->log, WLOG_DEBUG, "writing %d bytes to %s", Length, + serial->device.name); /* FIXME: CommWriteFile to be replaced by WriteFile */ - if (CommWriteFile(serial->hComm, Stream_Pointer(irp->input), Length, &nbWritten, NULL)) + if (CommWriteFile(serial->hComm, Stream_Pointer(irp->input), Length, &nbWritten, + NULL)) { irp->IoStatus = STATUS_SUCCESS; } else { - WLog_Print(serial->log, WLOG_DEBUG, "write failure to %s, nbWritten=%ld, last-error: 0x%lX", serial->device.name, nbWritten, GetLastError()); - + WLog_Print(serial->log, WLOG_DEBUG, + "write failure to %s, nbWritten=%ld, last-error: 0x%lX", serial->device.name, + nbWritten, GetLastError()); irp->IoStatus = _GetLastErrorToIoStatus(serial); } - WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes written to %s", nbWritten, serial->device.name); - + WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes written to %s", (unsigned long) nbWritten, + serial->device.name); Stream_Write_UINT32(irp->output, nbWritten); /* Length (4 bytes) */ Stream_Write_UINT8(irp->output, 0); /* Padding (1 byte) */ } @@ -346,13 +334,14 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) UINT32 OutputBufferLength; BYTE* OutputBuffer = NULL; DWORD BytesReturned = 0; - - Stream_Read_UINT32(irp->input, OutputBufferLength); /* OutputBufferLength (4 bytes) */ - Stream_Read_UINT32(irp->input, InputBufferLength); /* InputBufferLength (4 bytes) */ + Stream_Read_UINT32(irp->input, + OutputBufferLength); /* OutputBufferLength (4 bytes) */ + Stream_Read_UINT32(irp->input, + InputBufferLength); /* InputBufferLength (4 bytes) */ Stream_Read_UINT32(irp->input, IoControlCode); /* IoControlCode (4 bytes) */ Stream_Seek(irp->input, 20); /* Padding (20 bytes) */ - OutputBuffer = (BYTE*)calloc(OutputBufferLength, sizeof(BYTE)); + if (OutputBuffer == NULL) { irp->IoStatus = STATUS_NO_MEMORY; @@ -360,6 +349,7 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) } InputBuffer = (BYTE*)calloc(InputBufferLength, sizeof(BYTE)); + if (InputBuffer == NULL) { irp->IoStatus = STATUS_NO_MEMORY; @@ -367,32 +357,32 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) } Stream_Read(irp->input, InputBuffer, InputBufferLength); - - WLog_Print(serial->log, WLOG_DEBUG, "CommDeviceIoControl: CompletionId=%d, IoControlCode=[0x%X] %s", irp->CompletionId, IoControlCode, _comm_serial_ioctl_name(IoControlCode)); + WLog_Print(serial->log, WLOG_DEBUG, + "CommDeviceIoControl: CompletionId=%d, IoControlCode=[0x%X] %s", + irp->CompletionId, IoControlCode, _comm_serial_ioctl_name(IoControlCode)); /* FIXME: CommDeviceIoControl to be replaced by DeviceIoControl() */ - if (CommDeviceIoControl(serial->hComm, IoControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, &BytesReturned, NULL)) + if (CommDeviceIoControl(serial->hComm, IoControlCode, InputBuffer, + InputBufferLength, OutputBuffer, OutputBufferLength, &BytesReturned, NULL)) { /* WLog_Print(serial->log, WLOG_DEBUG, "CommDeviceIoControl: CompletionId=%d, IoControlCode=[0x%X] %s done", irp->CompletionId, IoControlCode, _comm_serial_ioctl_name(IoControlCode)); */ - irp->IoStatus = STATUS_SUCCESS; } else { - WLog_Print(serial->log, WLOG_DEBUG, "CommDeviceIoControl failure: IoControlCode=[0x%X] %s, last-error: 0x%lX", - IoControlCode, _comm_serial_ioctl_name(IoControlCode), GetLastError()); - + WLog_Print(serial->log, WLOG_DEBUG, + "CommDeviceIoControl failure: IoControlCode=[0x%X] %s, last-error: 0x%lX", + IoControlCode, _comm_serial_ioctl_name(IoControlCode), GetLastError()); irp->IoStatus = _GetLastErrorToIoStatus(serial); } - error_handle: - +error_handle: /* FIXME: find out whether it's required or not to get * BytesReturned == OutputBufferLength when * CommDeviceIoControl returns FALSE */ assert(OutputBufferLength == BytesReturned); - - Stream_Write_UINT32(irp->output, BytesReturned); /* OutputBufferLength (4 bytes) */ + Stream_Write_UINT32(irp->output, + BytesReturned); /* OutputBufferLength (4 bytes) */ if (BytesReturned > 0) { @@ -406,6 +396,7 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) Stream_Write(irp->output, OutputBuffer, BytesReturned); /* OutputBuffer */ } + /* FIXME: Why at least Windows 2008R2 gets lost with this * extra byte and likely on a IOCTL_SERIAL_SET_BAUD_RATE? The * extra byte is well required according MS-RDPEFS @@ -414,7 +405,6 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) /* { */ /* Stream_Write_UINT8(irp->output, 0); /\* Padding (1 byte) *\/ */ /* } */ - free(InputBuffer); free(OutputBuffer); return CHANNEL_RC_OK; @@ -428,8 +418,9 @@ static UINT serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) static UINT serial_process_irp(SERIAL_DEVICE* serial, IRP* irp) { UINT error = CHANNEL_RC_OK; - WLog_Print(serial->log, WLOG_DEBUG, "IRP MajorFunction: 0x%04X MinorFunction: 0x%04X\n", - irp->MajorFunction, irp->MinorFunction); + WLog_Print(serial->log, WLOG_DEBUG, + "IRP MajorFunction: 0x%04X MinorFunction: 0x%04X\n", + irp->MajorFunction, irp->MinorFunction); switch (irp->MajorFunction) { @@ -443,7 +434,8 @@ static UINT serial_process_irp(SERIAL_DEVICE* serial, IRP* irp) case IRP_MJ_READ: if ((error = serial_process_irp_read(serial, irp))) - WLog_ERR(TAG, "serial_process_irp_read failed with error %lu!", error); + WLog_ERR(TAG, "serial_process_irp_read failed with error %u!", error); + break; case IRP_MJ_WRITE: @@ -452,58 +444,57 @@ static UINT serial_process_irp(SERIAL_DEVICE* serial, IRP* irp) case IRP_MJ_DEVICE_CONTROL: if ((error = serial_process_irp_device_control(serial, irp))) - WLog_ERR(TAG, "serial_process_irp_device_control failed with error %lu!", error); + WLog_ERR(TAG, "serial_process_irp_device_control failed with error %u!", + error); + break; default: irp->IoStatus = STATUS_NOT_SUPPORTED; break; } + return error; } static void* irp_thread_func(void* arg) { - IRP_THREAD_DATA *data = (IRP_THREAD_DATA*)arg; + IRP_THREAD_DATA* data = (IRP_THREAD_DATA*)arg; UINT error; /* blocks until the end of the request */ if ((error = serial_process_irp(data->serial, data->irp))) { - WLog_ERR(TAG, "serial_process_irp failed with error %lu", error); + WLog_ERR(TAG, "serial_process_irp failed with error %u", error); goto error_out; } EnterCriticalSection(&data->serial->TerminatingIrpThreadsLock); data->serial->IrpThreadToBeTerminatedCount++; - error = data->irp->Complete(data->irp); - LeaveCriticalSection(&data->serial->TerminatingIrpThreadsLock); - error_out: + if (error && data->serial->rdpcontext) - setChannelError(data->serial->rdpcontext, error, "irp_thread_func reported an error"); + setChannelError(data->serial->rdpcontext, error, + "irp_thread_func reported an error"); /* NB: At this point, the server might already being reusing * the CompletionId whereas the thread is not yet * terminated */ - free(data); - ExitThread((DWORD)error); return NULL; } -static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp) +static void create_irp_thread(SERIAL_DEVICE* serial, IRP* irp) { - IRP_THREAD_DATA *data = NULL; + IRP_THREAD_DATA* data = NULL; HANDLE irpThread; HANDLE previousIrpThread; uintptr_t key; - /* for a test/debug purpose, uncomment the code below to get a * single thread for all IRPs. NB: two IRPs could not be * processed at the same time, typically two concurent @@ -511,65 +502,57 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp) /* serial_process_irp(serial, irp); */ /* irp->Complete(irp); */ /* return; */ - - /* NOTE: for good or bad, this implementation relies on the * server to avoid a flooding of requests. see also _purge(). */ - EnterCriticalSection(&serial->TerminatingIrpThreadsLock); + while (serial->IrpThreadToBeTerminatedCount > 0) { /* Cleaning up termitating and pending irp * threads. See also: irp_thread_func() */ - HANDLE irpThread; - ULONG_PTR *ids; + ULONG_PTR* ids; int i, nbIds; - nbIds = ListDictionary_GetKeys(serial->IrpThreads, &ids); - for (i=0; iIrpThreads, (void*)id); - /* FIXME: not quite sure a zero timeout is a good thing to check whether a thread is stil alived or not */ waitResult = WaitForSingleObject(irpThread, 0); if (waitResult == WAIT_OBJECT_0) { /* terminating thread */ - /* WLog_Print(serial->log, WLOG_DEBUG, "IRP thread with CompletionId=%d naturally died", id); */ - CloseHandle(irpThread); ListDictionary_Remove(serial->IrpThreads, (void*)id); - serial->IrpThreadToBeTerminatedCount--; } else if (waitResult != WAIT_TIMEOUT) - { + { /* unexpected thread state */ - - WLog_Print(serial->log, WLOG_WARN, "WaitForSingleObject, got an unexpected result=0x%lX\n", waitResult); + WLog_Print(serial->log, WLOG_WARN, + "WaitForSingleObject, got an unexpected result=0x%lX\n", waitResult); assert(FALSE); } + /* pending thread (but not yet terminating thread) if waitResult == WAIT_TIMEOUT */ } - if (serial->IrpThreadToBeTerminatedCount > 0) { - WLog_Print(serial->log, WLOG_DEBUG, "%d IRP thread(s) not yet terminated", serial->IrpThreadToBeTerminatedCount); + WLog_Print(serial->log, WLOG_DEBUG, "%d IRP thread(s) not yet terminated", + serial->IrpThreadToBeTerminatedCount); Sleep(1); /* 1 ms */ } } - LeaveCriticalSection(&serial->TerminatingIrpThreadsLock); + LeaveCriticalSection(&serial->TerminatingIrpThreadsLock); /* NB: At this point and thanks to the synchronization we're * sure that the incoming IRP uses well a recycled * CompletionId or the server sent again an IRP already posted @@ -580,22 +563,20 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp) * FIXME: behavior documented somewhere? behavior not yet * observed with FreeRDP). */ - key = irp->CompletionId; previousIrpThread = ListDictionary_GetItemValue(serial->IrpThreads, (void*)key); + if (previousIrpThread) { /* Thread still alived <=> Request still pending */ - - WLog_Print(serial->log, WLOG_DEBUG, "IRP recall: IRP with the CompletionId=%d not yet completed!", irp->CompletionId); - + WLog_Print(serial->log, WLOG_DEBUG, + "IRP recall: IRP with the CompletionId=%d not yet completed!", + irp->CompletionId); assert(FALSE); /* unimplemented */ - /* TODO: asserts that previousIrpThread handles well * the same request by checking more details. Need an * access to the IRP object used by previousIrpThread */ - /* TODO: taking over the pending IRP or sending a kind * of wake up signal to accelerate the pending * request @@ -605,18 +586,16 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp) * pComm->PendingEvents |= SERIAL_EV_FREERDP_*; * } */ - irp->Discard(irp); return; } - if (ListDictionary_Count(serial->IrpThreads) >= MAX_IRP_THREADS) { - WLog_Print(serial->log, WLOG_WARN, "Number of IRP threads threshold reached: %d, keep on anyway", ListDictionary_Count(serial->IrpThreads)); - + WLog_Print(serial->log, WLOG_WARN, + "Number of IRP threads threshold reached: %d, keep on anyway", + ListDictionary_Count(serial->IrpThreads)); assert(FALSE); /* unimplemented */ - /* TODO: MAX_IRP_THREADS has been thought to avoid a * flooding of pending requests. Use * WaitForMultipleObjects() when available in winpr @@ -624,10 +603,9 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp) */ } - /* error_handle to be used ... */ - data = (IRP_THREAD_DATA*)calloc(1, sizeof(IRP_THREAD_DATA)); + if (data == NULL) { WLog_Print(serial->log, WLOG_WARN, "Could not allocate a new IRP_THREAD_DATA."); @@ -636,15 +614,13 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp) data->serial = serial; data->irp = irp; - /* data freed by irp_thread_func */ - irpThread = CreateThread(NULL, - 0, - (LPTHREAD_START_ROUTINE)irp_thread_func, - (void*)data, - 0, - NULL); + 0, + (LPTHREAD_START_ROUTINE)irp_thread_func, + (void*)data, + 0, + NULL); if (irpThread == INVALID_HANDLE_VALUE) { @@ -652,8 +628,8 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp) goto error_handle; } - key = irp->CompletionId; + if (!ListDictionary_Add(serial->IrpThreads, (void*)key, irpThread)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); @@ -661,43 +637,36 @@ static void create_irp_thread(SERIAL_DEVICE *serial, IRP *irp) } return; - - error_handle: - +error_handle: irp->IoStatus = STATUS_NO_MEMORY; irp->Complete(irp); - free(data); } -static void terminate_pending_irp_threads(SERIAL_DEVICE *serial) +static void terminate_pending_irp_threads(SERIAL_DEVICE* serial) { - ULONG_PTR *ids; + ULONG_PTR* ids; int i, nbIds; - nbIds = ListDictionary_GetKeys(serial->IrpThreads, &ids); - WLog_Print(serial->log, WLOG_DEBUG, "Terminating %d IRP thread(s)", nbIds); - for (i=0; iIrpThreads, (void*)id); - TerminateThread(irpThread, 0); if (WaitForSingleObject(irpThread, INFINITE) == WAIT_FAILED) - { - WLog_ERR(TAG,"WaitForSingleObject failed!"); - continue; - } + { + WLog_ERR(TAG, "WaitForSingleObject failed!"); + continue; + } CloseHandle(irpThread); - - WLog_Print(serial->log, WLOG_DEBUG, "IRP thread terminated, CompletionId %d", id); + WLog_Print(serial->log, WLOG_DEBUG, "IRP thread terminated, CompletionId %d", + id); } ListDictionary_Clear(serial->IrpThreads); @@ -740,7 +709,8 @@ static void* serial_thread_func(void* arg) } if (error && serial->rdpcontext) - setChannelError(serial->rdpcontext, error, "serial_thread_func reported an error"); + setChannelError(serial->rdpcontext, error, + "serial_thread_func reported an error"); ExitThread((DWORD) error); return NULL; @@ -755,7 +725,6 @@ static void* serial_thread_func(void* arg) static UINT serial_irp_request(DEVICE* device, IRP* irp) { SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device; - assert(irp != NULL); if (irp == NULL) @@ -771,6 +740,7 @@ static UINT serial_irp_request(DEVICE* device, IRP* irp) WLog_ERR(TAG, "MessageQueue_Post failed!"); return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -782,18 +752,18 @@ static UINT serial_irp_request(DEVICE* device, IRP* irp) */ static UINT serial_free(DEVICE* device) { - UINT error; + UINT error; SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device; - WLog_Print(serial->log, WLOG_DEBUG, "freeing"); - MessageQueue_PostQuit(serial->MainIrpQueue, 0); + if (WaitForSingleObject(serial->MainThread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); + return error; + } + CloseHandle(serial->MainThread); if (serial->hComm) @@ -804,14 +774,13 @@ static UINT serial_free(DEVICE* device) MessageQueue_Free(serial->MainIrpQueue); ListDictionary_Free(serial->IrpThreads); DeleteCriticalSection(&serial->TerminatingIrpThreadsLock); - free(serial); - return CHANNEL_RC_OK; + return CHANNEL_RC_OK; } #endif /* __linux__ */ -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DeviceServiceEntry serial_DeviceServiceEntry #else #define DeviceServiceEntry FREERDP_API DeviceServiceEntry @@ -833,7 +802,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) SERIAL_DEVICE* serial; #endif /* __linux__ */ UINT error = CHANNEL_RC_OK; - device = (RDPDR_SERIAL*) pEntryPoints->device; name = device->Name; path = device->Path; @@ -848,18 +816,14 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) if ((name && name[0]) && (path && path[0])) { wLog* log; - WLog_Init(); log = WLog_Get("com.freerdp.channel.serial.client"); WLog_Print(log, WLOG_DEBUG, "initializing"); - #ifndef __linux__ /* to be removed */ - - WLog_Print(log, WLOG_WARN, "Serial ports redirection not supported on this platform."); + WLog_Print(log, WLOG_WARN, + "Serial ports redirection not supported on this platform."); return CHANNEL_RC_INITIALIZATION_ERROR; - #else /* __linux __ */ - WLog_Print(log, WLOG_DEBUG, "Defining %s as %s", name, path); if (!DefineCommDevice(name /* eg: COM1 */, path /* eg: /dev/ttyS0 */)) @@ -869,6 +833,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } serial = (SERIAL_DEVICE*) calloc(1, sizeof(SERIAL_DEVICE)); + if (!serial) { WLog_ERR(TAG, "calloc failed!"); @@ -876,15 +841,14 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } serial->log = log; - serial->device.type = RDPDR_DTYP_SERIAL; serial->device.name = name; serial->device.IRPRequest = serial_irp_request; serial->device.Free = serial_free; serial->rdpcontext = pEntryPoints->rdpcontext; - len = strlen(name); serial->device.data = Stream_New(NULL, len + 1); + if (!serial->device.data) { WLog_ERR(TAG, "calloc failed!"); @@ -906,8 +870,8 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) else { assert(FALSE); - - WLog_Print(serial->log, WLOG_DEBUG, "Unknown server's serial driver: %s. SerCx2 will be used", driver); + WLog_Print(serial->log, WLOG_DEBUG, + "Unknown server's serial driver: %s. SerCx2 will be used", driver); serial->ServerSerialDriverId = SerialDriverSerialSys; } } @@ -917,7 +881,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) serial->ServerSerialDriverId = SerialDriverSerialSys; } - if (device->Permissive != NULL) { if (_stricmp(device->Permissive, "permissive") == 0) @@ -931,11 +894,11 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } } - - WLog_Print(serial->log, WLOG_DEBUG, "Server's serial driver: %s (id: %d)", driver, serial->ServerSerialDriverId); + WLog_Print(serial->log, WLOG_DEBUG, "Server's serial driver: %s (id: %d)", + driver, serial->ServerSerialDriverId); /* TODO: implement auto detection of the server's serial driver */ - serial->MainIrpQueue = MessageQueue_New(NULL); + if (!serial->MainIrpQueue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -945,32 +908,36 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) /* IrpThreads content only modified by create_irp_thread() */ serial->IrpThreads = ListDictionary_New(FALSE); - if(!serial->IrpThreads) + + if (!serial->IrpThreads) { WLog_ERR(TAG, "ListDictionary_New failed!"); error = CHANNEL_RC_NO_MEMORY; goto error_out; } + serial->IrpThreadToBeTerminatedCount = 0; InitializeCriticalSection(&serial->TerminatingIrpThreadsLock); - if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) serial))) + if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, + (DEVICE*) serial))) { - WLog_ERR(TAG, "EntryPoints->RegisterDevice failed with error %lu!", error); + WLog_ERR(TAG, "EntryPoints->RegisterDevice failed with error %u!", error); goto error_out; } if (!(serial->MainThread = CreateThread(NULL, - 0, - (LPTHREAD_START_ROUTINE) serial_thread_func, - (void*) serial, - 0, - NULL))) + 0, + (LPTHREAD_START_ROUTINE) serial_thread_func, + (void*) serial, + 0, + NULL))) { WLog_ERR(TAG, "CreateThread failed!"); error = ERROR_INTERNAL_ERROR; goto error_out; } + #endif /* __linux __ */ } diff --git a/channels/server/channels.c b/channels/server/channels.c index 84ccf6e..9f99ebb 100644 --- a/channels/server/channels.c +++ b/channels/server/channels.c @@ -49,6 +49,7 @@ #include #include #include +#include void freerdp_channels_dummy() { @@ -79,6 +80,8 @@ void freerdp_channels_dummy() encomsp_server_context_new(NULL); encomsp_server_context_free(NULL); + rdpgfx_server_context_new(NULL); + rdpgfx_server_context_free(NULL); } /** diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index e8aa3c5..0fcdd43 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -7,6 +7,7 @@ * Copyright 2011 Anthony Tong * Copyright 2015 Thincast Technologies GmbH * Copyright 2015 DI (FH) Martin Haimberger + * Copyright 2016 David PHAM-VAN * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +44,6 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext) SMARTCARD_DEVICE* smartcard; SMARTCARD_OPERATION* operation; UINT error = CHANNEL_RC_OK; - smartcard = pContext->smartcard; nCount = 0; @@ -56,7 +56,7 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext) if (waitStatus == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error); break; } @@ -65,7 +65,7 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext) if (waitStatus == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); break; } @@ -78,7 +78,6 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext) break; } - if (message.id == WMQ_QUIT) break; @@ -88,7 +87,8 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext) { if ((status = smartcard_irp_device_control_call(smartcard, operation))) { - WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %u", + status); break; } @@ -97,7 +97,6 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext) WLog_ERR(TAG, "Queue_Enqueue failed!"); status = ERROR_INTERNAL_ERROR; break; - } free(operation); @@ -106,17 +105,19 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext) } if (status && smartcard->rdpcontext) - setChannelError(smartcard->rdpcontext, error, "smartcard_context_thread reported an error"); + setChannelError(smartcard->rdpcontext, error, + "smartcard_context_thread reported an error"); ExitThread((DWORD)status); return NULL; } -SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext) +SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, + SCARDCONTEXT hContext) { SMARTCARD_CONTEXT* pContext; - pContext = (SMARTCARD_CONTEXT*) calloc(1, sizeof(SMARTCARD_CONTEXT)); + if (!pContext) { WLog_ERR(TAG, "calloc failed!"); @@ -125,8 +126,8 @@ SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTE pContext->smartcard = smartcard; pContext->hContext = hContext; - pContext->IrpQueue = MessageQueue_New(NULL); + if (!pContext->IrpQueue) { WLog_ERR(TAG, "MessageQueue_New failed!"); @@ -134,8 +135,9 @@ SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTE } pContext->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) smartcard_context_thread, - pContext, 0, NULL); + (LPTHREAD_START_ROUTINE) smartcard_context_thread, + pContext, 0, NULL); + if (!pContext->thread) { WLog_ERR(TAG, "CreateThread failed!"); @@ -143,7 +145,6 @@ SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTE } return pContext; - error_thread: MessageQueue_Free(pContext->IrpQueue); error_irpqueue: @@ -158,18 +159,19 @@ void smartcard_context_free(SMARTCARD_CONTEXT* pContext) /* cancel blocking calls like SCardGetStatusChange */ SCardCancel(pContext->hContext); - if (MessageQueue_PostQuit(pContext->IrpQueue, 0) && (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED)) - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); + + if (MessageQueue_PostQuit(pContext->IrpQueue, 0) + && (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED)) + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) GetLastError()); CloseHandle(pContext->thread); - MessageQueue_Free(pContext->IrpQueue); - free(pContext); } -static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) { +static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) +{ int index; int keyCount; ULONG_PTR* pKeys; @@ -193,7 +195,8 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) { for (index = 0; index < keyCount; index++) { - pContext = (SMARTCARD_CONTEXT*) ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) pKeys[index]); + pContext = (SMARTCARD_CONTEXT*) ListDictionary_GetItemValue( + smartcard->rgSCardContextList, (void*) pKeys[index]); if (!pContext) continue; @@ -220,7 +223,8 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) { for (index = 0; index < keyCount; index++) { - pContext = (SMARTCARD_CONTEXT*) ListDictionary_Remove(smartcard->rgSCardContextList, (void*) pKeys[index]); + pContext = (SMARTCARD_CONTEXT*) ListDictionary_Remove( + smartcard->rgSCardContextList, (void*) pKeys[index]); if (!pContext) continue; @@ -230,6 +234,14 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) { if (SCardIsValidContext(hContext) == SCARD_S_SUCCESS) { SCardReleaseContext(hContext); + + if (MessageQueue_PostQuit(pContext->IrpQueue, 0) + && (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED)) + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) GetLastError()); + + CloseHandle(pContext->thread); + MessageQueue_Free(pContext->IrpQueue); + free(pContext); } } @@ -247,28 +259,26 @@ static UINT smartcard_free(DEVICE* device) { UINT error; SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; - /** * Calling smartcard_release_all_contexts to unblock all operations waiting for transactions * to unlock. */ - smartcard_release_all_contexts(smartcard); /* Stopping all threads and cancelling all IRPs */ if (smartcard->IrpQueue) { - if (MessageQueue_PostQuit(smartcard->IrpQueue, 0) && (WaitForSingleObject(smartcard->thread, INFINITE) == WAIT_FAILED)) + if (MessageQueue_PostQuit(smartcard->IrpQueue, 0) + && (WaitForSingleObject(smartcard->thread, INFINITE) == WAIT_FAILED)) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); return error; } MessageQueue_Free(smartcard->IrpQueue); smartcard->IrpQueue = NULL; - CloseHandle(smartcard->thread); smartcard->thread = NULL; } @@ -290,7 +300,6 @@ static UINT smartcard_free(DEVICE* device) } free(device); - return CHANNEL_RC_OK; } @@ -307,9 +316,7 @@ static UINT smartcard_free(DEVICE* device) static UINT smartcard_init(DEVICE* device) { SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; - smartcard_release_all_contexts(smartcard); - return CHANNEL_RC_OK; } @@ -321,10 +328,8 @@ static UINT smartcard_init(DEVICE* device) UINT smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) { void* key; - - key = (void*) (size_t) irp->CompletionId; + key = (void*)(size_t) irp->CompletionId; ListDictionary_Remove(smartcard->rgOutstandingMessages, key); - return irp->Complete(irp); } @@ -345,8 +350,8 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) BOOL asyncIrp = FALSE; SMARTCARD_CONTEXT* pContext = NULL; SMARTCARD_OPERATION* operation = NULL; + key = (void*)(size_t) irp->CompletionId; - key = (void*) (size_t) irp->CompletionId; if (!ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); @@ -364,7 +369,6 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) } operation->irp = irp; - status = smartcard_irp_device_control_decode(smartcard, operation); if (status != SCARD_S_SUCCESS) @@ -451,7 +455,8 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) break; } - pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) operation->hContext); + pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList, + (void*) operation->hContext); if (!pContext) asyncIrp = FALSE; @@ -460,14 +465,17 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) { if ((status = smartcard_irp_device_control_call(smartcard, operation))) { - WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %lu!", status); + WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %ld!", + status); return (UINT32)status; } + if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp)) { WLog_ERR(TAG, "Queue_Enqueue failed!"); return ERROR_INTERNAL_ERROR; } + free(operation); } else @@ -484,8 +492,9 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) } else { - WLog_ERR(TAG, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X", - irp->MajorFunction, irp->MinorFunction); + WLog_ERR(TAG, + "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X", + irp->MajorFunction, irp->MinorFunction); irp->IoStatus = (UINT32)STATUS_NOT_SUPPORTED; if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp)) @@ -494,6 +503,7 @@ UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) return ERROR_INTERNAL_ERROR; } } + return CHANNEL_RC_OK; } @@ -518,7 +528,7 @@ static void* smartcard_thread_func(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error); break; } @@ -527,7 +537,7 @@ static void* smartcard_thread_func(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); break; } @@ -540,7 +550,6 @@ static void* smartcard_thread_func(void* arg) break; } - if (message.id == WMQ_QUIT) { while (1) @@ -550,7 +559,7 @@ static void* smartcard_thread_func(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); goto out; } @@ -568,7 +577,7 @@ static void* smartcard_thread_func(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); goto out; } @@ -578,7 +587,7 @@ static void* smartcard_thread_func(void* arg) if ((error = smartcard_complete_irp(smartcard, irp))) { - WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error); + WLog_ERR(TAG, "smartcard_complete_irp failed with error %u!", error); goto out; } } @@ -593,7 +602,7 @@ static void* smartcard_thread_func(void* arg) { if ((error = smartcard_process_irp(smartcard, irp))) { - WLog_ERR(TAG, "smartcard_process_irp failed with error %lu!", error); + WLog_ERR(TAG, "smartcard_process_irp failed with error %u!", error); goto out; } } @@ -604,13 +613,12 @@ static void* smartcard_thread_func(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); break; } if (status == WAIT_OBJECT_0) { - irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue); if (irp) @@ -622,7 +630,7 @@ static void* smartcard_thread_func(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); break; } @@ -632,15 +640,24 @@ static void* smartcard_thread_func(void* arg) if ((error = smartcard_complete_irp(smartcard, irp))) { - WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error); + if (error == CHANNEL_RC_NOT_CONNECTED) + { + error = CHANNEL_RC_OK; + goto out; + } + + WLog_ERR(TAG, "smartcard_complete_irp failed with error %u!", error); goto out; } } } } + out: + if (error && smartcard->rdpcontext) - setChannelError(smartcard->rdpcontext, error, "smartcard_thread_func reported an error"); + setChannelError(smartcard->rdpcontext, error, + "smartcard_thread_func reported an error"); ExitThread((DWORD)error); return NULL; @@ -654,11 +671,13 @@ out: static UINT smartcard_irp_request(DEVICE* device, IRP* irp) { SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device; + if (!MessageQueue_Post(smartcard->IrpQueue, NULL, 0, (void*) irp, NULL)) { WLog_ERR(TAG, "MessageQueue_Post failed!"); return ERROR_INTERNAL_ERROR; } + return CHANNEL_RC_OK; } @@ -679,13 +698,11 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) RDPDR_SMARTCARD* device; SMARTCARD_DEVICE* smartcard; UINT error = CHANNEL_RC_NO_MEMORY; - device = (RDPDR_SMARTCARD*) pEntryPoints->device; - name = device->Name; path = device->Path; - smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE)); + if (!smartcard) { WLog_ERR(TAG, "calloc failed!"); @@ -698,9 +715,9 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) smartcard->device.Init = smartcard_init; smartcard->device.Free = smartcard_free; smartcard->rdpcontext = pEntryPoints->rdpcontext; - length = strlen(smartcard->device.name); smartcard->device.data = Stream_New(NULL, length + 1); + if (!smartcard->device.data) { WLog_ERR(TAG, "Stream_New failed!"); @@ -708,7 +725,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } Stream_Write(smartcard->device.data, "SCARD", 6); - smartcard->name = NULL; smartcard->path = NULL; @@ -726,14 +742,15 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } smartcard->IrpQueue = MessageQueue_New(NULL); + if (!smartcard->IrpQueue) { WLog_ERR(TAG, "MessageQueue_New failed!"); goto error_irp_queue; } - smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1); + if (!smartcard->CompletedIrpQueue) { WLog_ERR(TAG, "Queue_New failed!"); @@ -741,6 +758,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } smartcard->rgSCardContextList = ListDictionary_New(TRUE); + if (!smartcard->rgSCardContextList) { WLog_ERR(TAG, "ListDictionary_New failed!"); @@ -748,24 +766,26 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } ListDictionary_ValueObject(smartcard->rgSCardContextList)->fnObjectFree = - (OBJECT_FREE_FN) smartcard_context_free; - + (OBJECT_FREE_FN) smartcard_context_free; smartcard->rgOutstandingMessages = ListDictionary_New(TRUE); + if (!smartcard->rgOutstandingMessages) { WLog_ERR(TAG, "ListDictionary_New failed!"); goto error_outstanding_messages; } - if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) smartcard))) + if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, + (DEVICE*) smartcard))) { WLog_ERR(TAG, "RegisterDevice failed!"); goto error_outstanding_messages; } + smartcard->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) smartcard_thread_func, + smartcard, CREATE_SUSPENDED, NULL); - smartcard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func, - smartcard, CREATE_SUSPENDED, NULL); if (!smartcard->thread) { WLog_ERR(TAG, "ListDictionary_New failed!"); @@ -774,9 +794,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) } ResumeThread(smartcard->thread); - return CHANNEL_RC_OK; - error_thread: ListDictionary_Free(smartcard->rgOutstandingMessages); error_outstanding_messages: diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 3a37add..790314e 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -202,7 +202,7 @@ static LONG smartcard_EstablishContext_Decode(SMARTCARD_DEVICE* smartcard, SMART if ((status = smartcard_unpack_establish_context_call(smartcard, irp->input, call))) { - WLog_ERR(TAG, "smartcard_unpack_establish_context_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_establish_context_call failed with error %ld", status); return status; } smartcard_trace_establish_context_call(smartcard, call); @@ -236,7 +236,7 @@ static LONG smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCA } else { - WLog_ERR(TAG, "SCardEstablishContext failed with error %lu", status); + WLog_ERR(TAG, "SCardEstablishContext failed with error %ld", status); return status; } @@ -244,7 +244,7 @@ static LONG smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCA smartcard_trace_establish_context_return(smartcard, &ret); if ((status = smartcard_pack_establish_context_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_establish_context_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_establish_context_return failed with error %ld", status); return status; } @@ -260,7 +260,7 @@ static LONG smartcard_ReleaseContext_Decode(SMARTCARD_DEVICE* smartcard, SMARTCA return STATUS_NO_MEMORY; if ((status = smartcard_unpack_context_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %ld", status); smartcard_trace_context_call(smartcard, call, "ReleaseContext"); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; @@ -282,7 +282,7 @@ static LONG smartcard_ReleaseContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD } else { - WLog_ERR(TAG, "SCardReleaseContext failed with error %lu", status); + WLog_ERR(TAG, "SCardReleaseContext failed with error %ld", status); return status; } @@ -299,7 +299,7 @@ static LONG smartcard_IsValidContext_Decode(SMARTCARD_DEVICE* smartcard, SMARTCA return STATUS_NO_MEMORY; if ((status = smartcard_unpack_context_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %ld", status); smartcard_trace_context_call(smartcard, call, "IsValidContext"); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; @@ -311,7 +311,7 @@ static LONG smartcard_IsValidContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD Long_Return ret; if ((status = ret.ReturnCode = SCardIsValidContext(operation->hContext))) { - WLog_ERR(TAG, "SCardIsValidContext failed with error %lu", status); + WLog_ERR(TAG, "SCardIsValidContext failed with error %ld", status); return status; } smartcard_trace_long_return(smartcard, &ret, "IsValidContext"); @@ -327,7 +327,7 @@ static LONG smartcard_ListReadersA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD return STATUS_NO_MEMORY; if ((status = smartcard_unpack_list_readers_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_list_readers_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_list_readers_call failed with error %ld", status); smartcard_trace_list_readers_call(smartcard, call, FALSE); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; @@ -356,14 +356,14 @@ static LONG smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O if (status) { - WLog_ERR(TAG, "SCardListReadersA failed with error %lu", status); + WLog_ERR(TAG, "SCardListReadersA failed with error %ld", status); return status; } smartcard_trace_list_readers_return(smartcard, &ret, FALSE); if ((status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_list_readers_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_list_readers_return failed with error %ld", status); return status; } @@ -385,7 +385,7 @@ static LONG smartcard_ListReadersW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD return STATUS_NO_MEMORY; if ((status = smartcard_unpack_list_readers_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_list_readers_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_list_readers_call failed with error %ld", status); smartcard_trace_list_readers_call(smartcard, call, TRUE); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); @@ -417,7 +417,7 @@ static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O if (status) { - WLog_ERR(TAG, "SCardListReadersW failed with error %lu", status); + WLog_ERR(TAG, "SCardListReadersW failed with error %ld", status); return status; } @@ -425,7 +425,7 @@ static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_O if ((status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_list_readers_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_list_readers_return failed with error %ld", status); return status; } @@ -448,7 +448,7 @@ static LONG smartcard_GetStatusChangeA_Decode(SMARTCARD_DEVICE* smartcard, SMART if ((status = smartcard_unpack_get_status_change_a_call(smartcard, irp->input, call))) { - WLog_ERR(TAG, "smartcard_unpack_get_status_change_a_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_get_status_change_a_call failed with error %ld", status); return status; } @@ -492,7 +492,7 @@ static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, SMARTCA smartcard_trace_get_status_change_return(smartcard, &ret, FALSE); if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %ld", status); return status; } @@ -520,7 +520,7 @@ static LONG smartcard_GetStatusChangeW_Decode(SMARTCARD_DEVICE* smartcard, SMART return STATUS_NO_MEMORY; if ((status = smartcard_unpack_get_status_change_w_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_get_status_change_w_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_get_status_change_w_call failed with error %ld", status); smartcard_trace_get_status_change_w_call(smartcard, call); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; @@ -559,7 +559,7 @@ static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, SMARTCA smartcard_trace_get_status_change_return(smartcard, &ret, TRUE); if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %ld", status); return status; } @@ -587,7 +587,7 @@ static LONG smartcard_Cancel_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA return STATUS_NO_MEMORY; if ((status = smartcard_unpack_context_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %ld", status); smartcard_trace_context_call(smartcard, call, "Cancel"); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; @@ -600,7 +600,7 @@ static LONG smartcard_Cancel_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATI if ((status = ret.ReturnCode = SCardCancel(operation->hContext))) { - WLog_ERR(TAG, "SCardCancel failed with error %lu", status); + WLog_ERR(TAG, "SCardCancel failed with error %ld", status); return status; } smartcard_trace_long_return(smartcard, &ret, "Cancel"); @@ -616,7 +616,7 @@ static LONG smartcard_ConnectA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE return STATUS_NO_MEMORY; if ((status = smartcard_unpack_connect_a_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_connect_a_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_connect_a_call failed with error %ld", status); smartcard_trace_connect_a_call(smartcard, call); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->Common.hContext)); return status; @@ -644,14 +644,14 @@ static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA if (status) { - WLog_ERR(TAG, "SCardConnectA failed with error %lu", status); + WLog_ERR(TAG, "SCardConnectA failed with error %ld", status); return status; } if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %ld", status); return status; } @@ -669,7 +669,7 @@ static LONG smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE return STATUS_NO_MEMORY; if ((status = smartcard_unpack_connect_w_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_connect_w_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_connect_w_call failed with error %ld", status); smartcard_trace_connect_w_call(smartcard, call); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->Common.hContext)); @@ -699,13 +699,13 @@ static LONG smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA if (status) { - WLog_ERR(TAG, "SCardConnectW failed with error %lu", status); + WLog_ERR(TAG, "SCardConnectW failed with error %ld", status); return status; } if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %ld", status); return status; } @@ -723,7 +723,7 @@ static LONG smartcard_Reconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP return STATUS_NO_MEMORY; if ((status = smartcard_unpack_reconnect_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_reconnect_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_reconnect_call failed with error %ld", status); smartcard_trace_reconnect_call(smartcard, call); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard)); @@ -740,7 +740,7 @@ static LONG smartcard_Reconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER smartcard_trace_reconnect_return(smartcard, &ret); if ((status = smartcard_pack_reconnect_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_reconnect_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_reconnect_return failed with error %ld", status); return status; } @@ -756,7 +756,7 @@ static LONG smartcard_Disconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_O return STATUS_NO_MEMORY; if ((status = smartcard_unpack_hcard_and_disposition_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %ld", status); smartcard_trace_hcard_and_disposition_call(smartcard, call, "Disconnect"); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard)); @@ -769,7 +769,7 @@ static LONG smartcard_Disconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE Long_Return ret; if ((status = ret.ReturnCode = SCardDisconnect(operation->hCard, call->dwDisposition))) { - WLog_ERR(TAG, "SCardDisconnect failed with error %lu", status); + WLog_ERR(TAG, "SCardDisconnect failed with error %ld", status); return status; } smartcard_trace_long_return(smartcard, &ret, "Disconnect"); @@ -786,7 +786,7 @@ static LONG smartcard_BeginTransaction_Decode(SMARTCARD_DEVICE* smartcard, SMART return STATUS_NO_MEMORY; if ((status = smartcard_unpack_hcard_and_disposition_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %ld", status); smartcard_trace_hcard_and_disposition_call(smartcard, call, "BeginTransaction"); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard)); @@ -798,7 +798,7 @@ static LONG smartcard_BeginTransaction_Call(SMARTCARD_DEVICE* smartcard, SMARTCA Long_Return ret; if ((ret.ReturnCode = SCardBeginTransaction(operation->hCard))) { - WLog_ERR(TAG, "SCardBeginTransaction failed with error %lu", ret.ReturnCode); + WLog_ERR(TAG, "SCardBeginTransaction failed with error %ld", ret.ReturnCode); return ret.ReturnCode; } smartcard_trace_long_return(smartcard, &ret, "BeginTransaction"); @@ -814,7 +814,7 @@ static LONG smartcard_EndTransaction_Decode(SMARTCARD_DEVICE* smartcard, SMARTCA return STATUS_NO_MEMORY; if ((status = smartcard_unpack_hcard_and_disposition_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_hcard_and_disposition_call failed with error %ld", status); smartcard_trace_hcard_and_disposition_call(smartcard, call, "EndTransaction"); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard)); @@ -826,7 +826,7 @@ static LONG smartcard_EndTransaction_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD Long_Return ret; if ((ret.ReturnCode = SCardEndTransaction(operation->hCard, call->dwDisposition))) { - WLog_ERR(TAG, "SCardEndTransaction failed with error %lu", ret.ReturnCode); + WLog_ERR(TAG, "SCardEndTransaction failed with error %ld", ret.ReturnCode); return ret.ReturnCode; } smartcard_trace_long_return(smartcard, &ret, "EndTransaction"); @@ -842,7 +842,7 @@ static LONG smartcard_State_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT return STATUS_NO_MEMORY; if ((status = smartcard_unpack_state_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_state_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_state_call failed with error %ld", status); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard)); return status; @@ -857,7 +857,7 @@ static LONG smartcard_State_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATIO ret.ReturnCode = SCardState(operation->hCard, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.rgAtr, &ret.cbAtrLen); if ((status = smartcard_pack_state_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_state_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_state_return failed with error %ld", status); return status; } @@ -873,7 +873,7 @@ static LONG smartcard_StatusA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER return STATUS_NO_MEMORY; if ((status = smartcard_unpack_status_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %ld", status); smartcard_trace_status_call(smartcard, call, FALSE); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard)); @@ -904,7 +904,7 @@ static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT smartcard_trace_status_return(smartcard, &ret, FALSE); if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_status_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_status_return failed with error %ld", status); return status; } @@ -923,7 +923,7 @@ static LONG smartcard_StatusW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER return STATUS_NO_MEMORY; if ((status = smartcard_unpack_status_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %ld", status); smartcard_trace_status_call(smartcard, call, TRUE); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard)); @@ -950,7 +950,7 @@ static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT smartcard_trace_status_return(smartcard, &ret, TRUE); if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_status_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_status_return failed with error %ld", status); return status; } @@ -969,7 +969,7 @@ static LONG smartcard_Transmit_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPE return STATUS_NO_MEMORY; if ((status = smartcard_unpack_transmit_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_transmit_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_transmit_call failed with error %ld", status); smartcard_trace_transmit_call(smartcard, call); @@ -1007,7 +1007,7 @@ static LONG smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA smartcard_trace_transmit_return(smartcard, &ret); if ((status = smartcard_pack_transmit_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_transmit_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_transmit_return failed with error %ld", status); return status; } @@ -1028,7 +1028,7 @@ static LONG smartcard_Control_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER return STATUS_NO_MEMORY; if ((status = smartcard_unpack_control_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_control_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_control_call failed with error %ld", status); smartcard_trace_control_call(smartcard, call); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard)); @@ -1053,7 +1053,7 @@ static LONG smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT smartcard_trace_control_return(smartcard, &ret); if ((status = smartcard_pack_control_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_control_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_control_return failed with error %ld", status); return status; } @@ -1072,7 +1072,7 @@ static LONG smartcard_GetAttrib_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP return STATUS_NO_MEMORY; if ((status = smartcard_unpack_get_attrib_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_get_attrib_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_get_attrib_call failed with error %ld", status); smartcard_trace_get_attrib_call(smartcard, call); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); operation->hCard = smartcard_scard_handle_native_from_redir(smartcard, &(call->hCard)); @@ -1123,7 +1123,7 @@ static LONG smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER if ((status = smartcard_pack_get_attrib_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_get_attrib_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_get_attrib_return failed with error %ld", status); return status; } @@ -1169,7 +1169,7 @@ static LONG smartcard_LocateCardsByATRA_Decode(SMARTCARD_DEVICE* smartcard, SMAR return STATUS_NO_MEMORY; if ((status = smartcard_unpack_locate_cards_by_atr_a_call(smartcard, irp->input, call))) - WLog_ERR(TAG, "smartcard_unpack_locate_cards_by_atr_a_call failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_locate_cards_by_atr_a_call failed with error %ld", status); smartcard_trace_locate_cards_by_atr_a_call(smartcard, call); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; @@ -1249,7 +1249,7 @@ static LONG smartcard_LocateCardsByATRA_Call(SMARTCARD_DEVICE* smartcard, SMARTC smartcard_trace_get_status_change_return(smartcard, &ret, FALSE); if ((status = smartcard_pack_get_status_change_return(smartcard, irp->output, &ret))) { - WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_get_status_change_return failed with error %ld", status); return status; } @@ -1287,8 +1287,8 @@ LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_ if (Stream_GetRemainingLength(irp->input) < 32) { - WLog_WARN(TAG, "Device Control Request is too short: %d", - (int) Stream_GetRemainingLength(irp->input)); + WLog_WARN(TAG, "Device Control Request is too short: %lu", + (unsigned long) Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } @@ -1300,8 +1300,9 @@ LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_ if (Stream_Length(irp->input) != (Stream_GetPosition(irp->input) + inputBufferLength)) { - WLog_WARN(TAG, "InputBufferLength mismatch: Actual: %d Expected: %d", - Stream_Length(irp->input), Stream_GetPosition(irp->input) + inputBufferLength); + WLog_WARN(TAG, "InputBufferLength mismatch: Actual: %lu Expected: %lu", + (unsigned long) Stream_Length(irp->input), + (unsigned long) (Stream_GetPosition(irp->input) + inputBufferLength)); return SCARD_F_INTERNAL_ERROR; } @@ -1314,13 +1315,13 @@ LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_ { if ((status = smartcard_unpack_common_type_header(smartcard, irp->input))) { - WLog_ERR(TAG, "smartcard_unpack_common_type_header failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_common_type_header failed with error %ld", status); return SCARD_F_INTERNAL_ERROR; } if ((status = smartcard_unpack_private_type_header(smartcard, irp->input))) { - WLog_ERR(TAG, "smartcard_unpack_common_type_header failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_common_type_header failed with error %ld", status); return SCARD_F_INTERNAL_ERROR; } } @@ -1945,12 +1946,12 @@ LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP Stream_Write_UINT32(irp->output, outputBufferLength); /* OutputBufferLength (4 bytes) */ if ((result = smartcard_pack_common_type_header(smartcard, irp->output))) /* CommonTypeHeader (8 bytes) */ { - WLog_ERR(TAG, "smartcard_pack_common_type_header failed with error %lu", result); + WLog_ERR(TAG, "smartcard_pack_common_type_header failed with error %ld", result); return result; } if ((result = smartcard_pack_private_type_header(smartcard, irp->output, objectBufferLength))) /* PrivateTypeHeader (8 bytes) */ { - WLog_ERR(TAG, "smartcard_pack_private_type_header failed with error %lu", result); + WLog_ERR(TAG, "smartcard_pack_private_type_header failed with error %ld", result); return result; } diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index 766648b..7e968ea 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -109,8 +109,8 @@ LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* if (objectBufferLength != Stream_GetRemainingLength(s)) { - WLog_WARN(TAG, "PrivateTypeHeader ObjectBufferLength mismatch: Actual: %d, Expected: %d", - (int) objectBufferLength, Stream_GetRemainingLength(s)); + WLog_WARN(TAG, "PrivateTypeHeader ObjectBufferLength mismatch: Actual: %lu, Expected: %lu", + (unsigned long) objectBufferLength, (unsigned long)Stream_GetRemainingLength(s)); return STATUS_INVALID_PARAMETER; } @@ -166,8 +166,8 @@ SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartca if ((context->cbContext != sizeof(ULONG_PTR)) && (context->cbContext != 0)) { - WLog_WARN(TAG, "REDIR_SCARDCONTEXT does not match native size: Actual: %d, Expected: %d", - context->cbContext, sizeof(ULONG_PTR)); + WLog_WARN(TAG, "REDIR_SCARDCONTEXT does not match native size: Actual: %lu, Expected: %lu", + (unsigned long) context->cbContext, (unsigned long) sizeof(ULONG_PTR)); return 0; } @@ -192,8 +192,8 @@ SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard if (handle->cbHandle != sizeof(ULONG_PTR)) { - WLog_WARN(TAG, "REDIR_SCARDHANDLE does not match native size: Actual: %d, Expected: %d", - handle->cbHandle, sizeof(ULONG_PTR)); + WLog_WARN(TAG, "REDIR_SCARDHANDLE does not match native size: Actual: %lu, Expected: %lu", + (unsigned long) handle->cbHandle, (unsigned long) sizeof(ULONG_PTR)); return 0; } @@ -446,12 +446,12 @@ LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStrea if ((status = smartcard_pack_redir_scard_context(smartcard, s, &(ret->hContext)))) { - WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_pack_redir_scard_context_ref(smartcard, s, &(ret->hContext)))) - WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %ld", status); return status; } @@ -490,12 +490,12 @@ LONG smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } @@ -548,7 +548,7 @@ LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } @@ -566,7 +566,7 @@ LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } @@ -622,7 +622,7 @@ void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, ListReaders_ if (unicode) ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) call->mszGroups, call->cBytes / 2, &mszGroupsA, 0, NULL, NULL); - WLog_DBG(TAG, "ListReaders%S_Call {", unicode ? "W" : "A"); + WLog_DBG(TAG, "ListReaders%s_Call {", unicode ? "W" : "A"); pb = (BYTE*) &(call->hContext.pbContext); @@ -676,7 +676,7 @@ LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4))) { - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", error); + WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", error); return error; } } @@ -752,7 +752,7 @@ LONG smartcard_unpack_connect_common(SMARTCARD_DEVICE* smartcard, wStream* s, Co if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(common->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } @@ -780,7 +780,7 @@ LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common)))) { - WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %ld", status); return status; } @@ -803,7 +803,7 @@ LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co call->szReader[count] = '\0'; if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->Common.hContext)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } @@ -855,7 +855,7 @@ LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common)))) { - WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %ld", status); return status; } @@ -878,7 +878,7 @@ LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, Co call->szReader[count] = '\0'; if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->Common.hContext)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } @@ -923,13 +923,13 @@ LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Conn if ((status = smartcard_pack_redir_scard_context(smartcard, s, &(ret->hContext)))) { - WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_pack_redir_scard_handle(smartcard, s, &(ret->hCard)))) { - WLog_ERR(TAG, "smartcard_pack_redir_scard_handle failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_redir_scard_handle failed with error %ld", status); return status; } @@ -937,12 +937,12 @@ LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Conn if ((status = smartcard_pack_redir_scard_context_ref(smartcard, s, &(ret->hContext)))) { - WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_redir_scard_context_ref failed with error %ld", status); return status; } if ((status = smartcard_pack_redir_scard_handle_ref(smartcard, s, &(ret->hCard)))) - WLog_ERR(TAG, "smartcard_pack_redir_scard_handle_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_redir_scard_handle_ref failed with error %ld", status); return status; } @@ -997,13 +997,13 @@ LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Re if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status); return status; } @@ -1021,12 +1021,12 @@ LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Re if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status); return status; } @@ -1103,13 +1103,13 @@ LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wS if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status); return status; } @@ -1124,12 +1124,12 @@ LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wS if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status); return status; } @@ -1190,7 +1190,7 @@ LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStr if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } @@ -1207,7 +1207,7 @@ LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStr if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } @@ -1368,7 +1368,7 @@ LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStr if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } @@ -1385,7 +1385,7 @@ LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStr if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } @@ -1601,13 +1601,13 @@ LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_ if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status); return status; } @@ -1623,12 +1623,12 @@ LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_ if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status); return status; } @@ -1645,7 +1645,7 @@ LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, State_ Stream_Write(s, ret->rgAtr, ret->cbAtrLen); /* rgAtr */ if ((status = smartcard_pack_write_size_align(smartcard, s, ret->cbAtrLen, 4))) - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", status); return status; } @@ -1656,13 +1656,13 @@ LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Statu if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status); return status; } @@ -1679,12 +1679,12 @@ LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Statu if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status); return status; } @@ -1754,7 +1754,7 @@ LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, Statu Stream_Zero(s, ret->cBytes); if ((status = smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4))) - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", status); return status; } @@ -1834,13 +1834,13 @@ LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, G if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status); return status; } @@ -1857,12 +1857,12 @@ LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, G if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status); return status; } @@ -1927,7 +1927,7 @@ LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, G Stream_Write(s, ret->pbAttr, ret->cbAttrLen); /* pbAttr */ if ((status = smartcard_pack_write_size_align(smartcard, s, ret->cbAttrLen, 4))) - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", status); + WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", status); return status; } @@ -1968,13 +1968,13 @@ LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status); return status; } @@ -1993,13 +1993,13 @@ LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Cont if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } @@ -2107,7 +2107,7 @@ LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, Cont Stream_Write(s, ret->pvOutBuffer, ret->cbOutBufferSize); /* pvOutBuffer */ if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cbOutBufferSize, 4))) { - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu", error); + WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld", error); return error; } } @@ -2158,13 +2158,13 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->hCard)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle failed with error %ld", status); return status; } @@ -2200,13 +2200,13 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->hCard)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %ld", status); return status; } @@ -2528,7 +2528,7 @@ LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Tra Stream_Write(s, pbExtraBytes, cbExtraBytes); if ((error = smartcard_pack_write_size_align(smartcard, s, cbExtraBytes, 4))) { - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu!", error); + WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld!", error); return error; } } @@ -2546,7 +2546,7 @@ LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Tra Stream_Write(s, ret->pbRecvBuffer, ret->cbRecvLength); if ((error = smartcard_pack_write_size_align(smartcard, s, ret->cbRecvLength, 4))) { - WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %lu!", error); + WLog_ERR(TAG, "smartcard_pack_write_size_align failed with error %ld!", error); return error; } } @@ -2619,7 +2619,7 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context failed with error %ld", status); return status; } @@ -2637,7 +2637,7 @@ LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wS if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)))) { - WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %lu", status); + WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %ld", status); return status; } diff --git a/channels/tsmf/client/CMakeLists.txt b/channels/tsmf/client/CMakeLists.txt index 6916bc5..ee172fc 100644 --- a/channels/tsmf/client/CMakeLists.txt +++ b/channels/tsmf/client/CMakeLists.txt @@ -42,7 +42,7 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE target_link_libraries(${MODULE_NAME} freerdp winpr) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/tsmf/client/alsa/tsmf_alsa.c b/channels/tsmf/client/alsa/tsmf_alsa.c index 078c7d8..a5bc727 100644 --- a/channels/tsmf/client/alsa/tsmf_alsa.c +++ b/channels/tsmf/client/alsa/tsmf_alsa.c @@ -231,7 +231,7 @@ static void tsmf_alsa_free(ITSMFAudioDevice *audio) free(alsa); } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_tsmf_client_audio_subsystem_entry alsa_freerdp_tsmf_client_audio_subsystem_entry #else #define freerdp_tsmf_client_audio_subsystem_entry FREERDP_API freerdp_tsmf_client_audio_subsystem_entry diff --git a/channels/tsmf/client/ffmpeg/CMakeLists.txt b/channels/tsmf/client/ffmpeg/CMakeLists.txt index e18e0b3..cda0bdf 100644 --- a/channels/tsmf/client/ffmpeg/CMakeLists.txt +++ b/channels/tsmf/client/ffmpeg/CMakeLists.txt @@ -39,7 +39,7 @@ else() target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) endif() -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c index 4e5beff..7156e8f 100644 --- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c +++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c @@ -541,7 +541,7 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder) static BOOL initialized = FALSE; -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_tsmf_client_subsystem_entry ffmpeg_freerdp_tsmf_client_decoder_subsystem_entry #else #define freerdp_tsmf_client_subsystem_entry FREERDP_API freerdp_tsmf_client_decoder_subsystem_entry diff --git a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c index 466dd7d..1211e8d 100644 --- a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c +++ b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c @@ -1010,7 +1010,7 @@ BOOL tsmf_gstreamer_sync(ITSMFDecoder* decoder, void (*cb)(void *), void *stream return TRUE; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_tsmf_client_subsystem_entry gstreamer_freerdp_tsmf_client_decoder_subsystem_entry #else #define freerdp_tsmf_client_subsystem_entry FREERDP_API freerdp_tsmf_client_decoder_subsystem_entry diff --git a/channels/tsmf/client/oss/tsmf_oss.c b/channels/tsmf/client/oss/tsmf_oss.c index da792be..784ea0c 100644 --- a/channels/tsmf/client/oss/tsmf_oss.c +++ b/channels/tsmf/client/oss/tsmf_oss.c @@ -236,7 +236,7 @@ static void tsmf_oss_free(ITSMFAudioDevice* audio) free(oss); } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_tsmf_client_audio_subsystem_entry oss_freerdp_tsmf_client_audio_subsystem_entry #else #define freerdp_tsmf_client_audio_subsystem_entry FREERDP_API freerdp_tsmf_client_audio_subsystem_entry diff --git a/channels/tsmf/client/pulse/tsmf_pulse.c b/channels/tsmf/client/pulse/tsmf_pulse.c index e9ea79b..5a5a0ef 100644 --- a/channels/tsmf/client/pulse/tsmf_pulse.c +++ b/channels/tsmf/client/pulse/tsmf_pulse.c @@ -358,7 +358,7 @@ static void tsmf_pulse_free(ITSMFAudioDevice *audio) free(pulse); } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS ITSMFAudioDevice *pulse_freerdp_tsmf_client_audio_subsystem_entry(void) #else FREERDP_API ITSMFAudioDevice *freerdp_tsmf_client_audio_subsystem_entry(void) diff --git a/channels/tsmf/client/tsmf_ifman.c b/channels/tsmf/client/tsmf_ifman.c index 4c9da74..c118e3f 100644 --- a/channels/tsmf/client/tsmf_ifman.c +++ b/channels/tsmf/client/tsmf_ifman.c @@ -580,7 +580,7 @@ UINT tsmf_ifman_on_sample(TSMF_IFMAN* ifman) UINT64 ThrottleDuration; UINT32 SampleExtensions; UINT32 cbData; - UINT error; + UINT error; if (Stream_GetRemainingLength(ifman->input) < 60) return ERROR_INVALID_DATA; @@ -628,7 +628,7 @@ UINT tsmf_ifman_on_sample(TSMF_IFMAN* ifman) if ((error = tsmf_presentation_sync(presentation))) { - WLog_ERR(TAG, "tsmf_presentation_sync failed with error %lu", error); + WLog_ERR(TAG, "tsmf_presentation_sync failed with error %u", error); return error; } ifman->output_pending = TRUE; diff --git a/channels/tsmf/client/tsmf_main.c b/channels/tsmf/client/tsmf_main.c index bc202ea..3a04afb 100644 --- a/channels/tsmf/client/tsmf_main.c +++ b/channels/tsmf/client/tsmf_main.c @@ -525,7 +525,7 @@ static UINT tsmf_process_addin_args(IWTSPlugin *pPlugin, ADDIN_ARGV *args) return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DVCPluginEntry tsmf_DVCPluginEntry #else #define DVCPluginEntry FREERDP_API DVCPluginEntry diff --git a/channels/tsmf/client/tsmf_media.c b/channels/tsmf/client/tsmf_media.c index 2b1a574..7c53def 100644 --- a/channels/tsmf/client/tsmf_media.c +++ b/channels/tsmf/client/tsmf_media.c @@ -71,10 +71,10 @@ struct _TSMF_PRESENTATION { BYTE presentation_id[GUID_SIZE]; - const char *audio_name; - const char *audio_device; + const char* audio_name; + const char* audio_device; - IWTSVirtualChannelCallback *channel_callback; + IWTSVirtualChannelCallback* channel_callback; UINT64 audio_start_time; UINT64 audio_end_time; @@ -82,7 +82,7 @@ struct _TSMF_PRESENTATION UINT32 volume; UINT32 muted; - wArrayList *stream_list; + wArrayList* stream_list; int x; int y; @@ -90,7 +90,7 @@ struct _TSMF_PRESENTATION int height; int nr_rects; - void *rects; + void* rects; }; struct _TSMF_STREAM @@ -99,7 +99,7 @@ struct _TSMF_STREAM TSMF_PRESENTATION* presentation; - ITSMFDecoder *decoder; + ITSMFDecoder* decoder; int major_type; int eos; @@ -109,13 +109,13 @@ struct _TSMF_STREAM UINT32 width; UINT32 height; - ITSMFAudioDevice *audio; + ITSMFAudioDevice* audio; UINT32 sample_rate; UINT32 channels; UINT32 bits_per_sample; /* The start time of last played sample */ - UINT64 last_start_time; + UINT64 last_start_time; /* The end_time of last played sample */ UINT64 last_end_time; /* Next sample should not start before this system time. */ @@ -130,8 +130,8 @@ struct _TSMF_STREAM HANDLE stopEvent; HANDLE ready; - wQueue *sample_list; - wQueue *sample_ack_list; + wQueue* sample_list; + wQueue* sample_ack_list; rdpContext* rdpcontext; BOOL seeking; @@ -145,18 +145,18 @@ struct _TSMF_SAMPLE UINT64 duration; UINT32 extensions; UINT32 data_size; - BYTE *data; + BYTE* data; UINT32 decoded_size; UINT32 pixfmt; BOOL invalidTimestamps; TSMF_STREAM* stream; - IWTSVirtualChannelCallback *channel_callback; + IWTSVirtualChannelCallback* channel_callback; UINT64 ack_time; }; -static wArrayList *presentation_list = NULL; +static wArrayList* presentation_list = NULL; static int TERMINATING = 0; static void _tsmf_presentation_free(TSMF_PRESENTATION* presentation); @@ -173,7 +173,7 @@ static TSMF_SAMPLE* tsmf_stream_pop_sample(TSMF_STREAM* stream, int sync) { UINT32 index; UINT32 count; - TSMF_STREAM *s; + TSMF_STREAM* s; TSMF_SAMPLE* sample; BOOL pending = FALSE; TSMF_PRESENTATION* presentation = stream->presentation; @@ -203,13 +203,13 @@ static TSMF_SAMPLE* tsmf_stream_pop_sample(TSMF_STREAM* stream, int sync) for (index = 0; index < count; index++) { - s = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); + s = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); /* Start time is more reliable than end time as some stream types seem to have incorrect * end times from the server */ if (s != stream && !s->eos && s->last_start_time && - s->last_start_time < stream->last_start_time - AUDIO_TOLERANCE) + s->last_start_time < stream->last_start_time - AUDIO_TOLERANCE) { DEBUG_TSMF("Pending due to audio tolerance"); pending = TRUE; @@ -238,20 +238,22 @@ static TSMF_SAMPLE* tsmf_stream_pop_sample(TSMF_STREAM* stream, int sync) if (pending) return NULL; - sample = (TSMF_SAMPLE *) Queue_Dequeue(stream->sample_list); + sample = (TSMF_SAMPLE*) Queue_Dequeue(stream->sample_list); /* Only update stream last end time if the sample end time is valid and greater than the current stream end time */ - if (sample && (sample->end_time > stream->last_end_time) && (!sample->invalidTimestamps)) + if (sample && (sample->end_time > stream->last_end_time) + && (!sample->invalidTimestamps)) stream->last_end_time = sample->end_time; /* Only update stream last start time if the sample start time is valid and greater than the current stream start time */ - if (sample && (sample->start_time > stream->last_start_time) && (!sample->invalidTimestamps)) + if (sample && (sample->start_time > stream->last_start_time) + && (!sample->invalidTimestamps)) stream->last_start_time = sample->start_time; return sample; } -static void tsmf_sample_free(void *arg) +static void tsmf_sample_free(void* arg) { TSMF_SAMPLE* sample = arg; @@ -267,7 +269,8 @@ static BOOL tsmf_sample_ack(TSMF_SAMPLE* sample) if (!sample) return FALSE; - return tsmf_playback_ack(sample->channel_callback, sample->sample_id, sample->duration, sample->data_size); + return tsmf_playback_ack(sample->channel_callback, sample->sample_id, + sample->duration, sample->data_size); } static BOOL tsmf_sample_queue_ack(TSMF_SAMPLE* sample) @@ -306,7 +309,7 @@ static BOOL tsmf_stream_process_ack(void* arg, BOOL force) if (!force) { /* Do some min/max ack limiting if we have access to Buffer level information */ - if (stream->decoder->BufferLevel) + if (stream->decoder && stream->decoder->BufferLevel) { /* Try to keep buffer level below max by withholding acks */ if (stream->currentBufferLevel > stream->maxBufferLevel) @@ -325,6 +328,7 @@ static BOOL tsmf_stream_process_ack(void* arg, BOOL force) dequeue: sample = Queue_Dequeue(stream->sample_ack_list); + if (sample) { tsmf_sample_ack(sample); @@ -336,7 +340,8 @@ finally: return rc; } -TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCallback* pChannelCallback) +TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, + IWTSVirtualChannelCallback* pChannelCallback) { TSMF_PRESENTATION* presentation; @@ -344,6 +349,7 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal return NULL; presentation = (TSMF_PRESENTATION*) calloc(1, sizeof(TSMF_PRESENTATION)); + if (!presentation) { WLog_ERR(TAG, "calloc failed"); @@ -354,22 +360,22 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal presentation->channel_callback = pChannelCallback; presentation->volume = 5000; /* 50% */ presentation->muted = 0; + if (!(presentation->stream_list = ArrayList_New(TRUE))) goto error_stream_list; - ArrayList_Object(presentation->stream_list)->fnObjectFree = (OBJECT_FREE_FN) _tsmf_stream_free; + ArrayList_Object(presentation->stream_list)->fnObjectFree = + (OBJECT_FREE_FN) _tsmf_stream_free; if (ArrayList_Add(presentation_list, presentation) < 0) goto error_add; return presentation; - error_add: ArrayList_Free(presentation->stream_list); error_stream_list: free(presentation); return NULL; - } static char* guid_to_string(const BYTE* guid, char* str, size_t len) @@ -379,20 +385,19 @@ static char* guid_to_string(const BYTE* guid, char* str, size_t len) if (!guid || !str) return NULL; - for (i=0; i 2*i; i++) - sprintf_s(str + (2*i), len - 2*i, "%02X", guid[i]); + for (i = 0; i < GUID_SIZE && len > 2 * i; i++) + sprintf_s(str + (2 * i), len - 2 * i, "%02X", guid[i]); return str; } -TSMF_PRESENTATION* tsmf_presentation_find_by_id(const BYTE *guid) +TSMF_PRESENTATION* tsmf_presentation_find_by_id(const BYTE* guid) { UINT32 index; UINT32 count; BOOL found = FALSE; char guid_str[GUID_SIZE * 2 + 1]; TSMF_PRESENTATION* presentation; - ArrayList_Lock(presentation_list); count = ArrayList_Count(presentation_list); @@ -410,7 +415,8 @@ TSMF_PRESENTATION* tsmf_presentation_find_by_id(const BYTE *guid) ArrayList_Unlock(presentation_list); if (!found) - WLog_WARN(TAG, "presentation id %s not found", guid_to_string(guid, guid_str, sizeof(guid_str))); + WLog_WARN(TAG, "presentation id %s not found", guid_to_string(guid, guid_str, + sizeof(guid_str))); return (found) ? presentation : NULL; } @@ -421,11 +427,11 @@ static BOOL tsmf_sample_playback_video(TSMF_SAMPLE* sample) TSMF_VIDEO_FRAME_EVENT event; TSMF_STREAM* stream = sample->stream; TSMF_PRESENTATION* presentation = stream->presentation; - TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) sample->channel_callback; + TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) + sample->channel_callback; TsmfClientContext* tsmf = (TsmfClientContext*) callback->plugin->pInterface; - DEBUG_TSMF("MessageId %d EndTime %d data_size %d consumed.", - sample->sample_id, (int) sample->end_time, sample->data_size); + sample->sample_id, (int) sample->end_time, sample->data_size); if (sample->data) { @@ -435,35 +441,34 @@ static BOOL tsmf_sample_playback_video(TSMF_SAMPLE* sample) * end times from the server */ if (stream->next_start_time > t && - ((sample->start_time >= presentation->audio_start_time) || - ((sample->start_time < stream->last_start_time) && (!sample->invalidTimestamps)))) + ((sample->start_time >= presentation->audio_start_time) || + ((sample->start_time < stream->last_start_time) + && (!sample->invalidTimestamps)))) { USleep((stream->next_start_time - t) / 10); } stream->next_start_time = t + sample->duration - 50000; - ZeroMemory(&event, sizeof(TSMF_VIDEO_FRAME_EVENT)); - event.frameData = sample->data; event.frameSize = sample->decoded_size; event.framePixFmt = sample->pixfmt; event.frameWidth = sample->stream->width; event.frameHeight = sample->stream->height; - #if 0 /* Dump a .ppm image for every 30 frames. Assuming the frame is in YUV format, we extract the Y values to create a grayscale image. */ static int frame_id = 0; char buf[100]; - FILE *fp; + FILE* fp; if ((frame_id % 30) == 0) { sprintf_s(buf, sizeof(buf), "/tmp/FreeRDP_Frame_%d.ppm", frame_id); fp = fopen(buf, "wb"); fwrite("P5\n", 1, 3, fp); - sprintf_s(buf, sizeof(buf), "%d %d\n", sample->stream->width, sample->stream->height); + sprintf_s(buf, sizeof(buf), "%d %d\n", sample->stream->width, + sample->stream->height); fwrite(buf, 1, strlen(buf), fp); fwrite("255\n", 1, 4, fp); fwrite(sample->data, 1, sample->stream->width * sample->stream->height, fp); @@ -473,7 +478,6 @@ static BOOL tsmf_sample_playback_video(TSMF_SAMPLE* sample) frame_id++; #endif - /* The frame data ownership is passed to the event object, and is freed after the event is processed. */ sample->data = NULL; sample->decoded_size = 0; @@ -483,6 +487,7 @@ static BOOL tsmf_sample_playback_video(TSMF_SAMPLE* sample) free(event.frameData); } + return TRUE; } @@ -491,13 +496,13 @@ static BOOL tsmf_sample_playback_audio(TSMF_SAMPLE* sample) UINT64 latency = 0; TSMF_STREAM* stream = sample->stream; BOOL ret; - DEBUG_TSMF("MessageId %d EndTime %d consumed.", - sample->sample_id, (int)sample->end_time); + sample->sample_id, (int)sample->end_time); if (stream->audio && sample->data) { - ret = sample->stream->audio->Play(sample->stream->audio, sample->data, sample->decoded_size); + ret = sample->stream->audio->Play(sample->stream->audio, sample->data, + sample->decoded_size); sample->data = NULL; sample->decoded_size = 0; @@ -520,6 +525,7 @@ static BOOL tsmf_sample_playback_audio(TSMF_SAMPLE* sample) stream->presentation->audio_start_time = sample->start_time + latency; stream->presentation->audio_end_time = sample->end_time + latency; } + return ret; } @@ -540,21 +546,24 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) * render times. So, we try to adjust timestamps on the video buffer to match those on the audio buffer. */ if (stream->major_type == TSMF_MAJOR_TYPE_VIDEO) - { + { TSMF_STREAM* temp_stream = NULL; TSMF_PRESENTATION* presentation = stream->presentation; ArrayList_Lock(presentation->stream_list); int count = ArrayList_Count(presentation->stream_list); int index = 0; + for (index = 0; index < count; index++) { UINT64 time_diff; + temp_stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, + index); - temp_stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); if (temp_stream->major_type == TSMF_MAJOR_TYPE_AUDIO) { UINT64 video_time = (UINT64) stream->decoder->GetRunningTime(stream->decoder); - UINT64 audio_time = (UINT64) temp_stream->decoder->GetRunningTime(temp_stream->decoder); + UINT64 audio_time = (UINT64) temp_stream->decoder->GetRunningTime( + temp_stream->decoder); UINT64 max_adjust = VIDEO_ADJUST_MAX; if (video_time < audio_time) @@ -568,25 +577,28 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) time_diff = time_diff < VIDEO_ADJUST_MAX ? time_diff : max_adjust; sample->start_time += time_diff; sample->end_time += time_diff; - break; } } + ArrayList_Unlock(presentation->stream_list); } - ret = stream->decoder->DecodeEx(stream->decoder, sample->data, sample->data_size, sample->extensions, - sample->start_time, sample->end_time, sample->duration); + ret = stream->decoder->DecodeEx(stream->decoder, sample->data, + sample->data_size, sample->extensions, + sample->start_time, sample->end_time, sample->duration); } else { - ret = stream->decoder->Decode(stream->decoder, sample->data, sample->data_size, sample->extensions); + ret = stream->decoder->Decode(stream->decoder, sample->data, sample->data_size, + sample->extensions); } } if (!ret) { WLog_ERR(TAG, "decode error, queue ack anyways"); + if (!tsmf_sample_queue_ack(sample)) { WLog_ERR(TAG, "error queuing sample for ack"); @@ -605,13 +617,15 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) { pixfmt = stream->decoder->GetDecodedFormat(stream->decoder); - if (pixfmt == ((UINT32) -1)) + if (pixfmt == ((UINT32) - 1)) { WLog_ERR(TAG, "unable to decode video format"); + if (!tsmf_sample_queue_ack(sample)) { WLog_ERR(TAG, "error queuing sample for ack"); } + return FALSE; } @@ -633,18 +647,19 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) if (stream->decoder->GetDecodedData) { - sample->data = stream->decoder->GetDecodedData(stream->decoder, &sample->decoded_size); + sample->data = stream->decoder->GetDecodedData(stream->decoder, + &sample->decoded_size); switch (sample->stream->major_type) { case TSMF_MAJOR_TYPE_VIDEO: ret = tsmf_sample_playback_video(sample) && - tsmf_sample_queue_ack(sample); + tsmf_sample_queue_ack(sample); break; case TSMF_MAJOR_TYPE_AUDIO: ret = tsmf_sample_playback_audio(sample) && - tsmf_sample_queue_ack(sample); + tsmf_sample_queue_ack(sample); break; } } @@ -663,27 +678,30 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) if (buffer_filled) { - ack_anticipation_time += (sample->duration/2 < MAX_ACK_TIME) ? sample->duration/2 : MAX_ACK_TIME; + ack_anticipation_time += (sample->duration / 2 < MAX_ACK_TIME) ? + sample->duration / 2 : MAX_ACK_TIME; } else { - ack_anticipation_time += (sample->duration/2 < MAX_ACK_TIME) ? sample->duration/2 : MAX_ACK_TIME; + ack_anticipation_time += (sample->duration / 2 < MAX_ACK_TIME) ? + sample->duration / 2 : MAX_ACK_TIME; } switch (sample->stream->major_type) { case TSMF_MAJOR_TYPE_VIDEO: - { - break; - } + { + break; + } case TSMF_MAJOR_TYPE_AUDIO: - { - break; - } + { + break; + } } sample->ack_time = ack_anticipation_time; + if (!tsmf_sample_queue_ack(sample)) { WLog_ERR(TAG, "error queuing sample for ack"); @@ -694,7 +712,7 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample) return ret; } -static void* tsmf_stream_ack_func(void *arg) +static void* tsmf_stream_ack_func(void* arg) { HANDLE hdl[2]; TSMF_STREAM* stream = (TSMF_STREAM*) arg; @@ -711,7 +729,7 @@ static void* tsmf_stream_ack_func(void *arg) if (ev == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error); break; } @@ -721,10 +739,12 @@ static void* tsmf_stream_ack_func(void *arg) if (stream->eos) { - while ((stream->currentBufferLevel > 0) || !(tsmf_stream_process_ack(stream, TRUE))) + while ((stream->currentBufferLevel > 0) + || !(tsmf_stream_process_ack(stream, TRUE))) { DEBUG_TSMF("END OF STREAM PROCESSING!"); - if (stream->decoder->BufferLevel) + + if (stream->decoder && stream->decoder->BufferLevel) stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder); else stream->currentBufferLevel = 1; @@ -740,7 +760,7 @@ static void* tsmf_stream_ack_func(void *arg) DEBUG_TSMF("Finishing delayed stream stop, now that eos has processed."); tsmf_stream_flush(stream); - if (stream->decoder->Control) + if (stream->decoder && stream->decoder->Control) stream->decoder->Control(stream->decoder, Control_Stop, NULL); } } @@ -749,12 +769,15 @@ static void* tsmf_stream_ack_func(void *arg) if (ev == WAIT_OBJECT_0) { DEBUG_TSMF("ack: Stream stopped!"); - while(1) + + while (1) { if (tsmf_stream_process_ack(stream, TRUE)) break; + USleep(1000); } + break; } @@ -766,38 +789,41 @@ static void* tsmf_stream_ack_func(void *arg) } if (error && stream->rdpcontext) - setChannelError(stream->rdpcontext, error, "tsmf_stream_ack_func reported an error"); + setChannelError(stream->rdpcontext, error, + "tsmf_stream_ack_func reported an error"); DEBUG_TSMF("out %d", stream->stream_id); ExitThread(0); return NULL; } -static void* tsmf_stream_playback_func(void *arg) +static void* tsmf_stream_playback_func(void* arg) { HANDLE hdl[2]; TSMF_SAMPLE* sample = NULL; - TSMF_STREAM* stream = (TSMF_STREAM *) arg; + TSMF_STREAM* stream = (TSMF_STREAM*) arg; TSMF_PRESENTATION* presentation = stream->presentation; UINT error = CHANNEL_RC_OK; DWORD status; - DEBUG_TSMF("in %d", stream->stream_id); if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO && - stream->sample_rate && stream->channels && stream->bits_per_sample) + stream->sample_rate && stream->channels && stream->bits_per_sample) { if (stream->decoder) { if (stream->decoder->GetDecodedData) { stream->audio = tsmf_load_audio_device( - presentation->audio_name && presentation->audio_name[0] ? presentation->audio_name : NULL, - presentation->audio_device && presentation->audio_device[0] ? presentation->audio_device : NULL); + presentation->audio_name + && presentation->audio_name[0] ? presentation->audio_name : NULL, + presentation->audio_device + && presentation->audio_device[0] ? presentation->audio_device : NULL); if (stream->audio) { - stream->audio->SetFormat(stream->audio, stream->sample_rate, stream->channels, stream->bits_per_sample); + stream->audio->SetFormat(stream->audio, stream->sample_rate, stream->channels, + stream->bits_per_sample); } } } @@ -813,7 +839,7 @@ static void* tsmf_stream_playback_func(void *arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u!", error); break; } @@ -822,7 +848,7 @@ static void* tsmf_stream_playback_func(void *arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); break; } @@ -846,7 +872,6 @@ static void* tsmf_stream_playback_func(void *arg) USleep(1000); } - if (stream->audio) { stream->audio->Free(stream->audio); @@ -854,7 +879,8 @@ static void* tsmf_stream_playback_func(void *arg) } if (error && stream->rdpcontext) - setChannelError(stream->rdpcontext, error, "tsmf_stream_playback_func reported an error"); + setChannelError(stream->rdpcontext, error, + "tsmf_stream_playback_func reported an error"); DEBUG_TSMF("out %d", stream->stream_id); ExitThread(0); @@ -863,11 +889,11 @@ static void* tsmf_stream_playback_func(void *arg) static BOOL tsmf_stream_start(TSMF_STREAM* stream) { - if (!stream || !stream->presentation || !stream->decoder || !stream->decoder->Control) + if (!stream || !stream->presentation || !stream->decoder + || !stream->decoder->Control) return TRUE; stream->eos = 0; - return stream->decoder->Control(stream->decoder, Control_Restart, NULL); } @@ -891,7 +917,6 @@ static BOOL tsmf_stream_stop(TSMF_STREAM* stream) { DEBUG_TSMF("Stop with no pending eos response, so do it immediately."); tsmf_stream_flush(stream); - return stream->decoder->Control(stream->decoder, Control_Stop, NULL); } } @@ -910,11 +935,11 @@ static BOOL tsmf_stream_restart(TSMF_STREAM* stream) return TRUE; stream->eos = 0; - return stream->decoder->Control(stream->decoder, Control_Restart, NULL); } -static BOOL tsmf_stream_change_volume(TSMF_STREAM* stream, UINT32 newVolume, UINT32 muted) +static BOOL tsmf_stream_change_volume(TSMF_STREAM* stream, UINT32 newVolume, + UINT32 muted) { if (!stream || !stream->decoder) return TRUE; @@ -927,25 +952,25 @@ static BOOL tsmf_stream_change_volume(TSMF_STREAM* stream, UINT32 newVolume, UIN { return stream->audio->ChangeVolume(stream->audio, newVolume, muted); } + return TRUE; } -BOOL tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 newVolume, UINT32 muted) +BOOL tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, + UINT32 newVolume, UINT32 muted) { UINT32 index; UINT32 count; TSMF_STREAM* stream; BOOL ret = TRUE; - presentation->volume = newVolume; presentation->muted = muted; - ArrayList_Lock(presentation->stream_list); - count = ArrayList_Count(presentation->stream_list); + for (index = 0; index < count; index++) { - stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); + stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); ret &= tsmf_stream_change_volume(stream, newVolume, muted); } @@ -959,13 +984,12 @@ BOOL tsmf_presentation_paused(TSMF_PRESENTATION* presentation) UINT32 count; TSMF_STREAM* stream; BOOL ret = TRUE; - ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { - stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); + stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); ret &= tsmf_stream_pause(stream); } @@ -979,13 +1003,12 @@ BOOL tsmf_presentation_restarted(TSMF_PRESENTATION* presentation) UINT32 count; TSMF_STREAM* stream; BOOL ret = TRUE; - ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { - stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); + stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); ret &= tsmf_stream_restart(stream); } @@ -999,13 +1022,12 @@ BOOL tsmf_presentation_start(TSMF_PRESENTATION* presentation) UINT32 count; TSMF_STREAM* stream; BOOL ret = TRUE; - ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { - stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); + stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); ret &= tsmf_stream_start(stream); } @@ -1023,17 +1045,18 @@ UINT tsmf_presentation_sync(TSMF_PRESENTATION* presentation) UINT32 index; UINT32 count; UINT error; - ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { - TSMF_STREAM* stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); + TSMF_STREAM* stream = (TSMF_STREAM*) ArrayList_GetItem( + presentation->stream_list, index); + if (WaitForSingleObject(stream->ready, 500) == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %u!", error); return error; } } @@ -1048,30 +1071,28 @@ BOOL tsmf_presentation_stop(TSMF_PRESENTATION* presentation) UINT32 count; TSMF_STREAM* stream; BOOL ret = TRUE; - ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { - stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); + stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); ret &= tsmf_stream_stop(stream); } ArrayList_Unlock(presentation->stream_list); presentation->audio_start_time = 0; presentation->audio_end_time = 0; - return ret; } BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, - UINT32 x, UINT32 y, UINT32 width, UINT32 height, int num_rects, RDP_RECT *rects) + UINT32 x, UINT32 y, UINT32 width, UINT32 height, int num_rects, RDP_RECT* rects) { UINT32 index; UINT32 count; TSMF_STREAM* stream; - void *tmp_rects = NULL; + void* tmp_rects = NULL; BOOL ret = TRUE; /* The server may send messages with invalid width / height. @@ -1079,36 +1100,32 @@ BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, if (!width || !height) return TRUE; - /* Streams can be added/removed from the presentation and the server will resend geometry info when a new stream is + /* Streams can be added/removed from the presentation and the server will resend geometry info when a new stream is * added to the presentation. Also, num_rects is used to indicate whether or not the window is visible. * So, always process a valid message with unchanged position/size and/or no visibility rects. */ - presentation->x = x; presentation->y = y; presentation->width = width; presentation->height = height; - tmp_rects = realloc(presentation->rects, sizeof(RDP_RECT) * num_rects); - presentation->nr_rects = num_rects; presentation->rects = tmp_rects; - CopyMemory(presentation->rects, rects, sizeof(RDP_RECT) * num_rects); - ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); for (index = 0; index < count; index++) { - stream = (TSMF_STREAM *) ArrayList_GetItem(presentation->stream_list, index); + stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index); if (!stream->decoder) continue; if (stream->decoder->UpdateRenderingArea) { - ret = stream->decoder->UpdateRenderingArea(stream->decoder, x, y, width, height, num_rects, rects); + ret = stream->decoder->UpdateRenderingArea(stream->decoder, x, y, width, height, + num_rects, rects); } } @@ -1116,7 +1133,8 @@ BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, return ret; } -void tsmf_presentation_set_audio_device(TSMF_PRESENTATION* presentation, const char *name, const char *device) +void tsmf_presentation_set_audio_device(TSMF_PRESENTATION* presentation, + const char* name, const char* device) { presentation->audio_name = name; presentation->audio_device = device; @@ -1143,6 +1161,7 @@ BOOL tsmf_stream_flush(TSMF_STREAM* stream) stream->presentation->audio_start_time = 0; stream->presentation->audio_end_time = 0; } + return TRUE; } @@ -1151,9 +1170,7 @@ void _tsmf_presentation_free(TSMF_PRESENTATION* presentation) tsmf_presentation_stop(presentation); ArrayList_Clear(presentation->stream_list); ArrayList_Free(presentation->stream_list); - free(presentation->rects); - ZeroMemory(presentation, sizeof(TSMF_PRESENTATION)); free(presentation); } @@ -1163,7 +1180,8 @@ void tsmf_presentation_free(TSMF_PRESENTATION* presentation) ArrayList_Remove(presentation_list, presentation); } -TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id, rdpContext* rdpcontext) +TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id, + rdpContext* rdpcontext) { TSMF_STREAM* stream; stream = tsmf_stream_find_by_id(presentation, stream_id); @@ -1175,6 +1193,7 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id, } stream = (TSMF_STREAM*) calloc(1, sizeof(TSMF_STREAM)); + if (!stream) { WLog_ERR(TAG, "Calloc failed"); @@ -1184,7 +1203,6 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id, stream->minBufferLevel = VIDEO_MIN_BUFFER_LEVEL; stream->maxBufferLevel = VIDEO_MAX_BUFFER_LEVEL; stream->currentBufferLevel = 1; - stream->seeking = FALSE; stream->eos = 0; stream->eos_message_id = 0; @@ -1192,24 +1210,36 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id, stream->stream_id = stream_id; stream->presentation = presentation; stream->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!stream->stopEvent) goto error_stopEvent; + stream->ready = CreateEvent(NULL, TRUE, TRUE, NULL); + if (!stream->ready) goto error_ready; + stream->sample_list = Queue_New(TRUE, -1, -1); + if (!stream->sample_list) goto error_sample_list; + stream->sample_list->object.fnObjectFree = tsmf_sample_free; stream->sample_ack_list = Queue_New(TRUE, -1, -1); + if (!stream->sample_ack_list) goto error_sample_ack_list; - stream->sample_ack_list->object.fnObjectFree = tsmf_sample_free; - stream->play_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, 0, NULL); + stream->sample_ack_list->object.fnObjectFree = tsmf_sample_free; + stream->play_thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, 0, NULL); + if (!stream->play_thread) goto error_play_thread; - stream->ack_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tsmf_stream_ack_func, stream, 0, NULL); + + stream->ack_thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE)tsmf_stream_ack_func, stream, 0, NULL); + if (!stream->ack_thread) goto error_ack_thread; @@ -1217,17 +1247,19 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id, goto error_add; stream->rdpcontext = rdpcontext; - return stream; - error_add: SetEvent(stream->stopEvent); + if (WaitForSingleObject(stream->ack_thread, INFINITE) == WAIT_FAILED) - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) GetLastError()); + error_ack_thread: SetEvent(stream->stopEvent); + if (WaitForSingleObject(stream->play_thread, INFINITE) == WAIT_FAILED) - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) GetLastError()); + error_play_thread: Queue_Free(stream->sample_ack_list); error_sample_ack_list: @@ -1241,13 +1273,13 @@ error_stopEvent: return NULL; } -TSMF_STREAM *tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, UINT32 stream_id) +TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, + UINT32 stream_id) { UINT32 index; UINT32 count; BOOL found = FALSE; TSMF_STREAM* stream; - ArrayList_Lock(presentation->stream_list); count = ArrayList_Count(presentation->stream_list); @@ -1266,13 +1298,13 @@ TSMF_STREAM *tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, UINT32 stre return (found) ? stream : NULL; } -static void tsmf_stream_resync(void *arg) +static void tsmf_stream_resync(void* arg) { TSMF_STREAM* stream = arg; ResetEvent(stream->ready); } -BOOL tsmf_stream_set_format(TSMF_STREAM* stream, const char *name, wStream *s) +BOOL tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, wStream* s) { TS_AM_MEDIA_TYPE mediatype; BOOL ret = TRUE; @@ -1292,18 +1324,19 @@ BOOL tsmf_stream_set_format(TSMF_STREAM* stream, const char *name, wStream *s) if (mediatype.MajorType == TSMF_MAJOR_TYPE_VIDEO) { DEBUG_TSMF("video width %d height %d bit_rate %d frame_rate %f codec_data %d", - mediatype.Width, mediatype.Height, mediatype.BitRate, - (double) mediatype.SamplesPerSecond.Numerator / (double) mediatype.SamplesPerSecond.Denominator, - mediatype.ExtraDataSize); - + mediatype.Width, mediatype.Height, mediatype.BitRate, + (double) mediatype.SamplesPerSecond.Numerator / (double) + mediatype.SamplesPerSecond.Denominator, + mediatype.ExtraDataSize); stream->minBufferLevel = VIDEO_MIN_BUFFER_LEVEL; stream->maxBufferLevel = VIDEO_MAX_BUFFER_LEVEL; } else if (mediatype.MajorType == TSMF_MAJOR_TYPE_AUDIO) { DEBUG_TSMF("audio channel %d sample_rate %d bits_per_sample %d codec_data %d", - mediatype.Channels, mediatype.SamplesPerSecond.Numerator, mediatype.BitsPerSample, - mediatype.ExtraDataSize); + mediatype.Channels, mediatype.SamplesPerSecond.Numerator, + mediatype.BitsPerSample, + mediatype.ExtraDataSize); stream->sample_rate = mediatype.SamplesPerSecond.Numerator; stream->channels = mediatype.Channels; stream->bits_per_sample = mediatype.BitsPerSample; @@ -1319,20 +1352,25 @@ BOOL tsmf_stream_set_format(TSMF_STREAM* stream, const char *name, wStream *s) stream->width = mediatype.Width; stream->height = mediatype.Height; stream->decoder = tsmf_load_decoder(name, &mediatype); - ret &= tsmf_stream_change_volume(stream, stream->presentation->volume, stream->presentation->muted); + ret &= tsmf_stream_change_volume(stream, stream->presentation->volume, + stream->presentation->muted); if (!stream->decoder) return FALSE; if (stream->decoder->SetAckFunc) - ret &= stream->decoder->SetAckFunc(stream->decoder, tsmf_stream_process_ack, stream); + ret &= stream->decoder->SetAckFunc(stream->decoder, tsmf_stream_process_ack, + stream); if (stream->decoder->SetSyncFunc) - ret &= stream->decoder->SetSyncFunc(stream->decoder, tsmf_stream_resync, stream); + ret &= stream->decoder->SetSyncFunc(stream->decoder, tsmf_stream_resync, + stream); + return ret; } -void tsmf_stream_end(TSMF_STREAM* stream, UINT32 message_id, IWTSVirtualChannelCallback* pChannelCallback) +void tsmf_stream_end(TSMF_STREAM* stream, UINT32 message_id, + IWTSVirtualChannelCallback* pChannelCallback) { if (!stream) return; @@ -1354,7 +1392,7 @@ void _tsmf_stream_free(TSMF_STREAM* stream) { if (WaitForSingleObject(stream->play_thread, INFINITE) == WAIT_FAILED) { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) GetLastError()); return; } @@ -1366,9 +1404,10 @@ void _tsmf_stream_free(TSMF_STREAM* stream) { if (WaitForSingleObject(stream->ack_thread, INFINITE) == WAIT_FAILED) { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError()); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) GetLastError()); return; } + CloseHandle(stream->ack_thread); stream->ack_thread = NULL; } @@ -1394,9 +1433,11 @@ void tsmf_stream_free(TSMF_STREAM* stream) ArrayList_Remove(presentation->stream_list, stream); } -BOOL tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback *pChannelCallback, - UINT32 sample_id, UINT64 start_time, UINT64 end_time, UINT64 duration, UINT32 extensions, - UINT32 data_size, BYTE *data) +BOOL tsmf_stream_push_sample(TSMF_STREAM* stream, + IWTSVirtualChannelCallback* pChannelCallback, + UINT32 sample_id, UINT64 start_time, UINT64 end_time, UINT64 duration, + UINT32 extensions, + UINT32 data_size, BYTE* data) { TSMF_SAMPLE* sample; SetEvent(stream->ready); @@ -1405,6 +1446,7 @@ BOOL tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback *pC return TRUE; sample = (TSMF_SAMPLE*) calloc(1, sizeof(TSMF_SAMPLE)); + if (!sample) { WLog_ERR(TAG, "calloc sample failed!"); @@ -1416,10 +1458,12 @@ BOOL tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback *pC sample->end_time = end_time; sample->duration = duration; sample->extensions = extensions; + if ((sample->extensions & 0x00000080) || (sample->extensions & 0x00000040)) sample->invalidTimestamps = TRUE; else sample->invalidTimestamps = FALSE; + sample->stream = stream; sample->channel_callback = pChannelCallback; sample->data_size = data_size; @@ -1470,9 +1514,13 @@ BOOL tsmf_media_init(void) if (!presentation_list) { presentation_list = ArrayList_New(TRUE); + if (!presentation_list) return FALSE; - ArrayList_Object(presentation_list)->fnObjectFree = (OBJECT_FREE_FN) _tsmf_presentation_free; + + ArrayList_Object(presentation_list)->fnObjectFree = (OBJECT_FREE_FN) + _tsmf_presentation_free; } + return TRUE; } diff --git a/channels/tsmf/client/tsmf_types.h b/channels/tsmf/client/tsmf_types.h index 07cd999..cdda337 100644 --- a/channels/tsmf/client/tsmf_types.h +++ b/channels/tsmf/client/tsmf_types.h @@ -31,9 +31,9 @@ #define TAG CHANNELS_TAG("tsmf.client") #ifdef WITH_DEBUG_TSMF -#define DEBUG_TSMF(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__) +#define DEBUG_TSMF(...) WLog_DBG(TAG, __VA_ARGS__) #else -#define DEBUG_TSMF(fmt, ...) do { } while (0) +#define DEBUG_TSMF(...) do { } while (0) #endif typedef struct _TS_AM_MEDIA_TYPE @@ -53,7 +53,7 @@ typedef struct _TS_AM_MEDIA_TYPE UINT32 Channels; UINT32 BitsPerSample; UINT32 BlockAlign; - const BYTE *ExtraData; + const BYTE* ExtraData; UINT32 ExtraDataSize; } TS_AM_MEDIA_TYPE; diff --git a/channels/urbdrc/CMakeLists.txt b/channels/urbdrc/CMakeLists.txt index 995c63b..c7e546f 100644 --- a/channels/urbdrc/CMakeLists.txt +++ b/channels/urbdrc/CMakeLists.txt @@ -26,7 +26,12 @@ if(NOT WIN32) endif() if(DEVD_FOUND OR UDEV_FOUND) + include_directories(${UDEV_INCLUDE_DIR}) if(UUID_FOUND AND DBUS_GLIB_FOUND AND LIBUSB_1_FOUND) + include_directories(${UUID_INCLUDE_DIRS}) + include_directories(${LIBUSB_1_INCLUDE_DIRS}) + include_directories(${DBUS_GLIB_INCLUDE_DIRS}) + set(URBDRC_DEPENDENCIES_FOUND TRUE) message(STATUS "Found all URBDRC dependencies") else() diff --git a/channels/urbdrc/client/CMakeLists.txt b/channels/urbdrc/client/CMakeLists.txt index a1d5f5f..24c7ee9 100644 --- a/channels/urbdrc/client/CMakeLists.txt +++ b/channels/urbdrc/client/CMakeLists.txt @@ -46,7 +46,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr freerdp) target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWOARD} ${${MODULE_PREFIX}_LIBS}) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/urbdrc/client/libusb/CMakeLists.txt b/channels/urbdrc/client/libusb/CMakeLists.txt index bb42002..abb4356 100644 --- a/channels/urbdrc/client/libusb/CMakeLists.txt +++ b/channels/urbdrc/client/libusb/CMakeLists.txt @@ -42,7 +42,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT STATIC_CHANNELS AND BUILD_SHARED_LIBS) +if (WITH_DEBUG_SYMBOLS AND MSVC AND NOT BUILTIN_CHANNELS AND BUILD_SHARED_LIBS) install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${FREERDP_ADDIN_PATH} COMPONENT symbols) endif() diff --git a/channels/urbdrc/client/libusb/libusb_udevman.c b/channels/urbdrc/client/libusb/libusb_udevman.c index b8af3a4..cfa5ff1 100644 --- a/channels/urbdrc/client/libusb/libusb_udevman.c +++ b/channels/urbdrc/client/libusb/libusb_udevman.c @@ -577,7 +577,7 @@ static void urbdrc_udevman_parse_addin_args(UDEVMAN* udevman, ADDIN_ARGV* args) while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define freerdp_urbdrc_client_subsystem_entry libusb_freerdp_urbdrc_client_subsystem_entry #else #define freerdp_urbdrc_client_subsystem_entry FREERDP_API freerdp_urbdrc_client_subsystem_entry diff --git a/channels/urbdrc/client/urbdrc_main.c b/channels/urbdrc/client/urbdrc_main.c index cbb9379..41f1720 100644 --- a/channels/urbdrc/client/urbdrc_main.c +++ b/channels/urbdrc/client/urbdrc_main.c @@ -568,7 +568,7 @@ static void *urbdrc_search_usb_device(void *arg) { if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) error); return 0; } @@ -815,7 +815,7 @@ static void* urbdrc_search_usb_device(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", (unsigned long) error); goto out; } @@ -824,7 +824,7 @@ static void* urbdrc_search_usb_device(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) error); goto out; } @@ -839,7 +839,7 @@ static void* urbdrc_search_usb_device(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) error); goto out; } @@ -923,7 +923,7 @@ static void* urbdrc_search_usb_device(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", (unsigned long) error); goto out; } @@ -932,7 +932,7 @@ static void* urbdrc_search_usb_device(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", (unsigned long) error); goto out; } @@ -995,7 +995,7 @@ static void* urbdrc_search_usb_device(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", (unsigned long) error); goto out; } @@ -1004,7 +1004,7 @@ static void* urbdrc_search_usb_device(void* arg) if (status == WAIT_FAILED) { error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", (unsigned long) error); goto out; } @@ -1539,7 +1539,7 @@ static UINT urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args) return CHANNEL_RC_OK; } -#ifdef STATIC_CHANNELS +#ifdef BUILTIN_CHANNELS #define DVCPluginEntry urbdrc_DVCPluginEntry #else #define DVCPluginEntry FREERDP_API DVCPluginEntry diff --git a/channels/urbdrc/client/urbdrc_types.h b/channels/urbdrc/client/urbdrc_types.h index a3219d7..78c550e 100644 --- a/channels/urbdrc/client/urbdrc_types.h +++ b/channels/urbdrc/client/urbdrc_types.h @@ -30,11 +30,7 @@ #include #include -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) #include -#else -#include -#endif #include #include @@ -42,9 +38,9 @@ #define TAG CHANNELS_TAG("urbdrc.client") #ifdef WITH_DEBUG_DVC -#define DEBUG_DVC(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__) +#define DEBUG_DVC(...) WLog_DBG(TAG, __VA_ARGS__) #else -#define DEBUG_DVC(fmt, ...) do { } while (0) +#define DEBUG_DVC(...) do { } while (0) #endif #define CAPABILITIES_NEGOTIATOR 0x00000000 @@ -113,25 +109,25 @@ enum device_text_type { - DeviceTextDescription = 0, + DeviceTextDescription = 0, DeviceTextLocationInformation = 1, }; enum device_descriptor_table { - B_LENGTH = 0, - B_DESCRIPTOR_TYPE = 1, - BCD_USB = 2, + B_LENGTH = 0, + B_DESCRIPTOR_TYPE = 1, + BCD_USB = 2, B_DEVICE_CLASS = 4, - B_DEVICE_SUBCLASS = 5, + B_DEVICE_SUBCLASS = 5, B_DEVICE_PROTOCOL = 6, - B_MAX_PACKET_SIZE0 = 7, - ID_VENDOR = 8, + B_MAX_PACKET_SIZE0 = 7, + ID_VENDOR = 8, ID_PRODUCT = 10, - BCD_DEVICE = 12, + BCD_DEVICE = 12, I_MANUFACTURER = 14, - I_PRODUCT = 15, - I_SERIAL_NUMBER = 16, + I_PRODUCT = 15, + I_SERIAL_NUMBER = 16, B_NUM_CONFIGURATIONS = 17 }; @@ -263,11 +259,11 @@ enum device_descriptor_table #define USBD_TRANSFER_DIRECTION_IN 1 #define VALID_TRANSFER_FLAGS_MASK USBD_SHORT_TRANSFER_OK | \ - USBD_TRANSFER_DIRECTION | \ - USBD_START_ISO_TRANSFER_ASAP | \ - USBD_DEFAULT_PIPE_TRANSFER) - -#define ENDPOINT_HALT 0x00 + USBD_TRANSFER_DIRECTION | \ + USBD_START_ISO_TRANSFER_ASAP | \ + USBD_DEFAULT_PIPE_TRANSFER) + +#define ENDPOINT_HALT 0x00 #define DEVICE_REMOTE_WAKEUP 0x01 /* transfer type */ @@ -322,16 +318,16 @@ enum device_descriptor_table #define LOG_LEVEL 1 -#define dummy_wait_obj(void) do{ sleep(5); } while(0) -#define dummy_wait_s_obj(_s) do{ sleep(_s); } while(0) +#define dummy_wait_obj(void) do{ sleep(5); } while(0) +#define dummy_wait_s_obj(_s) do{ sleep(_s); } while(0) #define ISOCH_FIFO 1 #define WAIT_COMPLETE_SLEEP 10000 /* for cpu high loading */ #define urbdrc_get_mstime(_t) do { \ - struct timeval _tp; \ - gettimeofday(&_tp, 0); \ - _t = (_tp.tv_sec * 1000) + (_tp.tv_usec / 1000); \ -} while (0) + struct timeval _tp; \ + gettimeofday(&_tp, 0); \ + _t = (_tp.tv_sec * 1000) + (_tp.tv_usec / 1000); \ + } while (0) #endif /* __URBDRC_TYPES_H */ diff --git a/ci/cmake-preloads/config-linux-all.txt b/ci/cmake-preloads/config-linux-all.txt index 010e865..0dff3a0 100644 --- a/ci/cmake-preloads/config-linux-all.txt +++ b/ci/cmake-preloads/config-linux-all.txt @@ -5,7 +5,7 @@ set (CMAKE_BUILD_TYPE "Debug" CACHE STRING "build type") set (BUILD_TESTING ON CACHE BOOL "build testing") set (WITH_PULSE ON CACHE BOOL "pulse") set (WITH_CHANNELS ON CACHE BOOL "channels") -set (STATIC_CHANNELS ON CACHE BOOL "static channels") +set (BUILTIN_CHANNELS ON CACHE BOOL "static channels") set (WITH_CUPS ON CACHE BOOL "cups") set (WITH_PCSC ON CACHE BOOL "PCSC") set (WITH_JPEG ON CACHE BOOL "jepg") @@ -20,7 +20,6 @@ set (WITH_DEBUG_CERTIFICATE OFF CACHE BOOL "enable debug") set (WITH_DEBUG_CHANNELS OFF CACHE BOOL "enable debug") set (WITH_DEBUG_CLIPRDR OFF CACHE BOOL "enable debug") set (WITH_DEBUG_DVC OFF CACHE BOOL "enable debug") -set (WITH_DEBUG_GDI OFF CACHE BOOL "enable debug") set (WITH_DEBUG_KBD OFF CACHE BOOL "enable debug") set (WITH_DEBUG_LICENSE OFF CACHE BOOL "enable debug") set (WITH_DEBUG_NEGO OFF CACHE BOOL "enable debug") diff --git a/ci/cmake-preloads/config-windows.txt b/ci/cmake-preloads/config-windows.txt index 0a84d88..723f370 100644 --- a/ci/cmake-preloads/config-windows.txt +++ b/ci/cmake-preloads/config-windows.txt @@ -1,4 +1,4 @@ message("PRELOADING windows cache") set (CMAKE_BUILD_TYPE "Debug" CACHE STRING "build type") set(WITH_SERVER "ON" CACHE BOOL "Build server binaries") -#set (BUILD_TESTING ON CACHE BOOL "build testing") +set (BUILD_TESTING ON CACHE BOOL "build testing") diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index bb8e4f6..166847e 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -20,8 +20,8 @@ add_subdirectory(common) if(FREERDP_VENDOR AND WITH_CLIENT) - if(WIN32) - add_subdirectory(Windows) + if(WIN32 AND NOT UWP) + add_subdirectory(Windows) else() if(WITH_SAMPLE) add_subdirectory(Sample) diff --git a/client/DirectFB/dfreerdp.c b/client/DirectFB/dfreerdp.c index 5c801cd..0a867d8 100644 --- a/client/DirectFB/dfreerdp.c +++ b/client/DirectFB/dfreerdp.c @@ -51,33 +51,23 @@ struct thread_data BOOL df_context_new(freerdp* instance, rdpContext* context) { - if (!(context->channels = freerdp_channels_new())) - return FALSE; - return TRUE; } void df_context_free(freerdp* instance, rdpContext* context) { - if (context && context->channels) - { - freerdp_channels_close(context->channels, instance); - freerdp_channels_free(context->channels); - context->channels = NULL; - } } void df_begin_paint(rdpContext* context) { rdpGdi* gdi = context->gdi; - gdi->primary->hdc->hwnd->invalid->null = 1; + gdi->primary->hdc->hwnd->invalid->null = TRUE; } void df_end_paint(rdpContext* context) { rdpGdi* gdi; dfInfo* dfi; - gdi = context->gdi; dfi = ((dfContext*) context)->dfi; @@ -95,26 +85,23 @@ void df_end_paint(rdpContext* context) dfi->update_rect.w = gdi->width; dfi->update_rect.h = gdi->height; #endif - - dfi->primary->Blit(dfi->primary, dfi->surface, &(dfi->update_rect), dfi->update_rect.x, dfi->update_rect.y); + dfi->primary->Blit(dfi->primary, dfi->surface, &(dfi->update_rect), + dfi->update_rect.x, dfi->update_rect.y); } -BOOL df_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) +BOOL df_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, + int* wcount) { dfInfo* dfi; - dfi = ((dfContext*) instance->context)->dfi; - rfds[*rcount] = (void*)(long)(dfi->read_fds); (*rcount)++; - return TRUE; } BOOL df_check_fds(freerdp* instance, fd_set* set) { dfInfo* dfi; - dfi = ((dfContext*) instance->context)->dfi; if (!FD_ISSET(dfi->read_fds, set)) @@ -132,16 +119,12 @@ BOOL df_pre_connect(freerdp* instance) BOOL bitmap_cache; dfContext* context; rdpSettings* settings; - dfi = (dfInfo*) malloc(sizeof(dfInfo)); ZeroMemory(dfi, sizeof(dfInfo)); - context = ((dfContext*) instance->context); context->dfi = dfi; - settings = instance->settings; bitmap_cache = settings->BitmapCacheEnabled; - settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; @@ -166,20 +149,13 @@ BOOL df_pre_connect(freerdp* instance) settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; - dfi->clrconv = (CLRCONV*) malloc(sizeof(CLRCONV)); ZeroMemory(dfi->clrconv, sizeof(CLRCONV)); - dfi->clrconv->alpha = 1; dfi->clrconv->invert = 0; dfi->clrconv->rgb555 = 0; - dfi->clrconv->palette = (rdpPalette*) malloc(sizeof(rdpPalette)); ZeroMemory(dfi->clrconv->palette, sizeof(rdpPalette)); - - if (freerdp_channels_pre_connect(instance->context->channels, instance) != CHANNEL_RC_OK) - return FALSE; - return (instance->context->cache = cache_new(instance->settings)) != NULL; } @@ -188,29 +164,27 @@ BOOL df_post_connect(freerdp* instance) rdpGdi* gdi; dfInfo* dfi; dfContext* context; - context = ((dfContext*) instance->context); dfi = context->dfi; - if (!gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL)) + if (!gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | + CLRBUF_32BPP, NULL)) return FALSE; gdi = instance->context->gdi; - dfi->err = DirectFBCreate(&(dfi->dfb)); - dfi->dsc.flags = DSDESC_CAPS; dfi->dsc.caps = DSCAPS_PRIMARY; dfi->err = dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->primary)); dfi->err = dfi->primary->GetSize(dfi->primary, &(gdi->width), &(gdi->height)); dfi->dfb->SetVideoMode(dfi->dfb, gdi->width, gdi->height, gdi->dstBpp); - dfi->dfb->CreateInputEventBuffer(dfi->dfb, DICAPS_ALL, DFB_TRUE, &(dfi->event_buffer)); + dfi->dfb->CreateInputEventBuffer(dfi->dfb, DICAPS_ALL, DFB_TRUE, + &(dfi->event_buffer)); dfi->event_buffer->CreateFileDescriptor(dfi->event_buffer, &(dfi->read_fds)); - dfi->dfb->GetDisplayLayer(dfi->dfb, 0, &(dfi->layer)); dfi->layer->EnableCursor(dfi->layer, 1); - - dfi->dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT; + dfi->dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | + DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT; dfi->dsc.caps = DSCAPS_SYSTEMONLY; dfi->dsc.width = gdi->width; dfi->dsc.height = gdi->height; @@ -227,28 +201,26 @@ BOOL df_post_connect(freerdp* instance) dfi->dsc.preallocated[0].data = gdi->primary_buffer; dfi->dsc.preallocated[0].pitch = gdi->width * gdi->bytesPerPixel; dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->surface)); - instance->update->BeginPaint = df_begin_paint; instance->update->EndPaint = df_end_paint; - df_keyboard_init(); - pointer_cache_register_callbacks(instance->update); df_register_graphics(instance->context->graphics); - - return freerdp_channels_post_connect(instance->context->channels, instance) == CHANNEL_RC_OK; + return TRUE; } -BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, + char* fingerprint) { char answer; WLog_INFO(TAG, "Certificate details:"); WLog_INFO(TAG, "\tSubject: %s", subject); WLog_INFO(TAG, "\tIssuer: %s", issuer); WLog_INFO(TAG, "\tThumbprint: %s", fingerprint); - WLog_INFO(TAG, "The above X.509 certificate could not be verified, possibly because you do not have " - "the CA certificate in your certificate store, or the certificate has expired. " - "Please look at the documentation on how to create local certificate store for a private CA."); + WLog_INFO(TAG, + "The above X.509 certificate could not be verified, possibly because you do not have " + "the CA certificate in your certificate store, or the certificate has expired. " + "Please look at the documentation on how to create local certificate store for a private CA."); while (1) { @@ -268,28 +240,28 @@ BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* return FALSE; } -static int df_receive_channel_data(freerdp* instance, UINT16 channelId, BYTE* data, int size, int flags, int total_size) +static int df_receive_channel_data(freerdp* instance, UINT16 channelId, + BYTE* data, int size, int flags, int total_size) { - return freerdp_channels_data(instance, channelId, data, size, flags, total_size); + return freerdp_channels_data(instance, channelId, data, size, flags, + total_size); } -static void df_process_cb_monitor_ready_event(rdpChannels* channels, freerdp* instance) +static void df_process_cb_monitor_ready_event(rdpChannels* channels, + freerdp* instance) { wMessage* event; RDP_CB_FORMAT_LIST_EVENT* format_list_event; - - event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL, NULL); - + event = freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL, + NULL); format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event; format_list_event->num_formats = 0; - freerdp_channels_send_event(channels, event); } static void df_process_channel_event(rdpChannels* channels, freerdp* instance) { wMessage* event; - event = freerdp_channels_pop_event(channels); if (event) @@ -301,7 +273,8 @@ static void df_process_channel_event(rdpChannels* channels, freerdp* instance) break; default: - WLog_ERR(TAG, "df_process_channel_event: unknown event type %d", GetMessageType(event->id)); + WLog_ERR(TAG, "df_process_channel_event: unknown event type %d", + GetMessageType(event->id)); break; } @@ -329,7 +302,6 @@ int dfreerdp_run(freerdp* instance) dfInfo* dfi; dfContext* context; rdpChannels* channels; - ZeroMemory(rfds, sizeof(rfds)); ZeroMemory(wfds, sizeof(wfds)); @@ -337,7 +309,6 @@ int dfreerdp_run(freerdp* instance) return 0; context = (dfContext*) instance->context; - dfi = context->dfi; channels = instance->context->channels; @@ -351,11 +322,14 @@ int dfreerdp_run(freerdp* instance) WLog_ERR(TAG, "Failed to get FreeRDP file descriptor"); break; } - if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) + + if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, + &wcount) != TRUE) { WLog_ERR(TAG, "Failed to get channel manager file descriptor"); break; } + if (df_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { WLog_ERR(TAG, "Failed to get dfreerdp file descriptor"); @@ -383,9 +357,9 @@ int dfreerdp_run(freerdp* instance) { /* these are not really errors */ if (!((errno == EAGAIN) || - (errno == EWOULDBLOCK) || - (errno == EINPROGRESS) || - (errno == EINTR))) /* signal occurred */ + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ { WLog_ERR(TAG, "dfreerdp_run: select failed"); break; @@ -397,29 +371,26 @@ int dfreerdp_run(freerdp* instance) WLog_ERR(TAG, "Failed to check FreeRDP file descriptor"); break; } + if (df_check_fds(instance, &rfds_set) != TRUE) { WLog_ERR(TAG, "Failed to check dfreerdp file descriptor"); break; } + if (freerdp_channels_check_fds(channels, instance) != TRUE) { WLog_ERR(TAG, "Failed to check channel manager file descriptor"); break; } + df_process_channel_event(channels, instance); } - freerdp_channels_disconnect(channels, instance); freerdp_disconnect(instance); - - freerdp_channels_close(channels, instance); - freerdp_channels_free(channels); df_free(dfi); gdi_free(instance); - freerdp_disconnect(instance); freerdp_free(instance); - return 0; } @@ -427,17 +398,13 @@ void* thread_func(void* param) { struct thread_data* data; data = (struct thread_data*) param; - dfreerdp_run(data->instance); - free(data); - pthread_detach(pthread_self()); - g_thread_count--; - if (g_thread_count < 1) - ReleaseSemaphore(g_sem, 1, NULL); + if (g_thread_count < 1) + ReleaseSemaphore(g_sem, 1, NULL); return NULL; } @@ -450,7 +417,6 @@ int main(int argc, char* argv[]) dfContext* context; rdpChannels* channels; struct thread_data* data; - setlocale(LC_ALL, ""); if (!(g_sem = CreateSemaphore(NULL, 0, 1, NULL))) @@ -464,7 +430,6 @@ int main(int argc, char* argv[]) instance->PostConnect = df_post_connect; instance->VerifyCertificate = df_verify_certificate; instance->ReceiveChannelData = df_receive_channel_data; - instance->ContextSize = sizeof(dfContext); instance->ContextNew = df_context_new; instance->ContextFree = df_context_free; @@ -477,25 +442,22 @@ int main(int argc, char* argv[]) context = (dfContext*) instance->context; channels = instance->context->channels; - DirectFBInit(&argc, &argv); - instance->context->argc = argc; instance->context->argv = argv; - - status = freerdp_client_settings_parse_command_line(instance->settings, argc, argv, FALSE); + status = freerdp_client_settings_parse_command_line(instance->settings, argc, + argv, FALSE); if (status < 0) exit(0); - if (!freerdp_client_load_addins(instance->context->channels, instance->settings)) + if (!freerdp_client_load_addins(instance->context->channels, + instance->settings)) exit(-1); data = (struct thread_data*) malloc(sizeof(struct thread_data)); ZeroMemory(data, sizeof(sizeof(struct thread_data))); - data->instance = instance; - g_thread_count++; pthread_create(&thread, 0, thread_func, data); diff --git a/client/Sample/freerdp.c b/client/Sample/freerdp.c index 2e0d92b..2c5f006 100644 --- a/client/Sample/freerdp.c +++ b/client/Sample/freerdp.c @@ -3,6 +3,8 @@ * FreeRDP Test UI * * Copyright 2011 Marc-Andre Moreau + * Copyright 2016 Armin Novak + * Copyright 2016 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,27 +49,18 @@ typedef struct tf_context tfContext; static BOOL tf_context_new(freerdp* instance, rdpContext* context) { - if (!(context->channels = freerdp_channels_new())) - return FALSE; - return TRUE; } static void tf_context_free(freerdp* instance, rdpContext* context) { - if (context && context->channels) - { - freerdp_channels_close(context->channels, instance); - freerdp_channels_free(context->channels); - context->channels = NULL; - } } static BOOL tf_begin_paint(rdpContext* context) { rdpGdi* gdi = context->gdi; - gdi->primary->hdc->hwnd->invalid->null = 1; - return TRUE; + gdi->primary->hdc->hwnd->invalid->null = TRUE; + return TRUE; } static BOOL tf_end_paint(rdpContext* context) @@ -76,16 +69,14 @@ static BOOL tf_end_paint(rdpContext* context) if (gdi->primary->hdc->hwnd->invalid->null) return TRUE; + return TRUE; } static BOOL tf_pre_connect(freerdp* instance) { rdpSettings* settings; - - settings = instance->settings; - settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; @@ -108,22 +99,17 @@ static BOOL tf_pre_connect(freerdp* instance) settings->OrderSupport[NEG_POLYGON_CB_INDEX] = TRUE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = TRUE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = TRUE; - - if (freerdp_channels_pre_connect(instance->context->channels, instance) != CHANNEL_RC_OK) - return FALSE; - return TRUE; } static BOOL tf_post_connect(freerdp* instance) { - if (!gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL)) + if (!gdi_init(instance, PIXEL_FORMAT_XRGB32)) return FALSE; instance->update->BeginPaint = tf_begin_paint; instance->update->EndPaint = tf_end_paint; - - return (freerdp_channels_post_connect(instance->context->channels, instance) == CHANNEL_RC_OK); + return TRUE; } static void* tf_client_thread_proc(freerdp* instance) @@ -144,16 +130,17 @@ static void* tf_client_thread_proc(freerdp* instance) if (nCount == 0) { - WLog_ERR(TAG, "%s: freerdp_get_event_handles failed", __FUNCTION__); - break; + WLog_ERR(TAG, "%s: freerdp_get_event_handles failed", __FUNCTION__); + break; } status = WaitForMultipleObjects(nCount, handles, FALSE, 100); if (status == WAIT_FAILED) { - WLog_ERR(TAG, "%s: WaitForMultipleObjects failed with %lu", __FUNCTION__, status); - break; + WLog_ERR(TAG, "%s: WaitForMultipleObjects failed with %lu", __FUNCTION__, + (unsigned long) status); + break; } if (!freerdp_check_event_handles(instance->context)) @@ -164,7 +151,6 @@ static void* tf_client_thread_proc(freerdp* instance) } freerdp_disconnect(instance); - ExitThread(0); return NULL; } @@ -174,16 +160,16 @@ int main(int argc, char* argv[]) int status; HANDLE thread; freerdp* instance; - instance = freerdp_new(); + if (!instance) { WLog_ERR(TAG, "Couldn't create instance"); exit(1); } + instance->PreConnect = tf_pre_connect; instance->PostConnect = tf_post_connect; - instance->ContextSize = sizeof(tfContext); instance->ContextNew = tf_context_new; instance->ContextFree = tf_context_free; @@ -194,18 +180,20 @@ int main(int argc, char* argv[]) exit(1); } - status = freerdp_client_settings_parse_command_line(instance->settings, argc, argv, FALSE); + status = freerdp_client_settings_parse_command_line(instance->settings, argc, + argv, FALSE); if (status < 0) { exit(0); } - if (!freerdp_client_load_addins(instance->context->channels, instance->settings)) - exit (-1); + if (!freerdp_client_load_addins(instance->context->channels, + instance->settings)) + exit(-1); if (!(thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) - tf_client_thread_proc, instance, 0, NULL))) + tf_client_thread_proc, instance, 0, NULL))) { WLog_ERR(TAG, "Failed to create client thread"); } @@ -216,6 +204,5 @@ int main(int argc, char* argv[]) freerdp_context_free(instance); freerdp_free(instance); - return 0; } diff --git a/client/Wayland/CMakeLists.txt b/client/Wayland/CMakeLists.txt index e95055f..1b81d2e 100644 --- a/client/Wayland/CMakeLists.txt +++ b/client/Wayland/CMakeLists.txt @@ -27,6 +27,8 @@ set(${MODULE_PREFIX}_SRCS wlfreerdp.h wlf_input.c wlf_input.h + wlf_channels.c + wlf_channels.h ) add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) diff --git a/client/Wayland/wlf_channels.c b/client/Wayland/wlf_channels.c new file mode 100644 index 0000000..32cdb6b --- /dev/null +++ b/client/Wayland/wlf_channels.c @@ -0,0 +1,118 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Client Channels + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "wlf_channels.h" +#include "wlfreerdp.h" + +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT wlf_encomsp_participant_created(EncomspClientContext* context, + ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated) +{ + return CHANNEL_RC_OK; +} + +static void wlf_encomsp_init(wlfContext* wlf, EncomspClientContext* encomsp) +{ + if (!wlf) + return; + + wlf->encomsp = encomsp; + encomsp->custom = (void*) wlf; + encomsp->ParticipantCreated = wlf_encomsp_participant_created; +} + +static void wlf_encomsp_uninit(wlfContext* wlf, EncomspClientContext* encomsp) +{ + if (!wlf) + return; + + wlf->encomsp = NULL; +} + + +void wlf_OnChannelConnectedEventHandler(rdpContext* context, + ChannelConnectedEventArgs* e) +{ + wlfContext* wlf = (wlfContext*) context; + rdpSettings* settings = context->settings; + + if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0) + { + wlf->rdpei = (RdpeiClientContext*) e->pInterface; + } + else if (strcmp(e->name, TSMF_DVC_CHANNEL_NAME) == 0) + { + } + else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0) + { + if (settings->SoftwareGdi) + gdi_graphics_pipeline_init(context->gdi, (RdpgfxClientContext*) e->pInterface); + } + else if (strcmp(e->name, RAIL_SVC_CHANNEL_NAME) == 0) + { + } + else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0) + { + } + else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0) + { + wlf_encomsp_init(wlf, (EncomspClientContext*) e->pInterface); + } +} + +void wlf_OnChannelDisconnectedEventHandler(rdpContext* context, + ChannelDisconnectedEventArgs* e) +{ + wlfContext* wlf = (wlfContext*) context; + rdpSettings* settings = context->settings; + + if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0) + { + wlf->rdpei = NULL; + } + else if (strcmp(e->name, TSMF_DVC_CHANNEL_NAME) == 0) + { + } + else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0) + { + if (settings->SoftwareGdi) + gdi_graphics_pipeline_uninit(context->gdi, + (RdpgfxClientContext*) e->pInterface); + } + else if (strcmp(e->name, RAIL_SVC_CHANNEL_NAME) == 0) + { + } + else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0) + { + } + else if (strcmp(e->name, ENCOMSP_SVC_CHANNEL_NAME) == 0) + { + wlf_encomsp_uninit(wlf, (EncomspClientContext*) e->pInterface); + } +} diff --git a/client/Wayland/wlf_channels.h b/client/Wayland/wlf_channels.h new file mode 100644 index 0000000..b0e2ff1 --- /dev/null +++ b/client/Wayland/wlf_channels.h @@ -0,0 +1,42 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Client Channels + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WLF_CHANNELS_H +#define WLF_CHANNELS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +int wlf_on_channel_connected(freerdp* instance, const char* name, + void* pInterface); +int wlf_on_channel_disconnected(freerdp* instance, const char* name, + void* pInterface); + +void wlf_OnChannelConnectedEventHandler(rdpContext* context, + ChannelConnectedEventArgs* e); +void wlf_OnChannelDisconnectedEventHandler(rdpContext* context, + ChannelDisconnectedEventArgs* e); + +#endif diff --git a/client/Wayland/wlf_input.h b/client/Wayland/wlf_input.h index 0529f01..2e26ab8 100644 --- a/client/Wayland/wlf_input.h +++ b/client/Wayland/wlf_input.h @@ -22,14 +22,17 @@ #define __WLF_INPUT_H #include +#include +#include #include -BOOL wlf_handle_pointer_enter(freerdp* instance, UwacPointerEnterLeaveEvent *ev); -BOOL wlf_handle_pointer_motion(freerdp* instance, UwacPointerMotionEvent *ev); -BOOL wlf_handle_pointer_buttons(freerdp* instance, UwacPointerButtonEvent *ev); -BOOL wlf_handle_pointer_axis(freerdp* instance, UwacPointerAxisEvent *ev); +BOOL wlf_handle_pointer_enter(freerdp* instance, + UwacPointerEnterLeaveEvent* ev); +BOOL wlf_handle_pointer_motion(freerdp* instance, UwacPointerMotionEvent* ev); +BOOL wlf_handle_pointer_buttons(freerdp* instance, UwacPointerButtonEvent* ev); +BOOL wlf_handle_pointer_axis(freerdp* instance, UwacPointerAxisEvent* ev); -BOOL wlf_handle_key(freerdp* instance, UwacKeyEvent *ev); -BOOL wlf_keyboard_enter(freerdp *instance, UwacKeyboardEnterLeaveEvent *ev); +BOOL wlf_handle_key(freerdp* instance, UwacKeyEvent* ev); +BOOL wlf_keyboard_enter(freerdp* instance, UwacKeyboardEnterLeaveEvent* ev); #endif /* __WLF_INPUT_H */ diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 1768969..2d5a93b 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -3,6 +3,8 @@ * Wayland Client * * Copyright 2014 Manuel Bachmann + * Copyright 2016 Thincast Technologies GmbH + * Copyright 2016 Armin Novak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,37 +21,23 @@ #include #include +#include #include #include #include +#include +#include + #include +#include + #include "wlfreerdp.h" #include "wlf_input.h" +#include "wlf_channels.h" -UwacDisplay *g_display; -HANDLE g_displayHandle; - -static BOOL wl_context_new(freerdp* instance, rdpContext* context) -{ - if (!(context->channels = freerdp_channels_new())) - return FALSE; - - return TRUE; -} - -static void wl_context_free(freerdp* instance, rdpContext* context) -{ - if (context && context->channels) - { - freerdp_channels_close(context->channels, instance); - freerdp_channels_free(context->channels); - context->channels = NULL; - } -} - -BOOL wl_update_content(wlfContext *context_w) +static BOOL wl_update_content(wlfContext* context_w) { if (!context_w->waitingFrameDone && context_w->haveDamage) { @@ -64,9 +52,8 @@ BOOL wl_update_content(wlfContext *context_w) static BOOL wl_begin_paint(rdpContext* context) { rdpGdi* gdi; - gdi = context->gdi; - gdi->primary->hdc->hwnd->invalid->null = 1; + gdi->primary->hdc->hwnd->invalid->null = TRUE; return TRUE; } @@ -74,13 +61,13 @@ static BOOL wl_begin_paint(rdpContext* context) static BOOL wl_end_paint(rdpContext* context) { rdpGdi* gdi; - char *data; - wlfContext *context_w; + char* data; + wlfContext* context_w; INT32 x, y; UINT32 w, h; int i; - gdi = context->gdi; + if (gdi->primary->hdc->hwnd->invalid->null) return TRUE; @@ -88,18 +75,19 @@ static BOOL wl_end_paint(rdpContext* context) y = gdi->primary->hdc->hwnd->invalid->y; w = gdi->primary->hdc->hwnd->invalid->w; h = gdi->primary->hdc->hwnd->invalid->h; - context_w = (wlfContext*) context; - data = UwacWindowGetDrawingBuffer(context_w->window); + if (!data) return FALSE; for (i = 0; i < h; i++) { - memcpy(data + ((i+y)*(gdi->width*4)) + x*4, - gdi->primary_buffer + ((i+y)*(gdi->width*4)) + x*4, - w*4); + memcpy(data + ((i + y) * (gdi->width * GetBytesPerPixel( + gdi->dstFormat))) + x * GetBytesPerPixel(gdi->dstFormat), + gdi->primary_buffer + ((i + y) * (gdi->width * GetBytesPerPixel( + gdi->dstFormat))) + x * GetBytesPerPixel(gdi->dstFormat), + w * GetBytesPerPixel(gdi->dstFormat)); } if (UwacWindowAddDamage(context_w->window, x, y, w, h) != UWAC_SUCCESS) @@ -112,16 +100,54 @@ static BOOL wl_end_paint(rdpContext* context) static BOOL wl_pre_connect(freerdp* instance) { + rdpSettings* settings; wlfContext* context; - if (freerdp_channels_pre_connect(instance->context->channels, instance) != CHANNEL_RC_OK) + if (!instance) return FALSE; context = (wlfContext*) instance->context; - if (!context) + settings = instance->settings; + + if (!context || !settings) return FALSE; - context->display = g_display; + settings->OsMajorType = OSMAJORTYPE_UNIX; + settings->OsMinorType = OSMINORTYPE_NATIVE_WAYLAND; + settings->SoftwareGdi = TRUE; + ZeroMemory(settings->OrderSupport, 32); + settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; + settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; + settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE; + settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; + settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; + settings->OrderSupport[NEG_MEMBLT_INDEX] = settings->BitmapCacheEnabled; + settings->OrderSupport[NEG_MEM3BLT_INDEX] = TRUE; + settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = settings->BitmapCacheEnabled; + settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE; + settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE; + settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE; + settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE; + settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE; + settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE; + settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; + settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; + settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; + PubSub_SubscribeChannelConnected(instance->context->pubSub, + (pChannelConnectedEventHandler) wlf_OnChannelConnectedEventHandler); + PubSub_SubscribeChannelDisconnected(instance->context->pubSub, + (pChannelDisconnectedEventHandler) wlf_OnChannelDisconnectedEventHandler); + + if (!freerdp_client_load_addins(instance->context->channels, + instance->settings)) + return FALSE; return TRUE; } @@ -132,28 +158,26 @@ static BOOL wl_post_connect(freerdp* instance) UwacWindow* window; wlfContext* context; - if (!gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, NULL)) + if (!gdi_init(instance, PIXEL_FORMAT_BGRA32)) return FALSE; gdi = instance->context->gdi; + if (!gdi) return FALSE; context = (wlfContext*) instance->context; - context->window = window = UwacCreateWindowShm(context->display, gdi->width, gdi->height, WL_SHM_FORMAT_XRGB8888); + context->window = window = UwacCreateWindowShm(context->display, gdi->width, + gdi->height, WL_SHM_FORMAT_XRGB8888); + if (!window) return FALSE; UwacWindowSetTitle(window, "FreeRDP"); - instance->update->BeginPaint = wl_begin_paint; instance->update->EndPaint = wl_end_paint; - - if (freerdp_channels_post_connect(instance->context->channels, instance) != CHANNEL_RC_OK) - return FALSE; - - - memcpy(UwacWindowGetDrawingBuffer(context->window), gdi->primary_buffer, gdi->width * gdi->height * 4); + memcpy(UwacWindowGetDrawingBuffer(context->window), gdi->primary_buffer, + gdi->width * gdi->height * 4); UwacWindowAddDamage(context->window, 0, 0, gdi->width, gdi->height); context->haveDamage = TRUE; return wl_update_content(context); @@ -161,7 +185,8 @@ static BOOL wl_post_connect(freerdp* instance) static void wl_post_disconnect(freerdp* instance) { - wlfContext *context; + wlfContext* context; + if (!instance) return; @@ -169,19 +194,16 @@ static void wl_post_disconnect(freerdp* instance) return; context = (wlfContext*) instance->context; - gdi_free(instance); + if (context->window) UwacDestroyWindow(&context->window); - - if (context->display) - UwacCloseDisplay(&context->display); - } -static BOOL handle_uwac_events(freerdp* instance, UwacDisplay *display) { +static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display) +{ UwacEvent event; - wlfContext *context; + wlfContext* context; if (UwacDisplayDispatch(display, 1) < 0) return FALSE; @@ -192,117 +214,148 @@ static BOOL handle_uwac_events(freerdp* instance, UwacDisplay *display) { return FALSE; /*printf("UWAC event type %d\n", event.type);*/ - switch (event.type) { - case UWAC_EVENT_FRAME_DONE: - if (!instance) - continue; + switch (event.type) + { + case UWAC_EVENT_FRAME_DONE: + if (!instance) + continue; - context = (wlfContext *)instance->context; - context->waitingFrameDone = FALSE; - if (context->haveDamage && !wl_end_paint(instance->context)) - return FALSE; - break; - case UWAC_EVENT_POINTER_ENTER: - if (!wlf_handle_pointer_enter(instance, &event.mouse_enter_leave)) - return FALSE; - break; - case UWAC_EVENT_POINTER_MOTION: - if (!wlf_handle_pointer_motion(instance, &event.mouse_motion)) - return FALSE; - break; - case UWAC_EVENT_POINTER_BUTTONS: - if (!wlf_handle_pointer_buttons(instance, &event.mouse_button)) - return FALSE; - break; - case UWAC_EVENT_POINTER_AXIS: - if (!wlf_handle_pointer_axis(instance, &event.mouse_axis)) - return FALSE; - break; - case UWAC_EVENT_KEY: - if (!wlf_handle_key(instance, &event.key)) - return FALSE; - break; - case UWAC_EVENT_KEYBOARD_ENTER: - if (!wlf_keyboard_enter(instance, &event.keyboard_enter_leave)) - return FALSE; - break; - default: - break; + context = (wlfContext*)instance->context; + context->waitingFrameDone = FALSE; + + if (context->haveDamage && !wl_end_paint(instance->context)) + return FALSE; + + break; + + case UWAC_EVENT_POINTER_ENTER: + if (!wlf_handle_pointer_enter(instance, &event.mouse_enter_leave)) + return FALSE; + + break; + + case UWAC_EVENT_POINTER_MOTION: + if (!wlf_handle_pointer_motion(instance, &event.mouse_motion)) + return FALSE; + + break; + + case UWAC_EVENT_POINTER_BUTTONS: + if (!wlf_handle_pointer_buttons(instance, &event.mouse_button)) + return FALSE; + + break; + + case UWAC_EVENT_POINTER_AXIS: + if (!wlf_handle_pointer_axis(instance, &event.mouse_axis)) + return FALSE; + + break; + + case UWAC_EVENT_KEY: + if (!wlf_handle_key(instance, &event.key)) + return FALSE; + + break; + + case UWAC_EVENT_KEYBOARD_ENTER: + if (!wlf_keyboard_enter(instance, &event.keyboard_enter_leave)) + return FALSE; + + break; + + default: + break; } } + return TRUE; } static int wlfreerdp_run(freerdp* instance) { + wlfContext* context; DWORD count; HANDLE handles[64]; DWORD status; + if (!instance) + return -1; + + context = (wlfContext*)instance->context; + + if (!context) + return -1; + if (!freerdp_connect(instance)) { - printf("Failed to connect\n"); - return -1; + printf("Failed to connect\n"); + return -1; } - handle_uwac_events(instance, g_display); + handle_uwac_events(instance, context->display); while (!freerdp_shall_disconnect(instance)) { - handles[0] = g_displayHandle; - + handles[0] = context->displayHandle; count = freerdp_get_event_handles(instance->context, &handles[1], 63); + if (!count) { printf("Failed to get FreeRDP file descriptor\n"); break; } - status = WaitForMultipleObjects(count+1, handles, FALSE, INFINITE); + status = WaitForMultipleObjects(count + 1, handles, FALSE, INFINITE); + if (WAIT_FAILED == status) { printf("%s: WaitForMultipleObjects failed\n", __FUNCTION__); break; } - if (!handle_uwac_events(instance, g_display)) { + if (!handle_uwac_events(instance, context->display)) + { printf("error handling UWAC events\n"); break; } //if (WaitForMultipleObjects(count, &handles[1], FALSE, INFINITE)) { - if (freerdp_check_event_handles(instance->context) != TRUE) - { - printf("Failed to check FreeRDP file descriptor\n"); - break; - } - //} + if (freerdp_check_event_handles(instance->context) != TRUE) + { + printf("Failed to check FreeRDP file descriptor\n"); + break; + } + //} } - freerdp_channels_disconnect(instance->context->channels, instance); freerdp_disconnect(instance); - return 0; } -int main(int argc, char* argv[]) +static BOOL wlf_client_global_init() +{ + setlocale(LC_ALL, ""); + + if (freerdp_handle_signals() != 0) + return FALSE; + + return TRUE; +} + +static void wlf_client_global_uninit() +{ +} + +static BOOL wlf_client_new(freerdp* instance, rdpContext* context) { UwacReturnCode status; - freerdp* instance; + wlfContext* wfl = (wlfContext*) context; - g_display = UwacOpenDisplay(NULL, &status); - if (!g_display) - exit(1); + if (!instance || !context) + return FALSE; - g_displayHandle = CreateFileDescriptorEvent(NULL, FALSE, FALSE, UwacDisplayGetFd(g_display), WINPR_FD_READ); - if (!g_displayHandle) - exit(1); - - //if (!handle_uwac_events(NULL, g_display)) - // exit(1); - - instance = freerdp_new(); instance->PreConnect = wl_pre_connect; instance->PostConnect = wl_post_connect; instance->PostDisconnect = wl_post_disconnect; @@ -310,28 +363,92 @@ int main(int argc, char* argv[]) instance->GatewayAuthenticate = client_cli_gw_authenticate; instance->VerifyCertificate = client_cli_verify_certificate; instance->VerifyChangedCertificate = client_cli_verify_changed_certificate; + instance->LogonErrorInfo = NULL; + wfl->display = UwacOpenDisplay(NULL, &status); - instance->ContextSize = sizeof(wlfContext); - instance->ContextNew = wl_context_new; - instance->ContextFree = wl_context_free; + if (!wfl->display || (status != UWAC_SUCCESS)) + return FALSE; - freerdp_context_new(instance); + wfl->displayHandle = CreateFileDescriptorEvent(NULL, FALSE, FALSE, + UwacDisplayGetFd(wfl->display), WINPR_FD_READ); - status = freerdp_client_settings_parse_command_line(instance->settings, argc, argv, FALSE); + if (!wfl->displayHandle) + return FALSE; - status = freerdp_client_settings_command_line_status_print(instance->settings, status, argc, argv); + return TRUE; +} - if (status) - exit(0); - if (!freerdp_client_load_addins(instance->context->channels, instance->settings)) - exit(-1); +static void wlf_client_free(freerdp* instance, rdpContext* context) +{ + wlfContext* wlf = (wlfContext*) instance->context; - wlfreerdp_run(instance); + if (!context) + return; - freerdp_context_free(instance); + if (wlf->display) + UwacCloseDisplay(&wlf->display); - freerdp_free(instance); + if (wlf->displayHandle) + CloseHandle(wlf->displayHandle); +} +static int wfl_client_start(rdpContext* context) +{ return 0; } + +static int wfl_client_stop(rdpContext* context) +{ + return 0; +} + +static int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) +{ + ZeroMemory(pEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS)); + pEntryPoints->Version = RDP_CLIENT_INTERFACE_VERSION; + pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1); + pEntryPoints->GlobalInit = wlf_client_global_init; + pEntryPoints->GlobalUninit = wlf_client_global_uninit; + pEntryPoints->ContextSize = sizeof(wlfContext); + pEntryPoints->ClientNew = wlf_client_new; + pEntryPoints->ClientFree = wlf_client_free; + pEntryPoints->ClientStart = wfl_client_start; + pEntryPoints->ClientStop = wfl_client_stop; + return 0; +} + +int main(int argc, char* argv[]) +{ + int rc = -1; + DWORD status; + RDP_CLIENT_ENTRY_POINTS clientEntryPoints; + rdpContext* context; + //if (!handle_uwac_events(NULL, g_display)) + // exit(1); + RdpClientEntry(&clientEntryPoints); + context = freerdp_client_context_new(&clientEntryPoints); + + if (!context) + goto fail; + + status = freerdp_client_settings_parse_command_line(context->settings, argc, + argv, FALSE); + status = freerdp_client_settings_command_line_status_print(context->settings, + status, argc, argv); + + if (status) + return 0; + + if (freerdp_client_start(context) != 0) + goto fail; + + rc = wlfreerdp_run(context->instance); + + if (freerdp_client_stop(context) != 0) + rc = -1; + +fail: + freerdp_client_context_free(context); + return rc; +} diff --git a/client/Wayland/wlfreerdp.h b/client/Wayland/wlfreerdp.h index 575d7e4..f9fe716 100644 --- a/client/Wayland/wlfreerdp.h +++ b/client/Wayland/wlfreerdp.h @@ -20,6 +20,9 @@ #ifndef __WLFREERDP_H #define __WLFREERDP_H +#include +#include +#include #include #include #include @@ -34,11 +37,17 @@ struct wlf_context { rdpContext context; - UwacDisplay *display; - UwacWindow *window; + UwacDisplay* display; + HANDLE displayHandle; + UwacWindow* window; BOOL waitingFrameDone; BOOL haveDamage; + + /* Channels */ + RdpeiClientContext* rdpei; + RdpgfxClientContext* gfx; + EncomspClientContext* encomsp; }; #endif /* __WLFREERDP_H */ diff --git a/client/X11/.gitignore b/client/X11/.gitignore index de7ef22..2f903d6 100644 --- a/client/X11/.gitignore +++ b/client/X11/.gitignore @@ -1,2 +1,2 @@ -*.xml +xfreerdp-argument.1.xml generate_argument_docbook diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 82e7f2e..3bd5b0a 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -93,16 +93,19 @@ if(WITH_MANPAGES) add_custom_command(OUTPUT xfreerdp.1 COMMAND generate_argument_docbook - COMMAND ${CMAKE_COMMAND} -E copy + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E copy + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${XSLTPROC_EXECUTABLE} ${DOCBOOKXSL_DIR}/manpages/docbook.xsl xfreerdp.1.xml + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-envvar.1.xml ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${XSLTPROC_EXECUTABLE} ${DOCBOOKXSL_DIR}/manpages/docbook.xsl xfreerdp.1.xml WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1.xml ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml + ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-envvar.1.xml generate_argument_docbook) add_custom_target(xfreerdp.manpage ALL diff --git a/client/X11/generate_argument_docbook.c b/client/X11/generate_argument_docbook.c index 22abed3..1d54c43 100644 --- a/client/X11/generate_argument_docbook.c +++ b/client/X11/generate_argument_docbook.c @@ -146,13 +146,25 @@ int main(int argc, char *argv[]) const char *format = tr_esc_str(arg->Format); const char *text = tr_esc_str((LPSTR) arg->Text); fprintf(fp, "\t\t\t\n"); - if(COMMAND_LINE_VALUE_REQUIRED == arg->Flags) - fprintf(fp, "\t\t\t\t %s\n", name, format); - else - fprintf(fp, "\t\t\t\t\n", name); - fprintf(fp, "\t\t\t\t\n"); - fprintf(fp, "\t\t\t\t\t%s\n", format); - fprintf(fp, "\t\t\t\t\n"); + + fprintf(fp, "\t\t\t\t", name); + if ((arg->Flags == COMMAND_LINE_VALUE_REQUIRED) && format) + fprintf(fp, " %s\n", format); + fprintf(fp, "\n"); + + if (format || text) + { + fprintf(fp, "\t\t\t\t\n"); + fprintf(fp, "\t\t\t\t\t%s\n", format ? format : ""); + if (text) + { + if (format) + fprintf(fp, " - "); + fprintf(fp, "%s", text); + } + fprintf(fp, "\n"); + fprintf(fp, "\t\t\t\t\n"); + } fprintf(fp, "\t\t\t\n"); free((void*) name); free((void*) format); diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 16c1a58..461b868 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -6,6 +6,8 @@ * Copyright 2013 Corey Clayton * Copyright 2014 Thincast Technologies GmbH * Copyright 2014 Norbert Federa + * Copyright 2016 Armin Novak + * Copyright 2016 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -120,6 +122,7 @@ static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h) double yScalingFactor; int x2; int y2; + rdpSettings* settings = xfc->context.settings; if (xfc->scaledWidth <= 0 || xfc->scaledHeight <= 0) { @@ -127,18 +130,16 @@ static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h) return; } - if (xfc->sessionWidth <= 0 || xfc->sessionHeight <= 0) + if (settings->DesktopWidth <= 0 || settings->DesktopHeight <= 0) { WLog_ERR(TAG, "the window dimensions are invalid"); return; } - xScalingFactor = xfc->sessionWidth / (double)xfc->scaledWidth; - yScalingFactor = xfc->sessionHeight / (double)xfc->scaledHeight; - + xScalingFactor = settings->DesktopWidth / (double)xfc->scaledWidth; + yScalingFactor = settings->DesktopHeight / (double)xfc->scaledHeight; XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, 0); - /* Black out possible space between desktop and window borders */ { XRectangle box1 = { 0, 0, xfc->window->width, xfc->window->height }; @@ -151,22 +152,21 @@ static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h) if (XSubtractRegion(reg1, reg2, reg1) && !XEmptyRegion(reg1)) { XSetRegion(xfc->display, xfc->gc, reg1); - XFillRectangle(xfc->display, xfc->window->handle, xfc->gc, 0, 0, xfc->window->width, xfc->window->height); + XFillRectangle(xfc->display, xfc->window->handle, xfc->gc, 0, 0, + xfc->window->width, xfc->window->height); XSetClipMask(xfc->display, xfc->gc, None); } XDestroyRegion(reg1); XDestroyRegion(reg2); } - picFormat = XRenderFindVisualFormat(xfc->display, xfc->visual); - pa.subwindow_mode = IncludeInferiors; - primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, CPSubwindowMode, &pa); - windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, picFormat, CPSubwindowMode, &pa); - + primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, + CPSubwindowMode, &pa); + windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, + picFormat, CPSubwindowMode, &pa); XRenderSetPictureFilter(xfc->display, primaryPicture, FilterBilinear, 0, 0); - transform.matrix[0][0] = XDoubleToFixed(xScalingFactor); transform.matrix[0][1] = XDoubleToFixed(0.0); transform.matrix[0][2] = XDoubleToFixed(0.0); @@ -176,7 +176,6 @@ static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h) transform.matrix[2][0] = XDoubleToFixed(0.0); transform.matrix[2][1] = XDoubleToFixed(0.0); transform.matrix[2][2] = XDoubleToFixed(1.0); - /* calculate and fix up scaled coordinates */ x2 = x + w; y2 = y + h; @@ -184,18 +183,20 @@ static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h) y = floor(y / yScalingFactor) - 1; w = ceil(x2 / xScalingFactor) + 1 - x; h = ceil(y2 / yScalingFactor) + 1 - y; - XRenderSetPictureTransform(xfc->display, primaryPicture, &transform); - XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, x, y, 0, 0, xfc->offset_x + x, xfc->offset_y + y, w, h); + XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, x, + y, 0, 0, xfc->offset_x + x, xfc->offset_y + y, w, h); XRenderFreePicture(xfc->display, primaryPicture); XRenderFreePicture(xfc->display, windowPicture); } BOOL xf_picture_transform_required(xfContext* xfc) { + rdpSettings* settings = xfc->context.settings; + if (xfc->offset_x || xfc->offset_y || - xfc->scaledWidth != xfc->sessionWidth || - xfc->scaledHeight != xfc->sessionHeight) + xfc->scaledWidth != settings->DesktopWidth || + xfc->scaledHeight != settings->DesktopHeight) { return TRUE; } @@ -213,71 +214,86 @@ void xf_draw_screen(xfContext* xfc, int x, int y, int w, int h) } #ifdef WITH_XRENDER - if (xf_picture_transform_required(xfc)) { + + if (xf_picture_transform_required(xfc)) + { xf_draw_screen_scaled(xfc, x, y, w, h); return; } + #endif - XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y); + XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, + x, y); } static BOOL xf_desktop_resize(rdpContext* context) { rdpSettings* settings; xfContext* xfc = (xfContext*) context; - settings = xfc->settings; + settings = context->settings; if (xfc->primary) { BOOL same = (xfc->primary == xfc->drawing) ? TRUE : FALSE; XFreePixmap(xfc->display, xfc->primary); - if (!(xfc->primary = XCreatePixmap(xfc->display, xfc->drawable, xfc->sessionWidth, xfc->sessionHeight, xfc->depth))) + + if (!(xfc->primary = XCreatePixmap( + xfc->display, xfc->drawable, + settings->DesktopWidth, + settings->DesktopHeight, xfc->depth))) return FALSE; + if (same) xfc->drawing = xfc->primary; } #ifdef WITH_XRENDER - if (!xfc->settings->SmartSizing) + + if (!xfc->context.settings->SmartSizing) { - xfc->scaledWidth = xfc->sessionWidth; - xfc->scaledHeight = xfc->sessionHeight; + xfc->scaledWidth = settings->DesktopWidth; + xfc->scaledHeight = settings->DesktopHeight; } + #endif if (!xfc->fullscreen) { - xf_ResizeDesktopWindow(xfc, xfc->window, settings->DesktopWidth, settings->DesktopHeight); + xf_ResizeDesktopWindow(xfc, xfc->window, settings->DesktopWidth, + settings->DesktopHeight); } else { #ifdef WITH_XRENDER - if (!xfc->settings->SmartSizing) + + if (!xfc->context.settings->SmartSizing) #endif { /* Update the saved width and height values the window will be * resized to when toggling out of fullscreen */ - xfc->savedWidth = xfc->sessionWidth; - xfc->savedHeight = xfc->sessionHeight; + xfc->savedWidth = settings->DesktopWidth; + xfc->savedHeight = settings->DesktopHeight; } + XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, 0); - XFillRectangle(xfc->display, xfc->drawable, xfc->gc, 0, 0, xfc->window->width, xfc->window->height); + XFillRectangle(xfc->display, xfc->drawable, xfc->gc, 0, 0, xfc->window->width, + xfc->window->height); } return TRUE; } -BOOL xf_sw_begin_paint(rdpContext* context) +static BOOL xf_sw_begin_paint(rdpContext* context) { rdpGdi* gdi = context->gdi; - gdi->primary->hdc->hwnd->invalid->null = 1; + gdi->primary->hdc->hwnd->invalid->null = TRUE; gdi->primary->hdc->hwnd->ninvalid = 0; return TRUE; } -BOOL xf_sw_end_paint(rdpContext* context) +static BOOL xf_sw_end_paint(rdpContext* context) { int i; INT32 x, y; @@ -286,12 +302,10 @@ BOOL xf_sw_end_paint(rdpContext* context) HGDI_RGN cinvalid; xfContext* xfc = (xfContext*) context; rdpGdi* gdi = context->gdi; - x = gdi->primary->hdc->hwnd->invalid->x; y = gdi->primary->hdc->hwnd->invalid->y; w = gdi->primary->hdc->hwnd->invalid->w; h = gdi->primary->hdc->hwnd->invalid->h; - ninvalid = gdi->primary->hdc->hwnd->ninvalid; cinvalid = gdi->primary->hdc->hwnd->cinvalid; @@ -303,11 +317,9 @@ BOOL xf_sw_end_paint(rdpContext* context) return TRUE; xf_lock_x11(xfc, FALSE); - - XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h); - + XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, + x, y, x, y, w, h); xf_draw_screen(xfc, x, y, w, h); - xf_unlock_x11(xfc, FALSE); } else @@ -323,14 +335,12 @@ BOOL xf_sw_end_paint(rdpContext* context) y = cinvalid[i].y; w = cinvalid[i].w; h = cinvalid[i].h; - - XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h); - + XPutImage(xfc->display, xfc->primary, xfc->gc, + xfc->image, x, y, x, y, w, h); xf_draw_screen(xfc, x, y, w, h); } XFlush(xfc->display); - xf_unlock_x11(xfc, FALSE); } } @@ -340,56 +350,52 @@ BOOL xf_sw_end_paint(rdpContext* context) return TRUE; xf_lock_x11(xfc, FALSE); - xf_rail_paint(xfc, x, y, x + w, y + h); - xf_unlock_x11(xfc, FALSE); } + return TRUE; } -BOOL xf_sw_desktop_resize(rdpContext* context) +static BOOL xf_sw_desktop_resize(rdpContext* context) { rdpGdi* gdi = context->gdi; xfContext* xfc = (xfContext*) context; + rdpSettings* settings = context->settings; BOOL ret = FALSE; - xf_lock_x11(xfc, TRUE); - xfc->sessionWidth = context->settings->DesktopWidth; - xfc->sessionHeight = context->settings->DesktopHeight; - - if (!gdi_resize(gdi, xfc->sessionWidth, xfc->sessionHeight)) + if (!gdi_resize(gdi, settings->DesktopWidth, settings->DesktopHeight)) goto out; if (xfc->image) { xfc->image->data = NULL; XDestroyImage(xfc->image); + } - if (!(xfc->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char*) gdi->primary_buffer, gdi->width, gdi->height, xfc->scanline_pad, 0))) - { - goto out; - } + if (!(xfc->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, + 0, + (char*) gdi->primary_buffer, gdi->width, gdi->height, xfc->scanline_pad, 0))) + { + goto out; } ret = xf_desktop_resize(context); - out: xf_unlock_x11(xfc, TRUE); return ret; } -BOOL xf_hw_begin_paint(rdpContext* context) +static BOOL xf_hw_begin_paint(rdpContext* context) { xfContext* xfc = (xfContext*) context; - xfc->hdc->hwnd->invalid->null = 1; + xfc->hdc->hwnd->invalid->null = TRUE; xfc->hdc->hwnd->ninvalid = 0; return TRUE; } -BOOL xf_hw_end_paint(rdpContext* context) +static BOOL xf_hw_end_paint(rdpContext* context) { INT32 x, y; UINT32 w, h; @@ -406,11 +412,8 @@ BOOL xf_hw_end_paint(rdpContext* context) y = xfc->hdc->hwnd->invalid->y; w = xfc->hdc->hwnd->invalid->w; h = xfc->hdc->hwnd->invalid->h; - xf_lock_x11(xfc, FALSE); - xf_draw_screen(xfc, x, y, w, h); - xf_unlock_x11(xfc, FALSE); } else @@ -424,7 +427,6 @@ BOOL xf_hw_end_paint(rdpContext* context) ninvalid = xfc->hdc->hwnd->ninvalid; cinvalid = xfc->hdc->hwnd->cinvalid; - xf_lock_x11(xfc, FALSE); for (i = 0; i < ninvalid; i++) @@ -433,12 +435,10 @@ BOOL xf_hw_end_paint(rdpContext* context) y = cinvalid[i].y; w = cinvalid[i].w; h = cinvalid[i].h; - xf_draw_screen(xfc, x, y, w, h); } XFlush(xfc->display); - xf_unlock_x11(xfc, FALSE); } } @@ -451,48 +451,37 @@ BOOL xf_hw_end_paint(rdpContext* context) y = xfc->hdc->hwnd->invalid->y; w = xfc->hdc->hwnd->invalid->w; h = xfc->hdc->hwnd->invalid->h; - xf_lock_x11(xfc, FALSE); - xf_rail_paint(xfc, x, y, x + w, y + h); - xf_unlock_x11(xfc, FALSE); } + return TRUE; } -BOOL xf_hw_desktop_resize(rdpContext* context) +static BOOL xf_hw_desktop_resize(rdpContext* context) { + rdpGdi* gdi = context->gdi; xfContext* xfc = (xfContext*) context; - rdpSettings* settings = xfc->settings; - BOOL ret; - + rdpSettings* settings = context->settings; + BOOL ret = FALSE; xf_lock_x11(xfc, TRUE); - xfc->sessionWidth = settings->DesktopWidth; - xfc->sessionHeight = settings->DesktopHeight; + if (!gdi_resize(gdi, settings->DesktopWidth, settings->DesktopHeight)) + goto out; ret = xf_desktop_resize(context); - +out: xf_unlock_x11(xfc, TRUE); return ret; } -BOOL xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) -{ - xfContext* xfc = (xfContext*) instance->context; - rfds[*rcount] = (void*)(long)(xfc->xfds); - (*rcount)++; - return TRUE; -} - -BOOL xf_process_x_events(freerdp* instance) +static BOOL xf_process_x_events(freerdp* instance) { BOOL status; XEvent xevent; int pending_status; xfContext* xfc = (xfContext*) instance->context; - status = TRUE; pending_status = TRUE; @@ -506,13 +495,13 @@ BOOL xf_process_x_events(freerdp* instance) { ZeroMemory(&xevent, sizeof(xevent)); XNextEvent(xfc->display, &xevent); - status = xf_event_process(instance, &xevent); if (!status) return status; } } + return status; } @@ -522,15 +511,16 @@ BOOL xf_create_window(xfContext* xfc) XEvent xevent; int width, height; char* windowTitle; - rdpSettings* settings = xfc->settings; - + rdpGdi* gdi; + rdpSettings* settings; + settings = xfc->context.settings; + gdi = xfc->context.gdi; ZeroMemory(&xevent, sizeof(xevent)); - - width = xfc->sessionWidth; - height = xfc->sessionHeight; + width = settings->DesktopWidth; + height = settings->DesktopHeight; if (!xfc->hdc) - if (!(xfc->hdc = gdi_CreateDC(CLRBUF_32BPP, xfc->bpp))) + if (!(xfc->hdc = gdi_CreateDC(gdi->dstFormat))) return FALSE; if (!xfc->remote_app) @@ -542,7 +532,6 @@ BOOL xf_create_window(xfContext* xfc) xfc->attribs.colormap = xfc->colormap; xfc->attribs.bit_gravity = NorthWestGravity; xfc->attribs.win_gravity = NorthWestGravity; - #ifdef WITH_XRENDER xfc->offset_x = 0; xfc->offset_y = 0; @@ -551,42 +540,46 @@ BOOL xf_create_window(xfContext* xfc) if (settings->WindowTitle) { windowTitle = _strdup(settings->WindowTitle); + if (!windowTitle) return FALSE; } else if (settings->ServerPort == 3389) { - windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(settings->ServerHostname)); + windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen( + settings->ServerHostname)); sprintf(windowTitle, "FreeRDP: %s", settings->ServerHostname); } else { - windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(settings->ServerHostname) + sizeof(":00000")); - sprintf(windowTitle, "FreeRDP: %s:%i", settings->ServerHostname, settings->ServerPort); + windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(settings->ServerHostname) + + sizeof(":00000")); + sprintf(windowTitle, "FreeRDP: %s:%i", settings->ServerHostname, + settings->ServerPort); } #ifdef WITH_XRENDER + if (settings->SmartSizing && !xfc->fullscreen) { if (settings->SmartSizingWidth) width = settings->SmartSizingWidth; + if (settings->SmartSizingHeight) height = settings->SmartSizingHeight; xfc->scaledWidth = width; xfc->scaledHeight = height; } + #endif - xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height); - free(windowTitle); if (xfc->fullscreen) xf_SetWindowFullscreen(xfc, xfc->window, xfc->fullscreen); xfc->unobscured = (xevent.xvisibility.state == VisibilityUnobscured); - XSetWMProtocols(xfc->display, xfc->window->handle, &(xfc->WM_DELETE_WINDOW), 1); xfc->drawable = xfc->window->handle; } @@ -601,28 +594,46 @@ BOOL xf_create_window(xfContext* xfc) XFreeModifiermap(xfc->modifierMap); xfc->modifierMap = XGetModifierMapping(xfc->display); + if (!xfc->gc) xfc->gc = XCreateGC(xfc->display, xfc->drawable, GCGraphicsExposures, &gcv); + if (!xfc->primary) - xfc->primary = XCreatePixmap(xfc->display, xfc->drawable, xfc->sessionWidth, xfc->sessionHeight, xfc->depth); + xfc->primary = XCreatePixmap(xfc->display, xfc->drawable, + settings->DesktopWidth, + settings->DesktopHeight, xfc->depth); + xfc->drawing = xfc->primary; + if (!xfc->bitmap_mono) xfc->bitmap_mono = XCreatePixmap(xfc->display, xfc->drawable, 8, 8, 1); + if (!xfc->gc_mono) - xfc->gc_mono = XCreateGC(xfc->display, xfc->bitmap_mono, GCGraphicsExposures, &gcv); + xfc->gc_mono = XCreateGC(xfc->display, xfc->bitmap_mono, GCGraphicsExposures, + &gcv); + XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, BlackPixelOfScreen(xfc->screen)); - XFillRectangle(xfc->display, xfc->primary, xfc->gc, 0, 0, xfc->sessionWidth, xfc->sessionHeight); + XFillRectangle(xfc->display, xfc->primary, xfc->gc, 0, 0, + settings->DesktopWidth, + settings->DesktopHeight); XFlush(xfc->display); + if (!xfc->image) - xfc->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char*) xfc->primary_buffer, xfc->sessionWidth, xfc->sessionHeight, xfc->scanline_pad, 0); + { + rdpGdi* gdi = xfc->context.gdi; + xfc->image = XCreateImage(xfc->display, xfc->visual, + xfc->depth, + ZPixmap, 0, (char*) gdi->primary_buffer, + settings->DesktopWidth, settings->DesktopHeight, + xfc->scanline_pad, 0); + } return TRUE; } -void xf_window_free(xfContext* xfc) +static void xf_window_free(xfContext* xfc) { if (xfc->gc_mono) { @@ -648,13 +659,6 @@ void xf_window_free(xfContext* xfc) xfc->xv_context = NULL; } - if (xfc->bitmap_buffer) - { - _aligned_free(xfc->bitmap_buffer); - xfc->bitmap_buffer = NULL; - xfc->bitmap_size = 0; - } - if (xfc->image) { xfc->image->data = NULL; @@ -692,12 +696,9 @@ void xf_toggle_fullscreen(xfContext* xfc) WindowStateChangeEventArgs e; rdpContext* context = (rdpContext*) xfc; rdpSettings* settings = context->settings; - xfc->fullscreen = (xfc->fullscreen) ? FALSE : TRUE; xfc->decorations = (xfc->fullscreen) ? FALSE : settings->Decorations; - xf_SetWindowFullscreen(xfc, xfc->window, xfc->fullscreen); - EventArgsInit(&e, "xfreerdp"); e.state = xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0; PubSub_OnWindowStateChange(context->pubSub, context, &e); @@ -707,7 +708,6 @@ void xf_toggle_control(xfContext* xfc) { EncomspClientContext* encomsp; ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu; - encomsp = xfc->encomsp; if (!encomsp) @@ -720,7 +720,6 @@ void xf_toggle_control(xfContext* xfc) pdu.Flags |= ENCOMSP_REQUEST_INTERACT; encomsp->ChangeParticipantControlLevel(encomsp, &pdu); - xfc->controlToggle = !xfc->controlToggle; } @@ -729,7 +728,8 @@ void xf_toggle_control(xfContext* xfc) * * @return 0 on success, otherwise a Win32 error code */ -UINT xf_encomsp_participant_created(EncomspClientContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated) +static UINT xf_encomsp_participant_created(EncomspClientContext* context, + ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated) { return CHANNEL_RC_OK; } @@ -738,7 +738,6 @@ void xf_encomsp_init(xfContext* xfc, EncomspClientContext* encomsp) { xfc->encomsp = encomsp; encomsp->custom = (void*) xfc; - encomsp->ParticipantCreated = xf_encomsp_participant_created; } @@ -782,14 +781,14 @@ static void xf_calculate_color_shifts(UINT32 mask, UINT8* rsh, UINT8* lsh) (*rsh)--; } -BOOL xf_get_pixmap_info(xfContext* xfc) +static BOOL xf_get_pixmap_info(xfContext* xfc) { int i; int vi_count; int pf_count; XVisualInfo* vi; XVisualInfo* vis; - XVisualInfo template; + XVisualInfo tpl; XPixmapFormatValues* pf; XPixmapFormatValues* pfs; XWindowAttributes window_attributes; @@ -808,25 +807,25 @@ BOOL xf_get_pixmap_info(xfContext* xfc) if (pf->depth == xfc->depth) { - xfc->bpp = pf->bits_per_pixel; xfc->scanline_pad = pf->scanline_pad; break; } } XFree(pfs); + ZeroMemory(&tpl, sizeof(tpl)); + tpl.class = TrueColor; + tpl.screen = xfc->screen_number; - ZeroMemory(&template, sizeof(template)); - template.class = TrueColor; - template.screen = xfc->screen_number; - - if (XGetWindowAttributes(xfc->display, RootWindowOfScreen(xfc->screen), &window_attributes) == 0) + if (XGetWindowAttributes(xfc->display, RootWindowOfScreen(xfc->screen), + &window_attributes) == 0) { WLog_ERR(TAG, "XGetWindowAttributes failed"); return FALSE; } - vis = XGetVisualInfo(xfc->display, VisualClassMask | VisualScreenMask, &template, &vi_count); + vis = XGetVisualInfo(xfc->display, VisualClassMask | VisualScreenMask, + &tpl, &vi_count); if (!vis) { @@ -839,6 +838,7 @@ BOOL xf_get_pixmap_info(xfContext* xfc) for (i = 0; i < vi_count; i++) { vi = vis + i; + if (vi->visual == window_attributes.visual) { xfc->visual = vi->visual; @@ -849,9 +849,9 @@ BOOL xf_get_pixmap_info(xfContext* xfc) if (xfc->visual) { /* - * Detect if the server visual has an inverted colormap - * (BGR vs RGB, or red being the least significant byte) - */ + * Detect if the server visual has an inverted colormap + * (BGR vs RGB, or red being the least significant byte) + */ if (vi->red_mask & 0xFF) { xfc->invert = TRUE; @@ -859,8 +859,10 @@ BOOL xf_get_pixmap_info(xfContext* xfc) /* calculate color shifts required for rdp order color conversion */ xf_calculate_color_shifts(vi->red_mask, &xfc->red_shift_r, &xfc->red_shift_l); - xf_calculate_color_shifts(vi->green_mask, &xfc->green_shift_r, &xfc->green_shift_l); - xf_calculate_color_shifts(vi->blue_mask, &xfc->blue_shift_r, &xfc->blue_shift_l); + xf_calculate_color_shifts(vi->green_mask, &xfc->green_shift_r, + &xfc->green_shift_l); + xf_calculate_color_shifts(vi->blue_mask, &xfc->blue_shift_r, + &xfc->blue_shift_l); } XFree(vis); @@ -873,24 +875,21 @@ BOOL xf_get_pixmap_info(xfContext* xfc) return TRUE; } -int xf_error_handler(Display* d, XErrorEvent* ev) +static int xf_error_handler(Display* d, XErrorEvent* ev) { char buf[256]; - int do_abort = TRUE; XGetErrorText(d, ev->error_code, buf, sizeof(buf)); - WLog_ERR(TAG, "%s", buf); if (do_abort) abort(); _def_error_handler(d, ev); - return FALSE; } -int _xf_error_handler(Display* d, XErrorEvent* ev) +static int _xf_error_handler(Display* d, XErrorEvent* ev) { /* * ungrab the keyboard, in case a debugger is running in @@ -901,21 +900,23 @@ int _xf_error_handler(Display* d, XErrorEvent* ev) return xf_error_handler(d, ev); } -static BOOL xf_play_sound(rdpContext* context, PLAY_SOUND_UPDATE* play_sound) +static BOOL xf_play_sound(rdpContext* context, + const PLAY_SOUND_UPDATE* play_sound) { xfContext* xfc = (xfContext*) context; XkbBell(xfc->display, None, 100, 0); return TRUE; } -void xf_check_extensions(xfContext* context) +static void xf_check_extensions(xfContext* context) { int xkb_opcode, xkb_event, xkb_error; int xkb_major = XkbMajorVersion; int xkb_minor = XkbMinorVersion; - if (XkbLibraryVersion(&xkb_major, &xkb_minor) && XkbQueryExtension(context->display, &xkb_opcode, &xkb_event, - &xkb_error, &xkb_major, &xkb_minor)) + if (XkbLibraryVersion(&xkb_major, &xkb_minor) + && XkbQueryExtension(context->display, &xkb_opcode, &xkb_event, + &xkb_error, &xkb_major, &xkb_minor)) { context->xkbAvailable = TRUE; } @@ -926,7 +927,7 @@ void xf_check_extensions(xfContext* context) int xrender_error_base; if (XRenderQueryExtension(context->display, &xrender_event_base, - &xrender_error_base)) + &xrender_error_base)) { context->xrenderAvailable = TRUE; } @@ -938,13 +939,13 @@ void xf_check_extensions(xfContext* context) /* Input device which does NOT have the correct mapping. We must disregard */ /* this device when trying to find the input device which is the pointer. */ static const char TEST_PTR_STR [] = "Virtual core XTEST pointer"; -static const size_t TEST_PTR_LEN = sizeof (TEST_PTR_STR) / sizeof (char); +static const size_t TEST_PTR_LEN = sizeof(TEST_PTR_STR) / sizeof(char); /* Invalid device identifier which indicate failure. */ static const int INVALID_XID = -1; #endif /* WITH_XI */ -static void xf_get_x11_button_map (xfContext* xfc, unsigned char* x11_map) +static void xf_get_x11_button_map(xfContext* xfc, unsigned char* x11_map) { #ifdef WITH_XI int opcode, event, error; @@ -955,57 +956,64 @@ static void xf_get_x11_button_map (xfContext* xfc, unsigned char* x11_map) XIDeviceInfo* devices2; int i, num_devices; - if (XQueryExtension (xfc->display, "XInputExtension", &opcode, &event, &error)) + if (XQueryExtension(xfc->display, "XInputExtension", &opcode, &event, &error)) { WLog_DBG(TAG, "Searching for XInput pointer device"); xid = INVALID_XID; /* loop through every device, looking for a pointer */ - version = XGetExtensionVersion (xfc->display, INAME); + version = XGetExtensionVersion(xfc->display, INAME); + if (version->major_version >= 2) { /* XID of pointer device using XInput version 2 */ - devices2 = XIQueryDevice (xfc->display, XIAllDevices, &num_devices); + devices2 = XIQueryDevice(xfc->display, XIAllDevices, &num_devices); + if (devices2) { for (i = 0; i < num_devices; ++i) { if ((devices2[i].use == XISlavePointer) && - (strncmp (devices2[i].name, TEST_PTR_STR, TEST_PTR_LEN) != 0)) + (strncmp(devices2[i].name, TEST_PTR_STR, TEST_PTR_LEN) != 0)) { xid = devices2[i].deviceid; break; } } - XIFreeDeviceInfo (devices2); + + XIFreeDeviceInfo(devices2); } } else { /* XID of pointer device using XInput version 1 */ - devices1 = XListInputDevices (xfc->display, &num_devices); + devices1 = XListInputDevices(xfc->display, &num_devices); + if (devices1) { for (i = 0; i < num_devices; ++i) { if ((devices1[i].use == IsXExtensionPointer) && - (strncmp (devices1[i].name, TEST_PTR_STR, TEST_PTR_LEN) != 0)) + (strncmp(devices1[i].name, TEST_PTR_STR, TEST_PTR_LEN) != 0)) { xid = devices1[i].id; break; } } - XFreeDeviceList (devices1); + + XFreeDeviceList(devices1); } } - XFree (version); + + XFree(version); + /* get button mapping from input extension if there is a pointer device; */ /* otherwise leave unchanged. */ if (xid != INVALID_XID) { WLog_DBG(TAG, "Pointer device: %d", xid); - ptr_dev = XOpenDevice (xfc->display, xid); - XGetDeviceButtonMapping (xfc->display, ptr_dev, x11_map, NUM_BUTTONS_MAPPED); - XCloseDevice (xfc->display, ptr_dev); + ptr_dev = XOpenDevice(xfc->display, xid); + XGetDeviceButtonMapping(xfc->display, ptr_dev, x11_map, NUM_BUTTONS_MAPPED); + XCloseDevice(xfc->display, ptr_dev); } else { @@ -1016,36 +1024,37 @@ static void xf_get_x11_button_map (xfContext* xfc, unsigned char* x11_map) #endif /* WITH_XI */ { WLog_DBG(TAG, "Get global pointer mapping (no XInput)"); - XGetPointerMapping (xfc->display, x11_map, NUM_BUTTONS_MAPPED); + XGetPointerMapping(xfc->display, x11_map, NUM_BUTTONS_MAPPED); } } /* Assignment of physical (not logical) mouse buttons to wire flags. */ /* Notice that the middle button is 2 in X11, but 3 in RDP. */ -static const int xf_button_flags[NUM_BUTTONS_MAPPED] = { +static const int xf_button_flags[NUM_BUTTONS_MAPPED] = +{ PTR_FLAGS_BUTTON1, PTR_FLAGS_BUTTON3, PTR_FLAGS_BUTTON2 }; -static void xf_button_map_init (xfContext* xfc) +static void xf_button_map_init(xfContext* xfc) { /* loop counter for array initialization */ int physical; int logical; - /* logical mouse button which is used for each physical mouse */ /* button (indexed from zero). This is the default map. */ - unsigned char x11_map[NUM_BUTTONS_MAPPED] = { + unsigned char x11_map[NUM_BUTTONS_MAPPED] = + { Button1, Button2, Button3 }; /* query system for actual remapping */ - if (!xfc->settings->UnmapButtons) + if (!xfc->context.settings->UnmapButtons) { - xf_get_x11_button_map (xfc, x11_map); + xf_get_x11_button_map(xfc, x11_map); } /* iterate over all (mapped) physical buttons; for each of them */ @@ -1054,29 +1063,30 @@ static void xf_button_map_init (xfContext* xfc) for (physical = 0; physical < NUM_BUTTONS_MAPPED; ++physical) { logical = x11_map[physical]; + if (Button1 <= logical && logical <= Button3) { - xfc->button_map[logical-BUTTON_BASE] = xf_button_flags[physical]; + xfc->button_map[logical - BUTTON_BASE] = xf_button_flags[physical]; } else { - WLog_ERR(TAG,"Mouse physical button %d is mapped to logical button %d", - physical, logical); + WLog_ERR(TAG, "Mouse physical button %d is mapped to logical button %d", + physical, logical); } } } /** - * Callback given to freerdp_connect() to process the pre-connect operations. - * It will fill the rdp_freerdp structure (instance) with the appropriate options to use for the connection. - * - * @param instance - pointer to the rdp_freerdp structure that contains the connection's parameters, and will - * be filled with the appropriate informations. - * - * @return TRUE if successful. FALSE otherwise. - * Can exit with error code XF_EXIT_PARSE_ARGUMENTS if there is an error in the parameters. - */ -BOOL xf_pre_connect(freerdp* instance) +* Callback given to freerdp_connect() to process the pre-connect operations. +* It will fill the rdp_freerdp structure (instance) with the appropriate options to use for the connection. +* +* @param instance - pointer to the rdp_freerdp structure that contains the connection's parameters, and will +* be filled with the appropriate informations. +* +* @return TRUE if successful. FALSE otherwise. +* Can exit with error code XF_EXIT_PARSE_ARGUMENTS if there is an error in the parameters. +*/ +static BOOL xf_pre_connect(freerdp* instance) { rdpChannels* channels; rdpSettings* settings; @@ -1084,18 +1094,10 @@ BOOL xf_pre_connect(freerdp* instance) xfContext* xfc = (xfContext*) instance->context; UINT32 maxWidth = 0; UINT32 maxHeight = 0; - - - xfc->codecs = context->codecs; - xfc->settings = instance->settings; - xfc->instance = instance; - settings = instance->settings; channels = context->channels; - settings->OsMajorType = OSMAJORTYPE_UNIX; settings->OsMinorType = OSMINORTYPE_NATIVE_XSERVER; - ZeroMemory(settings->OrderSupport, 32); settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; @@ -1110,29 +1112,25 @@ BOOL xf_pre_connect(freerdp* instance) settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_INDEX] = settings->BitmapCacheEnabled; - settings->OrderSupport[NEG_MEM3BLT_INDEX] = (settings->SoftwareGdi) ? TRUE : FALSE; + settings->OrderSupport[NEG_MEM3BLT_INDEX] = settings->BitmapCacheEnabled; settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = settings->BitmapCacheEnabled; - settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE; + settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = settings->BitmapCacheEnabled; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE; - settings->OrderSupport[NEG_POLYGON_SC_INDEX] = (settings->SoftwareGdi) ? FALSE : TRUE; - settings->OrderSupport[NEG_POLYGON_CB_INDEX] = (settings->SoftwareGdi) ? FALSE : TRUE; + settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE; + settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; - PubSub_SubscribeChannelConnected(instance->context->pubSub, - (pChannelConnectedEventHandler) xf_OnChannelConnectedEventHandler); + (pChannelConnectedEventHandler) xf_OnChannelConnectedEventHandler); PubSub_SubscribeChannelDisconnected(instance->context->pubSub, - (pChannelDisconnectedEventHandler) xf_OnChannelDisconnectedEventHandler); + (pChannelDisconnectedEventHandler) xf_OnChannelDisconnectedEventHandler); if (!freerdp_client_load_addins(channels, instance->settings)) return FALSE; - if (freerdp_channels_pre_connect(channels, instance) != CHANNEL_RC_OK) - return FALSE; - if (!settings->Username && !settings->CredentialsFromStdin) { char* login_name = getlogin(); @@ -1140,8 +1138,10 @@ BOOL xf_pre_connect(freerdp* instance) if (login_name) { settings->Username = _strdup(login_name); + if (!settings->Username) return FALSE; + WLog_INFO(TAG, "No user name set. - Using login name: %s", settings->Username); } } @@ -1158,12 +1158,6 @@ BOOL xf_pre_connect(freerdp* instance) WLog_INFO(TAG, "Authentication only. Don't connect to X."); } - if (!context->cache) - { - if (!(context->cache = cache_new(settings))) - return FALSE; - } - if (!xf_keyboard_init(xfc)) return FALSE; @@ -1176,86 +1170,70 @@ BOOL xf_pre_connect(freerdp* instance) } #ifdef WITH_XRENDER + /** * If /f is specified in combination with /smart-sizing:widthxheight then * we run the session in the /smart-sizing dimensions scaled to full screen */ if (settings->Fullscreen && settings->SmartSizing && - settings->SmartSizingWidth && settings->SmartSizingHeight) + settings->SmartSizingWidth && settings->SmartSizingHeight) { settings->DesktopWidth = settings->SmartSizingWidth; settings->DesktopHeight = settings->SmartSizingHeight; } -#endif +#endif xfc->fullscreen = settings->Fullscreen; xfc->decorations = settings->Decorations; xfc->grab_keyboard = settings->GrabKeyboard; xfc->fullscreen_toggle = settings->ToggleFullscreen; - xf_button_map_init (xfc); - + xf_button_map_init(xfc); return TRUE; } /** - * Callback given to freerdp_connect() to perform post-connection operations. - * It will be called only if the connection was initialized properly, and will continue the initialization based on the - * newly created connection. - */ -BOOL xf_post_connect(freerdp* instance) +* Callback given to freerdp_connect() to perform post-connection operations. +* It will be called only if the connection was initialized properly, and will continue the initialization based on the +* newly created connection. +*/ +static BOOL xf_post_connect(freerdp* instance) { - UINT32 flags; - rdpCache* cache; rdpUpdate* update; rdpContext* context; rdpChannels* channels; rdpSettings* settings; ResizeWindowEventArgs e; xfContext* xfc = (xfContext*) instance->context; - context = instance->context; - cache = context->cache; channels = context->channels; settings = instance->settings; update = context->update; - if (!xf_register_graphics(context->graphics)) - { - WLog_ERR(TAG, "failed to register graphics"); + if (!gdi_init(instance, xf_get_local_color_format(xfc, TRUE))) return FALSE; - } - flags = CLRCONV_ALPHA; + if (!xf_register_pointer(context->graphics)) + return FALSE; - if (xfc->bpp > 16) - flags |= CLRBUF_32BPP; - else - flags |= CLRBUF_16BPP; - - if (settings->SoftwareGdi) + if (!settings->SoftwareGdi) { - rdpGdi* gdi; - - if (!gdi_init(instance, flags, NULL)) + if (!xf_register_graphics(context->graphics)) + { + WLog_ERR(TAG, "failed to register graphics"); return FALSE; + } - gdi = context->gdi; - xfc->primary_buffer = gdi->primary_buffer; - xfc->palette = gdi->palette; - } - else - { - xfc->palette = xfc->palette_hwgdi; - xfc->srcBpp = settings->ColorDepth; xf_gdi_register_update_callbacks(update); + brush_cache_register_callbacks(instance->update); + glyph_cache_register_callbacks(instance->update); + bitmap_cache_register_callbacks(instance->update); + offscreen_cache_register_callbacks(instance->update); + palette_cache_register_callbacks(instance->update); } - xfc->sessionWidth = settings->DesktopWidth; - xfc->sessionHeight = settings->DesktopHeight; - #ifdef WITH_XRENDER - xfc->scaledWidth = xfc->sessionWidth; - xfc->scaledHeight = xfc->sessionHeight; + xfc->scaledWidth = settings->DesktopWidth; + xfc->scaledHeight = settings->DesktopHeight; xfc->offset_x = 0; xfc->offset_y = 0; #endif @@ -1298,31 +1276,16 @@ BOOL xf_post_connect(freerdp* instance) } pointer_cache_register_callbacks(update); - - if (!settings->SoftwareGdi) - { - glyph_cache_register_callbacks(update); - brush_cache_register_callbacks(update); - bitmap_cache_register_callbacks(update); - offscreen_cache_register_callbacks(update); - palette_cache_register_callbacks(update); - update->BitmapUpdate = xf_gdi_bitmap_update; - } - update->PlaySound = xf_play_sound; update->SetKeyboardIndicators = xf_keyboard_set_indicators; if (!(xfc->clipboard = xf_clipboard_new(xfc))) return FALSE; - if (freerdp_channels_post_connect(channels, instance) != CHANNEL_RC_OK) - return FALSE; - EventArgsInit(&e, "xfreerdp"); e.width = settings->DesktopWidth; e.height = settings->DesktopHeight; PubSub_OnResizeWindow(context->pubSub, xfc, &e); - return TRUE; } @@ -1336,9 +1299,6 @@ static void xf_post_disconnect(freerdp* instance) context = instance->context; xfc = (xfContext*) context; - - freerdp_channels_disconnect(context->channels, instance); - gdi_free(instance); if (xfc->clipboard) @@ -1348,28 +1308,21 @@ static void xf_post_disconnect(freerdp* instance) } xf_window_free(xfc); - - if (context->cache) - { - cache_free(context->cache); - context->cache = NULL; - } - xf_keyboard_free(xfc); } -int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type) +static int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type) { xfContext* xfc = (xfContext*) instance->context; xf_rail_disable_remoteapp_mode(xfc); return 1; } -void* xf_input_thread(void* arg) +static void* xf_input_thread(void* arg) { DWORD status; DWORD nCount; - HANDLE events[2]; + HANDLE events[3]; XEvent xevent; wMessage msg; wMessageQueue* queue; @@ -1377,12 +1330,11 @@ void* xf_input_thread(void* arg) int process_status = 1; freerdp* instance = (freerdp*) arg; xfContext* xfc = (xfContext*) instance->context; - queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); - nCount = 0; events[nCount++] = MessageQueue_Event(queue); events[nCount++] = xfc->x11event; + events[nCount++] = instance->context->abortEvent; while (1) { @@ -1408,12 +1360,9 @@ void* xf_input_thread(void* arg) if (pending_status) { xf_lock_x11(xfc, FALSE); - ZeroMemory(&xevent, sizeof(xevent)); XNextEvent(xfc->display, &xevent); - process_status = xf_event_process(instance, &xevent); - xf_unlock_x11(xfc, FALSE); if (!process_status) @@ -1424,7 +1373,11 @@ void* xf_input_thread(void* arg) if (!process_status) break; + } + if (WaitForSingleObject(events[2], 0) == WAIT_OBJECT_0) + { + break; } } @@ -1433,13 +1386,11 @@ void* xf_input_thread(void* arg) return NULL; } -BOOL xf_auto_reconnect(freerdp* instance) +static BOOL xf_auto_reconnect(freerdp* instance) { UINT32 maxRetries; UINT32 numRetries = 0; - xfContext* xfc = (xfContext*) instance->context; - rdpSettings* settings = xfc->settings; - + rdpSettings* settings = instance->settings; maxRetries = settings->AutoReconnectMaxRetries; /* Only auto reconnect on network disconnects. */ @@ -1469,7 +1420,7 @@ BOOL xf_auto_reconnect(freerdp* instance) if (freerdp_reconnect(instance)) { - xfc->disconnect = FALSE; + freerdp_abort_connect(instance); return TRUE; } @@ -1477,18 +1428,17 @@ BOOL xf_auto_reconnect(freerdp* instance) } WLog_ERR(TAG, "Maximum reconnect retries exceeded"); - return FALSE; } /** Main loop for the rdp connection. - * It will be run from the thread's entry point (thread_func()). - * It initiates the connection, and will continue to run until the session ends, - * processing events as they are received. - * @param instance - pointer to the rdp_freerdp structure that contains the session's settings - * @return A code from the enum XF_EXIT_CODE (0 if successful) - */ -void* xf_client_thread(void* param) +* It will be run from the thread's entry point (thread_func()). +* It initiates the connection, and will continue to run until the session ends, +* processing events as they are received. +* @param instance - pointer to the rdp_freerdp structure that contains the session's settings +* @return A code from the enum XF_EXIT_CODE (0 if successful) +*/ +static void* xf_client_thread(void* param) { BOOL status; int exit_code; @@ -1502,28 +1452,28 @@ void* xf_client_thread(void* param) HANDLE inputThread = NULL; rdpChannels* channels; rdpSettings* settings; - exit_code = 0; instance = (freerdp*) param; context = instance->context; - status = freerdp_connect(instance); - xfc = (xfContext*) instance->context; /* --authonly ? */ if (instance->settings->AuthenticationOnly) { WLog_ERR(TAG, "Authentication only, exit status %d", !status); + if (!status) { - if (freerdp_get_last_error(instance->context) == FREERDP_ERROR_AUTHENTICATION_FAILED) + if (freerdp_get_last_error(instance->context) == + FREERDP_ERROR_AUTHENTICATION_FAILED) exit_code = XF_EXIT_AUTH_FAILURE; else exit_code = XF_EXIT_CONN_FAILED; } else exit_code = XF_EXIT_SUCCESS; + goto disconnect; } @@ -1531,10 +1481,13 @@ void* xf_client_thread(void* param) { WLog_ERR(TAG, "Freerdp connect error exit status %d", !status); exit_code = freerdp_error_info(instance); - if (freerdp_get_last_error(instance->context) == FREERDP_ERROR_AUTHENTICATION_FAILED) + + if (freerdp_get_last_error(instance->context) == + FREERDP_ERROR_AUTHENTICATION_FAILED) exit_code = XF_EXIT_AUTH_FAILURE; else exit_code = XF_EXIT_CONN_FAILED; + goto disconnect; } @@ -1544,16 +1497,12 @@ void* xf_client_thread(void* param) if (!settings->AsyncInput) { inputEvent = xfc->x11event; + handles[0] = inputEvent; } else { - if (!(inputEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE))) - { - WLog_ERR(TAG, "async input: failed to get input event handle"); - exit_code = XF_EXIT_UNKNOWN; - goto disconnect; - } - if (!(inputThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_input_thread, instance, 0, NULL))) + if (!(inputThread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) xf_input_thread, instance, 0, NULL))) { WLog_ERR(TAG, "async input: failed to create input thread"); exit_code = XF_EXIT_UNKNOWN; @@ -1561,21 +1510,20 @@ void* xf_client_thread(void* param) } } - while (!xfc->disconnect && !freerdp_shall_disconnect(instance)) + while (!freerdp_shall_disconnect(instance)) { /* - * win8 and server 2k12 seem to have some timing issue/race condition - * when a initial sync request is send to sync the keyboard indicators - * sending the sync event twice fixed this problem - */ + * win8 and server 2k12 seem to have some timing issue/race condition + * when a initial sync request is send to sync the keyboard indicators + * sending the sync event twice fixed this problem + */ if (freerdp_focus_required(instance)) { xf_keyboard_focus_in(xfc); xf_keyboard_focus_in(xfc); } - nCount = 0; - handles[nCount++] = inputEvent; + nCount = (settings->AsyncInput) ? 0 : 1; if (!settings->AsyncTransport) { @@ -1612,25 +1560,11 @@ void* xf_client_thread(void* param) break; } } - else - { - if (WaitForSingleObject(inputEvent, 0) == WAIT_OBJECT_0) - { - if (!freerdp_message_queue_process_pending_messages(instance, FREERDP_INPUT_MESSAGE_QUEUE)) - { - WLog_INFO(TAG, "User Disconnect"); - xfc->disconnect = TRUE; - break; - } - } - } } if (settings->AsyncInput) { - wMessageQueue* inputQueue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); - if (MessageQueue_PostQuit(inputQueue, 0)) - WaitForSingleObject(inputThread, INFINITE); + WaitForSingleObject(inputThread, INFINITE); CloseHandle(inputThread); } @@ -1645,7 +1579,8 @@ disconnect: DWORD xf_exit_code_from_disconnect_reason(DWORD reason) { - if (reason == 0 || (reason >= XF_EXIT_PARSE_ARGUMENTS && reason <= XF_EXIT_AUTH_FAILURE)) + if (reason == 0 || (reason >= XF_EXIT_PARSE_ARGUMENTS + && reason <= XF_EXIT_AUTH_FAILURE)) return reason; /* License error set */ else if (reason >= 0x100 && reason <= 0x10A) @@ -1660,29 +1595,17 @@ DWORD xf_exit_code_from_disconnect_reason(DWORD reason) return reason; } -void xf_TerminateEventHandler(rdpContext* context, TerminateEventArgs* e) +static void xf_TerminateEventHandler(rdpContext* context, TerminateEventArgs* e) { - wMessageQueue* queue; - - xfContext* xfc = (xfContext*) context; - - if (context->settings->AsyncInput) - { - queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE); - - if (queue) - MessageQueue_PostQuit(queue, 0); - } - else - { - xfc->disconnect = TRUE; - } + freerdp_abort_connect(context->instance); } #ifdef WITH_XRENDER -static void xf_ZoomingChangeEventHandler(rdpContext* context, ZoomingChangeEventArgs* e) +static void xf_ZoomingChangeEventHandler(rdpContext* context, + ZoomingChangeEventArgs* e) { xfContext* xfc = (xfContext*) context; + rdpSettings* settings = context->settings; int w = xfc->scaledWidth + e->dx; int h = xfc->scaledHeight + e->dy; @@ -1700,39 +1623,40 @@ static void xf_ZoomingChangeEventHandler(rdpContext* context, ZoomingChangeEvent xfc->scaledWidth = w; xfc->scaledHeight = h; - - xf_draw_screen(xfc, 0, 0, xfc->sessionWidth, xfc->sessionHeight); + xf_draw_screen(xfc, 0, 0, settings->DesktopWidth, settings->DesktopHeight); } -static void xf_PanningChangeEventHandler(rdpContext* context, PanningChangeEventArgs* e) +static void xf_PanningChangeEventHandler(rdpContext* context, + PanningChangeEventArgs* e) { xfContext* xfc = (xfContext*) context; + rdpSettings* settings = context->settings; if (e->dx == 0 && e->dy == 0) return; xfc->offset_x += e->dx; xfc->offset_y += e->dy; - - xf_draw_screen(xfc, 0, 0, xfc->sessionWidth, xfc->sessionHeight); + xf_draw_screen(xfc, 0, 0, settings->DesktopWidth, settings->DesktopHeight); } #endif /** - * Client Interface - */ +* Client Interface +*/ static BOOL xfreerdp_client_global_init() { setlocale(LC_ALL, ""); + if (freerdp_handle_signals() != 0) return FALSE; + return TRUE; } static void xfreerdp_client_global_uninit() { - } static int xfreerdp_client_start(rdpContext* context) @@ -1742,15 +1666,14 @@ static int xfreerdp_client_start(rdpContext* context) if (!settings->ServerHostname) { - WLog_ERR(TAG, "error: server hostname was not specified with /v:[:port]"); + WLog_ERR(TAG, + "error: server hostname was not specified with /v:[:port]"); return -1; } - xfc->disconnect = FALSE; - if (!(xfc->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) xf_client_thread, - context->instance, 0, NULL))) + (LPTHREAD_START_ROUTINE) xf_client_thread, + context->instance, 0, NULL))) { WLog_ERR(TAG, "failed to create client thread"); return -1; @@ -1762,20 +1685,7 @@ static int xfreerdp_client_start(rdpContext* context) static int xfreerdp_client_stop(rdpContext* context) { xfContext* xfc = (xfContext*) context; - - if (context->settings->AsyncInput) - { - wMessageQueue* queue; - - queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE); - - if (queue) - MessageQueue_PostQuit(queue, 0); - } - else - { - xfc->disconnect = TRUE; - } + freerdp_abort_connect(context->instance); if (xfc->thread) { @@ -1791,17 +1701,11 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) { rdpSettings* settings; xfContext* xfc = (xfContext*) instance->context; - assert(context); assert(xfc); - assert(!context->channels); assert(!xfc->display); assert(!xfc->mutex); assert(!xfc->x11event); - - if (!(context->channels = freerdp_channels_new())) - goto fail_channels_new; - instance->PreConnect = xf_pre_connect; instance->PostConnect = xf_post_connect; instance->PostDisconnect = xf_post_disconnect; @@ -1810,18 +1714,17 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) instance->VerifyCertificate = client_cli_verify_certificate; instance->VerifyChangedCertificate = client_cli_verify_changed_certificate; instance->LogonErrorInfo = xf_logon_error_info; - settings = instance->settings; - xfc->settings = instance->context->settings; - - PubSub_SubscribeTerminate(context->pubSub, (pTerminateEventHandler) xf_TerminateEventHandler); - + PubSub_SubscribeTerminate(context->pubSub, + (pTerminateEventHandler) xf_TerminateEventHandler); #ifdef WITH_XRENDER - PubSub_SubscribeZoomingChange(context->pubSub, (pZoomingChangeEventHandler) xf_ZoomingChangeEventHandler); - PubSub_SubscribePanningChange(context->pubSub, (pPanningChangeEventHandler) xf_PanningChangeEventHandler); + PubSub_SubscribeZoomingChange(context->pubSub, + (pZoomingChangeEventHandler) xf_ZoomingChangeEventHandler); + PubSub_SubscribePanningChange(context->pubSub, + (pPanningChangeEventHandler) xf_PanningChangeEventHandler); #endif - xfc->UseXThreads = TRUE; + //xfc->debug = TRUE; if (xfc->UseXThreads) { @@ -1837,7 +1740,8 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) if (!xfc->display) { WLog_ERR(TAG, "failed to open display: %s", XDisplayName(NULL)); - WLog_ERR(TAG, "Please check that the $DISPLAY environment variable is properly set."); + WLog_ERR(TAG, + "Please check that the $DISPLAY environment variable is properly set."); goto fail_open_display; } @@ -1851,40 +1755,54 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) xfc->_NET_WM_ICON = XInternAtom(xfc->display, "_NET_WM_ICON", False); xfc->_MOTIF_WM_HINTS = XInternAtom(xfc->display, "_MOTIF_WM_HINTS", False); - xfc->_NET_CURRENT_DESKTOP = XInternAtom(xfc->display, "_NET_CURRENT_DESKTOP", False); + xfc->_NET_CURRENT_DESKTOP = XInternAtom(xfc->display, "_NET_CURRENT_DESKTOP", + False); xfc->_NET_WORKAREA = XInternAtom(xfc->display, "_NET_WORKAREA", False); xfc->_NET_WM_STATE = XInternAtom(xfc->display, "_NET_WM_STATE", False); - xfc->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfc->display, "_NET_WM_STATE_FULLSCREEN", False); - xfc->_NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); - xfc->_NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False); - xfc->_NET_WM_FULLSCREEN_MONITORS = XInternAtom(xfc->display, "_NET_WM_FULLSCREEN_MONITORS", False); + xfc->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfc->display, + "_NET_WM_STATE_FULLSCREEN", False); + xfc->_NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(xfc->display, + "_NET_WM_STATE_MAXIMIZED_HORZ", False); + xfc->_NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(xfc->display, + "_NET_WM_STATE_MAXIMIZED_VERT", False); + xfc->_NET_WM_FULLSCREEN_MONITORS = XInternAtom(xfc->display, + "_NET_WM_FULLSCREEN_MONITORS", False); xfc->_NET_WM_NAME = XInternAtom(xfc->display, "_NET_WM_NAME", False); xfc->_NET_WM_PID = XInternAtom(xfc->display, "_NET_WM_PID", False); - xfc->_NET_WM_WINDOW_TYPE = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE", False); - xfc->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_NORMAL", False); - xfc->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_DIALOG", False); - xfc->_NET_WM_WINDOW_TYPE_POPUP = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_POPUP", False); - xfc->_NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_UTILITY", False); - xfc->_NET_WM_WINDOW_TYPE_DROPDOWN_MENU = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False); - xfc->_NET_WM_STATE_SKIP_TASKBAR = XInternAtom(xfc->display, "_NET_WM_STATE_SKIP_TASKBAR", False); - xfc->_NET_WM_STATE_SKIP_PAGER = XInternAtom(xfc->display, "_NET_WM_STATE_SKIP_PAGER", False); - xfc->_NET_WM_MOVERESIZE = XInternAtom(xfc->display, "_NET_WM_MOVERESIZE", False); - xfc->_NET_MOVERESIZE_WINDOW = XInternAtom(xfc->display, "_NET_MOVERESIZE_WINDOW", False); - + xfc->_NET_WM_WINDOW_TYPE = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE", + False); + xfc->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfc->display, + "_NET_WM_WINDOW_TYPE_NORMAL", False); + xfc->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfc->display, + "_NET_WM_WINDOW_TYPE_DIALOG", False); + xfc->_NET_WM_WINDOW_TYPE_POPUP = XInternAtom(xfc->display, + "_NET_WM_WINDOW_TYPE_POPUP", False); + xfc->_NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(xfc->display, + "_NET_WM_WINDOW_TYPE_UTILITY", False); + xfc->_NET_WM_WINDOW_TYPE_DROPDOWN_MENU = XInternAtom(xfc->display, + "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False); + xfc->_NET_WM_STATE_SKIP_TASKBAR = XInternAtom(xfc->display, + "_NET_WM_STATE_SKIP_TASKBAR", False); + xfc->_NET_WM_STATE_SKIP_PAGER = XInternAtom(xfc->display, + "_NET_WM_STATE_SKIP_PAGER", False); + xfc->_NET_WM_MOVERESIZE = XInternAtom(xfc->display, "_NET_WM_MOVERESIZE", + False); + xfc->_NET_MOVERESIZE_WINDOW = XInternAtom(xfc->display, + "_NET_MOVERESIZE_WINDOW", False); xfc->UTF8_STRING = XInternAtom(xfc->display, "UTF8_STRING", FALSE); xfc->WM_PROTOCOLS = XInternAtom(xfc->display, "WM_PROTOCOLS", False); xfc->WM_DELETE_WINDOW = XInternAtom(xfc->display, "WM_DELETE_WINDOW", False); xfc->WM_STATE = XInternAtom(xfc->display, "WM_STATE", False); - xfc->xfds = ConnectionNumber(xfc->display); xfc->screen_number = DefaultScreen(xfc->display); xfc->screen = ScreenOfDisplay(xfc->display, xfc->screen_number); xfc->depth = DefaultDepthOfScreen(xfc->screen); xfc->big_endian = (ImageByteOrder(xfc->display) == MSBFirst); - xfc->invert = (ImageByteOrder(xfc->display) == MSBFirst) ? TRUE : FALSE; + xfc->invert = (ImageByteOrder(xfc->display) == MSBFirst) ? FALSE : TRUE; xfc->complex_regions = TRUE; + xfc->x11event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds, + WINPR_FD_READ); - xfc->x11event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds, WINPR_FD_READ); if (!xfc->x11event) { WLog_ERR(TAG, "Could not create xfds event"); @@ -1892,18 +1810,6 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) } xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number); - xfc->format = PIXEL_FORMAT_XRGB32; - - if (xfc->depth == 32) - xfc->format = (!xfc->invert) ? PIXEL_FORMAT_XRGB32 : PIXEL_FORMAT_XBGR32; - else if (xfc->depth == 24) - xfc->format = (!xfc->invert) ? PIXEL_FORMAT_XRGB32 : PIXEL_FORMAT_XBGR32; - else if (xfc->depth == 16) - xfc->format = (!xfc->invert) ? PIXEL_FORMAT_RGB565 : PIXEL_FORMAT_BGR565; - else if (xfc->depth == 15) - xfc->format = (!xfc->invert) ? PIXEL_FORMAT_RGB555 : PIXEL_FORMAT_BGR555; - else - xfc->format = PIXEL_FORMAT_XRGB32; if (xfc->debug) { @@ -1926,7 +1832,6 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) goto fail_vscreen_monitors; return TRUE; - fail_vscreen_monitors: fail_pixmap_info: CloseHandle(xfc->x11event); @@ -1938,9 +1843,6 @@ fail_create_mutex: XCloseDisplay(xfc->display); xfc->display = NULL; fail_open_display: - freerdp_channels_free(context->channels); - context->channels = NULL; -fail_channels_new: return FALSE; } @@ -1951,13 +1853,6 @@ static void xfreerdp_client_free(freerdp* instance, rdpContext* context) if (!context) return; - if (context->channels) - { - freerdp_channels_close(context->channels, instance); - freerdp_channels_free(context->channels); - context->channels = NULL; - } - if (xfc->display) { XCloseDisplay(xfc->display); @@ -1972,7 +1867,6 @@ static void xfreerdp_client_free(freerdp* instance, rdpContext* context) if (xfc->mutex) { - WaitForSingleObject(xfc->mutex, INFINITE); CloseHandle(xfc->mutex); xfc->mutex = NULL; } diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 569f448..d62ddd4 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -124,17 +124,17 @@ static void xf_cliprdr_check_owner(xfClipboard* clipboard) static BOOL xf_cliprdr_is_self_owned(xfClipboard* clipboard) { xfContext* xfc = clipboard->xfc; - - return XGetSelectionOwner(xfc->display, clipboard->clipboard_atom) == xfc->drawable; + return XGetSelectionOwner(xfc->display, + clipboard->clipboard_atom) == xfc->drawable; } -static void xf_cliprdr_set_raw_transfer_enabled(xfClipboard* clipboard, BOOL enabled) +static void xf_cliprdr_set_raw_transfer_enabled(xfClipboard* clipboard, + BOOL enabled) { UINT32 data = enabled; xfContext* xfc = clipboard->xfc; - XChangeProperty(xfc->display, xfc->drawable, clipboard->raw_transfer_atom, - XA_INTEGER, 32, PropModeReplace, (BYTE*) &data, 1); + XA_INTEGER, 32, PropModeReplace, (BYTE*) &data, 1); } static BOOL xf_cliprdr_is_raw_transfer_available(xfClipboard* clipboard) @@ -148,14 +148,13 @@ static BOOL xf_cliprdr_is_raw_transfer_available(xfClipboard* clipboard) UINT32 is_enabled = 0; Window owner = None; xfContext* xfc = clipboard->xfc; - owner = XGetSelectionOwner(xfc->display, clipboard->clipboard_atom); if (owner != None) { result = XGetWindowProperty(xfc->display, owner, - clipboard->raw_transfer_atom, 0, 4, 0, XA_INTEGER, - &type, &format, &length, &bytes_left, (BYTE**) &data); + clipboard->raw_transfer_atom, 0, 4, 0, XA_INTEGER, + &type, &format, &length, &bytes_left, (BYTE**) &data); } if (data) @@ -173,12 +172,14 @@ static BOOL xf_cliprdr_is_raw_transfer_available(xfClipboard* clipboard) return is_enabled ? TRUE : FALSE; } -static BOOL xf_cliprdr_formats_equal(const CLIPRDR_FORMAT* server, const xfCliprdrFormat* client) +static BOOL xf_cliprdr_formats_equal(const CLIPRDR_FORMAT* server, + const xfCliprdrFormat* client) { if (server->formatName && client->formatName) { /* The server may be using short format names while we store them in full form. */ - return (0 == strncmp(server->formatName, client->formatName, strlen(server->formatName))); + return (0 == strncmp(server->formatName, client->formatName, + strlen(server->formatName))); } if (!server->formatName && !client->formatName) @@ -189,7 +190,8 @@ static BOOL xf_cliprdr_formats_equal(const CLIPRDR_FORMAT* server, const xfClipr return FALSE; } -static xfCliprdrFormat* xf_cliprdr_get_client_format_by_id(xfClipboard* clipboard, UINT32 formatId) +static xfCliprdrFormat* xf_cliprdr_get_client_format_by_id( + xfClipboard* clipboard, UINT32 formatId) { int index; xfCliprdrFormat* format; @@ -205,7 +207,8 @@ static xfCliprdrFormat* xf_cliprdr_get_client_format_by_id(xfClipboard* clipboar return NULL; } -static xfCliprdrFormat* xf_cliprdr_get_client_format_by_atom(xfClipboard* clipboard, Atom atom) +static xfCliprdrFormat* xf_cliprdr_get_client_format_by_atom( + xfClipboard* clipboard, Atom atom) { int i; xfCliprdrFormat* format; @@ -221,7 +224,8 @@ static xfCliprdrFormat* xf_cliprdr_get_client_format_by_atom(xfClipboard* clipbo return NULL; } -static CLIPRDR_FORMAT* xf_cliprdr_get_server_format_by_atom(xfClipboard* clipboard, Atom atom) +static CLIPRDR_FORMAT* xf_cliprdr_get_server_format_by_atom( + xfClipboard* clipboard, Atom atom) { int i, j; xfCliprdrFormat* client_format; @@ -251,15 +255,14 @@ static CLIPRDR_FORMAT* xf_cliprdr_get_server_format_by_atom(xfClipboard* clipboa * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_cliprdr_send_data_request(xfClipboard* clipboard, UINT32 formatId) +static UINT xf_cliprdr_send_data_request(xfClipboard* clipboard, + UINT32 formatId) { CLIPRDR_FORMAT_DATA_REQUEST request; - ZeroMemory(&request, sizeof(CLIPRDR_FORMAT_DATA_REQUEST)); - request.requestedFormatId = formatId; - - return clipboard->context->ClientFormatDataRequest(clipboard->context, &request); + return clipboard->context->ClientFormatDataRequest(clipboard->context, + &request); } /** @@ -267,17 +270,16 @@ static UINT xf_cliprdr_send_data_request(xfClipboard* clipboard, UINT32 formatId * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_cliprdr_send_data_response(xfClipboard* clipboard, BYTE* data, int size) +static UINT xf_cliprdr_send_data_response(xfClipboard* clipboard, BYTE* data, + int size) { CLIPRDR_FORMAT_DATA_RESPONSE response; - ZeroMemory(&response, sizeof(CLIPRDR_FORMAT_DATA_RESPONSE)); - response.msgFlags = (data) ? CB_RESPONSE_OK : CB_RESPONSE_FAIL; response.dataLen = size; response.requestedFormatData = data; - - return clipboard->context->ClientFormatDataResponse(clipboard->context, &response); + return clipboard->context->ClientFormatDataResponse(clipboard->context, + &response); } static wStream* xf_cliprdr_serialize_server_format_list(xfClipboard* clipboard) @@ -294,8 +296,8 @@ static wStream* xf_cliprdr_serialize_server_format_list(xfClipboard* clipboard) } /* If present, the last format is always synthetic CF_RAW. Do not include it. */ - formatCount = (clipboard->numServerFormats > 0) ? clipboard->numServerFormats - 1 : 0; - + formatCount = (clipboard->numServerFormats > 0) ? clipboard->numServerFormats - + 1 : 0; Stream_Write_UINT32(s, formatCount); for (i = 0; i < formatCount; i++) @@ -315,15 +317,14 @@ static wStream* xf_cliprdr_serialize_server_format_list(xfClipboard* clipboard) } Stream_SealLength(s); - return s; - error: Stream_Free(s, TRUE); return NULL; } -static CLIPRDR_FORMAT* xf_cliprdr_parse_server_format_list(BYTE* data, size_t length, UINT32* numFormats) +static CLIPRDR_FORMAT* xf_cliprdr_parse_server_format_list(BYTE* data, + size_t length, UINT32* numFormats) { UINT32 i; wStream* s = NULL; @@ -367,13 +368,13 @@ static CLIPRDR_FORMAT* xf_cliprdr_parse_server_format_list(BYTE* data, size_t le } Stream_Read_UINT32(s, formats[i].formatId); - formatName = (const char*) Stream_Pointer(s); formatNameLength = strnlen(formatName, Stream_GetRemainingLength(s)); if (formatNameLength == Stream_GetRemainingLength(s)) { - WLog_ERR(TAG, "missing terminating null byte, %zu bytes left to read", formatNameLength); + WLog_ERR(TAG, "missing terminating null byte, %zu bytes left to read", + formatNameLength); goto error; } @@ -382,9 +383,7 @@ static CLIPRDR_FORMAT* xf_cliprdr_parse_server_format_list(BYTE* data, size_t le } Stream_Free(s, FALSE); - return formats; - error: Stream_Free(s, FALSE); free(formats); @@ -404,7 +403,8 @@ static void xf_cliprdr_free_formats(CLIPRDR_FORMAT* formats, UINT32 numFormats) free(formats); } -static CLIPRDR_FORMAT* xf_cliprdr_get_raw_server_formats(xfClipboard* clipboard, UINT32* numFormats) +static CLIPRDR_FORMAT* xf_cliprdr_get_raw_server_formats(xfClipboard* clipboard, + UINT32* numFormats) { Atom type = None; int format = 0; @@ -413,21 +413,22 @@ static CLIPRDR_FORMAT* xf_cliprdr_get_raw_server_formats(xfClipboard* clipboard, BYTE* data = NULL; CLIPRDR_FORMAT* formats = NULL; xfContext* xfc = clipboard->xfc; - *numFormats = 0; + XGetWindowProperty(xfc->display, clipboard->owner, + clipboard->raw_format_list_atom, + 0, 4096, False, clipboard->raw_format_list_atom, &type, &format, + &length, &remaining, &data); - XGetWindowProperty(xfc->display, clipboard->owner, clipboard->raw_format_list_atom, - 0, 4096, False, clipboard->raw_format_list_atom, &type, &format, - &length, &remaining, &data); - - if (data && length > 0 && format == 8 && type == clipboard->raw_format_list_atom) + if (data && length > 0 && format == 8 + && type == clipboard->raw_format_list_atom) { formats = xf_cliprdr_parse_server_format_list(data, length, numFormats); } else { - WLog_ERR(TAG, "failed to retrieve raw format list: data=%p, length=%lu, format=%d, type=%d (expected=%d)", - data, length, format, type, clipboard->raw_format_list_atom); + WLog_ERR(TAG, + "failed to retrieve raw format list: data=%p, length=%lu, format=%d, type=%lu (expected=%lu)", + data, length, format, (unsigned long) type, (unsigned long) clipboard->raw_format_list_atom); } if (data) @@ -436,7 +437,8 @@ static CLIPRDR_FORMAT* xf_cliprdr_get_raw_server_formats(xfClipboard* clipboard, return formats; } -static CLIPRDR_FORMAT* xf_cliprdr_get_formats_from_targets(xfClipboard* clipboard, UINT32* numFormats) +static CLIPRDR_FORMAT* xf_cliprdr_get_formats_from_targets( + xfClipboard* clipboard, UINT32* numFormats) { int i; Atom atom; @@ -447,22 +449,21 @@ static CLIPRDR_FORMAT* xf_cliprdr_get_formats_from_targets(xfClipboard* clipboar xfCliprdrFormat* format = NULL; CLIPRDR_FORMAT* formats = NULL; xfContext* xfc = clipboard->xfc; - *numFormats = 0; - XGetWindowProperty(xfc->display, xfc->drawable, clipboard->property_atom, - 0, 200, 0, XA_ATOM, &atom, &format_property, &length, &bytes_left, &data); + 0, 200, 0, XA_ATOM, &atom, &format_property, &length, &bytes_left, &data); if (length > 0) { if (!data) { - WLog_ERR(TAG, "XGetWindowProperty set length = %d but data is NULL", length); + WLog_ERR(TAG, "XGetWindowProperty set length = %lu but data is NULL", length); goto out; } + if (!(formats = (CLIPRDR_FORMAT*) calloc(length, sizeof(CLIPRDR_FORMAT)))) { - WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", length); + WLog_ERR(TAG, "failed to allocate %lu CLIPRDR_FORMAT structs", length); goto out; } } @@ -470,7 +471,6 @@ static CLIPRDR_FORMAT* xf_cliprdr_get_formats_from_targets(xfClipboard* clipboar for (i = 0; i < length; i++) { atom = ((Atom*) data)[i]; - format = xf_cliprdr_get_client_format_by_atom(clipboard, atom); if (format) @@ -482,16 +482,17 @@ static CLIPRDR_FORMAT* xf_cliprdr_get_formats_from_targets(xfClipboard* clipboar } out: + if (data) XFree(data); return formats; } -static CLIPRDR_FORMAT* xf_cliprdr_get_client_formats(xfClipboard* clipboard, UINT32* numFormats) +static CLIPRDR_FORMAT* xf_cliprdr_get_client_formats(xfClipboard* clipboard, + UINT32* numFormats) { CLIPRDR_FORMAT* formats = NULL; - *numFormats = 0; if (xf_cliprdr_is_raw_transfer_available(clipboard)) @@ -502,7 +503,6 @@ static CLIPRDR_FORMAT* xf_cliprdr_get_client_formats(xfClipboard* clipboard, UIN if (*numFormats == 0) { xf_cliprdr_free_formats(formats, *numFormats); - formats = xf_cliprdr_get_formats_from_targets(clipboard, numFormats); } @@ -513,14 +513,13 @@ static void xf_cliprdr_provide_server_format_list(xfClipboard* clipboard) { wStream* formats = NULL; xfContext* xfc = clipboard->xfc; - formats = xf_cliprdr_serialize_server_format_list(clipboard); if (formats) { XChangeProperty(xfc->display, xfc->drawable, clipboard->raw_format_list_atom, - clipboard->raw_format_list_atom, 8, PropModeReplace, - Stream_Buffer(formats), Stream_Length(formats)); + clipboard->raw_format_list_atom, 8, PropModeReplace, + Stream_Buffer(formats), Stream_Length(formats)); } else { @@ -535,35 +534,31 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard) UINT32 numFormats = 0; CLIPRDR_FORMAT* formats = NULL; CLIPRDR_FORMAT_LIST formatList; - formats = xf_cliprdr_get_client_formats(clipboard, &numFormats); - ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST)); - formatList.msgFlags = CB_RESPONSE_OK; formatList.numFormats = numFormats; formatList.formats = formats; - clipboard->context->ClientFormatList(clipboard->context, &formatList); - xf_cliprdr_free_formats(formats, numFormats); } -static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasData, BYTE* data, int size) +static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, + BOOL hasData, BYTE* data, int size) { BOOL bSuccess; UINT32 SrcSize; UINT32 DstSize; UINT32 srcFormatId; UINT32 dstFormatId; - BYTE* pSrcData = NULL; BYTE* pDstData = NULL; xfCliprdrFormat* format; if (clipboard->incr_starts && hasData) return; - format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId); + format = xf_cliprdr_get_client_format_by_id(clipboard, + clipboard->requestedFormatId); if (!hasData || !data || !format) { @@ -572,7 +567,6 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa } srcFormatId = 0; - dstFormatId = 0; switch (format->formatId) { @@ -598,26 +592,12 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa } SrcSize = (UINT32) size; - pSrcData = (BYTE*) malloc(SrcSize); - - if (!pSrcData) - return; - - CopyMemory(pSrcData, data, SrcSize); - - bSuccess = ClipboardSetData(clipboard->system, srcFormatId, (void*) pSrcData, SrcSize); - - if (!bSuccess) - free(pSrcData); + bSuccess = ClipboardSetData(clipboard->system, srcFormatId, data, SrcSize); if (format->formatName) - { dstFormatId = ClipboardGetFormatId(clipboard->system, format->formatName); - } else - { dstFormatId = format->formatId; - } if (bSuccess) { @@ -646,8 +626,8 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target) unsigned long bytes_left; xfCliprdrFormat* format; xfContext* xfc = clipboard->xfc; - - format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId); + format = xf_cliprdr_get_client_format_by_id(clipboard, + clipboard->requestedFormatId); if (!format || (format->atom != target)) { @@ -656,8 +636,8 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target) } XGetWindowProperty(xfc->display, xfc->drawable, - clipboard->property_atom, 0, 0, 0, target, - &type, &format_property, &length, &bytes_left, &data); + clipboard->property_atom, 0, 0, 0, target, + &type, &format_property, &length, &bytes_left, &data); if (data) { @@ -667,7 +647,6 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target) if (bytes_left <= 0 && !clipboard->incr_starts) { - } else if (type == clipboard->incr_atom) { @@ -695,33 +674,35 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target) has_data = TRUE; } else if (XGetWindowProperty(xfc->display, xfc->drawable, - clipboard->property_atom, 0, bytes_left, 0, target, - &type, &format_property, &length, &dummy, &data) == Success) + clipboard->property_atom, 0, bytes_left, 0, target, + &type, &format_property, &length, &dummy, &data) == Success) { if (clipboard->incr_starts) { - BYTE *new_data; - + BYTE* new_data; bytes_left = length * format_property / 8; - new_data = (BYTE*) realloc(clipboard->incr_data, clipboard->incr_data_length + bytes_left); + new_data = (BYTE*) realloc(clipboard->incr_data, + clipboard->incr_data_length + bytes_left); + if (!new_data) return FALSE; + clipboard->incr_data = new_data; - CopyMemory(clipboard->incr_data + clipboard->incr_data_length, data, bytes_left); + CopyMemory(clipboard->incr_data + clipboard->incr_data_length, data, + bytes_left); clipboard->incr_data_length += bytes_left; XFree(data); data = NULL; } + has_data = TRUE; } else { - } } XDeleteProperty(xfc->display, xfc->drawable, clipboard->property_atom); - xf_cliprdr_process_requested_data(clipboard, has_data, data, (int) bytes_left); if (data) @@ -753,24 +734,26 @@ static void xf_cliprdr_provide_targets(xfClipboard* clipboard, XEvent* respond) if (respond->xselection.property != None) { XChangeProperty(xfc->display, respond->xselection.requestor, - respond->xselection.property, XA_ATOM, 32, PropModeReplace, - (BYTE*) clipboard->targets, clipboard->numTargets); + respond->xselection.property, XA_ATOM, 32, PropModeReplace, + (BYTE*) clipboard->targets, clipboard->numTargets); } } -static void xf_cliprdr_provide_data(xfClipboard* clipboard, XEvent* respond, BYTE* data, UINT32 size) +static void xf_cliprdr_provide_data(xfClipboard* clipboard, XEvent* respond, + BYTE* data, UINT32 size) { xfContext* xfc = clipboard->xfc; if (respond->xselection.property != None) { XChangeProperty(xfc->display, respond->xselection.requestor, - respond->xselection.property, respond->xselection.target, - 8, PropModeReplace, data, size); + respond->xselection.property, respond->xselection.target, + 8, PropModeReplace, data, size); } } -static BOOL xf_cliprdr_process_selection_notify(xfClipboard* clipboard, XEvent* xevent) +static BOOL xf_cliprdr_process_selection_notify(xfClipboard* clipboard, + XEvent* xevent) { if (xevent->xselection.target == clipboard->targets[1]) { @@ -791,7 +774,8 @@ static BOOL xf_cliprdr_process_selection_notify(xfClipboard* clipboard, XEvent* } } -static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* xevent) +static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, + XEvent* xevent) { int fmt; Atom type; @@ -829,7 +813,8 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* { /* TODO */ } - else if (xevent->xselectionrequest.target == clipboard->targets[1]) /* TARGETS */ + else if (xevent->xselectionrequest.target == + clipboard->targets[1]) /* TARGETS */ { /* Someone else requests our available formats */ respond->xselection.property = xevent->xselectionrequest.property; @@ -837,7 +822,8 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* } else { - format = xf_cliprdr_get_server_format_by_atom(clipboard, xevent->xselectionrequest.target); + format = xf_cliprdr_get_server_format_by_atom(clipboard, + xevent->xselectionrequest.target); if (format && (xevent->xselectionrequest.requestor != xfc->drawable)) { @@ -848,10 +834,9 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* if (formatId == CF_RAW) { if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor, - clipboard->property_atom, 0, 4, 0, XA_INTEGER, - &type, &fmt, &length, &bytes_left, &data) != Success) + clipboard->property_atom, 0, 4, 0, XA_INTEGER, + &type, &fmt, &length, &bytes_left, &data) != Success) { - } if (data) @@ -862,11 +847,13 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* } } - if ((clipboard->data != 0) && (formatId == clipboard->data_format_id) && (formatName == clipboard->data_format_name)) + if ((clipboard->data != 0) && (formatId == clipboard->data_format_id) + && (formatName == clipboard->data_format_name)) { /* Cached clipboard data available. Send it now */ respond->xselection.property = xevent->xselectionrequest.property; - xf_cliprdr_provide_data(clipboard, respond, clipboard->data, clipboard->data_length); + xf_cliprdr_provide_data(clipboard, respond, clipboard->data, + clipboard->data_length); } else if (clipboard->respond) { @@ -890,7 +877,6 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* clipboard->data_format_name = formatName; clipboard->data_raw_format = rawTransfer; delayRespond = TRUE; - xf_cliprdr_send_data_request(clipboard, formatId); } } @@ -906,7 +892,8 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* return TRUE; } -static BOOL xf_cliprdr_process_selection_clear(xfClipboard* clipboard, XEvent* xevent) +static BOOL xf_cliprdr_process_selection_clear(xfClipboard* clipboard, + XEvent* xevent) { xfContext* xfc = clipboard->xfc; @@ -914,11 +901,11 @@ static BOOL xf_cliprdr_process_selection_clear(xfClipboard* clipboard, XEvent* x return FALSE; XDeleteProperty(xfc->display, clipboard->root_window, clipboard->property_atom); - return TRUE; } -static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, XEvent* xevent) +static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, + XEvent* xevent) { xfCliprdrFormat* format; xfContext* xfc = clipboard->xfc; @@ -934,9 +921,10 @@ static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, XEvent* x xf_cliprdr_send_client_format_list(clipboard); } else if ((xevent->xproperty.window == xfc->drawable) && - (xevent->xproperty.state == PropertyNewValue) && clipboard->incr_starts) + (xevent->xproperty.state == PropertyNewValue) && clipboard->incr_starts) { - format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId); + format = xf_cliprdr_get_client_format_by_id(clipboard, + clipboard->requestedFormatId); if (format) xf_cliprdr_get_requested_data(clipboard, format->atom); @@ -958,7 +946,9 @@ void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event) return; #ifdef WITH_XFIXES - if (clipboard->xfixes_supported && event->type == XFixesSelectionNotify + clipboard->xfixes_event_base) + + if (clipboard->xfixes_supported + && event->type == XFixesSelectionNotify + clipboard->xfixes_event_base) { XFixesSelectionNotifyEvent* se = (XFixesSelectionNotifyEvent*) event; @@ -976,6 +966,7 @@ void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event) return; } + #endif switch (event->type) @@ -1001,6 +992,7 @@ void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event) { xf_cliprdr_check_owner(clipboard); } + break; } } @@ -1014,17 +1006,15 @@ UINT xf_cliprdr_send_client_capabilities(xfClipboard* clipboard) { CLIPRDR_CAPABILITIES capabilities; CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet; - capabilities.cCapabilitiesSets = 1; - capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &(generalCapabilitySet); - + capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) & + (generalCapabilitySet); generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL; generalCapabilitySet.capabilitySetLength = 12; - generalCapabilitySet.version = CB_CAPS_VERSION_2; generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES; - - return clipboard->context->ClientCapabilities(clipboard->context, &capabilities); + return clipboard->context->ClientCapabilities(clipboard->context, + &capabilities); } /** @@ -1039,10 +1029,9 @@ UINT xf_cliprdr_send_client_format_list(xfClipboard* clipboard) CLIPRDR_FORMAT_LIST formatList; xfContext* xfc = clipboard->xfc; UINT ret; - ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST)); - numFormats = clipboard->numClientFormats; + if (numFormats) { if (!(formats = (CLIPRDR_FORMAT*) calloc(numFormats, sizeof(CLIPRDR_FORMAT)))) @@ -1061,16 +1050,14 @@ UINT xf_cliprdr_send_client_format_list(xfClipboard* clipboard) formatList.msgFlags = CB_RESPONSE_OK; formatList.numFormats = numFormats; formatList.formats = formats; - ret = clipboard->context->ClientFormatList(clipboard->context, &formatList); - free(formats); if (clipboard->owner && clipboard->owner != xfc->drawable) { /* Request the owner for TARGETS, and wait for SelectionNotify event */ XConvertSelection(xfc->display, clipboard->clipboard_atom, - clipboard->targets[1], clipboard->property_atom, xfc->drawable, CurrentTime); + clipboard->targets[1], clipboard->property_atom, xfc->drawable, CurrentTime); } return ret; @@ -1081,15 +1068,15 @@ UINT xf_cliprdr_send_client_format_list(xfClipboard* clipboard) * * @return 0 on success, otherwise a Win32 error code */ -UINT xf_cliprdr_send_client_format_list_response(xfClipboard* clipboard, BOOL status) +UINT xf_cliprdr_send_client_format_list_response(xfClipboard* clipboard, + BOOL status) { CLIPRDR_FORMAT_LIST_RESPONSE formatListResponse; - formatListResponse.msgType = CB_FORMAT_LIST_RESPONSE; formatListResponse.msgFlags = status ? CB_RESPONSE_OK : CB_RESPONSE_FAIL; formatListResponse.dataLen = 0; - - return clipboard->context->ClientFormatListResponse(clipboard->context, &formatListResponse); + return clipboard->context->ClientFormatListResponse(clipboard->context, + &formatListResponse); } /** @@ -1097,18 +1084,19 @@ UINT xf_cliprdr_send_client_format_list_response(xfClipboard* clipboard, BOOL st * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_cliprdr_monitor_ready(CliprdrClientContext* context, CLIPRDR_MONITOR_READY* monitorReady) +static UINT xf_cliprdr_monitor_ready(CliprdrClientContext* context, + CLIPRDR_MONITOR_READY* monitorReady) { xfClipboard* clipboard = (xfClipboard*) context->custom; UINT ret; if ((ret = xf_cliprdr_send_client_capabilities(clipboard)) != CHANNEL_RC_OK) return ret; + if ((ret = xf_cliprdr_send_client_format_list(clipboard)) != CHANNEL_RC_OK) return ret; clipboard->sync = TRUE; - return CHANNEL_RC_OK; } @@ -1117,10 +1105,10 @@ static UINT xf_cliprdr_monitor_ready(CliprdrClientContext* context, CLIPRDR_MONI * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_cliprdr_server_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILITIES* capabilities) +static UINT xf_cliprdr_server_capabilities(CliprdrClientContext* context, + CLIPRDR_CAPABILITIES* capabilities) { //xfClipboard* clipboard = (xfClipboard*) context->custom; - return CHANNEL_RC_OK; } @@ -1129,7 +1117,8 @@ static UINT xf_cliprdr_server_capabilities(CliprdrClientContext* context, CLIPRD * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList) +static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, + CLIPRDR_FORMAT_LIST* formatList) { int i, j; CLIPRDR_FORMAT* format; @@ -1153,14 +1142,16 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR free(clipboard->serverFormats); clipboard->serverFormats = NULL; - clipboard->numServerFormats = 0; } clipboard->numServerFormats = formatList->numFormats + 1; /* +1 for CF_RAW */ - if (!(clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc(clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT)))) { - WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", clipboard->numServerFormats); + if (!(clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc( + clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT)))) + { + WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", + clipboard->numServerFormats); return CHANNEL_RC_NO_MEMORY; } @@ -1168,9 +1159,11 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR { format = &formatList->formats[i]; clipboard->serverFormats[i].formatId = format->formatId; + if (format->formatName) { clipboard->serverFormats[i].formatName = _strdup(format->formatName); + if (!clipboard->serverFormats[i].formatName) { for (--i; i >= 0; --i) @@ -1188,9 +1181,7 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR format = &clipboard->serverFormats[formatList->numFormats]; format->formatId = CF_RAW; format->formatName = NULL; - xf_cliprdr_provide_server_format_list(clipboard); - clipboard->numTargets = 2; for (i = 0; i < formatList->numFormats; i++) @@ -1207,11 +1198,9 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR } ret = xf_cliprdr_send_client_format_list_response(clipboard, TRUE); - - XSetSelectionOwner(xfc->display, clipboard->clipboard_atom, xfc->drawable, CurrentTime); - + XSetSelectionOwner(xfc->display, clipboard->clipboard_atom, xfc->drawable, + CurrentTime); XFlush(xfc->display); - return ret; } @@ -1220,10 +1209,10 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_cliprdr_server_format_list_response(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse) +static UINT xf_cliprdr_server_format_list_response(CliprdrClientContext* + context, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse) { //xfClipboard* clipboard = (xfClipboard*) context->custom; - return CHANNEL_RC_OK; } @@ -1232,22 +1221,21 @@ static UINT xf_cliprdr_server_format_list_response(CliprdrClientContext* context * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) +static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context, + CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) { BOOL rawTransfer; xfCliprdrFormat* format = NULL; UINT32 formatId = formatDataRequest->requestedFormatId; xfClipboard* clipboard = (xfClipboard*) context->custom; xfContext* xfc = clipboard->xfc; - rawTransfer = xf_cliprdr_is_raw_transfer_available(clipboard); if (rawTransfer) { format = xf_cliprdr_get_client_format_by_id(clipboard, CF_RAW); - XChangeProperty(xfc->display, xfc->drawable, clipboard->property_atom, - XA_INTEGER, 32, PropModeReplace, (BYTE*) &formatId, 1); + XA_INTEGER, 32, PropModeReplace, (BYTE*) &formatId, 1); } else format = xf_cliprdr_get_client_format_by_id(clipboard, formatId); @@ -1256,14 +1244,10 @@ static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context, return xf_cliprdr_send_data_response(clipboard, NULL, 0); clipboard->requestedFormatId = rawTransfer ? CF_RAW : formatId; - XConvertSelection(xfc->display, clipboard->clipboard_atom, - format->atom, clipboard->property_atom, xfc->drawable, CurrentTime); - + format->atom, clipboard->property_atom, xfc->drawable, CurrentTime); XFlush(xfc->display); - /* After this point, we expect a SelectionNotify event from the clipboard owner. */ - return CHANNEL_RC_OK; } @@ -1272,10 +1256,10 @@ static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context, * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) +static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* + context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) { BOOL bSuccess; - BYTE* pSrcData; BYTE* pDstData; UINT32 DstSize; UINT32 SrcSize; @@ -1298,7 +1282,6 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context pDstData = NULL; DstSize = 0; - srcFormatId = 0; dstFormatId = 0; @@ -1320,43 +1303,33 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context { switch (clipboard->data_format_id) { - case CF_TEXT: - srcFormatId = CF_TEXT; - dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); - nullTerminated = TRUE; - break; + case CF_TEXT: + srcFormatId = CF_TEXT; + dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); + nullTerminated = TRUE; + break; - case CF_OEMTEXT: - srcFormatId = CF_OEMTEXT; - dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); - nullTerminated = TRUE; - break; + case CF_OEMTEXT: + srcFormatId = CF_OEMTEXT; + dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); + nullTerminated = TRUE; + break; - case CF_UNICODETEXT: - srcFormatId = CF_UNICODETEXT; - dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); - nullTerminated = TRUE; - break; + case CF_UNICODETEXT: + srcFormatId = CF_UNICODETEXT; + dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); + nullTerminated = TRUE; + break; - case CF_DIB: - srcFormatId = CF_DIB; - dstFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp"); - break; + case CF_DIB: + srcFormatId = CF_DIB; + dstFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp"); + break; } } SrcSize = (UINT32) size; - pSrcData = (BYTE*) malloc(SrcSize); - - if (!pSrcData) - return CHANNEL_RC_NO_MEMORY; - - CopyMemory(pSrcData, data, SrcSize); - - bSuccess = ClipboardSetData(clipboard->system, srcFormatId, (void*) pSrcData, SrcSize); - - if (!bSuccess) - free (pSrcData); + bSuccess = ClipboardSetData(clipboard->system, srcFormatId, data, SrcSize); if (bSuccess) { @@ -1372,15 +1345,12 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context clipboard->data = pDstData; clipboard->data_length = DstSize; - xf_cliprdr_provide_data(clipboard, clipboard->respond, pDstData, DstSize); - - XSendEvent(xfc->display, clipboard->respond->xselection.requestor, 0, 0, clipboard->respond); + XSendEvent(xfc->display, clipboard->respond->xselection.requestor, 0, 0, + clipboard->respond); XFlush(xfc->display); - free(clipboard->respond); clipboard->respond = NULL; - return CHANNEL_RC_OK; } @@ -1397,16 +1367,11 @@ xfClipboard* xf_clipboard_new(xfContext* xfc) } xfc->clipboard = clipboard; - clipboard->xfc = xfc; - channels = ((rdpContext*) xfc)->channels; clipboard->channels = channels; - clipboard->system = ClipboardCreate(); - clipboard->requestedFormatId = -1; - clipboard->root_window = DefaultRootWindow(xfc->display); clipboard->clipboard_atom = XInternAtom(xfc->display, "CLIPBOARD", FALSE); @@ -1418,23 +1383,23 @@ xfClipboard* xf_clipboard_new(xfContext* xfc) } clipboard->property_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR", FALSE); - - clipboard->raw_transfer_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR_RAW", FALSE); - clipboard->raw_format_list_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR_FORMATS", FALSE); - + clipboard->raw_transfer_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR_RAW", + FALSE); + clipboard->raw_format_list_atom = XInternAtom(xfc->display, + "_FREERDP_CLIPRDR_FORMATS", FALSE); xf_cliprdr_set_raw_transfer_enabled(clipboard, TRUE); - XSelectInput(xfc->display, clipboard->root_window, PropertyChangeMask); - #ifdef WITH_XFIXES - if (XFixesQueryExtension(xfc->display, &clipboard->xfixes_event_base, &clipboard->xfixes_error_base)) + + if (XFixesQueryExtension(xfc->display, &clipboard->xfixes_event_base, + &clipboard->xfixes_error_base)) { int xfmajor, xfminor; if (XFixesQueryVersion(xfc->display, &xfmajor, &xfminor)) { XFixesSelectSelectionInput(xfc->display, clipboard->root_window, - clipboard->clipboard_atom, XFixesSetSelectionOwnerNotifyMask); + clipboard->clipboard_atom, XFixesSetSelectionOwnerNotifyMask); clipboard->xfixes_supported = TRUE; } else @@ -1446,59 +1411,57 @@ xfClipboard* xf_clipboard_new(xfContext* xfc) { WLog_ERR(TAG, "Error loading X Fixes extension"); } + #else - WLog_ERR(TAG, "Warning: Using clipboard redirection without XFIXES extension is strongly discouraged!"); + WLog_ERR(TAG, + "Warning: Using clipboard redirection without XFIXES extension is strongly discouraged!"); #endif - n = 0; - - clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "_FREERDP_RAW", False); + clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "_FREERDP_RAW", + False); clipboard->clientFormats[n].formatId = CF_RAW; n++; - - clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "UTF8_STRING", False); + clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "UTF8_STRING", + False); clipboard->clientFormats[n].formatId = CF_UNICODETEXT; n++; - clipboard->clientFormats[n].atom = XA_STRING; clipboard->clientFormats[n].formatId = CF_TEXT; n++; - - clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/png", False); + clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/png", + False); clipboard->clientFormats[n].formatId = CB_FORMAT_PNG; n++; - - clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/jpeg", False); + clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/jpeg", + False); clipboard->clientFormats[n].formatId = CB_FORMAT_JPEG; n++; - - clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/gif", False); + clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/gif", + False); clipboard->clientFormats[n].formatId = CB_FORMAT_GIF; n++; - - clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/bmp", False); + clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/bmp", + False); clipboard->clientFormats[n].formatId = CF_DIB; n++; - - clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "text/html", False); + clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "text/html", + False); clipboard->clientFormats[n].formatId = CB_FORMAT_HTML; clipboard->clientFormats[n].formatName = _strdup("HTML Format"); + if (!clipboard->clientFormats[n].formatName) { ClipboardDestroy(clipboard->system); free(clipboard); return NULL; } + n++; - clipboard->numClientFormats = n; - clipboard->targets[0] = XInternAtom(xfc->display, "TIMESTAMP", FALSE); clipboard->targets[1] = XInternAtom(xfc->display, "TARGETS", FALSE); clipboard->numTargets = 2; - clipboard->incr_atom = XInternAtom(xfc->display, "INCR", FALSE); - return clipboard; } @@ -1525,7 +1488,6 @@ void xf_clipboard_free(xfClipboard* clipboard) } ClipboardDestroy(clipboard->system); - free(clipboard->data); free(clipboard->respond); free(clipboard->incr_data); @@ -1537,7 +1499,6 @@ void xf_cliprdr_init(xfContext* xfc, CliprdrClientContext* cliprdr) xfc->cliprdr = cliprdr; xfc->clipboard->context = cliprdr; cliprdr->custom = (void*) xfc->clipboard; - cliprdr->MonitorReady = xf_cliprdr_monitor_ready; cliprdr->ServerCapabilities = xf_cliprdr_server_capabilities; cliprdr->ServerFormatList = xf_cliprdr_server_format_list; diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 2948693..a211e6b 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -80,9 +80,9 @@ const char* const X11_EVENT_STRINGS[] = }; #ifdef WITH_DEBUG_X11 -#define DEBUG_X11(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__) +#define DEBUG_X11(...) WLog_DBG(TAG, __VA_ARGS__) #else -#define DEBUG_X11(fmt, ...) do { } while (0) +#define DEBUG_X11(...) do { } while (0) #endif BOOL xf_event_action_script_init(xfContext* xfc) @@ -91,14 +91,13 @@ BOOL xf_event_action_script_init(xfContext* xfc) FILE* actionScript; char buffer[1024] = { 0 }; char command[1024] = { 0 }; - xfc->xevents = ArrayList_New(TRUE); + if (!xfc->xevents) return FALSE; + ArrayList_Object(xfc->xevents)->fnObjectFree = free; - sprintf_s(command, sizeof(command), "%s xevent", xfc->actionScript); - actionScript = popen(command, "r"); if (!actionScript) @@ -108,6 +107,7 @@ BOOL xf_event_action_script_init(xfContext* xfc) { strtok(buffer, "\n"); xevent = _strdup(buffer); + if (!xevent || ArrayList_Add(xfc->xevents, xevent) < 0) { ArrayList_Free(xfc->xevents); @@ -117,7 +117,6 @@ BOOL xf_event_action_script_init(xfContext* xfc) } pclose(actionScript); - return TRUE; } @@ -148,7 +147,6 @@ static BOOL xf_event_execute_action_script(xfContext* xfc, XEvent* event) return FALSE; xeventName = X11_EVENT_STRINGS[event->type]; - count = ArrayList_Count(xfc->xevents); for (index = 0; index < count; index++) @@ -166,8 +164,7 @@ static BOOL xf_event_execute_action_script(xfContext* xfc, XEvent* event) return FALSE; sprintf_s(command, sizeof(command), "%s xevent %s %d", - xfc->actionScript, xeventName, (int) xfc->window->handle); - + xfc->actionScript, xeventName, (int) xfc->window->handle); actionScript = popen(command, "r"); if (!actionScript) @@ -179,24 +176,33 @@ static BOOL xf_event_execute_action_script(xfContext* xfc, XEvent* event) } pclose(actionScript); - return TRUE; } -void xf_event_adjust_coordinates(xfContext* xfc, int* x, int *y) +void xf_event_adjust_coordinates(xfContext* xfc, int* x, int* y) { + rdpSettings* settings; + + if (!xfc || !xfc->context.settings || !y || !x) + return; + + settings = xfc->context.settings; + if (!xfc->remote_app) { #ifdef WITH_XRENDER + if (xf_picture_transform_required(xfc)) { - double xScalingFactor = xfc->sessionWidth / (double)xfc->scaledWidth; - double yScalingFactor = xfc->sessionHeight / (double)xfc->scaledHeight; + double xScalingFactor = settings->DesktopWidth / (double)xfc->scaledWidth; + double yScalingFactor = settings->DesktopHeight / (double)xfc->scaledHeight; *x = (int)((*x - xfc->offset_x) * xScalingFactor); *y = (int)((*y - xfc->offset_y) * yScalingFactor); } + #endif } + CLAMP_COORDINATES(*x, *y); } @@ -204,13 +210,14 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app) { int x, y; int w, h; + rdpSettings* settings = xfc->context.settings; - if (!app && (xfc->settings->SmartSizing || xfc->settings->MultiTouchGestures)) + if (!app && (settings->SmartSizing || settings->MultiTouchGestures)) { x = 0; y = 0; - w = xfc->sessionWidth; - h = xfc->sessionHeight; + w = settings->DesktopWidth; + h = settings->DesktopHeight; } else { @@ -233,7 +240,6 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app) else { xfAppWindow* appWindow; - appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window); if (appWindow) @@ -251,14 +257,14 @@ static BOOL xf_event_VisibilityNotify(xfContext* xfc, XEvent* event, BOOL app) return TRUE; } -BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window window, BOOL app) +BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, + Window window, BOOL app) { rdpInput* input; Window childWindow; + input = xfc->context.input; - input = xfc->instance->input; - - if (!xfc->settings->MouseMotion) + if (!xfc->context.settings->MouseMotion) { if ((state & (Button1Mask | Button2Mask | Button3Mask)) == 0) return TRUE; @@ -272,17 +278,17 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win /* Translate to desktop coordinates */ XTranslateCoordinates(xfc->display, window, - RootWindowOfScreen(xfc->screen), - x, y, &x, &y, &childWindow); + RootWindowOfScreen(xfc->screen), + x, y, &x, &y, &childWindow); } xf_event_adjust_coordinates(xfc, &x, &y); - input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); if (xfc->fullscreen && !app) { - XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime); + XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, + CurrentTime); } return TRUE; @@ -294,28 +300,28 @@ static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app) return TRUE; return xf_generic_MotionNotify(xfc, event->xmotion.x, event->xmotion.y, - event->xmotion.state, event->xmotion.window, app); + event->xmotion.state, event->xmotion.window, app); } -BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window window, BOOL app) +BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, + Window window, BOOL app) { int flags; BOOL wheel; BOOL extended; rdpInput* input; Window childWindow; - flags = 0; wheel = FALSE; extended = FALSE; - input = xfc->instance->input; + input = xfc->context.input; switch (button) { case Button1: case Button2: case Button3: - flags = PTR_FLAGS_DOWN | xfc->button_map[button-BUTTON_BASE]; + flags = PTR_FLAGS_DOWN | xfc->button_map[button - BUTTON_BASE]; break; case 4: @@ -342,14 +348,12 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win case 6: /* wheel left */ wheel = TRUE; - if (xfc->settings->HasHorizontalWheel) - flags = PTR_FLAGS_HWHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0078; + flags = PTR_FLAGS_HWHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0078; break; case 7: /* wheel right */ wheel = TRUE; - if (xfc->settings->HasHorizontalWheel) - flags = PTR_FLAGS_HWHEEL | 0x0078; + flags = PTR_FLAGS_HWHEEL | 0x0078; break; default: @@ -375,9 +379,8 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win /* Translate to desktop coordinates */ XTranslateCoordinates(xfc->display, window, - RootWindowOfScreen(xfc->screen), - x, y, &x, &y, &childWindow); - + RootWindowOfScreen(xfc->screen), + x, y, &x, &y, &childWindow); } xf_event_adjust_coordinates(xfc, &x, &y); @@ -398,28 +401,28 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app) return TRUE; return xf_generic_ButtonPress(xfc, event->xbutton.x, event->xbutton.y, - event->xbutton.button, event->xbutton.window, app); + event->xbutton.button, event->xbutton.window, app); } -BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window window, BOOL app) +BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, + Window window, BOOL app) { int flags; BOOL wheel; BOOL extended; rdpInput* input; Window childWindow; - flags = 0; wheel = FALSE; extended = FALSE; - input = xfc->instance->input; + input = xfc->context.input; switch (button) { case Button1: case Button2: case Button3: - flags = xfc->button_map[button-BUTTON_BASE]; + flags = xfc->button_map[button - BUTTON_BASE]; break; case 6: @@ -451,8 +454,8 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w /* Translate to desktop coordinates */ XTranslateCoordinates(xfc->display, window, - RootWindowOfScreen(xfc->screen), - x, y, &x, &y, &childWindow); + RootWindowOfScreen(xfc->screen), + x, y, &x, &y, &childWindow); } xf_event_adjust_coordinates(xfc, &x, &y); @@ -472,18 +475,15 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app) return TRUE; return xf_generic_ButtonRelease(xfc, event->xbutton.x, event->xbutton.y, - event->xbutton.button, event->xbutton.window, app); + event->xbutton.button, event->xbutton.window, app); } static BOOL xf_event_KeyPress(xfContext* xfc, XEvent* event, BOOL app) { KeySym keysym; char str[256]; - XLookupString((XKeyEvent*) event, str, sizeof(str), &keysym, NULL); - xf_keyboard_key_press(xfc, event->xkey.keycode, keysym); - return TRUE; } @@ -504,7 +504,6 @@ static BOOL xf_event_KeyRelease(xfContext* xfc, XEvent* event, BOOL app) } xf_keyboard_key_release(xfc, event->xkey.keycode); - return TRUE; } @@ -516,14 +515,13 @@ static BOOL xf_event_FocusIn(xfContext* xfc, XEvent* event, BOOL app) xfc->focused = TRUE; if (xfc->mouse_active && !app) - XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync, CurrentTime); + XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, + GrabModeAsync, CurrentTime); if (app) { xfAppWindow* appWindow; - xf_rail_send_activate(xfc, event->xany.window, TRUE); - appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window); /* Update the server with any window changes that occurred while the window was not focused. */ @@ -534,7 +532,6 @@ static BOOL xf_event_FocusIn(xfContext* xfc, XEvent* event, BOOL app) } xf_keyboard_focus_in(xfc); - return TRUE; } @@ -578,7 +575,6 @@ static BOOL xf_event_ClientMessage(xfContext* xfc, XEvent* event, BOOL app) if (app) { xfAppWindow* appWindow; - appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window); if (appWindow) @@ -605,15 +601,16 @@ static BOOL xf_event_EnterNotify(xfContext* xfc, XEvent* event, BOOL app) xfc->mouse_active = TRUE; if (xfc->fullscreen) - XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime); + XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, + CurrentTime); if (xfc->focused) - XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync, CurrentTime); + XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, + GrabModeAsync, CurrentTime); } else { xfAppWindow* appWindow; - appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window); /* keep track of which window has focus so that we can apply pointer updates */ @@ -642,6 +639,7 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app) { Window childWindow; xfAppWindow* appWindow; + rdpSettings* settings = xfc->context.settings; if (!app) { @@ -652,26 +650,30 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app) xfc->window->top = event->xconfigure.y; if (xfc->window->width != event->xconfigure.width || - xfc->window->height != event->xconfigure.height) + xfc->window->height != event->xconfigure.height) { xfc->window->width = event->xconfigure.width; xfc->window->height = event->xconfigure.height; #ifdef WITH_XRENDER xfc->offset_x = 0; xfc->offset_y = 0; - if (xfc->settings->SmartSizing || xfc->settings->MultiTouchGestures) + + if (xfc->context.settings->SmartSizing + || xfc->context.settings->MultiTouchGestures) { xfc->scaledWidth = xfc->window->width; xfc->scaledHeight = xfc->window->height; - xf_draw_screen(xfc, 0, 0, xfc->sessionWidth, xfc->sessionHeight); + xf_draw_screen(xfc, 0, 0, settings->DesktopWidth, settings->DesktopHeight); } else { - xfc->scaledWidth = xfc->sessionWidth; - xfc->scaledHeight = xfc->sessionHeight; + xfc->scaledWidth = settings->DesktopWidth; + xfc->scaledHeight = settings->DesktopHeight; } + #endif } + return TRUE; } @@ -683,11 +685,9 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app) * ConfigureNotify coordinates are expressed relative to the window parent. * Translate these to root window coordinates. */ - XTranslateCoordinates(xfc->display, appWindow->handle, - RootWindowOfScreen(xfc->screen), - 0, 0, &appWindow->x, &appWindow->y, &childWindow); - + RootWindowOfScreen(xfc->screen), + 0, 0, &appWindow->x, &appWindow->y, &childWindow); appWindow->width = event->xconfigure.width; appWindow->height = event->xconfigure.height; @@ -704,11 +704,11 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app) } else { - if ((!event->xconfigure.send_event || appWindow->local_move.state == LMS_NOT_ACTIVE) - && !appWindow->rail_ignore_configure && xfc->focused) + if ((!event->xconfigure.send_event + || appWindow->local_move.state == LMS_NOT_ACTIVE) + && !appWindow->rail_ignore_configure && xfc->focused) xf_rail_adjust_position(xfc, appWindow); } - } return TRUE; @@ -718,15 +718,15 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app) { RECTANGLE_16 rect; xfAppWindow* appWindow; - rdpUpdate* update = xfc->instance->update; + rdpUpdate* update = xfc->context.update; + rdpSettings* settings = xfc->context.settings; if (!app) { rect.left = 0; rect.top = 0; - rect.right = xfc->sessionWidth; - rect.bottom = xfc->sessionHeight; - + rect.right = settings->DesktopWidth; + rect.bottom = settings->DesktopHeight; update->SuppressOutput((rdpContext*) xfc, 1, &rect); } else @@ -736,12 +736,10 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app) if (appWindow) { /* local restore event */ - /* This is now handled as part of the PropertyNotify * Doing this here would inhibit the ability to restore a maximized window * that is minimized back to the maximized state */ - //xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE); appWindow->is_mapped = TRUE; } @@ -753,8 +751,7 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app) static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app) { xfAppWindow* appWindow; - rdpUpdate* update = xfc->instance->update; - + rdpUpdate* update = xfc->context.update; xf_keyboard_release_all_keypress(xfc); if (!app) @@ -781,43 +778,45 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app) * when the window has been minimized, maximized, restored locally * ie. not using the buttons on the rail window itself */ - if (app) { - xfAppWindow* appWindow; - + xfAppWindow* appWindow; appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window); if (!appWindow) return TRUE; - if ((((Atom) event->xproperty.atom == xfc->_NET_WM_STATE) && (event->xproperty.state != PropertyDelete)) || - (((Atom) event->xproperty.atom == xfc->WM_STATE) && (event->xproperty.state != PropertyDelete))) - { - int i; - BOOL status; - BOOL maxVert = FALSE; - BOOL maxHorz = FALSE; - BOOL minimized = FALSE; - unsigned long nitems; - unsigned long bytes; - unsigned char* prop; + if ((((Atom) event->xproperty.atom == xfc->_NET_WM_STATE) + && (event->xproperty.state != PropertyDelete)) || + (((Atom) event->xproperty.atom == xfc->WM_STATE) + && (event->xproperty.state != PropertyDelete))) + { + int i; + BOOL status; + BOOL maxVert = FALSE; + BOOL maxHorz = FALSE; + BOOL minimized = FALSE; + unsigned long nitems; + unsigned long bytes; + unsigned char* prop; - if ((Atom) event->xproperty.atom == xfc->_NET_WM_STATE) - { + if ((Atom) event->xproperty.atom == xfc->_NET_WM_STATE) + { status = xf_GetWindowProperty(xfc, event->xproperty.window, - xfc->_NET_WM_STATE, 12, &nitems, &bytes, &prop); + xfc->_NET_WM_STATE, 12, &nitems, &bytes, &prop); if (status) { for (i = 0; i < nitems; i++) { - if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False)) + if ((Atom)((UINT16**) prop)[i] == XInternAtom(xfc->display, + "_NET_WM_STATE_MAXIMIZED_VERT", False)) { maxVert = TRUE; } - if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False)) + if ((Atom)((UINT16**) prop)[i] == XInternAtom(xfc->display, + "_NET_WM_STATE_MAXIMIZED_HORZ", False)) { maxHorz = TRUE; } @@ -825,12 +824,12 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app) XFree(prop); } - } + } - if ((Atom) event->xproperty.atom == xfc->WM_STATE) - { + if ((Atom) event->xproperty.atom == xfc->WM_STATE) + { status = xf_GetWindowProperty(xfc, event->xproperty.window, - xfc->WM_STATE, 1, &nitems, &bytes, &prop); + xfc->WM_STATE, 1, &nitems, &bytes, &prop); if (status) { @@ -842,30 +841,33 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app) XFree(prop); } - } + } - if (maxVert && maxHorz && !minimized && (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED)) - { - appWindow->rail_state = WINDOW_SHOW_MAXIMIZED; - xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MAXIMIZE); - } - else if (minimized && (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)) - { - appWindow->rail_state = WINDOW_SHOW_MINIMIZED; - xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MINIMIZE); - } - else if (!minimized && !maxVert && !maxHorz && (appWindow->rail_state != WINDOW_SHOW)) - { - appWindow->rail_state = WINDOW_SHOW; - xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE); - } - } - } + if (maxVert && maxHorz && !minimized + && (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED)) + { + appWindow->rail_state = WINDOW_SHOW_MAXIMIZED; + xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MAXIMIZE); + } + else if (minimized && (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)) + { + appWindow->rail_state = WINDOW_SHOW_MINIMIZED; + xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MINIMIZE); + } + else if (!minimized && !maxVert && !maxHorz + && (appWindow->rail_state != WINDOW_SHOW)) + { + appWindow->rail_state = WINDOW_SHOW; + xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE); + } + } + } return TRUE; } -static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, XEvent* event) +static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, + XEvent* event) { if (!xfc->remote_app) return FALSE; @@ -873,51 +875,56 @@ static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, XEv switch (appWindow->local_move.state) { case LMS_NOT_ACTIVE: + /* No local move in progress, nothing to do */ /* Prevent Configure from happening during indeterminant state of Horz or Vert Max only */ - - if ((event->type == ConfigureNotify) && appWindow->rail_ignore_configure) - { - appWindow->rail_ignore_configure = FALSE; - return TRUE; - } + if ((event->type == ConfigureNotify) && appWindow->rail_ignore_configure) + { + appWindow->rail_ignore_configure = FALSE; + return TRUE; + } break; case LMS_STARTING: + /* Local move initiated by RDP server, but we have not yet seen any updates from the X server */ switch (event->type) { case ConfigureNotify: /* Starting to see move events from the X server. Local move is now in progress. */ appWindow->local_move.state = LMS_ACTIVE; - /* Allow these events to be processed during move to keep our state up to date. */ break; + case ButtonPress: case ButtonRelease: case KeyPress: case KeyRelease: case UnmapNotify: - /* - * A button release event means the X window server did not grab the - * mouse before the user released it. In this case we must cancel the - * local move. The event will be processed below as normal, below. - */ - break; + /* + * A button release event means the X window server did not grab the + * mouse before the user released it. In this case we must cancel the + * local move. The event will be processed below as normal, below. + */ + break; + case VisibilityNotify: case PropertyNotify: case Expose: /* Allow these events to pass */ break; + default: /* Eat any other events */ return TRUE; } + break; case LMS_ACTIVE: + /* Local move is in progress */ switch (event->type) { @@ -928,11 +935,13 @@ static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, XEv case GravityNotify: /* Keep us up to date on position */ break; + default: /* Any other event terminates move */ xf_rail_end_local_move(xfc, appWindow); break; } + break; case LMS_TERMINATING: @@ -967,7 +976,8 @@ BOOL xf_event_process(freerdp* instance, XEvent* event) xf_event_execute_action_script(xfc, event); if (event->type != MotionNotify) - DEBUG_X11("%s Event(%d): wnd=0x%04X", X11_EVENT_STRINGS[event->type], event->type, (UINT32) event->xany.window); + DEBUG_X11("%s Event(%d): wnd=0x%04X", X11_EVENT_STRINGS[event->type], + event->type, (UINT32) event->xany.window); switch (event->type) { @@ -1047,7 +1057,6 @@ BOOL xf_event_process(freerdp* instance, XEvent* event) case PropertyNotify: status = xf_event_PropertyNotify(xfc, event, xfc->remote_app); break; - } if (!xfc->remote_app) @@ -1056,8 +1065,6 @@ BOOL xf_event_process(freerdp* instance, XEvent* event) } xf_input_handle_event(xfc, event); - XSync(xfc->display, FALSE); - return status; } diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 96dd811..ca0b1b4 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -34,11 +34,12 @@ #include #include "xf_gdi.h" +#include "xf_graphics.h" #include #define TAG CLIENT_TAG("x11") -static UINT8 GDI_BS_HATCHED_PATTERNS[] = +static const UINT8 GDI_BS_HATCHED_PATTERNS[] = { 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, /* HS_HORIZONTAL */ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, /* HS_VERTICAL */ @@ -69,7 +70,7 @@ static const BYTE xf_rop2_table[] = GXset /* 1 */ }; -BOOL xf_set_rop2(xfContext* xfc, int rop2) +static BOOL xf_set_rop2(xfContext* xfc, int rop2) { if ((rop2 < 0x01) || (rop2 > 0x10)) { @@ -81,7 +82,7 @@ BOOL xf_set_rop2(xfContext* xfc, int rop2) return TRUE; } -BOOL xf_set_rop3(xfContext* xfc, int rop3) +static BOOL xf_set_rop3(xfContext* xfc, UINT32 rop3) { int function = -1; @@ -159,7 +160,7 @@ BOOL xf_set_rop3(xfContext* xfc, int rop3) function = GXequiv; break; - case GDI_D: + case GDI_DSTCOPY: function = GXnoop; break; @@ -215,84 +216,31 @@ BOOL xf_set_rop3(xfContext* xfc, int rop3) } XSetFunction(xfc->display, xfc->gc, function); - return TRUE; } -UINT32 xf_convert_rdp_order_color(xfContext* xfc, UINT32 color) -{ - UINT32 r = 0, g = 0, b = 0; - - switch (xfc->srcBpp) - { - case 32: - case 24: - if (xfc->visual->red_mask == 0xFF0000 && - xfc->visual->green_mask == 0xFF00 && - xfc->visual->blue_mask == 0xFF) - { - return color; - } - GetRGB32(r, g, b, color); - break; - - case 16: - color = (color & 0xFF00) | ((color >> 16) & 0xFF); - if (xfc->visual->red_mask == 0xF800 && - xfc->visual->green_mask == 0x07E0 && - xfc->visual->blue_mask == 0x001F) - { - return color; - } - GetRGB16(r, g, b, color); - break; - - case 15: - color = (color & 0xFF00) | ((color >> 16) & 0xFF); - GetRGB15(r, g, b, color); - break; - - case 8: - color = (color >> 16) & (UINT32) 0xFF; - if (xfc->palette) - { - r = xfc->palette[(color * 4) + 2]; - g = xfc->palette[(color * 4) + 1]; - b = xfc->palette[(color * 4) + 0]; - } - break; - - default: - return color; - } - - return ( ((r >> xfc->red_shift_r) << xfc->red_shift_l) | - ((g >> xfc->green_shift_r) << xfc->green_shift_l) | - ((b >> xfc->blue_shift_r) << xfc->blue_shift_l) ); -} - -Pixmap xf_brush_new(xfContext* xfc, int width, int height, int bpp, BYTE* data) +static Pixmap xf_brush_new(xfContext* xfc, UINT32 width, UINT32 height, + UINT32 bpp, + BYTE* data) { GC gc; Pixmap bitmap; BYTE* cdata; XImage* image; + rdpGdi* gdi; UINT32 brushFormat; - + gdi = xfc->context.gdi; bitmap = XCreatePixmap(xfc->display, xfc->drawable, width, height, xfc->depth); if (data) { - brushFormat = gdi_get_pixel_format(bpp, FALSE); - + brushFormat = gdi_get_pixel_format(bpp); cdata = (BYTE*) _aligned_malloc(width * height * 4, 16); - - freerdp_image_copy(cdata, xfc->format, -1, 0, 0, - width, height, data, brushFormat, -1, 0, 0, xfc->palette); - + freerdp_image_copy(cdata, gdi->dstFormat, 0, 0, 0, + width, height, data, brushFormat, 0, 0, 0, + &xfc->context.gdi->palette, FREERDP_FLIP_NONE); image = XCreateImage(xfc->display, xfc->visual, xfc->depth, - ZPixmap, 0, (char*) cdata, width, height, xfc->scanline_pad, 0); - + ZPixmap, 0, (char*) cdata, width, height, xfc->scanline_pad, 0); gc = XCreateGC(xfc->display, xfc->drawable, 0, NULL); XPutImage(xfc->display, bitmap, gc, image, 0, 0, 0, 0, width, height); XFree(image); @@ -306,174 +254,26 @@ Pixmap xf_brush_new(xfContext* xfc, int width, int height, int bpp, BYTE* data) return bitmap; } -Pixmap xf_mono_bitmap_new(xfContext* xfc, int width, int height, BYTE* data) +static Pixmap xf_mono_bitmap_new(xfContext* xfc, int width, int height, + const BYTE* data) { int scanline; XImage* image; Pixmap bitmap; - scanline = (width + 7) / 8; - bitmap = XCreatePixmap(xfc->display, xfc->drawable, width, height, 1); - image = XCreateImage(xfc->display, xfc->visual, 1, - ZPixmap, 0, (char*) data, width, height, 8, scanline); - + ZPixmap, 0, (char*) data, width, height, 8, scanline); XPutImage(xfc->display, bitmap, xfc->gc_mono, image, 0, 0, 0, 0, width, height); XFree(image); - return bitmap; } -BOOL xf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) -{ - int status; - int nXDst; - int nYDst; - int nXSrc; - int nYSrc; - int nWidth; - int nHeight; - UINT32 index; - XImage* image; - BYTE* pSrcData; - BYTE* pDstData; - UINT32 SrcSize; - BOOL compressed; - UINT32 SrcFormat; - UINT32 bitsPerPixel; - UINT32 bytesPerPixel; - BITMAP_DATA* bitmap; - rdpCodecs* codecs = context->codecs; - xfContext* xfc = (xfContext*) context; - BOOL ret = TRUE; - - for (index = 0; index < bitmapUpdate->number; index++) - { - bitmap = &(bitmapUpdate->rectangles[index]); - - nXSrc = 0; - nYSrc = 0; - - nXDst = bitmap->destLeft; - nYDst = bitmap->destTop; - - nWidth = bitmap->width; - nHeight = bitmap->height; - - pSrcData = bitmap->bitmapDataStream; - SrcSize = bitmap->bitmapLength; - - compressed = bitmap->compressed; - bitsPerPixel = bitmap->bitsPerPixel; - bytesPerPixel = (bitsPerPixel + 7) / 8; - - SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE); - - if (xfc->bitmap_size < (nWidth * nHeight * 4)) - { - xfc->bitmap_size = nWidth * nHeight * 4; - xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); - - if (!xfc->bitmap_buffer) - return FALSE; - } - - if (compressed) - { - pDstData = xfc->bitmap_buffer; - - if (bitsPerPixel < 32) - { - if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED)) - return FALSE; - - status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel, - &pDstData, xfc->format, -1, 0, 0, nWidth, nHeight, xfc->palette); - } - else - { - if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR)) - return FALSE; - - status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData, - xfc->format, -1, 0, 0, nWidth, nHeight, TRUE); - } - - if (status < 0) - { - WLog_ERR(TAG, "bitmap decompression failure"); - return FALSE; - } - - pSrcData = xfc->bitmap_buffer; - } - else - { - pDstData = xfc->bitmap_buffer; - - status = freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, - nWidth, nHeight, pSrcData, SrcFormat, -1, 0, 0, xfc->palette); - - pSrcData = xfc->bitmap_buffer; - } - - xf_lock_x11(xfc, FALSE); - - XSetFunction(xfc->display, xfc->gc, GXcopy); - - image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char*) pSrcData, nWidth, nHeight, xfc->scanline_pad, 0); - if (!image) - { - xf_unlock_x11(xfc, FALSE); - return FALSE; - } - - nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */ - nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */ - - XPutImage(xfc->display, xfc->primary, xfc->gc, - image, 0, 0, nXDst, nYDst, nWidth, nHeight); - - XFree(image); - - ret = gdi_InvalidateRegion(xfc->hdc, nXDst, nYDst, nWidth, nHeight); - - xf_unlock_x11(xfc, FALSE); - - if (!ret) - break; - } - return ret; -} - -static BOOL xf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) -{ - int index; - PALETTE_ENTRY* pe; - UINT32* palette32; - xfContext* xfc = (xfContext*) context; - - xf_lock_x11(xfc, FALSE); - - palette32 = (UINT32*) xfc->palette; - - for (index = 0; index < palette->number; index++) - { - pe = &(palette->entries[index]); - palette32[index] = RGB32(pe->red, pe->green, pe->blue); - } - - xf_unlock_x11(xfc, FALSE); - return TRUE; -} - -static BOOL xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds) +static BOOL xf_gdi_set_bounds(rdpContext* context, + const rdpBounds* bounds) { XRectangle clip; xfContext* xfc = (xfContext*) context; - xf_lock_x11(xfc, FALSE); if (bounds) @@ -493,190 +293,203 @@ static BOOL xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds) return TRUE; } -static BOOL xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) +static BOOL xf_gdi_dstblt(rdpContext* context, const DSTBLT_ORDER* dstblt) { xfContext* xfc = (xfContext*) context; - BOOL ret = TRUE; - + BOOL ret = FALSE; xf_lock_x11(xfc, FALSE); - xf_set_rop3(xfc, gdi_rop3_code(dstblt->bRop)); + if (!xf_set_rop3(xfc, gdi_rop3_code(dstblt->bRop))) + goto fail; XSetFillStyle(xfc->display, xfc->gc, FillSolid); XFillRectangle(xfc->display, xfc->drawing, xfc->gc, - dstblt->nLeftRect, dstblt->nTopRect, - dstblt->nWidth, dstblt->nHeight); + dstblt->nLeftRect, dstblt->nTopRect, + dstblt->nWidth, dstblt->nHeight); if (xfc->drawing == xfc->primary) - ret = gdi_InvalidateRegion(xfc->hdc, dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight); + ret = gdi_InvalidateRegion(xfc->hdc, dstblt->nLeftRect, dstblt->nTopRect, + dstblt->nWidth, dstblt->nHeight); + ret = TRUE; +fail: XSetFunction(xfc->display, xfc->gc, GXcopy); - xf_unlock_x11(xfc, FALSE); return ret; } static BOOL xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { - Pixmap pattern; - rdpBrush* brush; + const rdpBrush* brush; UINT32 foreColor; UINT32 backColor; xfContext* xfc = (xfContext*) context; - BOOL ret = TRUE; + BOOL ret = FALSE; + + if (!xf_decode_color(context->gdi, patblt->foreColor, &foreColor, NULL)) + return FALSE; + + if (!xf_decode_color(context->gdi, patblt->backColor, &backColor, NULL)) + return FALSE; xf_lock_x11(xfc, FALSE); - brush = &patblt->brush; - xf_set_rop3(xfc, gdi_rop3_code(patblt->bRop)); - foreColor = xf_convert_rdp_order_color(xfc, patblt->foreColor); - backColor = xf_convert_rdp_order_color(xfc, patblt->backColor); + if (!xf_set_rop3(xfc, gdi_rop3_code(patblt->bRop))) + goto fail; - if (brush->style == GDI_BS_SOLID) + switch (brush->style) { - XSetFillStyle(xfc->display, xfc->gc, FillSolid); - XSetForeground(xfc->display, xfc->gc, foreColor); - - XFillRectangle(xfc->display, xfc->drawing, xfc->gc, - patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); - } - else if (brush->style == GDI_BS_HATCHED) - { - pattern = xf_mono_bitmap_new(xfc, 8, 8, GDI_BS_HATCHED_PATTERNS + 8 * brush->hatch); - - XSetForeground(xfc->display, xfc->gc, backColor); - XSetBackground(xfc->display, xfc->gc, foreColor); - XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); - XSetStipple(xfc->display, xfc->gc, pattern); - XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); - - XFillRectangle(xfc->display, xfc->drawing, xfc->gc, - patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); - - XFreePixmap(xfc->display, pattern); - } - else if (brush->style == GDI_BS_PATTERN) - { - if (brush->bpp > 1) - { - pattern = xf_brush_new(xfc, 8, 8, brush->bpp, brush->data); - - XSetFillStyle(xfc->display, xfc->gc, FillTiled); - XSetTile(xfc->display, xfc->gc, pattern); - XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); - + case GDI_BS_SOLID: + XSetFillStyle(xfc->display, xfc->gc, FillSolid); + XSetBackground(xfc->display, xfc->gc, backColor); + XSetForeground(xfc->display, xfc->gc, foreColor); XFillRectangle(xfc->display, xfc->drawing, xfc->gc, - patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + break; - XSetTile(xfc->display, xfc->gc, xfc->primary); + case GDI_BS_HATCHED: + { + Pixmap pattern = xf_mono_bitmap_new(xfc, 8, 8, + &GDI_BS_HATCHED_PATTERNS[8 * brush->hatch]); + XSetBackground(xfc->display, xfc->gc, backColor); + XSetForeground(xfc->display, xfc->gc, foreColor); + XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); + XSetStipple(xfc->display, xfc->gc, pattern); + XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); + XFillRectangle(xfc->display, xfc->drawing, xfc->gc, + patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + XFreePixmap(xfc->display, pattern); + } + break; - XFreePixmap(xfc->display, pattern); - } - else - { - pattern = xf_mono_bitmap_new(xfc, 8, 8, brush->data); + case GDI_BS_PATTERN: + if (brush->bpp > 1) + { + Pixmap pattern = xf_brush_new(xfc, 8, 8, brush->bpp, brush->data); + XSetFillStyle(xfc->display, xfc->gc, FillTiled); + XSetTile(xfc->display, xfc->gc, pattern); + XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); + XFillRectangle(xfc->display, xfc->drawing, xfc->gc, + patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + XSetTile(xfc->display, xfc->gc, xfc->primary); + XFreePixmap(xfc->display, pattern); + } + else + { + Pixmap pattern = xf_mono_bitmap_new(xfc, 8, 8, brush->data); + XSetBackground(xfc->display, xfc->gc, backColor); + XSetForeground(xfc->display, xfc->gc, foreColor); + XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); + XSetStipple(xfc->display, xfc->gc, pattern); + XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); + XFillRectangle(xfc->display, xfc->drawing, xfc->gc, + patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + XFreePixmap(xfc->display, pattern); + } - XSetForeground(xfc->display, xfc->gc, backColor); - XSetBackground(xfc->display, xfc->gc, foreColor); - XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); - XSetStipple(xfc->display, xfc->gc, pattern); - XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); + break; - XFillRectangle(xfc->display, xfc->drawing, xfc->gc, - patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); - - XFreePixmap(xfc->display, pattern); - } - } - else - { - WLog_ERR(TAG, "unimplemented brush style:%d", brush->style); + default: + WLog_ERR(TAG, "unimplemented brush style:%d", brush->style); + goto fail; } if (xfc->drawing == xfc->primary) - ret = gdi_InvalidateRegion(xfc->hdc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + ret = gdi_InvalidateRegion(xfc->hdc, patblt->nLeftRect, patblt->nTopRect, + patblt->nWidth, patblt->nHeight); + ret = TRUE; +fail: XSetFunction(xfc->display, xfc->gc, GXcopy); - xf_unlock_x11(xfc, FALSE); return ret; } -static BOOL xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) +static BOOL xf_gdi_scrblt(rdpContext* context, const SCRBLT_ORDER* scrblt) { xfContext* xfc = (xfContext*) context; - BOOL ret = TRUE; + BOOL ret = FALSE; + + if (!xfc->display || !xfc->drawing) + return FALSE; xf_lock_x11(xfc, FALSE); - xf_set_rop3(xfc, gdi_rop3_code(scrblt->bRop)); + if (!xf_set_rop3(xfc, gdi_rop3_code(scrblt->bRop))) + goto fail; - XCopyArea(xfc->display, xfc->primary, xfc->drawing, xfc->gc, scrblt->nXSrc, scrblt->nYSrc, - scrblt->nWidth, scrblt->nHeight, scrblt->nLeftRect, scrblt->nTopRect); + XCopyArea(xfc->display, xfc->primary, xfc->drawing, xfc->gc, scrblt->nXSrc, + scrblt->nYSrc, + scrblt->nWidth, scrblt->nHeight, scrblt->nLeftRect, scrblt->nTopRect); if (xfc->drawing == xfc->primary) - ret = gdi_InvalidateRegion(xfc->hdc, scrblt->nLeftRect, scrblt->nTopRect, scrblt->nWidth, scrblt->nHeight); + ret = gdi_InvalidateRegion(xfc->hdc, scrblt->nLeftRect, scrblt->nTopRect, + scrblt->nWidth, scrblt->nHeight); XSetFunction(xfc->display, xfc->gc, GXcopy); - + ret = TRUE; +fail: xf_unlock_x11(xfc, FALSE); return ret; } -BOOL xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) +static BOOL xf_gdi_opaque_rect(rdpContext* context, + const OPAQUE_RECT_ORDER* opaque_rect) { UINT32 color; + rdpGdi* gdi = context->gdi; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; + if (!xf_decode_color(gdi, opaque_rect->color, &color, NULL)) + return FALSE; + xf_lock_x11(xfc, FALSE); - - color = xf_convert_rdp_order_color(xfc, opaque_rect->color); - XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); - XFillRectangle(xfc->display, xfc->drawing, xfc->gc, - opaque_rect->nLeftRect, opaque_rect->nTopRect, - opaque_rect->nWidth, opaque_rect->nHeight); + opaque_rect->nLeftRect, opaque_rect->nTopRect, + opaque_rect->nWidth, opaque_rect->nHeight); if (xfc->drawing == xfc->primary) - ret = gdi_InvalidateRegion(xfc->hdc, opaque_rect->nLeftRect, opaque_rect->nTopRect, - opaque_rect->nWidth, opaque_rect->nHeight); + ret = gdi_InvalidateRegion(xfc->hdc, opaque_rect->nLeftRect, + opaque_rect->nTopRect, + opaque_rect->nWidth, opaque_rect->nHeight); xf_unlock_x11(xfc, FALSE); return ret; } -BOOL xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +static BOOL xf_gdi_multi_opaque_rect(rdpContext* context, + const MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) { - int i; - UINT32 color; - DELTA_RECT* rectangle; + UINT32 i; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; + rdpGdi* gdi = context->gdi; + UINT32 color; + + if (!xf_decode_color(gdi, multi_opaque_rect->color, &color, NULL)) + return FALSE; xf_lock_x11(xfc, FALSE); - - color = xf_convert_rdp_order_color(xfc, multi_opaque_rect->color); - XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); - for (i = 1; i < multi_opaque_rect->numRectangles + 1; i++) + for (i = 0; i < multi_opaque_rect->numRectangles; i++) { - rectangle = &multi_opaque_rect->rectangles[i]; - + const DELTA_RECT* rectangle = &multi_opaque_rect->rectangles[i]; XFillRectangle(xfc->display, xfc->drawing, xfc->gc, - rectangle->left, rectangle->top, - rectangle->width, rectangle->height); + rectangle->left, rectangle->top, + rectangle->width, rectangle->height); if (xfc->drawing == xfc->primary) { - if (!(ret = gdi_InvalidateRegion(xfc->hdc, rectangle->left, rectangle->top, rectangle->width, rectangle->height))) + if (!(ret = gdi_InvalidateRegion(xfc->hdc, rectangle->left, rectangle->top, + rectangle->width, rectangle->height))) break; } } @@ -685,48 +498,39 @@ BOOL xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult return ret; } -void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid) -{ - WLog_ERR(TAG, "DrawNineGrid"); -} - -BOOL xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) +static BOOL xf_gdi_line_to(rdpContext* context, const LINE_TO_ORDER* line_to) { UINT32 color; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; + if (!xf_decode_color(context->gdi, line_to->penColor, &color, NULL)) + return FALSE; + xf_lock_x11(xfc, FALSE); - xf_set_rop2(xfc, line_to->bRop2); - color = xf_convert_rdp_order_color(xfc, line_to->penColor); - XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); - XDrawLine(xfc->display, xfc->drawing, xfc->gc, - line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd); + line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd); if (xfc->drawing == xfc->primary) { int x, y, w, h; - x = MIN(line_to->nXStart, line_to->nXEnd); y = MIN(line_to->nYStart, line_to->nYEnd); - w = abs(line_to->nXEnd - line_to->nXStart) + 1; h = abs(line_to->nYEnd - line_to->nYStart) + 1; - ret = gdi_InvalidateRegion(xfc->hdc, x, y, w, h); } XSetFunction(xfc->display, xfc->gc, GXcopy); - xf_unlock_x11(xfc, FALSE); return ret; } -static BOOL xf_gdi_invalidate_poly_region(xfContext* xfc, XPoint* points, int npoints) +static BOOL xf_gdi_invalidate_poly_region(xfContext* xfc, XPoint* points, + int npoints) { int x, y, x1, y1, x2, y2; @@ -744,21 +548,24 @@ static BOOL xf_gdi_invalidate_poly_region(xfContext* xfc, XPoint* points, int np if (x > x2) x2 = x; + if (x < x1) x1 = x; + if (y > y2) y2 = y; + if (y < y1) y1 = y; } x2++; y2++; - return gdi_InvalidateRegion(xfc->hdc, x1, y1, x2 - x1, y2 - y1); } -BOOL xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) +static BOOL xf_gdi_polyline(rdpContext* context, + const POLYLINE_ORDER* polyline) { int i; int npoints; @@ -767,16 +574,16 @@ BOOL xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; + if (!xf_decode_color(context->gdi, polyline->penColor, &color, NULL)) + return FALSE; + xf_lock_x11(xfc, FALSE); - xf_set_rop2(xfc, polyline->bRop2); - color = xf_convert_rdp_order_color(xfc, polyline->penColor); - XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); - npoints = polyline->numDeltaEntries + 1; points = malloc(sizeof(XPoint) * npoints); + if (!points) { xf_unlock_x11(xfc, FALSE); @@ -792,7 +599,8 @@ BOOL xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) points[i + 1].y = polyline->points[i].y; } - XDrawLines(xfc->display, xfc->drawing, xfc->gc, points, npoints, CoordModePrevious); + XDrawLines(xfc->display, xfc->drawing, xfc->gc, points, npoints, + CoordModePrevious); if (xfc->drawing == xfc->primary) { @@ -802,93 +610,111 @@ BOOL xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) XSetFunction(xfc->display, xfc->gc, GXcopy); free(points); - xf_unlock_x11(xfc, FALSE); return ret; } -BOOL xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) +static BOOL xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) { xfBitmap* bitmap; - xfContext* xfc = (xfContext*) context; + xfContext* xfc; BOOL ret = TRUE; + if (!context || !memblt) + return FALSE; + + bitmap = (xfBitmap*) memblt->bitmap; + xfc = (xfContext*) context; + + if (!bitmap || !xfc || !xfc->display || !xfc->drawing) + return FALSE; + xf_lock_x11(xfc, FALSE); - bitmap = (xfBitmap*) memblt->bitmap; - xf_set_rop3(xfc, gdi_rop3_code(memblt->bRop)); + if (xf_set_rop3(xfc, gdi_rop3_code(memblt->bRop))) + { + XCopyArea(xfc->display, bitmap->pixmap, xfc->drawing, xfc->gc, + memblt->nXSrc, memblt->nYSrc, memblt->nWidth, memblt->nHeight, + memblt->nLeftRect, memblt->nTopRect); - XCopyArea(xfc->display, bitmap->pixmap, xfc->drawing, xfc->gc, - memblt->nXSrc, memblt->nYSrc, memblt->nWidth, memblt->nHeight, - memblt->nLeftRect, memblt->nTopRect); - - if (xfc->drawing == xfc->primary) - ret = gdi_InvalidateRegion(xfc->hdc, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight); + if (xfc->drawing == xfc->primary) + ret = gdi_InvalidateRegion(xfc->hdc, memblt->nLeftRect, + memblt->nTopRect, memblt->nWidth, + memblt->nHeight); + } XSetFunction(xfc->display, xfc->gc, GXcopy); - xf_unlock_x11(xfc, FALSE); return ret; } -BOOL xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) +static BOOL xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) { - rdpBrush* brush; + const rdpBrush* brush; xfBitmap* bitmap; UINT32 foreColor; UINT32 backColor; Pixmap pattern = 0; xfContext* xfc = (xfContext*) context; - BOOL ret = TRUE; + BOOL ret = FALSE; + + if (!xfc->display || !xfc->drawing) + return FALSE; + + if (!xf_decode_color(context->gdi, mem3blt->foreColor, &foreColor, NULL)) + return FALSE; + + if (!xf_decode_color(context->gdi, mem3blt->backColor, &backColor, NULL)) + return FALSE; xf_lock_x11(xfc, FALSE); - brush = &mem3blt->brush; bitmap = (xfBitmap*) mem3blt->bitmap; - xf_set_rop3(xfc, gdi_rop3_code(mem3blt->bRop)); - foreColor = xf_convert_rdp_order_color(xfc, mem3blt->foreColor); - backColor = xf_convert_rdp_order_color(xfc, mem3blt->backColor); - if (brush->style == GDI_BS_PATTERN) + if (!xf_set_rop3(xfc, gdi_rop3_code(mem3blt->bRop))) + goto fail; + + switch (brush->style) { - if (brush->bpp > 1) - { - pattern = xf_brush_new(xfc, 8, 8, brush->bpp, brush->data); + case GDI_BS_PATTERN: + if (brush->bpp > 1) + { + pattern = xf_brush_new(xfc, 8, 8, brush->bpp, brush->data); + XSetFillStyle(xfc->display, xfc->gc, FillTiled); + XSetTile(xfc->display, xfc->gc, pattern); + XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); + } + else + { + pattern = xf_mono_bitmap_new(xfc, 8, 8, brush->data); + XSetBackground(xfc->display, xfc->gc, backColor); + XSetForeground(xfc->display, xfc->gc, foreColor); + XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); + XSetStipple(xfc->display, xfc->gc, pattern); + XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); + } - XSetFillStyle(xfc->display, xfc->gc, FillTiled); - XSetTile(xfc->display, xfc->gc, pattern); + break; + + case GDI_BS_SOLID: + XSetFillStyle(xfc->display, xfc->gc, FillSolid); + XSetBackground(xfc->display, xfc->gc, backColor); + XSetForeground(xfc->display, xfc->gc, foreColor); XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); - } - else - { - pattern = xf_mono_bitmap_new(xfc, 8, 8, brush->data); + break; - XSetForeground(xfc->display, xfc->gc, backColor); - XSetBackground(xfc->display, xfc->gc, foreColor); - XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); - XSetStipple(xfc->display, xfc->gc, pattern); - XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); - } - } - else if (brush->style == GDI_BS_SOLID) - { - XSetFillStyle(xfc->display, xfc->gc, FillSolid); - XSetForeground(xfc->display, xfc->gc, backColor); - XSetBackground(xfc->display, xfc->gc, foreColor); - - XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); - } - else - { - WLog_ERR(TAG, "Mem3Blt unimplemented brush style:%d", brush->style); + default: + WLog_ERR(TAG, "Mem3Blt unimplemented brush style:%d", brush->style); + goto fail; } XCopyArea(xfc->display, bitmap->pixmap, xfc->drawing, xfc->gc, - mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight, - mem3blt->nLeftRect, mem3blt->nTopRect); + mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight, + mem3blt->nLeftRect, mem3blt->nTopRect); if (xfc->drawing == xfc->primary) - ret = gdi_InvalidateRegion(xfc->hdc, mem3blt->nLeftRect, mem3blt->nTopRect, mem3blt->nWidth, mem3blt->nHeight); + ret = gdi_InvalidateRegion(xfc->hdc, mem3blt->nLeftRect, mem3blt->nTopRect, + mem3blt->nWidth, mem3blt->nHeight); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetTSOrigin(xfc->display, xfc->gc, 0, 0); @@ -896,14 +722,16 @@ BOOL xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) if (pattern != 0) XFreePixmap(xfc->display, pattern); + ret = TRUE; +fail: XSetFunction(xfc->display, xfc->gc, GXcopy); - xf_unlock_x11(xfc, FALSE); return ret; } -BOOL xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) +static BOOL xf_gdi_polygon_sc(rdpContext* context, + const POLYGON_SC_ORDER* polygon_sc) { int i, npoints; XPoint* points; @@ -911,13 +739,14 @@ BOOL xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; + if (!xf_decode_color(context->gdi, polygon_sc->brushColor, &brush_color, NULL)) + return FALSE; + xf_lock_x11(xfc, FALSE); - xf_set_rop2(xfc, polygon_sc->bRop2); - brush_color = xf_convert_rdp_order_color(xfc, polygon_sc->brushColor); - npoints = polygon_sc->numPoints + 1; points = malloc(sizeof(XPoint) * npoints); + if (!points) { xf_unlock_x11(xfc, FALSE); @@ -950,9 +779,8 @@ BOOL xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, brush_color); - XFillPolygon(xfc->display, xfc->drawing, xfc->gc, - points, npoints, Complex, CoordModePrevious); + points, npoints, Complex, CoordModePrevious); if (xfc->drawing == xfc->primary) { @@ -962,31 +790,34 @@ BOOL xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) XSetFunction(xfc->display, xfc->gc, GXcopy); free(points); - xf_unlock_x11(xfc, FALSE); return ret; } -BOOL xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) +static BOOL xf_gdi_polygon_cb(rdpContext* context, + POLYGON_CB_ORDER* polygon_cb) { int i, npoints; XPoint* points; Pixmap pattern; - rdpBrush* brush; + const rdpBrush* brush; UINT32 foreColor; UINT32 backColor; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - xf_lock_x11(xfc, FALSE); + if (!xf_decode_color(context->gdi, polygon_cb->foreColor, &foreColor, NULL)) + return FALSE; + if (!xf_decode_color(context->gdi, polygon_cb->backColor, &backColor, NULL)) + return FALSE; + + xf_lock_x11(xfc, FALSE); brush = &(polygon_cb->brush); xf_set_rop2(xfc, polygon_cb->bRop2); - foreColor = xf_convert_rdp_order_color(xfc, polygon_cb->foreColor); - backColor = xf_convert_rdp_order_color(xfc, polygon_cb->backColor); - npoints = polygon_cb->numPoints + 1; points = malloc(sizeof(XPoint) * npoints); + if (!points) { xf_unlock_x11(xfc, FALSE); @@ -1022,14 +853,12 @@ BOOL xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) if (brush->bpp > 1) { pattern = xf_brush_new(xfc, 8, 8, brush->bpp, brush->data); - XSetFillStyle(xfc->display, xfc->gc, FillTiled); XSetTile(xfc->display, xfc->gc, pattern); } else { pattern = xf_mono_bitmap_new(xfc, 8, 8, brush->data); - XSetForeground(xfc->display, xfc->gc, backColor); XSetBackground(xfc->display, xfc->gc, foreColor); @@ -1042,10 +871,8 @@ BOOL xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) } XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); - XFillPolygon(xfc->display, xfc->drawing, xfc->gc, - points, npoints, Complex, CoordModePrevious); - + points, npoints, Complex, CoordModePrevious); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetTSOrigin(xfc->display, xfc->gc, 0, 0); XFreePixmap(xfc->display, pattern); @@ -1063,37 +890,17 @@ BOOL xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) XSetFunction(xfc->display, xfc->gc, GXcopy); free(points); - xf_unlock_x11(xfc, FALSE); return ret; } -BOOL xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc) -{ - WLog_ERR(TAG, "Not implemented: EllipseSC"); - return TRUE; -} - -BOOL xf_gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb) -{ - WLog_ERR(TAG, "Not implemented: EllipseCB"); - return TRUE; -} - -BOOL xf_gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker) -{ - return TRUE; -} - -BOOL xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) +static BOOL xf_gdi_surface_frame_marker(rdpContext* context, + const SURFACE_FRAME_MARKER* surface_frame_marker) { rdpSettings* settings; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - - settings = xfc->instance->settings; - - + settings = xfc->context.settings; xf_lock_x11(xfc, FALSE); switch (surface_frame_marker->frameAction) @@ -1108,13 +915,17 @@ BOOL xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surf case SURFACECMD_FRAMEACTION_END: xfc->frame_begin = FALSE; + if ((xfc->frame_x2 > xfc->frame_x1) && (xfc->frame_y2 > xfc->frame_y1)) ret = gdi_InvalidateRegion(xfc->hdc, xfc->frame_x1, xfc->frame_y1, - xfc->frame_x2 - xfc->frame_x1, xfc->frame_y2 - xfc->frame_y1); + xfc->frame_x2 - xfc->frame_x1, xfc->frame_y2 - xfc->frame_y1); + if (settings->FrameAcknowledge > 0) { - IFCALL(xfc->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId); + IFCALL(xfc->context.update->SurfaceFrameAcknowledge, context, + surface_frame_marker->frameId); } + break; } @@ -1122,9 +933,11 @@ BOOL xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surf return ret; } -static BOOL xf_gdi_surface_update_frame(xfContext* xfc, UINT16 tx, UINT16 ty, UINT16 width, UINT16 height) +static BOOL xf_gdi_surface_update_frame(xfContext* xfc, UINT16 tx, UINT16 ty, + UINT16 width, UINT16 height) { BOOL ret = TRUE; + if (!xfc->remote_app) { if (xfc->frame_begin) @@ -1153,179 +966,100 @@ static BOOL xf_gdi_surface_update_frame(xfContext* xfc, UINT16 tx, UINT16 ty, UI { ret = gdi_InvalidateRegion(xfc->hdc, tx, ty, width, height); } + return ret; } -BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) +static BOOL xf_gdi_update_screen(xfContext* xfc, + const SURFACE_BITS_COMMAND* cmd, + const BYTE* pSrcData) { - int i, tx, ty; + BOOL ret = FALSE; XImage* image; - BYTE* pSrcData; - BYTE* pDstData; - RFX_MESSAGE* message; - xfContext* xfc = (xfContext*) context; - BOOL ret = TRUE; + if (!xfc || !pSrcData) + return FALSE; + + XSetFunction(xfc->display, xfc->gc, GXcopy); + XSetFillStyle(xfc->display, xfc->gc, FillSolid); + image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, + (char*) pSrcData, cmd->width, cmd->height, xfc->scanline_pad, 0); + + if (image) + { + XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, + cmd->destLeft, cmd->destTop, cmd->width, cmd->height); + XFree(image); + ret = xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, + cmd->height); + } + + XSetClipMask(xfc->display, xfc->gc, None); + return ret; +} + +static BOOL xf_gdi_surface_bits(rdpContext* context, + const SURFACE_BITS_COMMAND* cmd) +{ + BYTE* pSrcData; + xfContext* xfc = (xfContext*) context; + BOOL ret = FALSE; + DWORD format; + DWORD stride; + rdpGdi* gdi; + + if (!context || !cmd || !context->gdi) + return FALSE; + + gdi = context->gdi; + stride = cmd->width * GetBytesPerPixel(gdi->dstFormat); xf_lock_x11(xfc, FALSE); - if (cmd->codecID == RDP_CODEC_ID_REMOTEFX) + switch (cmd->codecID) { - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX)) - { - xf_unlock_x11(xfc, FALSE); - return FALSE; - } + case RDP_CODEC_ID_REMOTEFX: + format = PIXEL_FORMAT_BGRX32; - if (!(message = rfx_process_message(xfc->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength))) - { - WLog_ERR(TAG, "Failed to process RemoteFX message"); - xf_unlock_x11(xfc, FALSE); - return FALSE; - } + if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, + format, cmd->bitmapDataLength, + 0, 0, + gdi->primary_buffer, gdi->dstFormat, stride, + gdi->height, NULL)) + goto fail; - XSetFunction(xfc->display, xfc->gc, GXcopy); - XSetFillStyle(xfc->display, xfc->gc, FillSolid); + break; - XSetClipRectangles(xfc->display, xfc->gc, cmd->destLeft, cmd->destTop, - (XRectangle*) message->rects, message->numRects, YXBanded); + case RDP_CODEC_ID_NSCODEC: + format = gdi->dstFormat; - if (xfc->bitmap_size < (64 * 64 * 4)) - { - xfc->bitmap_size = 64 * 64 * 4; - xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); + if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width, + cmd->height, cmd->bitmapData, cmd->bitmapDataLength, + gdi->primary_buffer, format, stride, + 0, 0, cmd->width, cmd->height, FREERDP_FLIP_VERTICAL)) + goto fail; - if (!xfc->bitmap_buffer) - { - rfx_message_free(xfc->codecs->rfx, message); - XSetClipMask(xfc->display, xfc->gc, None); - xf_unlock_x11(xfc, FALSE); - return FALSE; - } - } + break; - /* Draw the tiles to primary surface, each is 64x64. */ - for (i = 0; i < message->numTiles; i++) - { - pSrcData = message->tiles[i]->data; - pDstData = pSrcData; + case RDP_CODEC_ID_NONE: + pSrcData = cmd->bitmapData; + format = PIXEL_FORMAT_BGRX32; - if ((xfc->depth != 24) || (xfc->depth != 32)) - { - pDstData = xfc->bitmap_buffer; + if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, stride, + 0, 0, + cmd->width, cmd->height, pSrcData, + format, 0, 0, 0, &xfc->context.gdi->palette, FREERDP_FLIP_VERTICAL)) + goto fail; - freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, - 64, 64, pSrcData, PIXEL_FORMAT_XRGB32, -1, 0, 0, xfc->palette); - } + break; - image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char*) pDstData, 64, 64, xfc->scanline_pad, 0); - - tx = message->tiles[i]->x + cmd->destLeft; - ty = message->tiles[i]->y + cmd->destTop; - - XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, tx, ty, 64, 64); - XFree(image); - } - - /* Invalidate the updated region */ - for (i = 0; i < message->numRects; i++) - { - tx = message->rects[i].x + cmd->destLeft; - ty = message->rects[i].y + cmd->destTop; - - if (!xf_gdi_surface_update_frame(xfc, tx, ty, message->rects[i].width, message->rects[i].height)) - { - ret = FALSE; - break; - } - } - - XSetClipMask(xfc->display, xfc->gc, None); - rfx_message_free(xfc->codecs->rfx, message); - } - else if (cmd->codecID == RDP_CODEC_ID_NSCODEC) - { - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC)) - { - xf_unlock_x11(xfc, FALSE); - return FALSE; - } - - nsc_process_message(xfc->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength); - - XSetFunction(xfc->display, xfc->gc, GXcopy); - XSetFillStyle(xfc->display, xfc->gc, FillSolid); - - if (xfc->bitmap_size < (cmd->width * cmd->height * 4)) - { - xfc->bitmap_size = cmd->width * cmd->height * 4; - xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); - - if (!xfc->bitmap_buffer) - { - xf_unlock_x11(xfc, FALSE); - return FALSE; - } - } - - pSrcData = xfc->codecs->nsc->BitmapData; - pDstData = xfc->bitmap_buffer; - - freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, - cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, xfc->palette); - - image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0); - - XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, - cmd->destLeft, cmd->destTop, cmd->width, cmd->height); - - XFree(image); - - ret = xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); - - XSetClipMask(xfc->display, xfc->gc, None); - } - else if (cmd->codecID == RDP_CODEC_ID_NONE) - { - XSetFunction(xfc->display, xfc->gc, GXcopy); - XSetFillStyle(xfc->display, xfc->gc, FillSolid); - - if (xfc->bitmap_size < (cmd->width * cmd->height * 4)) - { - xfc->bitmap_size = cmd->width * cmd->height * 4; - xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); - - if (!xfc->bitmap_buffer) - { - xf_unlock_x11(xfc, FALSE); - return FALSE; - } - } - - pSrcData = cmd->bitmapData; - pDstData = xfc->bitmap_buffer; - - freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, - cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, xfc->palette); - - image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0); - - XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, - cmd->destLeft, cmd->destTop, - cmd->width, cmd->height); - XFree(image); - - ret = xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); - - XSetClipMask(xfc->display, xfc->gc, None); - } - else - { - WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID); + default: + WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID); + ret = TRUE; + goto fail; } + ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); +fail: xf_unlock_x11(xfc, FALSE); return ret; } @@ -1333,36 +1067,19 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) void xf_gdi_register_update_callbacks(rdpUpdate* update) { rdpPrimaryUpdate* primary = update->primary; - - update->Palette = xf_gdi_palette_update; update->SetBounds = xf_gdi_set_bounds; - primary->DstBlt = xf_gdi_dstblt; primary->PatBlt = xf_gdi_patblt; primary->ScrBlt = xf_gdi_scrblt; primary->OpaqueRect = xf_gdi_opaque_rect; - primary->DrawNineGrid = NULL; - primary->MultiDstBlt = NULL; - primary->MultiPatBlt = NULL; - primary->MultiScrBlt = NULL; primary->MultiOpaqueRect = xf_gdi_multi_opaque_rect; - primary->MultiDrawNineGrid = NULL; primary->LineTo = xf_gdi_line_to; primary->Polyline = xf_gdi_polyline; primary->MemBlt = xf_gdi_memblt; primary->Mem3Blt = xf_gdi_mem3blt; - primary->SaveBitmap = NULL; - primary->GlyphIndex = NULL; - primary->FastIndex = NULL; - primary->FastGlyph = NULL; primary->PolygonSC = xf_gdi_polygon_sc; primary->PolygonCB = xf_gdi_polygon_cb; - primary->EllipseSC = xf_gdi_ellipse_sc; - primary->EllipseCB = xf_gdi_ellipse_cb; - update->SurfaceBits = xf_gdi_surface_bits; update->SurfaceFrameMarker = xf_gdi_surface_frame_marker; - - update->altsec->FrameMarker = xf_gdi_frame_marker; } diff --git a/client/X11/xf_gdi.h b/client/X11/xf_gdi.h index 5467d89..f11bd0b 100644 --- a/client/X11/xf_gdi.h +++ b/client/X11/xf_gdi.h @@ -3,6 +3,8 @@ * X11 GDI * * Copyright 2011 Marc-Andre Moreau + * Copyright 2016 Thincast Technologies GmbH + * Copyright 2016 Armin Novak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +28,5 @@ #include "xfreerdp.h" void xf_gdi_register_update_callbacks(rdpUpdate* update); -BOOL xf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate); -UINT32 xf_convert_rdp_order_color(xfContext* xfc, UINT32 color); #endif /* __XF_GDI_H */ diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 3c6363f..55ef570 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -3,6 +3,8 @@ * X11 Graphics Pipeline * * Copyright 2014 Marc-Andre Moreau + * Copyright 2016 Armin Novak + * Copyright 2016 Thincast Technologies GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,123 +28,86 @@ #define TAG CLIENT_TAG("x11") -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics) -{ - int index; - UINT16 count; - xfGfxSurface* surface; - UINT16* pSurfaceIds = NULL; - xfContext* xfc = (xfContext*) context->custom; - - context->GetSurfaceIds(context, &pSurfaceIds, &count); - - for (index = 0; index < count; index++) - { - surface = (xfGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]); - - if (!surface || !surface->outputMapped) - continue; - - if (!freerdp_client_codecs_reset(surface->codecs, FREERDP_CODEC_ALL, - surface->width, surface->height)) - { - free(pSurfaceIds); - return ERROR_INTERNAL_ERROR; - } - - region16_clear(&surface->invalidRegion); - } - - free(pSurfaceIds); - - if (!freerdp_client_codecs_reset(xfc->codecs, FREERDP_CODEC_ALL, - xfc->settings->DesktopWidth, - xfc->settings->DesktopHeight)) - return ERROR_INTERNAL_ERROR; - - xfc->graphicsReset = TRUE; - - return CHANNEL_RC_OK; -} - -static int xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface) +static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface) { UINT16 width, height; UINT32 surfaceX, surfaceY; RECTANGLE_16 surfaceRect; const RECTANGLE_16* extents; - - surfaceX = surface->outputOriginX; - surfaceY = surface->outputOriginY; - + rdpGdi* gdi; + gdi = xfc->context.gdi; + surfaceX = surface->gdi.outputOriginX; + surfaceY = surface->gdi.outputOriginY; surfaceRect.left = surfaceX; surfaceRect.top = surfaceY; - surfaceRect.right = surfaceX + surface->width; - surfaceRect.bottom = surfaceY + surface->height; - + surfaceRect.right = surfaceX + surface->gdi.width; + surfaceRect.bottom = surfaceY + surface->gdi.height; XSetClipMask(xfc->display, xfc->gc, None); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); - if (!region16_is_empty(&surface->invalidRegion)) + if (!region16_is_empty(&surface->gdi.invalidRegion)) { - extents = region16_extents(&surface->invalidRegion); - + extents = region16_extents(&surface->gdi.invalidRegion); width = extents->right - extents->left; height = extents->bottom - extents->top; - if (width > surface->width) - width = surface->width; + if (width > surface->gdi.width) + width = surface->gdi.width; - if (height > surface->height) - height = surface->height; + if (height > surface->gdi.height) + height = surface->gdi.height; if (surface->stage) { - freerdp_image_copy(surface->stage, xfc->format, surface->stageStep, 0, 0, - surface->width, surface->height, surface->data, surface->format, surface->scanline, 0, 0, NULL); + freerdp_image_copy(surface->stage, gdi->dstFormat, + surface->stageScanline, 0, 0, + surface->gdi.width, surface->gdi.height, + surface->gdi.data, surface->gdi.format, + surface->gdi.scanline, 0, 0, NULL, FREERDP_FLIP_NONE); } #ifdef WITH_XRENDER - if (xfc->settings->SmartSizing || xfc->settings->MultiTouchGestures) + + if (xfc->context.settings->SmartSizing + || xfc->context.settings->MultiTouchGestures) { XPutImage(xfc->display, xfc->primary, xfc->gc, surface->image, - extents->left, extents->top, extents->left + surfaceX, extents->top + surfaceY, width, height); - + extents->left, extents->top, extents->left + surfaceX, extents->top + surfaceY, + width, height); xf_draw_screen(xfc, extents->left, extents->top, width, height); } else #endif { - XPutImage(xfc->display, xfc->drawable, xfc->gc, surface->image, - extents->left, extents->top, extents->left + surfaceX, extents->top + surfaceY, width, height); + XPutImage(xfc->display, xfc->drawable, xfc->gc, + surface->image, extents->left, extents->top, + extents->left + surfaceX, extents->top + surfaceY, + width, height); } } - region16_clear(&surface->invalidRegion); - + region16_clear(&surface->gdi.invalidRegion); XSetClipMask(xfc->display, xfc->gc, None); XSync(xfc->display, False); - - return 1; + return 0; } -static int xf_UpdateSurfaces(xfContext* xfc) +static UINT xf_UpdateSurfaces(RdpgfxClientContext* context) { UINT16 count; - int index; - int status = 1; + UINT32 index; + UINT status = CHANNEL_RC_OK; xfGfxSurface* surface; UINT16* pSurfaceIds = NULL; - RdpgfxClientContext* context = xfc->gfx; + rdpGdi* gdi = (rdpGdi*)context->custom; + xfContext* xfc = (xfContext*) gdi->context; - if (!xfc->graphicsReset) - return 1; + if (!gdi) + return status; + + if (!gdi->graphicsReset) + return status; context->GetSurfaceIds(context, &pSurfaceIds, &count); @@ -150,50 +115,48 @@ static int xf_UpdateSurfaces(xfContext* xfc) { surface = (xfGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]); - if (!surface || !surface->outputMapped) + if (!surface || !surface->gdi.outputMapped) continue; status = xf_OutputUpdate(xfc, surface); - if (status < 0) + if (status != 0) break; } free(pSurfaceIds); - return status; } -int xf_OutputExpose(xfContext* xfc, int x, int y, int width, int height) +UINT xf_OutputExpose(xfContext* xfc, UINT32 x, UINT32 y, + UINT32 width, UINT32 height) { UINT16 count; - int index; - int status = 1; + UINT32 index; + UINT status = CHANNEL_RC_OK; xfGfxSurface* surface; RECTANGLE_16 invalidRect; RECTANGLE_16 surfaceRect; RECTANGLE_16 intersection; UINT16* pSurfaceIds = NULL; RdpgfxClientContext* context = xfc->gfx; - invalidRect.left = x; invalidRect.top = y; invalidRect.right = x + width; invalidRect.bottom = y + height; - context->GetSurfaceIds(context, &pSurfaceIds, &count); for (index = 0; index < count; index++) { surface = (xfGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]); - if (!surface || !surface->outputMapped) + if (!surface || !surface->gdi.outputMapped) continue; - surfaceRect.left = surface->outputOriginX; - surfaceRect.top = surface->outputOriginY; - surfaceRect.right = surface->outputOriginX + surface->width; - surfaceRect.bottom = surface->outputOriginY + surface->height; + surfaceRect.left = surface->gdi.outputOriginX; + surfaceRect.top = surface->gdi.outputOriginY; + surfaceRect.right = surface->gdi.outputOriginX + surface->gdi.width; + surfaceRect.bottom = surface->gdi.outputOriginY + surface->gdi.height; if (rectangles_intersection(&invalidRect, &surfaceRect, &intersection)) { @@ -202,666 +165,129 @@ int xf_OutputExpose(xfContext* xfc, int x, int y, int width, int height) intersection.top -= surfaceRect.top; intersection.right -= surfaceRect.left; intersection.bottom -= surfaceRect.top; - - region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &intersection); + region16_union_rect(&surface->gdi.invalidRegion, + &surface->gdi.invalidRegion, + &intersection); } } free(pSurfaceIds); - - if (xf_UpdateSurfaces(xfc) < 0) - status = -1; - + IFCALLRET(context->UpdateSurfaces, status, context); return status; } -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_StartFrame(RdpgfxClientContext* context, RDPGFX_START_FRAME_PDU* startFrame) +static INLINE UINT32 x11_pad_scanline(UINT32 scanline, UINT32 inPad) { - xfContext* xfc = (xfContext*) context->custom; + if (inPad > 0) + { + const UINT32 align = inPad / 8; + const UINT32 pad = align - scanline % align; - xfc->inGfxFrame = TRUE; + if (align != pad) + scanline += pad; + } - return CHANNEL_RC_OK; + return scanline; } -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_EndFrame(RdpgfxClientContext* context, RDPGFX_END_FRAME_PDU* endFrame) -{ - xfContext* xfc = (xfContext*) context->custom; - - xf_UpdateSurfaces(xfc); - - xfc->inGfxFrame = FALSE; - - return CHANNEL_RC_OK; -} /** * Function description * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_SurfaceCommand_Uncompressed(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) -{ - xfGfxSurface* surface; - RECTANGLE_16 invalidRect; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - freerdp_image_copy(surface->data, surface->format, surface->scanline, cmd->left, cmd->top, - cmd->width, cmd->height, cmd->data, PIXEL_FORMAT_XRGB32, -1, 0, 0, NULL); - - invalidRect.left = cmd->left; - invalidRect.top = cmd->top; - invalidRect.right = cmd->right; - invalidRect.bottom = cmd->bottom; - - region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) -{ - int j; - UINT16 i; - RFX_RECT* rect; - RFX_TILE* tile; - int nXDst, nYDst; - int nWidth, nHeight; - int nbUpdateRects; - RFX_MESSAGE* message; - xfGfxSurface* surface; - REGION16 updateRegion; - RECTANGLE_16 updateRect; - RECTANGLE_16* updateRects; - REGION16 clippingRects; - RECTANGLE_16 clippingRect; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_REMOTEFX)) - return ERROR_INTERNAL_ERROR; - - if (!(message = rfx_process_message(surface->codecs->rfx, cmd->data, cmd->length))) - { - WLog_ERR(TAG, "Failed to process RemoteFX message"); - return ERROR_INTERNAL_ERROR; - } - - region16_init(&clippingRects); - - for (i = 0; i < message->numRects; i++) - { - rect = &(message->rects[i]); - - clippingRect.left = cmd->left + rect->x; - clippingRect.top = cmd->top + rect->y; - clippingRect.right = clippingRect.left + rect->width; - clippingRect.bottom = clippingRect.top + rect->height; - - region16_union_rect(&clippingRects, &clippingRects, &clippingRect); - } - - for (i = 0; i < message->numTiles; i++) - { - tile = message->tiles[i]; - - updateRect.left = cmd->left + tile->x; - updateRect.top = cmd->top + tile->y; - updateRect.right = updateRect.left + 64; - updateRect.bottom = updateRect.top + 64; - - region16_init(&updateRegion); - region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); - updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); - - for (j = 0; j < nbUpdateRects; j++) - { - nXDst = updateRects[j].left; - nYDst = updateRects[j].top; - nWidth = updateRects[j].right - updateRects[j].left; - nHeight = updateRects[j].bottom - updateRects[j].top; - - freerdp_image_copy(surface->data, surface->format, surface->scanline, - nXDst, nYDst, nWidth, nHeight, - tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL); - - region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); - } - - region16_uninit(&updateRegion); - } - - rfx_message_free(surface->codecs->rfx, message); - - region16_uninit(&clippingRects); - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) -{ - int status; - BYTE* DstData = NULL; - xfGfxSurface* surface; - RECTANGLE_16 invalidRect; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC)) - return ERROR_INTERNAL_ERROR; - - DstData = surface->data; - - status = clear_decompress(xfc->codecs->clear, cmd->data, cmd->length, &DstData, - surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); - - if (status < 0) - { - WLog_ERR(TAG, "clear_decompress failure: %d", status); - return ERROR_INTERNAL_ERROR; - } - - invalidRect.left = cmd->left; - invalidRect.top = cmd->top; - invalidRect.right = cmd->right; - invalidRect.bottom = cmd->bottom; - - region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) -{ - int status; - BYTE* DstData = NULL; - xfGfxSurface* surface; - RECTANGLE_16 invalidRect; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_PLANAR)) - return ERROR_INTERNAL_ERROR; - - DstData = surface->data; - - status = planar_decompress(surface->codecs->planar, cmd->data, cmd->length, &DstData, - surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, FALSE); - - invalidRect.left = cmd->left; - invalidRect.top = cmd->top; - invalidRect.right = cmd->right; - invalidRect.bottom = cmd->bottom; - - region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceCommand_AVC420(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) -{ - int status; - UINT32 i; - xfGfxSurface* surface; - RDPGFX_H264_METABLOCK* meta; - RDPGFX_AVC420_BITMAP_STREAM* bs; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_AVC420)) - return ERROR_INTERNAL_ERROR; - - bs = (RDPGFX_AVC420_BITMAP_STREAM*) cmd->extra; - - if (!bs) - return ERROR_INTERNAL_ERROR; - - meta = &(bs->meta); - - status = avc420_decompress(surface->codecs->h264, bs->data, bs->length, - surface->data, surface->format, - surface->scanline , surface->width, - surface->height, meta->regionRects, - meta->numRegionRects); - - if (status < 0) - { - WLog_WARN(TAG, "avc420_decompress failure: %d, ignoring update.", status); - return CHANNEL_RC_OK; - } - - for (i = 0; i < meta->numRegionRects; i++) - { - region16_union_rect(&surface->invalidRegion, - &surface->invalidRegion, - &(meta->regionRects[i])); - } - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceCommand_AVC444(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) -{ - int status; - UINT32 i; - xfGfxSurface* surface; - RDPGFX_AVC444_BITMAP_STREAM* bs; - RDPGFX_AVC420_BITMAP_STREAM* avc1; - RDPGFX_AVC420_BITMAP_STREAM* avc2; - RDPGFX_H264_METABLOCK* meta1; - RDPGFX_H264_METABLOCK* meta2; - RECTANGLE_16* regionRects = NULL; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_AVC444)) - return ERROR_INTERNAL_ERROR; - - bs = (RDPGFX_AVC444_BITMAP_STREAM*) cmd->extra; - - if (!bs) - return ERROR_INTERNAL_ERROR; - - avc1 = &bs->bitstream[0]; - avc2 = &bs->bitstream[1]; - meta1 = &avc1->meta; - meta2 = &avc2->meta; - - status = avc444_decompress(surface->codecs->h264, bs->LC, - meta1->regionRects, meta1->numRegionRects, - avc1->data, avc1->length, - meta2->regionRects, meta2->numRegionRects, - avc2->data, avc2->length, surface->data, - surface->format, surface->scanline, - surface->width, surface->height); - - if (status < 0) - { - WLog_WARN(TAG, "avc444_decompress failure: %d, ignoring update.", status); - return CHANNEL_RC_OK; - } - - for (i = 0; i < meta1->numRegionRects; i++) - { - region16_union_rect(&surface->invalidRegion, - &surface->invalidRegion, - &(meta1->regionRects[i])); - } - for (i = 0; i < meta2->numRegionRects; i++) - { - region16_union_rect(&surface->invalidRegion, - &surface->invalidRegion, - &(meta2->regionRects[i])); - } - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - free (regionRects); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceCommand_Alpha(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) -{ - int status = 0; - xfGfxSurface* surface; - RECTANGLE_16 invalidRect; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_ALPHACODEC)) - return ERROR_INTERNAL_ERROR; - - WLog_DBG(TAG, "xf_SurfaceCommand_Alpha: status: %d", status); - /* fill with green for now to distinguish from the rest */ - - freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, - cmd->left, cmd->top, cmd->width, cmd->height, 0x00FF00); - - invalidRect.left = cmd->left; - invalidRect.top = cmd->top; - invalidRect.right = cmd->right; - invalidRect.bottom = cmd->bottom; - - region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) -{ - int i, j; - int status; - BYTE* DstData; - RFX_RECT* rect; - int nXDst, nYDst; - int nXSrc, nYSrc; - int nWidth, nHeight; - int nbUpdateRects; - xfGfxSurface* surface; - REGION16 updateRegion; - RECTANGLE_16 updateRect; - RECTANGLE_16* updateRects; - REGION16 clippingRects; - RECTANGLE_16 clippingRect; - RFX_PROGRESSIVE_TILE* tile; - PROGRESSIVE_BLOCK_REGION* region; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_PROGRESSIVE)) - return ERROR_INTERNAL_ERROR; - - progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId, surface->width, surface->height); - - DstData = surface->data; - - status = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, &DstData, - surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId); - - if (status < 0) - { - WLog_ERR(TAG, "progressive_decompress failure: %d", status); - return ERROR_INTERNAL_ERROR; - } - - region = &(surface->codecs->progressive->region); - - region16_init(&clippingRects); - - for (i = 0; i < region->numRects; i++) - { - rect = &(region->rects[i]); - - clippingRect.left = cmd->left + rect->x; - clippingRect.top = cmd->top + rect->y; - clippingRect.right = clippingRect.left + rect->width; - clippingRect.bottom = clippingRect.top + rect->height; - - region16_union_rect(&clippingRects, &clippingRects, &clippingRect); - } - - for (i = 0; i < region->numTiles; i++) - { - tile = region->tiles[i]; - - updateRect.left = cmd->left + tile->x; - updateRect.top = cmd->top + tile->y; - updateRect.right = updateRect.left + 64; - updateRect.bottom = updateRect.top + 64; - - region16_init(&updateRegion); - region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); - updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); - - for (j = 0; j < nbUpdateRects; j++) - { - nXDst = updateRects[j].left; - nYDst = updateRects[j].top; - nWidth = updateRects[j].right - updateRects[j].left; - nHeight = updateRects[j].bottom - updateRects[j].top; - - nXSrc = nXDst - (cmd->left + tile->x); - nYSrc = nYDst - (cmd->top + tile->y); - - freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, - surface->scanline, nXDst, nYDst, nWidth, nHeight, - tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc, NULL); - - region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); - } - - region16_uninit(&updateRegion); - } - - region16_uninit(&clippingRects); - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceCommand(RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) -{ - UINT status = CHANNEL_RC_OK; - xfContext* xfc = (xfContext*) context->custom; - - switch (cmd->codecId) - { - case RDPGFX_CODECID_UNCOMPRESSED: - status = xf_SurfaceCommand_Uncompressed(xfc, context, cmd); - break; - - case RDPGFX_CODECID_CAVIDEO: - status = xf_SurfaceCommand_RemoteFX(xfc, context, cmd); - break; - - case RDPGFX_CODECID_CLEARCODEC: - status = xf_SurfaceCommand_ClearCodec(xfc, context, cmd); - break; - - case RDPGFX_CODECID_PLANAR: - status = xf_SurfaceCommand_Planar(xfc, context, cmd); - break; - - case RDPGFX_CODECID_AVC420: - status = xf_SurfaceCommand_AVC420(xfc, context, cmd); - break; - - case RDPGFX_CODECID_AVC444: - status = xf_SurfaceCommand_AVC444(xfc, context, cmd); - break; - - case RDPGFX_CODECID_ALPHA: - status = xf_SurfaceCommand_Alpha(xfc, context, cmd); - break; - - case RDPGFX_CODECID_CAPROGRESSIVE: - status = xf_SurfaceCommand_Progressive(xfc, context, cmd); - break; - - case RDPGFX_CODECID_CAPROGRESSIVE_V2: - WLog_WARN(TAG, "SurfaceCommand %08X not implemented", cmd->codecId); - break; - - default: - WLog_WARN(TAG, "Invalid SurfaceCommand %08X", cmd->codecId); - break; - } - - return status; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_DeleteEncodingContext(RdpgfxClientContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext) -{ - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface) +static UINT xf_CreateSurface(RdpgfxClientContext* context, + const RDPGFX_CREATE_SURFACE_PDU* createSurface) { size_t size; - UINT32 bytesPerPixel; xfGfxSurface* surface; - xfContext* xfc = (xfContext*) context->custom; - + rdpGdi* gdi = (rdpGdi*)context->custom; + xfContext* xfc = (xfContext*) gdi->context; surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface)); if (!surface) return CHANNEL_RC_NO_MEMORY; - surface->codecs = codecs_new((rdpContext*) xfc); + surface->gdi.codecs = codecs_new(gdi->context); - if (!surface->codecs) - { - free (surface); - return CHANNEL_RC_NO_MEMORY; - } - - if (!freerdp_client_codecs_reset(surface->codecs, FREERDP_CODEC_ALL, - createSurface->width, createSurface->height)) - { - free (surface); - return ERROR_INTERNAL_ERROR; - } - - surface->surfaceId = createSurface->surfaceId; - surface->width = (UINT32) createSurface->width; - surface->height = (UINT32) createSurface->height; - surface->alpha = (createSurface->pixelFormat == PIXEL_FORMAT_ARGB_8888) ? TRUE : FALSE; - surface->format = PIXEL_FORMAT_XRGB32; - - surface->scanline = surface->width * 4; - surface->scanline += (surface->scanline % (xfc->scanline_pad / 8)); - - size = surface->scanline * surface->height; - surface->data = (BYTE*) _aligned_malloc(size, 16); - - if (!surface->data) + if (!surface->gdi.codecs) { free(surface); return CHANNEL_RC_NO_MEMORY; } - ZeroMemory(surface->data, size); + if (!freerdp_client_codecs_prepare(surface->gdi.codecs, FREERDP_CODEC_ALL, + createSurface->width, createSurface->height)) + { + free(surface); + return ERROR_INTERNAL_ERROR; + } - if ((xfc->depth == 24) || (xfc->depth == 32)) + surface->gdi.surfaceId = createSurface->surfaceId; + surface->gdi.width = (UINT32) createSurface->width; + surface->gdi.height = (UINT32) createSurface->height; + + switch (createSurface->pixelFormat) + { + case GFX_PIXEL_FORMAT_ARGB_8888: + surface->gdi.format = PIXEL_FORMAT_BGRA32; + break; + + case GFX_PIXEL_FORMAT_XRGB_8888: + surface->gdi.format = PIXEL_FORMAT_BGRX32; + break; + + default: + free(surface); + return ERROR_INTERNAL_ERROR; + } + + surface->gdi.scanline = surface->gdi.width * GetBytesPerPixel( + surface->gdi.format); + surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad); + size = surface->gdi.scanline * surface->gdi.height; + surface->gdi.data = (BYTE*) _aligned_malloc(size, 16); + + if (!surface->gdi.data) + { + free(surface); + return CHANNEL_RC_NO_MEMORY; + } + + ZeroMemory(surface->gdi.data, size); + + if (gdi->dstFormat == surface->gdi.format) { surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char*) surface->data, surface->width, surface->height, xfc->scanline_pad, surface->scanline); + (char*) surface->gdi.data, surface->gdi.width, surface->gdi.height, + xfc->scanline_pad, surface->gdi.scanline); } else { - bytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(xfc->format) / 8); - surface->stageStep = surface->width * bytesPerPixel; - surface->stageStep += (surface->stageStep % (xfc->scanline_pad / 8)); - size = surface->stageStep * surface->height; - + UINT32 width = surface->gdi.width; + UINT32 bytes = GetBytesPerPixel(gdi->dstFormat); + surface->stageScanline = width * bytes; + surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad); + size = surface->stageScanline * surface->gdi.height; surface->stage = (BYTE*) _aligned_malloc(size, 16); if (!surface->stage) { - free(surface->data); + _aligned_free(surface->gdi.data); free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->stage, size); - - surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char*) surface->stage, surface->width, surface->height, xfc->scanline_pad, surface->stageStep); + surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, + ZPixmap, 0, (char*) surface->stage, + surface->gdi.width, surface->gdi.height, + xfc->scanline_pad, surface->gdi.scanline); } - surface->outputMapped = FALSE; - - region16_init(&surface->invalidRegion); - - context->SetSurfaceData(context, surface->surfaceId, (void*) surface); - + surface->gdi.outputMapped = FALSE; + region16_init(&surface->gdi.invalidRegion); + context->SetSurfaceData(context, surface->gdi.surfaceId, (void*) surface); return CHANNEL_RC_OK; } @@ -870,333 +296,45 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface) +static UINT xf_DeleteSurface(RdpgfxClientContext* context, + const RDPGFX_DELETE_SURFACE_PDU* deleteSurface) { rdpCodecs* codecs = NULL; xfGfxSurface* surface = NULL; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId); + surface = (xfGfxSurface*) context->GetSurfaceData(context, + deleteSurface->surfaceId); if (surface) { XFree(surface->image); - _aligned_free(surface->data); + _aligned_free(surface->gdi.data); _aligned_free(surface->stage); - region16_uninit(&surface->invalidRegion); - codecs = surface->codecs; + region16_uninit(&surface->gdi.invalidRegion); + codecs = surface->gdi.codecs; free(surface); } context->SetSurfaceData(context, deleteSurface->surfaceId, NULL); if (codecs && codecs->progressive) - progressive_delete_surface_context(codecs->progressive, deleteSurface->surfaceId); + progressive_delete_surface_context(codecs->progressive, + deleteSurface->surfaceId); codecs_free(codecs); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SolidFill(RdpgfxClientContext* context, RDPGFX_SOLID_FILL_PDU* solidFill) -{ - UINT16 index; - UINT32 color; - BYTE a, r, g, b; - int nWidth, nHeight; - RECTANGLE_16* rect; - xfGfxSurface* surface; - RECTANGLE_16 invalidRect; - xfContext* xfc = (xfContext*) context->custom; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, solidFill->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - b = solidFill->fillPixel.B; - g = solidFill->fillPixel.G; - r = solidFill->fillPixel.R; - a = solidFill->fillPixel.XA; - - color = ARGB32(a, r, g, b); - - for (index = 0; index < solidFill->fillRectCount; index++) - { - rect = &(solidFill->fillRects[index]); - - nWidth = rect->right - rect->left; - nHeight = rect->bottom - rect->top; - - invalidRect.left = rect->left; - invalidRect.top = rect->top; - invalidRect.right = rect->right; - invalidRect.bottom = rect->bottom; - - freerdp_image_fill(surface->data, surface->format, surface->scanline, - rect->left, rect->top, nWidth, nHeight, color); - - region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); - } - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface) -{ - UINT16 index; - BOOL sameSurface; - int nWidth, nHeight; - RECTANGLE_16* rectSrc; - RDPGFX_POINT16* destPt; - RECTANGLE_16 invalidRect; - xfGfxSurface* surfaceSrc; - xfGfxSurface* surfaceDst; - xfContext* xfc = (xfContext*) context->custom; - - rectSrc = &(surfaceToSurface->rectSrc); - destPt = &surfaceToSurface->destPts[0]; - - surfaceSrc = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdSrc); - - sameSurface = (surfaceToSurface->surfaceIdSrc == surfaceToSurface->surfaceIdDest) ? TRUE : FALSE; - - if (!sameSurface) - surfaceDst = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdDest); - else - surfaceDst = surfaceSrc; - - if (!surfaceSrc || !surfaceDst) - return ERROR_INTERNAL_ERROR; - - nWidth = rectSrc->right - rectSrc->left; - nHeight = rectSrc->bottom - rectSrc->top; - - for (index = 0; index < surfaceToSurface->destPtsCount; index++) - { - destPt = &surfaceToSurface->destPts[index]; - - if (sameSurface) - { - freerdp_image_move(surfaceDst->data, surfaceDst->format, surfaceDst->scanline, - destPt->x, destPt->y, nWidth, nHeight, rectSrc->left, rectSrc->top); - } - else - { - freerdp_image_copy(surfaceDst->data, surfaceDst->format, surfaceDst->scanline, - destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, surfaceSrc->format, - surfaceSrc->scanline, rectSrc->left, rectSrc->top, NULL); - } - - invalidRect.left = destPt->x; - invalidRect.top = destPt->y; - invalidRect.right = destPt->x + rectSrc->right; - invalidRect.bottom = destPt->y + rectSrc->bottom; - - region16_union_rect(&surfaceDst->invalidRegion, &surfaceDst->invalidRegion, &invalidRect); - } - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_SurfaceToCache(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache) -{ - size_t size; - RECTANGLE_16* rect; - xfGfxSurface* surface; - xfGfxCacheEntry* cacheEntry; - xfContext* xfc = (xfContext*) context->custom; - - rect = &(surfaceToCache->rectSrc); - - surface = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToCache->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - cacheEntry = (xfGfxCacheEntry*) calloc(1, sizeof(xfGfxCacheEntry)); - - if (!cacheEntry) - return CHANNEL_RC_NO_MEMORY; - - cacheEntry->width = (UINT32) (rect->right - rect->left); - cacheEntry->height = (UINT32) (rect->bottom - rect->top); - cacheEntry->alpha = surface->alpha; - cacheEntry->format = surface->format; - - cacheEntry->scanline = cacheEntry->width * 4; - cacheEntry->scanline += (cacheEntry->scanline % (xfc->scanline_pad / 8)); - - size = cacheEntry->scanline * cacheEntry->height; - cacheEntry->data = (BYTE*) _aligned_malloc(size, 16); - - if (!cacheEntry->data) - { - free(cacheEntry); - return CHANNEL_RC_NO_MEMORY; - } - - ZeroMemory(cacheEntry->data, size); - - freerdp_image_copy(cacheEntry->data, cacheEntry->format, cacheEntry->scanline, - 0, 0, cacheEntry->width, cacheEntry->height, surface->data, - surface->format, surface->scanline, rect->left, rect->top, NULL); - - context->SetCacheSlotData(context, surfaceToCache->cacheSlot, (void*) cacheEntry); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_CacheToSurface(RdpgfxClientContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface) -{ - UINT16 index; - RDPGFX_POINT16* destPt; - xfGfxSurface* surface; - xfGfxCacheEntry* cacheEntry; - RECTANGLE_16 invalidRect; - xfContext* xfc = (xfContext*) context->custom; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, cacheToSurface->surfaceId); - cacheEntry = (xfGfxCacheEntry*) context->GetCacheSlotData(context, cacheToSurface->cacheSlot); - - if (!surface || !cacheEntry) - return ERROR_INTERNAL_ERROR; - - for (index = 0; index < cacheToSurface->destPtsCount; index++) - { - destPt = &cacheToSurface->destPts[index]; - - freerdp_image_copy(surface->data, surface->format, surface->scanline, - destPt->x, destPt->y, cacheEntry->width, cacheEntry->height, - cacheEntry->data, cacheEntry->format, cacheEntry->scanline, 0, 0, NULL); - - invalidRect.left = destPt->x; - invalidRect.top = destPt->y; - invalidRect.right = destPt->x + cacheEntry->width - 1; - invalidRect.bottom = destPt->y + cacheEntry->height - 1; - - region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); - } - - if (!xfc->inGfxFrame) - xf_UpdateSurfaces(xfc); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_CacheImportReply(RdpgfxClientContext* context, RDPGFX_CACHE_IMPORT_REPLY_PDU* cacheImportReply) -{ - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_EvictCacheEntry(RdpgfxClientContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry) -{ - xfGfxCacheEntry* cacheEntry; - - cacheEntry = (xfGfxCacheEntry*) context->GetCacheSlotData(context, evictCacheEntry->cacheSlot); - - if (cacheEntry) - { - _aligned_free(cacheEntry->data); - free(cacheEntry); - } - - context->SetCacheSlotData(context, evictCacheEntry->cacheSlot, NULL); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_MapSurfaceToOutput(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput) -{ - xfGfxSurface* surface; - - surface = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToOutput->surfaceId); - - if (!surface) - return ERROR_INTERNAL_ERROR; - - surface->outputMapped = TRUE; - surface->outputOriginX = surfaceToOutput->outputOriginX; - surface->outputOriginY = surfaceToOutput->outputOriginY; - - region16_clear(&surface->invalidRegion); - - return CHANNEL_RC_OK; -} - -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_MapSurfaceToWindow(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow) -{ return CHANNEL_RC_OK; } void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx) { - xfc->gfx = gfx; - gfx->custom = (void*) xfc; - - gfx->ResetGraphics = xf_ResetGraphics; - gfx->StartFrame = xf_StartFrame; - gfx->EndFrame = xf_EndFrame; - gfx->SurfaceCommand = xf_SurfaceCommand; - gfx->DeleteEncodingContext = xf_DeleteEncodingContext; + rdpGdi* gdi = xfc->context.gdi; + gdi_graphics_pipeline_init(gdi, gfx); + gfx->UpdateSurfaces = xf_UpdateSurfaces; gfx->CreateSurface = xf_CreateSurface; gfx->DeleteSurface = xf_DeleteSurface; - gfx->SolidFill = xf_SolidFill; - gfx->SurfaceToSurface = xf_SurfaceToSurface; - gfx->SurfaceToCache = xf_SurfaceToCache; - gfx->CacheToSurface = xf_CacheToSurface; - gfx->CacheImportReply = xf_CacheImportReply; - gfx->EvictCacheEntry = xf_EvictCacheEntry; - gfx->MapSurfaceToOutput = xf_MapSurfaceToOutput; - gfx->MapSurfaceToWindow = xf_MapSurfaceToWindow; } void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx) { - + rdpGdi* gdi = xfc->context.gdi; + gdi_graphics_pipeline_uninit(gdi, gfx); } diff --git a/client/X11/xf_gfx.h b/client/X11/xf_gfx.h index 423b335..df0c8e2 100644 --- a/client/X11/xf_gfx.h +++ b/client/X11/xf_gfx.h @@ -3,6 +3,8 @@ * X11 Graphics Pipeline * * Copyright 2014 Marc-Andre Moreau + * Copyright 2016 Thincast Technologies GmbH + * Copyright 2016 Armin Novak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,21 +29,10 @@ struct xf_gfx_surface { - UINT16 surfaceId; - rdpCodecs* codecs; - UINT32 width; - UINT32 height; - BOOL alpha; - BYTE* data; + gdiGfxSurface gdi; BYTE* stage; + UINT32 stageScanline; XImage* image; - int scanline; - int stageStep; - UINT32 format; - BOOL outputMapped; - UINT32 outputOriginX; - UINT32 outputOriginY; - REGION16 invalidRegion; }; typedef struct xf_gfx_surface xfGfxSurface; @@ -50,14 +41,14 @@ struct xf_gfx_cache_entry UINT64 cacheKey; UINT32 width; UINT32 height; - BOOL alpha; BYTE* data; - int scanline; + UINT32 scanline; UINT32 format; }; typedef struct xf_gfx_cache_entry xfGfxCacheEntry; -int xf_OutputExpose(xfContext* xfc, int x, int y, int width, int height); +UINT xf_OutputExpose(xfContext* xfc, UINT32 x, UINT32 y, + UINT32 width, UINT32 height); void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx); void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx); diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 6adbab3..2cfd6e1 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -3,6 +3,8 @@ * X11 Graphical Objects * * Copyright 2011 Marc-Andre Moreau + * Copyright 2016 Thincast Technologies GmbH + * Copyright 2016 Armin Novak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,23 +42,44 @@ #include #define TAG CLIENT_TAG("x11") -/* Bitmap Class */ +BOOL xf_decode_color(rdpGdi* gdi, const UINT32 srcColor, + UINT32* color, UINT32* format) +{ + xfContext* xfc; + UINT32 DstFormat; + UINT32 SrcFormat; -BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) + if (!gdi || !gdi->context || !gdi->context->settings) + return FALSE; + + xfc = (xfContext*)gdi->context; + SrcFormat = gdi_get_pixel_format(gdi->context->settings->ColorDepth); + + if (format) + *format = SrcFormat; + + DstFormat = xf_get_local_color_format(xfc, FALSE); + *color = ConvertColor(srcColor, SrcFormat, + DstFormat, &gdi->palette); + return TRUE; +} + +/* Bitmap Class */ +static BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) { int depth; BYTE* data; Pixmap pixmap; XImage* image; UINT32 SrcFormat; + rdpGdi* gdi; xfContext* xfc = (xfContext*) context; - + gdi = context->gdi; xf_lock_x11(xfc, FALSE); - data = bitmap->data; - depth = (bitmap->bpp >= 24) ? 24 : bitmap->bpp; - - pixmap = XCreatePixmap(xfc->display, xfc->drawable, bitmap->width, bitmap->height, xfc->depth); + depth = GetBitsPerPixel(bitmap->format); + pixmap = XCreatePixmap(xfc->display, xfc->drawable, bitmap->width, + bitmap->height, xfc->depth); if (bitmap->data) { @@ -70,35 +93,32 @@ BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) return FALSE; } - SrcFormat = gdi_get_pixel_format(bitmap->bpp, TRUE); - - freerdp_image_copy(data, xfc->format, -1, 0, 0, - bitmap->width, bitmap->height, bitmap->data, SrcFormat, -1, 0, 0, xfc->palette); - + SrcFormat = bitmap->format; + freerdp_image_copy(data, gdi->dstFormat, 0, 0, 0, + bitmap->width, bitmap->height, + bitmap->data, SrcFormat, + 0, 0, 0, &context->gdi->palette, FREERDP_FLIP_NONE); _aligned_free(bitmap->data); bitmap->data = data; - - bitmap->bpp = (xfc->depth >= 24) ? 32 : xfc->depth; + bitmap->format = gdi->dstFormat; } image = XCreateImage(xfc->display, xfc->visual, xfc->depth, - ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height, xfc->scanline_pad, 0); - - XPutImage(xfc->display, pixmap, xfc->gc, image, 0, 0, 0, 0, bitmap->width, bitmap->height); - + ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height, + xfc->scanline_pad, 0); + XPutImage(xfc->display, pixmap, xfc->gc, image, 0, 0, 0, 0, bitmap->width, + bitmap->height); XFree(image); } ((xfBitmap*) bitmap)->pixmap = pixmap; - xf_unlock_x11(xfc, FALSE); return TRUE; } -void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap) +static void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap) { xfContext* xfc = (xfContext*) context; - xf_lock_x11(xfc, FALSE); if (((xfBitmap*) bitmap)->pixmap != 0) @@ -107,101 +127,31 @@ void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap) xf_unlock_x11(xfc, FALSE); } -BOOL xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) +static BOOL xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) { XImage* image; int width, height; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - width = bitmap->right - bitmap->left + 1; height = bitmap->bottom - bitmap->top + 1; - xf_lock_x11(xfc, FALSE); - XSetFunction(xfc->display, xfc->gc, GXcopy); - image = XCreateImage(xfc->display, xfc->visual, xfc->depth, - ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height, xfc->scanline_pad, 0); - + ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height, + xfc->scanline_pad, 0); XPutImage(xfc->display, xfc->primary, xfc->gc, - image, 0, 0, bitmap->left, bitmap->top, width, height); - + image, 0, 0, bitmap->left, bitmap->top, width, height); XFree(image); - ret = gdi_InvalidateRegion(xfc->hdc, bitmap->left, bitmap->top, width, height); - xf_unlock_x11(xfc, FALSE); return TRUE; } -BOOL xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, - BYTE* data, int width, int height, int bpp, int length, - BOOL compressed, int codecId) -{ - int status; - UINT16 size; - BYTE* pSrcData; - BYTE* pDstData; - UINT32 SrcSize; - UINT32 SrcFormat; - UINT32 bytesPerPixel; - xfContext* xfc = (xfContext*) context; - - bytesPerPixel = (bpp + 7) / 8; - size = width * height * 4; - - bitmap->data = (BYTE*) _aligned_malloc(size, 16); - if (!bitmap->data) - return FALSE; - - pSrcData = data; - SrcSize = (UINT32) length; - pDstData = bitmap->data; - - if (compressed) - { - if (bpp < 32) - { - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_INTERLEAVED)) - return FALSE; - - status = interleaved_decompress(xfc->codecs->interleaved, pSrcData, SrcSize, bpp, - &pDstData, xfc->format, -1, 0, 0, width, height, xfc->palette); - } - else - { - if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR)) - return FALSE; - - status = planar_decompress(xfc->codecs->planar, pSrcData, SrcSize, - &pDstData, xfc->format, -1, 0, 0, width, height, TRUE); - } - - if (status < 0) - { - WLog_ERR(TAG, "Bitmap Decompression Failed"); - return FALSE; - } - } - else - { - SrcFormat = gdi_get_pixel_format(bpp, TRUE); - - status = freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, - width, height, pSrcData, SrcFormat, -1, 0, 0, xfc->palette); - } - - bitmap->compressed = FALSE; - bitmap->length = size; - bitmap->bpp = (xfc->depth >= 24) ? 32 : xfc->depth; - return TRUE; -} - -BOOL xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary) +static BOOL xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, + BOOL primary) { xfContext* xfc = (xfContext*) context; - xf_lock_x11(xfc, FALSE); if (primary) @@ -214,15 +164,26 @@ BOOL xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary) } /* Pointer Class */ - -BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer) +static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer) { #ifdef WITH_XCURSOR + UINT32 CursorFormat; + rdpGdi* gdi; + size_t size; XcursorImage ci; xfContext* xfc = (xfContext*) context; + xfPointer* xpointer = (xfPointer*)pointer; + if (!context || !pointer || !context->gdi) + return FALSE; + + if (!xfc->invert) + CursorFormat = PIXEL_FORMAT_RGBA32; + else + CursorFormat = PIXEL_FORMAT_BGRA32; + + gdi = context->gdi; xf_lock_x11(xfc, FALSE); - ZeroMemory(&ci, sizeof(ci)); ci.version = XCURSOR_IMAGE_VERSION; ci.size = sizeof(ci); @@ -230,39 +191,37 @@ BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer) ci.height = pointer->height; ci.xhot = pointer->xPos; ci.yhot = pointer->yPos; + size = ci.height * ci.width * GetBytesPerPixel(CursorFormat); - if (!(ci.pixels = (XcursorPixel*) calloc(1, ci.width * ci.height * 4))) + if (!(ci.pixels = (XcursorPixel*) _aligned_malloc(size, 16))) { xf_unlock_x11(xfc, FALSE); return FALSE; } - if (freerdp_image_copy_from_pointer_data( - (BYTE*) ci.pixels, PIXEL_FORMAT_ARGB32, - pointer->width * 4, 0, 0, pointer->width, pointer->height, - pointer->xorMaskData, pointer->lengthXorMask, - pointer->andMaskData, pointer->lengthAndMask, - pointer->xorBpp, xfc->palette) < 0) + if (!freerdp_image_copy_from_pointer_data( + (BYTE*) ci.pixels, CursorFormat, + 0, 0, 0, pointer->width, pointer->height, + pointer->xorMaskData, pointer->lengthXorMask, + pointer->andMaskData, pointer->lengthAndMask, + pointer->xorBpp, &context->gdi->palette)) { - free(ci.pixels); + _aligned_free(ci.pixels); xf_unlock_x11(xfc, FALSE); return FALSE; } - ((xfPointer*) pointer)->cursor = XcursorImageLoadCursor(xfc->display, &ci); - - free(ci.pixels); - + xpointer->cursor = XcursorImageLoadCursor(xfc->display, &ci); + _aligned_free(ci.pixels); xf_unlock_x11(xfc, FALSE); #endif return TRUE; } -void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer) +static void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer) { #ifdef WITH_XCURSOR xfContext* xfc = (xfContext*) context; - xf_lock_x11(xfc, FALSE); if (((xfPointer*) pointer)->cursor) @@ -272,13 +231,12 @@ void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer) #endif } -BOOL xf_Pointer_Set(rdpContext* context, rdpPointer* pointer) +static BOOL xf_Pointer_Set(rdpContext* context, + const rdpPointer* pointer) { #ifdef WITH_XCURSOR xfContext* xfc = (xfContext*) context; - xf_lock_x11(xfc, FALSE); - xfc->pointer = (xfPointer*) pointer; /* in RemoteApp mode, window can be null if none has had focus */ @@ -291,12 +249,11 @@ BOOL xf_Pointer_Set(rdpContext* context, rdpPointer* pointer) return TRUE; } -BOOL xf_Pointer_SetNull(rdpContext* context) +static BOOL xf_Pointer_SetNull(rdpContext* context) { #ifdef WITH_XCURSOR xfContext* xfc = (xfContext*) context; static Cursor nullcursor = None; - xf_lock_x11(xfc, FALSE); if (nullcursor == None) @@ -322,13 +279,11 @@ BOOL xf_Pointer_SetNull(rdpContext* context) return TRUE; } -BOOL xf_Pointer_SetDefault(rdpContext* context) +static BOOL xf_Pointer_SetDefault(rdpContext* context) { #ifdef WITH_XCURSOR xfContext* xfc = (xfContext*) context; - xf_lock_x11(xfc, FALSE); - xfc->pointer = NULL; if (xfc->window) @@ -339,7 +294,7 @@ BOOL xf_Pointer_SetDefault(rdpContext* context) return TRUE; } -BOOL xf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y) +static BOOL xf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y) { xfContext* xfc = (xfContext*) context; XWindowAttributes current; @@ -355,149 +310,144 @@ BOOL xf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y) goto out; tmp.event_mask = (current.your_event_mask & ~(PointerMotionMask)); - if (XChangeWindowAttributes(xfc->display, xfc->window->handle, CWEventMask, &tmp) == 0) + + if (XChangeWindowAttributes(xfc->display, xfc->window->handle, CWEventMask, + &tmp) == 0) goto out; XWarpPointer(xfc->display, None, xfc->window->handle, 0, 0, 0, 0, x, y); - tmp.event_mask = current.your_event_mask; XChangeWindowAttributes(xfc->display, xfc->window->handle, CWEventMask, &tmp); - ret = TRUE; out: xf_unlock_x11(xfc, FALSE); return ret; - } /* Glyph Class */ - -BOOL xf_Glyph_New(rdpContext* context, rdpGlyph* glyph) +static BOOL xf_Glyph_New(rdpContext* context, const rdpGlyph* glyph) { int scanline; XImage* image; xfGlyph* xf_glyph; - xf_glyph = (xfGlyph*) glyph; xfContext* xfc = (xfContext*) context; - xf_lock_x11(xfc, FALSE); - scanline = (glyph->cx + 7) / 8; - - xf_glyph->pixmap = XCreatePixmap(xfc->display, xfc->drawing, glyph->cx, glyph->cy, 1); - + xf_glyph->pixmap = XCreatePixmap(xfc->display, xfc->drawing, glyph->cx, + glyph->cy, 1); image = XCreateImage(xfc->display, xfc->visual, 1, - ZPixmap, 0, (char*) glyph->aj, glyph->cx, glyph->cy, 8, scanline); - + ZPixmap, 0, (char*) glyph->aj, glyph->cx, glyph->cy, 8, scanline); image->byte_order = MSBFirst; image->bitmap_bit_order = MSBFirst; - XInitImage(image); - XPutImage(xfc->display, xf_glyph->pixmap, xfc->gc_mono, image, 0, 0, 0, 0, glyph->cx, glyph->cy); + XPutImage(xfc->display, xf_glyph->pixmap, xfc->gc_mono, image, 0, 0, 0, 0, + glyph->cx, glyph->cy); XFree(image); - xf_unlock_x11(xfc, FALSE); return TRUE; } -void xf_Glyph_Free(rdpContext* context, rdpGlyph* glyph) +static void xf_Glyph_Free(rdpContext* context, rdpGlyph* glyph) { xfContext* xfc = (xfContext*) context; - xf_lock_x11(xfc, FALSE); if (((xfGlyph*) glyph)->pixmap != 0) XFreePixmap(xfc->display, ((xfGlyph*) glyph)->pixmap); xf_unlock_x11(xfc, FALSE); + free(glyph->aj); + free(glyph); } -BOOL xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y) +static BOOL xf_Glyph_Draw(rdpContext* context, const rdpGlyph* glyph, UINT32 x, + UINT32 y, UINT32 w, UINT32 h, UINT32 sx, UINT32 sy, + BOOL fOpRedundant) { xfGlyph* xf_glyph; xfContext* xfc = (xfContext*) context; - xf_glyph = (xfGlyph*) glyph; - xf_lock_x11(xfc, FALSE); - XSetStipple(xfc->display, xfc->gc, xf_glyph->pixmap); - XSetTSOrigin(xfc->display, xfc->gc, x, y); - XFillRectangle(xfc->display, xfc->drawing, xfc->gc, x, y, glyph->cx, glyph->cy); - XSetStipple(xfc->display, xfc->gc, xfc->bitmap_mono); + if (!fOpRedundant) + { + XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); + XFillRectangle(xfc->display, xfc->drawable, xfc->gc, x, y, w, h); + } + XSetFillStyle(xfc->display, xfc->gc, FillStippled); + XSetStipple(xfc->display, xfc->gc, xf_glyph->pixmap); + + if (sx || sy) + WLog_ERR(TAG, ""); + + //XSetClipOrigin(xfc->display, xfc->gc, sx, sy); + XSetTSOrigin(xfc->display, xfc->gc, x, y); + XFillRectangle(xfc->display, xfc->drawing, xfc->gc, x, y, w, h); xf_unlock_x11(xfc, FALSE); return TRUE; } -BOOL xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor, BOOL fOpRedundant) +static BOOL xf_Glyph_BeginDraw(rdpContext* context, UINT32 x, UINT32 y, + UINT32 width, UINT32 height, UINT32 bgcolor, + UINT32 fgcolor, BOOL fOpRedundant) { xfContext* xfc = (xfContext*) context; + XRectangle rect; - bgcolor = xf_convert_rdp_order_color(xfc, bgcolor); - fgcolor = xf_convert_rdp_order_color(xfc, fgcolor); + if (!xf_decode_color(context->gdi, bgcolor, &bgcolor, NULL)) + return FALSE; + if (!xf_decode_color(context->gdi, fgcolor, &fgcolor, NULL)) + return FALSE; + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; xf_lock_x11(xfc, FALSE); - XSetFunction(xfc->display, xfc->gc, GXcopy); - - if (width && height) + if (!fOpRedundant) { - XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, fgcolor); - XFillRectangle(xfc->display, xfc->drawing, xfc->gc, x, y, width, height); + XSetBackground(xfc->display, xfc->gc, fgcolor); + XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); + XFillRectangle(xfc->display, xfc->drawable, xfc->gc, x, y, width, height); } XSetForeground(xfc->display, xfc->gc, bgcolor); XSetBackground(xfc->display, xfc->gc, fgcolor); - - XSetFillStyle(xfc->display, xfc->gc, fOpRedundant ? FillOpaqueStippled : FillStippled); - xf_unlock_x11(xfc, FALSE); return TRUE; } -BOOL xf_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor) +static BOOL xf_Glyph_EndDraw(rdpContext* context, UINT32 x, UINT32 y, + UINT32 width, UINT32 height, + UINT32 bgcolor, UINT32 fgcolor) { xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - xf_lock_x11(xfc, FALSE); + if (!xf_decode_color(context->gdi, bgcolor, &bgcolor, NULL)) + return FALSE; + + if (!xf_decode_color(context->gdi, fgcolor, &fgcolor, NULL)) + return FALSE; if (xfc->drawing == xfc->primary) ret = gdi_InvalidateRegion(xfc->hdc, x, y, width, height); - xf_unlock_x11(xfc, FALSE); return ret; } /* Graphics Module */ - -BOOL xf_register_graphics(rdpGraphics* graphics) +BOOL xf_register_pointer(rdpGraphics* graphics) { - rdpBitmap* bitmap = NULL; rdpPointer* pointer = NULL; - rdpGlyph* glyph = NULL; - BOOL ret = FALSE; - - if (!(bitmap = (rdpBitmap*) calloc(1, sizeof(rdpBitmap)))) - goto out; if (!(pointer = (rdpPointer*) calloc(1, sizeof(rdpPointer)))) - goto out; - - if (!(glyph = (rdpGlyph*) calloc(1, sizeof(rdpGlyph)))) - goto out; - - bitmap->size = sizeof(xfBitmap); - bitmap->New = xf_Bitmap_New; - bitmap->Free = xf_Bitmap_Free; - bitmap->Paint = xf_Bitmap_Paint; - bitmap->Decompress = xf_Bitmap_Decompress; - bitmap->SetSurface = xf_Bitmap_SetSurface; - - graphics_register_bitmap(graphics, bitmap); + return FALSE; pointer->size = sizeof(xfPointer); pointer->New = xf_Pointer_New; @@ -506,24 +456,60 @@ BOOL xf_register_graphics(rdpGraphics* graphics) pointer->SetNull = xf_Pointer_SetNull; pointer->SetDefault = xf_Pointer_SetDefault; pointer->SetPosition = xf_Pointer_SetPosition; - graphics_register_pointer(graphics, pointer); - - glyph->size = sizeof(xfGlyph); - glyph->New = xf_Glyph_New; - glyph->Free = xf_Glyph_Free; - glyph->Draw = xf_Glyph_Draw; - glyph->BeginDraw = xf_Glyph_BeginDraw; - glyph->EndDraw = xf_Glyph_EndDraw; - - graphics_register_glyph(graphics, glyph); - - ret = TRUE; - -out: - free(bitmap); free(pointer); - free(glyph); - - return ret; + return TRUE; +} + +BOOL xf_register_graphics(rdpGraphics* graphics) +{ + rdpBitmap bitmap; + rdpGlyph glyph; + + if (!graphics || !graphics->Bitmap_Prototype || !graphics->Glyph_Prototype) + return FALSE; + + bitmap = *graphics->Bitmap_Prototype; + glyph = *graphics->Glyph_Prototype; + bitmap.size = sizeof(xfBitmap); + bitmap.New = xf_Bitmap_New; + bitmap.Free = xf_Bitmap_Free; + bitmap.Paint = xf_Bitmap_Paint; + bitmap.SetSurface = xf_Bitmap_SetSurface; + graphics_register_bitmap(graphics, &bitmap); + glyph.size = sizeof(xfGlyph); + glyph.New = xf_Glyph_New; + glyph.Free = xf_Glyph_Free; + glyph.Draw = xf_Glyph_Draw; + glyph.BeginDraw = xf_Glyph_BeginDraw; + glyph.EndDraw = xf_Glyph_EndDraw; + graphics_register_glyph(graphics, &glyph); + return TRUE; +} + +UINT32 xf_get_local_color_format(xfContext* xfc, BOOL aligned) +{ + UINT32 DstFormat; + BOOL invert = !(aligned ^ xfc->invert); + + if (!xfc) + return 0; + + if (xfc->depth == 32) + DstFormat = (!invert) ? PIXEL_FORMAT_RGBA32 : PIXEL_FORMAT_BGRA32; + else if (xfc->depth == 24) + { + if (aligned) + DstFormat = (!invert) ? PIXEL_FORMAT_RGBX32 : PIXEL_FORMAT_BGRX32; + else + DstFormat = (!invert) ? PIXEL_FORMAT_RGB24 : PIXEL_FORMAT_BGR24; + } + else if (xfc->depth == 16) + DstFormat = (!invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16; + else if (xfc->depth == 15) + DstFormat = (!invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16; + else + DstFormat = (!invert) ? PIXEL_FORMAT_RGBX32 : PIXEL_FORMAT_BGRX32; + + return DstFormat; } diff --git a/client/X11/xf_graphics.h b/client/X11/xf_graphics.h index b5871d5..dde4928 100644 --- a/client/X11/xf_graphics.h +++ b/client/X11/xf_graphics.h @@ -23,6 +23,11 @@ #include "xf_client.h" #include "xfreerdp.h" +BOOL xf_register_pointer(rdpGraphics* graphics); BOOL xf_register_graphics(rdpGraphics* graphics); +BOOL xf_decode_color(rdpGdi* gdi, const UINT32 srcColor, + UINT32* color, UINT32* format); +UINT32 xf_get_local_color_format(xfContext* xfc, BOOL aligned); + #endif /* __XF_GRAPHICS_H */ diff --git a/client/X11/xf_input.c b/client/X11/xf_input.c index b3a8627..c8b9cd5 100644 --- a/client/X11/xf_input.c +++ b/client/X11/xf_input.c @@ -104,11 +104,9 @@ int xf_input_init(xfContext* xfc, Window window) XIEventMask evmasks[64]; int opcode, event, error; BYTE masks[8][XIMaskLen(XI_LASTEVENT)]; - z_vector = 0; px_vector = 0; py_vector = 0; - nmasks = 0; ndevices = 0; active_contacts = 0; @@ -121,7 +119,6 @@ int xf_input_init(xfContext* xfc, Window window) } xfc->XInputOpcode = opcode; - XIQueryVersion(xfc->display, &major, &minor); if (major * 1000 + minor < 2002) @@ -130,7 +127,7 @@ int xf_input_init(xfContext* xfc, Window window) return -1; } - if (xfc->settings->MultiTouchInput) + if (xfc->context.settings->MultiTouchInput) xfc->use_xinput = TRUE; info = XIQueryDevice(xfc->display, XIAllDevices, &ndevices); @@ -157,11 +154,11 @@ int xf_input_init(xfContext* xfc, Window window) XIAnyClassInfo* class = dev->classes[j]; XITouchClassInfo* t = (XITouchClassInfo*) class; - if (xfc->settings->MultiTouchInput) + if (xfc->context.settings->MultiTouchInput) { WLog_INFO(TAG, "%s (%d) \"%s\" id: %d", - xf_input_get_class_string(class->type), - class->type, dev->name, dev->deviceid); + xf_input_get_class_string(class->type), + class->type, dev->name, dev->deviceid); } evmasks[nmasks].mask = masks[nmasks]; @@ -172,11 +169,11 @@ int xf_input_init(xfContext* xfc, Window window) if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) && (strcmp(dev->name, "Virtual core pointer") != 0)) { - if (xfc->settings->MultiTouchInput) + if (xfc->context.settings->MultiTouchInput) { WLog_INFO(TAG, "%s %s touch device (id: %d, mode: %d), supporting %d touches.", - dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent", - dev->deviceid, t->mode, t->num_touches); + dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent", + dev->deviceid, t->mode, t->num_touches); } XISetMask(masks[nmasks], XI_TouchBegin); @@ -187,11 +184,12 @@ int xf_input_init(xfContext* xfc, Window window) if (xfc->use_xinput) { - if (!touch && (class->type == XIButtonClass) && strcmp(dev->name, "Virtual core pointer")) + if (!touch && (class->type == XIButtonClass) + && strcmp(dev->name, "Virtual core pointer")) { WLog_INFO(TAG, "%s button device (id: %d, mode: %d)", - dev->name, - dev->deviceid, t->mode); + dev->name, + dev->deviceid, t->mode); XISetMask(masks[nmasks], XI_ButtonPress); XISetMask(masks[nmasks], XI_ButtonRelease); XISetMask(masks[nmasks], XI_Motion); @@ -200,6 +198,7 @@ int xf_input_init(xfContext* xfc, Window window) } } } + XIFreeDeviceInfo(info); if (nmasks > 0) @@ -211,15 +210,13 @@ int xf_input_init(xfContext* xfc, Window window) BOOL xf_input_is_duplicate(XGenericEventCookie* cookie) { XIDeviceEvent* event; - event = cookie->data; - - if ( (lastEvent.time == event->time) && + if ((lastEvent.time == event->time) && (lastEvType == cookie->evtype) && (lastEvent.detail == event->detail) && (lastEvent.event_x == event->event_x) && - (lastEvent.event_y == event->event_y) ) + (lastEvent.event_y == event->event_y)) { return TRUE; } @@ -230,11 +227,8 @@ BOOL xf_input_is_duplicate(XGenericEventCookie* cookie) void xf_input_save_last_event(XGenericEventCookie* cookie) { XIDeviceEvent* event; - event = cookie->data; - lastEvType = cookie->evtype; - lastEvent.time = event->time; lastEvent.detail = event->detail; lastEvent.event_x = event->event_x; @@ -245,10 +239,8 @@ void xf_input_detect_pan(xfContext* xfc) { double dx[2]; double dy[2]; - double px; double py; - double dist_x; double dist_y; @@ -259,16 +251,12 @@ void xf_input_detect_pan(xfContext* xfc) dx[0] = contacts[0].pos_x - contacts[0].last_x; dx[1] = contacts[1].pos_x - contacts[1].last_x; - dy[0] = contacts[0].pos_y - contacts[0].last_y; dy[1] = contacts[1].pos_y - contacts[1].last_y; - px = fabs(dx[0]) < fabs(dx[1]) ? dx[0] : dx[1]; py = fabs(dy[0]) < fabs(dy[1]) ? dy[0] : dy[1]; - px_vector += px; py_vector += py; - dist_x = fabs(contacts[0].pos_x - contacts[1].pos_x); dist_y = fabs(contacts[0].pos_y - contacts[1].pos_y); @@ -278,15 +266,12 @@ void xf_input_detect_pan(xfContext* xfc) { { PanningChangeEventArgs e; - EventArgsInit(&e, "xfreerdp"); e.dx = 5; e.dy = 0; PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e); } - px_vector = 0; - px_vector = 0; py_vector = 0; z_vector = 0; @@ -295,38 +280,30 @@ void xf_input_detect_pan(xfContext* xfc) { { PanningChangeEventArgs e; - EventArgsInit(&e, "xfreerdp"); e.dx = -5; e.dy = 0; PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e); } - px_vector = 0; - px_vector = 0; py_vector = 0; z_vector = 0; } - } if (dist_x > MIN_FINGER_DIST) { - if (py_vector > PAN_THRESHOLD) { { PanningChangeEventArgs e; - EventArgsInit(&e, "xfreerdp"); e.dx = 0; e.dy = 5; PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e); } - py_vector = 0; - px_vector = 0; py_vector = 0; z_vector = 0; @@ -335,15 +312,12 @@ void xf_input_detect_pan(xfContext* xfc) { { PanningChangeEventArgs e; - EventArgsInit(&e, "xfreerdp"); e.dx = 0; e.dy = -5; PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e); } - py_vector = 0; - px_vector = 0; py_vector = 0; z_vector = 0; @@ -355,7 +329,6 @@ void xf_input_detect_pinch(xfContext* xfc) { double dist; double zoom; - double delta; ZoomingChangeEventArgs e; @@ -367,7 +340,7 @@ void xf_input_detect_pinch(xfContext* xfc) /* first calculate the distance */ dist = sqrt(pow(contacts[1].pos_x - contacts[0].last_x, 2.0) + - pow(contacts[1].pos_y - contacts[0].last_y, 2.0)); + pow(contacts[1].pos_y - contacts[0].last_y, 2.0)); /* if this is the first 2pt touch */ if (firstDist <= 0) @@ -376,7 +349,6 @@ void xf_input_detect_pinch(xfContext* xfc) lastDist = firstDist; scale_cnt = 0; z_vector = 0; - px_vector = 0; py_vector = 0; z_vector = 0; @@ -385,16 +357,15 @@ void xf_input_detect_pinch(xfContext* xfc) { delta = lastDist - dist; - if(delta > 1.0) + if (delta > 1.0) delta = 1.0; - if(delta < -1.0) + + if (delta < -1.0) delta = -1.0; /* compare the current distance to the first one */ zoom = (dist / firstDist); - z_vector += delta; - lastDist = dist; if (z_vector > ZOOM_THRESHOLD) @@ -402,7 +373,6 @@ void xf_input_detect_pinch(xfContext* xfc) EventArgsInit(&e, "xfreerdp"); e.dx = e.dy = -10; PubSub_OnZoomingChange(((rdpContext*) xfc)->pubSub, xfc, &e); - z_vector = 0; px_vector = 0; py_vector = 0; @@ -414,7 +384,6 @@ void xf_input_detect_pinch(xfContext* xfc) EventArgsInit(&e, "xfreerdp"); e.dx = e.dy = 10; PubSub_OnZoomingChange(((rdpContext*) xfc)->pubSub, xfc, &e); - z_vector = 0; px_vector = 0; py_vector = 0; @@ -435,7 +404,6 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event) contacts[i].count = 1; contacts[i].pos_x = event->event_x; contacts[i].pos_y = event->event_y; - active_contacts++; break; } @@ -455,10 +423,8 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event) contacts[i].last_y = contacts[i].pos_y; contacts[i].pos_x = event->event_x; contacts[i].pos_y = event->event_y; - xf_input_detect_pinch(xfc); xf_input_detect_pan(xfc); - break; } } @@ -474,7 +440,6 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event) { contacts[i].id = 0; contacts[i].count = 0; - active_contacts--; break; } @@ -484,7 +449,6 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event) int xf_input_handle_event_local(xfContext* xfc, XEvent* event) { XGenericEventCookie* cookie = &event->xcookie; - XGetEventData(xfc->display, cookie); if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode)) @@ -494,18 +458,21 @@ int xf_input_handle_event_local(xfContext* xfc, XEvent* event) case XI_TouchBegin: if (xf_input_is_duplicate(cookie) == FALSE) xf_input_touch_begin(xfc, cookie->data); + xf_input_save_last_event(cookie); break; case XI_TouchUpdate: if (xf_input_is_duplicate(cookie) == FALSE) xf_input_touch_update(xfc, cookie->data); + xf_input_save_last_event(cookie); break; case XI_TouchEnd: if (xf_input_is_duplicate(cookie) == FALSE) xf_input_touch_end(xfc, cookie->data); + xf_input_save_last_event(cookie); break; @@ -515,8 +482,7 @@ int xf_input_handle_event_local(xfContext* xfc, XEvent* event) } } - XFreeEventData(xfc->display,cookie); - + XFreeEventData(xfc->display, cookie); return 0; } @@ -535,14 +501,13 @@ char* xf_input_touch_state_string(DWORD flags) void xf_input_hide_cursor(xfContext* xfc) { #ifdef WITH_XCURSOR + if (!xfc->cursorHidden) { XcursorImage ci; XcursorPixel xp = 0; static Cursor nullcursor = None; - xf_lock_x11(xfc, FALSE); - ZeroMemory(&ci, sizeof(ci)); ci.version = XCURSOR_IMAGE_VERSION; ci.size = sizeof(ci); @@ -555,9 +520,9 @@ void xf_input_hide_cursor(xfContext* xfc) XDefineCursor(xfc->display, xfc->window->handle, nullcursor); xfc->cursorHidden = TRUE; - xf_unlock_x11(xfc, FALSE); } + #endif } @@ -594,11 +559,9 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype) return 0; xf_input_hide_cursor(xfc); - touchId = event->detail; x = (int) event->event_x; y = (int) event->event_y; - xf_event_adjust_coordinates(xfc, &x, &y); if (evtype == XI_TouchBegin) @@ -627,21 +590,18 @@ int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype) switch (evtype) { case XI_ButtonPress: - xf_generic_ButtonPress(xfc, (int) event->event_x, (int) event->event_y, - event->detail, event->event, xfc->remote_app); + event->detail, event->event, xfc->remote_app); break; case XI_ButtonRelease: - xf_generic_ButtonRelease(xfc, (int) event->event_x, (int) event->event_y, - event->detail, event->event, xfc->remote_app); + event->detail, event->event, xfc->remote_app); break; case XI_Motion: - xf_generic_MotionNotify(xfc, (int) event->event_x, (int) event->event_y, - event->detail, event->event, xfc->remote_app); + event->detail, event->event, xfc->remote_app); break; } @@ -651,7 +611,6 @@ int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype) int xf_input_handle_event_remote(xfContext* xfc, XEvent* event) { XGenericEventCookie* cookie = &event->xcookie; - XGetEventData(xfc->display, cookie); if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode)) @@ -676,8 +635,7 @@ int xf_input_handle_event_remote(xfContext* xfc, XEvent* event) } } - XFreeEventData(xfc->display,cookie); - + XFreeEventData(xfc->display, cookie); return 0; } @@ -693,16 +651,17 @@ int xf_input_init(xfContext* xfc, Window window) int xf_input_handle_event(xfContext* xfc, XEvent* event) { #ifdef WITH_XI - if (xfc->settings->MultiTouchInput) + + if (xfc->context.settings->MultiTouchInput) { return xf_input_handle_event_remote(xfc, event); } - if (xfc->settings->MultiTouchGestures) + if (xfc->context.settings->MultiTouchGestures) { return xf_input_handle_event_local(xfc, event); } -#endif +#endif return 0; } diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 3e11b95..7a668ba 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -63,13 +63,12 @@ BOOL xf_keyboard_action_script_init(xfContext* xfc) return FALSE; xfc->keyCombinations = ArrayList_New(TRUE); + if (!xfc->keyCombinations) return FALSE; ArrayList_Object(xfc->keyCombinations)->fnObjectFree = free; - sprintf_s(command, sizeof(command), "%s key", xfc->actionScript); - keyScript = popen(command, "r"); if (!keyScript) @@ -83,6 +82,7 @@ BOOL xf_keyboard_action_script_init(xfContext* xfc) { strtok(buffer, "\n"); keyCombination = _strdup(buffer); + if (!keyCombination || ArrayList_Add(xfc->keyCombinations, keyCombination) < 0) { ArrayList_Free(xfc->keyCombinations); @@ -95,7 +95,6 @@ BOOL xf_keyboard_action_script_init(xfContext* xfc) pclose(keyScript); return xf_event_action_script_init(xfc); - } void xf_keyboard_action_script_free(xfContext* xfc) @@ -118,10 +117,9 @@ void xf_keyboard_action_script_free(xfContext* xfc) BOOL xf_keyboard_init(xfContext* xfc) { xf_keyboard_clear(xfc); - - xfc->KeyboardLayout = xfc->instance->settings->KeyboardLayout; + xfc->KeyboardLayout = xfc->context.settings->KeyboardLayout; xfc->KeyboardLayout = freerdp_keyboard_init(xfc->KeyboardLayout); - xfc->instance->settings->KeyboardLayout = xfc->KeyboardLayout; + xfc->context.settings->KeyboardLayout = xfc->KeyboardLayout; if (xfc->modifierMap) XFreeModifiermap(xfc->modifierMap); @@ -168,7 +166,6 @@ void xf_keyboard_key_release(xfContext* xfc, BYTE keycode) return; xfc->KeyboardState[keycode] = FALSE; - xf_keyboard_send_key(xfc, FALSE, keycode); } @@ -186,9 +183,10 @@ void xf_keyboard_release_all_keypress(xfContext* xfc) // release tab before releasing the windows key. // this stops the start menu from opening on unfocus event. if (rdp_scancode == RDP_SCANCODE_LWIN) - freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, RDP_SCANCODE_TAB); + freerdp_input_send_keyboard_event_ex(xfc->context.input, FALSE, + RDP_SCANCODE_TAB); - freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, rdp_scancode); + freerdp_input_send_keyboard_event_ex(xfc->context.input, FALSE, rdp_scancode); xfc->KeyboardState[keycode] = FALSE; } } @@ -204,8 +202,7 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode) { DWORD rdp_scancode; rdpInput* input; - - input = xfc->instance->input; + input = xfc->context.input; rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode); if (rdp_scancode == RDP_SCANCODE_UNKNOWN) @@ -213,7 +210,8 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode) WLog_ERR(TAG, "Unknown key with X keycode 0x%02x", keycode); } else if (rdp_scancode == RDP_SCANCODE_PAUSE && - !xf_keyboard_key_pressed(xfc, XK_Control_L) && !xf_keyboard_key_pressed(xfc, XK_Control_R)) + !xf_keyboard_key_pressed(xfc, XK_Control_L) + && !xf_keyboard_key_pressed(xfc, XK_Control_R)) { /* Pause without Ctrl has to be sent as a series of keycodes * in a single input PDU. Pause only happens on "press"; @@ -246,13 +244,13 @@ int xf_keyboard_read_keyboard_state(xfContext* xfc) if (!xfc->remote_app) { XQueryPointer(xfc->display, xfc->window->handle, - &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state); + &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state); } else { XQueryPointer(xfc->display, DefaultRootWindow(xfc->display), - &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state); - } + &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state); + } return state; } @@ -277,6 +275,7 @@ static int xf_keyboard_get_keymask(xfContext* xfc, int keysym) } } } + return keysymMask; } @@ -304,22 +303,25 @@ static BOOL xf_keyboard_set_key_state(xfContext* xfc, BOOL on, int keysym) return FALSE; } - return XkbLockModifiers(xfc->display, XkbUseCoreKbd, keysymMask, on ? keysymMask : 0); + return XkbLockModifiers(xfc->display, XkbUseCoreKbd, keysymMask, + on ? keysymMask : 0); } UINT32 xf_keyboard_get_toggle_keys_state(xfContext* xfc) { int state; UINT32 toggleKeysState = 0; - state = xf_keyboard_read_keyboard_state(xfc); if (xf_keyboard_get_key_state(xfc, state, XK_Scroll_Lock)) toggleKeysState |= KBD_SYNC_SCROLL_LOCK; + if (xf_keyboard_get_key_state(xfc, state, XK_Num_Lock)) toggleKeysState |= KBD_SYNC_NUM_LOCK; + if (xf_keyboard_get_key_state(xfc, state, XK_Caps_Lock)) toggleKeysState |= KBD_SYNC_CAPS_LOCK; + if (xf_keyboard_get_key_state(xfc, state, XK_Kana_Lock)) toggleKeysState |= KBD_SYNC_KANA_LOCK; @@ -336,9 +338,8 @@ void xf_keyboard_focus_in(xfContext* xfc) if (!xfc->display || !xfc->window) return; - input = xfc->instance->input; + input = xfc->context.input; syncFlags = xf_keyboard_get_toggle_keys_state(xfc); - input->FocusInEvent(input, syncFlags); /* finish with a mouse pointer position like mstsc.exe if required */ @@ -346,7 +347,8 @@ void xf_keyboard_focus_in(xfContext* xfc) if (xfc->remote_app) return; - if (XQueryPointer(xfc->display, xfc->window->handle, &w, &w, &d, &d, &x, &y, &state)) + if (XQueryPointer(xfc->display, xfc->window->handle, &w, &w, &d, &d, &x, &y, + &state)) { if (x >= 0 && x < xfc->window->width && y >= 0 && y < xfc->window->height) { @@ -356,7 +358,9 @@ void xf_keyboard_focus_in(xfContext* xfc) } } -int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, KeySym keysym) +static int xf_keyboard_execute_action_script(xfContext* xfc, + XF_MODIFIER_KEYS* mod, + KeySym keysym) { int index; int count; @@ -374,13 +378,14 @@ int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, Key return 1; if ((keysym == XK_Shift_L) || (keysym == XK_Shift_R) || - (keysym == XK_Alt_L) || (keysym == XK_Alt_R) || - (keysym == XK_Control_L) || (keysym == XK_Control_R)) + (keysym == XK_Alt_L) || (keysym == XK_Alt_R) || + (keysym == XK_Control_L) || (keysym == XK_Control_R)) { return 1; } keyStr = XKeysymToString(keysym); + if (keyStr == 0) { return 1; @@ -396,7 +401,6 @@ int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, Key strcat(combination, "Alt+"); strcat(combination, keyStr); - count = ArrayList_Count(xfc->keyCombinations); for (index = 0; index < count; index++) @@ -414,8 +418,7 @@ int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, Key return 1; sprintf_s(command, sizeof(command), "%s key %s", - xfc->actionScript, combination); - + xfc->actionScript, combination); keyScript = popen(command, "r"); if (!keyScript) @@ -430,7 +433,6 @@ int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, Key } exitCode = pclose(keyScript); - return status; } @@ -439,26 +441,21 @@ int xk_keyboard_get_modifier_keys(xfContext* xfc, XF_MODIFIER_KEYS* mod) mod->LeftShift = xf_keyboard_key_pressed(xfc, XK_Shift_L); mod->RightShift = xf_keyboard_key_pressed(xfc, XK_Shift_R); mod->Shift = mod->LeftShift || mod->RightShift; - mod->LeftAlt = xf_keyboard_key_pressed(xfc, XK_Alt_L); mod->RightAlt = xf_keyboard_key_pressed(xfc, XK_Alt_R); mod->Alt = mod->LeftAlt || mod->RightAlt; - mod->LeftCtrl = xf_keyboard_key_pressed(xfc, XK_Control_L); mod->RightCtrl = xf_keyboard_key_pressed(xfc, XK_Control_R); mod->Ctrl = mod->LeftCtrl || mod->RightCtrl; - mod->LeftSuper = xf_keyboard_key_pressed(xfc, XK_Super_L); mod->RightSuper = xf_keyboard_key_pressed(xfc, XK_Super_R); mod->Super = mod->LeftSuper || mod->RightSuper; - return 0; } BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym) { XF_MODIFIER_KEYS mod = { 0 }; - xk_keyboard_get_modifier_keys(xfc, &mod); if (!xf_keyboard_execute_action_script(xfc, &mod, keysym)) @@ -466,7 +463,7 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym) return TRUE; } - if(!xfc->remote_app && xfc->fullscreen_toggle) + if (!xfc->remote_app && xfc->fullscreen_toggle) { if (keysym == XK_Return) { @@ -491,6 +488,7 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym) #if 0 /* set to 1 to enable multi touch gesture simulation via keyboard */ #ifdef WITH_XRENDER + if (!xfc->remote_app && xfc->settings->MultiTouchGestures) { if (mod.Ctrl && mod.Alt) @@ -500,18 +498,20 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym) int zdx = 0; int zdy = 0; - switch(keysym) + switch (keysym) { case XK_0: /* Ctrl-Alt-0: Reset scaling and panning */ xfc->scaledWidth = xfc->sessionWidth; xfc->scaledHeight = xfc->sessionHeight; xfc->offset_x = 0; xfc->offset_y = 0; + if (!xfc->fullscreen && (xfc->sessionWidth != xfc->window->width || - xfc->sessionHeight != xfc->window->height)) + xfc->sessionHeight != xfc->window->height)) { xf_ResizeDesktopWindow(xfc, xfc->window, xfc->sessionWidth, xfc->sessionHeight); } + xf_draw_screen(xfc, 0, 0, xfc->sessionWidth, xfc->sessionHeight); return TRUE; @@ -561,6 +561,7 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym) } } } + #endif /* WITH_XRENDER defined */ #endif /* pinch/zoom/pan simulation */ return FALSE; @@ -569,8 +570,8 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym) BOOL xf_keyboard_set_indicators(rdpContext* context, UINT16 led_flags) { xfContext* xfc = (xfContext*) context; - - xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_SCROLL_LOCK, XK_Scroll_Lock); + xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_SCROLL_LOCK, + XK_Scroll_Lock); xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_NUM_LOCK, XK_Num_Lock); xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_CAPS_LOCK, XK_Caps_Lock); xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_KANA_LOCK, XK_Kana_Lock); diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index 346bcd9..f40ba98 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -48,7 +48,6 @@ int xf_list_monitors(xfContext* xfc) int major, minor; int i, nmonitors = 0; XineramaScreenInfo* screen = NULL; - display = XOpenDisplay(NULL); if (!display) @@ -66,9 +65,9 @@ int xf_list_monitors(xfContext* xfc) for (i = 0; i < nmonitors; i++) { printf(" %s [%d] %dx%d\t+%d+%d\n", - (i == 0) ? "*" : " ", i, - screen[i].width, screen[i].height, - screen[i].x_org, screen[i].y_org); + (i == 0) ? "*" : " ", i, + screen[i].width, screen[i].height, + screen[i].x_org, screen[i].y_org); } XFree(screen); @@ -79,7 +78,6 @@ int xf_list_monitors(xfContext* xfc) #else Screen* screen; Display* display; - display = XOpenDisplay(NULL); if (!display) @@ -89,19 +87,17 @@ int xf_list_monitors(xfContext* xfc) } screen = ScreenOfDisplay(display, DefaultScreen(display)); - - printf(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0); - + printf(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), + HeightOfScreen(screen), 0, 0); XCloseDisplay(display); #endif - return 0; } BOOL xf_is_monitor_id_active(xfContext* xfc, UINT32 id) { int index; - rdpSettings* settings = xfc->settings; + rdpSettings* settings = xfc->context.settings; if (!settings->NumMonitorIds) return TRUE; @@ -121,28 +117,26 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) int nmonitors = 0; int primaryMonitorFound = FALSE; VIRTUAL_SCREEN* vscreen; - rdpSettings* settings = xfc->settings; - + rdpSettings* settings = xfc->context.settings; int mouse_x, mouse_y, _dummy_i; Window _dummy_w; int current_monitor = 0; - #ifdef WITH_XINERAMA int major, minor; XineramaScreenInfo* screenInfo = NULL; #endif - vscreen = &xfc->vscreen; *pMaxWidth = settings->DesktopWidth; *pMaxHeight = settings->DesktopHeight; /* get mouse location */ if (!XQueryPointer(xfc->display, DefaultRootWindow(xfc->display), - &_dummy_w, &_dummy_w, &mouse_x, &mouse_y, - &_dummy_i, &_dummy_i, (void *) &_dummy_i)) + &_dummy_w, &_dummy_w, &mouse_x, &mouse_y, + &_dummy_i, &_dummy_i, (void*) &_dummy_i)) mouse_x = mouse_y = 0; #ifdef WITH_XINERAMA + if (XineramaQueryExtension(xfc->display, &major, &minor)) { if (XineramaIsActive(xfc->display)) @@ -159,10 +153,11 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) vscreen->monitors[i].area.left = screenInfo[i].x_org; vscreen->monitors[i].area.top = screenInfo[i].y_org; vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1; - vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - 1; + vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - + 1; /* Determine which monitor that the mouse cursor is on */ - if ((mouse_x >= vscreen->monitors[i].area.left) && + if ((mouse_x >= vscreen->monitors[i].area.left) && (mouse_x <= vscreen->monitors[i].area.right) && (mouse_y >= vscreen->monitors[i].area.top) && (mouse_y <= vscreen->monitors[i].area.bottom)) @@ -173,15 +168,15 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) XFree(screenInfo); } } -#endif +#endif xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom = - xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0; + xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0; /* WORKAROUND: With Remote Application Mode - using NET_WM_WORKAREA - * causes issues with the ability to fully size the window vertically - * (the bottom of the window area is never updated). So, we just set - * the workArea to match the full Screen width/height. + * causes issues with the ability to fully size the window vertically + * (the bottom of the window area is never updated). So, we just set + * the workArea to match the full Screen width/height. */ if (settings->RemoteApplicationMode || !xf_GetWorkArea(xfc)) { @@ -211,8 +206,12 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) */ if (vscreen->nmonitors > 0) { - *pMaxWidth = ((vscreen->monitors[current_monitor].area.right - vscreen->monitors[current_monitor].area.left + 1) * settings->PercentScreen) / 100; - *pMaxHeight = ((vscreen->monitors[current_monitor].area.bottom - vscreen->monitors[current_monitor].area.top + 1) * settings->PercentScreen) / 100; + *pMaxWidth = ((vscreen->monitors[current_monitor].area.right - + vscreen->monitors[current_monitor].area.left + 1) * settings->PercentScreen) / + 100; + *pMaxHeight = ((vscreen->monitors[current_monitor].area.bottom - + vscreen->monitors[current_monitor].area.top + 1) * settings->PercentScreen) / + 100; } } @@ -220,8 +219,9 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) return TRUE; /* If single monitor fullscreen OR workarea without remote app */ - if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) || - (settings->Workarea && !settings->RemoteApplicationMode)) + if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) + || + (settings->Workarea && !settings->RemoteApplicationMode)) { /* If no monitors were specified on the command-line then set the current monitor as active */ if (!settings->NumMonitorIds) @@ -244,10 +244,12 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) settings->MonitorDefArray[nmonitors].x = vscreen->monitors[i].area.left; settings->MonitorDefArray[nmonitors].y = vscreen->monitors[i].area.top; - settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1, *pMaxWidth); - settings->MonitorDefArray[nmonitors].height = MIN(vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, *pMaxHeight); + settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right + - vscreen->monitors[i].area.left + 1, *pMaxWidth); + settings->MonitorDefArray[nmonitors].height = MIN( + vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, + *pMaxHeight); settings->MonitorDefArray[nmonitors].orig_screen = i; - nmonitors++; } @@ -256,10 +258,13 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) { settings->MonitorDefArray[0].x = vscreen->monitors[current_monitor].area.left; settings->MonitorDefArray[0].y = vscreen->monitors[current_monitor].area.top; - settings->MonitorDefArray[0].width = MIN(vscreen->monitors[current_monitor].area.right - vscreen->monitors[current_monitor].area.left + 1, *pMaxWidth); - settings->MonitorDefArray[0].height = MIN(vscreen->monitors[current_monitor].area.bottom - vscreen->monitors[current_monitor].area.top + 1, *pMaxHeight); + settings->MonitorDefArray[0].width = MIN( + vscreen->monitors[current_monitor].area.right - + vscreen->monitors[current_monitor].area.left + 1, *pMaxWidth); + settings->MonitorDefArray[0].height = MIN( + vscreen->monitors[current_monitor].area.bottom - + vscreen->monitors[current_monitor].area.top + 1, *pMaxHeight); settings->MonitorDefArray[0].orig_screen = current_monitor; - nmonitors = 1; } @@ -274,7 +279,8 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) int vR = vX + settings->MonitorDefArray[0].width; int vB = vY + settings->MonitorDefArray[0].height; xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom = - xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = settings->MonitorDefArray[0].orig_screen; + xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = + settings->MonitorDefArray[0].orig_screen; /* Calculate bounding rectangle around all monitors to be used AND * also set the Xinerama indices which define left/top/right/bottom monitors. @@ -284,15 +290,20 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) /* does the same as gdk_rectangle_union */ int destX = MIN(vX, settings->MonitorDefArray[i].x); int destY = MIN(vY, settings->MonitorDefArray[i].y); - int destR = MAX(vR, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width); - int destB = MAX(vB, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height); + int destR = MAX(vR, settings->MonitorDefArray[i].x + + settings->MonitorDefArray[i].width); + int destB = MAX(vB, settings->MonitorDefArray[i].y + + settings->MonitorDefArray[i].height); if (vX != destX) xfc->fullscreenMonitors.left = settings->MonitorDefArray[i].orig_screen; + if (vY != destY) xfc->fullscreenMonitors.top = settings->MonitorDefArray[i].orig_screen; + if (vR != destR) xfc->fullscreenMonitors.right = settings->MonitorDefArray[i].orig_screen; + if (vB != destB) xfc->fullscreenMonitors.bottom = settings->MonitorDefArray[i].orig_screen; @@ -304,7 +315,6 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) settings->DesktopPosX = vX; settings->DesktopPosY = vY; - vscreen->area.left = 0; vscreen->area.right = vR - vX - 1; vscreen->area.top = 0; @@ -318,11 +328,12 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) /* If there are multiple monitors and we have not selected a primary */ if (!primaryMonitorFound) - { + { /* First lets try to see if there is a monitor with a 0,0 coordinate */ - for (i=0; iMonitorCount; i++) + for (i = 0; i < settings->MonitorCount; i++) { - if (!primaryMonitorFound && settings->MonitorDefArray[i].x == 0 && settings->MonitorDefArray[i].y == 0) + if (!primaryMonitorFound && settings->MonitorDefArray[i].x == 0 + && settings->MonitorDefArray[i].y == 0) { settings->MonitorDefArray[i].is_primary = TRUE; settings->MonitorLocalShiftX = settings->MonitorDefArray[i].x; @@ -341,16 +352,18 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) } } - /* Subtract monitor shift from monitor variables for server-side use. + /* Subtract monitor shift from monitor variables for server-side use. * We maintain monitor shift value as Window requires the primary monitor to have a coordinate of 0,0 * In some X configurations, no monitor may have a coordinate of 0,0. This can also be happen if the user * requests specific monitors from the command-line as well. So, we make sure to translate our primary monitor's * upper-left corner to 0,0 on the server. */ - for (i=0; i < settings->MonitorCount; i++) + for (i = 0; i < settings->MonitorCount; i++) { - settings->MonitorDefArray[i].x = settings->MonitorDefArray[i].x - settings->MonitorLocalShiftX; - settings->MonitorDefArray[i].y = settings->MonitorDefArray[i].y - settings->MonitorLocalShiftY; + settings->MonitorDefArray[i].x = settings->MonitorDefArray[i].x - + settings->MonitorLocalShiftX; + settings->MonitorDefArray[i].y = settings->MonitorDefArray[i].y - + settings->MonitorLocalShiftY; } /* Set the desktop width and height according to the bounding rectangle around the active monitors */ diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 6b49d56..ba96483 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -83,7 +83,6 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled) { xfAppWindow* appWindow; RAIL_ACTIVATE_ORDER activate; - appWindow = xf_AppWindowFromX11Window(xfc, xwindow); if (!appWindow) @@ -91,17 +90,15 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled) activate.windowId = appWindow->windowId; activate.enabled = enabled; - xfc->rail->ClientActivate(xfc->rail, &activate); } -void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16 command) +void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, + UINT16 command) { RAIL_SYSCOMMAND_ORDER syscommand; - syscommand.windowId = windowId; syscommand.command = command; - xfc->rail->ClientSystemCommand(xfc->rail, &syscommand); } @@ -120,9 +117,9 @@ void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow) /* If current window position disagrees with RDP window position, send update to RDP server */ if (appWindow->x != appWindow->windowOffsetX || - appWindow->y != appWindow->windowOffsetY || - appWindow->width != appWindow->windowWidth || - appWindow->height != appWindow->windowHeight) + appWindow->y != appWindow->windowOffsetY || + appWindow->width != appWindow->windowWidth || + appWindow->height != appWindow->windowHeight) { windowMove.windowId = appWindow->windowId; /* @@ -132,7 +129,6 @@ void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow) windowMove.top = appWindow->y; windowMove.right = windowMove.left + appWindow->width; windowMove.bottom = windowMove.top + appWindow->height; - xfc->rail->ClientWindowMove(xfc->rail, &windowMove); } } @@ -146,33 +142,30 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow) Window root_window; Window child_window; RAIL_WINDOW_MOVE_ORDER windowMove; - rdpInput* input = xfc->instance->input; - + rdpInput* input = xfc->context.input; /* * For keyboard moves send and explicit update to RDP server */ windowMove.windowId = appWindow->windowId; - /* * Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server * */ windowMove.left = appWindow->x; windowMove.top = appWindow->y; - windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */ + windowMove.right = windowMove.left + + appWindow->width; /* In the update to RDP the position is one past the window */ windowMove.bottom = windowMove.top + appWindow->height; - xfc->rail->ClientWindowMove(xfc->rail, &windowMove); - /* * Simulate button up at new position to end the local move (per RDP spec) */ XQueryPointer(xfc->display, appWindow->handle, - &root_window, &child_window, &x, &y, &child_x, &child_y, &mask); + &root_window, &child_window, &x, &y, &child_x, &child_y, &mask); /* only send the mouse coordinates if not a keyboard move or size */ if ((appWindow->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) && - (appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD)) + (appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD)) { input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y); } @@ -199,14 +192,13 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion) xfAppWindow* appWindow; const RECTANGLE_16* extents; REGION16 windowInvalidRegion; - region16_init(&windowInvalidRegion); - count = HashTable_GetKeys(xfc->railWindows, &pKeys); for (index = 0; index < count; index++) { - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]); + appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, + (void*) pKeys[index]); if (appWindow) { @@ -214,14 +206,12 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion) windowRect.top = MAX(appWindow->y, 0); windowRect.right = MAX(appWindow->x + appWindow->width, 0); windowRect.bottom = MAX(appWindow->y + appWindow->height, 0); - region16_clear(&windowInvalidRegion); region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect); if (!region16_is_empty(&windowInvalidRegion)) { extents = region16_extents(&windowInvalidRegion); - updateRect.left = extents->left - appWindow->x; updateRect.top = extents->top - appWindow->y; updateRect.right = extents->right - appWindow->x; @@ -230,8 +220,8 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion) if (appWindow) { xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top, - updateRect.right - updateRect.left, - updateRect.bottom - updateRect.top); + updateRect.right - updateRect.left, + updateRect.bottom - updateRect.top); } } } @@ -240,27 +230,25 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion) region16_uninit(&windowInvalidRegion); } -void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom) +void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, + UINT32 ubottom) { REGION16 invalidRegion; RECTANGLE_16 invalidRect; - invalidRect.left = uleft; invalidRect.top = utop; invalidRect.right = uright; invalidRect.bottom = ubottom; - region16_init(&invalidRegion); region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect); - xf_rail_invalidate_region(xfc, &invalidRegion); - region16_uninit(&invalidRegion); } /* RemoteApp Core Protocol Extension */ -static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState) +static BOOL xf_rail_window_common(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState) { xfAppWindow* appWindow = NULL; xfContext* xfc = (xfContext*) context; @@ -275,11 +263,9 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI return FALSE; appWindow->xfc = xfc; - appWindow->windowId = orderInfo->windowId; appWindow->dwStyle = windowState->style; appWindow->dwExStyle = windowState->extendedStyle; - appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX; appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY; appWindow->width = appWindow->windowWidth = windowState->windowWidth; @@ -299,7 +285,7 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI } } else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string, - windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1) + windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert window title"); /* error handled below */ @@ -319,14 +305,14 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI return FALSE; } - HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow); - + HashTable_Add(xfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId, + (void*) appWindow); xf_AppWindowInit(xfc, appWindow); } else { appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, - (void*) (UINT_PTR) orderInfo->windowId); + (void*)(UINT_PTR) orderInfo->windowId); } if (!appWindow) @@ -334,16 +320,15 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI /* Keep track of any position/size update so that we can force a refresh of the window */ if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) || - (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) || - (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) || - (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) || - (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) || - (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) || - (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)) + (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) || + (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) || + (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) || + (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) || + (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) || + (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)) { position_or_size_updated = TRUE; - } - + } /* Update Parameters */ @@ -388,11 +373,12 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI } } else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string, - windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1) + windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert window title"); return FALSE; } + free(appWindow->title); appWindow->title = title; } @@ -427,13 +413,14 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI if (appWindow->numWindowRects) { - appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects, sizeof(RECTANGLE_16)); + appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects, + sizeof(RECTANGLE_16)); if (!appWindow->windowRects) return FALSE; CopyMemory(appWindow->windowRects, windowState->windowRects, - appWindow->numWindowRects * sizeof(RECTANGLE_16)); + appWindow->numWindowRects * sizeof(RECTANGLE_16)); } } @@ -455,13 +442,14 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI if (appWindow->numVisibilityRects) { - appWindow->visibilityRects = (RECTANGLE_16*) calloc(appWindow->numVisibilityRects, sizeof(RECTANGLE_16)); + appWindow->visibilityRects = (RECTANGLE_16*) calloc( + appWindow->numVisibilityRects, sizeof(RECTANGLE_16)); if (!appWindow->visibilityRects) return FALSE; CopyMemory(appWindow->visibilityRects, windowState->visibilityRects, - appWindow->numVisibilityRects * sizeof(RECTANGLE_16)); + appWindow->numVisibilityRects * sizeof(RECTANGLE_16)); } } @@ -469,7 +457,6 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI if (fieldFlags & WINDOW_ORDER_FIELD_STYLE) { - } if (fieldFlags & WINDOW_ORDER_FIELD_SHOW) @@ -485,8 +472,10 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI if (position_or_size_updated) { - UINT32 visibilityRectsOffsetX = (appWindow->visibleOffsetX - (appWindow->clientOffsetX - appWindow->windowClientDeltaX)); - UINT32 visibilityRectsOffsetY = (appWindow->visibleOffsetY - (appWindow->clientOffsetY - appWindow->windowClientDeltaY)); + UINT32 visibilityRectsOffsetX = (appWindow->visibleOffsetX - + (appWindow->clientOffsetX - appWindow->windowClientDeltaX)); + UINT32 visibilityRectsOffsetY = (appWindow->visibleOffsetY - + (appWindow->clientOffsetY - appWindow->windowClientDeltaY)); /* * The rail server like to set the window to a small size when it is minimized even though it is hidden @@ -495,22 +484,25 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI */ if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED) { - /* Redraw window area if already in the correct position */ if (appWindow->x == appWindow->windowOffsetX && - appWindow->y == appWindow->windowOffsetY && - appWindow->width == appWindow->windowWidth && - appWindow->height == appWindow->windowHeight) + appWindow->y == appWindow->windowOffsetY && + appWindow->width == appWindow->windowWidth && + appWindow->height == appWindow->windowHeight) { - xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight); + xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, + appWindow->windowHeight); } else { - xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX, appWindow->windowOffsetY, - appWindow->windowWidth, appWindow->windowHeight); + xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX, + appWindow->windowOffsetY, + appWindow->windowWidth, appWindow->windowHeight); } - xf_SetWindowVisibilityRects(xfc, appWindow, visibilityRectsOffsetX, visibilityRectsOffsetY, appWindow->visibilityRects, appWindow->numVisibilityRects); + xf_SetWindowVisibilityRects(xfc, appWindow, visibilityRectsOffsetX, + visibilityRectsOffsetY, appWindow->visibilityRects, + appWindow->numVisibilityRects); } } @@ -519,104 +511,103 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI { xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects); }*/ - return TRUE; } -static BOOL xf_rail_window_delete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +static BOOL xf_rail_window_delete(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo) { xfAppWindow* appWindow = NULL; xfContext* xfc = (xfContext*) context; - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, - (void*) (UINT_PTR) orderInfo->windowId); + (void*)(UINT_PTR) orderInfo->windowId); if (!appWindow) return TRUE; - HashTable_Remove(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId); - + HashTable_Remove(xfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId); xf_DestroyWindow(xfc, appWindow); return TRUE; } -static BOOL xf_rail_window_icon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon) +static BOOL xf_rail_window_icon(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon) { BOOL bigIcon; xfAppWindow* railWindow; xfContext* xfc = (xfContext*) context; - railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, - (void*) (UINT_PTR) orderInfo->windowId); + (void*)(UINT_PTR) orderInfo->windowId); if (!railWindow) return FALSE; bigIcon = (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? TRUE : FALSE; - return TRUE; } -static BOOL xf_rail_window_cached_icon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* windowCachedIcon) +static BOOL xf_rail_window_cached_icon(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* windowCachedIcon) { return TRUE; } -static BOOL xf_rail_notify_icon_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) +static BOOL xf_rail_notify_icon_common(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) { if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) { - } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) { - } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) { - } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE) { - } if (orderInfo->fieldFlags & WINDOW_ORDER_ICON) { - } if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON) { - } + return TRUE; } -static BOOL xf_rail_notify_icon_create(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) +static BOOL xf_rail_notify_icon_create(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) { return xf_rail_notify_icon_common(context, orderInfo, notifyIconState); } -static BOOL xf_rail_notify_icon_update(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) +static BOOL xf_rail_notify_icon_update(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) { return xf_rail_notify_icon_common(context, orderInfo, notifyIconState); } -static BOOL xf_rail_notify_icon_delete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +static BOOL xf_rail_notify_icon_delete(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo) { return TRUE; } -static BOOL xf_rail_monitored_desktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitoredDesktop) +static BOOL xf_rail_monitored_desktop(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitoredDesktop) { return TRUE; } -static BOOL xf_rail_non_monitored_desktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +static BOOL xf_rail_non_monitored_desktop(rdpContext* context, + WINDOW_ORDER_INFO* orderInfo) { xfContext* xfc = (xfContext*) context; xf_rail_disable_remoteapp_mode(xfc); @@ -626,7 +617,6 @@ static BOOL xf_rail_non_monitored_desktop(rdpContext* context, WINDOW_ORDER_INFO void xf_rail_register_update_callbacks(rdpUpdate* update) { rdpWindowUpdate* window = update->window; - window->WindowCreate = xf_rail_window_common; window->WindowUpdate = xf_rail_window_common; window->WindowDelete = xf_rail_window_delete; @@ -646,15 +636,16 @@ void xf_rail_register_update_callbacks(rdpUpdate* update) * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORDER* execResult) +static UINT xf_rail_server_execute_result(RailClientContext* context, + RAIL_EXEC_RESULT_ORDER* execResult) { xfContext* xfc = (xfContext*) context->custom; if (execResult->execResult != RAIL_EXEC_S_OK) { WLog_ERR(TAG, "RAIL exec error: execResult=%s NtError=0x%X\n", - error_code_names[execResult->execResult], execResult->rawResult); - xfc->disconnect = TRUE; + error_code_names[execResult->execResult], execResult->rawResult); + freerdp_abort_connect(xfc->context.instance); } else { @@ -669,7 +660,8 @@ static UINT xf_rail_server_execute_result(RailClientContext* context, RAIL_EXEC_ * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam) +static UINT xf_rail_server_system_param(RailClientContext* context, + RAIL_SYSPARAM_ORDER* sysparam) { return CHANNEL_RC_OK; } @@ -679,18 +671,17 @@ static UINT xf_rail_server_system_param(RailClientContext* context, RAIL_SYSPARA * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake) +static UINT xf_rail_server_handshake(RailClientContext* context, + RAIL_HANDSHAKE_ORDER* handshake) { RAIL_EXEC_ORDER exec; RAIL_SYSPARAM_ORDER sysparam; RAIL_HANDSHAKE_ORDER clientHandshake; RAIL_CLIENT_STATUS_ORDER clientStatus; xfContext* xfc = (xfContext*) context->custom; - rdpSettings* settings = xfc->settings; - + rdpSettings* settings = xfc->context.settings; clientHandshake.buildNumber = 0x00001DB0; context->ClientHandshake(context, &clientHandshake); - ZeroMemory(&clientStatus, sizeof(RAIL_CLIENT_STATUS_ORDER)); clientStatus.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE; context->ClientInformation(context, &clientStatus); @@ -703,44 +694,31 @@ static UINT xf_rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ } ZeroMemory(&sysparam, sizeof(RAIL_SYSPARAM_ORDER)); - sysparam.params = 0; - sysparam.params |= SPI_MASK_SET_HIGH_CONTRAST; sysparam.highContrast.colorScheme.string = NULL; sysparam.highContrast.colorScheme.length = 0; sysparam.highContrast.flags = 0x7E; - sysparam.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP; sysparam.mouseButtonSwap = FALSE; - sysparam.params |= SPI_MASK_SET_KEYBOARD_PREF; sysparam.keyboardPref = FALSE; - sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS; sysparam.dragFullWindows = FALSE; - sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES; sysparam.keyboardCues = FALSE; - sysparam.params |= SPI_MASK_SET_WORK_AREA; sysparam.workArea.left = 0; sysparam.workArea.top = 0; sysparam.workArea.right = settings->DesktopWidth; sysparam.workArea.bottom = settings->DesktopHeight; - sysparam.dragFullWindows = FALSE; - context->ClientSystemParam(context, &sysparam); - ZeroMemory(&exec, sizeof(RAIL_EXEC_ORDER)); - exec.RemoteApplicationProgram = settings->RemoteApplicationProgram; exec.RemoteApplicationWorkingDir = settings->ShellWorkingDirectory; exec.RemoteApplicationArguments = settings->RemoteApplicationCmdLine; - context->ClientExecute(context, &exec); - return CHANNEL_RC_OK; } @@ -749,7 +727,8 @@ static UINT xf_rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx) +static UINT xf_rail_server_handshake_ex(RailClientContext* context, + RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { return CHANNEL_RC_OK; } @@ -759,16 +738,16 @@ static UINT xf_rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHA * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize) +static UINT xf_rail_server_local_move_size(RailClientContext* context, + RAIL_LOCALMOVESIZE_ORDER* localMoveSize) { int x = 0, y = 0; int direction = 0; Window child_window; xfAppWindow* appWindow = NULL; xfContext* xfc = (xfContext*) context->custom; - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, - (void*) (UINT_PTR) localMoveSize->windowId); + (void*)(UINT_PTR) localMoveSize->windowId); if (!appWindow) return ERROR_INTERNAL_ERROR; @@ -826,8 +805,8 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context, RAIL_LOCA case RAIL_WMSZ_MOVE: direction = _NET_WM_MOVERESIZE_MOVE; XTranslateCoordinates(xfc->display, appWindow->handle, - RootWindowOfScreen(xfc->screen), - localMoveSize->posX, localMoveSize->posY, &x, &y, &child_window); + RootWindowOfScreen(xfc->screen), + localMoveSize->posX, localMoveSize->posY, &x, &y, &child_window); break; case RAIL_WMSZ_KEYMOVE: @@ -864,23 +843,22 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context, RAIL_LOCA * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* minMaxInfo) +static UINT xf_rail_server_min_max_info(RailClientContext* context, + RAIL_MINMAXINFO_ORDER* minMaxInfo) { xfAppWindow* appWindow = NULL; xfContext* xfc = (xfContext*) context->custom; - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, - (void*) (UINT_PTR) minMaxInfo->windowId); + (void*)(UINT_PTR) minMaxInfo->windowId); if (!appWindow) return ERROR_INTERNAL_ERROR; xf_SetWindowMinMaxInfo(xfc, appWindow, - minMaxInfo->maxWidth, minMaxInfo->maxHeight, - minMaxInfo->maxPosX, minMaxInfo->maxPosY, - minMaxInfo->minTrackWidth, minMaxInfo->minTrackHeight, - minMaxInfo->maxTrackWidth, minMaxInfo->maxTrackHeight); - + minMaxInfo->maxWidth, minMaxInfo->maxHeight, + minMaxInfo->maxPosX, minMaxInfo->maxPosY, + minMaxInfo->minTrackWidth, minMaxInfo->minTrackHeight, + minMaxInfo->maxTrackWidth, minMaxInfo->maxTrackHeight); return CHANNEL_RC_OK; } @@ -889,7 +867,8 @@ static UINT xf_rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXI * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo) +static UINT xf_rail_server_language_bar_info(RailClientContext* context, + RAIL_LANGBAR_INFO_ORDER* langBarInfo) { return CHANNEL_RC_OK; } @@ -899,7 +878,8 @@ static UINT xf_rail_server_language_bar_info(RailClientContext* context, RAIL_LA * * @return 0 on success, otherwise a Win32 error code */ -static UINT xf_rail_server_get_appid_response(RailClientContext* context, RAIL_GET_APPID_RESP_ORDER* getAppIdResp) +static UINT xf_rail_server_get_appid_response(RailClientContext* context, + RAIL_GET_APPID_RESP_ORDER* getAppIdResp) { return CHANNEL_RC_OK; } @@ -907,13 +887,9 @@ static UINT xf_rail_server_get_appid_response(RailClientContext* context, RAIL_G int xf_rail_init(xfContext* xfc, RailClientContext* rail) { rdpContext* context = (rdpContext*) xfc; - xfc->rail = rail; - xf_rail_register_update_callbacks(context->update); - rail->custom = (void*) xfc; - rail->ServerExecuteResult = xf_rail_server_execute_result; rail->ServerSystemParam = xf_rail_server_system_param; rail->ServerHandshake = xf_rail_server_handshake; @@ -922,8 +898,8 @@ int xf_rail_init(xfContext* xfc, RailClientContext* rail) rail->ServerMinMaxInfo = xf_rail_server_min_max_info; rail->ServerLanguageBarInfo = xf_rail_server_language_bar_info; rail->ServerGetAppIdResponse = xf_rail_server_get_appid_response; - xfc->railWindows = HashTable_New(TRUE); + if (!xfc->railWindows) return 0; diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 95c29a0..1c7a51a 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -4,6 +4,8 @@ * * Copyright 2011 Marc-Andre Moreau * Copyright 2012 HP Development Company, LLC + * Copyright 2016 Thincast Technologies GmbH + * Copyright 2016 Armin Novak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,9 +58,9 @@ #define TAG CLIENT_TAG("x11") #ifdef WITH_DEBUG_X11 -#define DEBUG_X11(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__) +#define DEBUG_X11(...) WLog_DBG(TAG, __VA_ARGS__) #else -#define DEBUG_X11(fmt, ...) do { } while (0) +#define DEBUG_X11(...) do { } while (0) #endif #include "FreeRDP_Icon_256px.h" @@ -106,15 +108,14 @@ typedef struct _PropMotifWmHints PropMotifWmHints; /** * Post an event from the client to the X server */ -void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int numArgs, ...) +void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, + unsigned int numArgs, ...) { XEvent xevent; unsigned int i; va_list argp; va_start(argp, numArgs); - ZeroMemory(&xevent, sizeof(XEvent)); - xevent.xclient.type = ClientMessage; xevent.xclient.serial = 0; xevent.xclient.send_event = False; @@ -123,29 +124,26 @@ void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int n xevent.xclient.message_type = atom; xevent.xclient.format = 32; - for (i=0; idisplay, RootWindowOfScreen(xfc->screen), False, - SubstructureRedirectMask | SubstructureNotifyMask, &xevent); - + SubstructureRedirectMask | SubstructureNotifyMask, &xevent); XSync(xfc->display, False); - va_end(argp); } void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen) { int i; - rdpSettings* settings = xfc->settings; + rdpSettings* settings = xfc->context.settings; int startX, startY; UINT32 width = window->width; UINT32 height = window->height; - window->decorations = xfc->decorations; xf_SetWindowDecorations(xfc, window->handle, window->decorations); @@ -167,34 +165,34 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen) } /* Determine the x,y starting location for the fullscreen window */ - if (fullscreen && xfc->instance->settings->MonitorCount) + if (fullscreen && xfc->context.settings->MonitorCount) { /* Initialize startX and startY with reasonable values */ - startX = xfc->instance->settings->MonitorDefArray[0].x; - startY = xfc->instance->settings->MonitorDefArray[0].y; + startX = xfc->context.settings->MonitorDefArray[0].x; + startY = xfc->context.settings->MonitorDefArray[0].y; /* Search all monitors to find the lowest startX and startY values */ - for (i=0; i < xfc->instance->settings->MonitorCount; i++) + for (i = 0; i < xfc->context.settings->MonitorCount; i++) { - startX = MIN(startX, xfc->instance->settings->MonitorDefArray[i].x); - startY = MIN(startY, xfc->instance->settings->MonitorDefArray[i].y); + startX = MIN(startX, xfc->context.settings->MonitorDefArray[i].x); + startY = MIN(startY, xfc->context.settings->MonitorDefArray[i].y); } /* Lastly apply any monitor shift(translation from remote to local coordinate system) * to startX and startY values */ - startX = startX + xfc->instance->settings->MonitorLocalShiftX; - startY = startY + xfc->instance->settings->MonitorLocalShiftY; + startX = startX + xfc->context.settings->MonitorLocalShiftX; + startY = startY + xfc->context.settings->MonitorLocalShiftY; /* Set monitor bounds */ if (settings->MonitorCount > 1) { xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5, - xfc->fullscreenMonitors.top, - xfc->fullscreenMonitors.bottom, - xfc->fullscreenMonitors.left, - xfc->fullscreenMonitors.right, - 1); + xfc->fullscreenMonitors.top, + xfc->fullscreenMonitors.bottom, + xfc->fullscreenMonitors.left, + xfc->fullscreenMonitors.right, + 1); } } @@ -208,8 +206,8 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen) /* Set the fullscreen state */ xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4, - fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, - xfc->_NET_WM_STATE_FULLSCREEN, 0, 0); + fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, + xfc->_NET_WM_STATE_FULLSCREEN, 0, 0); if (!fullscreen) { @@ -220,8 +218,9 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen) /* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */ -BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int length, - unsigned long* nitems, unsigned long* bytes, BYTE** prop) +BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, + int length, + unsigned long* nitems, unsigned long* bytes, BYTE** prop) { int status; Atom actual_type; @@ -231,15 +230,15 @@ BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int leng return FALSE; status = XGetWindowProperty(xfc->display, window, - property, 0, length, FALSE, AnyPropertyType, - &actual_type, &actual_format, nitems, bytes, prop); + property, 0, length, FALSE, AnyPropertyType, + &actual_type, &actual_format, nitems, bytes, prop); if (status != Success) return FALSE; if (actual_type == None) { - WLog_INFO(TAG, "Property %lu does not exist", property); + WLog_INFO(TAG, "Property %lu does not exist", (unsigned long) property); return FALSE; } @@ -251,36 +250,32 @@ BOOL xf_GetCurrentDesktop(xfContext* xfc) BOOL status; unsigned long nitems; unsigned long bytes; - unsigned char *prop; - + unsigned char* prop; status = xf_GetWindowProperty(xfc, DefaultRootWindow(xfc->display), - xfc->_NET_CURRENT_DESKTOP, 1, &nitems, &bytes, &prop); + xfc->_NET_CURRENT_DESKTOP, 1, &nitems, &bytes, &prop); if (!status) return FALSE; - xfc->current_desktop = (int) *prop; - + xfc->current_desktop = (int) * prop; free(prop); - return TRUE; } BOOL xf_GetWorkArea(xfContext* xfc) { - long *plong; + long* plong; BOOL status; unsigned long nitems; unsigned long bytes; - unsigned char *prop; - + unsigned char* prop; status = xf_GetCurrentDesktop(xfc); if (!status) return FALSE; status = xf_GetWindowProperty(xfc, DefaultRootWindow(xfc->display), - xfc->_NET_WORKAREA, 32 * 4, &nitems, &bytes, &prop); + xfc->_NET_WORKAREA, 32 * 4, &nitems, &bytes, &prop); if (!status) return FALSE; @@ -296,35 +291,30 @@ BOOL xf_GetWorkArea(xfContext* xfc) xfc->workArea.y = plong[xfc->current_desktop * 4 + 1]; xfc->workArea.width = plong[xfc->current_desktop * 4 + 2]; xfc->workArea.height = plong[xfc->current_desktop * 4 + 3]; - free(prop); - return TRUE; } void xf_SetWindowDecorations(xfContext* xfc, Window window, BOOL show) { PropMotifWmHints hints; - hints.decorations = (show) ? MWM_DECOR_ALL : 0; hints.functions = MWM_FUNC_ALL ; hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS; hints.inputMode = 0; hints.status = 0; - - XChangeProperty(xfc->display, window, xfc->_MOTIF_WM_HINTS, xfc->_MOTIF_WM_HINTS, 32, - PropModeReplace, (BYTE*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS); + XChangeProperty(xfc->display, window, xfc->_MOTIF_WM_HINTS, + xfc->_MOTIF_WM_HINTS, 32, + PropModeReplace, (BYTE*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS); } void xf_SetWindowUnlisted(xfContext* xfc, Window window) { Atom window_state[2]; - window_state[0] = xfc->_NET_WM_STATE_SKIP_PAGER; window_state[1] = xfc->_NET_WM_STATE_SKIP_TASKBAR; - XChangeProperty(xfc->display, window, xfc->_NET_WM_STATE, - XA_ATOM, 32, PropModeReplace, (BYTE*) &window_state, 2); + XA_ATOM, 32, PropModeReplace, (BYTE*) &window_state, 2); } static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid) @@ -335,19 +325,20 @@ static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid) pid = getpid(); am_wm_pid = xfc->_NET_WM_PID; - XChangeProperty(xfc->display, window, am_wm_pid, XA_CARDINAL, - 32, PropModeReplace, (BYTE*) &pid, 1); + 32, PropModeReplace, (BYTE*) &pid, 1); } static const char* get_shm_id() { static char shm_id[64]; - sprintf_s(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId()); + sprintf_s(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", + GetCurrentProcessId()); return shm_id; } -xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height) +xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, + int height) { XEvent xevent; int input_mask; @@ -355,28 +346,25 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig Window parentWindow; XClassHint* classHints; rdpSettings* settings; - window = (xfWindow*) calloc(1, sizeof(xfWindow)); if (!window) return NULL; - settings = xfc->instance->settings; - parentWindow = (Window) xfc->settings->ParentWindowId; - + settings = xfc->context.settings; + parentWindow = (Window) xfc->context.settings->ParentWindowId; window->width = width; window->height = height; window->decorations = xfc->decorations; window->is_mapped = FALSE; window->is_transient = FALSE; - window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen), - xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height, - 0, xfc->depth, InputOutput, xfc->visual, - CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | - CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs); - - window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE)); + xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height, + 0, xfc->depth, InputOutput, xfc->visual, + CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | + CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs); + window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR), + (S_IREAD | S_IWRITE)); if (window->shmid < 0) { @@ -385,10 +373,9 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig else { void* mem; - ftruncate(window->shmid, sizeof(window->handle)); - - mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED, window->shmid, 0); + mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED, + window->shmid, 0); if (mem == MAP_FAILED) { @@ -407,8 +394,8 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig { classHints->res_name = "xfreerdp"; - if (xfc->settings->WmClass) - classHints->res_class = xfc->settings->WmClass; + if (xfc->context.settings->WmClass) + classHints->res_class = xfc->context.settings->WmClass; else classHints->res_class = "xfreerdp"; @@ -419,17 +406,17 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig xf_ResizeDesktopWindow(xfc, window, width, height); xf_SetWindowDecorations(xfc, window->handle, window->decorations); xf_SetWindowPID(xfc, window->handle, 0); - input_mask = - KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | - VisibilityChangeMask | FocusChangeMask | StructureNotifyMask | - PointerMotionMask | ExposureMask | PropertyChangeMask; + KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | + VisibilityChangeMask | FocusChangeMask | StructureNotifyMask | + PointerMotionMask | ExposureMask | PropertyChangeMask; if (xfc->grab_keyboard) input_mask |= EnterWindowMask | LeaveWindowMask; - XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32, - PropModeReplace, (BYTE*) xf_icon_prop, ARRAYSIZE(xf_icon_prop)); + XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, + 32, + PropModeReplace, (BYTE*) xf_icon_prop, ARRAYSIZE(xf_icon_prop)); if (parentWindow) XReparentWindow(xfc->display, window->handle, parentWindow, 0, 0); @@ -437,7 +424,6 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig XSelectInput(xfc->display, window->handle, input_mask); XClearWindow(xfc->display, window->handle); XMapWindow(xfc->display, window->handle); - xf_input_init(xfc, window->handle); /* @@ -449,47 +435,46 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig XMaskEvent(xfc->display, VisibilityChangeMask, &xevent); } while (xevent.type != VisibilityNotify); + /* * The XCreateWindow call will start the window in the upper-left corner of our current * monitor instead of the upper-left monitor for remote app mode (which uses all monitors). * This extra call after the window is mapped will position the login window correctly */ - if (xfc->settings->RemoteApplicationMode) + if (xfc->context.settings->RemoteApplicationMode) { XMoveWindow(xfc->display, window->handle, 0, 0); } else if (settings->DesktopPosX || settings->DesktopPosY) { - XMoveWindow(xfc->display, window->handle, settings->DesktopPosX, settings->DesktopPosY); + XMoveWindow(xfc->display, window->handle, settings->DesktopPosX, + settings->DesktopPosY); } XStoreName(xfc->display, window->handle, name); - return window; } -void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height) +void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, + int height) { XSizeHints* size_hints; if (!xfc || !window) - return; + return; if (!(size_hints = XAllocSizeHints())) - return; + return; size_hints->flags = PMinSize | PMaxSize | PWinGravity; - size_hints->win_gravity = NorthWestGravity; size_hints->min_width = size_hints->min_height = 1; size_hints->max_width = size_hints->max_height = 16384; - XSetWMNormalHints(xfc->display, window->handle, size_hints); - XResizeWindow(xfc->display, window->handle, width, height); - #ifdef WITH_XRENDER - if (!xfc->settings->SmartSizing) + + if (!xfc->context.settings->SmartSizing) #endif { if (!xfc->fullscreen) @@ -527,14 +512,13 @@ void xf_DestroyDesktopWindow(xfContext* xfc, xfWindow* window) close(window->shmid); shm_unlink(get_shm_id()); - - window->xfwin = (Window*) -1; + window->xfwin = (Window*) - 1; window->shmid = -1; - free(window); } -void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style) +void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, + UINT32 ex_style) { Atom window_type; @@ -551,7 +535,8 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN */ XSetWindowAttributes attrs; attrs.override_redirect = True; - XChangeWindowAttributes(xfc->display, appWindow->handle, CWOverrideRedirect, &attrs); + XChangeWindowAttributes(xfc->display, appWindow->handle, CWOverrideRedirect, + &attrs); appWindow->is_transient = TRUE; xf_SetWindowUnlisted(xfc, appWindow->handle); window_type = xfc->_NET_WM_WINDOW_TYPE_POPUP; @@ -569,7 +554,6 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN /* this includes dialogs, popups, etc, that need to be full-fledged windows */ appWindow->is_transient = TRUE; window_type = xfc->_NET_WM_WINDOW_TYPE_DIALOG; - xf_SetWindowUnlisted(xfc, appWindow->handle); } else @@ -578,22 +562,21 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN } XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE, - XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1); + XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1); } void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name) { const size_t i = strlen(name); XStoreName(xfc->display, appWindow->handle, name); - Atom wm_Name = xfc->_NET_WM_NAME; Atom utf8Str = xfc->UTF8_STRING; - XChangeProperty(xfc->display, appWindow->handle, wm_Name, utf8Str, 8, - PropModeReplace, (unsigned char *)name, i); + PropModeReplace, (unsigned char*)name, i); } -void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, int* height) +void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, + int* height) { int vscreen_width; int vscreen_height; @@ -604,24 +587,29 @@ void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, int* he { *width = 1; } + if (*height < 1) { *height = 1; } + if (*x < xfc->vscreen.area.left) { *width += *x; *x = xfc->vscreen.area.left; } + if (*y < xfc->vscreen.area.top) { *height += *y; *y = xfc->vscreen.area.top; } + if (*width > vscreen_width) { *width = vscreen_width; } + if (*height > vscreen_height) { *height = vscreen_height; @@ -634,9 +622,8 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow) int input_mask; XWMHints* InputModeHint; XClassHint* class_hints; - - xf_FixWindowCoordinates(xfc, &appWindow->x, &appWindow->y, &appWindow->width, &appWindow->height); - + xf_FixWindowCoordinates(xfc, &appWindow->x, &appWindow->y, &appWindow->width, + &appWindow->height); appWindow->decorations = FALSE; appWindow->fullscreen = FALSE; appWindow->local_move.state = LMS_NOT_ACTIVE; @@ -644,26 +631,25 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow) appWindow->is_transient = FALSE; appWindow->rail_state = 0; appWindow->rail_ignore_configure = FALSE; - appWindow->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen), - appWindow->x, appWindow->y, appWindow->width, appWindow->height, - 0, xfc->depth, InputOutput, xfc->visual, 0, &xfc->attribs); + appWindow->x, appWindow->y, appWindow->width, appWindow->height, + 0, xfc->depth, InputOutput, xfc->visual, 0, &xfc->attribs); if (!appWindow->handle) return -1; ZeroMemory(&gcv, sizeof(gcv)); - appWindow->gc = XCreateGC(xfc->display, appWindow->handle, GCGraphicsExposures, &gcv); - + appWindow->gc = XCreateGC(xfc->display, appWindow->handle, GCGraphicsExposures, + &gcv); class_hints = XAllocClassHint(); if (class_hints) { char* class = NULL; - if (xfc->settings->WmClass) + if (xfc->context.settings->WmClass) { - class_hints->res_class = xfc->settings->WmClass; + class_hints->res_class = xfc->context.settings->WmClass; } else { @@ -675,7 +661,6 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow) class_hints->res_name = "RAIL"; XSetClassHint(xfc->display, appWindow->handle, class_hints); XFree(class_hints); - free(class); } @@ -683,42 +668,34 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow) InputModeHint = XAllocWMHints(); InputModeHint->flags = (1L << 0); InputModeHint->input = True; - XSetWMHints(xfc->display, appWindow->handle, InputModeHint); XFree(InputModeHint); - XSetWMProtocols(xfc->display, appWindow->handle, &(xfc->WM_DELETE_WINDOW), 1); - input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | - ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | - PointerMotionMask | Button1MotionMask | Button2MotionMask | - Button3MotionMask | Button4MotionMask | Button5MotionMask | - ButtonMotionMask | KeymapStateMask | ExposureMask | - VisibilityChangeMask | StructureNotifyMask | SubstructureNotifyMask | - SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask | - ColormapChangeMask | OwnerGrabButtonMask; - + ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | + PointerMotionMask | Button1MotionMask | Button2MotionMask | + Button3MotionMask | Button4MotionMask | Button5MotionMask | + ButtonMotionMask | KeymapStateMask | ExposureMask | + VisibilityChangeMask | StructureNotifyMask | SubstructureNotifyMask | + SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask | + ColormapChangeMask | OwnerGrabButtonMask; XSelectInput(xfc->display, appWindow->handle, input_mask); - xf_SetWindowDecorations(xfc, appWindow->handle, appWindow->decorations); xf_SetWindowStyle(xfc, appWindow, appWindow->dwStyle, appWindow->dwExStyle); xf_SetWindowPID(xfc, appWindow->handle, 0); xf_ShowWindow(xfc, appWindow, WINDOW_SHOW); - XClearWindow(xfc->display, appWindow->handle); XMapWindow(xfc->display, appWindow->handle); - /* Move doesn't seem to work until window is mapped. */ - xf_MoveWindow(xfc, appWindow, appWindow->x, appWindow->y, appWindow->width, appWindow->height); - + xf_MoveWindow(xfc, appWindow, appWindow->x, appWindow->y, appWindow->width, + appWindow->height); xf_SetWindowText(xfc, appWindow, appWindow->title); - return 1; } void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow, - int maxWidth, int maxHeight, int maxPosX, int maxPosY, - int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight) + int maxWidth, int maxHeight, int maxPosX, int maxPosY, + int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight) { XSizeHints* size_hints; size_hints = XAllocSizeHints(); @@ -737,7 +714,8 @@ void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow, } } -void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction, int x, int y) +void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, + int direction, int x, int y) { if (appWindow->local_move.state != LMS_NOT_ACTIVE) return; @@ -750,17 +728,15 @@ void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction appWindow->local_move.root_y = y; appWindow->local_move.state = LMS_STARTING; appWindow->local_move.direction = direction; - XUngrabPointer(xfc->display, CurrentTime); - xf_SendClientEvent(xfc, appWindow->handle, - xfc->_NET_WM_MOVERESIZE, /* request X window manager to initiate a local move */ - 5, /* 5 arguments to follow */ - x, /* x relative to root window */ - y, /* y relative to root window */ - direction, /* extended ICCM direction flag */ - 1, /* simulated mouse button 1 */ - 1); /* 1 == application request per extended ICCM */ + xfc->_NET_WM_MOVERESIZE, /* request X window manager to initiate a local move */ + 5, /* 5 arguments to follow */ + x, /* x relative to root window */ + y, /* y relative to root window */ + direction, /* extended ICCM direction flag */ + 1, /* simulated mouse button 1 */ + 1); /* 1 == application request per extended ICCM */ } void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow) @@ -777,19 +753,20 @@ void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow) * Per ICCM, the X client can ask to cancel an active move. */ xf_SendClientEvent(xfc, appWindow->handle, - xfc->_NET_WM_MOVERESIZE, /* request X window manager to abort a local move */ - 5, /* 5 arguments to follow */ - appWindow->local_move.root_x, /* x relative to root window */ - appWindow->local_move.root_y, /* y relative to root window */ - _NET_WM_MOVERESIZE_CANCEL, /* extended ICCM direction flag */ - 1, /* simulated mouse button 1 */ - 1); /* 1 == application request per extended ICCM */ + xfc->_NET_WM_MOVERESIZE, /* request X window manager to abort a local move */ + 5, /* 5 arguments to follow */ + appWindow->local_move.root_x, /* x relative to root window */ + appWindow->local_move.root_y, /* y relative to root window */ + _NET_WM_MOVERESIZE_CANCEL, /* extended ICCM direction flag */ + 1, /* simulated mouse button 1 */ + 1); /* 1 == application request per extended ICCM */ } appWindow->local_move.state = LMS_NOT_ACTIVE; } -void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height) +void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, + int width, int height) { BOOL resize = FALSE; @@ -800,7 +777,7 @@ void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int wid resize = TRUE; if (appWindow->local_move.state == LMS_STARTING || - appWindow->local_move.state == LMS_ACTIVE) + appWindow->local_move.state == LMS_ACTIVE) return; appWindow->x = x; @@ -831,9 +808,10 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state) case WINDOW_SHOW_MAXIMIZED: /* Set the window as maximized */ xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, - _NET_WM_STATE_ADD, - xfc->_NET_WM_STATE_MAXIMIZED_VERT, - xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0); + _NET_WM_STATE_ADD, + xfc->_NET_WM_STATE_MAXIMIZED_VERT, + xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0); + /* * This is a workaround for the case where the window is maximized locally before the rail server is told to maximize * the window, this appears to be a race condition where the local window with incomplete data and once the window is @@ -842,16 +820,19 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state) */ if (appWindow->rail_state == WINDOW_SHOW_MAXIMIZED) { - xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight); + xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, + appWindow->windowHeight); } + break; case WINDOW_SHOW: /* Ensure the window is not maximized */ xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, - _NET_WM_STATE_REMOVE, - xfc->_NET_WM_STATE_MAXIMIZED_VERT, - xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0); + _NET_WM_STATE_REMOVE, + xfc->_NET_WM_STATE_MAXIMIZED_VERT, + xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0); + /* * Ignore configure requests until both the Maximized properties have been processed * to prevent condition where WM overrides size of request due to one or both of these properties @@ -863,6 +844,7 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state) if (appWindow->is_transient) xf_SetWindowUnlisted(xfc, appWindow->handle); + break; } @@ -877,9 +859,9 @@ void xf_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon) int x, y; int pixels; int propsize; - long *propdata; - long *dstp; - UINT32 *srcp; + long* propdata; + long* dstp; + UINT32* srcp; if (!icon->big) return; @@ -900,16 +882,16 @@ void xf_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon) } } - XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32, - PropModeReplace, (BYTE *) propdata, propsize); - + XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_ICON, XA_CARDINAL, + 32, + PropModeReplace, (BYTE*) propdata, propsize); XFlush(xfc->display); - free(propdata); } #endif -void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects) +void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, + RECTANGLE_16* rects, int nrects) { int i; XRectangle* xrects; @@ -928,13 +910,14 @@ void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rec xrects[i].height = rects[i].bottom - rects[i].top; } - XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); + XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, 0, 0, + xrects, nrects, ShapeSet, 0); free(xrects); #endif - } -void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32 rectsOffsetX, UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects) +void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, + UINT32 rectsOffsetX, UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects) { int i; XRectangle* xrects; @@ -953,37 +936,36 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32 xrects[i].height = rects[i].bottom - rects[i].top; } - XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, rectsOffsetX, rectsOffsetY, xrects, nrects, ShapeSet, 0); + XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, + rectsOffsetX, rectsOffsetY, xrects, nrects, ShapeSet, 0); free(xrects); #endif - } -void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height) +void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, + int width, int height) { int ax, ay; - ax = x + appWindow->windowOffsetX; ay = y + appWindow->windowOffsetY; if (ax + width > appWindow->windowOffsetX + appWindow->width) width = (appWindow->windowOffsetX + appWindow->width - 1) - ax; + if (ay + height > appWindow->windowOffsetY + appWindow->height) height = (appWindow->windowOffsetY + appWindow->height - 1) - ay; xf_lock_x11(xfc, TRUE); - if (xfc->settings->SoftwareGdi) + if (xfc->context.settings->SoftwareGdi) { XPutImage(xfc->display, xfc->primary, appWindow->gc, xfc->image, - ax, ay, ax, ay, width, height); + ax, ay, ax, ay, width, height); } XCopyArea(xfc->display, xfc->primary, appWindow->handle, appWindow->gc, - ax, ay, width, height, x, y); - + ax, ay, width, height, x, y); XFlush(xfc->display); - xf_unlock_x11(xfc, TRUE); } @@ -1008,14 +990,11 @@ void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow) close(appWindow->shmid); shm_unlink(get_shm_id()); - - appWindow->xfwin = (Window*) -1; + appWindow->xfwin = (Window*) - 1; appWindow->shmid = -1; - free(appWindow->title); free(appWindow->windowRects); free(appWindow->visibilityRects); - free(appWindow); } @@ -1025,12 +1004,12 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd) int count; ULONG_PTR* pKeys = NULL; xfAppWindow* appWindow; - count = HashTable_GetKeys(xfc->railWindows, &pKeys); for (index = 0; index < count; index++) { - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]); + appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, + (void*) pKeys[index]); if (appWindow->handle == wnd) { @@ -1040,6 +1019,5 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd) } free(pKeys); - return NULL; } diff --git a/client/X11/xfreerdp-envvar.1.xml b/client/X11/xfreerdp-envvar.1.xml new file mode 100644 index 0000000..b51653a --- /dev/null +++ b/client/X11/xfreerdp-envvar.1.xml @@ -0,0 +1,15 @@ + + Environment variables + + + + wlog environment variable + + xfreerdp uses wLog as its log facility, you can refer to the + corresponding man page (wlog(1)) for more informations. Arguments passed + via the /log-level or /log-filters + have precedence over the environment variables. + + + + \ No newline at end of file diff --git a/client/X11/xfreerdp.1.xml.in b/client/X11/xfreerdp.1.xml.in index 4dbb420..119f7f3 100644 --- a/client/X11/xfreerdp.1.xml.in +++ b/client/X11/xfreerdp.1.xml.in @@ -4,6 +4,7 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ + ] > @@ -49,6 +50,8 @@ PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" &channels; + &envvar; + &examples; diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index b90ac09..ecad9d7 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -3,6 +3,8 @@ * X11 Client * * Copyright 2011 Marc-Andre Moreau + * Copyright 2016 Thincast Technologies GmbH + * Copyright 2016 Armin Novak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,20 +94,12 @@ struct xf_context rdpContext context; DEFINE_RDP_CLIENT_COMMON(); - freerdp* instance; - rdpSettings* settings; - rdpCodecs* codecs; - GC gc; - int bpp; int xfds; int depth; - int sessionWidth; - int sessionHeight; - int srcBpp; + GC gc_mono; BOOL invert; - UINT32 format; Screen* screen; XImage* image; Pixmap primary; @@ -131,19 +125,13 @@ struct xf_context xfFullscreenMonitors fullscreenMonitors; int current_desktop; BOOL remote_app; - BOOL disconnect; HANDLE mutex; BOOL UseXThreads; BOOL cursorHidden; - BYTE* palette; - BYTE palette_hwgdi[256 * 4]; HGDI_DC hdc; UINT32 bitmap_size; BYTE* bitmap_buffer; - BYTE* primary_buffer; - BOOL inGfxFrame; - BOOL graphicsReset; BOOL frame_begin; UINT16 frame_x1; @@ -244,7 +232,6 @@ struct xf_context BOOL xf_create_window(xfContext* xfc); void xf_toggle_fullscreen(xfContext* xfc); void xf_toggle_control(xfContext* xfc); -BOOL xf_post_connect(freerdp* instance); void xf_encomsp_init(xfContext* xfc, EncomspClientContext* encomsp); void xf_encomsp_uninit(xfContext* xfc, EncomspClientContext* encomsp); diff --git a/client/common/CMakeLists.txt b/client/common/CMakeLists.txt index c9dacbc..bf44809 100644 --- a/client/common/CMakeLists.txt +++ b/client/common/CMakeLists.txt @@ -38,9 +38,6 @@ foreach(FREERDP_CHANNELS_CLIENT_SRC ${FREERDP_CHANNELS_CLIENT_SRCS}) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} "${FREERDP_CHANNELS_CLIENT_SRC}") endforeach() -if(MSVC) - set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS}) -endif() # On windows create dll version information. # Vendor, product and year are already set in top level CMakeLists.txt diff --git a/client/common/client.c b/client/common/client.c index 7d4cea6..0783aa5 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -55,8 +55,10 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) freerdp* instance; rdpContext* context; - pEntryPoints->GlobalInit(); + if (!pEntryPoints) + return NULL; + IFCALL(pEntryPoints->GlobalInit); instance = freerdp_new(); if (!instance) @@ -66,7 +68,8 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) instance->ContextSize = pEntryPoints->ContextSize; instance->ContextNew = freerdp_client_common_new; instance->ContextFree = freerdp_client_common_free; - instance->pClientEntryPoints = (RDP_CLIENT_ENTRY_POINTS*) malloc(pEntryPoints->Size); + instance->pClientEntryPoints = (RDP_CLIENT_ENTRY_POINTS*) malloc( + pEntryPoints->Size); if (!instance->pClientEntryPoints) goto out_fail; @@ -80,10 +83,11 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) context->instance = instance; context->settings = instance->settings; - freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); + if (freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, + 0) != CHANNEL_RC_OK) + goto out_fail2; return context; - out_fail2: free(instance->pClientEntryPoints); out_fail: @@ -93,11 +97,21 @@ out_fail: void freerdp_client_context_free(rdpContext* context) { - freerdp* instance = context->instance; + freerdp* instance; + + if (!context) + return; + + instance = context->instance; if (instance) { + RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints; freerdp_context_free(instance); + + if (pEntryPoints) + IFCALL(pEntryPoints->GlobalUninit); + free(instance->pClientEntryPoints); freerdp_free(instance); } @@ -105,23 +119,39 @@ void freerdp_client_context_free(rdpContext* context) int freerdp_client_start(rdpContext* context) { - RDP_CLIENT_ENTRY_POINTS* pEntryPoints = context->instance->pClientEntryPoints; - return pEntryPoints->ClientStart(context); + RDP_CLIENT_ENTRY_POINTS* pEntryPoints; + + if (!context || !context->instance || !context->instance->pClientEntryPoints) + return ERROR_BAD_ARGUMENTS; + + pEntryPoints = context->instance->pClientEntryPoints; + return IFCALLRESULT(CHANNEL_RC_OK, pEntryPoints->ClientStart, context); } int freerdp_client_stop(rdpContext* context) { - RDP_CLIENT_ENTRY_POINTS* pEntryPoints = context->instance->pClientEntryPoints; - return pEntryPoints->ClientStop(context); + RDP_CLIENT_ENTRY_POINTS* pEntryPoints; + + if (!context || !context->instance || !context->instance->pClientEntryPoints) + return ERROR_BAD_ARGUMENTS; + + pEntryPoints = context->instance->pClientEntryPoints; + return IFCALLRESULT(CHANNEL_RC_OK, pEntryPoints->ClientStop, context); } freerdp* freerdp_client_get_instance(rdpContext* context) { + if (!context || !context->instance) + return NULL; + return context->instance; } HANDLE freerdp_client_get_thread(rdpContext* context) { + if (!context) + return NULL; + return ((rdpClientContext*) context)->thread; } @@ -141,6 +171,7 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings) if (!settings->GatewayUsername) goto out_error; } + if (settings->Domain) { free(settings->GatewayDomain); @@ -149,6 +180,7 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings) if (!settings->GatewayDomain) goto out_error; } + if (settings->Password) { free(settings->GatewayPassword); @@ -173,7 +205,6 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings) } return TRUE; - out_error: free(settings->GatewayUsername); free(settings->GatewayDomain); @@ -183,7 +214,7 @@ out_error: int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, - char** argv, BOOL allowUnknown) + char** argv, BOOL allowUnknown) { int status; @@ -193,7 +224,8 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, if (!argv) return -1; - status = freerdp_client_settings_parse_command_line_arguments(settings, argc, argv, allowUnknown); + status = freerdp_client_settings_parse_command_line_arguments(settings, argc, + argv, allowUnknown); if (status < 0) return status; @@ -206,16 +238,19 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, return status; } -int freerdp_client_settings_parse_connection_file(rdpSettings* settings, const char* filename) +int freerdp_client_settings_parse_connection_file(rdpSettings* settings, + const char* filename) { rdpFile* file; int ret = -1; - file = freerdp_client_rdp_file_new(); + if (!file) return -1; + if (!freerdp_client_parse_rdp_file(file, filename)) goto out; + if (!freerdp_client_populate_settings_from_rdp_file(file, settings)) goto out; @@ -225,32 +260,33 @@ out: return ret; } -int freerdp_client_settings_parse_connection_file_buffer(rdpSettings* settings, const BYTE* buffer, size_t size) +int freerdp_client_settings_parse_connection_file_buffer(rdpSettings* settings, + const BYTE* buffer, size_t size) { rdpFile* file; int status = -1; - file = freerdp_client_rdp_file_new(); + if (!file) return -1; if (freerdp_client_parse_rdp_file_buffer(file, buffer, size) - && freerdp_client_populate_settings_from_rdp_file(file, settings)) + && freerdp_client_populate_settings_from_rdp_file(file, settings)) { status = 0; } freerdp_client_rdp_file_free(file); - return status; } -int freerdp_client_settings_write_connection_file(const rdpSettings* settings, const char* filename, BOOL unicode) +int freerdp_client_settings_write_connection_file(const rdpSettings* settings, + const char* filename, BOOL unicode) { rdpFile* file; int ret = -1; - file = freerdp_client_rdp_file_new(); + if (!file) return -1; @@ -263,15 +299,14 @@ int freerdp_client_settings_write_connection_file(const rdpSettings* settings, c ret = 0; out: freerdp_client_rdp_file_free(file); - return ret; } -int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const char* filename) +int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, + const char* filename) { int status; rdpAssistanceFile* file; - file = freerdp_assistance_file_new(); if (!file) @@ -288,7 +323,6 @@ int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const c return -1; freerdp_assistance_file_free(file); - return 0; } @@ -304,8 +338,9 @@ int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const c * @param domain - unused * @return TRUE if a password was successfully entered. See freerdp_passphrase_read() for more details. */ -static BOOL client_cli_authenticate_raw(freerdp* instance, BOOL gateway, char** username, - char** password, char** domain) +static BOOL client_cli_authenticate_raw(freerdp* instance, BOOL gateway, + char** username, + char** password, char** domain) { static const size_t password_size = 512; const char* auth[] = @@ -329,6 +364,7 @@ static BOOL client_cli_authenticate_raw(freerdp* instance, BOOL gateway, char** { size_t username_size = 0; printf("%s", prompt[0]); + if (GetLine(username, &username_size, stdin) < 0) { WLog_ERR(TAG, "GetLine returned %s [%d]", strerror(errno), errno); @@ -346,6 +382,7 @@ static BOOL client_cli_authenticate_raw(freerdp* instance, BOOL gateway, char** { size_t domain_size = 0; printf("%s", prompt[1]); + if (GetLine(domain, &domain_size, stdin) < 0) { WLog_ERR(TAG, "GetLine returned %s [%d]", strerror(errno), errno); @@ -362,34 +399,34 @@ static BOOL client_cli_authenticate_raw(freerdp* instance, BOOL gateway, char** if (!*password) { *password = calloc(password_size, sizeof(char)); + if (!*password) goto fail; if (freerdp_passphrase_read(prompt[2], *password, password_size, - instance->settings->CredentialsFromStdin) == NULL) + instance->settings->CredentialsFromStdin) == NULL) goto fail; } return TRUE; - fail: free(*username); free(*domain); free(*password); - *username = NULL; *domain = NULL; *password = NULL; - return FALSE; } -BOOL client_cli_authenticate(freerdp* instance, char** username, char** password, char** domain) +BOOL client_cli_authenticate(freerdp* instance, char** username, + char** password, char** domain) { return client_cli_authenticate_raw(instance, FALSE, username, password, domain); } -BOOL client_cli_gw_authenticate(freerdp* instance, char** username, char** password, char** domain) +BOOL client_cli_gw_authenticate(freerdp* instance, char** username, + char** password, char** domain) { return client_cli_authenticate_raw(instance, TRUE, username, password, domain); } @@ -409,26 +446,32 @@ static DWORD client_cli_accept_certificate(rdpSettings* settings) if (feof(stdin)) { printf("\nError: Could not read answer from stdin."); + if (settings->CredentialsFromStdin) printf(" - Run without parameter \"--from-stdin\" to set trust."); + printf("\n"); return 0; } - switch(answer) + switch (answer) { case 'y': case 'Y': return 1; + case 't': case 'T': return 2; + case 'n': case 'N': return 0; + default: break; } + printf("\n"); } @@ -448,17 +491,16 @@ static DWORD client_cli_accept_certificate(rdpSettings* settings) * @return 1 if the certificate is trusted, 2 if temporary trusted, 0 otherwise. */ DWORD client_cli_verify_certificate(freerdp* instance, const char* common_name, - const char* subject, const char* issuer, - const char* fingerprint, BOOL host_mismatch) + const char* subject, const char* issuer, + const char* fingerprint, BOOL host_mismatch) { printf("Certificate details:\n"); printf("\tSubject: %s\n", subject); printf("\tIssuer: %s\n", issuer); printf("\tThumbprint: %s\n", fingerprint); printf("The above X.509 certificate could not be verified, possibly because you do not have\n" - "the CA certificate in your certificate store, or the certificate has expired.\n" - "Please look at the documentation on how to create local certificate store for a private CA.\n"); - + "the CA certificate in your certificate store, or the certificate has expired.\n" + "Please look at the documentation on how to create local certificate store for a private CA.\n"); return client_cli_accept_certificate(instance->settings); } @@ -476,11 +518,12 @@ DWORD client_cli_verify_certificate(freerdp* instance, const char* common_name, * @param old_fingerprint * @return 1 if the certificate is trusted, 2 if temporary trusted, 0 otherwise. */ -DWORD client_cli_verify_changed_certificate(freerdp* instance, const char* common_name, - const char* subject, const char* issuer, - const char* fingerprint, - const char* old_subject, const char* old_issuer, - const char* old_fingerprint) +DWORD client_cli_verify_changed_certificate(freerdp* instance, + const char* common_name, + const char* subject, const char* issuer, + const char* fingerprint, + const char* old_subject, const char* old_issuer, + const char* old_fingerprint) { printf("!!! Certificate has changed !!!\n"); printf("\n"); @@ -495,9 +538,8 @@ DWORD client_cli_verify_changed_certificate(freerdp* instance, const char* commo printf("\tThumbprint: %s\n", old_fingerprint); printf("\n"); printf("The above X.509 certificate does not match the certificate used for previous connections.\n" - "This may indicate that the certificate has been tampered with.\n" - "Please contact the administrator of the RDP server and clarify.\n"); - + "This may indicate that the certificate has been tampered with.\n" + "Please contact the administrator of the RDP server and clarify.\n"); return client_cli_accept_certificate(instance->settings); } diff --git a/client/common/cmdline.c b/client/common/cmdline.c index bf6639d..59359c8 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -76,7 +76,7 @@ static COMMAND_LINE_ARGUMENT_A args[] = { "u", COMMAND_LINE_VALUE_REQUIRED, "[\\] or [@]", NULL, NULL, -1, NULL, "Username" }, { "p", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Password" }, { "d", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Domain" }, - { "g", COMMAND_LINE_VALUE_OPTIONAL, "[:port]", NULL, NULL, -1, NULL, "Gateway Hostname" }, + { "g", COMMAND_LINE_VALUE_REQUIRED, "[:port]", NULL, NULL, -1, NULL, "Gateway Hostname" }, { "gu", COMMAND_LINE_VALUE_REQUIRED, "[\\] or [@]", NULL, NULL, -1, NULL, "Gateway username" }, { "gp", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Gateway password" }, { "gd", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Gateway domain" }, @@ -89,7 +89,7 @@ static COMMAND_LINE_ARGUMENT_A args[] = { "app-cmd", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Remote application command-line parameters" }, { "app-file", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "File to open with remote application" }, { "app-guid", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Remote application GUID" }, - { "compression", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, "z", "Compression" }, + { "compression", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, "z", "Enable compression" }, { "compression-level", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Compression level (0,1,2)" }, { "shell", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Alternate shell" }, { "shell-dir", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Shell working directory" }, @@ -112,25 +112,25 @@ static COMMAND_LINE_ARGUMENT_A args[] = { "unmap-buttons", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Let server see real physical pointer button"}, { "echo", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "echo", "Echo channel" }, { "disp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Display control" }, - { "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Smooth fonts (ClearType)" }, - { "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL, "Desktop composition" }, - { "window-drag", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Full window drag" }, - { "menu-anims", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Menu animations" }, - { "themes", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Themes" }, - { "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Wallpaper" }, + { "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Enable smooth fonts (ClearType)" }, + { "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL, "Enable desktop composition" }, + { "window-drag", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Enable full window drag" }, + { "menu-anims", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Enable menu animations" }, + { "themes", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Enable themes" }, + { "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Enable wallpaper" }, { "gdi", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "GDI rendering" }, { "gfx", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, NULL, -1, NULL, "RDP8 graphics pipeline (experimental)" }, - { "gfx-thin-client", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "RDP8 graphics pipeline thin client mode" }, - { "gfx-small-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "RDP8 graphics pipeline small cache mode" }, - { "gfx-progressive", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "RDP8 graphics pipeline progressive codec" }, - { "gfx-h264", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, NULL, -1, NULL, "RDP8.1 graphics pipeline H264 codec" }, + { "gfx-thin-client", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "RDP8 graphics pipeline using thin client mode" }, + { "gfx-small-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "RDP8 graphics pipeline using small cache mode" }, + { "gfx-progressive", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "RDP8 graphics pipeline using progressive codec" }, + { "gfx-h264", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, NULL, -1, NULL, "RDP8.1 graphics pipeline using H264 codec" }, { "rfx", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "RemoteFX" }, { "rfx-mode", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "RemoteFX mode" }, - { "frame-ack", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Frame acknowledgement" }, - { "nsc", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "nscodec", "NSCodec" }, - { "jpeg", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "JPEG codec" }, + { "frame-ack", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Number of frame acknowledgement" }, + { "nsc", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "nscodec", "Enable NSCodec" }, + { "jpeg", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Enable JPEG codec" }, { "jpeg-quality", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "JPEG quality" }, - { "nego", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "protocol security negotiation" }, + { "nego", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Enable protocol security negotiation" }, { "sec", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "force specific protocol security" }, { "sec-rdp", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "rdp protocol security" }, { "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "tls protocol security" }, @@ -151,12 +151,13 @@ static COMMAND_LINE_ARGUMENT_A args[] = { "toggle-fullscreen", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Alt+Ctrl+Enter toggles fullscreen" }, { "mouse-motion", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "mouse-motion" }, { "parent-window", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Parent window id" }, - { "bitmap-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "bitmap cache" }, - { "offscreen-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "offscreen bitmap cache" }, - { "glyph-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "glyph cache" }, + { "bitmap-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Enable bitmap cache" }, + { "offscreen-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Enable offscreen bitmap cache" }, + { "glyph-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Glyph cache (EXPERIMENTAL)" }, { "codec-cache", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "bitmap codec cache" }, - { "fast-path", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "fast-path input/output" }, - { "max-fast-path-size", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, NULL, -1, NULL, "maximum fast-path update size" }, + { "fast-path", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Enable fast-path input/output" }, + { "max-fast-path-size", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, NULL, -1, NULL, "specify maximum fast-path update size" }, + { "max-loop-time", COMMAND_LINE_VALUE_REQUIRED, "