diff -Nru freerdp-2.0.0~dev201701161718+dfsg/ChangeLog freerdp-2.0.0~dev201703030839+dfsg/ChangeLog --- freerdp-2.0.0~dev201701161718+dfsg/ChangeLog 2017-01-22 09:25:07.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/ChangeLog 2017-03-05 07:11:50.000000000 +0000 @@ -1,11 +1,1191 @@ +2017-03-03 09:39:24 +0100 Martin Fleisz (14c236d) + + * Merge pull request #3829 from akallabeth/logon_error_info_string + (HEAD, origin/master, master) + +2017-03-02 18:19:05 +0100 Martin Fleisz (00701b1) + + * Merge pull request #3836 from akallabeth/avc_444_neon_fix + +2017-03-01 11:38:37 +0100 Armin Novak (d119745) + + * String representation of logon_error_info + +2017-03-02 17:56:23 +0100 Armin Novak (f0b61eb) + + * Fixed index for YUV filter in NEON path. + +2017-03-02 17:20:53 +0100 Martin Fleisz (210de68) + + * Merge pull request #3831 from hardening/logon_notify + +2017-03-02 13:37:25 +0100 Martin Fleisz (fcbd87e) + + * Merge pull request #3834 from akallabeth/afreerdp_hide_menu + +2017-03-02 13:06:10 +0100 Armin Novak (e1cfec1) + + * Added missing translations for color enumeration. + +2017-03-02 12:29:37 +0100 Armin Novak (93cd763) + + * Removed https links in MPL and apache license. + +2017-03-02 12:26:00 +0100 Martin Fleisz (1207fdb) + + * Merge pull request #3807 from akallabeth/afreerdp_update + +2017-03-02 10:27:13 +0100 Armin Novak (c204fbe) + + * Added client name reset if empty. + +2017-03-02 08:49:50 +0100 Armin Novak (345cbdd) + + * Updated intent filter to open RDP files. + +2017-03-02 00:39:08 +0100 David Fort (815c97e) + + * The LongCredentials capability were not parsed or used + +2017-03-02 00:29:48 +0100 David Fort (67607ce) + + * Take in account and set the LogonNotify flag + +2017-03-01 11:21:41 +0100 David Fort (5bb7a05) + + * Merge pull request #3823 from akallabeth/ssl_error_check_fix + +2017-02-27 15:41:27 +0100 Armin Novak (e455cc1) + + * Fixed SSL error checks in transport_ssl_cb + +2017-02-28 11:19:29 +0100 Norbert Federa (22ab66a) + + * Merge pull request #3825 from nfedera/getcomputername_test + +2017-02-27 17:14:04 +0100 Norbert Federa (97ab14a) + + * Added test for GetComputerName/GetComputerNameEx + +2017-02-28 10:29:22 +0100 Norbert Federa (3959ee2) + + * Merge pull request #3816 from akallabeth/get_name_fix + +2017-02-28 09:39:04 +0100 Armin Novak (270d68f) + + * Fixed setting of lpnSize according to spec. + +2017-02-27 10:56:19 +0100 Armin Novak (b11de26) + + * Fixed GetComputerNameExA return checks. + +2017-02-27 10:52:59 +0100 Armin Novak (71d9a83) + + * Fixed GetComputerNameEx last error. + +2017-02-25 08:35:37 +0100 akallabeth (8a22052) + + * Fixed memory leaks. + +2017-02-24 21:58:08 +0100 akallabeth (705c0c1) + + * Fixed GetComputerNameExA calls. #3815 + +2017-02-24 13:25:52 +0100 Norbert Federa (689d269) + + * Merge pull request #3800 from mfleisz/channel_fixes + +2017-02-22 13:46:47 +0100 Martin Fleisz (a391a3d) + + * client: Check if channel has already been added + +2017-02-24 12:26:30 +0100 akallabeth (b7dfaa6) + + * Merge pull request #3801 from chipitsine/master + +2017-02-24 11:30:04 +0100 Armin Novak (05f6dac) + + * Moved construction to onCreate. + +2017-02-24 09:48:40 +0100 Armin Novak (eeee92a) + + * All EditTextPreferences are now single lined. + +2017-02-24 09:29:26 +0100 Armin Novak (37e9db4) + + * Added signing configuration. + +2017-02-23 15:20:19 +0100 Armin Novak (65f761a) + + * Use HTTPS links in about. + +2017-02-23 15:00:30 +0100 Armin Novak (b938bb4) + + * Updated gradle build, allow to configure from file. + +2017-02-23 13:46:34 +0100 akallabeth (7ce1dd0) + + * Merge pull request #3791 from akallabeth/kerberos + +2017-02-23 12:37:55 +0100 Armin Novak (ae09ab7) + + * Updated about pages. + +2017-02-23 12:31:08 +0100 Armin Novak (f47bde3) + + * Added a H264 availability check. + +2017-02-23 11:06:47 +0100 Armin Novak (b905e0c) + + * Fixed initialisation of kerberos context. + +2017-02-23 10:51:21 +0100 Armin Novak (5d8a9f2) + + * Fixed asset loading. + +2017-02-22 19:09:01 +0100 Armin Novak (7129455) + + * Updated licensing information and data protection clause. + +2017-02-22 17:55:22 +0100 Armin Novak (70e43e6) + + * Refactored application settings, added client hostname (#1343) + +2017-02-22 20:39:32 +0500 Ilya Shipitsin (4af2f71) + + * resolve compiler warning + +2017-02-22 15:32:53 +0100 Armin Novak (91c6d0d) + + * Refactored db upgrade code. + +2017-02-22 15:25:34 +0100 Armin Novak (a8bf7af) + + * Using AppCompatActivity. + +2017-02-22 15:24:38 +0100 Armin Novak (57eea83) + + * Deactivated async_transport #3134 + +2017-02-22 14:33:40 +0100 Armin Novak (2a934b7) + + * Reformatted using AndroidStudio coding style. + +2017-02-22 14:29:42 +0100 Armin Novak (553d782) + + * Updated gradle. + +2017-02-22 13:15:49 +0100 Armin Novak (a8447d0) + + * Updated OpenSSL version in android script. + +2017-02-22 13:45:25 +0100 Martin Fleisz (eeae688) + + * core: Cleanup channel structs in close to allow instance reuse + +2017-02-22 13:28:29 +0100 Martin Fleisz (a443694) + + * Merge pull request #3785 from uplusplus/patch-4 + +2017-02-22 12:53:51 +0100 Martin Fleisz (f4efbd9) + + * Merge pull request #3797 from hardening/clientCapabilities + +2017-02-22 12:47:52 +0100 akallabeth (65b51a6) + + * Merge pull request #3798 from mfleisz/vc10_comp_fix + +2017-02-22 11:47:34 +0100 Martin Fleisz (52d16ca) + + * Merge pull request #3799 from akallabeth/yuv_fix + +2017-02-22 10:59:18 +0100 Armin Novak (6366868) + + * Fixed argument check of sse2_RGBToRGB_16s8u_P3AC4R + +2017-02-22 10:21:01 +0100 Martin Fleisz (966dbdf) + + * primitives: Fix compilation with VS 2010 + +2017-02-22 09:50:59 +0100 Armin Novak (70baa6f) + + * Added additional connect errors. + +2017-02-22 09:42:56 +0100 Armin Novak (363109c) + + * Using preloaded logger. + +2017-02-22 09:29:52 +0100 Armin Novak (1497b56) + + * Using SSL defines instead of magic numbers. + +2017-02-21 23:44:47 +0100 David Fort (7b43717) + + * Add a ClientCapabilities callback + +2017-02-21 23:00:41 +0100 David Fort (6894ed3) + + * Dropped some warnings and fix code style + +2017-02-21 17:35:57 +0100 Norbert Federa (43a4903) + + * Merge pull request #3795 from hardening/monitor_limit + +2017-02-21 15:03:00 +0100 David Fort (59dafc2) + + * Added the spec reference for the 16 monitors limit + +2017-02-21 12:44:33 +0100 akallabeth (9fc9188) + + * Merge pull request #3794 from Abhineet-Ayan-Verma/patch-3 + +2017-02-21 11:07:57 +0100 Martin Fleisz (0ed0ecb) + + * Merge pull request #3789 from akallabeth/scan_warning_fixes + +2017-02-21 11:02:12 +0100 David Fort (837491b) + + * Limit the number of client announced monitors + +2017-02-21 10:59:15 +0100 Armin Novak (a1542e9) + + * Enabled kerberos support on CI + +2017-02-21 10:52:13 +0100 Armin Novak (50cd702) + + * Updated KRB5 detection, added error case handler + +2017-02-21 10:08:55 +0100 akallabeth (09e3d29) + + * Merge pull request #3792 from Abhineet-Ayan-Verma/patch-1 + +2017-02-21 10:07:57 +0100 akallabeth (f3aad6e) + + * Merge pull request #3793 from Abhineet-Ayan-Verma/patch-2 + +2017-02-21 10:16:17 +0530 Abhineet-Ayan-Verma (be1f22f) + + * Added TAG macro definition + +2017-02-21 10:13:53 +0530 Abhineet-Ayan-Verma (f11ddb6) + + * Added TAG macro definition + +2017-02-21 10:12:10 +0530 Abhineet-Ayan-Verma (69fb77d) + + * Added TAG macro definition + +2016-06-20 11:49:54 +0200 HenryJacques (56c0219) + + * Update transport.c + +2016-06-20 11:38:13 +0200 HenryJacques (56d6c23) + + * Update errconnect.c + +2016-06-20 11:35:55 +0200 HenryJacques (3f9cbfe) + + * Update error.h + +2016-06-20 11:31:38 +0200 HenryJacques (642ce36) + + * Update config.h.in + +2017-02-20 15:58:29 +0100 akallabeth (b35224b) + + * Merge pull request #3788 from Abhineet-Ayan-Verma/patch-5 + +2017-02-20 15:20:17 +0100 akallabeth (9444de2) + + * Merge pull request #3786 from Abhineet-Ayan-Verma/patch-3 + +2017-02-20 14:33:10 +0100 Martin Fleisz (c806d0e) + + * Merge pull request #3774 from akallabeth/smartcard_reader_groups + +2017-02-20 14:32:54 +0100 Armin Novak (6900b5e) + + * Fixed scanbuild warnings. + +2017-02-20 14:28:33 +0100 Armin Novak (e9b5d78) + + * Fixed scanbuild warnings. + +2017-02-20 14:18:18 +0100 Armin Novak (c0671b4) + + * Fixed scanbuild warnings. + +2017-02-20 14:15:25 +0100 Armin Novak (844919d) + + * Fixed scanbuild issues. + +2017-02-20 14:12:39 +0100 Armin Novak (a1003ab) + + * Fixed scanbuild warnings. + +2017-02-20 14:08:14 +0100 Bernhard Miklautz (23cfd34) + + * Merge pull request #3746 from + volth/command-line-action-script-rebased + +2017-02-20 18:33:52 +0530 Abhineet-Ayan-Verma (8c1c4d2) + + * Added TAG definition + +2017-02-20 18:20:23 +0530 Abhineet-Ayan-Verma (a66b0b3) + + * Update wf_update.c + +2017-02-20 13:38:20 +0100 Armin Novak (c249705) + + * Fixed scanbuild warnings. + +2017-02-20 13:30:16 +0100 Armin Novak (4c7d013) + + * Fixed warings #3784 + +2017-02-20 13:07:12 +0100 akallabeth (3115c1e) + + * Merge pull request #3783 from chipitsine/master + +2017-02-20 16:54:51 +0800 joy.you (073e856) + + * dead lock fixed + +2017-02-17 18:36:03 +0500 Ilya Shipitsin (33f38da) + + * resolve trivial issues found by cppcheck + +2017-02-17 14:25:59 +0100 Armin Novak (ff56f75) + + * Fixed format specifier and unused variables. + +2017-02-17 13:09:32 +0000 Volth (c333aa3) + + * Add command line option to override action script path + +2017-02-17 13:22:51 +0100 Martin Fleisz (c325ec5) + + * Merge pull request #3780 from akallabeth/win_compile_fix + +2017-02-17 17:21:18 +0500 Ilya Shipitsin (0673bdd) + + * resolve trivial issues found by cppcheck + +2017-02-17 16:52:21 +0500 Ilya Shipitsin (44cfb01) + + * revolve possible null pointer dereference found by cppcheck + +2017-02-17 12:09:17 +0100 akallabeth (3c7cc55) + + * Merge pull request #3779 from chipitsine/master + +2017-02-17 11:53:57 +0100 Armin Novak (4f3633b) + + * Fix for #3627 + +2017-02-17 11:40:52 +0100 Armin Novak (1ef55e7) + + * Fixed #3778: Printer driver name conversion. + +2017-02-17 11:40:27 +0100 Armin Novak (5755cb7) + + * Fixed crash on h264 context cleanup (windows). + +2017-02-17 11:17:45 +0100 Armin Novak (f8d22c0) + + * Fixed compiler warnings and uninitialized data. + +2017-02-17 10:59:22 +0100 Armin Novak (bee73ad) + + * Replaced random() with winpr_RAND + +2017-02-17 10:56:16 +0100 Armin Novak (8bffcad) + + * Replaced snprintf with _snprintf. + +2017-02-17 14:54:31 +0500 Ilya Shipitsin (2517275) + + * resolve a typo found by cppcheck + +2017-02-17 10:46:35 +0100 akallabeth (ba99e35) + + * Merge pull request #3733 from chipitsine/master + +2017-02-17 10:06:38 +0100 akallabeth (2e64cca) + + * Merge pull request #3775 from nfedera/rgb_to_avc444yuv + +2017-02-17 09:52:22 +0100 akallabeth (4065581) + + * Merge pull request #3756 from bigpjo/master + +2017-02-17 13:38:05 +0500 Ilya Shipitsin (9b12feb) + + * an argument check in xf_UpdateWindowArea + +2017-02-16 19:16:56 +0000 bigpjo (51b4789) + + * Change request from akallabeth + +2017-02-15 17:40:12 +0100 Norbert Federa (a50242c) + + * primitives: SSSE3 RGB to AVC444YUV converter + +2017-02-15 17:20:30 +0100 Norbert Federa (13a60ae) + + * primitives: added RGB to AVC444YUV converter + +2015-06-30 17:42:01 +0200 Andreas Schultz (d2f9826) + + * smartcard: implement ListReaderGroups + +2017-02-16 16:37:27 +0100 David Fort (c0f4b6b) + + * Merge pull request #3772 from akallabeth/sse_test_fixes + +2017-02-16 15:43:02 +0100 Martin Fleisz (af4034b) + + * Merge pull request #3773 from hardening/gfx_and_sample_fixes + +2017-02-16 14:57:36 +0100 David Fort (2604b15) + + * Fix plugin loading for the sample client + +2017-02-16 14:46:20 +0100 David Fort (be41769) + + * Add some useful debug info for the egfx channel + +2017-02-16 14:34:43 +0100 Armin Novak (c50e5ba) + + * Fixed warnings. + +2017-02-16 14:00:25 +0100 Armin Novak (c04918d) + + * Added value comparison for all YCbCr functions. + +2017-02-16 13:51:50 +0100 Armin Novak (4891ae6) + + * Reduced test runtime. + +2017-02-16 13:17:49 +0100 Armin Novak (198bc6d) + + * Fixed compiler warnings. + +2017-02-16 12:14:36 +0100 Armin Novak (4d03a9a) + + * Improved YCoCgToRGB tests. + +2017-02-16 11:40:28 +0100 Armin Novak (799afe0) + + * Fixed YUV test result print. + +2017-02-16 11:32:10 +0100 Armin Novak (dda6b14) + + * Fixed SSE yCbCrToRGB_16s8u_P3AC4R, improved tests. + +2017-02-16 09:35:42 +0100 Armin Novak (ee3a3a7) + + * Fixed SSE checks and RGBToRGB_16s8u_P3AC4R + +2017-02-16 09:51:28 +0100 Martin Fleisz (0d43201) + + * Merge pull request #3767 from akallabeth/ssse3_optimize + +2017-02-16 09:51:10 +0100 Martin Fleisz (ae551e4) + + * Merge pull request #3762 from akallabeth/sspi_init + +2017-02-15 16:43:43 +0100 akallabeth (eeb060e) + + * Merge pull request #3770 from Abhineet-Ayan-Verma/patch-1 + +2017-02-15 15:55:30 +0100 akallabeth (5707319) + + * Merge pull request #3771 from mfleisz/code_cleanup + +2017-02-15 15:50:49 +0100 Bernhard Miklautz (a1d87fe) + + * Merge pull request #3769 from akallabeth/queue_fix + +2017-02-15 15:34:50 +0100 Armin Novak (6960ca2) + + * Added GFX surface command profiler. + +2017-02-15 15:34:12 +0100 Armin Novak (359077e) + + * Closing dynamic channels on shutdown. + +2017-02-15 14:22:15 +0100 Armin Novak (291362e) + + * Fixed possible memory leak. + +2017-02-15 14:59:24 +0100 Martin Fleisz (68a9408) + + * core: Get rid of useless settings copy + +2017-02-15 13:51:11 +0100 Martin Fleisz (4b6be87) + + * Merge pull request #3472 from ilammy/x11-cliprdr/raw-data-cache + +2017-02-15 12:38:26 +0100 Armin Novak (1b78c45) + + * Fixed alignment checks for SSE yCbCrToRGB + +2017-02-15 12:37:37 +0100 Armin Novak (01d2426) + + * Using aligned RFX buffers. + +2017-02-15 12:04:11 +0100 Armin Novak (dce3604) + + * Refined alignment checks for SSSE3 YUV444ToRGB + +2017-02-15 11:56:50 +0100 Armin Novak (03abaf1) + + * Align scanline to multiple of 16, required for ASM + +2017-02-15 15:56:44 +0530 Abhineet-Ayan-Verma (999cc22) + + * Fixed undefined behavior in wf_peer_main_loop function + +2017-02-15 11:44:19 +0800 pony (a57adc3) + + * libwinpr-utils: fix 3 logic errors + +2017-02-15 09:28:10 +0100 Armin Novak (f24b112) + + * Refactored AVC444 decoding to single YUV420 buffer + +2017-02-14 16:34:02 +0100 Armin Novak (2c99c17) + + * Fixed libavcodec issues. + +2017-02-14 14:42:33 +0100 Armin Novak (e44158e) + + * Reordered SSSE3 YUV444ToRGB + +2017-02-14 13:39:25 +0100 Armin Novak (d41d655) + + * Use bitmap color format in gdi_BitBlt + +2017-02-14 12:53:14 +0100 Armin Novak (2f8e206) + + * Fixed freerdp_client_parse_rdp_file_buffer + +2017-02-14 12:29:07 +0100 Armin Novak (2463575) + + * Print profiler header and footer. + +2017-02-14 12:28:58 +0100 Armin Novak (ef4515a) + + * Added FPS in profiler print. + +2017-02-14 12:12:24 +0100 Armin Novak (f324b0e) + + * Use aligned malloc/free for GFX surfaces/buffers + +2017-02-14 12:11:55 +0100 Armin Novak (9dba985) + + * SSSE3 YUV444ToRGB process 16 pixel per loop. + +2017-02-14 15:05:36 +0100 akallabeth (0540e18) + + * Merge pull request #3765 from mfleisz/gdi_resize + +2017-02-14 12:42:10 +0100 Martin Fleisz (096de0f) + + * Merge pull request #3755 from pentagra/master + +2017-02-14 11:41:27 +0100 Martin Fleisz (9ed81a5) + + * Merge pull request #3764 from akallabeth/libavcodec + +2017-02-14 09:47:36 +0100 Armin Novak (94b9fef) + + * Updated LIBAVCODEC support for H264 decoder. + +2017-02-14 09:52:44 +0100 Martin Fleisz (5930d7e) + + * gdi: Allow changing buffer even if size remains the same + +2017-02-14 09:23:21 +0100 Martin Fleisz (e97c4b5) + + * Merge pull request #3754 from akallabeth/asm3 + +2017-02-13 18:04:42 +0100 Armin Novak (4f44cdc) + + * Use INIT_ONCE for SSPI initialisation. #3471 + +2017-02-13 17:45:03 +0100 Armin Novak (a20adde) + + * Use POSIX cp syntax. + +2017-02-13 17:15:47 +0100 Armin Novak (e3ed91e) + + * Optimized clear codec line copy. + +2017-02-13 16:30:51 +0100 Norbert Federa (7020ed9) + + * Merge pull request #3758 from akallabeth/rfx_tile_crash + +2017-02-13 16:11:11 +0100 Armin Novak (3644d8d) + + * Fixed YUV444ToRGB, do not discard chroma frame. + +2017-02-13 16:09:57 +0100 Armin Novak (4f705b9) + + * Fixed primitives sign test buffer size. + +2017-02-13 16:09:28 +0100 Armin Novak (e60cc9b) + + * NEON optimized YCoCg conversion. + +2017-02-13 16:01:49 +0100 Armin Novak (a791ab0) + + * Added NEON and SSSE3 YCbCr conversion functions. + +2017-02-13 16:00:12 +0100 Armin Novak (b1e3bab) + + * Added NEON and SSSE3 YUV conversion optimisations. + +2017-02-13 15:31:05 +0100 Norbert Federa (5897d83) + + * Merge pull request #3760 from akallabeth/filetime_conversion + +2017-02-11 11:13:14 +0100 Armin Novak (85d8157) + + * Limit RFX update region to screen. + +2017-02-13 14:37:13 +0100 Armin Novak (c90a0be) + + * Fixed time conversion in FileSetFileTime. #3508 + +2016-08-15 22:45:20 +0300 ilammy (11c55f8) + + * client/X11: cache original clipboard data for raw transfers + +2017-02-10 20:38:52 +0000 bigpjo (f0a52d4) + + * .RDP Password Attribute + +2017-02-10 18:06:20 +0300 pentagra (df2b5c9) + + * ifdef's for Cygwin compilation + +2017-02-10 09:46:07 +0100 Norbert Federa (842a8c5) + + * Merge pull request #3753 from akallabeth/regression_fixes + +2017-02-10 08:31:32 +0100 Armin Novak (57db522) + + * Fixed AVC444 luma/chroma checks. + +2017-02-09 19:58:26 +0100 Armin Novak (656b3be) + + * Added fallback for CMSPAR. (See debian #854689) + +2017-02-09 19:55:40 +0100 Armin Novak (ef0a7cf) + + * Fixed missing chroma data for AVC444 + +2017-02-09 18:05:49 +0100 Martin Fleisz (26c2878) + + * Merge pull request #3752 from akallabeth/rfx_respect_height + +2017-02-09 12:36:54 +0100 Armin Novak (7ef9049) + + * Respect width and height in rfx_process_message + +2017-02-09 12:13:04 +0100 Martin Fleisz (9126881) + + * Merge pull request #3750 from hardening/gcc_fix + +2017-02-09 11:50:46 +0100 David Fort (4e00035) + + * Parses the SupportStatusInfoPdu early capability and send it to + clients if supported + +2017-02-06 04:54:54 +0000 Volth (e7487ce) + + * Add command line option to override action script path + +2017-02-08 08:11:38 +0100 David Fort (6af6aba) + + * Merge pull request #3748 from uplusplus/patch-1 + +2017-02-08 11:12:04 +0800 joy.you (75ceb36) + + * bug fix + +2017-02-07 11:19:25 +0100 David Fort (6d8969e) + + * Merge pull request #3747 from nfedera/improve-generic-rgb-to-yuv420 + +2017-02-04 16:49:38 +0100 Norbert Federa (490473d) + + * primitives: RGB to YUV420 (non SIMD) optimizations + +2017-02-06 15:13:56 +0100 Norbert Federa (246801e) + + * Merge pull request #3740 from akallabeth/gdi_color_conversion + +2017-02-06 10:31:43 +0100 Armin Novak (8845b3f) + + * Added warning for unsupported color depth. + +2017-02-05 10:06:51 +0100 akallabeth (1b522e8) + + * Merge pull request #3743 from nfedera/ssse3_rgbx_to_yuv420 + +2017-02-03 11:56:44 +0100 Norbert Federa (cb5dfd8) + + * primitives: added SSSE3 rgb to yuv420 encoder + +2017-02-02 00:29:37 +0500 Ilya Shipitsin (087671b) + + * Remove redundant condition + +2017-02-01 11:11:27 +0100 Norbert Federa (6001cb7) + + * Merge pull request #3717 from akallabeth/prim_fixes + +2017-02-01 11:06:52 +0100 akallabeth (f93e277) + + * Merge pull request #3735 from mfleisz/cmake_install_pdb_fix + +2017-02-01 11:00:24 +0100 Armin Novak (df764f5) + + * Fixed GDI color decoding issues. + +2017-02-01 10:54:13 +0100 David Fort (fc958b8) + + * Merge pull request #3737 from mbaum2000/flush-stdout + +2017-02-01 10:28:30 +0100 Bernhard Miklautz (c3d59df) + + * Merge pull request #3736 from akallabeth/date_legacy_support + +2017-01-31 15:33:44 -0500 Mike Baum (6de47e7) + + * Flush stdout when asking about certificate + +2017-01-31 16:52:20 +0100 Armin Novak (9158fe0) + + * Support old CMake versions without TIMESTAMP #3727 + +2017-01-31 12:28:17 +0100 Armin Novak (16de1bc) + + * Removed unused profiler. + +2017-01-31 13:32:51 +0100 Martin Fleisz (c2eacd3) + + * Build: Use correct pdb names when installing with symbols + +2017-01-31 15:59:25 +0500 Ilya Shipitsin (efaf181) + + * Resolve possible null pointer dereference + +2017-01-31 10:49:59 +0100 Armin Novak (dbfbd5b) + + * Fixed argument order of yCbCrToRGB_16s8u_P3AC4R + +2017-01-31 10:24:24 +0100 Armin Novak (c4122d3) + + * Added performance profiler to YUV test. + +2017-01-31 14:10:58 +0500 Ilya Shipitsin (0a3bd2a) + + * Remove redundant condition + +2017-01-31 10:05:45 +0100 Armin Novak (a926c73) + + * Fixed compiler warning. + +2017-01-31 10:04:00 +0100 Armin Novak (d7426d4) + + * Reverted RGB2V + +2017-01-31 10:01:41 +0100 Armin Novak (ef71f7f) + + * Removed unused files, added README with links + +2017-01-31 09:54:50 +0100 akallabeth (7c5a2f4) + + * Merge pull request #3729 from chipitsine/master + +2017-01-30 15:09:36 +0500 Ilya Shipitsin (52cb79a) + + * remove redundant assignment + +2017-01-30 10:08:48 +0100 Martin Fleisz (58cc996) + + * Merge pull request #3728 from chipitsine/master + +2017-01-28 12:36:08 +0500 Ilya Shipitsin (879f1c3) + + * removed redundant condition: + +2017-01-27 18:49:35 +0100 akallabeth (0d0eb78) + + * Merge pull request #3725 from chipitsine/master + +2017-01-27 11:42:50 +0100 Martin Fleisz (220f407) + + * Merge pull request #3726 from hardening/add_const + +2017-01-27 11:23:08 +0100 David Fort (a6dbc32) + + * Added missing const modifiers for source pointers in codecs + +2017-01-26 11:10:17 +0100 Martin Fleisz (ac12d46) + + * Merge pull request #3715 from akallabeth/reproducible_build + +2017-01-26 11:09:16 +0100 Martin Fleisz (77dc8ad) + + * Merge pull request #3722 from akallabeth/ccache_support + +2017-01-26 14:44:19 +0500 Ilya Shipitsin (12f5368) + + * make cppcheck even more happier: + +2017-01-25 16:00:29 +0100 Armin Novak (052e4bb) + + * Added CCACHE support for android OpenH264 build. + +2017-01-25 15:36:02 +0100 akallabeth (c966f71) + + * Merge pull request #3724 from chipitsine/master + +2017-01-25 15:19:31 +0100 Armin Novak (8b6b496) + + * Added CCACHE support for OpenSSL builds. + +2017-01-25 17:09:25 +0500 Ilya Shipitsin (102913e) + + * make cppcheck a bit happier: + +2017-01-25 12:51:04 +0100 akallabeth (81167cf) + + * Merge pull request #3723 from chipitsine/master + +2017-01-25 15:48:49 +0500 Ilya Shipitsin (0d15573) + + * trivial issue found by cppcheck: + +2017-01-25 09:27:08 +0100 Martin Fleisz (a1a28d1) + + * Merge pull request #3721 from akallabeth/x11_color_fix + +2017-01-25 09:05:27 +0100 Armin Novak (a148927) + + * Added CCACHE detection and option to disable. + +2017-01-25 08:33:36 +0100 Armin Novak (052736a) + + * Fixed conversion to XColor. + +2017-01-25 08:33:04 +0100 Armin Novak (042594b) + + * Fixed stride for XCreateImage. + +2017-01-24 12:54:02 +0100 Armin Novak (d39f4a4) + + * Removed unused functions. + +2017-01-24 11:37:24 +0100 Armin Novak (b04b830) + + * Using faster transformation for RFX decoder. + +2017-01-23 11:25:29 +0100 Armin Novak (00d71f6) + + * Use CMake TIMESTAMP, remove newline from TODAY + +2017-01-24 09:56:45 +0100 Armin Novak (0106405) + + * Using android cpufeatures library for detection. + +2017-01-24 09:28:27 +0100 Armin Novak (ec06c24) + + * Added arm64 and mips64 detection support. + +2017-01-23 17:10:40 +0100 Armin Novak (0d6fb17) + + * Fixed NEON primitives. + +2017-01-23 16:55:50 +0100 Armin Novak (dd430f7) + + * Fixed YUV tests. + +2017-01-23 15:38:02 +0100 Armin Novak (adcd09c) + + * Enabled ASM primitives. + +2017-01-23 17:00:07 +0100 akallabeth (d342910) + + * Merge pull request #3718 from bmiklautz/fix/nightly-pkgs + +2017-01-23 16:43:00 +0100 Bernhard Miklautz (c67ea79) + + * Fix nightly packages + +2017-01-23 15:47:39 +0100 Bernhard Miklautz (924a84b) + + * Merge pull request #3708 from akallabeth/termination_fixes + +2017-01-23 14:18:19 +0100 Armin Novak (7ed9962) + + * Fixed channel connected status. + +2017-01-23 13:49:25 +0100 Bernhard Miklautz (f37e9a0) + + * Merge pull request #3664 from realjiangms/fix_gfx_ack + +2017-01-23 13:44:18 +0100 Bernhard Miklautz (5f26641) + + * Merge pull request #3716 from akallabeth/planar_warning_fix + +2017-01-23 13:27:30 +0100 Armin Novak (b233afc) + + * Fixed uninitialized variable warning. + +2017-01-23 11:59:52 +0100 Martin Fleisz (13d69ca) + + * Merge pull request #3710 from akallabeth/local_16bpp_fixes + +2017-01-23 09:26:56 +0100 Armin Novak (00c32f6) + + * Fixed alpha channel for color formats without. + +2017-01-19 17:16:25 +0100 Armin Novak (6ceb574) + + * Fixed staging surface scanline. + +2017-01-19 17:14:16 +0100 Armin Novak (b32c241) + + * Fixed color format selection for 16bpp + +2017-01-19 17:13:07 +0100 Armin Novak (6188a12) + + * Fixed planar with if local framebuffer is 16bpp + +2017-01-19 16:40:58 +0100 Armin Novak (0acc54a) + + * Fixed scanline for RFX. + +2017-01-23 10:39:02 +0100 Bernhard Miklautz (85da68c) + + * Merge pull request #3703 from akallabeth/prim_optimize + +2017-01-23 10:02:14 +0100 Bernhard Miklautz (ac815e2) + + * Merge pull request #3711 from hardening/monitor_layout + +2017-01-22 16:54:24 +0000 Bernhard M. Wiedemann (3606a42) + + * make build reproducible + +2017-01-19 17:59:54 +0100 David Fort (f68888a) + + * Add a callback that allows to adjust monitors layout + +2017-01-19 17:57:44 +0100 David Fort (e775a2a) + + * Treat the result of the Capabilities callback + +2017-01-19 12:05:26 +0100 Bernhard Miklautz (14d0767) + + * Merge pull request #3705 from akallabeth/android_openssl_1_1 + +2017-01-18 16:52:52 +0100 Armin Novak (676871e) + + * Disabled OpenH264 in default android build. + +2017-01-18 16:41:02 +0100 Armin Novak (34eb0e5) + + * Progressive structs to private header for tests. + +2017-01-18 16:16:29 +0100 Armin Novak (d9810dd) + + * Progressive struct now opaque. + +2017-01-18 15:41:50 +0100 Armin Novak (a64fb34) + + * Fixed missing return. + +2017-01-18 15:25:24 +0100 Armin Novak (ace5100) + + * Progressive conversion and speed fixes + +2017-01-16 12:40:39 +0100 Armin Novak (7198970) + + * Removed obsolete primitive usage. + +2017-01-16 12:40:25 +0100 Armin Novak (7e4c6c6) + + * Optimized functions, removed duplicates. + +2017-01-16 12:39:34 +0100 Armin Novak (9cf6af3) + + * Inlined shift operations. + +2017-01-16 11:45:53 +0100 Armin Novak (326aafc) + + * Inlined freerdp_image_copy helpers. + +2017-01-16 11:39:55 +0100 Armin Novak (da84552) + + * Inlined interleaved helper functions. + +2017-01-16 11:36:35 +0100 Armin Novak (6be6eb2) + + * Optimized freerdp_image_fill + +2017-01-16 10:54:01 +0100 Armin Novak (6b7b1ce) + + * Optimized general_YUV444ToRGB_8u_P3AC4R for BGRX + +2017-01-16 10:25:12 +0100 Armin Novak (4d40b3c) + + * Inlined heavy used functions. + +2017-01-16 10:13:35 +0100 Armin Novak (948e633) + + * Optimized general_RGBToRGB_16s8u_P3AC4R for BGRX + +2017-01-16 10:01:51 +0100 Armin Novak (d76ecc7) + + * Optimized general_yCbCrToRGB_16s8u_P3AC4R for BGRX + +2017-01-18 14:30:06 +0100 Armin Novak (69dde84) + + * Fixed broken variable declaration. + +2017-01-18 14:28:27 +0100 Bernhard Miklautz (de34329) + + * Merge pull request #3702 from akallabeth/clear_reset_fix + +2017-01-18 13:45:34 +0100 Bernhard Miklautz (497db0d) + + * Merge pull request #3707 from akallabeth/AMV007-patch-2 + +2017-01-18 12:39:40 +0100 Armin Novak (9942042) + + * Fixed warnings due to API changes. + +2017-01-17 19:14:56 +0100 Martin Fleisz (95b3665) + + * Merge pull request #3704 from bmiklautz/versioning + +2017-01-17 16:27:56 +0100 Armin Novak (ea45c14) + + * Return OK in case of channel not connected. + +2017-01-17 16:02:13 +0100 Armin Novak (7f1d422) + + * Checks, return value fixes + +2017-01-17 16:00:51 +0100 Armin Novak (56a1425) + + * Do not terminate channel disconnect if one fails. + +2017-01-17 16:00:24 +0100 Armin Novak (221b525) + + * Decreased log verbosity. + +2017-01-17 15:59:50 +0100 Armin Novak (7960251) + + * Fixed audio termination code. + +2017-01-17 13:25:47 +0100 Bernhard Miklautz (2a6bac6) + + * Fix typos in man pages. + +2017-01-17 13:17:25 +0100 Armin Novak (5be65ac) + + * Fixed SONAME + +2017-01-17 10:03:05 +0100 Armin Novak (0f3dcc2) + + * Merge branch 'patch-2' of https://github.com/AMV007/FreeRDP into + AMV007-patch-2 + 2017-01-16 18:18:43 +0100 Norbert Federa (1046c95) - * Merge pull request #3669 from xhaakon/master (HEAD, master) + * Merge pull request #3669 from xhaakon/master + +2017-01-16 18:08:07 +0100 Armin Novak (6d93b92) + + * Updated library names after change in #3704 + +2017-01-16 16:40:06 +0100 Armin Novak (77a8821) + + * Updated gradle settings. + +2017-01-16 16:39:06 +0100 Armin Novak (548927e) + + * Renamed OpenSSL library + +2017-01-16 15:23:11 +0100 Armin Novak (62544e0) + + * Added android release build configurations. + +2017-01-16 14:57:28 +0100 Armin Novak (c74f051) + + * Updated android build scripts for OpenSSL 1.1 + +2017-01-16 11:34:32 +0100 Bernhard Miklautz (d817469) + + * Install man pages + +2017-01-16 11:09:26 +0100 Bernhard Miklautz (9c0e3e3) + + * wlfreerdp: add initial man page + +2017-01-16 09:25:58 +0100 Bernhard Miklautz (38e0bce) + + * shadow-cli: add initial man page + +2017-01-16 08:58:04 +0100 Bernhard Miklautz (d98f117) + + * shadow server: add more error messages + +2017-01-12 16:33:36 +0100 Bernhard Miklautz (af7febf) + + * cmdline: fix wlog man page reference + +2017-01-12 16:25:25 +0100 Bernhard Miklautz (84b542e) + + * winpr-makecert: add initial man page + +2017-01-12 15:46:13 +0100 Bernhard Miklautz (8aeb9df) + + * makecert: fix a regression with > 2048 bit + +2017-01-12 11:04:34 +0100 Bernhard Miklautz (960f464) + + * winpr-makecert: use sha256 and update command line + +2017-01-11 15:28:18 +0100 Bernhard Miklautz (2f93c0f) + + * winpr-hash: cleanup cmd line and add man page + +2017-01-11 15:24:49 +0100 Bernhard Miklautz (3a4e1ad) + + * utils: remove unnecessary debug message. + +2016-12-21 15:25:03 +0100 Bernhard Miklautz (bbb6bf6) + + * Include major version number in library names 2017-01-16 10:36:28 +0100 Martin Fleisz (e218dc0) * Merge pull request #3701 from akallabeth/progressive_inlined +2017-01-13 11:14:30 +0100 Armin Novak (6fec7e5) + + * Do not reset V-Bar storage. + 2017-01-13 09:46:14 +0100 Norbert Federa (71ce337) * Merge pull request #3665 from realjiangms/fix_ssl_add_all_digests @@ -298,6 +1478,28 @@ * Merge branch 'gateway-http-bugfix' +2016-12-10 02:25:50 +0800 zihao.jiang (25381a2) + + * Server/shadow: Fix handling for gfx acknowledge according to spec: + [MS-RDPEGFX]: 3.2.5.13 Processing an + RDPGFX_FRAME_ACKNOWLEDGE_PDU message If the queueDepth + field is less than 0xFFFFFFFF, the server MUST expect that + RDPGFX_FRAME_ACKNOWLEDGE_PDU messages will continue to be + sent by the client. Furthermore, if the queueDepth field + is in the range 0x00000001 to 0xFFFFFFFE the server SHOULD + use this value to determine how far the client is lagging + in terms of graphics decoding and then attempt to throttle + the graphics frame rate accordingly. If the queueDepth + field is set to SUSPEND_FRAME_ACKNOWLEDGEMENT + (0xFFFFFFFF), the server MUST clear the Unacknowledged + Frames (section 3.2.1.2) ADM element and MUST NOT expect + any further RDPGFX_FRAME_ACKNOWLEDGE_PDU messages from the + client. In this mode, the server MUST NOT wait or block on + unacknowledged frames (as the RDPGFX_FRAME_ACKNOWLEDGE_PDU + message is not sent by the client) and MUST assume that + the client is able to decode graphics data at a rate + faster than it is receiving frames. + 2016-12-08 18:51:26 +0100 Christian Plattner (49a6273) * Revert "HTTP Proxy: Simplify using buffered BIO and trio_asprintf" @@ -8049,6 +9251,14 @@ * gdi: fix nullification of instance->context->cache +2015-05-14 17:06:34 +0300 Maxim (c9d6611) + + * added start for suspended threads + +2015-05-14 16:57:37 +0300 Maxim (ed89fc7) + + * coding style update + 2015-05-13 08:24:35 +0200 Hardening (f219d34) * Merge pull request #2611 from nfedera/fix-async-transport-thread @@ -8548,6 +9758,11 @@ * Merge pull request #2547 from nfedera/fix-2015-04-16-01 +2015-04-17 12:14:30 +0300 Maxim (be7ff45) + + * fixed crash at mediaplayer closing, fixed tsmf event parameters-no + video, fixed tsmf no audio. + 2015-04-16 23:54:56 +0200 Norbert Federa (fd5f474) * xfreerdp: fixed initial smart-sizing dimensions @@ -8592,6 +9807,14 @@ * Merge pull request #2546 from akallabeth/error_fixes +2015-04-15 17:42:54 +0300 Maxim (26c054d) + + * fixed - detect realloc failed and return if calloc failed + +2015-04-15 14:08:51 +0300 Maxim (f3a1fe5) + + * fixed-check for calloc return memory + 2015-04-15 10:38:04 +0200 Armin Novak (5525d9f) * Fixed uninitialized return value. @@ -8600,6 +9823,11 @@ * Fixed NULL dereference. +2015-04-15 11:29:27 +0300 Maxim (87eae4a) + + * fixed crash at mediaplayer closing, fixed tsmf event parameters-no + video + 2015-04-14 09:23:47 -0400 Marc-André Moreau (4e1194c) * Merge pull request #2532 from dbungert/4bytestub diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/cliprdr/client/cliprdr_main.c freerdp-2.0.0~dev201703030839+dfsg/channels/cliprdr/client/cliprdr_main.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/cliprdr/client/cliprdr_main.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/cliprdr/client/cliprdr_main.c 2017-03-03 08:39:24.000000000 +0000 @@ -118,6 +118,7 @@ return status; } +#ifdef WITH_DEBUG_CLIPRDR static void cliprdr_print_general_capability_flags(UINT32 flags) { WLog_INFO(TAG, "generalFlags (0x%08"PRIX32") {", flags); @@ -136,6 +137,7 @@ WLog_INFO(TAG, "}"); } +#endif /** * Function description diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/drdynvc/client/drdynvc_main.c freerdp-2.0.0~dev201703030839+dfsg/channels/drdynvc/client/drdynvc_main.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/drdynvc/client/drdynvc_main.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/drdynvc/client/drdynvc_main.c 2017-03-03 08:39:24.000000000 +0000 @@ -390,6 +390,10 @@ { UINT status; DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; + + if (!channel || !channel->dvcman) + return CHANNEL_RC_BAD_CHANNEL; + EnterCriticalSection(&(channel->lock)); status = drdynvc_write_data(channel->dvcman->drdynvc, channel->channel_id, pBuffer, cbSize); @@ -405,6 +409,10 @@ static UINT dvcman_close_channel_iface(IWTSVirtualChannel* pChannel) { DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; + + if (!channel) + return CHANNEL_RC_BAD_CHANNEL; + WLog_DBG(TAG, "close_channel_iface: id=%"PRIu32"", channel->channel_id); return CHANNEL_RC_OK; } @@ -694,23 +702,26 @@ UINT status; if (!drdynvc) - { - status = CHANNEL_RC_BAD_INIT_HANDLE; - } + status = CHANNEL_RC_BAD_CHANNEL_HANDLE; else { status = drdynvc->channelEntryPoints.pVirtualChannelWriteEx(drdynvc->InitHandle, drdynvc->OpenHandle, Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s); } - if (status != CHANNEL_RC_OK) + switch (status) { - Stream_Free(s, TRUE); - WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", WTSErrorToString(status), - status); - } + case CHANNEL_RC_OK: + case CHANNEL_RC_NOT_CONNECTED: + return CHANNEL_RC_OK; - return status; + default: + Stream_Free(s, TRUE); + WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", + WTSErrorToString(status), + status); + return status; + } } /** @@ -727,12 +738,17 @@ UINT32 cbLen; unsigned long chunkLength; UINT status; - WLog_DBG(TAG, "write_data: ChannelId=%"PRIu32" size=%"PRIu32"", ChannelId, dataSize); + + if (!drdynvc) + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + + WLog_Print(drdynvc->log, WLOG_DEBUG, "write_data: ChannelId=%"PRIu32" size=%"PRIu32"", ChannelId, + dataSize); data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); if (!data_out) { - WLog_ERR(TAG, "Stream_New failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } @@ -775,7 +791,7 @@ if (!data_out) { - WLog_ERR(TAG, "Stream_New failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } @@ -799,8 +815,8 @@ if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", - WTSErrorToString(status), status); + WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", + WTSErrorToString(status), status); return status; } @@ -816,12 +832,16 @@ { UINT status; wStream* s; - WLog_DBG(TAG, "capability_response"); + + if (!drdynvc) + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + + WLog_Print(drdynvc->log, WLOG_TRACE, "capability_response"); s = Stream_New(NULL, 4); if (!s) { - WLog_ERR(TAG, "Stream_Ndrdynvc_write_variable_uintew failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_Ndrdynvc_write_variable_uintew failed!"); return CHANNEL_RC_NO_MEMORY; } @@ -832,8 +852,8 @@ if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", - WTSErrorToString(status), status); + WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", + WTSErrorToString(status), status); } return status; @@ -848,7 +868,11 @@ int cbChId, wStream* s) { UINT status; - WLog_DBG(TAG, "capability_request Sp=%d cbChId=%d", Sp, cbChId); + + if (!drdynvc) + return CHANNEL_RC_BAD_INIT_HANDLE; + + WLog_Print(drdynvc->log, WLOG_TRACE, "capability_request Sp=%d cbChId=%d", Sp, cbChId); Stream_Seek(s, 1); /* pad */ Stream_Read_UINT16(s, drdynvc->version); @@ -904,6 +928,9 @@ wStream* data_out; UINT channel_status; + if (!drdynvc) + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES) { /** @@ -915,7 +942,7 @@ if ((status = drdynvc_send_capability_response(drdynvc))) { - WLog_ERR(TAG, "drdynvc_send_capability_response failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_send_capability_response failed!"); return status; } @@ -924,15 +951,16 @@ ChannelId = drdynvc_read_variable_uint(s, cbChId); pos = Stream_GetPosition(s); - WLog_DBG(TAG, "process_create_request: ChannelId=%"PRIu32" ChannelName=%s", ChannelId, - Stream_Pointer(s)); + WLog_Print(drdynvc->log, WLOG_DEBUG, "process_create_request: ChannelId=%"PRIu32" 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) { - WLog_ERR(TAG, "Stream_New failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } @@ -942,12 +970,12 @@ if (channel_status == CHANNEL_RC_OK) { - WLog_DBG(TAG, "channel created"); + WLog_Print(drdynvc->log, WLOG_DEBUG, "channel created"); Stream_Write_UINT32(data_out, 0); } else { - WLog_DBG(TAG, "no listener"); + WLog_Print(drdynvc->log, WLOG_DEBUG, "no listener"); Stream_Write_UINT32(data_out, (UINT32) 0xC0000001); /* same code used by mstsc */ } @@ -965,14 +993,14 @@ { if ((status = dvcman_open_channel(drdynvc->channel_mgr, ChannelId))) { - WLog_ERR(TAG, "dvcman_open_channel failed with error %"PRIu32"!", status); + WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_open_channel failed with error %"PRIu32"!", status); return status; } } else { if ((status = dvcman_close_channel(drdynvc->channel_mgr, ChannelId))) - WLog_ERR(TAG, "dvcman_close_channel failed with error %"PRIu32"!", status); + WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_close_channel failed with error %"PRIu32"!", status); } return status; @@ -1012,8 +1040,9 @@ { UINT32 ChannelId; ChannelId = drdynvc_read_variable_uint(s, cbChId); - WLog_DBG(TAG, "process_data: Sp=%d cbChId=%d, ChannelId=%"PRIu32"", Sp, cbChId, - ChannelId); + WLog_Print(drdynvc->log, WLOG_TRACE, "process_data: Sp=%d cbChId=%d, ChannelId=%"PRIu32"", Sp, + cbChId, + ChannelId); return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId, s); } @@ -1074,34 +1103,28 @@ Cmd = (value & 0xf0) >> 4; Sp = (value & 0x0c) >> 2; cbChId = (value & 0x03) >> 0; - WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d", Cmd, Sp, cbChId); + WLog_Print(drdynvc->log, WLOG_DEBUG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d", Cmd, Sp, cbChId); switch (Cmd) { case CAPABILITY_REQUEST_PDU: return drdynvc_process_capability_request(drdynvc, Sp, cbChId, s); - break; case CREATE_REQUEST_PDU: return drdynvc_process_create_request(drdynvc, Sp, cbChId, s); - break; case DATA_FIRST_PDU: return drdynvc_process_data_first(drdynvc, Sp, cbChId, s); - break; case DATA_PDU: return drdynvc_process_data(drdynvc, Sp, cbChId, s); - break; case CLOSE_REQUEST_PDU: return drdynvc_process_close_request(drdynvc, Sp, cbChId, s); - break; default: WLog_ERR(TAG, "unknown drdynvc cmd 0x%x", Cmd); return ERROR_INTERNAL_ERROR; - break; } } @@ -1206,18 +1229,24 @@ UINT error = CHANNEL_RC_OK; drdynvcPlugin* drdynvc = (drdynvcPlugin*) arg; + if (!drdynvc) + { + ExitThread((DWORD) CHANNEL_RC_BAD_CHANNEL_HANDLE); + return NULL; + } + while (1) { if (!MessageQueue_Wait(drdynvc->queue)) { - WLog_ERR(TAG, "MessageQueue_Wait failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_Wait failed!"); error = ERROR_INTERNAL_ERROR; break; } if (!MessageQueue_Peek(drdynvc->queue, &message, TRUE)) { - WLog_ERR(TAG, "MessageQueue_Peek failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_Peek failed!"); error = ERROR_INTERNAL_ERROR; break; } @@ -1232,7 +1261,7 @@ if ((error = drdynvc_order_recv(drdynvc, data))) { Stream_Free(data, TRUE); - WLog_ERR(TAG, "drdynvc_order_recv failed with error %"PRIu32"!", error); + WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_order_recv failed with error %"PRIu32"!", error); break; } @@ -1240,6 +1269,21 @@ } } + { + /* Disconnect remaining dynamic channels that the server did not. + * This is required to properly shut down channels by calling the appropriate + * event handlers. */ + DVCMAN* drdynvcMgr = (DVCMAN*)drdynvc->channel_mgr; + + while (ArrayList_Count(drdynvcMgr->channels) > 0) + { + IWTSVirtualChannel* channel = (IWTSVirtualChannel*) + ArrayList_GetItem(drdynvcMgr->channels, 0); + const UINT32 ChannelId = drdynvc->channel_mgr->GetChannelId(channel); + dvcman_close_channel(drdynvc->channel_mgr, ChannelId); + } + } + if (error && drdynvc->rdpcontext) setChannelError(drdynvc->rdpcontext, error, "drdynvc_virtual_channel_client_thread reported an error"); @@ -1261,13 +1305,17 @@ UINT32 index; ADDIN_ARGV* args; rdpSettings* settings; + + if (!drdynvc) + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + 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 [%08"PRIX32"]", - WTSErrorToString(status), status); + WLog_Print(drdynvc->log, WLOG_ERROR, "pVirtualChannelOpen failed with %s [%08"PRIX32"]", + WTSErrorToString(status), status); return status; } @@ -1276,7 +1324,7 @@ if (!drdynvc->queue) { error = CHANNEL_RC_NO_MEMORY; - WLog_ERR(TAG, "MessageQueue_New failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_New failed!"); goto error; } @@ -1285,7 +1333,7 @@ if (!drdynvc->channel_mgr) { error = CHANNEL_RC_NO_MEMORY; - WLog_ERR(TAG, "dvcman_new failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_new failed!"); goto error; } @@ -1302,7 +1350,7 @@ if ((error = dvcman_init(drdynvc->channel_mgr))) { - WLog_ERR(TAG, "dvcman_init failed with error %"PRIu32"!", error); + WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_init failed with error %"PRIu32"!", error); goto error; } @@ -1313,7 +1361,7 @@ 0, NULL))) { error = ERROR_INTERNAL_ERROR; - WLog_ERR(TAG, "CreateThread failed!"); + WLog_Print(drdynvc->log, WLOG_ERROR, "CreateThread failed!"); goto error; } @@ -1330,11 +1378,20 @@ { UINT status; - if (MessageQueue_PostQuit(drdynvc->queue, 0) && - (WaitForSingleObject(drdynvc->thread, INFINITE) == WAIT_FAILED)) + if (!drdynvc) + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + + if (!MessageQueue_PostQuit(drdynvc->queue, 0)) + { + status = GetLastError(); + WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_PostQuit failed with error %"PRIu32"", status); + return status; + } + + if (WaitForSingleObject(drdynvc->thread, INFINITE) != WAIT_OBJECT_0) { status = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"", status); + WLog_Print(drdynvc->log, WLOG_ERROR, "WaitForSingleObject failed with error %"PRIu32"", status); return status; } @@ -1347,8 +1404,8 @@ if (status != CHANNEL_RC_OK) { - WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08"PRIX32"]", - WTSErrorToString(status), status); + WLog_Print(drdynvc->log, WLOG_ERROR, "pVirtualChannelClose failed with %s [%08"PRIX32"]", + WTSErrorToString(status), status); } drdynvc->OpenHandle = 0; @@ -1375,6 +1432,9 @@ */ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc) { + if (!drdynvc) + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + drdynvc->InitHandle = 0; free(drdynvc); return CHANNEL_RC_OK; @@ -1401,7 +1461,7 @@ if (pPlugin->Attached) if ((error = pPlugin->Attached(pPlugin))) { - WLog_ERR(TAG, "Attach failed with error %"PRIu32"!", error); + WLog_Print(drdynvc->log, WLOG_ERROR, "Attach failed with error %"PRIu32"!", error); return error; } } @@ -1430,7 +1490,7 @@ if (pPlugin->Detached) if ((error = pPlugin->Detached(pPlugin))) { - WLog_ERR(TAG, "Detach failed with error %"PRIu32"!", error); + WLog_Print(drdynvc->log, WLOG_ERROR, "Detach failed with error %"PRIu32"!", error); return error; } } @@ -1454,31 +1514,36 @@ { 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 %"PRIu32"", error); + WLog_Print(drdynvc->log, WLOG_ERROR, + "drdynvc_virtual_channel_event_connected failed with error %"PRIu32"", 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 %"PRIu32"", error); + WLog_Print(drdynvc->log, WLOG_ERROR, + "drdynvc_virtual_channel_event_disconnected failed with error %"PRIu32"", 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 %"PRIu32"", error); + WLog_Print(drdynvc->log, WLOG_ERROR, + "drdynvc_virtual_channel_event_terminated failed with error %"PRIu32"", error); break; case CHANNEL_EVENT_ATTACHED: if ((error = drdynvc_virtual_channel_event_attached(drdynvc))) - WLog_ERR(TAG, "drdynvc_virtual_channel_event_attached failed with error %"PRIu32"", error); + WLog_Print(drdynvc->log, WLOG_ERROR, + "drdynvc_virtual_channel_event_attached failed with error %"PRIu32"", error); break; case CHANNEL_EVENT_DETACHED: if ((error = drdynvc_virtual_channel_event_detached(drdynvc))) - WLog_ERR(TAG, "drdynvc_virtual_channel_event_detached failed with error %"PRIu32"", error); + WLog_Print(drdynvc->log, WLOG_ERROR, + "drdynvc_virtual_channel_event_detached failed with error %"PRIu32"", error); break; @@ -1554,8 +1619,8 @@ if (CHANNEL_RC_OK != rc) { - WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08"PRIX32"]", - WTSErrorToString(rc), rc); + WLog_Print(drdynvc->log, WLOG_ERROR, "pVirtualChannelInit failed with %s [%08"PRIX32"]", + WTSErrorToString(rc), rc); free(drdynvc->context); free(drdynvc); return FALSE; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/drive/client/drive_file.h freerdp-2.0.0~dev201703030839+dfsg/channels/drive/client/drive_file.h --- freerdp-2.0.0~dev201701161718+dfsg/channels/drive/client/drive_file.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/drive/client/drive_file.h 2017-03-03 08:39:24.000000000 +0000 @@ -61,7 +61,7 @@ typedef UINT32 ssize_t; typedef UINT32 mode_t; -#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) #define STAT stat #define OPEN open #define LSEEK lseek diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/printer/client/printer_cups.c freerdp-2.0.0~dev201703030839+dfsg/channels/printer/client/printer_cups.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/printer/client/printer_cups.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/printer/client/printer_cups.c 2017-03-03 08:39:24.000000000 +0000 @@ -100,6 +100,7 @@ if (fwrite(data, 1, size, fp) < size) { + fclose(fp); return ERROR_INTERNAL_ERROR; // FIXME once this function doesn't return void anymore! } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/printer/client/printer_win.c freerdp-2.0.0~dev201703030839+dfsg/channels/printer/client/printer_win.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/printer/client/printer_win.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/printer/client/printer_win.c 2017-03-03 08:39:24.000000000 +0000 @@ -186,8 +186,8 @@ rdpWinPrinter* win_printer; wchar_t wname[256]; DWORD needed; + int status; PRINTER_INFO_2 *prninfo=NULL; - size_t charsConverted; win_printer = (rdpWinPrinter*) calloc(1, sizeof(rdpWinPrinter)); if (!win_printer) @@ -220,10 +220,10 @@ GetPrinter(win_printer->hPrinter, 2, (LPBYTE) prninfo, needed, &needed); if (drivername) - win_printer->printer.driver = _wcsdup(drivername); + status = ConvertFromUnicode(CP_UTF8, 0, drivername, -1, &win_printer->printer.driver, 0, NULL, NULL); else - win_printer->printer.driver = _wcsdup(prninfo->pDriverName); - if (!win_printer->printer.driver) + status = ConvertFromUnicode(CP_UTF8, 0, prninfo->pDriverName, -1, &win_printer->printer.driver, 0, NULL, NULL); + if (!win_printer->printer.driver || (status <= 0)) { GlobalFree(prninfo); free(win_printer->printer.name); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/rdpgfx/client/rdpgfx_codec.c freerdp-2.0.0~dev201703030839+dfsg/channels/rdpgfx/client/rdpgfx_codec.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/rdpgfx/client/rdpgfx_codec.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/rdpgfx/client/rdpgfx_codec.c 2017-03-03 08:39:24.000000000 +0000 @@ -26,6 +26,7 @@ #include #include #include +#include #include "rdpgfx_common.h" @@ -39,13 +40,12 @@ * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, - RDPGFX_H264_METABLOCK* meta) + RDPGFX_H264_METABLOCK* meta) { UINT32 index; RECTANGLE_16* regionRect; RDPGFX_H264_QUANT_QUALITY* quantQualityVal; UINT error = ERROR_INVALID_DATA; - meta->regionRects = NULL; meta->quantQualityVals = NULL; @@ -72,7 +72,8 @@ goto error_out; } - meta->quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(meta->numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY)); + meta->quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(meta->numRegionRects * sizeof( + RDPGFX_H264_QUANT_QUALITY)); if (!meta->quantQualityVals) { @@ -86,13 +87,16 @@ for (index = 0; index < meta->numRegionRects; index++) { regionRect = &(meta->regionRects[index]); + if ((error = rdpgfx_read_rect16(s, regionRect))) { WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %"PRIu32"!", error); goto error_out; } - WLog_DBG(TAG, "regionRects[%"PRIu32"]: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16"", - index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom); + + WLog_DBG(TAG, + "regionRects[%"PRIu32"]: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16"", + index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom); } if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 2)) @@ -107,12 +111,12 @@ quantQualityVal = &(meta->quantQualityVals[index]); Stream_Read_UINT8(s, quantQualityVal->qpVal); /* qpVal (1 byte) */ Stream_Read_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */ - quantQualityVal->qp = quantQualityVal->qpVal & 0x3F; quantQualityVal->r = (quantQualityVal->qpVal >> 6) & 1; quantQualityVal->p = (quantQualityVal->qpVal >> 7) & 1; - WLog_DBG(TAG, "quantQualityVals[%"PRIu32"]: qp: %"PRIu8" r: %"PRIu8" p: %"PRIu8" qualityVal: %"PRIu8"", - index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal); + WLog_DBG(TAG, + "quantQualityVals[%"PRIu32"]: qp: %"PRIu8" r: %"PRIu8" p: %"PRIu8" qualityVal: %"PRIu8"", + index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal); } return CHANNEL_RC_OK; @@ -135,7 +139,6 @@ wStream* s; RDPGFX_AVC420_BITMAP_STREAM h264; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; - s = Stream_New(cmd->data, cmd->length); if (!s) @@ -152,21 +155,19 @@ h264.data = Stream_Pointer(s); h264.length = (UINT32) Stream_GetRemainingLength(s); - Stream_Free(s, FALSE); - cmd->extra = (void*) &h264; if (context) { IFCALLRET(context->SurfaceCommand, error, context, cmd); + if (error) WLog_ERR(TAG, "context->SurfaceCommand failed with error %"PRIu32"", error); } free(h264.meta.regionRects); free(h264.meta.quantQualityVals); - return error; } @@ -183,7 +184,6 @@ wStream* s; RDPGFX_AVC444_BITMAP_STREAM h264; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; - s = Stream_New(cmd->data, cmd->length); if (!s) @@ -203,18 +203,20 @@ return ERROR_INVALID_DATA; 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 %"PRIu32"!", error); return error; } - pos2 = Stream_GetPosition(s); + pos2 = Stream_GetPosition(s); h264.bitstream[0].data = Stream_Pointer(s); if (h264.LC == 0) { tmp = h264.cbAvc420EncodedBitstream1 - pos2 + pos1; + if (Stream_GetRemainingLength(s) < tmp) return ERROR_INVALID_DATA; @@ -237,12 +239,12 @@ } Stream_Free(s, FALSE); - cmd->extra = (void*) &h264; if (context) { IFCALLRET(context->SurfaceCommand, error, context, cmd); + if (error) WLog_ERR(TAG, "context->SurfaceCommand failed with error %"PRIu32"", error); } @@ -251,7 +253,6 @@ free(h264.bitstream[0].meta.quantQualityVals); free(h264.bitstream[1].meta.regionRects); free(h264.bitstream[1].meta.quantQualityVals); - return error; } @@ -264,34 +265,34 @@ { UINT error = CHANNEL_RC_OK; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; + PROFILER_ENTER(context->SurfaceProfiler); switch (cmd->codecId) { case RDPGFX_CODECID_AVC420: if ((error = rdpgfx_decode_AVC420(gfx, cmd))) - { WLog_ERR(TAG, "rdpgfx_decode_AVC420 failed with error %"PRIu32"", error); - return error; - } + break; case RDPGFX_CODECID_AVC444: if ((error = rdpgfx_decode_AVC444(gfx, cmd))) - { WLog_ERR(TAG, "rdpgfx_decode_AVC444 failed with error %"PRIu32"", error); - return error; - } + break; default: if (context) { IFCALLRET(context->SurfaceCommand, error, context, cmd); + if (error) WLog_ERR(TAG, "context->SurfaceCommand failed with error %"PRIu32"", error); } + break; } + PROFILER_EXIT(context->SurfaceProfiler); return error; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/rdpgfx/client/rdpgfx_main.c freerdp-2.0.0~dev201703030839+dfsg/channels/rdpgfx/client/rdpgfx_main.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/rdpgfx/client/rdpgfx_main.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/rdpgfx/client/rdpgfx_main.c 2017-03-03 08:39:24.000000000 +0000 @@ -271,6 +271,12 @@ Stream_Seek(s, pad); /* pad (total size is 340 bytes) */ WLog_DBG(TAG, "RecvResetGraphicsPdu: width: %"PRIu32" height: %"PRIu32" count: %"PRIu32"", pdu.width, pdu.height, pdu.monitorCount); + for (index = 0; index < pdu.monitorCount; index++) + { + monitor = &(pdu.monitorDefArray[index]); + WLog_DBG(TAG, "RecvResetGraphicsPdu: monitor left:%"PRIi32" top:%"PRIi32" right:%"PRIi32" left:%"PRIi32" flags:0x%"PRIx32"", + monitor->left, monitor->top, monitor->right, monitor->bottom, monitor->flags); + } if (context) { @@ -532,7 +538,7 @@ 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 %"PRIu32"", error); + WLog_DBG(TAG, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"", error); } return error; @@ -578,14 +584,13 @@ pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); WLog_DBG(TAG, - "RecvWireToSurface1Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") pixelFormat: 0x%02"PRIX8" " - "destRect: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" bitmapDataLength: %"PRIu32"", - 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); - + "RecvWireToSurface1Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") pixelFormat: 0x%02"PRIX8" " + "destRect: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" bitmapDataLength: %"PRIu32"", + 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); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = 0; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/rdpsnd/client/rdpsnd_main.c freerdp-2.0.0~dev201703030839+dfsg/channels/rdpsnd/client/rdpsnd_main.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/rdpsnd/client/rdpsnd_main.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/rdpsnd/client/rdpsnd_main.c 2017-03-03 08:39:24.000000000 +0000 @@ -1442,13 +1442,7 @@ 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 %"PRIu32"!", error); - rdpsnd_virtual_channel_event_terminated(plugin); - plugin = NULL; break; case CHANNEL_EVENT_ATTACHED: diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/smartcard/client/smartcard_operations.c freerdp-2.0.0~dev201703030839+dfsg/channels/smartcard/client/smartcard_operations.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/smartcard/client/smartcard_operations.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/smartcard/client/smartcard_operations.c 2017-03-03 08:39:24.000000000 +0000 @@ -192,10 +192,13 @@ return funcName ? "SCardUnknown" : "SCARD_IOCTL_UNKNOWN"; } -static LONG smartcard_EstablishContext_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, EstablishContext_Call* call) +static LONG smartcard_EstablishContext_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + EstablishContext_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(EstablishContext_Call)); if (!call) return STATUS_NO_MEMORY; @@ -205,16 +208,19 @@ WLog_ERR(TAG, "smartcard_unpack_establish_context_call failed with error %"PRId32"", status); return status; } + smartcard_trace_establish_context_call(smartcard, call); return SCARD_S_SUCCESS; } -static LONG smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, EstablishContext_Call* call) +static LONG smartcard_EstablishContext_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; SCARDCONTEXT hContext = -1; EstablishContext_Return ret; IRP* irp = operation->irp; + EstablishContext_Call* call = operation->call; status = ret.ReturnCode = SCardEstablishContext(call->dwScope, NULL, NULL, &hContext); if (ret.ReturnCode == SCARD_S_SUCCESS) @@ -223,11 +229,13 @@ void* key = (void*)(size_t) hContext; // TODO: handle return values pContext = smartcard_context_new(smartcard, hContext); + if (!pContext) { WLog_ERR(TAG, "smartcard_context_new failed!"); return STATUS_NO_MEMORY; } + if (!ListDictionary_Add(smartcard->rgSCardContextList, key, (void*) pContext)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); @@ -242,6 +250,7 @@ smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), hContext); 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 %"PRId32"", status); @@ -251,26 +260,30 @@ return ret.ReturnCode; } -static LONG smartcard_ReleaseContext_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Context_Call* call) +static LONG smartcard_ReleaseContext_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + Context_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(Context_Call)); if (!call) return STATUS_NO_MEMORY; if ((status = smartcard_unpack_context_call(smartcard, irp->input, call))) WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %"PRId32"", status); + smartcard_trace_context_call(smartcard, call, "ReleaseContext"); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; } -static LONG smartcard_ReleaseContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Context_Call* call) +static LONG smartcard_ReleaseContext_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; Long_Return ret; - status = ret.ReturnCode = SCardReleaseContext(operation->hContext); if (ret.ReturnCode == SCARD_S_SUCCESS) @@ -290,61 +303,163 @@ return ret.ReturnCode; } -static LONG smartcard_IsValidContext_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Context_Call* call) +static LONG smartcard_IsValidContext_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + Context_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(Context_Call)); if (!call) return STATUS_NO_MEMORY; if ((status = smartcard_unpack_context_call(smartcard, irp->input, call))) WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %"PRId32"", status); + smartcard_trace_context_call(smartcard, call, "IsValidContext"); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; } -static LONG smartcard_IsValidContext_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Context_Call* call) +static LONG smartcard_IsValidContext_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; Long_Return ret; + if ((status = ret.ReturnCode = SCardIsValidContext(operation->hContext))) { WLog_ERR(TAG, "SCardIsValidContext failed with error %"PRId32"", status); return status; } + smartcard_trace_long_return(smartcard, &ret, "IsValidContext"); return ret.ReturnCode; } -static LONG smartcard_ListReadersA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ListReaders_Call* call) +static LONG smartcard_ListReaderGroupsA_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) +{ + LONG status; + ListReaderGroups_Call* call; + IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(ListReaderGroups_Call)); + + if (!call) + return STATUS_NO_MEMORY; + + status = smartcard_unpack_list_reader_groups_call(smartcard, irp->input, call); + smartcard_trace_list_reader_groups_call(smartcard, call, FALSE); + operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); + return status; +} + +static LONG smartcard_ListReaderGroupsA_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) +{ + LONG status; + ListReaderGroups_Return ret; + LPSTR mszGroups = NULL; + DWORD cchGroups = 0; + IRP* irp = operation->irp; + cchGroups = SCARD_AUTOALLOCATE; + status = ret.ReturnCode = SCardListReaderGroupsA(operation->hContext, (LPSTR) &mszGroups, + &cchGroups); + ret.msz = (BYTE*) mszGroups; + ret.cBytes = cchGroups; + + if (status != SCARD_S_SUCCESS) + return status; + + smartcard_trace_list_reader_groups_return(smartcard, &ret, FALSE); + status = smartcard_pack_list_reader_groups_return(smartcard, irp->output, &ret); + + if (status != SCARD_S_SUCCESS) + return status; + + if (mszGroups) + SCardFreeMemory(operation->hContext, mszGroups); + + return ret.ReturnCode; +} + +static LONG smartcard_ListReaderGroupsW_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) +{ + LONG status; + ListReaderGroups_Call* call; + IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(ListReaderGroups_Call)); + + if (!call) + return STATUS_NO_MEMORY; + + status = smartcard_unpack_list_reader_groups_call(smartcard, irp->input, call); + smartcard_trace_list_reader_groups_call(smartcard, call, TRUE); + operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); + return status; +} + +static LONG smartcard_ListReaderGroupsW_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) +{ + LONG status; + ListReaderGroups_Return ret; + LPWSTR mszGroups = NULL; + DWORD cchGroups = 0; + IRP* irp = operation->irp; + cchGroups = SCARD_AUTOALLOCATE; + status = ret.ReturnCode = SCardListReaderGroupsW(operation->hContext, (LPWSTR) &mszGroups, + &cchGroups); + ret.msz = (BYTE*) mszGroups; + ret.cBytes = cchGroups; + + if (status != SCARD_S_SUCCESS) + return status; + + smartcard_trace_list_reader_groups_return(smartcard, &ret, TRUE); + status = smartcard_pack_list_reader_groups_return(smartcard, irp->output, &ret); + + if (status != SCARD_S_SUCCESS) + return status; + + if (mszGroups) + SCardFreeMemory(operation->hContext, mszGroups); + + return ret.ReturnCode; +} + +static LONG smartcard_ListReadersA_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + ListReaders_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(ListReaders_Call)); if (!call) 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 %"PRId32"", status); + smartcard_trace_list_readers_call(smartcard, call, FALSE); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; } -static LONG smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ListReaders_Call* call) +static LONG smartcard_ListReadersA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; ListReaders_Return ret; LPSTR mszReaders = NULL; DWORD cchReaders = 0; IRP* irp = operation->irp; - + ListReaders_Call* call = operation->call; cchReaders = SCARD_AUTOALLOCATE; - - status = ret.ReturnCode = SCardListReadersA(operation->hContext, (LPCSTR) call->mszGroups, (LPSTR) &mszReaders, &cchReaders); - + status = ret.ReturnCode = SCardListReadersA(operation->hContext, (LPCSTR) call->mszGroups, + (LPSTR) &mszReaders, &cchReaders); ret.msz = (BYTE*) mszReaders; ret.cBytes = cchReaders; @@ -361,6 +476,7 @@ } 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 %"PRId32"", status); @@ -376,10 +492,13 @@ return ret.ReturnCode; } -static LONG smartcard_ListReadersW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ListReaders_Call* call) +static LONG smartcard_ListReadersW_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + ListReaders_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(ListReaders_Call)); if (!call) return STATUS_NO_MEMORY; @@ -389,23 +508,20 @@ smartcard_trace_list_readers_call(smartcard, call, TRUE); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); - return status; } -static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ListReaders_Call* call) +static LONG smartcard_ListReadersW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; ListReaders_Return ret; LPWSTR mszReaders = NULL; DWORD cchReaders = 0; IRP* irp = operation->irp; - + ListReaders_Call* call = operation->call; cchReaders = SCARD_AUTOALLOCATE; - status = ret.ReturnCode = SCardListReadersW(operation->hContext, - (LPCWSTR) call->mszGroups, (LPWSTR) &mszReaders, &cchReaders); - + (LPCWSTR) call->mszGroups, (LPWSTR) &mszReaders, &cchReaders); ret.msz = (BYTE*) mszReaders; ret.cBytes = cchReaders * 2; @@ -415,7 +531,7 @@ call->mszGroups = NULL; } - if (status) + if (status != SCARD_S_SUCCESS) { WLog_ERR(TAG, "SCardListReadersW failed with error %"PRId32"", status); return status; @@ -438,10 +554,13 @@ return ret.ReturnCode; } -static LONG smartcard_GetStatusChangeA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, GetStatusChangeA_Call* call) +static LONG smartcard_GetStatusChangeA_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + GetStatusChangeA_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(GetStatusChangeA_Call)); if (!call) return STATUS_NO_MEMORY; @@ -457,16 +576,17 @@ return status; } -static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, GetStatusChangeA_Call* call) +static LONG smartcard_GetStatusChangeA_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; UINT32 index; GetStatusChange_Return ret; LPSCARD_READERSTATEA rgReaderState = NULL; IRP* irp = operation->irp; - + GetStatusChangeA_Call* call = operation->call; status = ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, - call->dwTimeOut, call->rgReaderStates, call->cReaders); + call->dwTimeOut, call->rgReaderStates, call->cReaders); if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED)) { @@ -475,6 +595,7 @@ ret.cReaders = call->cReaders; ret.rgReaderStates = NULL; + if (ret.cReaders > 0) ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return)); @@ -490,6 +611,7 @@ } 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 %"PRId32"", status); @@ -501,7 +623,7 @@ for (index = 0; index < call->cReaders; index++) { rgReaderState = &call->rgReaderStates[index]; - free((void *)rgReaderState->szReader); + free((void*)rgReaderState->szReader); } free(call->rgReaderStates); @@ -511,37 +633,45 @@ return ret.ReturnCode; } -static LONG smartcard_GetStatusChangeW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, GetStatusChangeW_Call* call) +static LONG smartcard_GetStatusChangeW_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + GetStatusChangeW_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(GetStatusChangeW_Call)); if (!call) 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 %"PRId32"", status); + smartcard_trace_get_status_change_w_call(smartcard, call); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; } -static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, GetStatusChangeW_Call* call) +static LONG smartcard_GetStatusChangeW_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; UINT32 index; GetStatusChange_Return ret; LPSCARD_READERSTATEW rgReaderState = NULL; IRP* irp = operation->irp; - status = ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut, call->rgReaderStates, call->cReaders); + GetStatusChangeW_Call* call = operation->call; + status = ret.ReturnCode = SCardGetStatusChangeW(operation->hContext, call->dwTimeOut, + call->rgReaderStates, call->cReaders); if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED)) { - call->cReaders=0; + call->cReaders = 0; } ret.cReaders = call->cReaders; ret.rgReaderStates = NULL; + if (ret.cReaders > 0) ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return)); @@ -557,6 +687,7 @@ } 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 %"PRId32"", status); @@ -568,7 +699,7 @@ for (index = 0; index < call->cReaders; index++) { rgReaderState = &call->rgReaderStates[index]; - free((void *)rgReaderState->szReader); + free((void*)rgReaderState->szReader); } free(call->rgReaderStates); @@ -578,22 +709,25 @@ return ret.ReturnCode; } -static LONG smartcard_Cancel_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Context_Call* call) +static LONG smartcard_Cancel_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + Context_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(Context_Call)); if (!call) return STATUS_NO_MEMORY; if ((status = smartcard_unpack_context_call(smartcard, irp->input, call))) WLog_ERR(TAG, "smartcard_unpack_context_call failed with error %"PRId32"", status); + smartcard_trace_context_call(smartcard, call, "Cancel"); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; } -static LONG smartcard_Cancel_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Context_Call* call) +static LONG smartcard_Cancel_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; Long_Return ret; @@ -603,41 +737,47 @@ WLog_ERR(TAG, "SCardCancel failed with error %"PRId32"", status); return status; } + smartcard_trace_long_return(smartcard, &ret, "Cancel"); return ret.ReturnCode; } -static LONG smartcard_ConnectA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ConnectA_Call* call) +static LONG smartcard_ConnectA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + ConnectA_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(ConnectA_Call)); if (!call) 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 %"PRId32"", status); + smartcard_trace_connect_a_call(smartcard, call); - operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->Common.hContext)); + operation->hContext = smartcard_scard_context_native_from_redir(smartcard, + &(call->Common.hContext)); return status; } -static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ConnectA_Call* call) +static LONG smartcard_ConnectA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; SCARDHANDLE hCard = 0; Connect_Return ret = { 0 }; IRP* irp = operation->irp; + ConnectA_Call* call = operation->call; if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) && - (call->Common.dwShareMode != SCARD_SHARE_DIRECT)) + (call->Common.dwShareMode != SCARD_SHARE_DIRECT)) { call->Common.dwPreferredProtocols = SCARD_PROTOCOL_Tx; } - status = ret.ReturnCode = SCardConnectA(operation->hContext, (char*) call->szReader, call->Common.dwShareMode, - call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol); - + status = ret.ReturnCode = SCardConnectA(operation->hContext, (char*) call->szReader, + call->Common.dwShareMode, + call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol); smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), operation->hContext); smartcard_scard_handle_native_to_redir(smartcard, &(ret.hCard), hCard); smartcard_trace_connect_return(smartcard, &ret); @@ -648,7 +788,6 @@ return status; } - if ((status = smartcard_pack_connect_return(smartcard, irp->output, &ret))) { WLog_ERR(TAG, "smartcard_pack_connect_return failed with error %"PRId32"", status); @@ -656,14 +795,15 @@ } free(call->szReader); - return ret.ReturnCode; } -static LONG smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ConnectW_Call* call) +static LONG smartcard_ConnectW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + ConnectW_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(ConnectW_Call)); if (!call) return STATUS_NO_MEMORY; @@ -672,27 +812,28 @@ WLog_ERR(TAG, "smartcard_unpack_connect_w_call failed with error %"PRId32"", status); smartcard_trace_connect_w_call(smartcard, call); - operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->Common.hContext)); - + operation->hContext = smartcard_scard_context_native_from_redir(smartcard, + &(call->Common.hContext)); return status; } -static LONG smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, ConnectW_Call* call) +static LONG smartcard_ConnectW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; SCARDHANDLE hCard = 0; Connect_Return ret = { 0 }; IRP* irp = operation->irp; + ConnectW_Call* call = operation->call; if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) && - (call->Common.dwShareMode != SCARD_SHARE_DIRECT)) + (call->Common.dwShareMode != SCARD_SHARE_DIRECT)) { call->Common.dwPreferredProtocols = SCARD_PROTOCOL_Tx; } - status = ret.ReturnCode = SCardConnectW(operation->hContext, (WCHAR*) call->szReader, call->Common.dwShareMode, - call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol); - + status = ret.ReturnCode = SCardConnectW(operation->hContext, (WCHAR*) call->szReader, + call->Common.dwShareMode, + call->Common.dwPreferredProtocols, &hCard, &ret.dwActiveProtocol); smartcard_scard_context_native_to_redir(smartcard, &(ret.hContext), operation->hContext); smartcard_scard_handle_native_to_redir(smartcard, &(ret.hCard), hCard); smartcard_trace_connect_return(smartcard, &ret); @@ -710,34 +851,38 @@ } free(call->szReader); - return ret.ReturnCode; } -static LONG smartcard_Reconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Reconnect_Call* call) +static LONG smartcard_Reconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + Reconnect_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(Reconnect_Call)); if (!call) return STATUS_NO_MEMORY; if ((status = smartcard_unpack_reconnect_call(smartcard, irp->input, call))) WLog_ERR(TAG, "smartcard_unpack_reconnect_call failed with error %"PRId32"", 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)); return status; } -static LONG smartcard_Reconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Reconnect_Call* call) +static LONG smartcard_Reconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; Reconnect_Return ret; IRP* irp = operation->irp; + Reconnect_Call* call = operation->call; status = ret.ReturnCode = SCardReconnect(operation->hCard, call->dwShareMode, - call->dwPreferredProtocols, call->dwInitialization, &ret.dwActiveProtocol); + call->dwPreferredProtocols, call->dwInitialization, &ret.dwActiveProtocol); 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 %"PRId32"", status); @@ -747,114 +892,143 @@ return ret.ReturnCode; } -static LONG smartcard_Disconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, HCardAndDisposition_Call* call) +static LONG smartcard_Disconnect_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + HCardAndDisposition_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(HCardAndDisposition_Call)); if (!call) 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 %"PRId32"", 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)); return status; } -static LONG smartcard_Disconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, HCardAndDisposition_Call* call) +static LONG smartcard_Disconnect_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; Long_Return ret; + HCardAndDisposition_Call* call = operation->call; + if ((status = ret.ReturnCode = SCardDisconnect(operation->hCard, call->dwDisposition))) { WLog_ERR(TAG, "SCardDisconnect failed with error %"PRId32"", status); return status; } + smartcard_trace_long_return(smartcard, &ret, "Disconnect"); + if (status != SCARD_S_SUCCESS) + return status; + return ret.ReturnCode; } -static LONG smartcard_BeginTransaction_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, HCardAndDisposition_Call* call) +static LONG smartcard_BeginTransaction_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + HCardAndDisposition_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(HCardAndDisposition_Call)); if (!call) 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 %"PRId32"", 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)); return status; } -static LONG smartcard_BeginTransaction_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, HCardAndDisposition_Call* call) +static LONG smartcard_BeginTransaction_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { Long_Return ret; + if ((ret.ReturnCode = SCardBeginTransaction(operation->hCard))) { WLog_ERR(TAG, "SCardBeginTransaction failed with error %"PRId32"", ret.ReturnCode); return ret.ReturnCode; } + smartcard_trace_long_return(smartcard, &ret, "BeginTransaction"); return ret.ReturnCode; } -static LONG smartcard_EndTransaction_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, HCardAndDisposition_Call* call) +static LONG smartcard_EndTransaction_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + HCardAndDisposition_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(HCardAndDisposition_Call)); if (!call) 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 %"PRId32"", 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)); return status; } -static LONG smartcard_EndTransaction_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, HCardAndDisposition_Call* call) +static LONG smartcard_EndTransaction_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { Long_Return ret; + HCardAndDisposition_Call* call = operation->call; + if ((ret.ReturnCode = SCardEndTransaction(operation->hCard, call->dwDisposition))) { WLog_ERR(TAG, "SCardEndTransaction failed with error %"PRId32"", ret.ReturnCode); return ret.ReturnCode; } + smartcard_trace_long_return(smartcard, &ret, "EndTransaction"); return ret.ReturnCode; } -static LONG smartcard_State_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, State_Call* call) +static LONG smartcard_State_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + State_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(State_Call)); if (!call) return STATUS_NO_MEMORY; if ((status = smartcard_unpack_state_call(smartcard, irp->input, call))) WLog_ERR(TAG, "smartcard_unpack_state_call failed with error %"PRId32"", 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; } -static LONG smartcard_State_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, State_Call* call) +static LONG smartcard_State_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; State_Return ret; IRP* irp = operation->irp; ret.cbAtrLen = SCARD_ATR_LENGTH; - ret.ReturnCode = SCardState(operation->hCard, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.rgAtr, &ret.cbAtrLen); + 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 %"PRId32"", status); @@ -864,36 +1038,42 @@ return ret.ReturnCode; } -static LONG smartcard_StatusA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Status_Call* call) +static LONG smartcard_StatusA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + Status_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(State_Call)); if (!call) return STATUS_NO_MEMORY; if ((status = smartcard_unpack_status_call(smartcard, irp->input, call))) WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %"PRId32"", 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)); return status; } -static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Status_Call* call) +static LONG smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; Status_Return ret = { 0 }; DWORD cchReaderLen = 0; LPSTR mszReaderNames = NULL; IRP* irp = operation->irp; + Status_Call* call = operation->call; + + if (call->cbAtrLen > 32) + call->cbAtrLen = 32; - ret.cbAtrLen = 32; + ret.cbAtrLen = call->cbAtrLen; ZeroMemory(ret.pbAtr, 32); cchReaderLen = SCARD_AUTOALLOCATE; - status = ret.ReturnCode = SCardStatusA(operation->hCard, (LPSTR) &mszReaderNames, &cchReaderLen, - &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen); + &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen); if (status == SCARD_S_SUCCESS) { @@ -902,6 +1082,7 @@ } 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 %"PRId32"", status); @@ -914,40 +1095,46 @@ return ret.ReturnCode; } -static LONG smartcard_StatusW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Status_Call* call) +static LONG smartcard_StatusW_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + Status_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(State_Call)); if (!call) return STATUS_NO_MEMORY; if ((status = smartcard_unpack_status_call(smartcard, irp->input, call))) WLog_ERR(TAG, "smartcard_unpack_status_call failed with error %"PRId32"", 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)); return status; } -static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Status_Call* call) +static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; Status_Return ret; DWORD cchReaderLen = 0; LPWSTR mszReaderNames = NULL; IRP* irp = operation->irp; + Status_Call* call = operation->call; + + if (call->cbAtrLen > 32) + call->cbAtrLen = 32; - ret.cbAtrLen = 32; + ret.cbAtrLen = call->cbAtrLen; ZeroMemory(ret.pbAtr, 32); cchReaderLen = SCARD_AUTOALLOCATE; - status = ret.ReturnCode = SCardStatusW(operation->hCard, (LPWSTR) &mszReaderNames, &cchReaderLen, - &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen); - + &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen); ret.mszReaderNames = (BYTE*) mszReaderNames; ret.cBytes = cchReaderLen * 2; 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 %"PRId32"", status); @@ -960,10 +1147,12 @@ return ret.ReturnCode; } -static LONG smartcard_Transmit_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Transmit_Call* call) +static LONG smartcard_Transmit_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + Transmit_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(Transmit_Call)); if (!call) return STATUS_NO_MEMORY; @@ -972,18 +1161,17 @@ WLog_ERR(TAG, "smartcard_unpack_transmit_call failed with error %"PRId32"", status); smartcard_trace_transmit_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)); - return status; } -static LONG smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Transmit_Call* call) +static LONG smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; Transmit_Return ret; IRP* irp = operation->irp; + Transmit_Call* call = operation->call; ret.cbRecvLength = 0; ret.pbRecvBuffer = NULL; @@ -1000,11 +1188,10 @@ } ret.pioRecvPci = call->pioRecvPci; - - ret.ReturnCode = SCardTransmit(operation->hCard, call->pioSendPci, call->pbSendBuffer, - call->cbSendLength, ret.pioRecvPci, ret.pbRecvBuffer, &(ret.cbRecvLength)); - + status = ret.ReturnCode = SCardTransmit(operation->hCard, call->pioSendPci, call->pbSendBuffer, + call->cbSendLength, ret.pioRecvPci, ret.pbRecvBuffer, &(ret.cbRecvLength)); 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 %"PRId32"", status); @@ -1015,31 +1202,34 @@ free(ret.pbRecvBuffer); free(call->pioSendPci); free(call->pioRecvPci); - return ret.ReturnCode; } -static LONG smartcard_Control_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Control_Call* call) +static LONG smartcard_Control_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + Control_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(Control_Call)); if (!call) return STATUS_NO_MEMORY; if ((status = smartcard_unpack_control_call(smartcard, irp->input, call))) WLog_ERR(TAG, "smartcard_unpack_control_call failed with error %"PRId32"", 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)); return status; } -static LONG smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Control_Call* call) +static LONG smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; Control_Return ret; IRP* irp = operation->irp; + Control_Call* call = operation->call; ret.cbOutBufferSize = call->cbOutBufferSize; ret.pvOutBuffer = (BYTE*) malloc(call->cbOutBufferSize); @@ -1047,10 +1237,10 @@ return SCARD_E_NO_MEMORY; status = ret.ReturnCode = SCardControl(operation->hCard, - call->dwControlCode, call->pvInBuffer, call->cbInBufferSize, - ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize); - + call->dwControlCode, call->pvInBuffer, call->cbInBufferSize, + ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize); 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 %"PRId32"", status); @@ -1059,34 +1249,36 @@ free(call->pvInBuffer); free(ret.pvOutBuffer); - return ret.ReturnCode; } -static LONG smartcard_GetAttrib_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, GetAttrib_Call* call) +static LONG smartcard_GetAttrib_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; + GetAttrib_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(GetAttrib_Call)); if (!call) 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 %"PRId32"", 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)); return status; } -static LONG smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, GetAttrib_Call* call) +static LONG smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) { LONG status; DWORD cbAttrLen; BOOL autoAllocate; GetAttrib_Return ret; IRP* irp = operation->irp; - + GetAttrib_Call* call = operation->call; ret.pbAttr = NULL; if (call->fpbAttrIsNULL) @@ -1103,20 +1295,16 @@ } cbAttrLen = call->cbAttrLen; - status = ret.ReturnCode = SCardGetAttrib(operation->hCard, call->dwAttrId, - autoAllocate ? (LPBYTE) &(ret.pbAttr) : ret.pbAttr, &cbAttrLen); - + autoAllocate ? (LPBYTE) & (ret.pbAttr) : ret.pbAttr, &cbAttrLen); ret.cbAttrLen = cbAttrLen; - smartcard_trace_get_attrib_return(smartcard, &ret, call->dwAttrId); if (ret.ReturnCode) { WLog_WARN(TAG, "SCardGetAttrib: %s (0x%08"PRIX32") cbAttrLen: %"PRIu32"", - SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->cbAttrLen); + SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->cbAttrLen); Stream_Zero(irp->output, 256); - free(ret.pbAttr); return ret.ReturnCode; } @@ -1131,9 +1319,12 @@ return ret.ReturnCode; } -static LONG smartcard_AccessStartedEvent_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Long_Call* call) +static LONG smartcard_AccessStartedEvent_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { + Long_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(Long_Call)); if (!call) return STATUS_NO_MEMORY; @@ -1141,7 +1332,7 @@ if (Stream_GetRemainingLength(irp->input) < 4) { WLog_WARN(TAG, "AccessStartedEvent is too short: %"PRIuz"", - Stream_GetRemainingLength(irp->input)); + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } @@ -1149,33 +1340,41 @@ return SCARD_S_SUCCESS; } -static LONG smartcard_AccessStartedEvent_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Long_Call* call) +static LONG smartcard_AccessStartedEvent_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { + LONG status = SCARD_S_SUCCESS; + if (!smartcard->StartedEvent) smartcard->StartedEvent = SCardAccessStartedEvent(); if (!smartcard->StartedEvent) - return SCARD_E_NO_SERVICE; + status = SCARD_E_NO_SERVICE; - return SCARD_S_SUCCESS; + return status; } -static LONG smartcard_LocateCardsByATRA_Decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, LocateCardsByATRA_Call* call) +static LONG smartcard_LocateCardsByATRA_Decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; + LocateCardsByATRA_Call* call; IRP* irp = operation->irp; + operation->call = call = calloc(1, sizeof(LocateCardsByATRA_Call)); if (!call) 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 %"PRId32"", status); + smartcard_trace_locate_cards_by_atr_a_call(smartcard, call); operation->hContext = smartcard_scard_context_native_from_redir(smartcard, &(call->hContext)); return status; } -static LONG smartcard_LocateCardsByATRA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, LocateCardsByATRA_Call* call) +static LONG smartcard_LocateCardsByATRA_Call(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; BOOL equal; @@ -1184,7 +1383,7 @@ LPSCARD_READERSTATEA state = NULL; LPSCARD_READERSTATEA states = NULL; IRP* irp = operation->irp; - + LocateCardsByATRA_Call* call = operation->call; states = (LPSCARD_READERSTATEA) calloc(call->cReaders, sizeof(SCARD_READERSTATEA)); if (!states) @@ -1199,7 +1398,8 @@ CopyMemory(&(states[i].rgbAtr), &(call->rgReaderStates[i].Common.rgbAtr), 36); } - status = ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, 0x000001F4, states, call->cReaders); + status = ret.ReturnCode = SCardGetStatusChangeA(operation->hContext, 0x000001F4, states, + call->cReaders); if (status && (status != SCARD_E_TIMEOUT) && (status != SCARD_E_CANCELLED)) { @@ -1220,6 +1420,7 @@ equal = FALSE; break; } + if (equal) { states[j].dwEventState |= SCARD_STATE_ATRMATCH; @@ -1230,6 +1431,7 @@ ret.cReaders = call->cReaders; ret.rgReaderStates = NULL; + if (ret.cReaders > 0) ret.rgReaderStates = (ReaderState_Return*) calloc(ret.cReaders, sizeof(ReaderState_Return)); @@ -1244,9 +1446,10 @@ ret.rgReaderStates[i].cbAtr = state->cbAtr; CopyMemory(&(ret.rgReaderStates[i].rgbAtr), &(state->rgbAtr), 32); } - free(states); + free(states); 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 %"PRId32"", status); @@ -1259,7 +1462,8 @@ { state = (LPSCARD_READERSTATEA) &call->rgReaderStates[i]; - if (state->szReader) { + if (state->szReader) + { free((void*) state->szReader); state->szReader = NULL; } @@ -1273,11 +1477,11 @@ return ret.ReturnCode; } -LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation) +LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, + SMARTCARD_OPERATION* operation) { LONG status; UINT32 offset; - void* call = NULL; UINT32 ioControlCode; UINT32 outputBufferLength; UINT32 inputBufferLength; @@ -1288,7 +1492,7 @@ if (Stream_GetRemainingLength(irp->input) < 32) { WLog_WARN(TAG, "Device Control Request is too short: %"PRIuz"", - Stream_GetRemainingLength(irp->input)); + Stream_GetRemainingLength(irp->input)); return SCARD_F_INTERNAL_ERROR; } @@ -1301,17 +1505,17 @@ if (Stream_Length(irp->input) != (Stream_GetPosition(irp->input) + inputBufferLength)) { WLog_WARN(TAG, "InputBufferLength mismatch: Actual: %"PRIuz" Expected: %"PRIuz"", - Stream_Length(irp->input), - Stream_GetPosition(irp->input) + inputBufferLength); + Stream_Length(irp->input), + Stream_GetPosition(irp->input) + inputBufferLength); return SCARD_F_INTERNAL_ERROR; } WLog_DBG(TAG, "%s (0x%08"PRIX32") FileId: %"PRIu32" CompletionId: %"PRIu32"", - smartcard_get_ioctl_string(ioControlCode, TRUE), - ioControlCode, irp->FileId, irp->CompletionId); + smartcard_get_ioctl_string(ioControlCode, TRUE), + ioControlCode, irp->FileId, irp->CompletionId); if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && - (ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT)) + (ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT)) { if ((status = smartcard_unpack_common_type_header(smartcard, irp->input))) { @@ -1327,60 +1531,36 @@ } /* Decode */ + operation->call = NULL; switch (ioControlCode) { case SCARD_IOCTL_ESTABLISHCONTEXT: - if (!(call = calloc(1, sizeof(EstablishContext_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_EstablishContext_Decode(smartcard, operation, (EstablishContext_Call*) call); + status = smartcard_EstablishContext_Decode(smartcard, operation); break; case SCARD_IOCTL_RELEASECONTEXT: - if (!(call = calloc(1, sizeof(Context_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_ReleaseContext_Decode(smartcard, operation, (Context_Call*) call); + status = smartcard_ReleaseContext_Decode(smartcard, operation); break; case SCARD_IOCTL_ISVALIDCONTEXT: - if (!(call = calloc(1, sizeof(Context_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_IsValidContext_Decode(smartcard, operation, (Context_Call*) call); + status = smartcard_IsValidContext_Decode(smartcard, operation); break; case SCARD_IOCTL_LISTREADERGROUPSA: - status = SCARD_F_INTERNAL_ERROR; + status = smartcard_ListReaderGroupsA_Decode(smartcard, operation); break; case SCARD_IOCTL_LISTREADERGROUPSW: - status = SCARD_F_INTERNAL_ERROR; + status = smartcard_ListReaderGroupsW_Decode(smartcard, operation); break; case SCARD_IOCTL_LISTREADERSA: - if (!(call = calloc(1, sizeof(ListReaders_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_ListReadersA_Decode(smartcard, operation, (ListReaders_Call*) call); + status = smartcard_ListReadersA_Decode(smartcard, operation); break; case SCARD_IOCTL_LISTREADERSW: - if (!(call = calloc(1, sizeof(ListReaders_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_ListReadersW_Decode(smartcard, operation, (ListReaders_Call*) call); + status = smartcard_ListReadersW_Decode(smartcard, operation); break; case SCARD_IOCTL_INTRODUCEREADERGROUPA: @@ -1440,138 +1620,63 @@ break; case SCARD_IOCTL_GETSTATUSCHANGEA: - if (!(call = calloc(1, sizeof(GetStatusChangeA_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_GetStatusChangeA_Decode(smartcard, operation, (GetStatusChangeA_Call*) call); + status = smartcard_GetStatusChangeA_Decode(smartcard, operation); break; case SCARD_IOCTL_GETSTATUSCHANGEW: - if (!(call = calloc(1, sizeof(GetStatusChangeW_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_GetStatusChangeW_Decode(smartcard, operation, (GetStatusChangeW_Call*) call); + status = smartcard_GetStatusChangeW_Decode(smartcard, operation); break; case SCARD_IOCTL_CANCEL: - if (!(call = calloc(1, sizeof(Context_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_Cancel_Decode(smartcard, operation, (Context_Call*) call); + status = smartcard_Cancel_Decode(smartcard, operation); break; case SCARD_IOCTL_CONNECTA: - if (!(call = calloc(1, sizeof(ConnectA_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_ConnectA_Decode(smartcard, operation, (ConnectA_Call*) call); + status = smartcard_ConnectA_Decode(smartcard, operation); break; case SCARD_IOCTL_CONNECTW: - if (!(call = calloc(1, sizeof(ConnectW_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_ConnectW_Decode(smartcard, operation, (ConnectW_Call*) call); + status = smartcard_ConnectW_Decode(smartcard, operation); break; case SCARD_IOCTL_RECONNECT: - if (!(call = calloc(1, sizeof(Reconnect_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_Reconnect_Decode(smartcard, operation, (Reconnect_Call*) call); + status = smartcard_Reconnect_Decode(smartcard, operation); break; case SCARD_IOCTL_DISCONNECT: - if (!(call = calloc(1, sizeof(HCardAndDisposition_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_Disconnect_Decode(smartcard, operation, (HCardAndDisposition_Call*) call); + status = smartcard_Disconnect_Decode(smartcard, operation); break; case SCARD_IOCTL_BEGINTRANSACTION: - if (!(call = calloc(1, sizeof(HCardAndDisposition_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_BeginTransaction_Decode(smartcard, operation, (HCardAndDisposition_Call*) call); + status = smartcard_BeginTransaction_Decode(smartcard, operation); break; case SCARD_IOCTL_ENDTRANSACTION: - if (!(call = calloc(1, sizeof(HCardAndDisposition_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_EndTransaction_Decode(smartcard, operation, (HCardAndDisposition_Call*) call); + status = smartcard_EndTransaction_Decode(smartcard, operation); break; case SCARD_IOCTL_STATE: - if (!(call = calloc(1, sizeof(State_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_State_Decode(smartcard, operation, (State_Call*) call); + status = smartcard_State_Decode(smartcard, operation); break; case SCARD_IOCTL_STATUSA: - if (!(call = calloc(1, sizeof(Status_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_StatusA_Decode(smartcard, operation, (Status_Call*) call); + status = smartcard_StatusA_Decode(smartcard, operation); break; case SCARD_IOCTL_STATUSW: - if (!(call = calloc(1, sizeof(Status_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_StatusW_Decode(smartcard, operation, (Status_Call*) call); + status = smartcard_StatusW_Decode(smartcard, operation); break; case SCARD_IOCTL_TRANSMIT: - if (!(call = calloc(1, sizeof(Transmit_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_Transmit_Decode(smartcard, operation, (Transmit_Call*) call); + status = smartcard_Transmit_Decode(smartcard, operation); break; case SCARD_IOCTL_CONTROL: - if (!(call = calloc(1, sizeof(Control_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_Control_Decode(smartcard, operation, (Control_Call*) call); + status = smartcard_Control_Decode(smartcard, operation); break; case SCARD_IOCTL_GETATTRIB: - if (!(call = calloc(1, sizeof(GetAttrib_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_GetAttrib_Decode(smartcard, operation, (GetAttrib_Call*) call); + status = smartcard_GetAttrib_Decode(smartcard, operation); break; case SCARD_IOCTL_SETATTRIB: @@ -1579,21 +1684,11 @@ break; case SCARD_IOCTL_ACCESSSTARTEDEVENT: - if (!(call = calloc(1, sizeof(Long_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_AccessStartedEvent_Decode(smartcard, operation, (Long_Call*) call); + status = smartcard_AccessStartedEvent_Decode(smartcard, operation); break; case SCARD_IOCTL_LOCATECARDSBYATRA: - if (!(call = calloc(1, sizeof(LocateCardsByATRA_Call)))) - { - WLog_ERR(TAG, "calloc failed!"); - return SCARD_E_NO_MEMORY; - } - status = smartcard_LocateCardsByATRA_Decode(smartcard, operation, (LocateCardsByATRA_Call*) call); + status = smartcard_LocateCardsByATRA_Decode(smartcard, operation); break; case SCARD_IOCTL_LOCATECARDSBYATRW: @@ -1638,20 +1733,21 @@ } if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && - (ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT)) + (ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT)) { offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH); smartcard_unpack_read_size_align(smartcard, irp->input, - Stream_GetPosition(irp->input) - offset, 8); + Stream_GetPosition(irp->input) - offset, 8); } if (Stream_GetPosition(irp->input) < Stream_Length(irp->input)) { SIZE_T difference; difference = Stream_Length(irp->input) - Stream_GetPosition(irp->input); - WLog_WARN(TAG, "IRP was not fully parsed %s (0x%08"PRIX32"): Actual: %"PRIuz", Expected: %"PRIuz", Difference: %"PRIuz"", - smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, - Stream_GetPosition(irp->input), Stream_Length(irp->input), difference); + WLog_WARN(TAG, + "IRP was not fully parsed %s (0x%08"PRIX32"): Actual: %"PRIuz", Expected: %"PRIuz", Difference: %"PRIuz"", + smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, + Stream_GetPosition(irp->input), Stream_Length(irp->input), difference); winpr_HexDump(TAG, WLOG_WARN, Stream_Pointer(irp->input), difference); } @@ -1659,18 +1755,18 @@ { SIZE_T difference; difference = Stream_GetPosition(irp->input) - Stream_Length(irp->input); - WLog_WARN(TAG, "IRP was parsed beyond its end %s (0x%08"PRIX32"): Actual: %"PRIuz", Expected: %"PRIuz", Difference: %"PRIuz"", - smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, - Stream_GetPosition(irp->input), Stream_Length(irp->input), difference); + WLog_WARN(TAG, + "IRP was parsed beyond its end %s (0x%08"PRIX32"): Actual: %"PRIuz", Expected: %"PRIuz", Difference: %"PRIuz"", + smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, + Stream_GetPosition(irp->input), Stream_Length(irp->input), difference); } if (status != SCARD_S_SUCCESS) { - free(call); - call = NULL; + free(operation->call); + operation->call = NULL; } - operation->call = call; return status; } @@ -1679,14 +1775,11 @@ IRP* irp; LONG result; UINT32 offset; - ULONG_PTR* call; UINT32 ioControlCode; UINT32 outputBufferLength; UINT32 objectBufferLength; irp = operation->irp; - call = operation->call; ioControlCode = operation->ioControlCode; - /** * [MS-RDPESC] 3.2.5.1: Sending Outgoing Messages: * the output buffer length SHOULD be set to 2048 @@ -1695,7 +1788,6 @@ * about it, but we still reserve at least 2048 bytes. */ Stream_EnsureRemainingCapacity(irp->output, 2048); - /* Device Control Response */ Stream_Seek_UINT32(irp->output); /* OutputBufferLength (4 bytes) */ Stream_Seek(irp->output, SMARTCARD_COMMON_TYPE_HEADER_LENGTH); /* CommonTypeHeader (8 bytes) */ @@ -1707,31 +1799,31 @@ switch (ioControlCode) { case SCARD_IOCTL_ESTABLISHCONTEXT: - result = smartcard_EstablishContext_Call(smartcard, operation, (EstablishContext_Call*) call); + result = smartcard_EstablishContext_Call(smartcard, operation); break; case SCARD_IOCTL_RELEASECONTEXT: - result = smartcard_ReleaseContext_Call(smartcard, operation, (Context_Call*) call); + result = smartcard_ReleaseContext_Call(smartcard, operation); break; case SCARD_IOCTL_ISVALIDCONTEXT: - result = smartcard_IsValidContext_Call(smartcard, operation, (Context_Call*) call); + result = smartcard_IsValidContext_Call(smartcard, operation); break; case SCARD_IOCTL_LISTREADERGROUPSA: - result = SCARD_F_INTERNAL_ERROR; + result = smartcard_ListReaderGroupsA_Call(smartcard, operation); break; case SCARD_IOCTL_LISTREADERGROUPSW: - result = SCARD_F_INTERNAL_ERROR; + result = smartcard_ListReaderGroupsW_Call(smartcard, operation); break; case SCARD_IOCTL_LISTREADERSA: - result = smartcard_ListReadersA_Call(smartcard, operation, (ListReaders_Call*) call); + result = smartcard_ListReadersA_Call(smartcard, operation); break; case SCARD_IOCTL_LISTREADERSW: - result = smartcard_ListReadersW_Call(smartcard, operation, (ListReaders_Call*) call); + result = smartcard_ListReadersW_Call(smartcard, operation); break; case SCARD_IOCTL_INTRODUCEREADERGROUPA: @@ -1791,63 +1883,63 @@ break; case SCARD_IOCTL_GETSTATUSCHANGEA: - result = smartcard_GetStatusChangeA_Call(smartcard, operation, (GetStatusChangeA_Call*) call); + result = smartcard_GetStatusChangeA_Call(smartcard, operation); break; case SCARD_IOCTL_GETSTATUSCHANGEW: - result = smartcard_GetStatusChangeW_Call(smartcard, operation, (GetStatusChangeW_Call*) call); + result = smartcard_GetStatusChangeW_Call(smartcard, operation); break; case SCARD_IOCTL_CANCEL: - result = smartcard_Cancel_Call(smartcard, operation, (Context_Call*) call); + result = smartcard_Cancel_Call(smartcard, operation); break; case SCARD_IOCTL_CONNECTA: - result = smartcard_ConnectA_Call(smartcard, operation, (ConnectA_Call*) call); + result = smartcard_ConnectA_Call(smartcard, operation); break; case SCARD_IOCTL_CONNECTW: - result = smartcard_ConnectW_Call(smartcard, operation, (ConnectW_Call*) call); + result = smartcard_ConnectW_Call(smartcard, operation); break; case SCARD_IOCTL_RECONNECT: - result = smartcard_Reconnect_Call(smartcard, operation, (Reconnect_Call*) call); + result = smartcard_Reconnect_Call(smartcard, operation); break; case SCARD_IOCTL_DISCONNECT: - result = smartcard_Disconnect_Call(smartcard, operation, (HCardAndDisposition_Call*) call); + result = smartcard_Disconnect_Call(smartcard, operation); break; case SCARD_IOCTL_BEGINTRANSACTION: - result = smartcard_BeginTransaction_Call(smartcard, operation, (HCardAndDisposition_Call*) call); + result = smartcard_BeginTransaction_Call(smartcard, operation); break; case SCARD_IOCTL_ENDTRANSACTION: - result = smartcard_EndTransaction_Call(smartcard, operation, (HCardAndDisposition_Call*) call); + result = smartcard_EndTransaction_Call(smartcard, operation); break; case SCARD_IOCTL_STATE: - result = smartcard_State_Call(smartcard, operation, (State_Call*) call); + result = smartcard_State_Call(smartcard, operation); break; case SCARD_IOCTL_STATUSA: - result = smartcard_StatusA_Call(smartcard, operation, (Status_Call*) call); + result = smartcard_StatusA_Call(smartcard, operation); break; case SCARD_IOCTL_STATUSW: - result = smartcard_StatusW_Call(smartcard, operation, (Status_Call*) call); + result = smartcard_StatusW_Call(smartcard, operation); break; case SCARD_IOCTL_TRANSMIT: - result = smartcard_Transmit_Call(smartcard, operation, (Transmit_Call*) call); + result = smartcard_Transmit_Call(smartcard, operation); break; case SCARD_IOCTL_CONTROL: - result = smartcard_Control_Call(smartcard, operation, (Control_Call*) call); + result = smartcard_Control_Call(smartcard, operation); break; case SCARD_IOCTL_GETATTRIB: - result = smartcard_GetAttrib_Call(smartcard, operation, (GetAttrib_Call*) call); + result = smartcard_GetAttrib_Call(smartcard, operation); break; case SCARD_IOCTL_SETATTRIB: @@ -1855,11 +1947,11 @@ break; case SCARD_IOCTL_ACCESSSTARTEDEVENT: - result = smartcard_AccessStartedEvent_Call(smartcard, operation, (Long_Call*) call); + result = smartcard_AccessStartedEvent_Call(smartcard, operation); break; case SCARD_IOCTL_LOCATECARDSBYATRA: - result = smartcard_LocateCardsByATRA_Call(smartcard, operation, (LocateCardsByATRA_Call*) call); + result = smartcard_LocateCardsByATRA_Call(smartcard, operation); break; case SCARD_IOCTL_LOCATECARDSBYATRW: @@ -1903,7 +1995,8 @@ break; } - free(call); + free(operation->call); + operation->call = NULL; /** * [MS-RPCE] 2.2.6.3 Primitive Type Serialization @@ -1912,18 +2005,19 @@ */ if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) && - (ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT)) + (ioControlCode != SCARD_IOCTL_RELEASESTARTEDEVENT)) { offset = (RDPDR_DEVICE_IO_RESPONSE_LENGTH + RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH); - smartcard_pack_write_size_align(smartcard, irp->output, Stream_GetPosition(irp->output) - offset, 8); + smartcard_pack_write_size_align(smartcard, irp->output, Stream_GetPosition(irp->output) - offset, + 8); } if ((result != SCARD_S_SUCCESS) && (result != SCARD_E_TIMEOUT) && - (result != SCARD_E_NO_READERS_AVAILABLE) && (result != SCARD_E_NO_SERVICE)) + (result != SCARD_E_NO_READERS_AVAILABLE) && (result != SCARD_E_NO_SERVICE)) { WLog_WARN(TAG, "IRP failure: %s (0x%08"PRIX32"), status: %s (0x%08"PRIX32")", - smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, - SCardGetErrorString(result), result); + smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, + SCardGetErrorString(result), result); } irp->IoStatus = 0; @@ -1934,22 +2028,25 @@ irp->IoStatus = (UINT32)result; Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH); WLog_WARN(TAG, "IRP failure: %s (0x%08"PRIX32"), ntstatus: 0x%08"PRIX32"", - smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result); + smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result); } Stream_SealLength(irp->output); outputBufferLength = Stream_Length(irp->output) - RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4; objectBufferLength = outputBufferLength - RDPDR_DEVICE_IO_RESPONSE_LENGTH; Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH); - /* Device Control Response */ Stream_Write_UINT32(irp->output, outputBufferLength); /* OutputBufferLength (4 bytes) */ - if ((result = smartcard_pack_common_type_header(smartcard, irp->output))) /* CommonTypeHeader (8 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 %"PRId32"", result); return result; } - if ((result = smartcard_pack_private_type_header(smartcard, irp->output, objectBufferLength))) /* PrivateTypeHeader (8 bytes) */ + + 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 %"PRId32"", result); return result; @@ -1957,7 +2054,6 @@ Stream_Write_UINT32(irp->output, result); /* Result (4 bytes) */ Stream_SetPosition(irp->output, Stream_Length(irp->output)); - return SCARD_S_SUCCESS; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/smartcard/client/smartcard_pack.c freerdp-2.0.0~dev201703030839+dfsg/channels/smartcard/client/smartcard_pack.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/smartcard/client/smartcard_pack.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/smartcard/client/smartcard_pack.c 2017-03-03 08:39:24.000000000 +0000 @@ -38,12 +38,11 @@ if (Stream_GetRemainingLength(s) < 8) { WLog_WARN(TAG, "CommonTypeHeader is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } /* Process CommonTypeHeader */ - Stream_Read_UINT8(s, version); /* Version (1 byte) */ Stream_Read_UINT8(s, endianness); /* Endianness (1 byte) */ Stream_Read_UINT16(s, commonHeaderLength); /* CommonHeaderLength (2 bytes) */ @@ -82,7 +81,6 @@ Stream_Write_UINT8(s, 0x10); /* Endianness (1 byte) */ Stream_Write_UINT16(s, 8); /* CommonHeaderLength (2 bytes) */ Stream_Write_UINT32(s, 0xCCCCCCCC); /* Filler (4 bytes), should be 0xCCCCCCCC */ - return SCARD_S_SUCCESS; } @@ -94,7 +92,7 @@ if (Stream_GetRemainingLength(s) < 8) { WLog_WARN(TAG, "PrivateTypeHeader is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -109,26 +107,27 @@ if (objectBufferLength != Stream_GetRemainingLength(s)) { - WLog_WARN(TAG, "PrivateTypeHeader ObjectBufferLength mismatch: Actual: %"PRIu32", Expected: %"PRIuz"", - objectBufferLength, Stream_GetRemainingLength(s)); + WLog_WARN(TAG, + "PrivateTypeHeader ObjectBufferLength mismatch: Actual: %"PRIu32", Expected: %"PRIuz"", + objectBufferLength, Stream_GetRemainingLength(s)); return STATUS_INVALID_PARAMETER; } return SCARD_S_SUCCESS; } -LONG smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 objectBufferLength) +LONG smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, + UINT32 objectBufferLength) { Stream_Write_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */ Stream_Write_UINT32(s, 0x00000000); /* Filler (4 bytes), should be 0x00000000 */ - return SCARD_S_SUCCESS; } -LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment) +LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, + UINT32 alignment) { UINT32 pad; - pad = size; size = (size + alignment - 1) & ~(alignment - 1); pad = size - pad; @@ -139,10 +138,10 @@ return pad; } -LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment) +LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, + UINT32 alignment) { UINT32 pad; - pad = size; size = (size + alignment - 1) & ~(alignment - 1); pad = size - pad; @@ -154,20 +153,23 @@ WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return SCARD_F_INTERNAL_ERROR; } + Stream_Zero(s, pad); } return SCARD_S_SUCCESS; } -SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDCONTEXT* context) +SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard, + REDIR_SCARDCONTEXT* context) { SCARDCONTEXT hContext = 0; if ((context->cbContext != sizeof(ULONG_PTR)) && (context->cbContext != 0)) { - WLog_WARN(TAG, "REDIR_SCARDCONTEXT does not match native size: Actual: %"PRIu32", Expected: %"PRIuz"", - context->cbContext, sizeof(ULONG_PTR)); + WLog_WARN(TAG, + "REDIR_SCARDCONTEXT does not match native size: Actual: %"PRIu32", Expected: %"PRIuz"", + context->cbContext, sizeof(ULONG_PTR)); return 0; } @@ -179,21 +181,24 @@ return hContext; } -void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext) +void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard, + REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext) { ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT)); context->cbContext = sizeof(ULONG_PTR); CopyMemory(&(context->pbContext), &hContext, context->cbContext); } -SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle) +SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard, + REDIR_SCARDHANDLE* handle) { SCARDHANDLE hCard = 0; if (handle->cbHandle != sizeof(ULONG_PTR)) { - WLog_WARN(TAG, "REDIR_SCARDHANDLE does not match native size: Actual: %"PRIu32", Expected: %"PRIuz"", - handle->cbHandle, sizeof(ULONG_PTR)); + WLog_WARN(TAG, + "REDIR_SCARDHANDLE does not match native size: Actual: %"PRIu32", Expected: %"PRIuz"", + handle->cbHandle, sizeof(ULONG_PTR)); return 0; } @@ -203,23 +208,24 @@ return hCard; } -void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle, SCARDHANDLE hCard) +void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle, + SCARDHANDLE hCard) { ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE)); handle->cbHandle = sizeof(ULONG_PTR); CopyMemory(&(handle->pbHandle), &hCard, handle->cbHandle); } -LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context) +LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context) { UINT32 pbContextNdrPtr; - ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT)); if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -228,7 +234,7 @@ if (Stream_GetRemainingLength(s) < context->cbContext) { WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: Actual: %"PRIuz", Expected: %"PRIu32"", - Stream_GetRemainingLength(s), context->cbContext); + Stream_GetRemainingLength(s), context->cbContext); return STATUS_BUFFER_TOO_SMALL; } @@ -240,36 +246,36 @@ Stream_Read_UINT32(s, pbContextNdrPtr); /* pbContextNdrPtr (4 bytes) */ - if (((context->cbContext == 0) && pbContextNdrPtr) || ((context->cbContext != 0) && !pbContextNdrPtr)) + if (((context->cbContext == 0) && pbContextNdrPtr) || ((context->cbContext != 0) && + !pbContextNdrPtr)) { WLog_WARN(TAG, "REDIR_SCARDCONTEXT cbContext (%"PRIu32") pbContextNdrPtr (%"PRIu32") inconsistency", - context->cbContext, pbContextNdrPtr); + context->cbContext, pbContextNdrPtr); return STATUS_INVALID_PARAMETER; } if (context->cbContext > Stream_GetRemainingLength(s)) { WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too long: Actual: %"PRIuz", Expected: %"PRIu32"", - Stream_GetRemainingLength(s), context->cbContext); + Stream_GetRemainingLength(s), context->cbContext); return STATUS_INVALID_PARAMETER; } return SCARD_S_SUCCESS; } -LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context) +LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context) { UINT32 pbContextNdrPtr; - pbContextNdrPtr = (context->cbContext) ? 0x00020001 : 0; - Stream_Write_UINT32(s, context->cbContext); /* cbContext (4 bytes) */ Stream_Write_UINT32(s, pbContextNdrPtr); /* pbContextNdrPtr (4 bytes) */ - return SCARD_S_SUCCESS; } -LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context) +LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context) { UINT32 length; @@ -279,7 +285,7 @@ if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: Actual: %"PRIuz", Expected: 4", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -288,7 +294,7 @@ if (length != context->cbContext) { WLog_WARN(TAG, "REDIR_SCARDCONTEXT length (%"PRIu32") cbContext (%"PRIu32") mismatch", - length, context->cbContext); + length, context->cbContext); return STATUS_INVALID_PARAMETER; } @@ -301,7 +307,7 @@ if (Stream_GetRemainingLength(s) < context->cbContext) { WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: Actual: %"PRIuz", Expected: %"PRIu32"", - Stream_GetRemainingLength(s), context->cbContext); + Stream_GetRemainingLength(s), context->cbContext); return STATUS_BUFFER_TOO_SMALL; } @@ -313,7 +319,8 @@ return SCARD_S_SUCCESS; } -LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context) +LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context) { Stream_Write_UINT32(s, context->cbContext); /* Length (4 bytes) */ @@ -325,16 +332,16 @@ return SCARD_S_SUCCESS; } -LONG smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle) +LONG smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle) { UINT32 pbHandleNdrPtr; - ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE)); if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "SCARDHANDLE is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -343,35 +350,33 @@ if ((Stream_GetRemainingLength(s) < handle->cbHandle) || (!handle->cbHandle)) { WLog_WARN(TAG, "SCARDHANDLE is too short: Actual: %"PRIuz", Expected: %"PRIu32"", - Stream_GetRemainingLength(s), handle->cbHandle); + Stream_GetRemainingLength(s), handle->cbHandle); return STATUS_BUFFER_TOO_SMALL; } Stream_Read_UINT32(s, pbHandleNdrPtr); /* NdrPtr (4 bytes) */ - return SCARD_S_SUCCESS; } -LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle) +LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle) { UINT32 pbHandleNdrPtr; - pbHandleNdrPtr = (handle->cbHandle) ? 0x00020002 : 0; - Stream_Write_UINT32(s, handle->cbHandle); /* cbHandle (4 bytes) */ Stream_Write_UINT32(s, pbHandleNdrPtr); /* pbHandleNdrPtr (4 bytes) */ - return SCARD_S_SUCCESS; } -LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle) +LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle) { UINT32 length; if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "REDIR_SCARDHANDLE is too short: Actual: %"PRIuz", Expected: 4", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -380,7 +385,7 @@ if (length != handle->cbHandle) { WLog_WARN(TAG, "REDIR_SCARDHANDLE length (%"PRIu32") cbHandle (%"PRIu32") mismatch", - length, handle->cbHandle); + length, handle->cbHandle); return STATUS_INVALID_PARAMETER; } @@ -393,7 +398,7 @@ if ((Stream_GetRemainingLength(s) < handle->cbHandle) || (!handle->cbHandle)) { WLog_WARN(TAG, "REDIR_SCARDHANDLE is too short: Actual: %"PRIuz", Expected: %"PRIu32"", - Stream_GetRemainingLength(s), handle->cbHandle); + Stream_GetRemainingLength(s), handle->cbHandle); return STATUS_BUFFER_TOO_SMALL; } @@ -403,7 +408,8 @@ return SCARD_S_SUCCESS; } -LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle) +LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle) { Stream_Write_UINT32(s, handle->cbHandle); /* Length (4 bytes) */ @@ -413,34 +419,34 @@ return SCARD_S_SUCCESS; } -LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Call* call) +LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, + EstablishContext_Call* call) { if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "EstablishContext_Call is too short: Actual: %"PRIuz", Expected: 4", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } Stream_Read_UINT32(s, call->dwScope); /* dwScope (4 bytes) */ - return SCARD_S_SUCCESS; } -void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, EstablishContext_Call* call) +void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, + EstablishContext_Call* call) { if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) return; WLog_DBG(TAG, "EstablishContext_Call {"); - WLog_DBG(TAG, "dwScope: %s (0x%08"PRIX32")", - SCardGetScopeString(call->dwScope), call->dwScope); - + SCardGetScopeString(call->dwScope), call->dwScope); WLog_DBG(TAG, "}"); } -LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Return* ret) +LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s, + EstablishContext_Return* ret) { LONG status; @@ -456,7 +462,8 @@ return status; } -void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard, EstablishContext_Return* ret) +void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard, + EstablishContext_Return* ret) { BYTE* pb; @@ -464,21 +471,20 @@ return; WLog_DBG(TAG, "EstablishContext_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); - - pb = (BYTE*) &(ret->hContext.pbContext); + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + pb = (BYTE*) & (ret->hContext.pbContext); if (ret->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], ret->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], ret->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], ret->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], ret->hContext.cbContext); } WLog_DBG(TAG, "}"); @@ -508,18 +514,18 @@ return; WLog_DBG(TAG, "%s_Call {", name); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } WLog_DBG(TAG, "}"); @@ -531,19 +537,131 @@ return; WLog_DBG(TAG, "%s_Return {", name); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_DBG(TAG, "}"); +} + +LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStream* s, + ListReaderGroups_Call* call) +{ + LONG status; + status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)); + + if (status) + return status; + + if (Stream_GetRemainingLength(s) < 8) + { + WLog_WARN(TAG, "ListReaderGroups_Call is too short: %d", + (int) Stream_GetRemainingLength(s)); + return STATUS_BUFFER_TOO_SMALL; + } + + Stream_Read_UINT32(s, call->fmszGroupsIsNULL); /* fmszGroupsIsNULL (4 bytes) */ + Stream_Read_UINT32(s, call->cchGroups); /* cchGroups (4 bytes) */ + status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->hContext)); + + if (status) + return status; + + return SCARD_S_SUCCESS; +} + +void smartcard_trace_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, + ListReaderGroups_Call* call, BOOL unicode) +{ + BYTE* pb; + + if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + return; + + WLog_DBG(TAG, "ListReaderGroups%S_Call {", unicode ? "W" : "A"); + pb = (BYTE*) & (call->hContext.pbContext); + + if (call->hContext.cbContext > 4) + { + WLog_DBG(TAG, + "hContext: 0x%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + } + else + { + WLog_DBG(TAG, "hContext: 0x%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + } + + WLog_DBG(TAG, "fmszGroupsIsNULL: %"PRId32" cchGroups: 0x%08"PRIx32, + call->fmszGroupsIsNULL, call->cchGroups); + WLog_DBG(TAG, "}"); +} + +LONG smartcard_pack_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, wStream* s, + ListReaderGroups_Return* ret) +{ + UINT32 mszNdrPtr; + mszNdrPtr = (ret->cBytes) ? 0x00020008 : 0; + Stream_EnsureRemainingCapacity(s, ret->cBytes + 32); + Stream_Write_UINT32(s, ret->cBytes); /* cBytes (4 bytes) */ + Stream_Write_UINT32(s, mszNdrPtr); /* mszNdrPtr (4 bytes) */ + + if (mszNdrPtr) + { + Stream_Write_UINT32(s, ret->cBytes); /* mszNdrLen (4 bytes) */ + + if (ret->msz) + Stream_Write(s, ret->msz, ret->cBytes); + else + Stream_Zero(s, ret->cBytes); + + smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4); + } + + return SCARD_S_SUCCESS; +} +void smartcard_trace_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, + ListReaderGroups_Return* ret, BOOL unicode) +{ + int index; + int length; + char* mszA = NULL; + + if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) + return; + + if (unicode) + { + length = ret->cBytes / 2; + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) ret->msz, length, &mszA, 0, NULL, NULL); + } + else + { + length = ret->cBytes; + mszA = (char*) malloc(length); + CopyMemory(mszA, ret->msz, ret->cBytes); + } + + for (index = 0; index < length - 2; index++) + { + if (mszA[index] == '\0') + mszA[index] = ','; + } + + WLog_DBG(TAG, "ListReaderGroups%s_Return {", unicode ? "W" : "A"); + WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIx32")", + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + WLog_DBG(TAG, "cBytes: %"PRIu32" msz: %s", ret->cBytes, mszA); WLog_DBG(TAG, "}"); + free(mszA); } -LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Call* call) +LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, + ListReaders_Call* call) { LONG status; UINT32 count; UINT32 mszGroupsNdrPtr; - call->mszGroups = NULL; if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) @@ -555,7 +673,7 @@ if (Stream_GetRemainingLength(s) < 16) { WLog_WARN(TAG, "ListReaders_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -572,46 +690,47 @@ if ((mszGroupsNdrPtr && !call->cBytes) || (!mszGroupsNdrPtr && call->cBytes)) { - WLog_WARN(TAG, "ListReaders_Call mszGroupsNdrPtr (0x%08"PRIX32") and cBytes (0x%08"PRIX32") inconsistency", - mszGroupsNdrPtr, call->cBytes); + WLog_WARN(TAG, + "ListReaders_Call mszGroupsNdrPtr (0x%08"PRIX32") and cBytes (0x%08"PRIX32") inconsistency", + mszGroupsNdrPtr, call->cBytes); return STATUS_INVALID_PARAMETER; } - + if (mszGroupsNdrPtr) { Stream_Read_UINT32(s, count); /* NdrCount (4 bytes) */ - + if (count != call->cBytes) { WLog_WARN(TAG, "ListReaders_Call NdrCount (0x%08"PRIX32") and cBytes (0x%08"PRIX32") inconsistency", - count, call->cBytes); + count, call->cBytes); return STATUS_INVALID_PARAMETER; } - + if (Stream_GetRemainingLength(s) < call->cBytes) { WLog_WARN(TAG, "ListReaders_Call is too short: Actual: %"PRIuz", Expected: %"PRIu32"", - Stream_GetRemainingLength(s), call->cBytes); + Stream_GetRemainingLength(s), call->cBytes); return STATUS_BUFFER_TOO_SMALL; } - + call->mszGroups = (BYTE*) calloc(1, call->cBytes + 4); - + if (!call->mszGroups) { WLog_WARN(TAG, "ListReaders_Call out of memory error (mszGroups)"); return STATUS_NO_MEMORY; } - + Stream_Read(s, call->mszGroups, call->cBytes); - smartcard_unpack_read_size_align(smartcard, s, call->cBytes, 4); } return SCARD_S_SUCCESS; } -void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, ListReaders_Call* call, BOOL unicode) +void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, ListReaders_Call* call, + BOOL unicode) { BYTE* pb; char* mszGroupsA = NULL; @@ -620,33 +739,35 @@ return; if (unicode) - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) call->mszGroups, call->cBytes / 2, &mszGroupsA, 0, NULL, NULL); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) call->mszGroups, call->cBytes / 2, &mszGroupsA, 0, NULL, + NULL); WLog_DBG(TAG, "ListReaders%s_Call {", unicode ? "W" : "A"); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } - WLog_DBG(TAG, "cBytes: %"PRIu32" mszGroups: %s fmszReadersIsNULL: %"PRId32" cchReaders: 0x%08"PRIX32"", - call->cBytes, mszGroupsA, call->fmszReadersIsNULL, call->cchReaders); - + WLog_DBG(TAG, + "cBytes: %"PRIu32" mszGroups: %s fmszReadersIsNULL: %"PRId32" cchReaders: 0x%08"PRIX32"", + call->cBytes, mszGroupsA, call->fmszReadersIsNULL, call->cchReaders); WLog_DBG(TAG, "}"); if (unicode) free(mszGroupsA); } -LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Return* ret) +LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, + ListReaders_Return* ret) { UINT32 mszNdrPtr; LONG error; @@ -684,7 +805,8 @@ return SCARD_S_SUCCESS; } -void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, ListReaders_Return* ret, BOOL unicode) +void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, ListReaders_Return* ret, + BOOL unicode) { int index; size_t length; @@ -694,9 +816,8 @@ return; WLog_DBG(TAG, "ListReaders%s_Return {", unicode ? "W" : "A"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); if (ret->ReturnCode != SCARD_S_SUCCESS) { @@ -707,8 +828,9 @@ if (unicode) { length = ret->cBytes / 2; + if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) ret->msz, (int)length, - &mszA, 0, NULL, NULL) < 1) + &mszA, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "ConvertFromUnicode failed"); return; @@ -718,11 +840,13 @@ { length = ret->cBytes; mszA = (char*) malloc(length); + if (!mszA) { WLog_ERR(TAG, "malloc failed!"); return; } + CopyMemory(mszA, ret->msz, ret->cBytes); } @@ -733,20 +857,19 @@ } WLog_DBG(TAG, "cBytes: %"PRIu32" msz: %s", ret->cBytes, mszA); - WLog_DBG(TAG, "}"); - free(mszA); } -LONG smartcard_unpack_connect_common(SMARTCARD_DEVICE* smartcard, wStream* s, Connect_Common* common) +LONG smartcard_unpack_connect_common(SMARTCARD_DEVICE* smartcard, wStream* s, + Connect_Common* common) { LONG status; if (Stream_GetRemainingLength(s) < 8) { WLog_WARN(TAG, "Connect_Common is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -758,7 +881,6 @@ Stream_Read_UINT32(s, common->dwShareMode); /* dwShareMode (4 bytes) */ Stream_Read_UINT32(s, common->dwPreferredProtocols); /* dwPreferredProtocols (4 bytes) */ - return SCARD_S_SUCCESS; } @@ -766,13 +888,12 @@ { LONG status; UINT32 count; - call->szReader = NULL; if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "ConnectA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -785,11 +906,9 @@ } /* szReader */ - Stream_Seek_UINT32(s); /* NdrMaxCount (4 bytes) */ Stream_Seek_UINT32(s); /* NdrOffset (4 bytes) */ Stream_Read_UINT32(s, count); /* NdrActualCount (4 bytes) */ - call->szReader = (unsigned char*) malloc(count + 1); if (!call->szReader) @@ -816,24 +935,24 @@ return; WLog_DBG(TAG, "ConnectA_Call {"); - - pb = (BYTE*) &(call->Common.hContext.pbContext); + pb = (BYTE*) & (call->Common.hContext.pbContext); if (call->Common.hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->Common.hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->Common.hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->Common.hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->Common.hContext.cbContext); } - WLog_DBG(TAG, "szReader: %s dwShareMode: %s (0x%08"PRIX32") dwPreferredProtocols: %s (0x%08"PRIX32")", - call->szReader, SCardGetShareModeString(call->Common.dwShareMode), call->Common.dwShareMode, - SCardGetProtocolString(call->Common.dwPreferredProtocols), call->Common.dwPreferredProtocols); - + WLog_DBG(TAG, + "szReader: %s dwShareMode: %s (0x%08"PRIX32") dwPreferredProtocols: %s (0x%08"PRIX32")", + call->szReader, SCardGetShareModeString(call->Common.dwShareMode), call->Common.dwShareMode, + SCardGetProtocolString(call->Common.dwPreferredProtocols), call->Common.dwPreferredProtocols); WLog_DBG(TAG, "}"); } @@ -841,13 +960,12 @@ { LONG status; UINT32 count; - call->szReader = NULL; if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "ConnectW_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -860,11 +978,9 @@ } /* szReader */ - Stream_Seek_UINT32(s); /* NdrMaxCount (4 bytes) */ Stream_Seek_UINT32(s); /* NdrOffset (4 bytes) */ Stream_Read_UINT32(s, count); /* NdrActualCount (4 bytes) */ - call->szReader = (WCHAR*) malloc((count + 1) * 2); if (!call->szReader) @@ -892,28 +1008,26 @@ return; ConvertFromUnicode(CP_UTF8, 0, call->szReader, -1, &szReaderA, 0, NULL, NULL); - WLog_DBG(TAG, "ConnectW_Call {"); - - pb = (BYTE*) &(call->Common.hContext.pbContext); + pb = (BYTE*) & (call->Common.hContext.pbContext); if (call->Common.hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->Common.hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->Common.hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->Common.hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->Common.hContext.cbContext); } - WLog_DBG(TAG, "szReader: %s dwShareMode: %s (0x%08"PRIX32") dwPreferredProtocols: %s (0x%08"PRIX32")", - szReaderA, SCardGetShareModeString(call->Common.dwShareMode), call->Common.dwShareMode, - SCardGetProtocolString(call->Common.dwPreferredProtocols), call->Common.dwPreferredProtocols); - + WLog_DBG(TAG, + "szReader: %s dwShareMode: %s (0x%08"PRIX32") dwPreferredProtocols: %s (0x%08"PRIX32")", + szReaderA, SCardGetShareModeString(call->Common.dwShareMode), call->Common.dwShareMode, + SCardGetProtocolString(call->Common.dwPreferredProtocols), call->Common.dwPreferredProtocols); WLog_DBG(TAG, "}"); - free(szReaderA); } @@ -955,39 +1069,38 @@ return; WLog_DBG(TAG, "Connect_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); - - pb = (BYTE*) &(ret->hContext.pbContext); + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + pb = (BYTE*) & (ret->hContext.pbContext); if (ret->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], ret->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], ret->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], ret->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], ret->hContext.cbContext); } - pb = (BYTE*) &(ret->hCard.pbHandle); + pb = (BYTE*) & (ret->hCard.pbHandle); if (ret->hCard.cbHandle > 4) { - WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], ret->hCard.cbHandle); + WLog_DBG(TAG, + "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], ret->hCard.cbHandle); } else { WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], ret->hCard.cbHandle); + pb[0], pb[1], pb[2], pb[3], ret->hCard.cbHandle); } WLog_DBG(TAG, "dwActiveProtocol: %s (0x%08"PRIX32")", - SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol); - + SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol); WLog_DBG(TAG, "}"); } @@ -1007,11 +1120,10 @@ return status; } - if (Stream_GetRemainingLength(s) < 12) { WLog_WARN(TAG, "Reconnect_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1039,45 +1151,45 @@ return; WLog_DBG(TAG, "Reconnect_Call {"); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } - pb = (BYTE*) &(call->hCard.pbHandle); + pb = (BYTE*) & (call->hCard.pbHandle); if (call->hCard.cbHandle > 4) { - WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); + WLog_DBG(TAG, + "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); } else { WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); + pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); } - WLog_DBG(TAG, "dwShareMode: %s (0x%08"PRIX32") dwPreferredProtocols: %s (0x%08"PRIX32") dwInitialization: %s (0x%08"PRIX32")", - SCardGetShareModeString(call->dwShareMode), call->dwShareMode, - SCardGetProtocolString(call->dwPreferredProtocols), call->dwPreferredProtocols, - SCardGetDispositionString(call->dwInitialization), call->dwInitialization); - + WLog_DBG(TAG, + "dwShareMode: %s (0x%08"PRIX32") dwPreferredProtocols: %s (0x%08"PRIX32") dwInitialization: %s (0x%08"PRIX32")", + SCardGetShareModeString(call->dwShareMode), call->dwShareMode, + SCardGetProtocolString(call->dwPreferredProtocols), call->dwPreferredProtocols, + SCardGetDispositionString(call->dwInitialization), call->dwInitialization); WLog_DBG(TAG, "}"); } LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Return* ret) { Stream_Write_UINT32(s, ret->dwActiveProtocol); /* dwActiveProtocol (4 bytes) */ - return SCARD_S_SUCCESS; } @@ -1087,17 +1199,15 @@ return; WLog_DBG(TAG, "Reconnect_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); - + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); WLog_DBG(TAG, "dwActiveProtocol: %s (0x%08"PRIX32")", - SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol); - + SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol); WLog_DBG(TAG, "}"); } -LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s, HCardAndDisposition_Call* call) +LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s, + HCardAndDisposition_Call* call) { LONG status; @@ -1116,7 +1226,7 @@ if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "HCardAndDisposition_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1134,7 +1244,8 @@ return status; } -void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, HCardAndDisposition_Call* call, const char* name) +void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, + HCardAndDisposition_Call* call, const char* name) { BYTE* pb; @@ -1142,40 +1253,41 @@ return; WLog_DBG(TAG, "%s_Call {", name); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } - pb = (BYTE*) &(call->hCard.pbHandle); + pb = (BYTE*) & (call->hCard.pbHandle); if (call->hCard.cbHandle > 4) { - WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); + WLog_DBG(TAG, + "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); } else { WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); + pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); } WLog_DBG(TAG, "dwDisposition: %s (0x%08"PRIX32")", - SCardGetDispositionString(call->dwDisposition), call->dwDisposition); - + SCardGetDispositionString(call->dwDisposition), call->dwDisposition); WLog_DBG(TAG, "}"); } -LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeA_Call* call) +LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, + GetStatusChangeA_Call* call) { UINT32 index; UINT32 count; @@ -1185,7 +1297,6 @@ UINT32 szReaderNdrPtr; UINT32 rgReaderStatesNdrPtr; LPSCARD_READERSTATEA readerState; - call->rgReaderStates = NULL; if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) @@ -1197,7 +1308,7 @@ if (Stream_GetRemainingLength(s) < 12) { WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1214,7 +1325,7 @@ if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1222,8 +1333,9 @@ if (count != call->cReaders) { - WLog_WARN(TAG, "GetStatusChangeA_Call unexpected reader count: Actual: %"PRIu32", Expected: %"PRIu32"", - count, call->cReaders); + WLog_WARN(TAG, + "GetStatusChangeA_Call unexpected reader count: Actual: %"PRIu32", Expected: %"PRIu32"", + count, call->cReaders); return STATUS_INVALID_PARAMETER; } @@ -1244,7 +1356,7 @@ if (Stream_GetRemainingLength(s) < 52) { WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1263,7 +1375,7 @@ if (Stream_GetRemainingLength(s) < 12) { WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1274,7 +1386,7 @@ if (Stream_GetRemainingLength(s) < count) { WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1301,7 +1413,8 @@ return SCARD_S_SUCCESS; } -void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, GetStatusChangeA_Call* call) +void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, + GetStatusChangeA_Call* call) { BYTE* pb; UINT32 index; @@ -1313,39 +1426,34 @@ return; WLog_DBG(TAG, "GetStatusChangeA_Call {"); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } WLog_DBG(TAG, "dwTimeOut: 0x%08"PRIX32" cReaders: %"PRIu32"", - call->dwTimeOut, call->cReaders); + call->dwTimeOut, call->cReaders); for (index = 0; index < call->cReaders; index++) { readerState = &call->rgReaderStates[index]; - WLog_DBG(TAG, "\t[%"PRIu32"]: szReader: %s cbAtr: %"PRIu32"", - index, readerState->szReader, readerState->cbAtr); - + index, readerState->szReader, readerState->cbAtr); szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState); szEventState = SCardGetReaderStateString(readerState->dwEventState); - WLog_DBG(TAG, "\t[%"PRIu32"]: dwCurrentState: %s (0x%08"PRIX32")", - index, szCurrentState, readerState->dwCurrentState); - + index, szCurrentState, readerState->dwCurrentState); WLog_DBG(TAG, "\t[%"PRIu32"]: dwEventState: %s (0x%08"PRIX32")", - index, szEventState, readerState->dwEventState); - + index, szEventState, readerState->dwEventState); free(szCurrentState); free(szEventState); } @@ -1353,7 +1461,8 @@ WLog_DBG(TAG, "}"); } -LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeW_Call* call) +LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, + GetStatusChangeW_Call* call) { UINT32 index; UINT32 count; @@ -1363,7 +1472,6 @@ UINT32 szReaderNdrPtr; UINT32 rgReaderStatesNdrPtr; LPSCARD_READERSTATEW readerState; - call->rgReaderStates = NULL; if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) @@ -1375,7 +1483,7 @@ if (Stream_GetRemainingLength(s) < 12) { WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1392,7 +1500,7 @@ if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1415,7 +1523,7 @@ if (Stream_GetRemainingLength(s) < 52) { WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1434,7 +1542,7 @@ if (Stream_GetRemainingLength(s) < 12) { WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1445,7 +1553,7 @@ if (Stream_GetRemainingLength(s) < (count * 2)) { WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1472,7 +1580,8 @@ return SCARD_S_SUCCESS; } -void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, GetStatusChangeW_Call* call) +void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, + GetStatusChangeW_Call* call) { BYTE* pb; UINT32 index; @@ -1484,57 +1593,49 @@ return; WLog_DBG(TAG, "GetStatusChangeW_Call {"); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } WLog_DBG(TAG, "dwTimeOut: 0x%08"PRIX32" cReaders: %"PRIu32"", - call->dwTimeOut, call->cReaders); + call->dwTimeOut, call->cReaders); for (index = 0; index < call->cReaders; index++) { char* szReaderA = NULL; - readerState = &call->rgReaderStates[index]; - ConvertFromUnicode(CP_UTF8, 0, readerState->szReader, -1, &szReaderA, 0, NULL, NULL); - WLog_DBG(TAG, "\t[%"PRIu32"]: szReader: %s cbAtr: %"PRIu32"", - index, szReaderA, readerState->cbAtr); - + index, szReaderA, readerState->cbAtr); szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState); szEventState = SCardGetReaderStateString(readerState->dwEventState); - WLog_DBG(TAG, "\t[%"PRIu32"]: dwCurrentState: %s (0x%08"PRIX32")", - index, szCurrentState, readerState->dwCurrentState); - + index, szCurrentState, readerState->dwCurrentState); WLog_DBG(TAG, "\t[%"PRIu32"]: dwEventState: %s (0x%08"PRIX32")", - index, szEventState, readerState->dwEventState); - + index, szEventState, readerState->dwEventState); free(szCurrentState); free(szEventState); - free(szReaderA); } WLog_DBG(TAG, "}"); } -LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChange_Return* ret) +LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, + GetStatusChange_Return* ret) { UINT32 index; ReaderState_Return* rgReaderState; - Stream_Write_UINT32(s, ret->cReaders); /* cReaders (4 bytes) */ Stream_Write_UINT32(s, 0x00020100); /* rgReaderStatesNdrPtr (4 bytes) */ Stream_Write_UINT32(s, ret->cReaders); /* rgReaderStatesNdrCount (4 bytes) */ @@ -1552,7 +1653,8 @@ return SCARD_S_SUCCESS; } -void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard, GetStatusChange_Return* ret, BOOL unicode) +void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard, + GetStatusChange_Return* ret, BOOL unicode) { UINT32 index; char* rgbAtr; @@ -1564,29 +1666,22 @@ return; WLog_DBG(TAG, "GetStatusChange%s_Return {", unicode ? "W" : "A"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); - + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); WLog_DBG(TAG, "cReaders: %"PRIu32"", ret->cReaders); for (index = 0; index < ret->cReaders; index++) { rgReaderState = &(ret->rgReaderStates[index]); - szCurrentState = SCardGetReaderStateString(rgReaderState->dwCurrentState); szEventState = SCardGetReaderStateString(rgReaderState->dwEventState); - rgbAtr = winpr_BinToHexString((BYTE*) &(rgReaderState->rgbAtr), rgReaderState->cbAtr, FALSE); - + rgbAtr = winpr_BinToHexString((BYTE*) & (rgReaderState->rgbAtr), rgReaderState->cbAtr, FALSE); WLog_DBG(TAG, "\t[%"PRIu32"]: dwCurrentState: %s (0x%08"PRIX32")", - index, szCurrentState, rgReaderState->dwCurrentState); - + index, szCurrentState, rgReaderState->dwCurrentState); WLog_DBG(TAG, "\t[%"PRIu32"]: dwEventState: %s (0x%08"PRIX32")", - index, szEventState, rgReaderState->dwEventState); - + index, szEventState, rgReaderState->dwEventState); WLog_DBG(TAG, "\t[%"PRIu32"]: cbAtr: %"PRIu32" rgbAtr: %s", - index, rgReaderState->cbAtr, rgbAtr); - + index, rgReaderState->cbAtr, rgbAtr); free(szCurrentState); free(szEventState); free(rgbAtr); @@ -1614,7 +1709,7 @@ if (Stream_GetRemainingLength(s) < 8) { WLog_WARN(TAG, "State_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1636,7 +1731,6 @@ LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, State_Return* ret) { LONG status; - Stream_Write_UINT32(s, ret->dwState); /* dwState (4 bytes) */ Stream_Write_UINT32(s, ret->dwProtocol); /* dwProtocol (4 bytes) */ Stream_Write_UINT32(s, ret->cbAtrLen); /* cbAtrLen (4 bytes) */ @@ -1669,7 +1763,7 @@ if (Stream_GetRemainingLength(s) < 12) { WLog_WARN(TAG, "Status_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1697,42 +1791,43 @@ return; WLog_DBG(TAG, "Status%s_Call {", unicode ? "W" : "A"); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } - pb = (BYTE*) &(call->hCard.pbHandle); + pb = (BYTE*) & (call->hCard.pbHandle); if (call->hCard.cbHandle > 4) { - WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); + WLog_DBG(TAG, + "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); } else { WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); + pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); } WLog_DBG(TAG, "fmszReaderNamesIsNULL: %"PRId32" cchReaderLen: %"PRIu32" cbAtrLen: %"PRIu32"", - call->fmszReaderNamesIsNULL, call->cchReaderLen, call->cbAtrLen); - + call->fmszReaderNamesIsNULL, call->cchReaderLen, call->cbAtrLen); WLog_DBG(TAG, "}"); } LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Return* ret) { LONG status; + if (!Stream_EnsureRemainingCapacity(s, ret->cBytes + 64)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); @@ -1745,14 +1840,13 @@ Stream_Write_UINT32(s, ret->dwProtocol); /* dwProtocol (4 bytes) */ Stream_Write(s, ret->pbAtr, 32); /* pbAtr (32 bytes) */ Stream_Write_UINT32(s, ret->cbAtrLen); /* cbAtrLen (4 bytes) */ - Stream_Write_UINT32(s, ret->cBytes); /* mszReaderNamesNdrLen (4 bytes) */ - + if (ret->mszReaderNames) Stream_Write(s, ret->mszReaderNames, ret->cBytes); else 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 %"PRId32"", status); @@ -1772,8 +1866,9 @@ if (unicode) { length = ret->cBytes / 2; + if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) ret->mszReaderNames, (int)length, - &mszReaderNamesA, 0, NULL, NULL) < 1) + &mszReaderNamesA, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "ConvertFromUnicode failed"); return; @@ -1783,11 +1878,13 @@ { length = (int) ret->cBytes; mszReaderNamesA = (char*) malloc(length); + if (!mszReaderNamesA) { WLog_ERR(TAG, "malloc failed!"); return; } + CopyMemory(mszReaderNamesA, ret->mszReaderNames, ret->cBytes); } @@ -1804,26 +1901,21 @@ } pbAtr = winpr_BinToHexString(ret->pbAtr, ret->cbAtrLen, FALSE); - WLog_DBG(TAG, "Status%s_Return {", unicode ? "W" : "A"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); - + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); WLog_DBG(TAG, "dwState: %s (0x%08"PRIX32") dwProtocol: %s (0x%08"PRIX32")", - SCardGetCardStateString(ret->dwState), ret->dwState, - SCardGetProtocolString(ret->dwProtocol), ret->dwProtocol); + SCardGetCardStateString(ret->dwState), ret->dwState, + SCardGetProtocolString(ret->dwProtocol), ret->dwProtocol); if (mszReaderNamesA) { WLog_DBG(TAG, "cBytes: %"PRIu32" mszReaderNames: %s", - ret->cBytes, mszReaderNamesA); + ret->cBytes, mszReaderNamesA); } WLog_DBG(TAG, "cbAtrLen: %"PRIu32" pbAtr: %s", ret->cbAtrLen, pbAtr); - WLog_DBG(TAG, "}"); - free(mszReaderNamesA); free(pbAtr); } @@ -1847,7 +1939,7 @@ if (Stream_GetRemainingLength(s) < 12) { WLog_WARN(TAG, "GetAttrib_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -1875,42 +1967,44 @@ return; WLog_DBG(TAG, "GetAttrib_Call {"); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } - pb = (BYTE*) &(call->hCard.pbHandle); + pb = (BYTE*) & (call->hCard.pbHandle); if (call->hCard.cbHandle > 4) { - WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); + WLog_DBG(TAG, + "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); } else { WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); + pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); } WLog_DBG(TAG, "dwAttrId: %s (0x%08"PRIX32") fpbAttrIsNULL: %"PRId32" cbAttrLen: 0x%08"PRIX32"", - SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->fpbAttrIsNULL, call->cbAttrLen); - + SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->fpbAttrIsNULL, call->cbAttrLen); WLog_DBG(TAG, "}"); } -LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Return* ret) +LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, + GetAttrib_Return* ret) { LONG status; + if (!Stream_EnsureRemainingCapacity(s, ret->cbAttrLen + 32)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); @@ -1932,18 +2026,17 @@ return status; } -void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, GetAttrib_Return* ret, DWORD dwAttrId) +void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, GetAttrib_Return* ret, + DWORD dwAttrId) { if (!WLog_IsLevelActive(WLog_Get(TAG), WLOG_DEBUG)) return; WLog_DBG(TAG, "GetAttrib_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); - + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); WLog_DBG(TAG, "dwAttrId: %s (0x%08"PRIX32") cbAttrLen: 0x%08"PRIX32"", - SCardGetAttributeString(dwAttrId), dwAttrId, ret->cbAttrLen); + SCardGetAttributeString(dwAttrId), dwAttrId, ret->cbAttrLen); if (dwAttrId == SCARD_ATTR_VENDOR_NAME) { @@ -1953,7 +2046,7 @@ { UINT32 dwProtocolType = *((UINT32*) ret->pbAttr); WLog_DBG(TAG, "dwProtocolType: %s (0x%08"PRIX32")", - SCardGetProtocolString(dwProtocolType), dwProtocolType); + SCardGetProtocolString(dwProtocolType), dwProtocolType); } WLog_DBG(TAG, "}"); @@ -1963,7 +2056,6 @@ { LONG status; UINT32 length; - call->pvInBuffer = NULL; if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) @@ -1981,7 +2073,7 @@ if (Stream_GetRemainingLength(s) < 20) { WLog_WARN(TAG, "Control_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2008,7 +2100,7 @@ if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "Control_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2017,7 +2109,7 @@ if (Stream_GetRemainingLength(s) < length) { WLog_WARN(TAG, "Control_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2030,7 +2122,6 @@ } call->cbInBufferSize = length; - Stream_Read(s, call->pvInBuffer, length); } @@ -2045,35 +2136,37 @@ return; WLog_DBG(TAG, "Control_Call {"); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } - pb = (BYTE*) &(call->hCard.pbHandle); + pb = (BYTE*) & (call->hCard.pbHandle); if (call->hCard.cbHandle > 4) { - WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); + WLog_DBG(TAG, + "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); } else { WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); + pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); } - WLog_DBG(TAG, "dwControlCode: 0x%08"PRIX32" cbInBufferSize: %"PRIu32" fpvOutBufferIsNULL: %"PRId32" cbOutBufferSize: %"PRIu32"", - call->dwControlCode, call->cbInBufferSize, call->fpvOutBufferIsNULL, call->cbOutBufferSize); + WLog_DBG(TAG, + "dwControlCode: 0x%08"PRIX32" cbInBufferSize: %"PRIu32" fpvOutBufferIsNULL: %"PRId32" cbOutBufferSize: %"PRIu32"", + call->dwControlCode, call->cbInBufferSize, call->fpvOutBufferIsNULL, call->cbOutBufferSize); if (call->pvInBuffer) { @@ -2092,6 +2185,7 @@ LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Return* ret) { LONG error; + if (!Stream_EnsureRemainingCapacity(s, ret->cbOutBufferSize + 32)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); @@ -2105,6 +2199,7 @@ if (ret->cbOutBufferSize > 0) { 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 %"PRId32"", error); @@ -2121,10 +2216,8 @@ return; WLog_DBG(TAG, "Control_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); - + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); WLog_DBG(TAG, "cbOutBufferSize: %"PRIu32"", ret->cbOutBufferSize); if (ret->pvOutBuffer) @@ -2151,7 +2244,6 @@ UINT32 pioRecvPciNdrPtr; SCardIO_Request ioSendPci; SCardIO_Request ioRecvPci; - call->pioSendPci = NULL; call->pioRecvPci = NULL; call->pbSendBuffer = NULL; @@ -2171,7 +2263,7 @@ if (Stream_GetRemainingLength(s) < 32) { WLog_WARN(TAG, "Transmit_Call is too short: Actual: %"PRIuz", Expected: 32", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2187,14 +2279,14 @@ if (ioSendPci.cbExtraBytes > 1024) { WLog_WARN(TAG, "Transmit_Call ioSendPci.cbExtraBytes is out of bounds: %"PRIu32" (max: 1024)", - ioSendPci.cbExtraBytes); + ioSendPci.cbExtraBytes); return STATUS_INVALID_PARAMETER; } if (call->cbSendLength > 66560) { WLog_WARN(TAG, "Transmit_Call cbSendLength is out of bounds: %"PRIu32" (max: 66560)", - ioSendPci.cbExtraBytes); + ioSendPci.cbExtraBytes); return STATUS_INVALID_PARAMETER; } @@ -2221,7 +2313,7 @@ if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "Transmit_Call is too short: %"PRIuz" (ioSendPci.pbExtraBytes)", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2229,13 +2321,13 @@ if (Stream_GetRemainingLength(s) < ioSendPci.cbExtraBytes) { - WLog_WARN(TAG, "Transmit_Call is too short: Actual: %"PRIuz", Expected: %"PRIu32" (ioSendPci.cbExtraBytes)", - Stream_GetRemainingLength(s), ioSendPci.cbExtraBytes); + WLog_WARN(TAG, + "Transmit_Call is too short: Actual: %"PRIuz", Expected: %"PRIu32" (ioSendPci.cbExtraBytes)", + Stream_GetRemainingLength(s), ioSendPci.cbExtraBytes); return STATUS_BUFFER_TOO_SMALL; } ioSendPci.pbExtraBytes = Stream_Pointer(s); - call->pioSendPci = (LPSCARD_IO_REQUEST) malloc(sizeof(SCARD_IO_REQUEST) + ioSendPci.cbExtraBytes); if (!call->pioSendPci) @@ -2246,10 +2338,8 @@ call->pioSendPci->dwProtocol = ioSendPci.dwProtocol; call->pioSendPci->cbPciLength = (DWORD)(ioSendPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST)); - pbExtraBytes = &((BYTE*) call->pioSendPci)[sizeof(SCARD_IO_REQUEST)]; Stream_Read(s, pbExtraBytes, ioSendPci.cbExtraBytes); - smartcard_unpack_read_size_align(smartcard, s, ioSendPci.cbExtraBytes, 4); } else @@ -2271,7 +2361,7 @@ if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "Transmit_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2279,15 +2369,16 @@ if (length != call->cbSendLength) { - WLog_WARN(TAG, "Transmit_Call unexpected length: Actual: %"PRIu32", Expected: %"PRIu32" (cbSendLength)", - length, call->cbSendLength); + WLog_WARN(TAG, + "Transmit_Call unexpected length: Actual: %"PRIu32", Expected: %"PRIu32" (cbSendLength)", + length, call->cbSendLength); return STATUS_INVALID_PARAMETER; } if (Stream_GetRemainingLength(s) < call->cbSendLength) { WLog_WARN(TAG, "Transmit_Call is too short: Actual: %"PRIuz", Expected: %"PRIu32" (cbSendLength)", - Stream_GetRemainingLength(s), call->cbSendLength); + Stream_GetRemainingLength(s), call->cbSendLength); return STATUS_BUFFER_TOO_SMALL; } @@ -2300,7 +2391,6 @@ } Stream_Read(s, call->pbSendBuffer, call->cbSendLength); - smartcard_unpack_read_size_align(smartcard, s, call->cbSendLength, 4); } @@ -2309,7 +2399,7 @@ if (Stream_GetRemainingLength(s) < 12) { WLog_WARN(TAG, "Transmit_Call is too short: Actual: %"PRIuz", Expected: 12", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2328,7 +2418,7 @@ if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "Transmit_Call is too short: %"PRIuz" (ioRecvPci.pbExtraBytes)", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2337,26 +2427,27 @@ if (ioRecvPci.cbExtraBytes > 1024) { WLog_WARN(TAG, "Transmit_Call ioRecvPci.cbExtraBytes is out of bounds: %"PRIu32" (max: 1024)", - ioRecvPci.cbExtraBytes); + ioRecvPci.cbExtraBytes); return STATUS_INVALID_PARAMETER; } if (length != ioRecvPci.cbExtraBytes) { - WLog_WARN(TAG, "Transmit_Call unexpected length: Actual: %"PRIu32", Expected: %"PRIu32" (ioRecvPci.cbExtraBytes)", - length, ioRecvPci.cbExtraBytes); + WLog_WARN(TAG, + "Transmit_Call unexpected length: Actual: %"PRIu32", Expected: %"PRIu32" (ioRecvPci.cbExtraBytes)", + length, ioRecvPci.cbExtraBytes); return STATUS_INVALID_PARAMETER; } if (Stream_GetRemainingLength(s) < ioRecvPci.cbExtraBytes) { - WLog_WARN(TAG, "Transmit_Call is too short: Actual: %"PRIuz", Expected: %"PRIu32" (ioRecvPci.cbExtraBytes)", - Stream_GetRemainingLength(s), ioRecvPci.cbExtraBytes); + WLog_WARN(TAG, + "Transmit_Call is too short: Actual: %"PRIuz", Expected: %"PRIu32" (ioRecvPci.cbExtraBytes)", + Stream_GetRemainingLength(s), ioRecvPci.cbExtraBytes); return STATUS_BUFFER_TOO_SMALL; } ioRecvPci.pbExtraBytes = Stream_Pointer(s); - call->pioRecvPci = (LPSCARD_IO_REQUEST) malloc(sizeof(SCARD_IO_REQUEST) + ioRecvPci.cbExtraBytes); if (!call->pioRecvPci) @@ -2367,10 +2458,8 @@ call->pioRecvPci->dwProtocol = ioRecvPci.dwProtocol; call->pioRecvPci->cbPciLength = (DWORD)(ioRecvPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST)); - pbExtraBytes = &((BYTE*) call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; Stream_Read(s, pbExtraBytes, ioRecvPci.cbExtraBytes); - smartcard_unpack_read_size_align(smartcard, s, ioRecvPci.cbExtraBytes, 4); } else @@ -2401,40 +2490,40 @@ return; WLog_DBG(TAG, "Transmit_Call {"); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } - pb = (BYTE*) &(call->hCard.pbHandle); + pb = (BYTE*) & (call->hCard.pbHandle); if (call->hCard.cbHandle > 4) { - WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); + WLog_DBG(TAG, + "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hCard.cbHandle); } else { WLog_DBG(TAG, "hCard: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); + pb[0], pb[1], pb[2], pb[3], call->hCard.cbHandle); } if (call->pioSendPci) { cbExtraBytes = (UINT32)(call->pioSendPci->cbPciLength - sizeof(SCARD_IO_REQUEST)); pbExtraBytes = &((BYTE*) call->pioSendPci)[sizeof(SCARD_IO_REQUEST)]; - WLog_DBG(TAG, "pioSendPci: dwProtocol: %"PRIu32" cbExtraBytes: %"PRIu32"", - call->pioSendPci->dwProtocol, cbExtraBytes); + call->pioSendPci->dwProtocol, cbExtraBytes); if (cbExtraBytes) { @@ -2465,9 +2554,8 @@ { cbExtraBytes = (UINT32)(call->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST)); pbExtraBytes = &((BYTE*) call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; - WLog_DBG(TAG, "pioRecvPci: dwProtocol: %"PRIu32" cbExtraBytes: %"PRIu32"", - call->pioRecvPci->dwProtocol, cbExtraBytes); + call->pioRecvPci->dwProtocol, cbExtraBytes); if (cbExtraBytes) { @@ -2482,8 +2570,7 @@ } WLog_DBG(TAG, "fpbRecvBufferIsNULL: %"PRId32" cbRecvLength: %"PRIu32"", - call->fpbRecvBufferIsNULL, call->cbRecvLength); - + call->fpbRecvBufferIsNULL, call->cbRecvLength); WLog_DBG(TAG, "}"); } @@ -2501,7 +2588,6 @@ pioRecvPciNdrPtr = (ret->pioRecvPci) ? 0x00020000 : 0; pbRecvBufferNdrPtr = (ret->pbRecvBuffer) ? 0x00020004 : 0; - Stream_Write_UINT32(s, pioRecvPciNdrPtr); /* pioRecvPciNdrPtr (4 bytes) */ Stream_Write_UINT32(s, ret->cbRecvLength); /* cbRecvLength (4 bytes) */ Stream_Write_UINT32(s, pbRecvBufferNdrPtr); /* pbRecvBufferNdrPtr (4 bytes) */ @@ -2526,6 +2612,7 @@ { Stream_Write_UINT32(s, cbExtraBytes); /* Length (4 bytes) */ 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 %"PRId32"!", error); @@ -2544,6 +2631,7 @@ Stream_Write_UINT32(s, ret->cbRecvLength); /* pbRecvBufferNdrLen (4 bytes) */ 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 %"PRId32"!", error); @@ -2563,17 +2651,15 @@ return; WLog_DBG(TAG, "Transmit_Return {"); - WLog_DBG(TAG, "ReturnCode: %s (0x%08"PRIX32")", - SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); + SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); if (ret->pioRecvPci) { cbExtraBytes = (UINT32)(ret->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST)); pbExtraBytes = &((BYTE*) ret->pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; - WLog_DBG(TAG, "pioRecvPci: dwProtocol: %"PRIu32" cbExtraBytes: %"PRIu32"", - ret->pioRecvPci->dwProtocol, cbExtraBytes); + ret->pioRecvPci->dwProtocol, cbExtraBytes); if (cbExtraBytes) { @@ -2603,7 +2689,8 @@ WLog_DBG(TAG, "}"); } -LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, LocateCardsByATRA_Call* call) +LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, + LocateCardsByATRA_Call* call) { UINT32 index; UINT32 count; @@ -2614,7 +2701,6 @@ UINT32 rgReaderStatesNdrPtr; UINT32 rgAtrMasksNdrPtr; LPSCARD_READERSTATEA readerState; - call->rgReaderStates = NULL; if ((status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->hContext)))) @@ -2626,7 +2712,7 @@ if (Stream_GetRemainingLength(s) < 16) { WLog_WARN(TAG, "LocateCardsByATRA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2644,14 +2730,15 @@ if (Stream_GetRemainingLength(s) < 4) { WLog_WARN(TAG, "LocateCardsByATRA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs)) { - WLog_WARN(TAG, "LocateCardsByATRA_Call rgAtrMasksNdrPtr (0x%08"PRIX32") and cAtrs (0x%08"PRIX32") inconsistency", - rgAtrMasksNdrPtr, call->cAtrs); + WLog_WARN(TAG, + "LocateCardsByATRA_Call rgAtrMasksNdrPtr (0x%08"PRIX32") and cAtrs (0x%08"PRIX32") inconsistency", + rgAtrMasksNdrPtr, call->cAtrs); return STATUS_INVALID_PARAMETER; } @@ -2661,19 +2748,21 @@ if (count != call->cAtrs) { - WLog_WARN(TAG, "LocateCardsByATRA_Call NdrCount (0x%08"PRIX32") and cAtrs (0x%08"PRIX32") inconsistency", - count, call->cAtrs); + WLog_WARN(TAG, + "LocateCardsByATRA_Call NdrCount (0x%08"PRIX32") and cAtrs (0x%08"PRIX32") inconsistency", + count, call->cAtrs); return STATUS_INVALID_PARAMETER; } if (Stream_GetRemainingLength(s) < call->cAtrs) { WLog_WARN(TAG, "LocateCardsByATRA_Call is too short: Actual: %"PRIuz", Expected: %"PRIu32"", - Stream_GetRemainingLength(s), call->cAtrs); + Stream_GetRemainingLength(s), call->cAtrs); return STATUS_BUFFER_TOO_SMALL; } call->rgAtrMasks = calloc(call->cAtrs, sizeof(SCARD_ATRMASK)); + if (!call->rgAtrMasks) { WLog_WARN(TAG, "LocateCardsByATRA_Call out of memory error (call->rgAtrMasks)"); @@ -2692,8 +2781,9 @@ if (count != call->cReaders) { - WLog_WARN(TAG, "GetStatusChangeA_Call unexpected reader count: Actual: %"PRIu32", Expected: %"PRIu32"", - count, call->cReaders); + WLog_WARN(TAG, + "GetStatusChangeA_Call unexpected reader count: Actual: %"PRIu32", Expected: %"PRIu32"", + count, call->cReaders); return STATUS_INVALID_PARAMETER; } @@ -2714,7 +2804,7 @@ if (Stream_GetRemainingLength(s) < 52) { WLog_WARN(TAG, "LocateCardsByATRA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2733,7 +2823,7 @@ if (Stream_GetRemainingLength(s) < 12) { WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2744,7 +2834,7 @@ if (Stream_GetRemainingLength(s) < count) { WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %"PRIuz"", - Stream_GetRemainingLength(s)); + Stream_GetRemainingLength(s)); return STATUS_BUFFER_TOO_SMALL; } @@ -2771,7 +2861,8 @@ return SCARD_S_SUCCESS; } -void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, LocateCardsByATRA_Call* call) +void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, + LocateCardsByATRA_Call* call) { BYTE* pb; UINT32 index; @@ -2784,51 +2875,48 @@ return; WLog_DBG(TAG, "LocateCardsByATRA_Call {"); - - pb = (BYTE*) &(call->hContext.pbContext); + pb = (BYTE*) & (call->hContext.pbContext); if (call->hContext.cbContext > 4) { - WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); + WLog_DBG(TAG, + "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", + pb[0], pb[1], pb[2], pb[3], pb[4], pb[5], pb[6], pb[7], call->hContext.cbContext); } else { WLog_DBG(TAG, "hContext: 0x%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8" (%"PRIu32")", - pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); + pb[0], pb[1], pb[2], pb[3], call->hContext.cbContext); } for (index = 0; index < call->cReaders; index++) { readerState = (LPSCARD_READERSTATEA) &call->rgReaderStates[index]; - WLog_DBG(TAG, "\t[%"PRIu32"]: szReader: %s cbAtr: %"PRIu32"", - index, readerState->szReader, readerState->cbAtr); - + index, readerState->szReader, readerState->cbAtr); szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState); szEventState = SCardGetReaderStateString(readerState->dwEventState); - rgbAtr = winpr_BinToHexString((BYTE*) &(readerState->rgbAtr), readerState->cbAtr, FALSE); - + rgbAtr = winpr_BinToHexString((BYTE*) & (readerState->rgbAtr), readerState->cbAtr, FALSE); WLog_DBG(TAG, "\t[%"PRIu32"]: dwCurrentState: %s (0x%08"PRIX32")", - index, szCurrentState, readerState->dwCurrentState); - + index, szCurrentState, readerState->dwCurrentState); WLog_DBG(TAG, "\t[%"PRIu32"]: dwEventState: %s (0x%08"PRIX32")", - index, szEventState, readerState->dwEventState); + index, szEventState, readerState->dwEventState); if (rgbAtr) { WLog_DBG(TAG, "\t[%"PRIu32"]: cbAtr: %"PRIu32" rgbAtr: %s", - index, readerState->cbAtr, rgbAtr); + index, readerState->cbAtr, rgbAtr); } else { WLog_DBG(TAG, "\t[%"PRIu32"]: cbAtr: 0 rgbAtr: n/a", - index); + index); } free(szCurrentState); free(szEventState); free(rgbAtr); } + WLog_DBG(TAG, "}"); } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/smartcard/client/smartcard_pack.h freerdp-2.0.0~dev201703030839+dfsg/channels/smartcard/client/smartcard_pack.h --- freerdp-2.0.0~dev201701161718+dfsg/channels/smartcard/client/smartcard_pack.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/smartcard/client/smartcard_pack.h 2017-03-03 08:39:24.000000000 +0000 @@ -55,7 +55,7 @@ { LONG ReturnCode; /* [range] */ DWORD cBytes; - /* [size_is][unique] */ BYTE *msz; + /* [size_is][unique] */ BYTE* msz; } ListReaderGroups_Return; typedef struct _longAndMultiString_Return ListReaders_Return; @@ -68,27 +68,27 @@ typedef struct _ContextAndStringA_Call { REDIR_SCARDCONTEXT hContext; - /* [string] */ unsigned char *sz; + /* [string] */ unsigned char* sz; } ContextAndStringA_Call; typedef struct _ContextAndStringW_Call { REDIR_SCARDCONTEXT hContext; - /* [string] */ WCHAR *sz; + /* [string] */ WCHAR* sz; } ContextAndStringW_Call; typedef struct _ContextAndTwoStringA_Call { REDIR_SCARDCONTEXT hContext; - /* [string] */ unsigned char *sz1; - /* [string] */ unsigned char *sz2; + /* [string] */ unsigned char* sz1; + /* [string] */ unsigned char* sz2; } ContextAndTwoStringA_Call; typedef struct _ContextAndTwoStringW_Call { REDIR_SCARDCONTEXT hContext; - /* [string] */ WCHAR *sz1; - /* [string] */ WCHAR *sz2; + /* [string] */ WCHAR* sz1; + /* [string] */ WCHAR* sz2; } ContextAndTwoStringW_Call; typedef struct _EstablishContext_Call @@ -113,7 +113,7 @@ { REDIR_SCARDCONTEXT hContext; /* [range] */ DWORD cBytes; - /* [size_is][unique] */ BYTE *mszGroups; + /* [size_is][unique] */ BYTE* mszGroups; LONG fmszReadersIsNULL; DWORD cchReaders; } ListReaders_Call; @@ -128,13 +128,13 @@ typedef struct _ReaderStateA { - /* [string] */ unsigned char *szReader; + /* [string] */ unsigned char* szReader; ReaderState_Common_Call Common; } ReaderStateA; typedef struct _ReaderStateW { - /* [string] */ WCHAR *szReader; + /* [string] */ WCHAR* szReader; ReaderState_Common_Call Common; } ReaderStateW; @@ -158,18 +158,18 @@ { REDIR_SCARDCONTEXT hContext; /* [range] */ DWORD cBytes; - /* [size_is] */ BYTE *mszCards; + /* [size_is] */ BYTE* mszCards; /* [range] */ DWORD cReaders; - /* [size_is] */ ReaderStateA *rgReaderStates; + /* [size_is] */ ReaderStateA* rgReaderStates; } LocateCardsA_Call; typedef struct _LocateCardsW_Call { REDIR_SCARDCONTEXT hContext; /* [range] */ DWORD cBytes; - /* [size_is] */ BYTE *mszCards; + /* [size_is] */ BYTE* mszCards; /* [range] */ DWORD cReaders; - /* [size_is] */ ReaderStateW *rgReaderStates; + /* [size_is] */ ReaderStateW* rgReaderStates; } LocateCardsW_Call; typedef struct _LocateCards_ATRMask @@ -183,25 +183,25 @@ { REDIR_SCARDCONTEXT hContext; /* [range] */ DWORD cAtrs; - /* [size_is] */ LocateCards_ATRMask *rgAtrMasks; + /* [size_is] */ LocateCards_ATRMask* rgAtrMasks; /* [range] */ DWORD cReaders; - /* [size_is] */ ReaderStateA *rgReaderStates; + /* [size_is] */ ReaderStateA* rgReaderStates; } LocateCardsByATRA_Call; typedef struct _LocateCardsByATRW_Call { REDIR_SCARDCONTEXT hContext; /* [range] */ DWORD cAtrs; - /* [size_is] */ LocateCards_ATRMask *rgAtrMasks; + /* [size_is] */ LocateCards_ATRMask* rgAtrMasks; /* [range] */ DWORD cReaders; - /* [size_is] */ ReaderStateW *rgReaderStates; + /* [size_is] */ ReaderStateW* rgReaderStates; } LocateCardsByATRW_Call; typedef struct _GetStatusChange_Return { LONG ReturnCode; /* [range] */ DWORD cReaders; - /* [size_is] */ ReaderState_Return *rgReaderStates; + /* [size_is] */ ReaderState_Return* rgReaderStates; } LocateCards_Return; typedef struct _GetStatusChange_Return GetStatusChange_Return; @@ -223,13 +223,13 @@ typedef struct _ConnectA_Call { - /* [string] */ unsigned char *szReader; + /* [string] */ unsigned char* szReader; Connect_Common Common; } ConnectA_Call; typedef struct _ConnectW_Call { - /* [string] */ WCHAR *szReader; + /* [string] */ WCHAR* szReader; Connect_Common Common; } ConnectW_Call; @@ -293,7 +293,7 @@ { LONG ReturnCode; /* [range] */ DWORD cBytes; - /* [size_is][unique] */ BYTE *mszReaderNames; + /* [size_is][unique] */ BYTE* mszReaderNames; DWORD dwState; DWORD dwProtocol; BYTE pbAtr[32]; @@ -304,7 +304,7 @@ { DWORD dwProtocol; /* [range] */ DWORD cbExtraBytes; - /* [size_is][unique] */ BYTE *pbExtraBytes; + /* [size_is][unique] */ BYTE* pbExtraBytes; } SCardIO_Request; typedef struct _Transmit_Call @@ -313,7 +313,7 @@ REDIR_SCARDHANDLE hCard; LPSCARD_IO_REQUEST pioSendPci; /* [range] */ DWORD cbSendLength; - /* [size_is] */ BYTE *pbSendBuffer; + /* [size_is] */ BYTE* pbSendBuffer; /* [unique] */ LPSCARD_IO_REQUEST pioRecvPci; LONG fpbRecvBufferIsNULL; DWORD cbRecvLength; @@ -324,7 +324,7 @@ LONG ReturnCode; /* [unique] */ LPSCARD_IO_REQUEST pioRecvPci; /* [range] */ DWORD cbRecvLength; - /* [size_is][unique] */ BYTE *pbRecvBuffer; + /* [size_is][unique] */ BYTE* pbRecvBuffer; } Transmit_Return; typedef struct _GetTransmitCount_Call @@ -345,7 +345,7 @@ REDIR_SCARDHANDLE hCard; DWORD dwControlCode; /* [range] */ DWORD cbInBufferSize; - /* [size_is][unique] */ BYTE *pvInBuffer; + /* [size_is][unique] */ BYTE* pvInBuffer; LONG fpvOutBufferIsNULL; DWORD cbOutBufferSize; } Control_Call; @@ -354,7 +354,7 @@ { LONG ReturnCode; /* [range] */ DWORD cbOutBufferSize; - /* [size_is][unique] */ BYTE *pvOutBuffer; + /* [size_is][unique] */ BYTE* pvOutBuffer; } Control_Return; typedef struct _GetAttrib_Call @@ -370,7 +370,7 @@ { LONG ReturnCode; /* [range] */ DWORD cbAttrLen; - /* [size_is][unique] */ BYTE *pbAttr; + /* [size_is][unique] */ BYTE* pbAttr; } GetAttrib_Return; typedef struct _SetAttrib_Call @@ -379,13 +379,13 @@ REDIR_SCARDHANDLE hCard; DWORD dwAttrId; /* [range] */ DWORD cbAttrLen; - /* [size_is] */ BYTE *pbAttr; + /* [size_is] */ BYTE* pbAttr; } SetAttrib_Call; typedef struct _ReadCache_Common { REDIR_SCARDCONTEXT hContext; - UUID *CardIdentifier; + UUID* CardIdentifier; DWORD FreshnessCounter; LONG fPbDataIsNULL; DWORD cbDataLen; @@ -393,13 +393,13 @@ typedef struct _ReadCacheA_Call { - /* [string] */ unsigned char *szLookupName; + /* [string] */ unsigned char* szLookupName; ReadCache_Common Common; } ReadCacheA_Call; typedef struct _ReadCacheW_Call { - /* [string] */ WCHAR *szLookupName; + /* [string] */ WCHAR* szLookupName; ReadCache_Common Common; } ReadCacheW_Call; @@ -407,27 +407,27 @@ { LONG ReturnCode; /* [range] */ DWORD cbDataLen; - /* [size_is][unique] */ BYTE *pbData; + /* [size_is][unique] */ BYTE* pbData; } ReadCache_Return; typedef struct _WriteCache_Common { REDIR_SCARDCONTEXT hContext; - UUID *CardIdentifier; + UUID* CardIdentifier; DWORD FreshnessCounter; /* [range] */ DWORD cbDataLen; - /* [size_is][unique] */ BYTE *pbData; + /* [size_is][unique] */ BYTE* pbData; } WriteCache_Common; typedef struct _WriteCacheA_Call { - /* [string] */ unsigned char *szLookupName; + /* [string] */ unsigned char* szLookupName; WriteCache_Common Common; } WriteCacheA_Call; typedef struct _WriteCacheW_Call { - /* [string] */ WCHAR *szLookupName; + /* [string] */ WCHAR* szLookupName; WriteCache_Common Common; } WriteCacheW_Call; @@ -436,49 +436,83 @@ #include "smartcard_main.h" -LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment); -LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment); - -SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDCONTEXT* context); -void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext); - -SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle); -void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle, SCARDHANDLE hCard); +LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, + UINT32 alignment); +LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, + UINT32 alignment); + +SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard, + REDIR_SCARDCONTEXT* context); +void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard, + REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext); + +SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard, + REDIR_SCARDHANDLE* handle); +void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle, + SCARDHANDLE hCard); LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s); LONG smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s); LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s); -LONG smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 objectBufferLength); - -LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context); -LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context); - -LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context); -LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context); - -LONG smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle); -LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle); - -LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle); -LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle); +LONG smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, + UINT32 objectBufferLength); -LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Call* call); -void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, EstablishContext_Call* call); - -LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Return* ret); -void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard, EstablishContext_Return* ret); +LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context); +LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context); + +LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context); +LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDCONTEXT* context); + +LONG smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle); +LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle); + +LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle); +LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, + REDIR_SCARDHANDLE* handle); + +LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, + EstablishContext_Call* call); +void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, + EstablishContext_Call* call); + +LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s, + EstablishContext_Return* ret); +void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard, + EstablishContext_Return* ret); LONG smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Context_Call* call); -void smartcard_trace_context_call(SMARTCARD_DEVICE* smartcard, Context_Call* call, const char* name); +void smartcard_trace_context_call(SMARTCARD_DEVICE* smartcard, Context_Call* call, + const char* name); void smartcard_trace_long_return(SMARTCARD_DEVICE* smartcard, Long_Return* ret, const char* name); -LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Call* call); -void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, ListReaders_Call* call, BOOL unicode); - -LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Return* ret); -void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, ListReaders_Return* ret, BOOL unicode); +LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStream* s, + ListReaderGroups_Call* call); +void smartcard_trace_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, + ListReaderGroups_Call* call, BOOL unicode); + +LONG smartcard_pack_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, wStream* s, + ListReaderGroups_Return* ret); +void smartcard_trace_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, + ListReaderGroups_Return* ret, BOOL unicode); + +LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, + ListReaders_Call* call); +void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, ListReaders_Call* call, + BOOL unicode); + +LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, + ListReaders_Return* ret); +void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, ListReaders_Return* ret, + BOOL unicode); LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectA_Call* call); void smartcard_trace_connect_a_call(SMARTCARD_DEVICE* smartcard, ConnectA_Call* call); @@ -492,20 +526,29 @@ LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call); void smartcard_trace_reconnect_call(SMARTCARD_DEVICE* smartcard, Reconnect_Call* call); -LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Return* ret); +LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, + Reconnect_Return* ret); void smartcard_trace_reconnect_return(SMARTCARD_DEVICE* smartcard, Reconnect_Return* ret); -LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s, HCardAndDisposition_Call* call); -void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, HCardAndDisposition_Call* call, const char* name); - -LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeA_Call* call); -void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, GetStatusChangeA_Call* call); - -LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeW_Call* call); -void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, GetStatusChangeW_Call* call); - -LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChange_Return* ret); -void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard, GetStatusChange_Return* ret, BOOL unicode); +LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s, + HCardAndDisposition_Call* call); +void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, + HCardAndDisposition_Call* call, const char* name); + +LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, + GetStatusChangeA_Call* call); +void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, + GetStatusChangeA_Call* call); + +LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, + GetStatusChangeW_Call* call); +void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, + GetStatusChangeW_Call* call); + +LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, + GetStatusChange_Return* ret); +void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard, + GetStatusChange_Return* ret, BOOL unicode); LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call); LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, State_Return* ret); @@ -516,11 +559,14 @@ LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Return* ret); void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, Status_Return* ret, BOOL unicode); -LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Call* call); +LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, + GetAttrib_Call* call); void smartcard_trace_get_attrib_call(SMARTCARD_DEVICE* smartcard, GetAttrib_Call* call); -LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Return* ret); -void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, GetAttrib_Return* ret, DWORD dwAttrId); +LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, + GetAttrib_Return* ret); +void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, GetAttrib_Return* ret, + DWORD dwAttrId); LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call); void smartcard_trace_control_call(SMARTCARD_DEVICE* smartcard, Control_Call* call); @@ -534,8 +580,10 @@ LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Return* ret); void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, Transmit_Return* ret); -LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, LocateCardsByATRA_Call* call); -void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, LocateCardsByATRA_Call* call); +LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, + LocateCardsByATRA_Call* call); +void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, + LocateCardsByATRA_Call* call); #endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H */ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/gstreamer/tsmf_X11.c freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/gstreamer/tsmf_X11.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/gstreamer/tsmf_X11.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/gstreamer/tsmf_X11.c 2017-03-03 08:39:24.000000000 +0000 @@ -21,7 +21,9 @@ #include #include #include +#ifndef __CYGWIN__ #include +#endif #include #include @@ -314,14 +316,14 @@ { struct X11Handle* hdl; + if (!decoder) + return -1; + if (decoder->media_type != TSMF_MAJOR_TYPE_VIDEO) { return -3; } - if (!decoder) - return -1; - if (!decoder->platform) return -1; @@ -467,14 +469,15 @@ int tsmf_window_destroy(TSMFGstreamerDecoder* decoder) { struct X11Handle* hdl; + + if (!decoder) + return -1; + decoder->ready = FALSE; if (decoder->media_type != TSMF_MAJOR_TYPE_VIDEO) return -3; - if (!decoder) - return -1; - if (!decoder->platform) return -1; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/pulse/tsmf_pulse.c freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/pulse/tsmf_pulse.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/pulse/tsmf_pulse.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/pulse/tsmf_pulse.c 2017-03-03 08:39:24.000000000 +0000 @@ -130,7 +130,7 @@ return FALSE; } pa_context_set_state_callback(pulse->context, tsmf_pulse_context_state_callback, pulse); - if(tsmf_pulse_connect(pulse)) + if(!tsmf_pulse_connect(pulse)) { WLog_ERR(TAG, "tsmf_pulse_connect failed"); return FALSE; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/tsmf_ifman.c freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/tsmf_ifman.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/tsmf_ifman.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/tsmf_ifman.c 2017-03-03 08:39:24.000000000 +0000 @@ -50,15 +50,15 @@ if (Stream_GetRemainingLength(ifman->input) < 4) return ERROR_INVALID_DATA; - Stream_Read_UINT32(ifman->input, CapabilityValue); + Stream_Read_UINT32(ifman->input, CapabilityValue); DEBUG_TSMF("server CapabilityValue %"PRIu32"", CapabilityValue); if (!Stream_EnsureRemainingCapacity(ifman->output, 8)) return ERROR_INVALID_DATA; + Stream_Write_UINT32(ifman->output, 1); /* CapabilityValue */ Stream_Write_UINT32(ifman->output, 0); /* Result */ - return CHANNEL_RC_OK; } @@ -78,12 +78,14 @@ if (!Stream_EnsureRemainingCapacity(ifman->output, ifman->input_size + 4)) return ERROR_OUTOFMEMORY; + pos = Stream_GetPosition(ifman->output); Stream_Copy(ifman->input, ifman->output, ifman->input_size); Stream_SetPosition(ifman->output, pos); if (Stream_GetRemainingLength(ifman->output) < 4) return ERROR_INVALID_DATA; + Stream_Read_UINT32(ifman->output, numHostCapabilities); for (i = 0; i < numHostCapabilities; i++) @@ -108,6 +110,7 @@ Stream_Read_UINT32(ifman->output, v); DEBUG_TSMF("server protocol version %"PRIu32"", v); break; + case 2: /* Supported platform */ if (Stream_GetRemainingLength(ifman->output) < 4) return ERROR_INVALID_DATA; @@ -115,18 +118,20 @@ Stream_Peek_UINT32(ifman->output, v); DEBUG_TSMF("server supported platform %"PRIu32"", v); /* Claim that we support both MF and DShow platforms. */ - Stream_Write_UINT32(ifman->output, MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW); + Stream_Write_UINT32(ifman->output, + MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW); break; + default: WLog_ERR(TAG, "skipping unknown capability type %"PRIu32"", CapabilityType); break; } + Stream_SetPosition(ifman->output, pos + cbCapabilityLength); } Stream_Write_UINT32(ifman->output, 0); /* Result */ ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; - return CHANNEL_RC_OK; } @@ -147,7 +152,6 @@ Stream_Read_UINT32(ifman->input, PlatformCookie); Stream_Seek_UINT32(ifman->input); /* NoRolloverFlags (4 bytes) */ Stream_Read_UINT32(ifman->input, numMediaType); - DEBUG_TSMF("PlatformCookie %"PRIu32" numMediaType %"PRIu32"", PlatformCookie, numMediaType); if (!tsmf_codec_check_media_type(ifman->decoder_name, ifman->input)) @@ -158,11 +162,11 @@ if (!Stream_EnsureRemainingCapacity(ifman->output, 12)) return -1; + Stream_Write_UINT32(ifman->output, FormatSupported); Stream_Write_UINT32(ifman->output, PlatformCookie); Stream_Write_UINT32(ifman->output, 0); /* Result */ ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; - return CHANNEL_RC_OK; } @@ -175,7 +179,6 @@ { UINT status = CHANNEL_RC_OK; TSMF_PRESENTATION* presentation; - DEBUG_TSMF(""); if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE) @@ -198,7 +201,6 @@ tsmf_presentation_set_audio_device(presentation, ifman->audio_name, ifman->audio_device); ifman->output_pending = TRUE; - return status; } @@ -213,7 +215,6 @@ UINT status = CHANNEL_RC_OK; TSMF_STREAM* stream; TSMF_PRESENTATION* presentation; - DEBUG_TSMF(""); if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) @@ -232,6 +233,7 @@ Stream_Read_UINT32(ifman->input, StreamId); Stream_Seek_UINT32(ifman->input); /* numMediaType */ stream = tsmf_stream_new(presentation, StreamId, rdpcontext); + if (!stream) { WLog_ERR(TAG, "failed to create stream"); @@ -243,6 +245,8 @@ WLog_ERR(TAG, "failed to set stream format"); return ERROR_OUTOFMEMORY; } + + tsmf_stream_start_threads(stream); } ifman->output_pending = TRUE; @@ -257,6 +261,7 @@ UINT tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman) { DEBUG_TSMF(""); + if (!Stream_EnsureRemainingCapacity(ifman->output, 8)) return ERROR_OUTOFMEMORY; @@ -277,14 +282,12 @@ UINT32 StreamId; TSMF_STREAM* stream; TSMF_PRESENTATION* presentation; - DEBUG_TSMF(""); if (Stream_GetRemainingLength(ifman->input) < 20) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); - Stream_Seek(ifman->input, GUID_SIZE); if (!presentation) @@ -303,11 +306,10 @@ } ifman->output_pending = TRUE; - return status; } -float tsmf_stream_read_float(wStream *s) +float tsmf_stream_read_float(wStream* s) { float fValue; UINT32 iValue; @@ -327,14 +329,12 @@ float Left, Top; float Right, Bottom; TSMF_PRESENTATION* presentation; - DEBUG_TSMF(""); if (Stream_GetRemainingLength(ifman->input) < 32) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); - Stream_Seek(ifman->input, GUID_SIZE); if (!presentation) @@ -348,11 +348,10 @@ Right = tsmf_stream_read_float(ifman->input); /* Right (4 bytes) */ Bottom = tsmf_stream_read_float(ifman->input); /* Bottom (4 bytes) */ DEBUG_TSMF("SetSourceVideoRect: Left: %f Top: %f Right: %f Bottom: %f", - Left, Top, Right, Bottom); + Left, Top, Right, Bottom); } ifman->output_pending = TRUE; - return status; } @@ -364,13 +363,13 @@ UINT tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman) { TSMF_PRESENTATION* presentation; - DEBUG_TSMF(""); if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + if (presentation) tsmf_presentation_free(presentation); else @@ -384,7 +383,6 @@ Stream_Write_UINT32(ifman->output, 0); /* Result */ ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; - return CHANNEL_RC_OK; } @@ -398,7 +396,6 @@ TSMF_PRESENTATION* presentation; UINT32 newVolume; UINT32 muted; - DEBUG_TSMF("on stream volume"); if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) @@ -422,7 +419,6 @@ return ERROR_INVALID_OPERATION; ifman->output_pending = TRUE; - return 0; } @@ -434,13 +430,13 @@ UINT tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman) { TSMF_PRESENTATION* presentation; - DEBUG_TSMF("on channel volume"); if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + if (presentation) { UINT32 channelVolume; @@ -453,7 +449,6 @@ } ifman->output_pending = TRUE; - return CHANNEL_RC_OK; } @@ -483,7 +478,7 @@ UINT32 Width; UINT32 Height; UINT32 cbVisibleRect; - RDP_RECT *rects = NULL; + RDP_RECT* rects = NULL; int num_rects = 0; UINT error = CHANNEL_RC_OK; int i; @@ -493,6 +488,7 @@ return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + if (!presentation) return ERROR_NOT_FOUND; @@ -504,12 +500,11 @@ Stream_Read_UINT32(ifman->input, Height); Stream_Read_UINT32(ifman->input, Left); Stream_Read_UINT32(ifman->input, Top); - Stream_SetPosition(ifman->input, pos + numGeometryInfo); Stream_Read_UINT32(ifman->input, cbVisibleRect); num_rects = cbVisibleRect / 16; DEBUG_TSMF("numGeometryInfo %"PRIu32" Width %"PRIu32" Height %"PRIu32" Left %"PRIu32" Top %"PRIu32" cbVisibleRect %"PRIu32" num_rects %d", - numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects); + numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects); if (num_rects > 0) { @@ -528,7 +523,7 @@ rects[i].width -= rects[i].x; rects[i].height -= rects[i].y; DEBUG_TSMF("rect %d: %"PRId16" %"PRId16" %"PRId16" %"PRId16"", i, - rects[i].x, rects[i].y, rects[i].width, rects[i].height); + rects[i].x, rects[i].y, rects[i].width, rects[i].height); } } @@ -536,7 +531,6 @@ return ERROR_INVALID_OPERATION; ifman->output_pending = TRUE; - return error; } @@ -584,6 +578,7 @@ if (Stream_GetRemainingLength(ifman->input) < 60) return ERROR_INVALID_DATA; + Stream_Seek(ifman->input, 16); Stream_Read_UINT32(ifman->input, StreamId); Stream_Seek_UINT32(ifman->input); /* numSample */ @@ -598,10 +593,9 @@ return ERROR_INVALID_DATA; DEBUG_TSMF("MessageId %"PRIu32" StreamId %"PRIu32" SampleStartTime %"PRIu64" SampleEndTime %"PRIu64" " - "ThrottleDuration %"PRIu64" SampleExtensions %"PRIu32" cbData %"PRIu32"", - ifman->message_id, StreamId, SampleStartTime, SampleEndTime, - ThrottleDuration, SampleExtensions, cbData); - + "ThrottleDuration %"PRIu64" SampleExtensions %"PRIu32" cbData %"PRIu32"", + ifman->message_id, StreamId, SampleStartTime, SampleEndTime, + ThrottleDuration, SampleExtensions, cbData); presentation = tsmf_presentation_find_by_id(ifman->presentation_id); if (!presentation) @@ -619,20 +613,20 @@ } if (!tsmf_stream_push_sample(stream, ifman->channel_callback, - ifman->message_id, SampleStartTime, SampleEndTime, - ThrottleDuration, SampleExtensions, cbData, Stream_Pointer(ifman->input))) + ifman->message_id, SampleStartTime, SampleEndTime, + ThrottleDuration, SampleExtensions, cbData, Stream_Pointer(ifman->input))) { WLog_ERR(TAG, "unable to push sample"); return ERROR_OUTOFMEMORY; } if ((error = tsmf_presentation_sync(presentation))) - { - WLog_ERR(TAG, "tsmf_presentation_sync failed with error %"PRIu32"", error); - return error; - } - ifman->output_pending = TRUE; + { + WLog_ERR(TAG, "tsmf_presentation_sync failed with error %"PRIu32"", error); + return error; + } + ifman->output_pending = TRUE; return CHANNEL_RC_OK; } @@ -652,10 +646,9 @@ Stream_Seek(ifman->input, 16); Stream_Read_UINT32(ifman->input, StreamId); - DEBUG_TSMF("StreamId %"PRIu32"", StreamId); - presentation = tsmf_presentation_find_by_id(ifman->presentation_id); + if (!presentation) { WLog_ERR(TAG, "unknown presentation id"); @@ -666,6 +659,7 @@ * therefore we only flush the stream as intended per the MS-RDPEV spec */ stream = tsmf_stream_find_by_id(presentation, StreamId); + if (stream) { if (!tsmf_stream_flush(stream)) @@ -675,7 +669,6 @@ WLog_ERR(TAG, "unknown stream id"); ifman->output_pending = TRUE; - return CHANNEL_RC_OK; } @@ -694,7 +687,6 @@ return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); - Stream_Seek(ifman->input, 16); Stream_Read_UINT32(ifman->input, StreamId); @@ -703,13 +695,11 @@ stream = tsmf_stream_find_by_id(presentation, StreamId); if (stream) - tsmf_stream_end(stream, ifman->message_id, ifman->channel_callback); + tsmf_stream_end(stream, ifman->message_id, ifman->channel_callback); } DEBUG_TSMF("StreamId %"PRIu32"", StreamId); - ifman->output_pending = TRUE; - ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; return CHANNEL_RC_OK; } @@ -722,7 +712,6 @@ UINT tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman) { TSMF_PRESENTATION* presentation; - DEBUG_TSMF(""); if (Stream_GetRemainingLength(ifman->input) < 16) @@ -743,7 +732,6 @@ Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_START_COMPLETED); /* EventId */ Stream_Write_UINT32(ifman->output, 0); /* cbData */ ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; - return CHANNEL_RC_OK; } @@ -755,10 +743,8 @@ UINT tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman) { TSMF_PRESENTATION* presentation; - DEBUG_TSMF(""); ifman->output_pending = TRUE; - /* Added pause control so gstreamer pipeline can be paused accordingly */ presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); @@ -781,12 +767,11 @@ UINT tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman) { TSMF_PRESENTATION* presentation; - DEBUG_TSMF(""); ifman->output_pending = TRUE; - /* Added restart control so gstreamer pipeline can be resumed accordingly */ presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + if (presentation) { if (!tsmf_presentation_restarted(presentation)) @@ -806,10 +791,9 @@ UINT tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman) { TSMF_PRESENTATION* presentation; - DEBUG_TSMF(""); - presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); + if (presentation) { if (!tsmf_presentation_stop(presentation)) @@ -825,7 +809,6 @@ Stream_Write_UINT32(ifman->output, 0); /* StreamId */ Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_STOP_COMPLETED); /* EventId */ Stream_Write_UINT32(ifman->output, 0); /* cbData */ - ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; return CHANNEL_RC_OK; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/tsmf_media.c freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/tsmf_media.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/tsmf_media.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/tsmf_media.c 2017-03-03 08:39:24.000000000 +0000 @@ -176,11 +176,13 @@ TSMF_STREAM* s; TSMF_SAMPLE* sample; BOOL pending = FALSE; - TSMF_PRESENTATION* presentation = stream->presentation; + TSMF_PRESENTATION* presentation = NULL; if (!stream) return NULL; + presentation = stream->presentation; + if (Queue_Count(stream->sample_list) < 1) return NULL; @@ -455,6 +457,26 @@ event.framePixFmt = sample->pixfmt; event.frameWidth = sample->stream->width; event.frameHeight = sample->stream->height; + event.x = presentation->x; + event.y = presentation->y; + event.width = presentation->width; + event.height = presentation->height; + + if (presentation->nr_rects > 0) + { + event.numVisibleRects = presentation->nr_rects; + event.visibleRects = (RECTANGLE_16*) calloc(1, event.numVisibleRects * sizeof(RECTANGLE_16)); + + if (!event.visibleRects) + { + WLog_ERR(TAG, "can't allocate memory for copy rectangles"); + return FALSE; + } + + memcpy(event.visibleRects, presentation->rects, presentation->nr_rects * sizeof(RDP_RECT)); + presentation->nr_rects = 0; + } + #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. */ @@ -486,6 +508,9 @@ tsmf->FrameEvent(tsmf, &event); free(event.frameData); + + if (event.visibleRects != NULL) + free(event.visibleRects); } return TRUE; @@ -718,7 +743,6 @@ TSMF_STREAM* stream = (TSMF_STREAM*) arg; UINT error = CHANNEL_RC_OK; DEBUG_TSMF("in %"PRIu32"", stream->stream_id); - hdl[0] = stream->stopEvent; hdl[1] = Queue_Event(stream->sample_ack_list); @@ -740,7 +764,7 @@ if (stream->eos) { while ((stream->currentBufferLevel > 0) - || !(tsmf_stream_process_ack(stream, TRUE))) + && !(tsmf_stream_process_ack(stream, TRUE))) { DEBUG_TSMF("END OF STREAM PROCESSING!"); @@ -1109,6 +1133,10 @@ presentation->width = width; presentation->height = height; tmp_rects = realloc(presentation->rects, sizeof(RDP_RECT) * num_rects); + + if (!tmp_rects && num_rects) + return FALSE; + presentation->nr_rects = num_rects; presentation->rects = tmp_rects; CopyMemory(presentation->rects, rects, sizeof(RDP_RECT) * num_rects); @@ -1231,14 +1259,14 @@ 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->play_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, + stream, CREATE_SUSPENDED, 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, + CREATE_SUSPENDED, NULL); if (!stream->ack_thread) goto error_ack_thread; @@ -1273,6 +1301,12 @@ return NULL; } +void tsmf_stream_start_threads(TSMF_STREAM* stream) +{ + ResumeThread(stream->play_thread); + ResumeThread(stream->ack_thread); +} + TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, UINT32 stream_id) { diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/tsmf_media.h freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/tsmf_media.h --- freerdp-2.0.0~dev201701161718+dfsg/channels/tsmf/client/tsmf_media.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/tsmf/client/tsmf_media.h 2017-03-03 08:39:24.000000000 +0000 @@ -36,33 +36,38 @@ typedef struct _TSMF_SAMPLE TSMF_SAMPLE; -TSMF_PRESENTATION *tsmf_presentation_new(const BYTE *guid, IWTSVirtualChannelCallback *pChannelCallback); -TSMF_PRESENTATION *tsmf_presentation_find_by_id(const BYTE *guid); -BOOL tsmf_presentation_start(TSMF_PRESENTATION *presentation); -BOOL tsmf_presentation_stop(TSMF_PRESENTATION *presentation); -UINT tsmf_presentation_sync(TSMF_PRESENTATION *presentation); -BOOL tsmf_presentation_paused(TSMF_PRESENTATION *presentation); -BOOL tsmf_presentation_restarted(TSMF_PRESENTATION *presentation); -BOOL tsmf_presentation_volume_changed(TSMF_PRESENTATION *presentation, UINT32 newVolume, UINT32 muted); -BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION *presentation, - UINT32 x, UINT32 y, UINT32 width, UINT32 height, - int num_rects, RDP_RECT *rects); -void tsmf_presentation_set_audio_device(TSMF_PRESENTATION *presentation, - const char *name, const char *device); -void tsmf_presentation_free(TSMF_PRESENTATION *presentation); - -TSMF_STREAM *tsmf_stream_new(TSMF_PRESENTATION *presentation, UINT32 stream_id, rdpContext* rdpcontext); -TSMF_STREAM *tsmf_stream_find_by_id(TSMF_PRESENTATION *presentation, UINT32 stream_id); -BOOL tsmf_stream_set_format(TSMF_STREAM *stream, const char *name, wStream *s); -void tsmf_stream_end(TSMF_STREAM *stream, UINT32 message_id, IWTSVirtualChannelCallback* pChannelCallback); -void tsmf_stream_free(TSMF_STREAM *stream); +TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, + IWTSVirtualChannelCallback* pChannelCallback); +TSMF_PRESENTATION* tsmf_presentation_find_by_id(const BYTE* guid); +BOOL tsmf_presentation_start(TSMF_PRESENTATION* presentation); +BOOL tsmf_presentation_stop(TSMF_PRESENTATION* presentation); +UINT tsmf_presentation_sync(TSMF_PRESENTATION* presentation); +BOOL tsmf_presentation_paused(TSMF_PRESENTATION* presentation); +BOOL tsmf_presentation_restarted(TSMF_PRESENTATION* presentation); +BOOL tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 newVolume, + UINT32 muted); +BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, + UINT32 x, UINT32 y, UINT32 width, UINT32 height, + int num_rects, RDP_RECT* rects); +void tsmf_presentation_set_audio_device(TSMF_PRESENTATION* presentation, + const char* name, const char* device); +void tsmf_presentation_free(TSMF_PRESENTATION* presentation); + +TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id, + rdpContext* rdpcontext); +TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, UINT32 stream_id); +BOOL tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, wStream* s); +void tsmf_stream_end(TSMF_STREAM* stream, UINT32 message_id, + IWTSVirtualChannelCallback* pChannelCallback); +void tsmf_stream_free(TSMF_STREAM* stream); BOOL tsmf_stream_flush(TSMF_STREAM* 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); BOOL tsmf_media_init(void); +void tsmf_stream_start_threads(TSMF_STREAM* stream); #endif diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/urbdrc/client/data_transfer.c freerdp-2.0.0~dev201703030839+dfsg/channels/urbdrc/client/data_transfer.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/urbdrc/client/data_transfer.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/urbdrc/client/data_transfer.c 2017-03-03 08:39:24.000000000 +0000 @@ -2319,12 +2319,9 @@ pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice); if (pdev == NULL || pdev->isSigToEnd(pdev)) { - if (transfer_data) - { - if (transfer_data->pBuffer) - zfree(transfer_data->pBuffer); - zfree(transfer_data); - } + if (transfer_data->pBuffer) + zfree(transfer_data->pBuffer); + zfree(transfer_data); return 0; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/channels/urbdrc/client/isoch_queue.c freerdp-2.0.0~dev201703030839+dfsg/channels/urbdrc/client/isoch_queue.c --- freerdp-2.0.0~dev201701161718+dfsg/channels/urbdrc/client/isoch_queue.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/channels/urbdrc/client/isoch_queue.c 2017-03-03 08:39:24.000000000 +0000 @@ -120,11 +120,13 @@ } queue->isoch_num--; - /* free data info */ - isoch->out_data = NULL; - if (isoch) + { + /* free data info */ + isoch->out_data = NULL; + zfree(isoch); + } return 1; /* unregistration successful */ } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/ci/cmake-preloads/config-debian-squeeze.txt freerdp-2.0.0~dev201703030839+dfsg/ci/cmake-preloads/config-debian-squeeze.txt --- freerdp-2.0.0~dev201701161718+dfsg/ci/cmake-preloads/config-debian-squeeze.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/ci/cmake-preloads/config-debian-squeeze.txt 2017-03-03 08:39:24.000000000 +0000 @@ -2,6 +2,7 @@ set (WITH_MANPAGES OFF CACHE BOOL "man pages") set (CMAKE_BUILD_TYPE "Debug" CACHE STRING "build type") set (WITH_CUPS OFF CACHE BOOL "CUPS printing") +set (WITH_KRB5 ON CACHE BOOL "Kerberos support") set (WITH_ALSA OFF CACHE BOOL "alsa audio") set (WITH_FFMPEG OFF CACHE BOOL "ffmepg support") set (WITH_XV OFF CACHE BOOL "xvideo support") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/ci/cmake-preloads/config-linux-all.txt freerdp-2.0.0~dev201703030839+dfsg/ci/cmake-preloads/config-linux-all.txt --- freerdp-2.0.0~dev201701161718+dfsg/ci/cmake-preloads/config-linux-all.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/ci/cmake-preloads/config-linux-all.txt 2017-03-03 08:39:24.000000000 +0000 @@ -7,6 +7,7 @@ set (WITH_CHANNELS ON CACHE BOOL "channels") set (BUILTIN_CHANNELS ON CACHE BOOL "static channels") set (WITH_CUPS ON CACHE BOOL "cups") +set (WITH_KRB5 ON CACHE BOOL "Kerberos support") set (WITH_PCSC ON CACHE BOOL "PCSC") set (WITH_JPEG ON CACHE BOOL "jepg") set (WITH_GSTREAMER_0_10 ON CACHE BOOL "gstreamer") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/ci/cmake-preloads/config-ubuntu-1204.txt freerdp-2.0.0~dev201703030839+dfsg/ci/cmake-preloads/config-ubuntu-1204.txt --- freerdp-2.0.0~dev201701161718+dfsg/ci/cmake-preloads/config-ubuntu-1204.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/ci/cmake-preloads/config-ubuntu-1204.txt 2017-03-03 08:39:24.000000000 +0000 @@ -2,6 +2,7 @@ set (WITH_MANPAGES OFF CACHE BOOL "man pages") set (CMAKE_BUILD_TYPE "Debug" CACHE STRING "build type") set (WITH_CUPS OFF CACHE BOOL "CUPS printing") +set (WITH_KRB5 ON CACHE BOOL "Kerberos support") set (WITH_ALSA OFF CACHE BOOL "alsa audio") set (WITH_FFMPEG OFF CACHE BOOL "ffmepg support") set (WITH_XV OFF CACHE BOOL "xvideo support") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/common/client.c freerdp-2.0.0~dev201703030839+dfsg/client/common/client.c --- freerdp-2.0.0~dev201701161718+dfsg/client/common/client.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/common/client.c 2017-03-03 08:39:24.000000000 +0000 @@ -441,6 +441,7 @@ while (1) { printf("Do you trust the above certificate? (Y/T/N) "); + fflush(stdout); answer = fgetc(stdin); if (feof(stdin)) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/common/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/client/common/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/client/common/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/common/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -57,6 +57,7 @@ add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${FREERDP_API_VERSION}) include_directories(${OPENSSL_INCLUDE_DIR}) if (WITH_LIBRARY_VERSIONING) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) @@ -75,7 +76,8 @@ install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT FreeRDP-ClientTargets) if (WITH_DEBUG_SYMBOLS AND MSVC AND BUILD_SHARED_LIBS) - install(FILES ${CMAKE_PDB_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) + get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME) + install(FILES ${CMAKE_PDB_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Common") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/common/cmdline.c freerdp-2.0.0~dev201703030839+dfsg/client/common/cmdline.c --- freerdp-2.0.0~dev201701161718+dfsg/client/common/cmdline.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/common/cmdline.c 2017-03-03 08:39:24.000000000 +0000 @@ -179,14 +179,15 @@ { "encryption-methods", COMMAND_LINE_VALUE_REQUIRED, "<40,56,128,FIPS>", NULL, NULL, -1, NULL, "RDP standard security encryption methods" }, { "from-stdin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Read credentials from stdin, do not use defaults." }, { "buildconfig", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_BUILDCONFIG, NULL, NULL, NULL, -1, NULL, "print the build configuration" }, - { "log-level", COMMAND_LINE_VALUE_REQUIRED, "[OFF|FATAL|ERROR|WARN|INFO|DEBUG|TRACE]", NULL, NULL, -1, NULL, "Set the default log level, see wLog(1) for details" }, - { "log-filters", COMMAND_LINE_VALUE_REQUIRED, ":[, :][, ...]]", NULL, NULL, -1, NULL, "Set logger filters, see wLog(1) for details" }, + { "log-level", COMMAND_LINE_VALUE_REQUIRED, "[OFF|FATAL|ERROR|WARN|INFO|DEBUG|TRACE]", NULL, NULL, -1, NULL, "Set the default log level, see wLog(7) for details" }, + { "log-filters", COMMAND_LINE_VALUE_REQUIRED, ":[, :][, ...]]", NULL, NULL, -1, NULL, "Set logger filters, see wLog(7) for details" }, { "pwidth", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Physical width of display (in millimeters)" }, { "pheight", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Physical height of display (in millimeters)" }, { "orientation", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Orientation of display in degrees (0, 90, 180, 270)" }, { "scale", COMMAND_LINE_VALUE_REQUIRED, "", "100", NULL, -1, NULL, "Scaling factor of the display (value of 100, 140, or 180)" }, { "scale-desktop", COMMAND_LINE_VALUE_REQUIRED, "", "100", NULL, -1, NULL, "Scaling factor for desktop applications (value between 100 and 500)" }, { "scale-device", COMMAND_LINE_VALUE_REQUIRED, "", "100", NULL, -1, NULL, "Scaling factor for app store applications (100, 140, or 180)" }, + { "action-script", COMMAND_LINE_VALUE_REQUIRED, "", "~/.config/freerdp/action.sh", NULL, -1, NULL, "Action script" }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; @@ -627,6 +628,13 @@ { int index; ADDIN_ARGV* args; + + if (!settings || !params || !params[0]) + return FALSE; + + if (freerdp_static_channel_collection_find(settings, params[0])) + return TRUE; + args = (ADDIN_ARGV*) calloc(1, sizeof(ADDIN_ARGV)); if (!args) @@ -672,6 +680,13 @@ { int index; ADDIN_ARGV* args; + + if (!settings || !params || !params[0]) + return FALSE; + + if (freerdp_dynamic_channel_collection_find(settings, params[0])) + return TRUE; + args = (ADDIN_ARGV*) malloc(sizeof(ADDIN_ARGV)); if (!args) @@ -2506,6 +2521,12 @@ return COMMAND_LINE_ERROR; } } + CommandLineSwitchCase(arg, "action-script") + { + free (settings->ActionScript); + if (!(settings->ActionScript = _strdup(arg->Value))) + return COMMAND_LINE_ERROR_MEMORY; + } CommandLineSwitchDefault(arg) { } @@ -2513,36 +2534,41 @@ } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); - free(settings->Username); - - if (!settings->Domain && user) + if (user) { - BOOL ret; - free(settings->Domain); - ret = freerdp_parse_username(user, &settings->Username, &settings->Domain); - free(user); + free(settings->Username); + if (!settings->Domain && user) + { + BOOL ret; + free(settings->Domain); - if (!ret) - return COMMAND_LINE_ERROR; + ret = freerdp_parse_username(user, &settings->Username, &settings->Domain); + free(user); + if (!ret) + return COMMAND_LINE_ERROR; + } + else + settings->Username = user; } - else - settings->Username = user; - free(settings->GatewayUsername); - - if (!settings->GatewayDomain && gwUser) + if (gwUser) { - BOOL ret; - free(settings->GatewayDomain); - ret = freerdp_parse_username(gwUser, &settings->GatewayUsername, - &settings->GatewayDomain); - free(gwUser); + free(settings->GatewayUsername); + + if (!settings->GatewayDomain && gwUser) + { + BOOL ret; + free(settings->GatewayDomain); + ret = freerdp_parse_username(gwUser, &settings->GatewayUsername, + &settings->GatewayDomain); + free(gwUser); - if (!ret) - return COMMAND_LINE_ERROR; + if (!ret) + return COMMAND_LINE_ERROR; + } + else + settings->GatewayUsername = gwUser; } - else - settings->GatewayUsername = gwUser; freerdp_performance_flags_make(settings); @@ -2674,7 +2700,7 @@ if (settings->DeviceRedirection) { if (!freerdp_client_load_static_channel_addin(channels, settings, "rdpdr", - settings)) + settings)) return FALSE; if (!freerdp_static_channel_collection_find(settings, "rdpsnd")) @@ -2726,14 +2752,11 @@ if (settings->RedirectClipboard) { - if (!freerdp_static_channel_collection_find(settings, "cliprdr")) - { - char* params[1]; - params[0] = "cliprdr"; + char* params[1]; + params[0] = "cliprdr"; - if (!freerdp_client_add_static_channel(settings, 1, (char**) params)) - return FALSE; - } + if (!freerdp_client_add_static_channel(settings, 1, (char**) params)) + return FALSE; } if (settings->LyncRdpMode) @@ -2752,14 +2775,14 @@ if (settings->EncomspVirtualChannel) { if (!freerdp_client_load_static_channel_addin(channels, settings, "encomsp", - settings)) + settings)) return FALSE; } if (settings->RemdeskVirtualChannel) { if (!freerdp_client_load_static_channel_addin(channels, settings, "remdesk", - settings)) + settings)) return FALSE; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/common/file.c freerdp-2.0.0~dev201703030839+dfsg/client/common/file.c --- freerdp-2.0.0~dev201701161718+dfsg/client/common/file.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/common/file.c 2017-03-03 08:39:24.000000000 +0000 @@ -59,10 +59,10 @@ * */ -static int freerdp_client_rdp_file_set_integer(rdpFile* file, const char* name, int value, int index) +static int freerdp_client_rdp_file_set_integer(rdpFile* file, const char* name, int value, + int index) { int standard = 1; - #ifdef DEBUG_CLIENT_FILE WLog_DBG(TAG, "%s:i:%d", name, value); #endif @@ -201,10 +201,11 @@ if (index >= 0) { file->lines[index].name = _strdup(name); + if (!file->lines[index].name) return -1; - file->lines[index].iValue = (DWORD) value; + file->lines[index].iValue = (DWORD) value; file->lines[index].flags = RDP_FILE_LINE_FLAG_FORMATTED; file->lines[index].flags |= RDP_FILE_LINE_FLAG_TYPE_INTEGER; @@ -217,32 +218,35 @@ return standard; } -static BOOL freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, WCHAR* name, WCHAR* value, int index) +static BOOL freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, const WCHAR* name, + const WCHAR* value, int index) { int length; int ivalue; char* nameA; char* valueA; BOOL ret = TRUE; - length = (int) _wcslen(name); nameA = (char*) malloc(length + 1); + if (!nameA) return FALSE; + WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL); nameA[length] = '\0'; - length = (int) _wcslen(value); valueA = (char*) malloc(length + 1); + if (!valueA) { free(nameA); return FALSE; } + WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); valueA[length] = '\0'; - ivalue = atoi(valueA); + if (freerdp_client_rdp_file_set_integer(file, nameA, ivalue, index) < 0) ret = FALSE; @@ -251,11 +255,14 @@ return ret; } -static BOOL freerdp_client_parse_rdp_file_integer_ascii(rdpFile* file, const char* name, const char* value, int index) +static BOOL freerdp_client_parse_rdp_file_integer_ascii(rdpFile* file, const char* name, + const char* value, int index) { int ivalue = atoi(value); + if (freerdp_client_rdp_file_set_integer(file, name, ivalue, index) < 0) return FALSE; + return TRUE; } @@ -268,11 +275,11 @@ * @return 0 on success, 1 if the key wasn't found (not a standard key), -1 on error */ -static int freerdp_client_rdp_file_set_string(rdpFile* file, const char* name, const char* value, int index) +static int freerdp_client_rdp_file_set_string(rdpFile* file, const char* name, const char* value, + int index) { int standard = 0; - LPSTR *tmp = NULL; - + LPSTR* tmp = NULL; #ifdef DEBUG_CLIENT_FILE WLog_DBG(TAG, "%s:s:%s", name, value); #endif @@ -284,6 +291,8 @@ tmp = &file->Username; else if (_stricmp(name, "domain") == 0) tmp = &file->Domain; + else if (_stricmp(name, "password") == 0) + tmp = &file->Password; else if (_stricmp(name, "full address") == 0) tmp = &file->FullAddress; else if (_stricmp(name, "alternate full address") == 0) @@ -331,6 +340,7 @@ file->lines[index].name = _strdup(name); file->lines[index].sValue = _strdup(value); + if (!file->lines[index].name || !file->lines[index].sValue) { free(file->lines[index].name); @@ -355,19 +365,22 @@ while ((file->argc + 1) > file->argSize) { int new_size; - char **new_argv; - + char** new_argv; new_size = file->argSize * 2; new_argv = (char**) realloc(file->argv, new_size * sizeof(char*)); + if (!new_argv) return FALSE; + file->argv = new_argv; file->argSize = new_size; } file->argv[file->argc] = _strdup(option); + if (!file->argv[file->argc]) return FALSE; + (file->argc)++; return TRUE; } @@ -380,33 +393,35 @@ while ((file->lineCount + 1) > file->lineSize) { int new_size; - rdpFileLine *new_line; - + rdpFileLine* new_line; new_size = file->lineSize * 2; new_line = (rdpFileLine*) realloc(file->lines, new_size * sizeof(rdpFileLine)); + if (!new_line) return -1; + file->lines = new_line; file->lineSize = new_size; } ZeroMemory(&(file->lines[file->lineCount]), sizeof(rdpFileLine)); file->lines[file->lineCount].text = _strdup(line); + if (!file->lines[file->lineCount].text) return -1; file->lines[file->lineCount].index = index; (file->lineCount)++; - return index; } -static BOOL freerdp_client_parse_rdp_file_add_line_unicode(rdpFile* file, WCHAR* line, int index) +static BOOL freerdp_client_parse_rdp_file_add_line_unicode(rdpFile* file, const WCHAR* line, + int index) { char* lineA = NULL; BOOL ret = TRUE; - ConvertFromUnicode(CP_UTF8, 0, line, -1, &lineA, 0, NULL, NULL); + if (!lineA) return FALSE; @@ -421,30 +436,34 @@ { if (freerdp_client_parse_rdp_file_add_line(file, line, index) == -1) return FALSE; + return TRUE; } -static BOOL freerdp_client_parse_rdp_file_string_unicode(rdpFile* file, WCHAR* name, WCHAR* value, int index) +static BOOL freerdp_client_parse_rdp_file_string_unicode(rdpFile* file, const WCHAR* name, + const WCHAR* value, int index) { int length; char* nameA; char* valueA; BOOL ret = TRUE; - length = (int) _wcslen(name); nameA = (char*) malloc(length + 1); + if (!nameA) return FALSE; + WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL); nameA[length] = '\0'; - length = (int) _wcslen(value); valueA = (char*) malloc(length + 1); + if (!valueA) { free(nameA); return FALSE; } + WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); valueA[length] = '\0'; @@ -456,10 +475,12 @@ return ret; } -static BOOL freerdp_client_parse_rdp_file_string_ascii(rdpFile* file, char* name, char* value, int index) +static BOOL freerdp_client_parse_rdp_file_string_ascii(rdpFile* file, char* name, char* value, + int index) { BOOL ret = TRUE; char* valueA = _strdup(value); + if (!valueA) return FALSE; @@ -470,18 +491,18 @@ return ret; } -static BOOL freerdp_client_parse_rdp_file_option_unicode(rdpFile* file, WCHAR* option, int index) +static BOOL freerdp_client_parse_rdp_file_option_unicode(rdpFile* file, const WCHAR* option, + int index) { char* optionA = NULL; BOOL ret; - ConvertFromUnicode(CP_UTF8, 0, option, -1, &optionA, 0, NULL, NULL); + if (!optionA) return FALSE; ret = freerdp_client_add_option(file, optionA); free(optionA); - return ret; } @@ -490,19 +511,26 @@ return freerdp_client_add_option(file, option); } -static BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, const BYTE* buffer, size_t size) +static BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, const BYTE* buffer, + size_t size) { + BOOL rc = FALSE; int index; int length; char* line; char* type; char* context; - char *d1, *d2; - char *beg, *end; - char *name, *value; + char* d1, *d2; + char* beg, *end; + char* name, *value; + char* copy = calloc(1, size + sizeof(BYTE)); + + if (!copy) + return FALSE; + memcpy(copy, buffer, size); index = 0; - line = strtok_s((char*) buffer, "\r\n", &context); + line = strtok_s(copy, "\r\n", &context); while (line) { @@ -538,7 +566,6 @@ if ((d2 - d1) != 2) goto next_line; /* improper type length */ - *d1 = 0; *d2 = 0; name = beg; @@ -548,13 +575,13 @@ { /* integer type */ if (!freerdp_client_parse_rdp_file_integer_ascii(file, name, value, index)) - return FALSE; + goto fail; } else if (*type == 's') { /* string type */ if (!freerdp_client_parse_rdp_file_string_ascii(file, name, value, index)) - return FALSE; + goto fail; } else if (*type == 'b') { @@ -562,27 +589,36 @@ } } -next_line: + next_line: line = strtok_s(NULL, "\r\n", &context); index++; } - return TRUE; + rc = TRUE; +fail: + free(copy); + return rc; } -static BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, const BYTE* buffer, size_t size) +static BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, const BYTE* buffer, + size_t size) { + BOOL rc = FALSE; int index; int length; - WCHAR* line; + const WCHAR* line; WCHAR* type; WCHAR* context; - WCHAR *d1, *d2; - WCHAR *beg, *end; - WCHAR *name, *value; + WCHAR* d1, *d2; + const WCHAR* name, *value; + WCHAR* copy = (WCHAR*)calloc(1, size + sizeof(WCHAR)); + + if (!copy) + return FALSE; + memcpy(copy, buffer, size); index = 0; - line = wcstok_s((WCHAR*) buffer, CR_LF_STR_W, &context); + line = wcstok_s(copy, CR_LF_STR_W, &context); while (line != NULL) { @@ -590,11 +626,10 @@ if (length > 1) { - beg = line; - end = &line[length - 1]; + const WCHAR* beg = line; if (!freerdp_client_parse_rdp_file_add_line_unicode(file, line, index)) - return FALSE; + goto fail; if (beg[0] == '/') { @@ -617,7 +652,6 @@ if ((d2 - d1) != 2) goto next_line; /* improper type length */ - *d1 = 0; *d2 = 0; name = beg; @@ -627,13 +661,13 @@ { /* integer type */ if (!freerdp_client_parse_rdp_file_integer_unicode(file, name, value, index)) - return FALSE; + goto fail; } else if (*type == 's') { /* string type */ if (!freerdp_client_parse_rdp_file_string_unicode(file, name, value, index)) - return FALSE; + goto fail; } else if (*type == 'b') { @@ -641,12 +675,15 @@ } } -next_line: + next_line: line = wcstok_s(NULL, CR_LF_STR_W, &context); index++; } - return TRUE; + rc = TRUE; +fail: + free(copy); + return rc; } BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, const BYTE* buffer, size_t size) @@ -667,7 +704,6 @@ FILE* fp = NULL; size_t read_size; long int file_size; - fp = fopen(name, "r"); if (!fp) @@ -684,11 +720,13 @@ } buffer = (BYTE*) malloc(file_size + 2); + if (!buffer) { fclose(fp); return FALSE; } + read_size = fread(buffer, file_size, 1, fp); if (!read_size) @@ -696,6 +734,7 @@ if (!ferror(fp)) read_size = file_size; } + fclose(fp); if (read_size < 1) @@ -706,11 +745,8 @@ buffer[file_size] = '\0'; buffer[file_size + 1] = '\0'; - status = freerdp_client_parse_rdp_file_buffer(file, buffer, file_size); - free(buffer); - return status; } @@ -718,13 +754,14 @@ #define SETTING_MODIFIED(_settings, _field) (WRITE_ALL_SETTINGS || _settings->SettingsModified[FreeRDP_##_field]) #define SETTING_MODIFIED_SET(_target, _settings, _field) if SETTING_MODIFIED(_settings, _field) _target = _settings->_field #define SETTING_MODIFIED_SET_STRING(_target, _settings, _field) do { if SETTING_MODIFIED(_settings, _field) _target = _strdup(_settings->_field); \ - if (!_target) return FALSE; \ - } while (0) + if (!_target) return FALSE; \ + } while (0) BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, const rdpSettings* settings) { SETTING_MODIFIED_SET_STRING(file->Domain, settings, Domain); SETTING_MODIFIED_SET_STRING(file->Username, settings, Username); + SETTING_MODIFIED_SET_STRING(file->Password, settings, Password); SETTING_MODIFIED_SET(file->ServerPort, settings, ServerPort); SETTING_MODIFIED_SET_STRING(file->FullAddress, settings, ServerHostname); SETTING_MODIFIED_SET(file->DesktopWidth, settings, DesktopWidth); @@ -751,7 +788,6 @@ SETTING_MODIFIED_SET_STRING(file->GatewayHostname, settings, GatewayHostname); SETTING_MODIFIED_SET(file->GatewayUsageMethod, settings, GatewayUsageMethod); SETTING_MODIFIED_SET(file->PromptCredentialOnce, settings, GatewayUseSameCredentials); - SETTING_MODIFIED_SET(file->RemoteApplicationMode, settings, RemoteApplicationMode); SETTING_MODIFIED_SET_STRING(file->RemoteApplicationProgram, settings, RemoteApplicationProgram); SETTING_MODIFIED_SET_STRING(file->RemoteApplicationName, settings, RemoteApplicationName); @@ -759,10 +795,8 @@ SETTING_MODIFIED_SET_STRING(file->RemoteApplicationFile, settings, RemoteApplicationFile); SETTING_MODIFIED_SET_STRING(file->RemoteApplicationGuid, settings, RemoteApplicationGuid); SETTING_MODIFIED_SET_STRING(file->RemoteApplicationCmdLine, settings, RemoteApplicationCmdLine); - SETTING_MODIFIED_SET(file->SpanMonitors, settings, SpanMonitors); SETTING_MODIFIED_SET(file->UseMultiMon, settings, UseMultimon); - return TRUE; } @@ -773,7 +807,6 @@ char* buffer; int status = 0; WCHAR* unicodestr = NULL; - length = (int) freerdp_client_write_rdp_file_buffer(file, NULL, 0); if (length < 0) @@ -801,7 +834,7 @@ /* Write multi-byte header */ if (fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp) != 2 || - fwrite(unicodestr, 2, length, fp) != length) + fwrite(unicodestr, 2, length, fp) != length) { free(buffer); free(unicodestr); @@ -826,7 +859,6 @@ } free(buffer); - return (status == 0) ? TRUE : FALSE; } @@ -845,7 +877,6 @@ for (index = 0; index < file->lineCount; index++) { line = &(file->lines[index]); - length = (int) strlen(line->text); if (!buffer) @@ -882,6 +913,7 @@ if (!freerdp_parse_username(file->Username, &user, &domain)) return FALSE; + if (freerdp_set_param_string(settings, FreeRDP_Username, user) != 0) return FALSE; @@ -895,6 +927,12 @@ free(domain); } + if (~((size_t)file->Password)) + { + if (freerdp_set_param_string(settings, FreeRDP_Password, file->Password) != 0) + return FALSE; + } + if (~((size_t) file->FullAddress)) { int port = -1; @@ -917,26 +955,35 @@ if (~file->DesktopWidth) freerdp_set_param_uint32(settings, FreeRDP_DesktopWidth, file->DesktopWidth); + if (~file->DesktopHeight) freerdp_set_param_uint32(settings, FreeRDP_DesktopHeight, file->DesktopHeight); + if (~file->SessionBpp) freerdp_set_param_uint32(settings, FreeRDP_ColorDepth, file->SessionBpp); + if (~file->ConnectToConsole) freerdp_set_param_bool(settings, FreeRDP_ConsoleSession, file->ConnectToConsole); + if (~file->AdministrativeSession) freerdp_set_param_bool(settings, FreeRDP_ConsoleSession, file->AdministrativeSession); + if (~file->NegotiateSecurityLayer) freerdp_set_param_bool(settings, FreeRDP_NegotiateSecurityLayer, file->NegotiateSecurityLayer); + if (~file->EnableCredSSPSupport) freerdp_set_param_bool(settings, FreeRDP_NlaSecurity, file->EnableCredSSPSupport); + if (~((size_t) file->AlternateShell)) { - if(freerdp_set_param_string(settings, FreeRDP_AlternateShell, file->AlternateShell) != 0) + if (freerdp_set_param_string(settings, FreeRDP_AlternateShell, file->AlternateShell) != 0) return FALSE; } + if (~((size_t) file->ShellWorkingDirectory)) { - if (freerdp_set_param_string(settings, FreeRDP_ShellWorkingDirectory, file->ShellWorkingDirectory) != 0) + if (freerdp_set_param_string(settings, FreeRDP_ShellWorkingDirectory, + file->ShellWorkingDirectory) != 0) return FALSE; } @@ -954,22 +1001,23 @@ * 1: The remote session will appear in a window. * 2: The remote session will appear full screen. */ - freerdp_set_param_bool(settings, FreeRDP_Fullscreen, - (file->ScreenModeId == 2) ? TRUE : FALSE); + (file->ScreenModeId == 2) ? TRUE : FALSE); } if (~((size_t) file->SmartSizing)) { freerdp_set_param_bool(settings, FreeRDP_SmartSizing, - (file->SmartSizing == 1) ? TRUE : FALSE); + (file->SmartSizing == 1) ? TRUE : FALSE); } if (~((size_t) file->LoadBalanceInfo)) { settings->LoadBalanceInfo = (BYTE*) _strdup(file->LoadBalanceInfo); + if (!settings->LoadBalanceInfo) return FALSE; + settings->LoadBalanceInfoLength = (int) strlen((char*) settings->LoadBalanceInfo); } @@ -989,9 +1037,8 @@ * 2: If server authentication fails, show a warning and allow me to connect or refuse the connection (Warn me). * 3: No authentication requirement is specified. */ - freerdp_set_param_bool(settings, FreeRDP_IgnoreCertificate, - (file->AuthenticationLevel == 0) ? TRUE : FALSE); + (file->AuthenticationLevel == 0) ? TRUE : FALSE); } if (~file->ConnectionType) @@ -1039,50 +1086,66 @@ if (~file->PromptCredentialOnce) freerdp_set_param_bool(settings, FreeRDP_GatewayUseSameCredentials, file->PromptCredentialOnce); - + if (~file->RemoteApplicationMode) freerdp_set_param_bool(settings, FreeRDP_RemoteApplicationMode, file->RemoteApplicationMode); + if (~((size_t) file->RemoteApplicationProgram)) { - if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationProgram, file->RemoteApplicationProgram) != 0) + if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationProgram, + file->RemoteApplicationProgram) != 0) return FALSE; } + if (~((size_t) file->RemoteApplicationName)) { - if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationName, file->RemoteApplicationName) != 0) + if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationName, + file->RemoteApplicationName) != 0) return FALSE; } + if (~((size_t) file->RemoteApplicationIcon)) { - if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationIcon, file->RemoteApplicationIcon) != 0) + if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationIcon, + file->RemoteApplicationIcon) != 0) return FALSE; } + if (~((size_t) file->RemoteApplicationFile)) { - if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationGuid, file->RemoteApplicationGuid) != 0) + if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationGuid, + file->RemoteApplicationGuid) != 0) return FALSE; } + if (~((size_t) file->RemoteApplicationCmdLine)) { - if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationCmdLine, file->RemoteApplicationCmdLine) != 0) + if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationCmdLine, + file->RemoteApplicationCmdLine) != 0) return FALSE; } if (~file->SpanMonitors) freerdp_set_param_bool(settings, FreeRDP_SpanMonitors, file->SpanMonitors); + if (~file->UseMultiMon) freerdp_set_param_bool(settings, FreeRDP_UseMultimon, file->UseMultiMon); if (~file->AllowFontSmoothing) freerdp_set_param_bool(settings, FreeRDP_AllowFontSmoothing, file->AllowFontSmoothing); + if (~file->DisableWallpaper) freerdp_set_param_bool(settings, FreeRDP_DisableWallpaper, file->DisableWallpaper); + if (~file->DisableFullWindowDrag) freerdp_set_param_bool(settings, FreeRDP_DisableFullWindowDrag, file->DisableFullWindowDrag); + if (~file->DisableMenuAnims) freerdp_set_param_bool(settings, FreeRDP_DisableMenuAnims, file->DisableMenuAnims); + if (~file->DisableThemes) freerdp_set_param_bool(settings, FreeRDP_DisableThemes, file->DisableThemes); + if (~file->AllowDesktopComposition) freerdp_set_param_bool(settings, FreeRDP_AllowDesktopComposition, file->AllowDesktopComposition); @@ -1090,10 +1153,12 @@ freerdp_set_param_bool(settings, FreeRDP_BitmapCachePersistEnabled, file->BitmapCachePersistEnable); if (~file->DisableRemoteAppCapsCheck) - freerdp_set_param_bool(settings, FreeRDP_DisableRemoteAppCapsCheck, file->DisableRemoteAppCapsCheck); + freerdp_set_param_bool(settings, FreeRDP_DisableRemoteAppCapsCheck, + file->DisableRemoteAppCapsCheck); if (~file->AutoReconnectionEnabled) freerdp_set_param_bool(settings, FreeRDP_AutoReconnectionEnabled, file->AutoReconnectionEnabled); + if (~file->AutoReconnectMaxRetries) freerdp_set_param_uint32(settings, FreeRDP_AutoReconnectMaxRetries, file->AutoReconnectMaxRetries); @@ -1152,7 +1217,6 @@ * devicestoredirect:s:USB\VID_04A9&PID_30C1\6&4BD985D&0&2;,DynamicDevices * */ - freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE); } @@ -1164,7 +1228,6 @@ * Very similar to DevicesToRedirect, but can contain a * comma-separated list of drive letters to redirect. */ - freerdp_set_param_bool(settings, FreeRDP_RedirectDrives, TRUE); } @@ -1176,10 +1239,11 @@ if (file->argc > 1) { char* ConnectionFile = settings->ConnectionFile; - settings->ConnectionFile = NULL; + if (freerdp_client_settings_parse_command_line(settings, file->argc, file->argv, FALSE) < 0) return FALSE; + settings->ConnectionFile = ConnectionFile; } @@ -1189,9 +1253,7 @@ static rdpFileLine* freerdp_client_rdp_file_find_line_index(rdpFile* file, int index) { rdpFileLine* line; - line = &(file->lines[index]); - return line; } @@ -1232,19 +1294,21 @@ int length; char* text; rdpFileLine* line; - length = _scprintf("%s:s:%s", name, value); text = (char*) malloc(length + 1); + if (!text) return -1; + sprintf_s(text, length + 1, "%s:s:%s", name, value ? value : ""); text[length] = '\0'; - line = freerdp_client_rdp_file_find_line_by_name(file, name); + if (line) { free(line->sValue); line->sValue = _strdup(value); + if (!line->sValue) goto out_fail; @@ -1254,6 +1318,7 @@ else { index = freerdp_client_parse_rdp_file_add_line(file, text, -1); + if (index == -1) goto out_fail; @@ -1267,17 +1332,14 @@ } return 0; - out_fail: free(text); return -1; - } const char* freerdp_client_rdp_file_get_string_option(rdpFile* file, const char* name) { rdpFileLine* line; - line = freerdp_client_rdp_file_find_line_by_name(file, name); if (!line) @@ -1295,9 +1357,7 @@ int length; char* text; rdpFileLine* line; - line = freerdp_client_rdp_file_find_line_by_name(file, name); - length = _scprintf("%s:i:%d", name, value); text = (char*) malloc(length + 1); sprintf_s(text, length + 1, "%s:i:%d", name, value); @@ -1306,18 +1366,19 @@ if (line) { line->iValue = value; - free(line->text); line->text = text; } else { index = freerdp_client_parse_rdp_file_add_line(file, text, -1); + if (index < 0) { free(text); return -1; } + line = freerdp_client_rdp_file_find_line_index(file, index); if (freerdp_client_rdp_file_set_integer(file, (char*) name, value, index) < 0) @@ -1335,7 +1396,6 @@ int freerdp_client_rdp_file_get_integer_option(rdpFile* file, const char* name) { rdpFileLine* line; - line = freerdp_client_rdp_file_find_line_by_name(file, name); if (!line) @@ -1356,26 +1416,25 @@ rdpFile* freerdp_client_rdp_file_new() { rdpFile* file; - file = (rdpFile*) malloc(sizeof(rdpFile)); if (file) { FillMemory(file, sizeof(rdpFile), 0xFF); - file->lineCount = 0; file->lineSize = 32; file->lines = (rdpFileLine*) malloc(file->lineSize * sizeof(rdpFileLine)); + if (!file->lines) { free(file); return NULL; } - file->argc = 0; file->argSize = 32; file->argv = (char**) malloc(file->argSize * sizeof(char*)); + if (!file->argv) { free(file->lines); @@ -1423,6 +1482,7 @@ freerdp_client_file_string_check_free(file->Username); freerdp_client_file_string_check_free(file->Domain); + freerdp_client_file_string_check_free(file->Password); freerdp_client_file_string_check_free(file->FullAddress); freerdp_client_file_string_check_free(file->AlternateFullAddress); freerdp_client_file_string_check_free(file->UsbDevicesToRedirect); @@ -1440,7 +1500,6 @@ freerdp_client_file_string_check_free(file->DrivesToRedirect); freerdp_client_file_string_check_free(file->DevicesToRedirect); freerdp_client_file_string_check_free(file->WinPosStr); - free(file); } } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/common/test/TestClientRdpFile.c freerdp-2.0.0~dev201703030839+dfsg/client/common/test/TestClientRdpFile.c --- freerdp-2.0.0~dev201701161718+dfsg/client/common/test/TestClientRdpFile.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/common/test/TestClientRdpFile.c 2017-03-03 08:39:24.000000000 +0000 @@ -5,7 +5,7 @@ #include -static BYTE testRdpFileUTF16[] = +static const BYTE testRdpFileUTF16[] = { 0xff, 0xfe, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, @@ -210,55 +210,55 @@ }; static char testRdpFileUTF8[] = - "screen mode id:i:2\n" - "use multimon:i:0\n" - "desktopwidth:i:1920\n" - "desktopheight:i:1080\n" - "session bpp:i:32\n" - "winposstr:s:0,1,553,211,1353,811\n" - "compression:i:1\n" - "keyboardhook:i:2\n" - "audiocapturemode:i:0\n" - "videoplaybackmode:i:1\n" - "connection type:i:7\n" - "networkautodetect:i:1\n" - "bandwidthautodetect:i:1\n" - "displayconnectionbar:i:1\n" - "enableworkspacereconnect:i:0\n" - "disable wallpaper:i:0\n" - "allow font smoothing:i:0\n" - "allow desktop composition:i:0\n" - "disable full window drag:i:1\n" - "disable menu anims:i:1\n" - "disable themes:i:0\n" - "disable cursor setting:i:0\n" - "bitmapcachepersistenable:i:1\n" - "full address:s:LAB1-W7-DM-01.lab1.awake.local\n" - "audiomode:i:0\n" - "redirectprinters:i:1\n" - "redirectcomports:i:0\n" - "redirectsmartcards:i:1\n" - "redirectclipboard:i:1\n" - "redirectposdevices:i:0\n" - "autoreconnection enabled:i:1\n" - "authentication level:i:2\n" - "prompt for credentials:i:0\n" - "negotiate security layer:i:1\n" - "remoteapplicationmode:i:0\n" - "alternate shell:s:\n" - "shell working directory:s:\n" - "gatewayhostname:s:LAB1-W2K8R2-GW.lab1.awake.local\n" - "gatewayusagemethod:i:1\n" - "gatewaycredentialssource:i:0\n" - "gatewayprofileusagemethod:i:1\n" - "promptcredentialonce:i:1\n" - "use redirection server name:i:0\n" - "rdgiskdcproxy:i:0\n" - "kdcproxyname:s:\n" - "drivestoredirect:s:*\n" - "username:s:LAB1\\JohnDoe\n" - "vendor integer:i:123\n" - "vendor string:s:microsoft\n"; + "screen mode id:i:2\n" + "use multimon:i:0\n" + "desktopwidth:i:1920\n" + "desktopheight:i:1080\n" + "session bpp:i:32\n" + "winposstr:s:0,1,553,211,1353,811\n" + "compression:i:1\n" + "keyboardhook:i:2\n" + "audiocapturemode:i:0\n" + "videoplaybackmode:i:1\n" + "connection type:i:7\n" + "networkautodetect:i:1\n" + "bandwidthautodetect:i:1\n" + "displayconnectionbar:i:1\n" + "enableworkspacereconnect:i:0\n" + "disable wallpaper:i:0\n" + "allow font smoothing:i:0\n" + "allow desktop composition:i:0\n" + "disable full window drag:i:1\n" + "disable menu anims:i:1\n" + "disable themes:i:0\n" + "disable cursor setting:i:0\n" + "bitmapcachepersistenable:i:1\n" + "full address:s:LAB1-W7-DM-01.lab1.awake.local\n" + "audiomode:i:0\n" + "redirectprinters:i:1\n" + "redirectcomports:i:0\n" + "redirectsmartcards:i:1\n" + "redirectclipboard:i:1\n" + "redirectposdevices:i:0\n" + "autoreconnection enabled:i:1\n" + "authentication level:i:2\n" + "prompt for credentials:i:0\n" + "negotiate security layer:i:1\n" + "remoteapplicationmode:i:0\n" + "alternate shell:s:\n" + "shell working directory:s:\n" + "gatewayhostname:s:LAB1-W2K8R2-GW.lab1.awake.local\n" + "gatewayusagemethod:i:1\n" + "gatewaycredentialssource:i:0\n" + "gatewayprofileusagemethod:i:1\n" + "promptcredentialonce:i:1\n" + "use redirection server name:i:0\n" + "rdgiskdcproxy:i:0\n" + "kdcproxyname:s:\n" + "drivestoredirect:s:*\n" + "username:s:LAB1\\JohnDoe\n" + "vendor integer:i:123\n" + "vendor string:s:microsoft\n"; int TestClientRdpFile(int argc, char* argv[]) { @@ -267,15 +267,15 @@ char* sValue; rdpFile* file; rdpFileLine* line; - /* Unicode */ - file = freerdp_client_rdp_file_new(); + if (!file) { printf("rdp_file_new failed\n"); return -1; } + freerdp_client_parse_rdp_file_buffer(file, testRdpFileUTF16, sizeof(testRdpFileUTF16)); if (file->UseMultiMon != 0) @@ -292,21 +292,20 @@ if (file->GatewayProfileUsageMethod != 1) { - printf("GatewayProfileUsageMethod mismatch: Actual: %"PRIu32", Expected: 1\n", file->GatewayProfileUsageMethod); + printf("GatewayProfileUsageMethod mismatch: Actual: %"PRIu32", Expected: 1\n", + file->GatewayProfileUsageMethod); return -1; } if (strcmp(file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local") != 0) { printf("GatewayHostname mismatch: Actual: %s, Expected: %s\n", - file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local"); + file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local"); return -1; } freerdp_client_rdp_file_free(file); - /* Ascii */ - file = freerdp_client_rdp_file_new(); freerdp_client_parse_rdp_file_buffer(file, (BYTE*) testRdpFileUTF8, sizeof(testRdpFileUTF8)); @@ -324,18 +323,20 @@ if (file->GatewayProfileUsageMethod != 1) { - printf("GatewayProfileUsageMethod mismatch: Actual: %"PRIu32", Expected: 1\n", file->GatewayProfileUsageMethod); + printf("GatewayProfileUsageMethod mismatch: Actual: %"PRIu32", Expected: 1\n", + file->GatewayProfileUsageMethod); return -1; } if (strcmp(file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local") != 0) { printf("GatewayHostname mismatch: Actual: %s, Expected: %s\n", - file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local"); + file->GatewayHostname, "LAB1-W2K8R2-GW.lab1.awake.local"); return -1; } iValue = freerdp_client_rdp_file_get_integer_option(file, "vendor integer"); + if (freerdp_client_rdp_file_set_integer_option(file, "vendor integer", 456) == -1) { printf("failed to set integer: vendor integer"); @@ -343,12 +344,11 @@ } iValue = freerdp_client_rdp_file_get_integer_option(file, "vendor integer"); - sValue = (char*) freerdp_client_rdp_file_get_string_option(file, "vendor string"); freerdp_client_rdp_file_set_string_option(file, "vendor string", "apple"); sValue = (char*) freerdp_client_rdp_file_get_string_option(file, "vendor string"); - freerdp_client_rdp_file_set_string_option(file, "fruits", "banana,oranges"); + if (freerdp_client_rdp_file_set_integer_option(file, "numbers", 123456789) == -1) { printf("failed to set integer: numbers"); @@ -364,19 +364,18 @@ if (line->flags & RDP_FILE_LINE_FLAG_TYPE_STRING) { printf("line %02d: name: %s value: %s, %s\n", - line->index, line->name, line->sValue, - (line->flags & RDP_FILE_LINE_FLAG_STANDARD) ? "standard" : "non-standard"); + line->index, line->name, line->sValue, + (line->flags & RDP_FILE_LINE_FLAG_STANDARD) ? "standard" : "non-standard"); } else if (line->flags & RDP_FILE_LINE_FLAG_TYPE_INTEGER) { printf("line %02d: name: %s value: %"PRIu32", %s\n", - line->index, line->name, line->iValue, - (line->flags & RDP_FILE_LINE_FLAG_STANDARD) ? "standard" : "non-standard"); + line->index, line->name, line->iValue, + (line->flags & RDP_FILE_LINE_FLAG_STANDARD) ? "standard" : "non-standard"); } } } freerdp_client_rdp_file_free(file); - return 0; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/freerdp-client.pc.in freerdp-2.0.0~dev201703030839+dfsg/client/freerdp-client.pc.in --- freerdp-2.0.0~dev201701161718+dfsg/client/freerdp-client.pc.in 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/freerdp-client.pc.in 2017-03-03 08:39:24.000000000 +0000 @@ -2,7 +2,7 @@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=${prefix}/@FREERDP_INCLUDE_DIR@ -libs=-lfreerdp-client +libs=-lfreerdp-client@FREERDP_API_VERSION@ Name: FreeRDP client Description: FreeRDP: A Remote Desktop Protocol Implementation diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/.gitignore freerdp-2.0.0~dev201703030839+dfsg/client/.gitignore --- freerdp-2.0.0~dev201701161718+dfsg/client/.gitignore 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/.gitignore 2017-03-03 08:39:24.000000000 +0000 @@ -10,3 +10,4 @@ !/Wayland !/CMakeLists.txt !*.in +Wayland/wlfreerdp.1 diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/Sample/freerdp.c freerdp-2.0.0~dev201703030839+dfsg/client/Sample/freerdp.c --- freerdp-2.0.0~dev201701161718+dfsg/client/Sample/freerdp.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/Sample/freerdp.c 2017-03-03 08:39:24.000000000 +0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -174,6 +175,8 @@ instance->ContextNew = tf_context_new; instance->ContextFree = tf_context_free; + freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); + if (!freerdp_context_new(instance)) { WLog_ERR(TAG, "Couldn't create context"); @@ -188,6 +191,7 @@ exit(0); } + if (!freerdp_client_load_addins(instance->context->channels, instance->settings)) exit(-1); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/Wayland/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/client/Wayland/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/client/Wayland/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/Wayland/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -39,3 +39,5 @@ install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Wayland") +configure_file(wlfreerdp.1.in ${CMAKE_CURRENT_BINARY_DIR}/wlfreerdp.1) +install_freerdp_man(${CMAKE_CURRENT_BINARY_DIR}/wlfreerdp.1 1) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/Wayland/wlfreerdp.1.in freerdp-2.0.0~dev201703030839+dfsg/client/Wayland/wlfreerdp.1.in --- freerdp-2.0.0~dev201701161718+dfsg/client/Wayland/wlfreerdp.1.in 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/Wayland/wlfreerdp.1.in 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,38 @@ +.de URL +\\$2 \(laURL: \\$1 \(ra\\$3 +.. +.if \n[.g] .mso www.tmac)) +.TH wlfreerdp 1 2017-01-12 "@FREERDP_VERSION_FULL@" "FreeRDP" +.SH NAME +wlfreerdp \- FreeRDP wayland client +.SH SYNOPSIS +.B wlfreerdp +[file] +[\fIdefault_client_options\fP] +[\fB/v\fP:[:port]] +[\fB/version\fP] +[\fB/help\fP] +.SH DESCRIPTION +.B wlfreerdp +is a wayland Remote Desktop Protocol (RDP) client which is part of the FreeRDP project. A RDP server is built-in to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox). +.SH OPTIONS +The wayland client also supports a lot of the \fIdefault client options\fP which are not described here. For details on those see the xfreerdp(1) man page. +.IP \fB/v:\fP\fI[:port]\fP +The server hostname or IP, and optionally the port, to connect to. +.IP /version +Print the version and exit. +.IP /help +Print the help and exit. +.SH EXIT STATUS +.TP +.B 0 +Successful program execution. +.TP +.B not 0 +On failure. + +.SH SEE ALSO +xfreerdp(1) wlog(7) + +.SH AUTHOR +FreeRDP diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/client/X11/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -111,11 +111,7 @@ add_custom_target(xfreerdp.manpage ALL DEPENDS xfreerdp.1) - if(OPENBSD) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1 DESTINATION man/man1) - else() - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1 DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/man/man1) - endif() + install_freerdp_man(${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1 1) else() message(WARNING "WITH_MANPAGES was set, but xsltproc was not found. man-pages will not be installed") endif() diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_client.c freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_client.c --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_client.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_client.c 2017-03-03 08:39:24.000000000 +0000 @@ -375,8 +375,8 @@ } if (!(xfc->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, - 0, - (char*) gdi->primary_buffer, gdi->width, gdi->height, xfc->scanline_pad, 0))) + 0, (char*)gdi->primary_buffer, gdi->width, + gdi->height, xfc->scanline_pad, gdi->stride))) { goto out; } @@ -627,7 +627,7 @@ xfc->depth, ZPixmap, 0, (char*) gdi->primary_buffer, settings->DesktopWidth, settings->DesktopHeight, - xfc->scanline_pad, 0); + xfc->scanline_pad, gdi->stride); } return TRUE; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_cliprdr.c freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_cliprdr.c --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_cliprdr.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_cliprdr.c 2017-03-03 08:39:24.000000000 +0000 @@ -81,10 +81,12 @@ int requestedFormatId; BYTE* data; + BYTE* data_raw; BOOL data_raw_format; UINT32 data_format_id; const char* data_format_name; int data_length; + int data_raw_length; XEvent* respond; Window owner; @@ -774,6 +776,23 @@ } } +static void xf_cliprdr_clear_cached_data(xfClipboard* clipboard) +{ + if (clipboard->data) + { + free(clipboard->data); + clipboard->data = NULL; + } + clipboard->data_length = 0; + + if (clipboard->data_raw) + { + free(clipboard->data_raw); + clipboard->data_raw = NULL; + } + clipboard->data_raw_length = 0; +} + static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent* xevent) { @@ -785,6 +804,7 @@ BYTE* data = NULL; BOOL delayRespond; BOOL rawTransfer; + BOOL matchingFormat; unsigned long length; unsigned long bytes_left; CLIPRDR_FORMAT* format; @@ -847,14 +867,24 @@ } } - if ((clipboard->data != 0) && (formatId == clipboard->data_format_id) - && (formatName == clipboard->data_format_name)) + /* We can compare format names by pointer value here as they are both + * taken from the same clipboard->serverFormats array */ + matchingFormat = (formatId == clipboard->data_format_id) + && (formatName == clipboard->data_format_name); + + if (matchingFormat && (clipboard->data != 0) && !rawTransfer) { - /* Cached clipboard data available. Send it now */ + /* Cached converted clipboard data available. Send it now */ respond->xselection.property = xevent->xselectionrequest.property; xf_cliprdr_provide_data(clipboard, respond, clipboard->data, clipboard->data_length); } + else if (matchingFormat && (clipboard->data_raw != 0) && rawTransfer) + { + /* Cached raw clipboard data available. Send it now */ + respond->xselection.property = xevent->xselectionrequest.property; + xf_cliprdr_provide_data(clipboard, respond, clipboard->data_raw, clipboard->data_raw_length); + } else if (clipboard->respond) { /* duplicate request */ @@ -865,11 +895,7 @@ * Send clipboard data request to the server. * Response will be postponed after receiving the data */ - if (clipboard->data) - { - free(clipboard->data); - clipboard->data = NULL; - } + xf_cliprdr_clear_cached_data(clipboard); respond->xselection.property = xevent->xselectionrequest.property; clipboard->respond = respond; @@ -908,11 +934,13 @@ XEvent* xevent) { xfCliprdrFormat* format; - xfContext* xfc = clipboard->xfc; + xfContext* xfc = NULL; if (!clipboard) return TRUE; + xfc = clipboard->xfc; + if (xevent->xproperty.atom != clipboard->property_atom) return FALSE; /* Not cliprdr-related */ @@ -1126,11 +1154,7 @@ xfContext* xfc = clipboard->xfc; UINT ret; - if (clipboard->data) - { - free(clipboard->data); - clipboard->data = NULL; - } + xf_cliprdr_clear_cached_data(clipboard); clipboard->data_format_id = -1; clipboard->data_format_name = NULL; @@ -1274,11 +1298,7 @@ if (!clipboard->respond) return CHANNEL_RC_OK; - if (clipboard->data) - { - free(clipboard->data); - clipboard->data = NULL; - } + xf_cliprdr_clear_cached_data(clipboard); pDstData = NULL; DstSize = 0; @@ -1343,8 +1363,25 @@ } } + /* Cache converted and original data to avoid doing a possibly costly + * conversion again on subsequent requests */ clipboard->data = pDstData; clipboard->data_length = DstSize; + + /* We have to copy the original data again, as pSrcData is now owned + * by clipboard->system. Memory allocation failure is not fatal here + * as this is only a cached value. */ + clipboard->data_raw = (BYTE*) malloc(size); + if (clipboard->data_raw) + { + CopyMemory(clipboard->data_raw, data, size); + clipboard->data_raw_length = size; + } + else + { + WLog_WARN(TAG, "failed to allocate %"PRIu32" bytes for a copy of raw clipboard data", size); + } + xf_cliprdr_provide_data(clipboard, clipboard->respond, pDstData, DstSize); XSendEvent(xfc->display, clipboard->respond->xselection.requestor, 0, 0, clipboard->respond); @@ -1489,6 +1526,7 @@ ClipboardDestroy(clipboard->system); free(clipboard->data); + free(clipboard->data_raw); free(clipboard->respond); free(clipboard->incr_data); free(clipboard); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_event.c freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_event.c --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_event.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_event.c 2017-03-03 08:39:24.000000000 +0000 @@ -97,7 +97,7 @@ return FALSE; ArrayList_Object(xfc->xevents)->fnObjectFree = free; - sprintf_s(command, sizeof(command), "%s xevent", xfc->actionScript); + sprintf_s(command, sizeof(command), "%s xevent", xfc->context.settings->ActionScript); actionScript = popen(command, "r"); if (!actionScript) @@ -140,7 +140,7 @@ char buffer[1024] = { 0 }; char command[1024] = { 0 }; - if (!xfc->actionScript || !xfc->xevents) + if (!xfc->actionScriptExists || !xfc->xevents) return FALSE; if (event->type > (sizeof(X11_EVENT_STRINGS) / sizeof(const char*))) @@ -164,7 +164,7 @@ return FALSE; sprintf_s(command, sizeof(command), "%s xevent %s %lu", - xfc->actionScript, xeventName, (unsigned long) xfc->window->handle); + xfc->context.settings->ActionScript, xeventName, (unsigned long) xfc->window->handle); actionScript = popen(command, "r"); if (!actionScript) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_gdi.c freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_gdi.c --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_gdi.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_gdi.c 2017-03-03 08:39:24.000000000 +0000 @@ -321,15 +321,14 @@ static BOOL xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { const rdpBrush* brush; - UINT32 foreColor; - UINT32 backColor; xfContext* xfc = (xfContext*) context; BOOL ret = FALSE; + XColor xfg, xbg; - if (!xf_decode_color(context->gdi, patblt->foreColor, &foreColor, NULL)) + if (!xf_decode_color(xfc, patblt->foreColor, &xfg)) return FALSE; - if (!xf_decode_color(context->gdi, patblt->backColor, &backColor, NULL)) + if (!xf_decode_color(xfc, patblt->backColor, &xbg)) return FALSE; xf_lock_x11(xfc, FALSE); @@ -342,8 +341,8 @@ { case GDI_BS_SOLID: XSetFillStyle(xfc->display, xfc->gc, FillSolid); - XSetBackground(xfc->display, xfc->gc, backColor); - XSetForeground(xfc->display, xfc->gc, foreColor); + XSetBackground(xfc->display, xfc->gc, xbg.pixel); + XSetForeground(xfc->display, xfc->gc, xfg.pixel); XFillRectangle(xfc->display, xfc->drawing, xfc->gc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); break; @@ -352,8 +351,8 @@ { 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); + XSetBackground(xfc->display, xfc->gc, xbg.pixel); + XSetForeground(xfc->display, xfc->gc, xfg.pixel); XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); XSetStipple(xfc->display, xfc->gc, pattern); XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); @@ -378,8 +377,8 @@ else { Pixmap pattern = xf_mono_bitmap_new(xfc, 8, 8, brush->data); - XSetBackground(xfc->display, xfc->gc, foreColor); - XSetForeground(xfc->display, xfc->gc, backColor); + XSetBackground(xfc->display, xfc->gc, xfg.pixel); + XSetForeground(xfc->display, xfc->gc, xbg.pixel); XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); XSetStipple(xfc->display, xfc->gc, pattern); XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); @@ -437,18 +436,17 @@ static BOOL xf_gdi_opaque_rect(rdpContext* context, const OPAQUE_RECT_ORDER* opaque_rect) { - UINT32 color; - rdpGdi* gdi = context->gdi; + XColor color; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - if (!xf_decode_color(gdi, opaque_rect->color, &color, NULL)) + if (!xf_decode_color(xfc, opaque_rect->color, &color)) return FALSE; xf_lock_x11(xfc, FALSE); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); - XSetForeground(xfc->display, xfc->gc, color); + XSetForeground(xfc->display, xfc->gc, color.pixel); XFillRectangle(xfc->display, xfc->drawing, xfc->gc, opaque_rect->nLeftRect, opaque_rect->nTopRect, opaque_rect->nWidth, opaque_rect->nHeight); @@ -468,16 +466,15 @@ UINT32 i; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - rdpGdi* gdi = context->gdi; - UINT32 color; + XColor color; - if (!xf_decode_color(gdi, multi_opaque_rect->color, &color, NULL)) + if (!xf_decode_color(xfc, multi_opaque_rect->color, &color)) return FALSE; xf_lock_x11(xfc, FALSE); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); - XSetForeground(xfc->display, xfc->gc, color); + XSetForeground(xfc->display, xfc->gc, color.pixel); for (i = 0; i < multi_opaque_rect->numRectangles; i++) { @@ -500,17 +497,17 @@ static BOOL xf_gdi_line_to(rdpContext* context, const LINE_TO_ORDER* line_to) { - UINT32 color; + XColor color; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - if (!xf_decode_color(context->gdi, line_to->penColor, &color, NULL)) + if (!xf_decode_color(xfc, line_to->penColor, &color)) return FALSE; xf_lock_x11(xfc, FALSE); xf_set_rop2(xfc, line_to->bRop2); XSetFillStyle(xfc->display, xfc->gc, FillSolid); - XSetForeground(xfc->display, xfc->gc, color); + XSetForeground(xfc->display, xfc->gc, color.pixel); XDrawLine(xfc->display, xfc->drawing, xfc->gc, line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd); @@ -569,18 +566,18 @@ { int i; int npoints; - UINT32 color; + XColor color; XPoint* points; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - if (!xf_decode_color(context->gdi, polyline->penColor, &color, NULL)) + if (!xf_decode_color(xfc, polyline->penColor, &color)) return FALSE; xf_lock_x11(xfc, FALSE); xf_set_rop2(xfc, polyline->bRop2); XSetFillStyle(xfc->display, xfc->gc, FillSolid); - XSetForeground(xfc->display, xfc->gc, color); + XSetForeground(xfc->display, xfc->gc, color.pixel); npoints = polyline->numDeltaEntries + 1; points = malloc(sizeof(XPoint) * npoints); @@ -652,8 +649,8 @@ { const rdpBrush* brush; xfBitmap* bitmap; - UINT32 foreColor; - UINT32 backColor; + XColor foreColor; + XColor backColor; Pixmap pattern = 0; xfContext* xfc = (xfContext*) context; BOOL ret = FALSE; @@ -661,10 +658,10 @@ if (!xfc->display || !xfc->drawing) return FALSE; - if (!xf_decode_color(context->gdi, mem3blt->foreColor, &foreColor, NULL)) + if (!xf_decode_color(xfc, mem3blt->foreColor, &foreColor)) return FALSE; - if (!xf_decode_color(context->gdi, mem3blt->backColor, &backColor, NULL)) + if (!xf_decode_color(xfc, mem3blt->backColor, &backColor)) return FALSE; xf_lock_x11(xfc, FALSE); @@ -687,8 +684,8 @@ else { pattern = xf_mono_bitmap_new(xfc, 8, 8, brush->data); - XSetBackground(xfc->display, xfc->gc, backColor); - XSetForeground(xfc->display, xfc->gc, foreColor); + XSetBackground(xfc->display, xfc->gc, backColor.pixel); + XSetForeground(xfc->display, xfc->gc, foreColor.pixel); XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); XSetStipple(xfc->display, xfc->gc, pattern); XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); @@ -698,8 +695,8 @@ case GDI_BS_SOLID: XSetFillStyle(xfc->display, xfc->gc, FillSolid); - XSetBackground(xfc->display, xfc->gc, backColor); - XSetForeground(xfc->display, xfc->gc, foreColor); + XSetBackground(xfc->display, xfc->gc, backColor.pixel); + XSetForeground(xfc->display, xfc->gc, foreColor.pixel); XSetTSOrigin(xfc->display, xfc->gc, brush->x, brush->y); break; @@ -735,11 +732,11 @@ { int i, npoints; XPoint* points; - UINT32 brush_color; + XColor brush_color; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - if (!xf_decode_color(context->gdi, polygon_sc->brushColor, &brush_color, NULL)) + if (!xf_decode_color(xfc, polygon_sc->brushColor, &brush_color)) return FALSE; xf_lock_x11(xfc, FALSE); @@ -778,7 +775,7 @@ } XSetFillStyle(xfc->display, xfc->gc, FillSolid); - XSetForeground(xfc->display, xfc->gc, brush_color); + XSetForeground(xfc->display, xfc->gc, brush_color.pixel); XFillPolygon(xfc->display, xfc->drawing, xfc->gc, points, npoints, Complex, CoordModePrevious); @@ -801,15 +798,15 @@ XPoint* points; Pixmap pattern; const rdpBrush* brush; - UINT32 foreColor; - UINT32 backColor; + XColor foreColor; + XColor backColor; xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; - if (!xf_decode_color(context->gdi, polygon_cb->foreColor, &foreColor, NULL)) + if (!xf_decode_color(xfc, polygon_cb->foreColor, &foreColor)) return FALSE; - if (!xf_decode_color(context->gdi, polygon_cb->backColor, &backColor, NULL)) + if (!xf_decode_color(xfc, polygon_cb->backColor, &backColor)) return FALSE; xf_lock_x11(xfc, FALSE); @@ -859,8 +856,8 @@ else { pattern = xf_mono_bitmap_new(xfc, 8, 8, brush->data); - XSetForeground(xfc->display, xfc->gc, backColor); - XSetBackground(xfc->display, xfc->gc, foreColor); + XSetForeground(xfc->display, xfc->gc, backColor.pixel); + XSetBackground(xfc->display, xfc->gc, foreColor.pixel); if (polygon_cb->backMode == BACKMODE_TRANSPARENT) XSetFillStyle(xfc->display, xfc->gc, FillStippled); @@ -972,7 +969,7 @@ static BOOL xf_gdi_update_screen(xfContext* xfc, const SURFACE_BITS_COMMAND* cmd, - const BYTE* pSrcData) + const BYTE* pSrcData, UINT32 scanline) { BOOL ret = FALSE; XImage* image; @@ -983,7 +980,8 @@ 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); + (char*) pSrcData, cmd->width, cmd->height, + xfc->scanline_pad, scanline); if (image) { @@ -1005,14 +1003,12 @@ 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); switch (cmd->codecID) @@ -1020,18 +1016,16 @@ case RDP_CODEC_ID_REMOTEFX: if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength, 0, 0, - gdi->primary_buffer, gdi->dstFormat, stride, + gdi->primary_buffer, gdi->dstFormat, gdi->stride, gdi->height, NULL)) goto fail; break; case RDP_CODEC_ID_NSCODEC: - format = gdi->dstFormat; - if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength, - gdi->primary_buffer, format, stride, + gdi->primary_buffer, gdi->dstFormat, gdi->stride, 0, 0, cmd->width, cmd->height, FREERDP_FLIP_VERTICAL)) goto fail; @@ -1041,10 +1035,10 @@ pSrcData = cmd->bitmapData; format = gdi_get_pixel_format(cmd->bpp); - 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)) + if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, + 0, 0, cmd->width, cmd->height, + pSrcData, format, 0, 0, 0, + &xfc->context.gdi->palette, FREERDP_FLIP_VERTICAL)) goto fail; break; @@ -1055,7 +1049,7 @@ goto fail; } - ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); + ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer, gdi->stride); fail: xf_unlock_x11(xfc, FALSE); return ret; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_gfx.c freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_gfx.c --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_gfx.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_gfx.c 2017-03-03 08:39:24.000000000 +0000 @@ -176,8 +176,9 @@ return status; } -static INLINE UINT32 x11_pad_scanline(UINT32 scanline, UINT32 inPad) +UINT32 x11_pad_scanline(UINT32 scanline, UINT32 inPad) { + /* Ensure X11 alignment is met */ if (inPad > 0) { const UINT32 align = inPad / 8; @@ -187,6 +188,10 @@ scanline += pad; } + /* 16 byte alingment is required for ASM optimized code */ + if (scanline % 16) + scanline += 16 - scanline % 16; + return scanline; } @@ -275,7 +280,7 @@ 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); + xfc->scanline_pad, surface->stageScanline); } surface->gdi.outputMapped = FALSE; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_graphics.c freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_graphics.c --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_graphics.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_graphics.c 2017-03-03 08:39:24.000000000 +0000 @@ -42,25 +42,58 @@ #include #define TAG CLIENT_TAG("x11") -BOOL xf_decode_color(rdpGdi* gdi, const UINT32 srcColor, - UINT32* color, UINT32* format) +BOOL xf_decode_color(xfContext* xfc, const UINT32 srcColor, XColor* color) { - xfContext* xfc; - UINT32 DstFormat; + rdpGdi* gdi; + rdpSettings* settings; UINT32 SrcFormat; + BYTE r, g, b, a; + + if (!xfc || !color) + return FALSE; - if (!gdi || !gdi->context || !gdi->context->settings) + gdi = xfc->context.gdi; + + if (!gdi) return FALSE; - xfc = (xfContext*)gdi->context; - SrcFormat = gdi_get_pixel_format(gdi->context->settings->ColorDepth); + settings = xfc->context.settings; + + if (!settings) + return FALSE; - if (format) - *format = SrcFormat; + switch (settings->ColorDepth) + { + case 32: + case 24: + SrcFormat = PIXEL_FORMAT_BGR24; + break; + + case 16: + SrcFormat = PIXEL_FORMAT_RGB16; + break; + + case 15: + SrcFormat = PIXEL_FORMAT_RGB15; + break; + + case 8: + SrcFormat = PIXEL_FORMAT_RGB8; + break; + + default: + return FALSE; + } + + SplitColor(srcColor, SrcFormat, &r, &g, &b, &a, &gdi->palette); + color->blue = (unsigned short)(b << 8); + color->green = (unsigned short)(g << 8); + color->red = (unsigned short)(r << 8); + color->flags = DoRed | DoGreen | DoBlue; + + if (XAllocColor(xfc->display, xfc->colormap, color) == 0) + return FALSE; - DstFormat = xf_get_local_color_format(xfc, FALSE); - *color = ConvertColor(srcColor, SrcFormat, - DstFormat, &gdi->palette); return TRUE; } @@ -71,7 +104,6 @@ BYTE* data; Pixmap pixmap; XImage* image; - UINT32 SrcFormat; rdpGdi* gdi; xfContext* xfc = (xfContext*) context; gdi = context->gdi; @@ -93,10 +125,9 @@ return FALSE; } - SrcFormat = bitmap->format; freerdp_image_copy(data, gdi->dstFormat, 0, 0, 0, bitmap->width, bitmap->height, - bitmap->data, SrcFormat, + bitmap->data, bitmap->format, 0, 0, 0, &context->gdi->palette, FREERDP_FLIP_NONE); _aligned_free(bitmap->data); bitmap->data = data; @@ -395,11 +426,12 @@ { xfContext* xfc = (xfContext*) context; XRectangle rect; + XColor xbgcolor, xfgcolor; - if (!xf_decode_color(context->gdi, bgcolor, &bgcolor, NULL)) + if (!xf_decode_color(xfc, bgcolor, &xbgcolor)) return FALSE; - if (!xf_decode_color(context->gdi, fgcolor, &fgcolor, NULL)) + if (!xf_decode_color(xfc, fgcolor, &xfgcolor)) return FALSE; rect.x = x; @@ -410,14 +442,14 @@ if (!fOpRedundant) { - XSetForeground(xfc->display, xfc->gc, fgcolor); - XSetBackground(xfc->display, xfc->gc, fgcolor); + XSetForeground(xfc->display, xfc->gc, xfgcolor.pixel); + XSetBackground(xfc->display, xfc->gc, xfgcolor.pixel); 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); + XSetForeground(xfc->display, xfc->gc, xbgcolor.pixel); + XSetBackground(xfc->display, xfc->gc, xfgcolor.pixel); xf_unlock_x11(xfc, FALSE); return TRUE; } @@ -428,11 +460,12 @@ { xfContext* xfc = (xfContext*) context; BOOL ret = TRUE; + XColor xfgcolor, xbgcolor; - if (!xf_decode_color(context->gdi, bgcolor, &bgcolor, NULL)) + if (!xf_decode_color(xfc, bgcolor, &xbgcolor)) return FALSE; - if (!xf_decode_color(context->gdi, fgcolor, &fgcolor, NULL)) + if (!xf_decode_color(xfc, fgcolor, &xfgcolor)) return FALSE; if (xfc->drawing == xfc->primary) @@ -490,11 +523,13 @@ UINT32 xf_get_local_color_format(xfContext* xfc, BOOL aligned) { UINT32 DstFormat; - BOOL invert = !(aligned ^ xfc->invert); + BOOL invert = FALSE; if (!xfc) return 0; + invert = xfc->invert; + if (xfc->depth == 32) DstFormat = (!invert) ? PIXEL_FORMAT_RGBA32 : PIXEL_FORMAT_BGRA32; else if (xfc->depth == 24) @@ -505,9 +540,9 @@ DstFormat = (!invert) ? PIXEL_FORMAT_RGB24 : PIXEL_FORMAT_BGR24; } else if (xfc->depth == 16) - DstFormat = (!invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16; + DstFormat = PIXEL_FORMAT_RGB16; else if (xfc->depth == 15) - DstFormat = (!invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16; + DstFormat = PIXEL_FORMAT_RGB15; else DstFormat = (!invert) ? PIXEL_FORMAT_RGBX32 : PIXEL_FORMAT_BGRX32; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_graphics.h freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_graphics.h --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_graphics.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_graphics.h 2017-03-03 08:39:24.000000000 +0000 @@ -26,8 +26,7 @@ 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); +BOOL xf_decode_color(xfContext* xfc, const UINT32 srcColor, XColor* color); UINT32 xf_get_local_color_format(xfContext* xfc, BOOL aligned); #endif /* __XF_GRAPHICS_H */ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_keyboard.c freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_keyboard.c --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_keyboard.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_keyboard.c 2017-03-03 08:39:24.000000000 +0000 @@ -53,16 +53,9 @@ char buffer[1024] = { 0 }; char command[1024] = { 0 }; - if (xfc->actionScript) - { - free(xfc->actionScript); - xfc->actionScript = NULL; - } - - if (PathFileExistsA("/usr/share/freerdp/action.sh")) - xfc->actionScript = _strdup("/usr/share/freerdp/action.sh"); + xfc->actionScriptExists = PathFileExistsA(xfc->context.settings->ActionScript); - if (!xfc->actionScript) + if (!xfc->actionScriptExists) return FALSE; xfc->keyCombinations = ArrayList_New(TRUE); @@ -71,13 +64,12 @@ return FALSE; ArrayList_Object(xfc->keyCombinations)->fnObjectFree = free; - sprintf_s(command, sizeof(command), "%s key", xfc->actionScript); + sprintf_s(command, sizeof(command), "%s key", xfc->context.settings->ActionScript); keyScript = popen(command, "r"); if (!keyScript) { - free(xfc->actionScript); - xfc->actionScript = NULL; + xfc->actionScriptExists = FALSE; return FALSE; } @@ -89,8 +81,7 @@ if (!keyCombination || ArrayList_Add(xfc->keyCombinations, keyCombination) < 0) { ArrayList_Free(xfc->keyCombinations); - free(xfc->actionScript); - xfc->actionScript = NULL; + xfc->actionScriptExists = FALSE; pclose(keyScript); return FALSE; } @@ -108,12 +99,7 @@ { ArrayList_Free(xfc->keyCombinations); xfc->keyCombinations = NULL; - } - - if (xfc->actionScript) - { - free(xfc->actionScript); - xfc->actionScript = NULL; + xfc->actionScriptExists = FALSE; } } @@ -380,7 +366,7 @@ char command[1024] = { 0 }; char combination[1024] = { 0 }; - if (!xfc->actionScript) + if (!xfc->actionScriptExists) return 1; if ((keysym == XK_Shift_L) || (keysym == XK_Shift_R) || @@ -424,7 +410,7 @@ return 1; sprintf_s(command, sizeof(command), "%s key %s", - xfc->actionScript, combination); + xfc->context.settings->ActionScript, combination); keyScript = popen(command, "r"); if (!keyScript) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_keyboard.h freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_keyboard.h --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_keyboard.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_keyboard.h 2017-03-03 08:39:24.000000000 +0000 @@ -25,8 +25,6 @@ #include "xf_client.h" #include "xfreerdp.h" -#define XF_ACTION_SCRIPT "~/.config/freerdp/action.sh" - struct _XF_MODIFIER_KEYS { BOOL Shift; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_rail.c freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_rail.c --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_rail.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_rail.c 2017-03-03 08:39:24.000000000 +0000 @@ -217,12 +217,9 @@ updateRect.right = extents->right - appWindow->x; updateRect.bottom = extents->bottom - appWindow->y; - if (appWindow) - { - xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top, - updateRect.right - updateRect.left, - updateRect.bottom - updateRect.top); - } + xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top, + updateRect.right - updateRect.left, + updateRect.bottom - updateRect.top); } } } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xfreerdp.h freerdp-2.0.0~dev201703030839+dfsg/client/X11/xfreerdp.h --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xfreerdp.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xfreerdp.h 2017-03-03 08:39:24.000000000 +0000 @@ -171,7 +171,7 @@ XModifierKeymap* modifierMap; wArrayList* keyCombinations; wArrayList* xevents; - char* actionScript; + BOOL actionScriptExists; XSetWindowAttributes attribs; BOOL complex_regions; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_window.c freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_window.c --- freerdp-2.0.0~dev201701161718+dfsg/client/X11/xf_window.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/client/X11/xf_window.c 2017-03-03 08:39:24.000000000 +0000 @@ -945,6 +945,10 @@ int width, int height) { int ax, ay; + + if (appWindow == NULL) + return; + ax = x + appWindow->windowOffsetX; ay = y + appWindow->windowOffsetY; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/cmake/ConfigOptions.cmake freerdp-2.0.0~dev201703030839+dfsg/cmake/ConfigOptions.cmake --- freerdp-2.0.0~dev201701161718+dfsg/cmake/ConfigOptions.cmake 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/cmake/ConfigOptions.cmake 2017-03-03 08:39:24.000000000 +0000 @@ -128,6 +128,7 @@ option(WITH_DEBUG_RINGBUFFER "Enable Ringbuffer debug messages" ${DEFAULT_DEBUG_OPTION}) option(WITH_DEBUG_SYMBOLS "Pack debug symbols to installer" OFF) +option(WITH_CCACHE "Use ccache support if available" ON) if(ANDROID) include(ConfigOptionsAndroid) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/cmake/FindKRB5.cmake freerdp-2.0.0~dev201703030839+dfsg/cmake/FindKRB5.cmake --- freerdp-2.0.0~dev201701161718+dfsg/cmake/FindKRB5.cmake 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/cmake/FindKRB5.cmake 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,28 @@ +# - Try to find krb5 +# Once done this will define +# KRB5_FOUND - pcsc was found +# KRB5_INCLUDE_DIRS - pcsc include directories +# KRB5_LIBRARIES - libraries needed for linking + +include(FindPkgConfig) + +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_KRB5 QUIET libkrb5) +endif() + +find_path(KRB5_INCLUDE_DIR krb5.h + HINTS ${PC_KRB5_INCLUDEDIR} ${PC_KRB5_INCLUDE_DIRS} + PATH_SUFFIXES KRB5) + +find_library(KRB5_LIBRARY NAMES krb5 + HINTS ${PC_KRB5_LIBDIR} ${PC_KRB5_LIBRARY_DIRS}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(KRB5 DEFAULT_MSG KRB5_LIBRARY KRB5_INCLUDE_DIR) + +set(KRB5_LIBRARIES ${KRB5_LIBRARY}) +set(KRB5_INCLUDE_DIRS ${KRB5_INCLUDE_DIR}) + +mark_as_advanced(KRB5_INCLUDE_DIR KRB5_LIBRARY) + + diff -Nru freerdp-2.0.0~dev201701161718+dfsg/cmake/FindOpenSSL.cmake freerdp-2.0.0~dev201703030839+dfsg/cmake/FindOpenSSL.cmake --- freerdp-2.0.0~dev201701161718+dfsg/cmake/FindOpenSSL.cmake 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/cmake/FindOpenSSL.cmake 2017-03-03 08:39:24.000000000 +0000 @@ -24,10 +24,10 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -if (UNIX) +if (UNIX AND NOT ANDROID) find_package(PkgConfig QUIET) pkg_check_modules(_OPENSSL QUIET openssl) -endif (UNIX) +endif (UNIX AND NOT ANDROID) # http://www.slproweb.com/products/Win32OpenSSL.html SET(_OPENSSL_ROOT_HINTS @@ -71,7 +71,15 @@ endif() ENDIF(WIN32) -IF(WIN32 AND NOT CYGWIN) +IF(ANDROID) + FIND_LIBRARY(OPENSSL_LIBRARIES + NAMES + "freerdp-openssl" + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib" + ) +ELSEIF(WIN32 AND NOT CYGWIN) # MINGW should go here too IF(MSVC) # /MD and /MDd are the standard values - if someone wants to use @@ -230,7 +238,7 @@ SET(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) -ENDIF(WIN32 AND NOT CYGWIN) +ENDIF(ANDROID) function(from_hex HEX DEC) string(TOUPPER "${HEX}" HEX) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/cmake/InstallFreeRDPMan.cmake freerdp-2.0.0~dev201703030839+dfsg/cmake/InstallFreeRDPMan.cmake --- freerdp-2.0.0~dev201701161718+dfsg/cmake/InstallFreeRDPMan.cmake 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/cmake/InstallFreeRDPMan.cmake 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,9 @@ +function(install_freerdp_man manpage section) + if(WITH_MANPAGES) + if(OPENBSD) + install(FILES ${manpage} DESTINATION man/man${section}) + else() + install(FILES ${manpage} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/man/man${section}) + endif() + endif() +endfunction() diff -Nru freerdp-2.0.0~dev201701161718+dfsg/cmake/today.cmake freerdp-2.0.0~dev201703030839+dfsg/cmake/today.cmake --- freerdp-2.0.0~dev201701161718+dfsg/cmake/today.cmake 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/cmake/today.cmake 2017-03-03 08:39:24.000000000 +0000 @@ -3,14 +3,17 @@ # YYYY-MM-DD # MACRO (TODAY RESULT) - IF (WIN32) - EXECUTE_PROCESS(COMMAND "cmd" " /C date +%Y-%m-%d" OUTPUT_VARIABLE ${RESULT}) - string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}}) - ELSEIF(UNIX) - EXECUTE_PROCESS(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE ${RESULT}) - string(REGEX REPLACE "(..)/(..)/..(..).*" "\\1/\\2/\\3" ${RESULT} ${${RESULT}}) - ELSE (WIN32) - MESSAGE(SEND_ERROR "date not implemented") - SET(${RESULT} 000000) - ENDIF (WIN32) + if (DEFINED ENV{SOURCE_DATE_EPOCH} AND NOT WIN32) + EXECUTE_PROCESS(COMMAND "date" "-u" "-d" "@$ENV{SOURCE_DATE_EPOCH}" "+%Y-%m-%d" + OUTPUT_VARIABLE ${RESULT} OUTPUT_STRIP_TRAILING_WHITESPACE) + elseif(CMAKE_VERSION VERSION_LESS "2.8.11") + if (WIN32) + message(FATAL_ERROR "Your CMake version is too old. Please update to a more recent version >= 2.8.11") + else() + EXECUTE_PROCESS(COMMAND "date" "-u" "+%Y-%m-%d" + OUTPUT_VARIABLE ${RESULT} OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + else() + STRING(TIMESTAMP ${RESULT} "%Y-%m-%d" UTC) + endif() ENDMACRO (TODAY) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -67,6 +67,7 @@ include(CheckCXXCompilerFlag) include(GNUInstallDirsWrapper) include(CMakePackageConfigHelpers) +include(InstallFreeRDPMan) # Soname versioning set(BUILD_NUMBER 0) @@ -106,6 +107,12 @@ SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) endif(CMAKE_CROSSCOMPILING) +find_program(CCACHE ccache) +if(CCACHE AND WITH_CCACHE) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE}) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE}) +endif(CCACHE AND WITH_CCACHE) + include(GetGitRevisionDescription) git_get_exact_tag(GIT_REVISION --tags --always) @@ -649,6 +656,10 @@ set(OPENH264_FEATURE_PURPOSE "codec") set(OPENH264_FEATURE_DESCRIPTION "use OpenH264 library") +set(KRB5_FEATURE_TYPE "OPTIONAL") +set(KRB5_FEATURE_PURPOSE "auth") +set(KRB5_FEATURE_DESCRIPTION "add kerberos support") + set(GSM_FEATURE_TYPE "OPTIONAL") set(GSM_FEATURE_PURPOSE "codec") set(GSM_FEATURE_DESCRIPTION "GSM audio codec library") @@ -746,6 +757,7 @@ find_feature(x264 ${X264_FEATURE_TYPE} ${X264_FEATURE_PURPOSE} ${X264_FEATURE_DESCRIPTION}) find_feature(OpenH264 ${OPENH264_FEATURE_TYPE} ${OPENH264_FEATURE_PURPOSE} ${OPENH264_FEATURE_DESCRIPTION}) find_feature(GSM ${GSM_FEATURE_TYPE} ${GSM_FEATURE_PURPOSE} ${GSM_FEATURE_DESCRIPTION}) +find_feature(KRB5 ${KRB5_FEATURE_TYPE} ${KRB5_FEATURE_PURPOSE} ${KRB5_FEATURE_DESCRIPTION}) if(TARGET_ARCH MATCHES "x86|x64") if (NOT APPLE) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/config.h.in freerdp-2.0.0~dev201703030839+dfsg/config.h.in --- freerdp-2.0.0~dev201701161718+dfsg/config.h.in 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/config.h.in 2017-03-03 08:39:24.000000000 +0000 @@ -53,7 +53,7 @@ /* Plugins */ #cmakedefine BUILTIN_CHANNELS #cmakedefine WITH_RDPDR - +#cmakedefine WITH_KRB5 /* Debug */ #cmakedefine WITH_DEBUG_CERTIFICATE diff -Nru freerdp-2.0.0~dev201701161718+dfsg/debian/changelog freerdp-2.0.0~dev201703030839+dfsg/debian/changelog --- freerdp-2.0.0~dev201701161718+dfsg/debian/changelog 2017-01-22 09:25:08.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/debian/changelog 2017-03-05 07:11:51.000000000 +0000 @@ -1,4 +1,10 @@ -freerdp (2.0.0~dev201701161718+dfsg-1ubuntu0~git1046c95~yakkety) yakkety; urgency=medium +freerdp (2.0.0~dev201703030839+dfsg-1ubuntu0~git14c236d~yakkety) yakkety; urgency=medium + + * New release aligned with commit #14c236d of FreeRDP repository. + + -- Matteo Nastasi Sun, 22 Jan 2017 08:31:16 +0100 + +ffreerdp (2.0.0~dev201701161718+dfsg-1ubuntu0~git1046c95~trusty) trusty; urgency=medium * New release aligned with commit #1046c95 of FreeRDP repository. diff -Nru freerdp-2.0.0~dev201701161718+dfsg/debian/patches/1001_hide-internal-symbols.patch freerdp-2.0.0~dev201703030839+dfsg/debian/patches/1001_hide-internal-symbols.patch --- freerdp-2.0.0~dev201701161718+dfsg/debian/patches/1001_hide-internal-symbols.patch 2016-12-17 10:52:07.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/debian/patches/1001_hide-internal-symbols.patch 2017-03-05 07:05:10.000000000 +0000 @@ -52,19 +52,6 @@ const BYTE* pSrc1, UINT32 src1Step, const BYTE* pSrc2, UINT32 src2Step, BYTE* pDst, UINT32 dstStep, -Index: freerdp-1.2.0~git20141201+dfsg1/libfreerdp/primitives/prim_colors_opt.c -=================================================================== ---- freerdp-1.2.0~git20141201+dfsg1.orig/libfreerdp/primitives/prim_colors_opt.c -+++ freerdp-1.2.0~git20141201+dfsg1/libfreerdp/primitives/prim_colors_opt.c -@@ -356,7 +356,7 @@ pstatus_t sse2_RGBToYCbCr_16s16s_P3P3( - #define XMM_ALL_ONES \ - _mm_set1_epi32(0xFFFFFFFFU) - --pstatus_t sse2_RGBToRGB_16s8u_P3AC4R( -+PRIMITIVES_HIDDEN pstatus_t sse2_RGBToRGB_16s8u_P3AC4R( - const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ - UINT32 srcStep, /* bytes between rows in source data */ - BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ Index: freerdp-1.2.0~git20141201+dfsg1/libfreerdp/primitives/prim_internal.h =================================================================== --- freerdp-1.2.0~git20141201+dfsg1.orig/libfreerdp/primitives/prim_internal.h @@ -79,9 +66,9 @@ + #define PRIMITIVES_HIDDEN +#endif + - /* Use lddqu for unaligned; load for 16-byte aligned. */ - #define LOAD_SI128(_ptr_) \ - (((ULONG_PTR) (_ptr_) & 0x0f) \ + + #ifdef __GNUC__ + #define PRIM_ALIGN_128 __attribute__((aligned(16))) Index: freerdp-1.2.0~git20141201+dfsg1/libfreerdp/primitives/prim_templates.h =================================================================== --- freerdp-1.2.0~git20141201+dfsg1.orig/libfreerdp/primitives/prim_templates.h @@ -102,7 +89,7 @@ - pstatus_t _name_(const _type_ *pSrc, _type_ val, _type_ *pDst, INT32 len) \ +PRIMITIVES_HIDDEN pstatus_t _name_(const _type_ *pSrc, _type_ val, _type_ *pDst, INT32 len) \ { \ - int shifts; \ + int shifts = 0; \ UINT32 offBeatMask; \ @@ -293,7 +295,7 @@ pstatus_t _name_(const _type_ *pSrc, _ty * SSD = Source1, Source2, Destination @@ -111,5 +98,5 @@ - pstatus_t _name_(const _type_ *pSrc1, const _type_ *pSrc2, _type_ *pDst, UINT32 len) \ +PRIMITIVES_HIDDEN pstatus_t _name_(const _type_ *pSrc1, const _type_ *pSrc2, _type_ *pDst, UINT32 len) \ { \ - int shifts; \ + int shifts = 0; \ UINT32 offBeatMask; \ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/debian/patches/1005_parse-buffer-endianess.patch freerdp-2.0.0~dev201703030839+dfsg/debian/patches/1005_parse-buffer-endianess.patch --- freerdp-2.0.0~dev201701161718+dfsg/debian/patches/1005_parse-buffer-endianess.patch 2016-09-10 12:12:51.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/debian/patches/1005_parse-buffer-endianess.patch 2017-03-01 12:56:30.000000000 +0000 @@ -21,39 +21,39 @@ //#define DEBUG_CLIENT_FILE 1 static BYTE BOM_UTF16_LE[2] = { 0xFF, 0xFE }; -@@ -573,7 +585,8 @@ next_line: - static BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, const BYTE* buffer, size_t size) +@@ -605,7 +585,8 @@ next_line: { + BOOL rc = FALSE; int index; - int length; + int i, length; + BYTE* bufferne; - WCHAR* line; + const WCHAR* line; WCHAR* type; WCHAR* context; -@@ -582,7 +595,20 @@ BOOL freerdp_client_parse_rdp_file_buffe - WCHAR *name, *value; +@@ -618,7 +595,20 @@ BOOL freerdp_client_parse_rdp_file_buffe + memcpy(copy, buffer, size); index = 0; -- line = wcstok_s((WCHAR*) buffer, CR_LF_STR_W, &context); +- line = wcstok_s(copy, CR_LF_STR_W, &context); + +#if __BYTE_ORDER == __BIG_ENDIAN + /* Convert the buffer from little endian to native endian */ + bufferne = (BYTE*) malloc(size); + for (i = 0; i < size / 2; i++) + { -+ bufferne[i*2] = buffer[i*2 + 1]; -+ bufferne[i*2 + 1] = buffer[i*2]; ++ bufferne[i*2] = copy[i*2 + 1]; ++ bufferne[i*2 + 1] = copy[i*2]; + } +#else -+ bufferne = buffer; ++ bufferne = copy; +#endif + + line = wcstok_s((WCHAR*) bufferne, CR_LF_STR_W, &context); while (line != NULL) { -@@ -646,6 +672,10 @@ next_line: +@@ -680,6 +672,10 @@ next_line: index++; } @@ -61,6 +61,6 @@ + free(bufferne); +#endif + - return TRUE; - } - + rc = TRUE; + fail: + free(copy); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/debian/patches/1008_gcc-fPIC-on-arm64.patch freerdp-2.0.0~dev201703030839+dfsg/debian/patches/1008_gcc-fPIC-on-arm64.patch --- freerdp-2.0.0~dev201701161718+dfsg/debian/patches/1008_gcc-fPIC-on-arm64.patch 2016-12-17 10:52:07.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/debian/patches/1008_gcc-fPIC-on-arm64.patch 2017-03-01 12:56:30.000000000 +0000 @@ -1,6 +1,6 @@ --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -194,6 +194,9 @@ +@@ -201,6 +201,9 @@ endif() endif() diff -Nru freerdp-2.0.0~dev201701161718+dfsg/debian/patches/9900_version-suffix.patch freerdp-2.0.0~dev201703030839+dfsg/debian/patches/9900_version-suffix.patch --- freerdp-2.0.0~dev201701161718+dfsg/debian/patches/9900_version-suffix.patch 2016-09-10 12:12:51.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/debian/patches/9900_version-suffix.patch 2017-03-01 12:56:30.000000000 +0000 @@ -1,6 +1,6 @@ --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -77,11 +77,11 @@ +@@ -78,11 +78,11 @@ set(FREERDP_VERSION_MAJOR "2") set(FREERDP_VERSION_MINOR "0") set(FREERDP_VERSION_REVISION "0") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/docs/README.android freerdp-2.0.0~dev201703030839+dfsg/docs/README.android --- freerdp-2.0.0~dev201701161718+dfsg/docs/README.android 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/docs/README.android 2017-03-03 08:39:24.000000000 +0000 @@ -45,6 +45,15 @@ When the script is finished the libraries are ready for android studio to be picked up in client/Android/Studio/freeRDPCore/src/main/jniLibs +The default configuration build configuration can be found in +./scripts/android-build.conf and is configured to provide debug builds. +They are limited to API level 21 and above. + +If release binaries (and old android API support) are required, build 32 bit architectures with +./scripts/android-build-freerdp.sh --ndk --sdk --conf ./scripts/android-build-32.conf +and 64 bit architectures with +./scripts/android-build-freerdp.sh --ndk --sdk --conf ./scripts/android-build-32.conf + Building the APK (Android Studio) ================ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/client/file.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/client/file.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/client/file.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/client/file.h 2017-03-03 08:39:24.000000000 +0000 @@ -89,6 +89,7 @@ LPSTR Username; /* username */ LPSTR Domain; /* domain */ + LPSTR Password; /*password*/ PBYTE Password51; /* password 51 */ LPSTR FullAddress; /* full address */ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/client/rdpgfx.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/client/rdpgfx.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/client/rdpgfx.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/client/rdpgfx.h 2017-03-03 08:39:24.000000000 +0000 @@ -23,6 +23,7 @@ #define FREERDP_CHANNEL_CLIENT_RDPGFX_H #include +#include /** * Client Interface @@ -105,6 +106,8 @@ pcRdpgfxGetCacheSlotData GetCacheSlotData; pcRdpgfxUpdateSurfaces UpdateSurfaces; + + PROFILER_DEFINE(SurfaceProfiler); }; #endif /* FREERDP_CHANNEL_CLIENT_RDPGFX_H */ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/codec/bitmap.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/codec/bitmap.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/codec/bitmap.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/codec/bitmap.h 2017-03-03 08:39:24.000000000 +0000 @@ -32,7 +32,7 @@ extern "C" { #endif -FREERDP_API int freerdp_bitmap_compress(char* in_data, int width, int height, +FREERDP_API int freerdp_bitmap_compress(const char* in_data, int width, int height, wStream* s, int bpp, int byte_limit, int start_line, wStream* temp_s, int e); #ifdef __cplusplus diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/codec/clear.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/codec/clear.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/codec/clear.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/codec/clear.h 2017-03-03 08:39:24.000000000 +0000 @@ -32,7 +32,7 @@ extern "C" { #endif -FREERDP_API int clear_compress(CLEAR_CONTEXT* clear, BYTE* pSrcData, +FREERDP_API int clear_compress(CLEAR_CONTEXT* clear, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize); FREERDP_API INT32 clear_decompress(CLEAR_CONTEXT* clear, const BYTE* pSrcData, diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/codec/h264.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/codec/h264.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/codec/h264.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/codec/h264.h 2017-03-03 08:39:24.000000000 +0000 @@ -29,10 +29,10 @@ typedef BOOL (*pfnH264SubsystemInit)(H264_CONTEXT* h264); typedef void (*pfnH264SubsystemUninit)(H264_CONTEXT* h264); -typedef int (*pfnH264SubsystemDecompress)(H264_CONTEXT* h264, BYTE* pSrcData, - UINT32 SrcSize, UINT32 plane); +typedef int (*pfnH264SubsystemDecompress)(H264_CONTEXT* h264, const BYTE* pSrcData, + UINT32 SrcSize); typedef int (*pfnH264SubsystemCompress)(H264_CONTEXT* h264, BYTE** ppDstData, - UINT32* pDstSize, UINT32 plane); + UINT32* pDstSize); struct _H264_CONTEXT_SUBSYSTEM { @@ -64,8 +64,8 @@ UINT32 QP; UINT32 NumberOfThreads; - UINT32 iStride[2][3]; - BYTE* pYUVData[2][3]; + UINT32 iStride[3]; + BYTE* pYUVData[3]; UINT32 iYUV444Size[3]; UINT32 iYUV444Stride[3]; @@ -80,30 +80,30 @@ extern "C" { #endif -FREERDP_API INT32 avc420_compress(H264_CONTEXT* h264, BYTE* pSrcData, - DWORD SrcFormat, UINT32 nSrcStep, - UINT32 nSrcWidth, UINT32 nSrcHeight, - BYTE** ppDstData, UINT32* pDstSize); - -FREERDP_API INT32 avc420_decompress(H264_CONTEXT* h264, BYTE* pSrcData, - UINT32 SrcSize, BYTE* pDstData, - DWORD DstFormat, UINT32 nDstStep, - UINT32 nDstWidth, UINT32 nDstHeight, - RECTANGLE_16* regionRects, UINT32 numRegionRect); - -FREERDP_API INT32 avc444_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat, - UINT32 nSrcStep, UINT32 nSrcWidth, UINT32 nSrcHeight, - BYTE* op, - BYTE** pDstData, UINT32* pDstSize, - BYTE** pAuxDstData, UINT32* pAuxDstSize); +FREERDP_API INT32 avc420_compress(H264_CONTEXT* h264, const BYTE* pSrcData, + DWORD SrcFormat, UINT32 nSrcStep, + UINT32 nSrcWidth, UINT32 nSrcHeight, + BYTE** ppDstData, UINT32* pDstSize); + +FREERDP_API INT32 avc420_decompress(H264_CONTEXT* h264, const BYTE* pSrcData, + UINT32 SrcSize, BYTE* pDstData, + DWORD DstFormat, UINT32 nDstStep, + UINT32 nDstWidth, UINT32 nDstHeight, + RECTANGLE_16* regionRects, UINT32 numRegionRect); + +FREERDP_API INT32 avc444_compress(H264_CONTEXT* h264, const BYTE* pSrcData, DWORD SrcFormat, + UINT32 nSrcStep, UINT32 nSrcWidth, UINT32 nSrcHeight, + BYTE* op, + BYTE** pDstData, UINT32* pDstSize, + BYTE** pAuxDstData, UINT32* pAuxDstSize); FREERDP_API INT32 avc444_decompress(H264_CONTEXT* h264, BYTE op, - RECTANGLE_16* regionRects, UINT32 numRegionRect, - BYTE* pSrcData, UINT32 SrcSize, - RECTANGLE_16* auxRegionRects, UINT32 numAuxRegionRect, - BYTE* pAuxSrcData, UINT32 AuxSrcSize, - BYTE* pDstData, DWORD DstFormat, - UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight); + RECTANGLE_16* regionRects, UINT32 numRegionRect, + const BYTE* pSrcData, UINT32 SrcSize, + RECTANGLE_16* auxRegionRects, UINT32 numAuxRegionRect, + const BYTE* pAuxSrcData, UINT32 AuxSrcSize, + BYTE* pDstData, DWORD DstFormat, + UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight); FREERDP_API BOOL h264_context_reset(H264_CONTEXT* h264, UINT32 width, UINT32 height); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/codec/progressive.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/codec/progressive.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/codec/progressive.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/codec/progressive.h 2017-03-03 08:39:24.000000000 +0000 @@ -31,211 +31,12 @@ #include #include -#define RFX_SUBBAND_DIFFING 0x01 - -#define RFX_TILE_DIFFERENCE 0x01 - -#define RFX_DWT_REDUCE_EXTRAPOLATE 0x01 - -#define PROGRESSIVE_WBT_SYNC 0xCCC0 -#define PROGRESSIVE_WBT_FRAME_BEGIN 0xCCC1 -#define PROGRESSIVE_WBT_FRAME_END 0xCCC2 -#define PROGRESSIVE_WBT_CONTEXT 0xCCC3 -#define PROGRESSIVE_WBT_REGION 0xCCC4 -#define PROGRESSIVE_WBT_TILE_SIMPLE 0xCCC5 -#define PROGRESSIVE_WBT_TILE_FIRST 0xCCC6 -#define PROGRESSIVE_WBT_TILE_UPGRADE 0xCCC7 - -struct _RFX_COMPONENT_CODEC_QUANT -{ - BYTE LL3; - BYTE HL3; - BYTE LH3; - BYTE HH3; - BYTE HL2; - BYTE LH2; - BYTE HH2; - BYTE HL1; - BYTE LH1; - BYTE HH1; -}; -typedef struct _RFX_COMPONENT_CODEC_QUANT RFX_COMPONENT_CODEC_QUANT; - -struct _RFX_PROGRESSIVE_CODEC_QUANT -{ - BYTE quality; - RFX_COMPONENT_CODEC_QUANT yQuantValues; - RFX_COMPONENT_CODEC_QUANT cbQuantValues; - RFX_COMPONENT_CODEC_QUANT crQuantValues; -}; -typedef struct _RFX_PROGRESSIVE_CODEC_QUANT RFX_PROGRESSIVE_CODEC_QUANT; - -struct _PROGRESSIVE_BLOCK -{ - UINT16 blockType; - UINT32 blockLen; -}; -typedef struct _PROGRESSIVE_BLOCK PROGRESSIVE_BLOCK; - -struct _PROGRESSIVE_BLOCK_SYNC -{ - UINT16 blockType; - UINT32 blockLen; - - UINT32 magic; - UINT16 version; -}; -typedef struct _PROGRESSIVE_BLOCK_SYNC PROGRESSIVE_BLOCK_SYNC; - -struct _PROGRESSIVE_BLOCK_CONTEXT -{ - UINT16 blockType; - UINT32 blockLen; - - BYTE ctxId; - UINT16 tileSize; - BYTE flags; -}; -typedef struct _PROGRESSIVE_BLOCK_CONTEXT PROGRESSIVE_BLOCK_CONTEXT; - -struct _RFX_PROGRESSIVE_TILE -{ - UINT16 blockType; - UINT32 blockLen; - - BYTE quantIdxY; - BYTE quantIdxCb; - BYTE quantIdxCr; - UINT16 xIdx; - UINT16 yIdx; - - BYTE flags; - BYTE quality; - - UINT16 yLen; - UINT16 cbLen; - UINT16 crLen; - UINT16 tailLen; - const BYTE* yData; - const BYTE* cbData; - const BYTE* crData; - const BYTE* tailData; - - UINT16 ySrlLen; - UINT16 yRawLen; - UINT16 cbSrlLen; - UINT16 cbRawLen; - UINT16 crSrlLen; - UINT16 crRawLen; - const BYTE* ySrlData; - const BYTE* yRawData; - const BYTE* cbSrlData; - const BYTE* cbRawData; - const BYTE* crSrlData; - const BYTE* crRawData; - - UINT32 x; - UINT32 y; - UINT32 width; - UINT32 height; - BYTE* data; - BYTE* current; - - UINT16 pass; - BYTE* sign; - RFX_COMPONENT_CODEC_QUANT yBitPos; - RFX_COMPONENT_CODEC_QUANT cbBitPos; - RFX_COMPONENT_CODEC_QUANT crBitPos; - RFX_COMPONENT_CODEC_QUANT yQuant; - RFX_COMPONENT_CODEC_QUANT cbQuant; - RFX_COMPONENT_CODEC_QUANT crQuant; - RFX_COMPONENT_CODEC_QUANT yProgQuant; - RFX_COMPONENT_CODEC_QUANT cbProgQuant; - RFX_COMPONENT_CODEC_QUANT crProgQuant; -}; -typedef struct _RFX_PROGRESSIVE_TILE RFX_PROGRESSIVE_TILE; - -struct _PROGRESSIVE_BLOCK_REGION -{ - UINT16 blockType; - UINT32 blockLen; - - BYTE tileSize; - UINT16 numRects; - BYTE numQuant; - BYTE numProgQuant; - BYTE flags; - UINT16 numTiles; - UINT32 tileDataSize; - RFX_RECT* rects; - RFX_COMPONENT_CODEC_QUANT* quantVals; - RFX_PROGRESSIVE_CODEC_QUANT* quantProgVals; - RFX_PROGRESSIVE_TILE** tiles; -}; -typedef struct _PROGRESSIVE_BLOCK_REGION PROGRESSIVE_BLOCK_REGION; - -struct _PROGRESSIVE_BLOCK_FRAME_BEGIN -{ - UINT16 blockType; - UINT32 blockLen; - - UINT32 frameIndex; - UINT16 regionCount; - PROGRESSIVE_BLOCK_REGION* regions; -}; -typedef struct _PROGRESSIVE_BLOCK_FRAME_BEGIN PROGRESSIVE_BLOCK_FRAME_BEGIN; - -struct _PROGRESSIVE_BLOCK_FRAME_END -{ - UINT16 blockType; - UINT32 blockLen; -}; -typedef struct _PROGRESSIVE_BLOCK_FRAME_END PROGRESSIVE_BLOCK_FRAME_END; - -struct _PROGRESSIVE_SURFACE_CONTEXT -{ - UINT16 id; - UINT32 width; - UINT32 height; - UINT32 gridWidth; - UINT32 gridHeight; - UINT32 gridSize; - RFX_PROGRESSIVE_TILE* tiles; -}; -typedef struct _PROGRESSIVE_SURFACE_CONTEXT PROGRESSIVE_SURFACE_CONTEXT; - -struct _PROGRESSIVE_CONTEXT -{ - BOOL Compressor; - - BOOL invert; - - wBufferPool* bufferPool; - - UINT32 cRects; - RFX_RECT* rects; - - UINT32 cTiles; - RFX_PROGRESSIVE_TILE** tiles; - - UINT32 cQuant; - RFX_COMPONENT_CODEC_QUANT* quantVals; - - UINT32 cProgQuant; - RFX_PROGRESSIVE_CODEC_QUANT* quantProgVals; - - PROGRESSIVE_BLOCK_REGION region; - RFX_PROGRESSIVE_CODEC_QUANT quantProgValFull; - - wHashTable* SurfaceContexts; -}; - #ifdef __cplusplus extern "C" { #endif FREERDP_API int progressive_compress(PROGRESSIVE_CONTEXT* progressive, - BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize); + const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize); FREERDP_API INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize, diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/error.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/error.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/error.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/error.h 2017-03-03 08:39:24.000000000 +0000 @@ -238,6 +238,11 @@ #define ERRCONNECT_CONNECT_CANCELLED 0x0000000B #define ERRCONNECT_SECURITY_NEGO_CONNECT_FAILED 0x0000000C #define ERRCONNECT_CONNECT_TRANSPORT_FAILED 0x0000000D +#define ERRCONNECT_PASSWORD_EXPIRED 0x0000000E +/* For non-domain workstation where we can't contact a kerberos server */ +#define ERRCONNECT_PASSWORD_CERTAINLY_EXPIRED 0x0000000F +#define ERRCONNECT_CLIENT_REVOKED 0x00000010 +#define ERRCONNECT_KDC_UNREACHABLE 0x00000011 #define ERRCONNECT_SUCCESS ERRINFO_SUCCESS #define ERRCONNECT_NONE ERRINFO_NONE @@ -248,43 +253,55 @@ #define FREERDP_ERROR_CONNECT_CLASS (FREERDP_ERROR_BASE + 2) #define FREERDP_ERROR_PRE_CONNECT_FAILED \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_PRE_CONNECT_FAILED) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_PRE_CONNECT_FAILED) #define FREERDP_ERROR_CONNECT_UNDEFINED \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_UNDEFINED) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_UNDEFINED) #define FREERDP_ERROR_POST_CONNECT_FAILED \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_POST_CONNECT_FAILED) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_POST_CONNECT_FAILED) #define FREERDP_ERROR_DNS_ERROR \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_DNS_ERROR) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_DNS_ERROR) #define FREERDP_ERROR_DNS_NAME_NOT_FOUND \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_DNS_NAME_NOT_FOUND) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_DNS_NAME_NOT_FOUND) #define FREERDP_ERROR_CONNECT_FAILED \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_FAILED) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_FAILED) #define FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_MCS_CONNECT_INITIAL_ERROR) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_MCS_CONNECT_INITIAL_ERROR) #define FREERDP_ERROR_TLS_CONNECT_FAILED \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_TLS_CONNECT_FAILED) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_TLS_CONNECT_FAILED) #define FREERDP_ERROR_AUTHENTICATION_FAILED \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_AUTHENTICATION_FAILED) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_AUTHENTICATION_FAILED) #define FREERDP_ERROR_INSUFFICIENT_PRIVILEGES \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_INSUFFICIENT_PRIVILEGES) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_INSUFFICIENT_PRIVILEGES) #define FREERDP_ERROR_CONNECT_CANCELLED \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_CANCELLED) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_CANCELLED) #define FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_SECURITY_NEGO_CONNECT_FAILED) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_SECURITY_NEGO_CONNECT_FAILED) #define FREERDP_ERROR_CONNECT_TRANSPORT_FAILED \ - MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_TRANSPORT_FAILED) + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CONNECT_TRANSPORT_FAILED) + +#define FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_PASSWORD_EXPIRED) + +#define FREERDP_ERROR_CONNECT_PASSWORD_CERTAINLY_EXPIRED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_PASSWORD_CERTAINLY_EXPIRED) + +#define FREERDP_ERROR_CONNECT_CLIENT_REVOKED \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_CLIENT_REVOKED) + +#define FREERDP_ERROR_CONNECT_KDC_UNREACHABLE \ + MAKE_FREERDP_ERROR(CONNECT, ERRCONNECT_KDC_UNREACHABLE) #ifdef __cplusplus } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/freerdp.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/freerdp.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/freerdp.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/freerdp.h 2017-03-03 08:39:24.000000000 +0000 @@ -361,6 +361,9 @@ FREERDP_API const char* freerdp_get_last_error_string(UINT32 error); FREERDP_API void freerdp_set_last_error(rdpContext* context, UINT32 lastError); +FREERDP_API const char* freerdp_get_logon_error_info_type(UINT32 type); +FREERDP_API const char* freerdp_get_logon_error_info_data(UINT32 data); + FREERDP_API ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/peer.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/peer.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/peer.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/peer.h 2017-03-03 08:39:24.000000000 +0000 @@ -47,6 +47,8 @@ typedef BOOL (*psPeerPostConnect)(freerdp_peer* peer); typedef BOOL (*psPeerActivate)(freerdp_peer* peer); typedef BOOL (*psPeerLogon)(freerdp_peer* peer, SEC_WINNT_AUTH_IDENTITY* identity, BOOL automatic); +typedef BOOL (*psPeerAdjustMonitorsLayout)(freerdp_peer* peer); +typedef BOOL (*psPeerClientCapabilities)(freerdp_peer* peer); typedef int (*psPeerSendChannelData)(freerdp_peer* peer, UINT16 channelId, BYTE* data, int size); typedef int (*psPeerReceiveChannelData)(freerdp_peer* peer, UINT16 channelId, BYTE* data, int size, @@ -61,6 +63,7 @@ typedef void* (*psPeerVirtualChannelGetData)(freerdp_peer* peer, HANDLE hChannel); typedef int (*psPeerVirtualChannelSetData)(freerdp_peer* peer, HANDLE hChannel, void* data); + struct rdp_freerdp_peer { rdpContext* context; @@ -113,6 +116,8 @@ psPeerDrainOutputBuffer DrainOutputBuffer; psPeerHasMoreToRead HasMoreToRead; psPeerGetEventHandles GetEventHandles; + psPeerAdjustMonitorsLayout AdjustMonitorsLayout; + psPeerClientCapabilities ClientCapabilities; }; #ifdef __cplusplus diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/primitives.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/primitives.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/primitives.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/primitives.h 2017-03-03 08:39:24.000000000 +0000 @@ -141,10 +141,6 @@ const INT16* pSrc[3], UINT32 srcStep, BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, const prim_size_t* roi); -typedef pstatus_t (*__yCbCrToBGR_16s8u_P3AC4R_t)( - const INT16* pSrc[3], UINT32 srcStep, - BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, - const prim_size_t* roi); typedef pstatus_t (*__yCbCrToRGB_16s16s_P3P3_t)( const INT16* pSrc[3], INT32 srcStep, INT16* pDst[3], INT32 dstStep, @@ -194,6 +190,11 @@ BYTE* pMainDst[3], const UINT32 dstMainStep[3], BYTE* pAuxDst[3], const UINT32 srcAuxStep[3], const prim_size_t* roi); +typedef pstatus_t (*__RGBToAVC444YUV_t)( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pMainDst[3], const UINT32 dstMainStep[3], + BYTE* pAuxDst[3], const UINT32 dstAuxStep[3], + const prim_size_t* roi); typedef pstatus_t (*__andC_32u_t)( const UINT32* pSrc, UINT32 val, @@ -234,7 +235,6 @@ __sign_16s_t sign_16s; /* Color conversions */ __yCbCrToRGB_16s8u_P3AC4R_t yCbCrToRGB_16s8u_P3AC4R; - __yCbCrToBGR_16s8u_P3AC4R_t yCbCrToBGR_16s8u_P3AC4R; __yCbCrToRGB_16s16s_P3P3_t yCbCrToRGB_16s16s_P3P3; __RGBToYCbCr_16s16s_P3P3_t RGBToYCbCr_16s16s_P3P3; __RGBToRGB_16s8u_P3AC4R_t RGBToRGB_16s8u_P3AC4R; @@ -245,6 +245,7 @@ __YUV420CombineToYUV444_t YUV420CombineToYUV444; __YUV444SplitToYUV420_t YUV444SplitToYUV420; __YUV444ToRGB_8u_P3AC4R_t YUV444ToRGB_8u_P3AC4R; + __RGBToAVC444YUV_t RGBToAVC444YUV; } primitives_t; #ifdef __cplusplus diff -Nru freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/settings.h freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/settings.h --- freerdp-2.0.0~dev201701161718+dfsg/include/freerdp/settings.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/include/freerdp/settings.h 2017-03-03 08:39:24.000000000 +0000 @@ -238,10 +238,10 @@ typedef struct _TARGET_NET_ADDRESS TARGET_NET_ADDRESS; /* Logon Error Info */ - +#define LOGON_MSG_DISCONNECT_REFUSED 0xFFFFFFF9 #define LOGON_MSG_NO_PERMISSION 0xFFFFFFFA #define LOGON_MSG_BUMP_OPTIONS 0xFFFFFFFB -#define LOGON_MSG_SESSION_RECONNECT 0xFFFFFFFC +#define LOGON_MSG_RECONNECT_OPTIONS 0xFFFFFFFC #define LOGON_MSG_SESSION_TERMINATE 0xFFFFFFFD #define LOGON_MSG_SESSION_CONTINUE 0xFFFFFFFE @@ -1434,6 +1434,7 @@ ALIGN64 BYTE* SettingsModified; /* byte array marking fields that have been modified from their default value */ + ALIGN64 char* ActionScript; }; typedef struct rdp_settings rdpSettings; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -176,11 +176,10 @@ freerdp_library_add(${OPENH264_LIBRARIES}) endif() -if(WITH_LIBAVCODEC) +if(WITH_FFMPEG) freerdp_definition_add(-DWITH_LIBAVCODEC) - find_library(LIBAVCODEC_LIB avcodec) - find_library(LIBAVUTIL_LIB avutil) - freerdp_library_add(${LIBAVCODEC_LIB} ${LIBAVUTIL_LIB}) + freerdp_include_directory_add(${FFMPEG_INCLUDE_DIRS}) + freerdp_library_add(${FFMPEG_LIBRARIES}) endif() freerdp_module_add(${CODEC_SRCS}) @@ -291,6 +290,7 @@ add_definitions(${LIBFREERDP_DEFINITIONS}) set_target_properties(${MODULE_NAME} PROPERTIES LINKER_LANGUAGE C) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${FREERDP_VERSION_MAJOR}) if (WITH_LIBRARY_VERSIONING) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) @@ -300,7 +300,8 @@ target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${LIBFREERDP_LIBS} winpr) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT FreeRDPTargets) if (WITH_DEBUG_SYMBOLS AND MSVC AND BUILD_SHARED_LIBS) - install(FILES ${CMAKE_PDB_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) + get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME) + install(FILES ${CMAKE_PDB_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/bitmap.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/bitmap.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/bitmap.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/bitmap.c 2017-03-03 08:39:24.000000000 +0000 @@ -456,11 +456,9 @@ bicolor_spin = 0; \ } -int freerdp_bitmap_compress(char* srcData, int width, int height, +int freerdp_bitmap_compress(const char* srcData, int width, int height, wStream* s, int bpp, int byte_limit, int start_line, wStream* temp_s, int e) { - char *line; - char *last_line; char fom_mask[8192]; /* good for up to 64K bitmap */ int lines_sent; int pixel; @@ -485,7 +483,6 @@ Stream_SetPosition(temp_s, 0); fom_mask_len = 0; - last_line = 0; lines_sent = 0; end = width + e; count = 0; @@ -502,9 +499,10 @@ if ((bpp == 15) || (bpp == 16)) { + const char* line = srcData + width * start_line * 2; + const char *last_line = NULL; mix = (bpp == 15) ? 0xBA1F : 0xFFFF; out_count = end * 2; - line = srcData + width * start_line * 2; while (start_line >= 0 && out_count < 32768) { @@ -794,9 +792,10 @@ } else if (bpp == 24) { + const char* line = srcData + width * start_line * 4; + const char *last_line = NULL; mix = 0xFFFFFF; out_count = end * 3; - line = srcData + width * start_line * 4; while (start_line >= 0 && out_count < 32768) { diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/clear.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/clear.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/clear.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/clear.c 2017-03-03 08:39:24.000000000 +0000 @@ -103,35 +103,14 @@ const BYTE* src, UINT32 nSrcStep, UINT32 SrcFormat, UINT32 nDstWidth, UINT32 nDstHeight, const gdiPalette* palette) { - UINT32 x, y; - if (nWidth + nXDst > nDstWidth) nWidth = nDstWidth - nXDst; if (nHeight + nYDst > nDstHeight) nHeight = nDstHeight - nYDst; - for (y = 0; y < nHeight; y++) - { - const BYTE* pSrcLine = &src[y * nSrcStep]; - BYTE* pDstLine = &dst[(nYDst + y) * nDstStep]; - - for (x = 0; x < nWidth; x++) - { - const BYTE* pSrcPixel = - &pSrcLine[x * GetBytesPerPixel(SrcFormat)]; - BYTE* pDstPixel = - &pDstLine[(nXDst + x) * GetBytesPerPixel(DstFormat)]; - UINT32 color = ReadColor(pSrcPixel, SrcFormat); - color = ConvertColor(color, SrcFormat, - DstFormat, palette); - - if (!WriteColor(pDstPixel, DstFormat, color)) - return FALSE; - } - } - - return TRUE; + return freerdp_image_copy(dst, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight, + src, SrcFormat, nSrcStep, 0, 0, palette, 0); } static BOOL clear_decompress_nscodec(NSC_CONTEXT* nsc, UINT32 width, @@ -165,7 +144,6 @@ UINT32 x = 0, y = 0; UINT32 i; UINT32 pixelCount; - UINT32 nSrcStep; UINT32 bitmapDataOffset; UINT32 pixelIndex; UINT32 numBits; @@ -330,8 +308,6 @@ pixelIndex += (suiteDepth + 1); } - nSrcStep = width * GetBytesPerPixel(DstFormat); - if (pixelIndex != pixelCount) { WLog_ERR(TAG, "pixelIndex %"PRIu32" != pixelCount %"PRIu32"", pixelIndex, pixelCount); @@ -863,7 +839,7 @@ for (x = 0; x < count; x++) { UINT32 color; - color = ReadColor(&vBarShortEntry->pixels[x * GetBytesPerPixel(clear->format)], + color = ReadColor(&pSrcPixel[x * GetBytesPerPixel(clear->format)], clear->format); if (!WriteColor(dstBuffer, clear->format, color)) @@ -1185,7 +1161,7 @@ return rc; } -int clear_compress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, +int clear_compress(CLEAR_CONTEXT* clear, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize) { WLog_ERR(TAG, "TODO: %s not implemented!", __FUNCTION__); @@ -1197,8 +1173,6 @@ return FALSE; clear->seqNumber = 0; - clear->VBarStorageCursor = 0; - clear->ShortVBarStorageCursor = 0; return TRUE; } CLEAR_CONTEXT* clear_context_new(BOOL Compressor) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/color.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/color.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/color.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/color.c 2017-03-03 08:39:24.000000000 +0000 @@ -84,17 +84,12 @@ { UINT32 x, y; BOOL vFlip; - UINT32 nDstPad; UINT32 monoStep; - UINT32 dstBitsPerPixel; - UINT32 dstBytesPerPixel; - dstBitsPerPixel = GetBitsPerPixel(DstFormat); - dstBytesPerPixel = GetBytesPerPixel(DstFormat); + const UINT32 dstBytesPerPixel = GetBytesPerPixel(DstFormat); if (nDstStep == 0) nDstStep = dstBytesPerPixel * nWidth; - nDstPad = (nDstStep - (nWidth * dstBytesPerPixel)); vFlip = FALSE; monoStep = (nWidth + 7) / 8; @@ -167,7 +162,6 @@ { UINT32 x, y; BOOL vFlip; - UINT32 nDstPad; UINT32 xorStep; UINT32 andStep; UINT32 xorBit; @@ -182,7 +176,6 @@ if (nDstStep <= 0) nDstStep = dstBytesPerPixel * nWidth; - nDstPad = (nDstStep - (nWidth * dstBytesPerPixel)); vFlip = (xorBpp == 1) ? FALSE : TRUE; andStep = (nWidth + 7) / 8; andStep += (andStep % 2); @@ -357,8 +350,6 @@ } /* Ignore the AND mask, if the color format already supplies alpha data. */ - color = xorPixel; - if (andPixel && !ignoreAndMask) { if (xorPixel == 0xFF000000) /* black -> transparent */ @@ -384,11 +375,11 @@ } } -static BOOL overlapping(const BYTE* pDstData, UINT32 nXDst, UINT32 nYDst, - UINT32 nDstStep, UINT32 dstBytesPerPixel, - const BYTE* pSrcData, UINT32 nXSrc, UINT32 nYSrc, - UINT32 nSrcStep, UINT32 srcBytesPerPixel, - UINT32 nWidth, UINT32 nHeight) +static INLINE BOOL overlapping(const BYTE* pDstData, UINT32 nXDst, UINT32 nYDst, + UINT32 nDstStep, UINT32 dstBytesPerPixel, + const BYTE* pSrcData, UINT32 nXSrc, UINT32 nYSrc, + UINT32 nSrcStep, UINT32 srcBytesPerPixel, + UINT32 nWidth, UINT32 nHeight) { const BYTE* pDstStart = &pDstData[nXDst * dstBytesPerPixel + nYDst * nDstStep]; const BYTE* pDstEnd = pDstStart + nHeight * nDstStep; @@ -416,7 +407,7 @@ const UINT32 copyDstWidth = nWidth * dstByte; const UINT32 xSrcOffset = nXSrc * srcByte; const UINT32 xDstOffset = nXDst * dstByte; - BOOL vSrcVFlip = flags & FREERDP_FLIP_VERTICAL; + const BOOL vSrcVFlip = flags & FREERDP_FLIP_VERTICAL; UINT32 srcVOffset = 0; INT32 srcVMultiplier = 1; UINT32 dstVOffset = 0; @@ -556,16 +547,20 @@ UINT32 nWidth, UINT32 nHeight, UINT32 color) { UINT32 x, y; + const UINT32 bpp = GetBytesPerPixel(DstFormat); + BYTE* pFirstDstLine = &pDstData[nYDst * nDstStep]; + BYTE* pFirstDstLineXOffset = &pFirstDstLine[nXDst * bpp]; - for (y = 0; y < nHeight; y++) + for (x = 0; x < nWidth; x++) { - BYTE* pDstLine = &pDstData[(y + nYDst) * nDstStep]; + BYTE* pDst = &pFirstDstLine[(x + nXDst) * bpp]; + WriteColor(pDst, DstFormat, color); + } - for (x = 0; x < nWidth; x++) - { - BYTE* pDst = &pDstLine[(x + nXDst) * GetBytesPerPixel(DstFormat)]; - WriteColor(pDst, DstFormat, color); - } + for (y = 1; y < nHeight; y++) + { + BYTE* pDstLine = &pDstData[(y + nYDst) * nDstStep + nXDst * bpp]; + memcpy(pDstLine, pFirstDstLineXOffset, nWidth * bpp); } return TRUE; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/h264.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/h264.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/h264.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/h264.c 2017-03-03 08:39:24.000000000 +0000 @@ -36,12 +36,17 @@ * Dummy subsystem */ -static int dummy_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, - UINT32 plane) +static int dummy_decompress(H264_CONTEXT* h264, const BYTE* pSrcData, UINT32 SrcSize) { return -1; } +static int dummy_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstSize) +{ + //H264_CONTEXT_X264* sys = (H264_CONTEXT_X264*) h264->pSystemData; + return -1; +} + static void dummy_uninit(H264_CONTEXT* h264) { } @@ -56,7 +61,8 @@ "dummy", dummy_init, dummy_uninit, - dummy_decompress + dummy_decompress, + dummy_compress }; /** @@ -260,8 +266,7 @@ return hr; } -static int mf_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, - UINT32 plane) +static int mf_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize) { HRESULT hr; BYTE* pbBuffer = NULL; @@ -273,8 +278,8 @@ IMFMediaBuffer* outputBuffer = NULL; MFT_OUTPUT_DATA_BUFFER outputDataBuffer; H264_CONTEXT_MF* sys = (H264_CONTEXT_MF*) h264->pSystemData; - INT32* iStride = h264->iStride[plane]; - BYTE** pYUVData = h264->pYUVData[plane]; + INT32* iStride = h264->iStride; + BYTE** pYUVData = h264->pYUVData; hr = sys->MFCreateMemoryBuffer(SrcSize, &inputBuffer); if (FAILED(hr)) @@ -486,8 +491,7 @@ return -1; } -static int mf_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstSize, - UINT32 plane) +static int mf_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstSize) { H264_CONTEXT_MF* sys = (H264_CONTEXT_MF*) h264->pSystemData; return 1; @@ -537,7 +541,7 @@ } for (x = 0; x < sizeof(h264->pYUVData) / sizeof(h264->pYUVData[0]); x++) - free(h264->pYUVData[x][0]); + free(h264->pYUVData[x]); memset(h264->pYUVData, 0, sizeof(h264->pYUVData)); memset(h264->iStride, 0, sizeof(h264->iStride)); @@ -735,18 +739,16 @@ }; typedef struct _H264_CONTEXT_X264 H264_CONTEXT_X264; -static int x264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, - UINT32 plane) +static int x264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize) { //H264_CONTEXT_X264* sys = (H264_CONTEXT_X264*) h264->pSystemData; - return 1; + return -1; } -static int x264_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstSize, - UINT32 plane) +static int x264_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstSize) { //H264_CONTEXT_X264* sys = (H264_CONTEXT_X264*) h264->pSystemData; - return 1; + return -1; } static void x264_uninit(H264_CONTEXT* h264) @@ -847,15 +849,15 @@ WLog_INFO(TAG, "%d - %s", level, message); } -static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, - UINT32 SrcSize, UINT32 plane) +static int openh264_decompress(H264_CONTEXT* h264, const BYTE* pSrcData, + UINT32 SrcSize) { DECODING_STATE state; SBufferInfo sBufferInfo; SSysMEMBuffer* pSystemBuffer; H264_CONTEXT_OPENH264* sys = (H264_CONTEXT_OPENH264*) h264->pSystemData; - UINT32* iStride = h264->iStride[plane]; - BYTE** pYUVData = h264->pYUVData[plane]; + UINT32* iStride = h264->iStride; + BYTE** pYUVData = h264->pYUVData; if (!sys->pDecoder) return -2001; @@ -927,7 +929,7 @@ } static int openh264_compress(H264_CONTEXT* h264, BYTE** ppDstData, - UINT32* pDstSize, UINT32 plane) + UINT32* pDstSize) { int i, j; int status; @@ -935,8 +937,8 @@ SSourcePicture pic; SBitrateInfo bitrate; H264_CONTEXT_OPENH264* sys; - BYTE** pYUVData = h264->pYUVData[plane]; - UINT32* iStride = h264->iStride[plane]; + BYTE** pYUVData = h264->pYUVData; + UINT32* iStride = h264->iStride; sys = &((H264_CONTEXT_OPENH264*) h264->pSystemData)[0]; if (!sys->pEncoder) @@ -1273,6 +1275,11 @@ #include #include +/* Fallback support for older libavcodec versions */ +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 59, 100) +#define AV_CODEC_ID_H264 CODEC_ID_H264 +#endif + struct _H264_CONTEXT_LIBAVCODEC { AVCodec* codec; @@ -1282,20 +1289,39 @@ }; typedef struct _H264_CONTEXT_LIBAVCODEC H264_CONTEXT_LIBAVCODEC; -static int libavcodec_decompress(H264_CONTEXT* h264, BYTE* pSrcData, - UINT32 SrcSize, UINT32 plane) +static int libavcodec_decompress(H264_CONTEXT* h264, const BYTE* pSrcData, + UINT32 SrcSize) { int status; int gotFrame = 0; AVPacket packet; H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*) h264->pSystemData; - BYTE** pYUVData = h264->pYUVData[plane]; - INT32* iStride = h264->iStride[plane]; + BYTE** pYUVData = h264->pYUVData; + UINT32* iStride = h264->iStride; av_init_packet(&packet); - packet.data = pSrcData; + packet.data = (BYTE*)pSrcData; packet.size = SrcSize; + /* avcodec_decode_video2 is deprecated with libavcodec 57.48.101 */ +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101) + status = avcodec_send_packet(sys->codecContext, &packet); + + if (status < 0) + { + WLog_ERR(TAG, "Failed to decode video frame (status=%d)", status); + return -1; + } + + do + { + status = avcodec_receive_frame(sys->codecContext, sys->videoFrame); + } + while (status == AVERROR(EAGAIN)); + + gotFrame = (status == 0); +#else status = avcodec_decode_video2(sys->codecContext, sys->videoFrame, &gotFrame, &packet); +#endif if (status < 0) { @@ -1329,6 +1355,11 @@ return 1; } +static int libavcodec_compress(H264_CONTEXT* h264, BYTE** ppDstData, UINT32* pDstSize) +{ + return -1; +} + static void libavcodec_uninit(H264_CONTEXT* h264) { H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*) h264->pSystemData; @@ -1338,7 +1369,11 @@ if (sys->videoFrame) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 18, 102) + av_frame_free(&sys->videoFrame); +#else av_free(sys->videoFrame); +#endif } if (sys->codecParser) @@ -1349,7 +1384,11 @@ if (sys->codecContext) { avcodec_close(sys->codecContext); +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 69, 100) + avcodec_free_context(&sys->codecContext); +#else av_free(sys->codecContext); +#endif } free(sys); @@ -1368,7 +1407,7 @@ h264->pSystemData = (void*) sys; avcodec_register_all(); - sys->codec = avcodec_find_decoder(CODEC_ID_H264); + sys->codec = avcodec_find_decoder(AV_CODEC_ID_H264); if (!sys->codec) { @@ -1395,7 +1434,7 @@ goto EXCEPTION; } - sys->codecParser = av_parser_init(CODEC_ID_H264); + sys->codecParser = av_parser_init(AV_CODEC_ID_H264); if (!sys->codecParser) { @@ -1403,7 +1442,11 @@ goto EXCEPTION; } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 18, 102) + sys->videoFrame = av_frame_alloc(); +#else sys->videoFrame = avcodec_alloc_frame(); +#endif if (!sys->videoFrame) { @@ -1422,7 +1465,8 @@ "libavcodec", libavcodec_init, libavcodec_uninit, - libavcodec_decompress + libavcodec_decompress, + libavcodec_compress }; #endif @@ -1472,8 +1516,8 @@ } else { - iStride = h264->iStride[0]; - ppYUVData = h264->pYUVData[0]; + iStride = h264->iStride; + ppYUVData = h264->pYUVData; } if (!check_rect(h264, rect, nDstWidth, nDstHeight)) @@ -1521,7 +1565,7 @@ return TRUE; } -INT32 avc420_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, +INT32 avc420_decompress(H264_CONTEXT* h264, const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight, RECTANGLE_16* regionRects, UINT32 numRegionRects) @@ -1531,7 +1575,7 @@ if (!h264) return -1001; - status = h264->subsystem->Decompress(h264, pSrcData, SrcSize, 0); + status = h264->subsystem->Decompress(h264, pSrcData, SrcSize); if (status == 0) return 1; @@ -1546,7 +1590,7 @@ return 1; } -INT32 avc420_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat, +INT32 avc420_compress(H264_CONTEXT* h264, const BYTE* pSrcData, DWORD SrcFormat, UINT32 nSrcStep, UINT32 nSrcWidth, UINT32 nSrcHeight, BYTE** ppDstData, UINT32* pDstSize) { @@ -1563,22 +1607,22 @@ if (!h264->subsystem->Compress) return -1; - iStride = h264->iStride[0]; - pYUVData = h264->pYUVData[0]; + iStride = h264->iStride; + pYUVData = h264->pYUVData; nWidth = (nSrcWidth + 1) & ~1; nHeight = (nSrcHeight + 1) & ~1; - if (!(pYUVData[0] = (BYTE*) malloc(nWidth * nHeight))) + if (!(pYUVData[0] = (BYTE*) _aligned_malloc(nWidth * nHeight, 16))) return -1; iStride[0] = nWidth; - if (!(pYUVData[1] = (BYTE*) malloc(nWidth * nHeight))) + if (!(pYUVData[1] = (BYTE*) _aligned_malloc(nWidth * nHeight, 16))) goto error_1; iStride[1] = nWidth / 2; - if (!(pYUVData[2] = (BYTE*) malloc(nWidth * nHeight))) + if (!(pYUVData[2] = (BYTE*) _aligned_malloc(nWidth * nHeight, 16))) goto error_2; iStride[2] = nWidth / 2; @@ -1586,19 +1630,19 @@ roi.height = nSrcHeight; prims->RGBToYUV420_8u_P3AC4R(pSrcData, SrcFormat, nSrcStep, pYUVData, iStride, &roi); - status = h264->subsystem->Compress(h264, ppDstData, pDstSize, 0); - free(pYUVData[2]); + status = h264->subsystem->Compress(h264, ppDstData, pDstSize); + _aligned_free(pYUVData[2]); pYUVData[2] = NULL; error_2: - free(pYUVData[1]); + _aligned_free(pYUVData[1]); pYUVData[1] = NULL; error_1: - free(pYUVData[0]); + _aligned_free(pYUVData[0]); pYUVData[0] = NULL; return status; } -INT32 avc444_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat, +INT32 avc444_compress(H264_CONTEXT* h264, const BYTE* pSrcData, DWORD SrcFormat, UINT32 nSrcStep, UINT32 nSrcWidth, UINT32 nSrcHeight, BYTE* op, BYTE** ppDstData, UINT32* pDstSize, BYTE** ppAuxDstData, UINT32* pAuxDstSize) @@ -1606,89 +1650,12 @@ return -1; } -static BOOL avc444_process_rect(H264_CONTEXT* h264, - const RECTANGLE_16* rect, - UINT32 nDstWidth, UINT32 nDstHeight) -{ - const primitives_t* prims = primitives_get(); - prim_size_t roi; - UINT16 width, height; - const BYTE* pYUVMainPoint[3]; - const BYTE* pYUVAuxPoint[3]; - BYTE* pYUVDstPoint[3]; - UINT32* piDstStride = h264->iYUV444Stride; - BYTE** ppYUVDstData = h264->pYUV444Data; - const UINT32* piAuxStride = h264->iStride[1]; - const UINT32* piMainStride = h264->iStride[0]; - BYTE** ppYUVAuxData = h264->pYUVData[1]; - BYTE** ppYUVMainData = h264->pYUVData[0]; - - if (!check_rect(h264, rect, nDstWidth, nDstHeight)) - return FALSE; - - width = rect->right - rect->left + 1; - height = rect->bottom - rect->top + 1; - roi.width = width; - roi.height = height; - pYUVMainPoint[0] = ppYUVMainData[0] + rect->top * piMainStride[0] + - rect->left; - pYUVMainPoint[1] = ppYUVMainData[1] + rect->top / 2 * piMainStride[1] + - rect->left / 2; - pYUVMainPoint[2] = ppYUVMainData[2] + rect->top / 2 * piMainStride[2] + - rect->left / 2; - pYUVDstPoint[0] = ppYUVDstData[0] + rect->top * piDstStride[0] + - rect->left; - pYUVDstPoint[1] = ppYUVDstData[1] + rect->top * piDstStride[1] + - rect->left; - pYUVDstPoint[2] = ppYUVDstData[2] + rect->top * piDstStride[2] + - rect->left; - pYUVAuxPoint[0] = ppYUVAuxData[0] + rect->top * piAuxStride[0] + - rect->left; - pYUVAuxPoint[1] = ppYUVAuxData[1] + rect->top / 2 * piAuxStride[1] + - rect->left / 2; - pYUVAuxPoint[2] = ppYUVAuxData[2] + rect->top / 2 * piAuxStride[2] + - rect->left / 2; - pYUVDstPoint[0] = ppYUVDstData[0] + rect->top * piDstStride[0] + - rect->left; - pYUVDstPoint[1] = ppYUVDstData[1] + rect->top * piDstStride[1] + - rect->left; - pYUVDstPoint[2] = ppYUVDstData[2] + rect->top * piDstStride[2] + - rect->left; - - if (prims->YUV420CombineToYUV444(pYUVMainPoint, piMainStride, - NULL, NULL, - pYUVDstPoint, piDstStride, - &roi) != PRIMITIVES_SUCCESS) - return FALSE; - - return TRUE; -} - -static void avc444_rectangle_max(RECTANGLE_16* dst, const RECTANGLE_16* add) -{ - if (dst->left > add->left) - dst->left = add->left; - - if (dst->right < add->right) - dst->right = add->right; - - if (dst->top > add->top) - dst->top = add->top; - - if (dst->bottom < add->bottom) - dst->bottom = add->bottom; -} -static BOOL avc444_combine_yuv(H264_CONTEXT* h264, - const RECTANGLE_16* mainRegionRects, - UINT32 numMainRegionRect, - const RECTANGLE_16* auxRegionRects, - UINT32 numAuxRegionRect, UINT32 nDstWidth, - DWORD nDstHeight, UINT32 nDstStep) +static BOOL avc444_ensure_buffer(H264_CONTEXT* h264, + DWORD nDstHeight) { UINT32 x; - RECTANGLE_16 rect; - const UINT32* piMainStride = h264->iStride[0]; + const UINT32* piMainStride = h264->iStride; UINT32* piDstSize = h264->iYUV444Size; UINT32* piDstStride = h264->iYUV444Stride; BYTE** ppYUVDstData = h264->pYUV444Data; @@ -1699,15 +1666,14 @@ { for (x = 0; x < 3; x++) { - BYTE* ppYUVTmpData; piDstStride[x] = piMainStride[0]; piDstSize[x] = piDstStride[x] * padDstHeight; - ppYUVTmpData = realloc(ppYUVDstData[x], piDstSize[x]); + _aligned_free(ppYUVDstData[x]); + ppYUVDstData[x] = _aligned_malloc(piDstSize[x], 16); - if (!ppYUVTmpData) + if (!ppYUVDstData[x]) goto fail; - ppYUVDstData[x] = ppYUVTmpData; memset(ppYUVDstData[x], 0, piDstSize[x]); } } @@ -1721,31 +1687,86 @@ } } - rect.right = 0; - rect.bottom = 0; - rect.left = 0xFFFF; - rect.top = 0xFFFF; - - for (x = 0; x < numMainRegionRect; x++) - avc444_rectangle_max(&rect, &mainRegionRects[x]); - - for (x = 0; x < numAuxRegionRect; x++) - avc444_rectangle_max(&rect, &auxRegionRects[x]); - - if (!avc444_process_rect(h264, &rect, nDstWidth, nDstHeight)) - goto fail; - return TRUE; fail: - free(ppYUVDstData[0]); - free(ppYUVDstData[1]); - free(ppYUVDstData[2]); + _aligned_free(ppYUVDstData[0]); + _aligned_free(ppYUVDstData[1]); + _aligned_free(ppYUVDstData[2]); ppYUVDstData[0] = NULL; ppYUVDstData[1] = NULL; ppYUVDstData[2] = NULL; return FALSE; } +static BOOL avc444_process_rects(H264_CONTEXT* h264, const BYTE* pSrcData, + UINT32 SrcSize, BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, + UINT32 nDstWidth, UINT32 nDstHeight, + const RECTANGLE_16* rects, UINT32 nrRects, + BOOL main) +{ + const primitives_t* prims = primitives_get(); + UINT32 x; + const BYTE* pYUVPoint[3] = { NULL, NULL, NULL }; + BYTE* pYUVDstPoint[3]; + UINT32* piDstStride = h264->iYUV444Stride; + BYTE** ppYUVDstData = h264->pYUV444Data; + const UINT32* piStride = h264->iStride; + BYTE** ppYUVData = h264->pYUVData; + + if (h264->subsystem->Decompress(h264, pSrcData, SrcSize) < 0) + return FALSE; + + if (!avc444_ensure_buffer(h264, nDstHeight)) + return FALSE; + + for (x = 0; x < nrRects; x++) + { + const RECTANGLE_16* rect = &rects[x]; + prim_size_t roi; + + if (!check_rect(h264, rect, nDstWidth, nDstHeight)) + continue; + + pYUVPoint[0] = ppYUVData[0] + rect->top * piStride[0] + + rect->left; + pYUVPoint[1] = ppYUVData[1] + rect->top / 2 * piStride[1] + + rect->left / 2; + pYUVPoint[2] = ppYUVData[2] + rect->top / 2 * piStride[2] + + rect->left / 2; + pYUVDstPoint[0] = ppYUVDstData[0] + rect->top * piDstStride[0] + + rect->left; + pYUVDstPoint[1] = ppYUVDstData[1] + rect->top * piDstStride[1] + + rect->left; + pYUVDstPoint[2] = ppYUVDstData[2] + rect->top * piDstStride[2] + + rect->left; + roi.width = rect->right - rect->left + 1; + roi.height = rect->bottom - rect->top + 1; + + if (main) + { + if (prims->YUV420CombineToYUV444(pYUVPoint, piStride, + NULL, NULL, + pYUVDstPoint, piDstStride, + &roi) != PRIMITIVES_SUCCESS) + return FALSE; + } + else + { + if (prims->YUV420CombineToYUV444(NULL, NULL, + pYUVPoint, piStride, + pYUVDstPoint, piDstStride, + &roi) != PRIMITIVES_SUCCESS) + return FALSE; + } + } + + if (!avc_yuv_to_rgb(h264, rects, nrRects, nDstWidth, + nDstHeight, nDstStep, pDstData, DstFormat, TRUE)) + return FALSE; + + return TRUE; +} + #if defined(AVC444_FRAME_STAT) static UINT64 op1 = 0; static double op1sum = 0; @@ -1764,17 +1785,13 @@ INT32 avc444_decompress(H264_CONTEXT* h264, BYTE op, RECTANGLE_16* regionRects, UINT32 numRegionRects, - BYTE* pSrcData, UINT32 SrcSize, + const BYTE* pSrcData, UINT32 SrcSize, RECTANGLE_16* auxRegionRects, UINT32 numAuxRegionRect, - BYTE* pAuxSrcData, UINT32 AuxSrcSize, + const BYTE* pAuxSrcData, UINT32 AuxSrcSize, BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight) { INT32 status = -1; - UINT32 numYuvRects = 0; - RECTANGLE_16* yuvRects = NULL; - UINT32 numChromaRects = 0; - RECTANGLE_16* chromaRects = NULL; if (!h264 || !regionRects || !pSrcData || !pDstData) @@ -1784,27 +1801,37 @@ { case 0: /* YUV420 in stream 1 * Chroma420 in stream 2 */ - numYuvRects = numRegionRects; - yuvRects = regionRects; - numChromaRects = numAuxRegionRect; - chromaRects = auxRegionRects; - status = h264->subsystem->Decompress(h264, pSrcData, SrcSize, 0); - - if (status >= 0) - status = h264->subsystem->Decompress(h264, pAuxSrcData, AuxSrcSize, 1); + if (!avc444_process_rects(h264, pSrcData, SrcSize, pDstData, DstFormat, nDstStep, nDstWidth, + nDstHeight, + regionRects, numRegionRects, TRUE)) + status = -1; + else if (!avc444_process_rects(h264, pAuxSrcData, AuxSrcSize, pDstData, DstFormat, nDstStep, + nDstWidth, nDstHeight, + auxRegionRects, numAuxRegionRect, FALSE)) + status = -1; + else + status = 0; break; case 2: /* Chroma420 in stream 1 */ - status = h264->subsystem->Decompress(h264, pSrcData, SrcSize, 1); - numChromaRects = numRegionRects; - chromaRects = regionRects; + if (!avc444_process_rects(h264, pSrcData, SrcSize, pDstData, DstFormat, nDstStep, nDstWidth, + nDstHeight, + regionRects, numRegionRects, FALSE)) + status = -1; + else + status = 0; + break; case 1: /* YUV420 in stream 1 */ - status = h264->subsystem->Decompress(h264, pSrcData, SrcSize, 0); - numYuvRects = numRegionRects; - yuvRects = regionRects; + if (!avc444_process_rects(h264, pSrcData, SrcSize, pDstData, DstFormat, nDstStep, nDstWidth, + nDstHeight, + regionRects, numRegionRects, TRUE)) + status = -1; + else + status = 0; + break; default: /* WTF? */ @@ -1835,32 +1862,6 @@ "luma=%"PRIu64" [avg=%lf] chroma=%"PRIu64" [avg=%lf] combined=%"PRIu64" [avg=%lf]", op1, op1sum, op2, op2sum, op3, op3sum); #endif - - if (status >= 0) - { - if (!avc444_combine_yuv(h264, yuvRects, numYuvRects, - chromaRects, numChromaRects, - nDstWidth, nDstHeight, nDstStep)) - status = -1002; - else - { - if (numYuvRects > 0) - { - if (!avc_yuv_to_rgb(h264, regionRects, numRegionRects, nDstWidth, - nDstHeight, nDstStep, pDstData, DstFormat, TRUE)) - status = -1003; - } - - if (numChromaRects > 0) - { - if (!avc_yuv_to_rgb(h264, auxRegionRects, numAuxRegionRect, - nDstWidth, nDstHeight, nDstStep, pDstData, - DstFormat, TRUE)) - status = -1004; - } - } - } - return status; } @@ -1947,9 +1948,9 @@ if (h264) { h264->subsystem->Uninit(h264); - free(h264->pYUV444Data[0]); - free(h264->pYUV444Data[1]); - free(h264->pYUV444Data[2]); + _aligned_free(h264->pYUV444Data[0]); + _aligned_free(h264->pYUV444Data[1]); + _aligned_free(h264->pYUV444Data[2]); free(h264); } } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/include/bitmap.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/include/bitmap.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/include/bitmap.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/include/bitmap.c 2017-03-03 08:39:24.000000000 +0000 @@ -24,8 +24,8 @@ /** * Write a foreground/background image to a destination buffer. */ -static BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, - BYTE bitmask, PIXEL fgPel, INT32 cBits) +static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, + BYTE bitmask, PIXEL fgPel, INT32 cBits) { PIXEL xorPixel; DESTREADPIXEL(xorPixel, pbDest - rowDelta); @@ -167,8 +167,8 @@ * Write a foreground/background image to a destination buffer * for the first line of compressed data. */ -static BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, - PIXEL fgPel, UINT32 cBits) +static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, + PIXEL fgPel, UINT32 cBits) { if (bitmask & g_MaskBit0) { @@ -292,9 +292,9 @@ /** * Decompress an RLE compressed bitmap. */ -static void RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, - BYTE* pbDestBuffer, - UINT32 rowDelta, UINT32 width, UINT32 height) +static INLINE void RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, + BYTE* pbDestBuffer, + UINT32 rowDelta, UINT32 width, UINT32 height) { const BYTE* pbSrc = pbSrcBuffer; const BYTE* pbEnd = pbSrcBuffer + cbSrcBuffer; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/mppc.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/mppc.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/mppc.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/mppc.c 2017-03-03 08:39:24.000000000 +0000 @@ -34,7 +34,7 @@ #define MPPC_MATCH_INDEX(_sym1, _sym2, _sym3) \ ((((MPPC_MATCH_TABLE[_sym3] << 16) + (MPPC_MATCH_TABLE[_sym2] << 8) + MPPC_MATCH_TABLE[_sym1]) & 0x07FFF000) >> 12) -const UINT32 MPPC_MATCH_TABLE[256] = +static const UINT32 MPPC_MATCH_TABLE[256] = { 0x00000000, 0x009CCF93, 0x01399F26, 0x01D66EB9, 0x02733E4C, 0x03100DDF, 0x03ACDD72, 0x0449AD05, 0x04E67C98, 0x05834C2B, 0x06201BBE, 0x06BCEB51, 0x0759BAE4, 0x07F68A77, 0x08935A0A, 0x0930299D, @@ -72,7 +72,8 @@ //#define DEBUG_MPPC 1 -int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags) +int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, + UINT32* pDstSize, UINT32 flags) { BYTE Literal; BYTE* SrcPtr; @@ -86,12 +87,10 @@ UINT32 HistoryBufferSize; UINT32 CompressionLevel; wBitStream* bs = mppc->bs; - HistoryBuffer = mppc->HistoryBuffer; HistoryBufferSize = mppc->HistoryBufferSize; HistoryBufferEnd = &HistoryBuffer[HistoryBufferSize - 1]; CompressionLevel = mppc->CompressionLevel; - BitStream_Attach(bs, pSrcData, SrcSize); BitStream_Fetch(bs); @@ -138,14 +137,10 @@ * Literal, less than 0x80 * bit 0 followed by the lower 7 bits of the literal */ - Literal = ((accumulator & 0x7F000000) >> 24); - *(HistoryPtr) = Literal; HistoryPtr++; - BitStream_Shift(bs, 8); - continue; } else if ((accumulator & 0xC0000000) == 0x80000000) @@ -154,21 +149,16 @@ * Literal, greater than 0x7F * bits 10 followed by the lower 7 bits of the literal */ - Literal = ((accumulator & 0x3F800000) >> 23) + 0x80; - *(HistoryPtr) = Literal; HistoryPtr++; - BitStream_Shift(bs, 9); - continue; } /** * CopyOffset Encoding */ - CopyOffset = 0; if (CompressionLevel) /* RDP5 */ @@ -179,7 +169,6 @@ * CopyOffset, range [0, 63] * bits 11111 + lower 6 bits of CopyOffset */ - CopyOffset = ((accumulator >> 21) & 0x3F); BitStream_Shift(bs, 11); } @@ -189,7 +178,6 @@ * CopyOffset, range [64, 319] * bits 11110 + lower 8 bits of (CopyOffset - 64) */ - CopyOffset = ((accumulator >> 19) & 0xFF) + 64; BitStream_Shift(bs, 13); } @@ -199,7 +187,6 @@ * CopyOffset, range [320, 2367] * bits 1110 + lower 11 bits of (CopyOffset - 320) */ - CopyOffset = ((accumulator >> 17) & 0x7FF) + 320; BitStream_Shift(bs, 15); } @@ -209,7 +196,6 @@ * CopyOffset, range [2368, ] * bits 110 + lower 16 bits of (CopyOffset - 2368) */ - CopyOffset = ((accumulator >> 13) & 0xFFFF) + 2368; BitStream_Shift(bs, 19); } @@ -227,7 +213,6 @@ * CopyOffset, range [0, 63] * bits 1111 + lower 6 bits of CopyOffset */ - CopyOffset = ((accumulator >> 22) & 0x3F); BitStream_Shift(bs, 10); } @@ -237,7 +222,6 @@ * CopyOffset, range [64, 319] * bits 1110 + lower 8 bits of (CopyOffset - 64) */ - CopyOffset = ((accumulator >> 20) & 0xFF) + 64; BitStream_Shift(bs, 12); } @@ -247,7 +231,6 @@ * CopyOffset, range [320, 8191] * bits 110 + lower 13 bits of (CopyOffset - 320) */ - CopyOffset = ((accumulator >> 16) & 0x1FFF) + 320; BitStream_Shift(bs, 16); } @@ -261,7 +244,6 @@ /** * LengthOfMatch Encoding */ - LengthOfMatch = 0; accumulator = bs->accumulator; @@ -271,7 +253,6 @@ * LengthOfMatch [3] * bit 0 + 0 lower bits of LengthOfMatch */ - LengthOfMatch = 3; BitStream_Shift(bs, 1); } @@ -281,7 +262,6 @@ * LengthOfMatch [4, 7] * bits 10 + 2 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 28) & 0x0003) + 0x0004; BitStream_Shift(bs, 4); } @@ -291,7 +271,6 @@ * LengthOfMatch [8, 15] * bits 110 + 3 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 26) & 0x0007) + 0x0008; BitStream_Shift(bs, 6); } @@ -301,7 +280,6 @@ * LengthOfMatch [16, 31] * bits 1110 + 4 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 24) & 0x000F) + 0x0010; BitStream_Shift(bs, 8); } @@ -311,7 +289,6 @@ * LengthOfMatch [32, 63] * bits 11110 + 5 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 22) & 0x001F) + 0x0020; BitStream_Shift(bs, 10); } @@ -321,7 +298,6 @@ * LengthOfMatch [64, 127] * bits 111110 + 6 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 20) & 0x003F) + 0x0040; BitStream_Shift(bs, 12); } @@ -331,7 +307,6 @@ * LengthOfMatch [128, 255] * bits 1111110 + 7 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 18) & 0x007F) + 0x0080; BitStream_Shift(bs, 14); } @@ -341,7 +316,6 @@ * LengthOfMatch [256, 511] * bits 11111110 + 8 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 16) & 0x00FF) + 0x0100; BitStream_Shift(bs, 16); } @@ -351,7 +325,6 @@ * LengthOfMatch [512, 1023] * bits 111111110 + 9 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 14) & 0x01FF) + 0x0200; BitStream_Shift(bs, 18); } @@ -361,7 +334,6 @@ * LengthOfMatch [1024, 2047] * bits 1111111110 + 10 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 12) & 0x03FF) + 0x0400; BitStream_Shift(bs, 20); } @@ -371,7 +343,6 @@ * LengthOfMatch [2048, 4095] * bits 11111111110 + 11 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 10) & 0x07FF) + 0x0800; BitStream_Shift(bs, 22); } @@ -381,7 +352,6 @@ * LengthOfMatch [4096, 8191] * bits 111111111110 + 12 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 8) & 0x0FFF) + 0x1000; BitStream_Shift(bs, 24); } @@ -391,7 +361,6 @@ * LengthOfMatch [8192, 16383] * bits 1111111111110 + 13 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 6) & 0x1FFF) + 0x2000; BitStream_Shift(bs, 26); } @@ -401,7 +370,6 @@ * LengthOfMatch [16384, 32767] * bits 11111111111110 + 14 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 4) & 0x3FFF) + 0x4000; BitStream_Shift(bs, 28); } @@ -411,7 +379,6 @@ * LengthOfMatch [32768, 65535] * bits 111111111111110 + 15 lower bits of LengthOfMatch */ - LengthOfMatch = ((accumulator >> 2) & 0x7FFF) + 0x8000; BitStream_Shift(bs, 30); } @@ -431,21 +398,24 @@ return -1005; } - SrcPtr = &HistoryBuffer[(HistoryPtr - HistoryBuffer - CopyOffset) & (CompressionLevel ? 0xFFFF : 0x1FFF)]; + SrcPtr = &HistoryBuffer[(HistoryPtr - HistoryBuffer - CopyOffset) & (CompressionLevel ? 0xFFFF : + 0x1FFF)]; - do { + do + { *HistoryPtr++ = *SrcPtr++; - } while (--LengthOfMatch); + } + while (--LengthOfMatch); } - *pDstSize = (UINT32) (HistoryPtr - mppc->HistoryPtr); + *pDstSize = (UINT32)(HistoryPtr - mppc->HistoryPtr); *ppDstData = mppc->HistoryPtr; mppc->HistoryPtr = HistoryPtr; - return 1; } -int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags) +int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, + UINT32* pDstSize, UINT32* pFlags) { BYTE* pSrcPtr; BYTE* pSrcEnd; @@ -466,14 +436,11 @@ BYTE Sym1, Sym2, Sym3; UINT32 CompressionLevel; wBitStream* bs = mppc->bs; - HistoryBuffer = mppc->HistoryBuffer; HistoryBufferSize = mppc->HistoryBufferSize; CompressionLevel = mppc->CompressionLevel; - HistoryPtr = mppc->HistoryPtr; HistoryOffset = mppc->HistoryOffset; - *pFlags = 0; PacketFlushed = FALSE; @@ -491,7 +458,6 @@ } HistoryPtr = &(HistoryBuffer[HistoryOffset]); - pDstData = *ppDstData; if (!pDstData) @@ -503,7 +469,6 @@ DstSize = *pDstSize; BitStream_Attach(bs, pDstData, DstSize); - pSrcPtr = pSrcData; pSrcEnd = &(pSrcData[SrcSize - 1]); pDstEnd = &(pDstData[DstSize - 1]); @@ -513,21 +478,19 @@ Sym1 = pSrcPtr[0]; Sym2 = pSrcPtr[1]; Sym3 = pSrcPtr[2]; - *HistoryPtr++ = *pSrcPtr++; - MatchIndex = MPPC_MATCH_INDEX(Sym1, Sym2, Sym3); MatchPtr = &(HistoryBuffer[mppc->MatchBuffer[MatchIndex]]); if (MatchPtr != (HistoryPtr - 1)) - mppc->MatchBuffer[MatchIndex] = (UINT16) (HistoryPtr - HistoryBuffer); + mppc->MatchBuffer[MatchIndex] = (UINT16)(HistoryPtr - HistoryBuffer); if (mppc->HistoryPtr < HistoryPtr) mppc->HistoryPtr = HistoryPtr; if ((Sym1 != *(MatchPtr - 1)) || (Sym2 != MatchPtr[0]) || (Sym3 != MatchPtr[1]) || - (&MatchPtr[1] > mppc->HistoryPtr) || (MatchPtr == HistoryBuffer) || - (MatchPtr == (HistoryPtr - 1)) || (MatchPtr == HistoryPtr)) + (&MatchPtr[1] > mppc->HistoryPtr) || (MatchPtr == HistoryBuffer) || + (MatchPtr == (HistoryPtr - 1)) || (MatchPtr == HistoryPtr)) { if (((bs->position / 8) + 2) > (DstSize - 1)) { @@ -540,7 +503,6 @@ } accumulator = Sym1; - #ifdef DEBUG_MPPC WLog_DBG(TAG, "%"PRIu32"", accumulator); #endif @@ -560,11 +522,9 @@ else { CopyOffset = (HistoryBufferSize - 1) & (HistoryPtr - MatchPtr); - *HistoryPtr++ = Sym2; *HistoryPtr++ = Sym3; pSrcPtr += 2; - LengthOfMatch = 3; MatchPtr += 2; @@ -749,7 +709,6 @@ } accumulator = *pSrcPtr; - #ifdef DEBUG_MPPC WLog_DBG(TAG, "%"PRIu32"", accumulator); #endif @@ -770,7 +729,6 @@ } BitStream_Flush(bs); - *pFlags |= PACKET_COMPRESSED; *pFlags |= CompressionLevel; @@ -781,10 +739,8 @@ *pFlags |= PACKET_FLUSHED; *pDstSize = ((bs->position + 7) / 8); - mppc->HistoryPtr = HistoryPtr; mppc->HistoryOffset = HistoryPtr - HistoryBuffer; - return 1; } @@ -818,7 +774,6 @@ MPPC_CONTEXT* mppc_context_new(DWORD CompressionLevel, BOOL Compressor) { MPPC_CONTEXT* mppc; - mppc = calloc(1, sizeof(MPPC_CONTEXT)); if (mppc) @@ -837,6 +792,7 @@ } mppc->bs = BitStream_New(); + if (!mppc->bs) { free(mppc); @@ -854,7 +810,6 @@ if (mppc) { BitStream_Free(mppc->bs); - free(mppc); } } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/planar.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/planar.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/planar.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/planar.c 2017-03-03 08:39:24.000000000 +0000 @@ -33,18 +33,16 @@ #define TAG FREERDP_TAG("codec") -static BYTE* freerdp_bitmap_planar_compress_plane_rle( +static INLINE BYTE* freerdp_bitmap_planar_compress_plane_rle( const BYTE* plane, UINT32 width, UINT32 height, BYTE* outPlane, UINT32* dstSize); -static BYTE* freerdp_bitmap_planar_delta_encode_plane( +static INLINE BYTE* freerdp_bitmap_planar_delta_encode_plane( const BYTE* inPlane, UINT32 width, UINT32 height, BYTE* outPlane); -static INT32 planar_skip_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, - UINT32 nWidth, UINT32 nHeight) +static INLINE INT32 planar_skip_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, + UINT32 nWidth, UINT32 nHeight) { UINT32 x, y; - int cRawBytes; - int nRunLength; BYTE controlByte; const BYTE* pRLE = pSrcData; const BYTE* pEnd = &pSrcData[SrcSize]; @@ -53,6 +51,9 @@ { for (x = 0; x < nWidth;) { + int cRawBytes; + int nRunLength; + if (pRLE >= pEnd) return -1; @@ -73,9 +74,7 @@ pRLE += cRawBytes; x += cRawBytes; - cRawBytes = 0; x += nRunLength; - nRunLength = 0; if (x > nWidth) return -1; @@ -88,14 +87,13 @@ return (INT32)(pRLE - pSrcData); } -static INT32 planar_decompress_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, +static INLINE INT32 planar_decompress_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, INT32 nDstStep, UINT32 nXDst, UINT32 nYDst, UINT32 nWidth, UINT32 nHeight, UINT32 nChannel, BOOL vFlip) { UINT32 x, y; - BYTE* dstp; UINT32 pixel; UINT32 cRawBytes; UINT32 nRunLength; @@ -105,7 +103,6 @@ BYTE* currentScanline; BYTE* previousScanline; const BYTE* srcp = pSrcData; - dstp = pDstData; previousScanline = NULL; if (vFlip) @@ -123,7 +120,7 @@ for (y = beg; y != end; y += inc) { - dstp = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4) + nChannel]; + BYTE* dstp = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4) + nChannel]; pixel = 0; currentScanline = dstp; @@ -223,12 +220,71 @@ return (INT32)(srcp - pSrcData); } -static BOOL planar_decompress_planes_raw(const BYTE* pSrcData[4], +static INLINE BOOL writeLine(BYTE** ppRgba, UINT32 DstFormat, UINT32 width, const BYTE** ppR, + const BYTE** ppG, const BYTE** ppB, const BYTE** ppA) +{ + UINT32 x; + + if (!ppRgba || !ppR || !ppG || !ppB) + return FALSE; + + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + for (x = 0; x < width; x++) + { + *(*ppRgba)++ = *(*ppB)++; + *(*ppRgba)++ = *(*ppG)++; + *(*ppRgba)++ = *(*ppR)++; + *(*ppRgba)++ = *(*ppA)++; + } + + return TRUE; + + case PIXEL_FORMAT_BGRX32: + for (x = 0; x < width; x++) + { + *(*ppRgba)++ = *(*ppB)++; + *(*ppRgba)++ = *(*ppG)++; + *(*ppRgba)++ = *(*ppR)++; + *(*ppRgba)++ = 0xFF; + } + + return TRUE; + + default: + if (ppA) + { + for (x = 0; x < width; x++) + { + BYTE alpha = *(*ppA)++; + UINT32 color = GetColor(DstFormat, *(*ppR)++, *(*ppG)++, *(*ppB)++, alpha); + WriteColor(*ppRgba, DstFormat, color); + *ppRgba += GetBytesPerPixel(DstFormat); + } + } + else + { + const BYTE alpha = 0xFF; + + for (x = 0; x < width; x++) + { + UINT32 color = GetColor(DstFormat, *(*ppR)++, *(*ppG)++, *(*ppB)++, alpha); + WriteColor(*ppRgba, DstFormat, color); + *ppRgba += GetBytesPerPixel(DstFormat); + } + } + + return TRUE; + } +} + +static INLINE BOOL planar_decompress_planes_raw(const BYTE* pSrcData[4], BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst, UINT32 nWidth, UINT32 nHeight, BOOL alpha, BOOL vFlip) { - INT32 x, y; + INT32 y; INT32 beg, end, inc; const BYTE* pR = pSrcData[0]; const BYTE* pG = pSrcData[1]; @@ -255,12 +311,8 @@ BYTE* pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * GetBytesPerPixel( DstFormat))]; - for (x = 0; x < nWidth; x++) - { - UINT32 color = GetColor(DstFormat, *pR++, *pG++, *pB++, *pA++); - WriteColor(pRGB, DstFormat, color); - pRGB += GetBytesPerPixel(DstFormat); - } + if (!writeLine(&pRGB, DstFormat, nWidth, &pR, &pG, &pB, &pA)) + return FALSE; } } else @@ -270,12 +322,8 @@ BYTE* pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * GetBytesPerPixel( DstFormat))]; - for (x = 0; x < nWidth; x++) - { - UINT32 color = GetColor(DstFormat, *pR++, *pG++, *pB++, 0xFF); - WriteColor(pRGB, DstFormat, color); - pRGB += GetBytesPerPixel(DstFormat); - } + if (!writeLine(&pRGB, DstFormat, nWidth, &pR, &pG, &pB, &pA)) + return FALSE; } } @@ -304,21 +352,15 @@ UINT32 rawWidths[4]; UINT32 rawHeights[4]; BYTE FormatHeader; - UINT32 dstBitsPerPixel; - UINT32 dstBytesPerPixel; const BYTE* planes[4]; - UINT32 UncompressedSize; const UINT32 w = MIN(nSrcWidth, nDstWidth); const UINT32 h = MIN(nSrcHeight, nDstHeight); const primitives_t* prims = primitives_get(); - dstBitsPerPixel = GetBitsPerPixel(DstFormat); - dstBytesPerPixel = GetBytesPerPixel(DstFormat); if (nDstStep <= 0) nDstStep = nDstWidth * GetBytesPerPixel(DstFormat); srcp = pSrcData; - UncompressedSize = nSrcWidth * nSrcHeight * GetBytesPerPixel(DstFormat); if (!pDstData) { @@ -470,13 +512,14 @@ || (nSrcHeight != nDstHeight)) { pTempData = planar->pTempData; + nTempStep = planar->nTempStep; } if (!rle) /* RAW */ { if (alpha) { - if (!planar_decompress_planes_raw(planes, pTempData, TempFormat, nDstStep, + if (!planar_decompress_planes_raw(planes, pTempData, TempFormat, nTempStep, nXDst, nYDst, nSrcWidth, nSrcHeight, alpha, vFlip)) return FALSE; @@ -484,7 +527,7 @@ } else /* NoAlpha */ { - if (!planar_decompress_planes_raw(planes, pTempData, TempFormat, nDstStep, + if (!planar_decompress_planes_raw(planes, pTempData, TempFormat, nTempStep, nXDst, nYDst, nSrcWidth, nSrcHeight, alpha, vFlip)) return FALSE; @@ -573,7 +616,7 @@ { BYTE* pTempData = planar->pTempData; UINT32 nTempStep = planar->nTempStep; - UINT32 TempFormat = PIXEL_FORMAT_RGBA32; + UINT32 TempFormat = PIXEL_FORMAT_BGRA32; if (!pTempData) return FALSE; @@ -676,9 +719,9 @@ return (SrcSize == (srcp - pSrcData)) ? TRUE : FALSE; } -static BOOL freerdp_split_color_planes(const BYTE* data, UINT32 format, - UINT32 width, UINT32 height, - UINT32 scanline, BYTE* planes[4]) +static INLINE BOOL freerdp_split_color_planes(const BYTE* data, UINT32 format, + UINT32 width, UINT32 height, + UINT32 scanline, BYTE* planes[4]) { INT32 i, j, k; k = 0; @@ -703,7 +746,7 @@ return TRUE; } -static UINT32 freerdp_bitmap_planar_write_rle_bytes( +static INLINE UINT32 freerdp_bitmap_planar_write_rle_bytes( const BYTE* pInBuffer, UINT32 cRawBytes, UINT32 nRunLength, BYTE* pOutBuffer, UINT32 outBufferSize) { @@ -817,7 +860,7 @@ return (pOutput - pOutBuffer); } -static UINT32 freerdp_bitmap_planar_encode_rle_bytes(const BYTE* pInBuffer, +static INLINE UINT32 freerdp_bitmap_planar_encode_rle_bytes(const BYTE* pInBuffer, UINT32 inBufferSize, BYTE* pOutBuffer, UINT32 outBufferSize) @@ -955,7 +998,7 @@ return outPlane; } -static UINT32 freerdp_bitmap_planar_compress_planes_rle( +static INLINE UINT32 freerdp_bitmap_planar_compress_planes_rle( BYTE* inPlanes[4], UINT32 width, UINT32 height, BYTE* outPlanes, UINT32* dstSizes, BOOL skipAlpha) { @@ -1003,8 +1046,6 @@ outPlanes, &dstSizes[3])) return 0; - outPlanes += dstSizes[3]; - outPlanesSize -= dstSizes[3]; return 1; } @@ -1047,7 +1088,7 @@ return outPlane; } -static BOOL freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], +static INLINE BOOL freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], UINT32 width, UINT32 height, BYTE* outPlanes[4]) { @@ -1073,7 +1114,7 @@ UINT32 size; BYTE* dstp; UINT32 planeSize; - UINT32 dstSizes[4]; + UINT32 dstSizes[4] = { 0 }; BYTE FormatHeader = 0; if (!context || !context->rlePlanesBuffer) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/progressive.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/progressive.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/progressive.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/progressive.c 2017-03-03 08:39:24.000000000 +0000 @@ -34,6 +34,7 @@ #include "rfx_differential.h" #include "rfx_quantization.h" #include "rfx_rlgr.h" +#include "progressive.h" #define TAG FREERDP_TAG("codec.progressive") @@ -745,12 +746,12 @@ const primitives_t* prims = primitives_get(); tile->pass = 1; diff = tile->flags & RFX_TILE_DIFFERENCE; - WLog_DBG(TAG, - "ProgressiveTile%s: quantIdx Y: %"PRIu8" Cb: %"PRIu8" Cr: %"PRIu8" xIdx: %"PRIu16" yIdx: %"PRIu16" flags: 0x%02"PRIX8" quality: %"PRIu8" yLen: %"PRIu16" cbLen: %"PRIu16" crLen: %"PRIu16" tailLen: %"PRIu16"", - (tile->blockType == PROGRESSIVE_WBT_TILE_FIRST) ? "First" : "Simple", - tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, - tile->xIdx, tile->yIdx, tile->flags, tile->quality, tile->yLen, - tile->cbLen, tile->crLen, tile->tailLen); + WLog_Print(progressive->log, WLOG_DEBUG, + "ProgressiveTile%s: quantIdx Y: %"PRIu8" Cb: %"PRIu8" Cr: %"PRIu8" xIdx: %"PRIu16" yIdx: %"PRIu16" flags: 0x%02"PRIX8" quality: %"PRIu8" yLen: %"PRIu16" cbLen: %"PRIu16" crLen: %"PRIu16" tailLen: %"PRIu16"", + (tile->blockType == PROGRESSIVE_WBT_TILE_FIRST) ? "First" : "Simple", + tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, + tile->xIdx, tile->yIdx, tile->flags, tile->quality, tile->yLen, + tile->cbLen, tile->crLen, tile->tailLen); region = &(progressive->region); if (tile->quantIdxY >= region->numQuant) @@ -844,16 +845,9 @@ progressive_rfx_decode_component(progressive, &shiftCr, tile->crData, tile->crLen, pSrcDst[2], pCurrent[2], pSign[2], diff); /* Cr */ - - if (!progressive->invert) - prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, - tile->data, PIXEL_FORMAT_BGRX32, - 64 * 4, &roi_64x64); - else - prims->yCbCrToBGR_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, - tile->data, PIXEL_FORMAT_BGRX32, - 64 * 4, &roi_64x64); - + prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, + tile->data, tile->stride, tile->format, + &roi_64x64); BufferPool_Return(progressive->bufferPool, pBuffer); return 1; } @@ -1106,12 +1100,12 @@ if (srlLen) pSrlLen = (int)((((float) aSrlLen) / ((float) srlLen)) * 100.0f); - WLog_INFO(TAG, - "RAW: %"PRIu32"/%"PRIu32" %d%% (%"PRIu32"/%"PRIu32":%"PRIu32")\tSRL: %"PRIu32"/%"PRIu32" %d%% (%"PRIu32"/%"PRIu32":%"PRIu32")", - aRawLen, rawLen, pRawLen, state.raw->position, rawLen * 8, - (rawLen * 8) - state.raw->position, - aSrlLen, srlLen, pSrlLen, state.srl->position, srlLen * 8, - (srlLen * 8) - state.srl->position); + WLog_Print(progressive->log, WLOG_INFO, + "RAW: %"PRIu32"/%"PRIu32" %d%% (%"PRIu32"/%"PRIu32":%"PRIu32")\tSRL: %"PRIu32"/%"PRIu32" %d%% (%"PRIu32"/%"PRIu32":%"PRIu32")", + aRawLen, rawLen, pRawLen, state.raw->position, rawLen * 8, + (rawLen * 8) - state.raw->position, + aSrlLen, srlLen, pSrlLen, state.srl->position, srlLen * 8, + (srlLen * 8) - state.srl->position); return -1; } @@ -1152,11 +1146,11 @@ static const prim_size_t roi_64x64 = { 64, 64 }; const primitives_t* prims = primitives_get(); tile->pass++; - WLog_DBG(TAG, - "ProgressiveTileUpgrade: pass: %"PRIu16" quantIdx Y: %"PRIu8" Cb: %"PRIu8" Cr: %"PRIu8" xIdx: %"PRIu16" yIdx: %"PRIu16" quality: %"PRIu8" ySrlLen: %"PRIu16" yRawLen: %"PRIu16" cbSrlLen: %"PRIu16" cbRawLen: %"PRIu16" crSrlLen: %"PRIu16" crRawLen: %"PRIu16"", - tile->pass, tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, - tile->yIdx, tile->quality, tile->ySrlLen, tile->yRawLen, tile->cbSrlLen, - tile->cbRawLen, tile->crSrlLen, tile->crRawLen); + WLog_Print(progressive->log, WLOG_DEBUG, + "ProgressiveTileUpgrade: pass: %"PRIu16" quantIdx Y: %"PRIu8" Cb: %"PRIu8" Cr: %"PRIu8" xIdx: %"PRIu16" yIdx: %"PRIu16" quality: %"PRIu8" ySrlLen: %"PRIu16" yRawLen: %"PRIu16" cbSrlLen: %"PRIu16" cbRawLen: %"PRIu16" crSrlLen: %"PRIu16" crRawLen: %"PRIu16"", + tile->pass, tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, + tile->yIdx, tile->quality, tile->ySrlLen, tile->yRawLen, tile->cbSrlLen, + tile->cbRawLen, tile->crSrlLen, tile->crRawLen); region = &(progressive->region); if (tile->quantIdxY >= region->numQuant) @@ -1191,13 +1185,13 @@ quantProgCr = &(quantProg->crQuantValues); if (!progressive_rfx_quant_cmp_equal(quantY, &(tile->yQuant))) - WLog_WARN(TAG, "non-progressive quantY has changed!"); + WLog_Print(progressive->log, WLOG_WARN, "non-progressive quantY has changed!"); if (!progressive_rfx_quant_cmp_equal(quantCb, &(tile->cbQuant))) - WLog_WARN(TAG, "non-progressive quantCb has changed!"); + WLog_Print(progressive->log, WLOG_WARN, "non-progressive quantCb has changed!"); if (!progressive_rfx_quant_cmp_equal(quantCr, &(tile->crQuant))) - WLog_WARN(TAG, "non-progressive quantCr has changed!"); + WLog_Print(progressive->log, WLOG_WARN, "non-progressive quantCr has changed!"); progressive_rfx_quant_add(quantY, quantProgY, &yBitPos); progressive_rfx_quant_add(quantCb, quantProgCb, &cbBitPos); @@ -1266,15 +1260,9 @@ if (status < 0) return -1; - if (!progressive->invert) - prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, - tile->data, PIXEL_FORMAT_BGRX32, - 64 * 4, &roi_64x64); - else - prims->yCbCrToBGR_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, - tile->data, PIXEL_FORMAT_BGRX32, - 64 * 4, &roi_64x64); - + prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, + tile->data, tile->stride, tile->format, + &roi_64x64); BufferPool_Return(progressive->bufferPool, pBuffer); return 1; } @@ -1307,8 +1295,7 @@ blockType = *((UINT16*) &block[boffset + 0]); /* blockType (2 bytes) */ blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */ boffset += 6; - - //WLog_DBG(TAG, "%s", progressive_get_block_type_string(blockType)); + WLog_Print(progressive->log, WLOG_DEBUG, "%s", progressive_get_block_type_string(blockType)); if ((blocksLen - offset) < blockLen) return -1003; @@ -1369,6 +1356,8 @@ tile->height = 64; tile->x = tile->xIdx * 64; tile->y = tile->yIdx * 64; + tile->format = progressive->format; + tile->stride = GetBytesPerPixel(tile->format) * tile->width; tile->flags &= 1; break; @@ -1426,6 +1415,8 @@ tile->height = 64; tile->x = tile->xIdx * 64; tile->y = tile->yIdx * 64; + tile->format = progressive->format; + tile->stride = GetBytesPerPixel(tile->format) * tile->width; break; case PROGRESSIVE_WBT_TILE_UPGRADE: @@ -1496,11 +1487,12 @@ tile->height = 64; tile->x = tile->xIdx * 64; tile->y = tile->yIdx * 64; + tile->format = progressive->format; + tile->stride = GetBytesPerPixel(tile->format) * tile->width; break; default: return -1039; - break; } if (boffset != blockLen) @@ -1515,8 +1507,9 @@ if (count != region->numTiles) { - WLog_WARN(TAG, "numTiles inconsistency: actual: %"PRIu32", expected: %"PRIu16"\n", count, - region->numTiles); + WLog_Print(progressive->log, WLOG_WARN, + "numTiles inconsistency: actual: %"PRIu32", expected: %"PRIu16"\n", count, + region->numTiles); } for (index = 0; index < region->numTiles; index++) @@ -1572,7 +1565,6 @@ REGION16 clippingRects, updateRegion; PROGRESSIVE_SURFACE_CONTEXT* surface; PROGRESSIVE_BLOCK_REGION* region; - progressive->invert = FREERDP_PIXEL_FORMAT_IS_ABGR(DstFormat) ? TRUE : FALSE; surface = (PROGRESSIVE_SURFACE_CONTEXT*) progressive_get_surface_data( progressive, surfaceId); @@ -1582,6 +1574,7 @@ blocks = pSrcData; blocksLen = SrcSize; region = &(progressive->region); + progressive->format = DstFormat; while ((blocksLen - offset) >= 6) { @@ -1603,7 +1596,7 @@ switch (blockType) { case PROGRESSIVE_WBT_SYNC: - WLog_DBG(TAG, "ProgressiveSync"); + WLog_Print(progressive->log, WLOG_DEBUG, "ProgressiveSync"); sync.blockType = blockType; sync.blockLen = blockLen; @@ -1635,8 +1628,9 @@ frameBegin.regionCount = (UINT32) * ((UINT16*) &block[boffset + 4]); /* regionCount (2 bytes) */ boffset += 6; - WLog_DBG(TAG, "ProgressiveFrameBegin: frameIndex: %"PRIu32" regionCount: %"PRIu16"", - frameBegin.frameIndex, frameBegin.regionCount); + WLog_Print(progressive->log, WLOG_DEBUG, + "ProgressiveFrameBegin: frameIndex: %"PRIu32" regionCount: %"PRIu16"", + frameBegin.frameIndex, frameBegin.regionCount); /** * If the number of elements specified by the regionCount field is * larger than the actual number of elements in the regions field, @@ -1645,7 +1639,7 @@ break; case PROGRESSIVE_WBT_FRAME_END: - WLog_DBG(TAG, "ProgressiveFrameEnd"); + WLog_Print(progressive->log, WLOG_DEBUG, "ProgressiveFrameEnd"); frameEnd.blockType = blockType; frameEnd.blockLen = blockLen; @@ -1669,12 +1663,10 @@ if (context.tileSize != 64) return -1010; - WLog_DBG(TAG, "ProgressiveContext: flags: 0x%02"PRIX8"", context.flags); + WLog_Print(progressive->log, WLOG_DEBUG, "ProgressiveContext: flags: 0x%02"PRIX8"", context.flags); if (!(context.flags & RFX_SUBBAND_DIFFING)) - { - WLog_WARN(TAG, "RFX_SUBBAND_DIFFING is not set"); - } + WLog_Print(progressive->log, WLOG_WARN, "RFX_SUBBAND_DIFFING is not set"); break; @@ -1802,15 +1794,13 @@ if (!region->tiles) return -1; - WLog_DBG(TAG, - "ProgressiveRegion: numRects: %"PRIu16" numTiles: %"PRIu16" tileDataSize: %"PRIu32" flags: 0x%02"PRIX8" numQuant: %"PRIu8" numProgQuant: %"PRIu8"", - region->numRects, region->numTiles, region->tileDataSize, region->flags, - region->numQuant, region->numProgQuant); + WLog_Print(progressive->log, WLOG_DEBUG, + "ProgressiveRegion: numRects: %"PRIu16" numTiles: %"PRIu16" tileDataSize: %"PRIu32" flags: 0x%02"PRIX8" numQuant: %"PRIu8" numProgQuant: %"PRIu8"", + region->numRects, region->numTiles, region->tileDataSize, region->flags, + region->numQuant, region->numProgQuant); if (!(region->flags & RFX_DWT_REDUCE_EXTRAPOLATE)) - { - WLog_WARN(TAG, "RFX_DWT_REDUCE_EXTRAPOLATE is not set"); - } + WLog_Print(progressive->log, WLOG_WARN, "RFX_DWT_REDUCE_EXTRAPOLATE is not set"); boxLeft = surface->gridWidth; boxTop = surface->gridHeight; @@ -1837,8 +1827,9 @@ if (idxBottom > boxBottom) boxBottom = idxBottom; - WLog_DBG(TAG, "rect[%"PRIu16"]: x: %"PRIu16" y: %"PRIu16" w: %"PRIu16" h: %"PRIu16"", - index, rect->x, rect->y, rect->width, rect->height); + WLog_Print(progressive->log, WLOG_DEBUG, + "rect[%"PRIu16"]: x: %"PRIu16" y: %"PRIu16" w: %"PRIu16" h: %"PRIu16"", + index, rect->x, rect->y, rect->width, rect->height); } status = progressive_process_tiles(progressive, &block[boffset], @@ -1921,9 +1912,9 @@ if (!freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, - width, height, - tile->data, PIXEL_FORMAT_BGRX32, - 64 * 4, nXSrc, nYSrc, NULL, FREERDP_FLIP_NONE)) + width, height, tile->data, tile->format, + tile->stride, + nXSrc, nYSrc, NULL, FREERDP_FLIP_NONE)) { rc = -42; break; @@ -1937,7 +1928,7 @@ return rc; } -int progressive_compress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, +int progressive_compress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize) { return 1; @@ -1992,15 +1983,12 @@ progressive->quantProgValFull.quality = 100; progressive->SurfaceContexts = HashTable_New(TRUE); progressive_context_reset(progressive); + progressive->log = WLog_Get(TAG); } return progressive; cleanup: - free(progressive->rects); - free(progressive->tiles); - free(progressive->quantVals); - free(progressive->quantProgVals); - free(progressive); + progressive_context_free(progressive); return NULL; } @@ -2019,17 +2007,22 @@ free(progressive->tiles); free(progressive->quantVals); free(progressive->quantProgVals); - count = HashTable_GetKeys(progressive->SurfaceContexts, &pKeys); - for (index = 0; index < count; index++) + if (progressive->SurfaceContexts) { - surface = (PROGRESSIVE_SURFACE_CONTEXT*) HashTable_GetItemValue( - progressive->SurfaceContexts, (void*) pKeys[index]); - progressive_surface_context_free(surface); + count = HashTable_GetKeys(progressive->SurfaceContexts, &pKeys); + + for (index = 0; index < count; index++) + { + surface = (PROGRESSIVE_SURFACE_CONTEXT*) HashTable_GetItemValue( + progressive->SurfaceContexts, (void*) pKeys[index]); + progressive_surface_context_free(surface); + } + + free(pKeys); + HashTable_Free(progressive->SurfaceContexts); } - free(pKeys); - HashTable_Free(progressive->SurfaceContexts); free(progressive); } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/progressive.h freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/progressive.h --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/progressive.h 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/progressive.h 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,233 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Progressive Codec Bitmap Compression + * + * Copyright 2017 Armin Novak + * Copyright 2017 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. + * 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 INTERNAL_CODEC_PROGRESSIVE_H +#define INTERNAL_CODEC_PROGRESSIVE_H + +#include +#include + +#include + +#define RFX_SUBBAND_DIFFING 0x01 + +#define RFX_TILE_DIFFERENCE 0x01 + +#define RFX_DWT_REDUCE_EXTRAPOLATE 0x01 + +#define PROGRESSIVE_WBT_SYNC 0xCCC0 +#define PROGRESSIVE_WBT_FRAME_BEGIN 0xCCC1 +#define PROGRESSIVE_WBT_FRAME_END 0xCCC2 +#define PROGRESSIVE_WBT_CONTEXT 0xCCC3 +#define PROGRESSIVE_WBT_REGION 0xCCC4 +#define PROGRESSIVE_WBT_TILE_SIMPLE 0xCCC5 +#define PROGRESSIVE_WBT_TILE_FIRST 0xCCC6 +#define PROGRESSIVE_WBT_TILE_UPGRADE 0xCCC7 + +struct _RFX_COMPONENT_CODEC_QUANT +{ + BYTE LL3; + BYTE HL3; + BYTE LH3; + BYTE HH3; + BYTE HL2; + BYTE LH2; + BYTE HH2; + BYTE HL1; + BYTE LH1; + BYTE HH1; +}; +typedef struct _RFX_COMPONENT_CODEC_QUANT RFX_COMPONENT_CODEC_QUANT; + +struct _RFX_PROGRESSIVE_CODEC_QUANT +{ + BYTE quality; + RFX_COMPONENT_CODEC_QUANT yQuantValues; + RFX_COMPONENT_CODEC_QUANT cbQuantValues; + RFX_COMPONENT_CODEC_QUANT crQuantValues; +}; +typedef struct _RFX_PROGRESSIVE_CODEC_QUANT RFX_PROGRESSIVE_CODEC_QUANT; + +struct _PROGRESSIVE_BLOCK +{ + UINT16 blockType; + UINT32 blockLen; +}; +typedef struct _PROGRESSIVE_BLOCK PROGRESSIVE_BLOCK; + +struct _PROGRESSIVE_BLOCK_SYNC +{ + UINT16 blockType; + UINT32 blockLen; + + UINT32 magic; + UINT16 version; +}; +typedef struct _PROGRESSIVE_BLOCK_SYNC PROGRESSIVE_BLOCK_SYNC; + +struct _PROGRESSIVE_BLOCK_CONTEXT +{ + UINT16 blockType; + UINT32 blockLen; + + BYTE ctxId; + UINT16 tileSize; + BYTE flags; +}; +typedef struct _PROGRESSIVE_BLOCK_CONTEXT PROGRESSIVE_BLOCK_CONTEXT; + +struct _RFX_PROGRESSIVE_TILE +{ + UINT16 blockType; + UINT32 blockLen; + + BYTE quantIdxY; + BYTE quantIdxCb; + BYTE quantIdxCr; + UINT16 xIdx; + UINT16 yIdx; + + BYTE flags; + BYTE quality; + + UINT16 yLen; + UINT16 cbLen; + UINT16 crLen; + UINT16 tailLen; + const BYTE* yData; + const BYTE* cbData; + const BYTE* crData; + const BYTE* tailData; + + UINT16 ySrlLen; + UINT16 yRawLen; + UINT16 cbSrlLen; + UINT16 cbRawLen; + UINT16 crSrlLen; + UINT16 crRawLen; + const BYTE* ySrlData; + const BYTE* yRawData; + const BYTE* cbSrlData; + const BYTE* cbRawData; + const BYTE* crSrlData; + const BYTE* crRawData; + + UINT32 x; + UINT32 y; + UINT32 width; + UINT32 height; + UINT32 format; + UINT32 stride; + + BYTE* data; + BYTE* current; + + UINT16 pass; + BYTE* sign; + RFX_COMPONENT_CODEC_QUANT yBitPos; + RFX_COMPONENT_CODEC_QUANT cbBitPos; + RFX_COMPONENT_CODEC_QUANT crBitPos; + RFX_COMPONENT_CODEC_QUANT yQuant; + RFX_COMPONENT_CODEC_QUANT cbQuant; + RFX_COMPONENT_CODEC_QUANT crQuant; + RFX_COMPONENT_CODEC_QUANT yProgQuant; + RFX_COMPONENT_CODEC_QUANT cbProgQuant; + RFX_COMPONENT_CODEC_QUANT crProgQuant; +}; +typedef struct _RFX_PROGRESSIVE_TILE RFX_PROGRESSIVE_TILE; + +struct _PROGRESSIVE_BLOCK_REGION +{ + UINT16 blockType; + UINT32 blockLen; + + BYTE tileSize; + UINT16 numRects; + BYTE numQuant; + BYTE numProgQuant; + BYTE flags; + UINT16 numTiles; + UINT32 tileDataSize; + RFX_RECT* rects; + RFX_COMPONENT_CODEC_QUANT* quantVals; + RFX_PROGRESSIVE_CODEC_QUANT* quantProgVals; + RFX_PROGRESSIVE_TILE** tiles; +}; +typedef struct _PROGRESSIVE_BLOCK_REGION PROGRESSIVE_BLOCK_REGION; + +struct _PROGRESSIVE_BLOCK_FRAME_BEGIN +{ + UINT16 blockType; + UINT32 blockLen; + + UINT32 frameIndex; + UINT16 regionCount; + PROGRESSIVE_BLOCK_REGION* regions; +}; +typedef struct _PROGRESSIVE_BLOCK_FRAME_BEGIN PROGRESSIVE_BLOCK_FRAME_BEGIN; + +struct _PROGRESSIVE_BLOCK_FRAME_END +{ + UINT16 blockType; + UINT32 blockLen; +}; +typedef struct _PROGRESSIVE_BLOCK_FRAME_END PROGRESSIVE_BLOCK_FRAME_END; + +struct _PROGRESSIVE_SURFACE_CONTEXT +{ + UINT16 id; + UINT32 width; + UINT32 height; + UINT32 gridWidth; + UINT32 gridHeight; + UINT32 gridSize; + RFX_PROGRESSIVE_TILE* tiles; +}; +typedef struct _PROGRESSIVE_SURFACE_CONTEXT PROGRESSIVE_SURFACE_CONTEXT; + +struct _PROGRESSIVE_CONTEXT +{ + BOOL Compressor; + + wBufferPool* bufferPool; + + UINT32 cRects; + RFX_RECT* rects; + + UINT32 format; + + UINT32 cTiles; + RFX_PROGRESSIVE_TILE** tiles; + + UINT32 cQuant; + RFX_COMPONENT_CODEC_QUANT* quantVals; + + UINT32 cProgQuant; + RFX_PROGRESSIVE_CODEC_QUANT* quantProgVals; + + PROGRESSIVE_BLOCK_REGION region; + RFX_PROGRESSIVE_CODEC_QUANT quantProgValFull; + + wHashTable* SurfaceContexts; + wLog* log; +}; + +#endif /* INTERNAL_CODEC_PROGRESSIVE_H */ + diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/rfx.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/rfx.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/rfx.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/rfx.c 2017-03-03 08:39:24.000000000 +0000 @@ -91,8 +91,6 @@ "rfx_quantization_decode"); PROFILER_CREATE(context->priv->prof_rfx_dwt_2d_decode, "rfx_dwt_2d_decode"); PROFILER_CREATE(context->priv->prof_rfx_ycbcr_to_rgb, "prims->yCbCrToRGB"); - PROFILER_CREATE(context->priv->prof_rfx_decode_format_rgb, - "rfx_decode_format_rgb"); PROFILER_CREATE(context->priv->prof_rfx_encode_rgb, "rfx_encode_rgb"); PROFILER_CREATE(context->priv->prof_rfx_encode_component, "rfx_encode_component"); @@ -116,7 +114,6 @@ PROFILER_FREE(context->priv->prof_rfx_quantization_decode); PROFILER_FREE(context->priv->prof_rfx_dwt_2d_decode); PROFILER_FREE(context->priv->prof_rfx_ycbcr_to_rgb); - PROFILER_FREE(context->priv->prof_rfx_decode_format_rgb); PROFILER_FREE(context->priv->prof_rfx_encode_rgb); PROFILER_FREE(context->priv->prof_rfx_encode_component); PROFILER_FREE(context->priv->prof_rfx_rlgr_encode); @@ -137,7 +134,6 @@ PROFILER_PRINT(context->priv->prof_rfx_quantization_decode); PROFILER_PRINT(context->priv->prof_rfx_dwt_2d_decode); PROFILER_PRINT(context->priv->prof_rfx_ycbcr_to_rgb); - PROFILER_PRINT(context->priv->prof_rfx_decode_format_rgb); PROFILER_PRINT(context->priv->prof_rfx_encode_rgb); PROFILER_PRINT(context->priv->prof_rfx_encode_component); PROFILER_PRINT(context->priv->prof_rfx_rlgr_encode); @@ -171,7 +167,7 @@ if (!(tile = (RFX_TILE*) calloc(1, sizeof(RFX_TILE)))) return NULL; - if (!(tile->data = (BYTE*) malloc(4 * 64 * 64))) + if (!(tile->data = (BYTE*) _aligned_malloc(4 * 64 * 64, 16))) { free(tile); return NULL; @@ -186,7 +182,7 @@ if (tile) { if (tile->allocated) - free(tile->data); + _aligned_free(tile->data); free(tile); } @@ -708,7 +704,8 @@ Stream_Read_UINT16(s, rect->y); /* y (2 bytes) */ Stream_Read_UINT16(s, rect->width); /* width (2 bytes) */ Stream_Read_UINT16(s, rect->height); /* height (2 bytes) */ - WLog_Print(context->priv->log, WLOG_DEBUG, "rect %d (x,y=%"PRIu16",%"PRIu16" w,h=%"PRIu16" %"PRIu16").", i, + WLog_Print(context->priv->log, WLOG_DEBUG, + "rect %d (x,y=%"PRIu16",%"PRIu16" w,h=%"PRIu16" %"PRIu16").", i, rect->x, rect->y, rect->width, rect->height); } @@ -1153,16 +1150,17 @@ REGION16 clippingRects; const RECTANGLE_16* updateRects; const DWORD formatSize = GetBytesPerPixel(context->pixel_format); + const UINT32 dstWidth = dstStride / formatSize; region16_init(&clippingRects); for (i = 0; i < message->numRects; i++) { RECTANGLE_16 clippingRect; const RFX_RECT* rect = &(message->rects[i]); - clippingRect.left = left + rect->x; - clippingRect.top = top + rect->y; - clippingRect.right = clippingRect.left + rect->width; - clippingRect.bottom = clippingRect.top + rect->height; + clippingRect.left = MIN(left + rect->x, dstWidth); + clippingRect.top = MIN(top + rect->y, dstHeight); + clippingRect.right = MIN(clippingRect.left + rect->width, dstWidth); + clippingRect.bottom = MIN(clippingRect.top + rect->height, dstHeight); region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } @@ -1180,13 +1178,13 @@ for (j = 0; j < nbUpdateRects; j++) { - UINT32 stride = 64 * formatSize; - UINT32 nXDst = updateRects[j].left; - UINT32 nYDst = updateRects[j].top; - UINT32 nXSrc = nXDst - updateRect.left; - UINT32 nYSrc = nYDst - updateRect.top; - UINT32 nWidth = MIN(64, updateRects[j].right - updateRects[j].left); - UINT32 nHeight = MIN(64, updateRects[j].bottom - updateRects[j].top); + const UINT32 stride = 64 * formatSize; + const UINT32 nXDst = updateRects[j].left; + const UINT32 nYDst = updateRects[j].top; + const UINT32 nXSrc = nXDst - updateRect.left; + const UINT32 nYSrc = nYDst - updateRect.top; + const UINT32 nWidth = updateRects[j].right - updateRects[j].left; + const UINT32 nHeight = updateRects[j].bottom - updateRects[j].top; if (!freerdp_image_copy(dst, dstFormat, dstStride, nXDst, nYDst, nWidth, nHeight, diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/rfx_decode.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/rfx_decode.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/rfx_decode.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/rfx_decode.c 2017-03-03 08:39:24.000000000 +0000 @@ -37,26 +37,6 @@ #include "rfx_decode.h" -/* stride is bytes between rows in the output buffer. */ -static void rfx_decode_format_rgb(const INT16* r_buf, const INT16* g_buf, - const INT16* b_buf, UINT32 pixel_format, - BYTE* dst_buf, UINT32 stride) -{ - primitives_t* prims = primitives_get(); - const INT16* r = r_buf; - const INT16* g = g_buf; - const INT16* b = b_buf; - const INT16* pSrc[3]; - static const prim_size_t roi_64x64 = { 64, 64 }; - BYTE* dst = dst_buf; - pSrc[0] = r; - pSrc[1] = g; - pSrc[2] = b; - prims->RGBToRGB_16s8u_P3AC4R( - (const INT16**) pSrc, 64 * sizeof(INT16), - dst, stride, pixel_format, &roi_64x64); -} - static void rfx_decode_component(RFX_CONTEXT* context, const UINT32* quantization_values, const BYTE* data, int size, INT16* buffer) @@ -86,6 +66,7 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer, int stride) { + BOOL rc = TRUE; BYTE* pBuffer; INT16* pSrcDst[3]; UINT32* y_quants, *cb_quants, *cr_quants; @@ -109,14 +90,13 @@ rfx_decode_component(context, cr_quants, tile->CrData, tile->CrLen, pSrcDst[2]); /* CrData */ PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb); - prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * sizeof(INT16), - pSrcDst, 64 * sizeof(INT16), &roi_64x64); + + if (prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**)pSrcDst, 64 * sizeof(INT16), + rgb_buffer, stride, context->pixel_format, &roi_64x64) != PRIMITIVES_SUCCESS) + rc = FALSE; + PROFILER_EXIT(context->priv->prof_rfx_ycbcr_to_rgb); - PROFILER_ENTER(context->priv->prof_rfx_decode_format_rgb); - rfx_decode_format_rgb(pSrcDst[0], pSrcDst[1], pSrcDst[2], - context->pixel_format, rgb_buffer, stride); - PROFILER_EXIT(context->priv->prof_rfx_decode_format_rgb); PROFILER_EXIT(context->priv->prof_rfx_decode_rgb); BufferPool_Return(context->priv->BufferPool, pBuffer); - return TRUE; + return rc; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/rfx_types.h freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/rfx_types.h --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/rfx_types.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/rfx_types.h 2017-03-03 08:39:24.000000000 +0000 @@ -17,8 +17,8 @@ * limitations under the License. */ -#ifndef __RFX_TYPES_H -#define __RFX_TYPES_H +#ifndef CODEC_RFX_TYPES_H +#define CODEC_RFX_TYPES_H #ifdef HAVE_CONFIG_H #include "config.h" @@ -66,7 +66,6 @@ PROFILER_DEFINE(prof_rfx_quantization_decode); PROFILER_DEFINE(prof_rfx_dwt_2d_decode); PROFILER_DEFINE(prof_rfx_ycbcr_to_rgb); - PROFILER_DEFINE(prof_rfx_decode_format_rgb); PROFILER_DEFINE(prof_rfx_encode_rgb); PROFILER_DEFINE(prof_rfx_encode_component); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c 2017-03-03 08:39:24.000000000 +0000 @@ -8,6 +8,8 @@ #include +#include "../progressive.h" + /** * Microsoft Progressive Codec Sample Data * (available under NDA only) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/activation.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/activation.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/activation.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/activation.c 2017-03-03 08:39:24.000000000 +0000 @@ -365,11 +365,13 @@ BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s) { rdpSettings *settings = rdp->settings; + freerdp_peer *peer = rdp->context->peer; if (!rdp_recv_client_font_list_pdu(s)) return FALSE; - if (settings->SupportMonitorLayoutPdu && settings->MonitorCount) + if (settings->SupportMonitorLayoutPdu && settings->MonitorCount && peer->AdjustMonitorsLayout && + peer->AdjustMonitorsLayout(peer)) { /* client supports the monitorLayout PDU, let's send him the monitors if any */ wStream *st; @@ -386,8 +388,6 @@ } r = rdp_send_data_pdu(rdp, st, DATA_PDU_TYPE_MONITOR_LAYOUT, 0); - Stream_Free(st, TRUE); - if (!r) return FALSE; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/bulk.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/bulk.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/bulk.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/bulk.c 2017-03-03 08:39:24.000000000 +0000 @@ -27,7 +27,7 @@ //#define WITH_BULK_DEBUG 1 -const char* bulk_get_compression_flags_string(UINT32 flags) +static INLINE const char* bulk_get_compression_flags_string(UINT32 flags) { flags &= BULK_COMPRESSION_FLAGS_MASK; @@ -55,7 +55,7 @@ { rdpSettings* settings = bulk->context->settings; bulk->CompressionLevel = (settings->CompressionLevel >= PACKET_COMPR_TYPE_RDP61) ? - PACKET_COMPR_TYPE_RDP61 : settings->CompressionLevel; + PACKET_COMPR_TYPE_RDP61 : settings->CompressionLevel; return bulk->CompressionLevel; } @@ -66,7 +66,8 @@ return bulk->CompressionMaxSize; } -int bulk_compress_validate(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags) +static INLINE int bulk_compress_validate(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, + BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags) { int status; BYTE* _pSrcData = NULL; @@ -87,7 +88,8 @@ if (_DstSize != SrcSize) { - WLog_DBG(TAG, "compression/decompression size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"", _DstSize, SrcSize); + WLog_DBG(TAG, "compression/decompression size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"", + _DstSize, SrcSize); return -1; } @@ -106,7 +108,8 @@ return status; } -int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags) +int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, + UINT32* pDstSize, UINT32 flags) { UINT32 type; int status = -1; @@ -159,11 +162,12 @@ CompressionRatio = metrics_write_bytes(metrics, UncompressedBytes, CompressedBytes); #ifdef WITH_BULK_DEBUG { - WLog_DBG(TAG, "Decompress Type: %"PRIu32" Flags: %s (0x%08"PRIX32") Compression Ratio: %f (%"PRIu32" / %"PRIu32"), Total: %f (%"PRIu64" / %"PRIu64")", - type, bulk_get_compression_flags_string(flags), flags, - CompressionRatio, CompressedBytes, UncompressedBytes, - metrics->TotalCompressionRatio, metrics->TotalCompressedBytes, - metrics->TotalUncompressedBytes); + WLog_DBG(TAG, + "Decompress Type: %"PRIu32" Flags: %s (0x%08"PRIX32") Compression Ratio: %f (%"PRIu32" / %"PRIu32"), Total: %f (%"PRIu64" / %"PRIu64")", + type, bulk_get_compression_flags_string(flags), flags, + CompressionRatio, CompressedBytes, UncompressedBytes, + metrics->TotalCompressionRatio, metrics->TotalCompressedBytes, + metrics->TotalUncompressedBytes); } #endif } @@ -175,7 +179,8 @@ return status; } -int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags) +int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, + UINT32* pFlags) { int status = -1; rdpMetrics* metrics; @@ -197,7 +202,7 @@ bulk_compression_max_size(bulk); if ((bulk->CompressionLevel == PACKET_COMPR_TYPE_8K) || - (bulk->CompressionLevel == PACKET_COMPR_TYPE_64K)) + (bulk->CompressionLevel == PACKET_COMPR_TYPE_64K)) { mppc_set_compression_level(bulk->mppcSend, bulk->CompressionLevel); status = mppc_compress(bulk->mppcSend, pSrcData, SrcSize, ppDstData, pDstSize, pFlags); @@ -222,11 +227,12 @@ CompressionRatio = metrics_write_bytes(metrics, UncompressedBytes, CompressedBytes); #ifdef WITH_BULK_DEBUG { - WLog_DBG(TAG, "Compress Type: %"PRIu32" Flags: %s (0x%08"PRIX32") Compression Ratio: %f (%"PRIu32" / %"PRIu32"), Total: %f (%"PRIu64" / %"PRIu64")", - bulk->CompressionLevel, bulk_get_compression_flags_string(*pFlags), *pFlags, - CompressionRatio, CompressedBytes, UncompressedBytes, - metrics->TotalCompressionRatio, metrics->TotalCompressedBytes, - metrics->TotalUncompressedBytes); + WLog_DBG(TAG, + "Compress Type: %"PRIu32" Flags: %s (0x%08"PRIX32") Compression Ratio: %f (%"PRIu32" / %"PRIu32"), Total: %f (%"PRIu64" / %"PRIu64")", + bulk->CompressionLevel, bulk_get_compression_flags_string(*pFlags), *pFlags, + CompressionRatio, CompressedBytes, UncompressedBytes, + metrics->TotalCompressionRatio, metrics->TotalCompressedBytes, + metrics->TotalUncompressedBytes); } #endif } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/capabilities.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/capabilities.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/capabilities.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/capabilities.c 2017-03-03 08:39:24.000000000 +0000 @@ -74,8 +74,9 @@ return CAPSET_TYPE_STRINGS[type]; } -static BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, - BOOL receiving); +#ifdef WITH_DEBUG_CAPABILITIES +static BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, BOOL receiving); +#endif /* CODEC_GUID_REMOTEFX: 0x76772F12BD724463AFB3B73C9C6F7886 */ @@ -192,10 +193,10 @@ Stream_Seek_UINT16(s); /* remoteUnshareFlag (2 bytes) */ Stream_Seek_UINT16(s); /* generalCompressionLevel (2 bytes) */ Stream_Read_UINT8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */ - Stream_Read_UINT8(s, - suppressOutputSupport); /* suppressOutputSupport (1 byte) */ - settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) ? - TRUE : FALSE; + Stream_Read_UINT8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */ + + settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) ? TRUE : FALSE; + settings->LongCredentialsSupported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) ? TRUE : FALSE; if (!(extraFlags & FASTPATH_OUTPUT_SUPPORTED)) settings->FastPathOutput = FALSE; @@ -236,7 +237,10 @@ return FALSE; header = rdp_capability_set_start(s); - extraFlags = LONG_CREDENTIALS_SUPPORTED; + extraFlags = 0; + + if (settings->LongCredentialsSupported) + extraFlags |= LONG_CREDENTIALS_SUPPORTED; if (settings->NoBitmapCompressionHeader) extraFlags |= NO_BITMAP_COMPRESSION_HDR; @@ -266,6 +270,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_general_capability_set(wStream* s, UINT16 length) { UINT16 osMajorType; @@ -288,17 +293,13 @@ Stream_Read_UINT16(s, osMinorType); /* osMinorType (2 bytes) */ Stream_Read_UINT16(s, protocolVersion); /* protocolVersion (2 bytes) */ Stream_Read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ - Stream_Read_UINT16(s, - generalCompressionTypes); /* generalCompressionTypes (2 bytes) */ + Stream_Read_UINT16(s, generalCompressionTypes); /* generalCompressionTypes (2 bytes) */ Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ - Stream_Read_UINT16(s, - updateCapabilityFlag); /* updateCapabilityFlag (2 bytes) */ + Stream_Read_UINT16(s, updateCapabilityFlag); /* updateCapabilityFlag (2 bytes) */ Stream_Read_UINT16(s, remoteUnshareFlag); /* remoteUnshareFlag (2 bytes) */ - Stream_Read_UINT16(s, - generalCompressionLevel); /* generalCompressionLevel (2 bytes) */ + Stream_Read_UINT16(s, generalCompressionLevel); /* generalCompressionLevel (2 bytes) */ Stream_Read_UINT8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */ - Stream_Read_UINT8(s, - suppressOutputSupport); /* suppressOutputSupport (1 byte) */ + Stream_Read_UINT8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */ WLog_INFO(TAG, "\tosMajorType: 0x%04"PRIX16"", osMajorType); WLog_INFO(TAG, "\tosMinorType: 0x%04"PRIX16"", osMinorType); WLog_INFO(TAG, "\tprotocolVersion: 0x%04"PRIX16"", protocolVersion); @@ -312,6 +313,7 @@ WLog_INFO(TAG, "\tsuppressOutputSupport: 0x%02"PRIX8"", suppressOutputSupport); return TRUE; } +#endif /** * Read bitmap capability set.\n @@ -333,8 +335,7 @@ if (length < 28) return FALSE; - Stream_Read_UINT16(s, - preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ + Stream_Read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ Stream_Seek_UINT16(s); /* receive1BitPerPixel (2 bytes) */ Stream_Seek_UINT16(s); /* receive4BitsPerPixel (2 bytes) */ Stream_Seek_UINT16(s); /* receive8BitsPerPixel (2 bytes) */ @@ -365,16 +366,13 @@ } if (settings->DrawAllowSkipAlpha) - settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) ? TRUE : - FALSE; + settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) ? TRUE : FALSE; if (settings->DrawAllowDynamicColorFidelity) - settings->DrawAllowDynamicColorFidelity = (drawingFlags & - DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) ? TRUE : FALSE; + settings->DrawAllowDynamicColorFidelity = (drawingFlags & DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) ? TRUE : FALSE; if (settings->DrawAllowColorSubsampling) - settings->DrawAllowColorSubsampling = (drawingFlags & - DRAW_ALLOW_COLOR_SUBSAMPLING) ? TRUE : FALSE; + settings->DrawAllowColorSubsampling = (drawingFlags & DRAW_ALLOW_COLOR_SUBSAMPLING) ? TRUE : FALSE; return TRUE; } @@ -420,16 +418,14 @@ else preferredBitsPerPixel = 8; - Stream_Write_UINT16(s, - preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ + Stream_Write_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ Stream_Write_UINT16(s, 1); /* receive1BitPerPixel (2 bytes) */ Stream_Write_UINT16(s, 1); /* receive4BitsPerPixel (2 bytes) */ Stream_Write_UINT16(s, 1); /* receive8BitsPerPixel (2 bytes) */ Stream_Write_UINT16(s, settings->DesktopWidth); /* desktopWidth (2 bytes) */ Stream_Write_UINT16(s, settings->DesktopHeight); /* desktopHeight (2 bytes) */ Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ - Stream_Write_UINT16(s, - settings->DesktopResize); /* desktopResizeFlag (2 bytes) */ + Stream_Write_UINT16(s, settings->DesktopResize); /* desktopResizeFlag (2 bytes) */ Stream_Write_UINT16(s, 1); /* bitmapCompressionFlag (2 bytes) */ Stream_Write_UINT8(s, 0); /* highColorFlags (1 byte) */ Stream_Write_UINT8(s, drawingFlags); /* drawingFlags (1 byte) */ @@ -439,6 +435,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_bitmap_capability_set(wStream* s, UINT16 length) { UINT16 preferredBitsPerPixel; @@ -459,23 +456,18 @@ if (length < 28) return FALSE; - Stream_Read_UINT16(s, - preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ + Stream_Read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ Stream_Read_UINT16(s, receive1BitPerPixel); /* receive1BitPerPixel (2 bytes) */ - Stream_Read_UINT16(s, - receive4BitsPerPixel); /* receive4BitsPerPixel (2 bytes) */ - Stream_Read_UINT16(s, - receive8BitsPerPixel); /* receive8BitsPerPixel (2 bytes) */ + Stream_Read_UINT16(s, receive4BitsPerPixel); /* receive4BitsPerPixel (2 bytes) */ + Stream_Read_UINT16(s, receive8BitsPerPixel); /* receive8BitsPerPixel (2 bytes) */ Stream_Read_UINT16(s, desktopWidth); /* desktopWidth (2 bytes) */ Stream_Read_UINT16(s, desktopHeight); /* desktopHeight (2 bytes) */ Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ Stream_Read_UINT16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ - Stream_Read_UINT16(s, - bitmapCompressionFlag); /* bitmapCompressionFlag (2 bytes) */ + Stream_Read_UINT16(s, bitmapCompressionFlag); /* bitmapCompressionFlag (2 bytes) */ Stream_Read_UINT8(s, highColorFlags); /* highColorFlags (1 byte) */ Stream_Read_UINT8(s, drawingFlags); /* drawingFlags (1 byte) */ - Stream_Read_UINT16(s, - multipleRectangleSupport); /* multipleRectangleSupport (2 bytes) */ + Stream_Read_UINT16(s, multipleRectangleSupport); /* multipleRectangleSupport (2 bytes) */ Stream_Read_UINT16(s, pad2OctetsB); /* pad2OctetsB (2 bytes) */ WLog_INFO(TAG, "\tpreferredBitsPerPixel: 0x%04"PRIX16"", preferredBitsPerPixel); WLog_INFO(TAG, "\treceive1BitPerPixel: 0x%04"PRIX16"", receive1BitPerPixel); @@ -492,6 +484,7 @@ WLog_INFO(TAG, "\tpad2OctetsB: 0x%04"PRIX16"", pad2OctetsB); return TRUE; } +#endif /** * Read order capability set.\n @@ -618,6 +611,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_order_capability_set(wStream* s, UINT16 length) { BYTE terminalDescriptor[16]; @@ -644,10 +638,8 @@ Stream_Read(s, terminalDescriptor, 16); /* terminalDescriptor (16 bytes) */ Stream_Read_UINT32(s, pad4OctetsA); /* pad4OctetsA (4 bytes) */ - Stream_Read_UINT16(s, - desktopSaveXGranularity); /* desktopSaveXGranularity (2 bytes) */ - Stream_Read_UINT16(s, - desktopSaveYGranularity); /* desktopSaveYGranularity (2 bytes) */ + Stream_Read_UINT16(s, desktopSaveXGranularity); /* desktopSaveXGranularity (2 bytes) */ + Stream_Read_UINT16(s, desktopSaveYGranularity); /* desktopSaveYGranularity (2 bytes) */ Stream_Read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ Stream_Read_UINT16(s, maximumOrderLevel); /* maximumOrderLevel (2 bytes) */ Stream_Read_UINT16(s, numberFonts); /* numberFonts (2 bytes) */ @@ -678,8 +670,7 @@ WLog_INFO(TAG, "\t\tAEXTTEXTOUT: %"PRIu8"", orderSupport[NEG_AEXTTEXTOUT_INDEX]); WLog_INFO(TAG, "\t\tDRAWNINEGRID: %"PRIu8"", orderSupport[NEG_DRAWNINEGRID_INDEX]); WLog_INFO(TAG, "\t\tLINETO: %"PRIu8"", orderSupport[NEG_LINETO_INDEX]); - WLog_INFO(TAG, "\t\tMULTI_DRAWNINEGRID: %"PRIu8"", - orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]); + WLog_INFO(TAG, "\t\tMULTI_DRAWNINEGRID: %"PRIu8"", orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]); WLog_INFO(TAG, "\t\tOPAQUE_RECT: %"PRIu8"", orderSupport[NEG_OPAQUE_RECT_INDEX]); WLog_INFO(TAG, "\t\tSAVEBITMAP: %"PRIu8"", orderSupport[NEG_SAVEBITMAP_INDEX]); WLog_INFO(TAG, "\t\tWTEXTOUT: %"PRIu8"", orderSupport[NEG_WTEXTOUT_INDEX]); @@ -688,8 +679,7 @@ WLog_INFO(TAG, "\t\tMULTIDSTBLT: %"PRIu8"", orderSupport[NEG_MULTIDSTBLT_INDEX]); WLog_INFO(TAG, "\t\tMULTIPATBLT: %"PRIu8"", orderSupport[NEG_MULTIPATBLT_INDEX]); WLog_INFO(TAG, "\t\tMULTISCRBLT: %"PRIu8"", orderSupport[NEG_MULTISCRBLT_INDEX]); - WLog_INFO(TAG, "\t\tMULTIOPAQUERECT: %"PRIu8"", - orderSupport[NEG_MULTIOPAQUERECT_INDEX]); + WLog_INFO(TAG, "\t\tMULTIOPAQUERECT: %"PRIu8"", orderSupport[NEG_MULTIOPAQUERECT_INDEX]); WLog_INFO(TAG, "\t\tFAST_INDEX: %"PRIu8"", orderSupport[NEG_FAST_INDEX_INDEX]); WLog_INFO(TAG, "\t\tPOLYGON_SC: %"PRIu8"", orderSupport[NEG_POLYGON_SC_INDEX]); WLog_INFO(TAG, "\t\tPOLYGON_CB: %"PRIu8"", orderSupport[NEG_POLYGON_CB_INDEX]); @@ -699,12 +689,9 @@ WLog_INFO(TAG, "\t\tELLIPSE_SC: %"PRIu8"", orderSupport[NEG_ELLIPSE_SC_INDEX]); WLog_INFO(TAG, "\t\tELLIPSE_CB: %"PRIu8"", orderSupport[NEG_ELLIPSE_CB_INDEX]); WLog_INFO(TAG, "\t\tGLYPH_INDEX: %"PRIu8"", orderSupport[NEG_GLYPH_INDEX_INDEX]); - WLog_INFO(TAG, "\t\tGLYPH_WEXTTEXTOUT: %"PRIu8"", - orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]); - WLog_INFO(TAG, "\t\tGLYPH_WLONGTEXTOUT: %"PRIu8"", - orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]); - WLog_INFO(TAG, "\t\tGLYPH_WLONGEXTTEXTOUT: %"PRIu8"", - orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]); + WLog_INFO(TAG, "\t\tGLYPH_WEXTTEXTOUT: %"PRIu8"", orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]); + WLog_INFO(TAG, "\t\tGLYPH_WLONGTEXTOUT: %"PRIu8"", orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]); + WLog_INFO(TAG, "\t\tGLYPH_WLONGEXTTEXTOUT: %"PRIu8"", orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]); WLog_INFO(TAG, "\t\tUNUSED31: %"PRIu8"", orderSupport[NEG_UNUSED31_INDEX]); WLog_INFO(TAG, "\ttextFlags: 0x%04"PRIX16"", textFlags); WLog_INFO(TAG, "\torderSupportExFlags: 0x%04"PRIX16"", orderSupportExFlags); @@ -716,6 +703,7 @@ WLog_INFO(TAG, "\tpad2OctetsE: 0x%04"PRIX16"", pad2OctetsE); return TRUE; } +#endif /** * Read bitmap cache capability set.\n @@ -784,6 +772,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_bitmap_cache_capability_set(wStream* s, UINT16 length) { UINT32 pad1, pad2, pad3; @@ -806,14 +795,11 @@ Stream_Read_UINT32(s, pad5); /* pad5 (4 bytes) */ Stream_Read_UINT32(s, pad6); /* pad6 (4 bytes) */ Stream_Read_UINT16(s, Cache0Entries); /* Cache0Entries (2 bytes) */ - Stream_Read_UINT16(s, - Cache0MaximumCellSize); /* Cache0MaximumCellSize (2 bytes) */ + Stream_Read_UINT16(s, Cache0MaximumCellSize); /* Cache0MaximumCellSize (2 bytes) */ Stream_Read_UINT16(s, Cache1Entries); /* Cache1Entries (2 bytes) */ - Stream_Read_UINT16(s, - Cache1MaximumCellSize); /* Cache1MaximumCellSize (2 bytes) */ + Stream_Read_UINT16(s, Cache1MaximumCellSize); /* Cache1MaximumCellSize (2 bytes) */ Stream_Read_UINT16(s, Cache2Entries); /* Cache2Entries (2 bytes) */ - Stream_Read_UINT16(s, - Cache2MaximumCellSize); /* Cache2MaximumCellSize (2 bytes) */ + Stream_Read_UINT16(s, Cache2MaximumCellSize); /* Cache2MaximumCellSize (2 bytes) */ WLog_INFO(TAG, "\tpad1: 0x%08"PRIX32"", pad1); WLog_INFO(TAG, "\tpad2: 0x%08"PRIX32"", pad2); WLog_INFO(TAG, "\tpad3: 0x%08"PRIX32"", pad3); @@ -828,6 +814,7 @@ WLog_INFO(TAG, "\tCache2MaximumCellSize: 0x%04"PRIX16"", Cache2MaximumCellSize); return TRUE; } +#endif /** * Read control capability set.\n @@ -873,6 +860,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_control_capability_set(wStream* s, UINT16 length) { UINT16 controlFlags; @@ -894,6 +882,7 @@ WLog_INFO(TAG, "\tdetachInterest: 0x%04"PRIX16"", detachInterest); return TRUE; } +#endif /** * Read window activation capability set.\n @@ -940,6 +929,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_window_activation_capability_set(wStream* s, UINT16 length) { @@ -955,14 +945,14 @@ Stream_Read_UINT16(s, helpKeyFlag); /* helpKeyFlag (2 bytes) */ Stream_Read_UINT16(s, helpKeyIndexFlag); /* helpKeyIndexFlag (2 bytes) */ Stream_Read_UINT16(s, helpExtendedKeyFlag); /* helpExtendedKeyFlag (2 bytes) */ - Stream_Read_UINT16(s, - windowManagerKeyFlag); /* windowManagerKeyFlag (2 bytes) */ + Stream_Read_UINT16(s, windowManagerKeyFlag); /* windowManagerKeyFlag (2 bytes) */ WLog_INFO(TAG, "\thelpKeyFlag: 0x%04"PRIX16"", helpKeyFlag); WLog_INFO(TAG, "\thelpKeyIndexFlag: 0x%04"PRIX16"", helpKeyIndexFlag); WLog_INFO(TAG, "\thelpExtendedKeyFlag: 0x%04"PRIX16"", helpExtendedKeyFlag); WLog_INFO(TAG, "\twindowManagerKeyFlag: 0x%04"PRIX16"", windowManagerKeyFlag); return TRUE; } +#endif /** * Read pointer capability set.\n @@ -1021,19 +1011,18 @@ header = rdp_capability_set_start(s); colorPointerFlag = (settings->ColorPointerFlag) ? 1 : 0; Stream_Write_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ - Stream_Write_UINT16(s, - settings->PointerCacheSize); /* colorPointerCacheSize (2 bytes) */ + Stream_Write_UINT16(s, settings->PointerCacheSize); /* colorPointerCacheSize (2 bytes) */ if (settings->LargePointerFlag) { - Stream_Write_UINT16(s, - settings->PointerCacheSize); /* pointerCacheSize (2 bytes) */ + Stream_Write_UINT16(s, settings->PointerCacheSize); /* pointerCacheSize (2 bytes) */ } rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_pointer_capability_set(wStream* s, UINT16 length) { UINT16 colorPointerFlag; @@ -1045,14 +1034,14 @@ WLog_INFO(TAG, "PointerCapabilitySet (length %"PRIu16"):", length); Stream_Read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ - Stream_Read_UINT16(s, - colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ + Stream_Read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ Stream_Read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ WLog_INFO(TAG, "\tcolorPointerFlag: 0x%04"PRIX16"", colorPointerFlag); WLog_INFO(TAG, "\tcolorPointerCacheSize: 0x%04"PRIX16"", colorPointerCacheSize); WLog_INFO(TAG, "\tpointerCacheSize: 0x%04"PRIX16"", pointerCacheSize); return TRUE; } +#endif /** * Read share capability set.\n @@ -1096,6 +1085,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_share_capability_set(wStream* s, UINT16 length) { UINT16 nodeId; @@ -1111,6 +1101,7 @@ WLog_INFO(TAG, "\tpad2Octets: 0x%04"PRIX16"", pad2Octets); return TRUE; } +#endif /** * Read color cache capability set.\n @@ -1153,6 +1144,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_color_cache_capability_set(wStream* s, UINT16 length) { UINT16 colorTableCacheSize; @@ -1168,6 +1160,7 @@ WLog_INFO(TAG, "\tpad2Octets: 0x%04"PRIX16"", pad2Octets); return TRUE; } +#endif /** * Read sound capability set.\n @@ -1214,6 +1207,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_sound_capability_set(wStream* s, UINT16 length) { UINT16 soundFlags; @@ -1229,6 +1223,7 @@ WLog_INFO(TAG, "\tpad2OctetsA: 0x%04"PRIX16"", pad2OctetsA); return TRUE; } +#endif /** * Read input capability set.\n @@ -1253,10 +1248,8 @@ { Stream_Read_UINT32(s, settings->KeyboardLayout); /* keyboardLayout (4 bytes) */ Stream_Read_UINT32(s, settings->KeyboardType); /* keyboardType (4 bytes) */ - Stream_Read_UINT32(s, - settings->KeyboardSubType); /* keyboardSubType (4 bytes) */ - Stream_Read_UINT32(s, - settings->KeyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ + Stream_Read_UINT32(s, settings->KeyboardSubType); /* keyboardSubType (4 bytes) */ + Stream_Read_UINT32(s, settings->KeyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ } else { @@ -1322,15 +1315,14 @@ Stream_Write_UINT16(s, 0); /* pad2OctetsA (2 bytes) */ Stream_Write_UINT32(s, settings->KeyboardLayout); /* keyboardLayout (4 bytes) */ Stream_Write_UINT32(s, settings->KeyboardType); /* keyboardType (4 bytes) */ - Stream_Write_UINT32(s, - settings->KeyboardSubType); /* keyboardSubType (4 bytes) */ - Stream_Write_UINT32(s, - settings->KeyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ + Stream_Write_UINT32(s, settings->KeyboardSubType); /* keyboardSubType (4 bytes) */ + Stream_Write_UINT32(s, settings->KeyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ Stream_Zero(s, 64); /* imeFileName (64 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_input_capability_set(wStream* s, UINT16 length) { UINT16 inputFlags; @@ -1359,6 +1351,7 @@ WLog_INFO(TAG, "\tkeyboardFunctionKey: 0x%08"PRIX32"", keyboardFunctionKey); return TRUE; } +#endif /** * Read font capability set.\n @@ -1401,6 +1394,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_font_capability_set(wStream* s, UINT16 length) { UINT16 fontSupportFlags = 0; @@ -1417,6 +1411,7 @@ WLog_INFO(TAG, "\tpad2Octets: 0x%04"PRIX16"", pad2Octets); return TRUE; } +#endif /** * Read brush capability set. @@ -1456,6 +1451,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_brush_capability_set(wStream* s, UINT16 length) { UINT32 brushSupportLevel; @@ -1468,6 +1464,7 @@ WLog_INFO(TAG, "\tbrushSupportLevel: 0x%08"PRIX32"", brushSupportLevel); return TRUE; } +#endif /** * Read cache definition (glyph).\n @@ -1477,10 +1474,8 @@ static void rdp_read_cache_definition(wStream* s, GLYPH_CACHE_DEFINITION* cache_definition) { - Stream_Read_UINT16(s, - cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ - Stream_Read_UINT16(s, - cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ + Stream_Read_UINT16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ + Stream_Read_UINT16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ } /** @@ -1491,10 +1486,8 @@ static void rdp_write_cache_definition(wStream* s, GLYPH_CACHE_DEFINITION* cache_definition) { - Stream_Write_UINT16(s, - cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ - Stream_Write_UINT16(s, - cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ + Stream_Write_UINT16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ + Stream_Write_UINT16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ } /** @@ -1512,29 +1505,18 @@ return FALSE; /* glyphCache (40 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[0])); /* glyphCache0 (4 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[1])); /* glyphCache1 (4 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[2])); /* glyphCache2 (4 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[3])); /* glyphCache3 (4 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[4])); /* glyphCache4 (4 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[5])); /* glyphCache5 (4 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[6])); /* glyphCache6 (4 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[7])); /* glyphCache7 (4 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[8])); /* glyphCache8 (4 bytes) */ - rdp_read_cache_definition(s, - &(settings->GlyphCache[9])); /* glyphCache9 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[0])); /* glyphCache0 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[1])); /* glyphCache1 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[2])); /* glyphCache2 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[3])); /* glyphCache3 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[4])); /* glyphCache4 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[5])); /* glyphCache5 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[6])); /* glyphCache6 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[7])); /* glyphCache7 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[8])); /* glyphCache8 (4 bytes) */ + rdp_read_cache_definition(s, &(settings->GlyphCache[9])); /* glyphCache9 (4 bytes) */ rdp_read_cache_definition(s, settings->FragCache); /* fragCache (4 bytes) */ - Stream_Read_UINT16(s, - settings->GlyphSupportLevel); /* glyphSupportLevel (2 bytes) */ + Stream_Read_UINT16(s, settings->GlyphSupportLevel); /* glyphSupportLevel (2 bytes) */ Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ return TRUE; } @@ -1556,34 +1538,24 @@ header = rdp_capability_set_start(s); /* glyphCache (40 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[0])); /* glyphCache0 (4 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[1])); /* glyphCache1 (4 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[2])); /* glyphCache2 (4 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[3])); /* glyphCache3 (4 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[4])); /* glyphCache4 (4 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[5])); /* glyphCache5 (4 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[6])); /* glyphCache6 (4 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[7])); /* glyphCache7 (4 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[8])); /* glyphCache8 (4 bytes) */ - rdp_write_cache_definition(s, - &(settings->GlyphCache[9])); /* glyphCache9 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[0])); /* glyphCache0 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[1])); /* glyphCache1 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[2])); /* glyphCache2 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[3])); /* glyphCache3 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[4])); /* glyphCache4 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[5])); /* glyphCache5 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[6])); /* glyphCache6 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[7])); /* glyphCache7 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[8])); /* glyphCache8 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->GlyphCache[9])); /* glyphCache9 (4 bytes) */ rdp_write_cache_definition(s, settings->FragCache); /* fragCache (4 bytes) */ - Stream_Write_UINT16(s, - settings->GlyphSupportLevel); /* glyphSupportLevel (2 bytes) */ + Stream_Write_UINT16(s, settings->GlyphSupportLevel); /* glyphSupportLevel (2 bytes) */ Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_glyph_cache_capability_set(wStream* s, UINT16 length) { GLYPH_CACHE_DEFINITION glyphCache[10]; @@ -1635,6 +1607,7 @@ WLog_INFO(TAG, "\tpad2Octets: 0x%04"PRIX16"", pad2Octets); return TRUE; } +#endif /** * Read offscreen bitmap cache capability set.\n @@ -1652,12 +1625,9 @@ if (length < 12) return FALSE; - Stream_Read_UINT32(s, - offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ - Stream_Read_UINT16(s, - settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ - Stream_Read_UINT16(s, - settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ + Stream_Read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ + Stream_Read_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ + Stream_Read_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ if (offscreenSupportLevel & TRUE) settings->OffscreenSupportLevel = TRUE; @@ -1686,16 +1656,14 @@ if (settings->OffscreenSupportLevel) offscreenSupportLevel = TRUE; - Stream_Write_UINT32(s, - offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ - Stream_Write_UINT16(s, - settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ - Stream_Write_UINT16(s, - settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ + Stream_Write_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ + Stream_Write_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ + Stream_Write_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_offscreen_bitmap_cache_capability_set(wStream* s, UINT16 length) { @@ -1707,16 +1675,15 @@ if (length < 12) return FALSE; - Stream_Read_UINT32(s, - offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ + Stream_Read_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ Stream_Read_UINT16(s, offscreenCacheSize); /* offscreenCacheSize (2 bytes) */ - Stream_Read_UINT16(s, - offscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ + Stream_Read_UINT16(s, offscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ WLog_INFO(TAG, "\toffscreenSupportLevel: 0x%08"PRIX32"", offscreenSupportLevel); WLog_INFO(TAG, "\toffscreenCacheSize: 0x%04"PRIX16"", offscreenCacheSize); WLog_INFO(TAG, "\toffscreenCacheEntries: 0x%04"PRIX16"", offscreenCacheEntries); return TRUE; } +#endif /** * Read bitmap cache host support capability set.\n @@ -1767,6 +1734,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_bitmap_cache_host_support_capability_set(wStream* s, UINT16 length) { @@ -1787,8 +1755,7 @@ return TRUE; } -static void rdp_read_bitmap_cache_cell_info(wStream* s, - BITMAP_CACHE_V2_CELL_INFO* cellInfo) +static void rdp_read_bitmap_cache_cell_info(wStream* s, BITMAP_CACHE_V2_CELL_INFO* cellInfo) { UINT32 info; /** @@ -1799,6 +1766,7 @@ cellInfo->numEntries = (info & 0x7FFFFFFF); cellInfo->persistent = (info & 0x80000000) ? 1 : 0; } +#endif static void rdp_write_bitmap_cache_cell_info(wStream* s, BITMAP_CACHE_V2_CELL_INFO* cellInfo) @@ -1864,21 +1832,17 @@ Stream_Write_UINT8(s, 0); /* pad2 (1 byte) */ Stream_Write_UINT8(s, settings->BitmapCacheV2NumCells); /* numCellCaches (1 byte) */ - rdp_write_bitmap_cache_cell_info(s, - &settings->BitmapCacheV2CellInfo[0]); /* bitmapCache0CellInfo (4 bytes) */ - rdp_write_bitmap_cache_cell_info(s, - &settings->BitmapCacheV2CellInfo[1]); /* bitmapCache1CellInfo (4 bytes) */ - rdp_write_bitmap_cache_cell_info(s, - &settings->BitmapCacheV2CellInfo[2]); /* bitmapCache2CellInfo (4 bytes) */ - rdp_write_bitmap_cache_cell_info(s, - &settings->BitmapCacheV2CellInfo[3]); /* bitmapCache3CellInfo (4 bytes) */ - rdp_write_bitmap_cache_cell_info(s, - &settings->BitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */ + rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[0]); /* bitmapCache0CellInfo (4 bytes) */ + rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[1]); /* bitmapCache1CellInfo (4 bytes) */ + rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[2]); /* bitmapCache2CellInfo (4 bytes) */ + rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[3]); /* bitmapCache3CellInfo (4 bytes) */ + rdp_write_bitmap_cache_cell_info(s, &settings->BitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */ Stream_Zero(s, 12); /* pad3 (12 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_bitmap_cache_v2_capability_set(wStream* s, UINT16 length) { UINT16 cacheFlags; @@ -1893,16 +1857,11 @@ Stream_Read_UINT16(s, cacheFlags); /* cacheFlags (2 bytes) */ Stream_Read_UINT8(s, pad2); /* pad2 (1 byte) */ Stream_Read_UINT8(s, numCellCaches); /* numCellCaches (1 byte) */ - rdp_read_bitmap_cache_cell_info(s, - &bitmapCacheV2CellInfo[0]); /* bitmapCache0CellInfo (4 bytes) */ - rdp_read_bitmap_cache_cell_info(s, - &bitmapCacheV2CellInfo[1]); /* bitmapCache1CellInfo (4 bytes) */ - rdp_read_bitmap_cache_cell_info(s, - &bitmapCacheV2CellInfo[2]); /* bitmapCache2CellInfo (4 bytes) */ - rdp_read_bitmap_cache_cell_info(s, - &bitmapCacheV2CellInfo[3]); /* bitmapCache3CellInfo (4 bytes) */ - rdp_read_bitmap_cache_cell_info(s, - &bitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */ + rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[0]); /* bitmapCache0CellInfo (4 bytes) */ + rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[1]); /* bitmapCache1CellInfo (4 bytes) */ + rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[2]); /* bitmapCache2CellInfo (4 bytes) */ + rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[3]); /* bitmapCache3CellInfo (4 bytes) */ + rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */ Stream_Seek(s, 12); /* pad3 (12 bytes) */ WLog_INFO(TAG, "\tcacheFlags: 0x%04"PRIX16"", cacheFlags); WLog_INFO(TAG, "\tpad2: 0x%02"PRIX8"", pad2); @@ -1919,6 +1878,7 @@ bitmapCacheV2CellInfo[4].numEntries, bitmapCacheV2CellInfo[4].persistent); return TRUE; } +#endif /** * Read virtual channel capability set.\n @@ -1975,6 +1935,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_virtual_channel_capability_set(wStream* s, UINT16 length) { UINT32 flags; @@ -1995,6 +1956,7 @@ WLog_INFO(TAG, "\tVCChunkSize: 0x%08"PRIX32"", VCChunkSize); return TRUE; } +#endif /** * Read drawn nine grid cache capability set.\n @@ -2012,12 +1974,9 @@ if (length < 12) return FALSE; - Stream_Read_UINT32(s, - drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ - Stream_Read_UINT16(s, - settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ - Stream_Read_UINT16(s, - settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ + Stream_Read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ + Stream_Read_UINT16(s, settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ + Stream_Read_UINT16(s, settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ if ((drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED) || (drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED_V2)) @@ -2045,12 +2004,9 @@ header = rdp_capability_set_start(s); drawNineGridSupportLevel = (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT; - Stream_Write_UINT32(s, - drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ - Stream_Write_UINT16(s, - settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ - Stream_Write_UINT16(s, - settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ + Stream_Write_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ + Stream_Write_UINT16(s, settings->DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ + Stream_Write_UINT16(s, settings->DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE); return TRUE; } @@ -2083,6 +2039,7 @@ Stream_Write_UINT16(s, oicms); /* gdipObjectImageCacheMaxSize (2 bytes) */ } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_draw_nine_grid_cache_capability_set(wStream* s, UINT16 length) { @@ -2094,14 +2051,12 @@ if (length < 12) return FALSE; - Stream_Read_UINT32(s, - drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ - Stream_Read_UINT16(s, - DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ - Stream_Read_UINT16(s, - DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ + Stream_Read_UINT32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ + Stream_Read_UINT16(s, DrawNineGridCacheSize); /* drawNineGridCacheSize (2 bytes) */ + Stream_Read_UINT16(s, DrawNineGridCacheEntries); /* drawNineGridCacheEntries (2 bytes) */ return TRUE; } +#endif /** * Read GDI+ cache capability set.\n @@ -2120,11 +2075,9 @@ if (length < 40) return FALSE; - Stream_Read_UINT32(s, - drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ + Stream_Read_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ Stream_Seek_UINT32(s); /* GdipVersion (4 bytes) */ - Stream_Read_UINT32(s, - drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ + Stream_Read_UINT32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ Stream_Seek(s, 10); /* GdipCacheEntries (10 bytes) */ Stream_Seek(s, 8); /* GdipCacheChunkSize (8 bytes) */ Stream_Seek(s, 6); /* GdipImageCacheProperties (6 bytes) */ @@ -2160,21 +2113,17 @@ DRAW_GDIPLUS_SUPPORTED : DRAW_GDIPLUS_DEFAULT; drawGdiplusCacheLevel = (settings->DrawGdiPlusEnabled) ? DRAW_GDIPLUS_CACHE_LEVEL_ONE : DRAW_GDIPLUS_CACHE_LEVEL_DEFAULT; - Stream_Write_UINT32(s, - drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ + Stream_Write_UINT32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ Stream_Write_UINT32(s, 0); /* GdipVersion (4 bytes) */ - Stream_Write_UINT32(s, - drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ - rdp_write_gdiplus_cache_entries(s, 10, 5, 5, 10, - 2); /* GdipCacheEntries (10 bytes) */ - rdp_write_gdiplus_cache_chunk_size(s, 512, 2048, 1024, - 64); /* GdipCacheChunkSize (8 bytes) */ - rdp_write_gdiplus_image_cache_properties(s, 4096, 256, - 128); /* GdipImageCacheProperties (6 bytes) */ + Stream_Write_UINT32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ + rdp_write_gdiplus_cache_entries(s, 10, 5, 5, 10, 2); /* GdipCacheEntries (10 bytes) */ + rdp_write_gdiplus_cache_chunk_size(s, 512, 2048, 1024, 64); /* GdipCacheChunkSize (8 bytes) */ + rdp_write_gdiplus_image_cache_properties(s, 4096, 256, 128); /* GdipImageCacheProperties (6 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_GDI_PLUS); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_draw_gdiplus_cache_capability_set(wStream* s, UINT16 length) { @@ -2186,16 +2135,15 @@ if (length < 40) return FALSE; - Stream_Read_UINT32(s, - drawGdiPlusSupportLevel); /* drawGdiPlusSupportLevel (4 bytes) */ + Stream_Read_UINT32(s, drawGdiPlusSupportLevel); /* drawGdiPlusSupportLevel (4 bytes) */ Stream_Read_UINT32(s, GdipVersion); /* GdipVersion (4 bytes) */ - Stream_Read_UINT32(s, - drawGdiplusCacheLevel); /* drawGdiPlusCacheLevel (4 bytes) */ + Stream_Read_UINT32(s, drawGdiplusCacheLevel); /* drawGdiPlusCacheLevel (4 bytes) */ Stream_Seek(s, 10); /* GdipCacheEntries (10 bytes) */ Stream_Seek(s, 8); /* GdipCacheChunkSize (8 bytes) */ Stream_Seek(s, 6); /* GdipImageCacheProperties (6 bytes) */ return TRUE; } +#endif /** * Read remote programs capability set.\n @@ -2254,6 +2202,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_remote_programs_capability_set(wStream* s, UINT16 length) { UINT32 railSupportLevel; @@ -2266,6 +2215,7 @@ WLog_INFO(TAG, "\trailSupportLevel: 0x%08"PRIX32"", railSupportLevel); return TRUE; } +#endif /** * Read window list capability set.\n @@ -2306,14 +2256,13 @@ header = rdp_capability_set_start(s); wndSupportLevel = WINDOW_LEVEL_SUPPORTED_EX; Stream_Write_UINT32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */ - Stream_Write_UINT8(s, - settings->RemoteAppNumIconCaches); /* numIconCaches (1 byte) */ - Stream_Write_UINT16(s, - settings->RemoteAppNumIconCacheEntries); /* numIconCacheEntries (2 bytes) */ + Stream_Write_UINT8(s, settings->RemoteAppNumIconCaches); /* numIconCaches (1 byte) */ + Stream_Write_UINT16(s, settings->RemoteAppNumIconCacheEntries); /* numIconCacheEntries (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_window_list_capability_set(wStream* s, UINT16 length) { UINT32 wndSupportLevel; @@ -2332,6 +2281,7 @@ WLog_INFO(TAG, "\tnumIconCacheEntries: 0x%04"PRIX16"", numIconCacheEntries); return TRUE; } +#endif /** * Read desktop composition capability set.\n @@ -2370,12 +2320,12 @@ header = rdp_capability_set_start(s); compDeskSupportLevel = (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED; - Stream_Write_UINT16(s, - compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ + Stream_Write_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_desktop_composition_capability_set(wStream* s, UINT16 length) { @@ -2385,11 +2335,11 @@ if (length < 6) return FALSE; - Stream_Read_UINT16(s, - compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ + Stream_Read_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ WLog_INFO(TAG, "\tcompDeskSupportLevel: 0x%04"PRIX16"", compDeskSupportLevel); return TRUE; } +#endif /** * Read multifragment update capability set.\n @@ -2498,12 +2448,12 @@ } header = rdp_capability_set_start(s); - Stream_Write_UINT32(s, - settings->MultifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ + Stream_Write_UINT32(s, settings->MultifragMaxRequestSize); /* MaxRequestSize (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_multifragment_update_capability_set(wStream* s, UINT16 length) { @@ -2517,6 +2467,7 @@ WLog_INFO(TAG, "\tmaxRequestSize: 0x%08"PRIX32"", maxRequestSize); return TRUE; } +#endif /** * Read large pointer capability set.\n @@ -2534,8 +2485,7 @@ if (length < 6) return FALSE; - Stream_Read_UINT16(s, - largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ + Stream_Read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ settings->LargePointerFlag = (largePointerSupportFlags & LARGE_POINTER_FLAG_96x96) ? 1 : 0; return TRUE; @@ -2548,8 +2498,7 @@ * @param settings settings */ -static BOOL rdp_write_large_pointer_capability_set(wStream* s, - rdpSettings* settings) +static BOOL rdp_write_large_pointer_capability_set(wStream* s, rdpSettings* settings) { int header; UINT16 largePointerSupportFlags; @@ -2558,14 +2507,13 @@ return FALSE; header = rdp_capability_set_start(s); - largePointerSupportFlags = (settings->LargePointerFlag) ? - LARGE_POINTER_FLAG_96x96 : 0; - Stream_Write_UINT16(s, - largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ + largePointerSupportFlags = (settings->LargePointerFlag) ? LARGE_POINTER_FLAG_96x96 : 0; + Stream_Write_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER); return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_large_pointer_capability_set(wStream* s, UINT16 length) { UINT16 largePointerSupportFlags; @@ -2574,11 +2522,11 @@ if (length < 6) return FALSE; - Stream_Read_UINT16(s, - largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ + Stream_Read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ WLog_INFO(TAG, "\tlargePointerSupportFlags: 0x%04"PRIX16"", largePointerSupportFlags); return TRUE; } +#endif /** * Read surface commands capability set.\n @@ -2632,6 +2580,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_surface_commands_capability_set(wStream* s, UINT16 length) { UINT32 cmdFlags; @@ -2648,6 +2597,7 @@ return TRUE; } + static void rdp_print_bitmap_codec_guid(const GUID* guid) { WLog_INFO(TAG, "%08"PRIX32"%04"PRIX16"%04"PRIX16"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"", @@ -2656,6 +2606,7 @@ guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); } + static char* rdp_get_bitmap_codec_guid_name(const GUID* guid) { RPC_STATUS rpc_status; @@ -2673,7 +2624,7 @@ return "CODEC_GUID_UNKNOWN"; } - +#endif static void rdp_read_bitmap_codec_guid(wStream* s, GUID* guid) { @@ -2748,8 +2699,7 @@ rdp_read_bitmap_codec_guid(s, &codecGuid); /* codecGuid (16 bytes) */ Stream_Read_UINT8(s, codecId); /* codecId (1 byte) */ - Stream_Read_UINT16(s, - codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ + Stream_Read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ remainingLength -= 19; if (remainingLength < codecPropertiesLength) @@ -2868,8 +2818,7 @@ BYTE fAllowDynamicFidelity; guidNSCodec = TRUE; settings->NSCodecId = codecId; - Stream_Read_UINT8(s, - fAllowDynamicFidelity); /* fAllowDynamicFidelity (1 byte) */ + Stream_Read_UINT8(s, fAllowDynamicFidelity); /* fAllowDynamicFidelity (1 byte) */ Stream_Read_UINT8(s, fAllowSubsampling); /* fAllowSubsampling (1 byte) */ Stream_Read_UINT8(s, colorLossLevel); /* colorLossLevel (1 byte) */ @@ -2915,8 +2864,7 @@ { /* only enable a codec if we've announced/enabled it before */ settings->RemoteFxCodec = settings->RemoteFxCodec && guidRemoteFx; - settings->RemoteFxImageCodec = settings->RemoteFxImageCodec - && guidRemoteFxImage; + settings->RemoteFxImageCodec = settings->RemoteFxImageCodec && guidRemoteFxImage; settings->NSCodec = settings->NSCodec && guidNSCodec; settings->JpegCodec = FALSE; } @@ -3177,6 +3125,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) { GUID codecGuid; @@ -3219,6 +3168,7 @@ return TRUE; } +#endif /** * Read frame acknowledge capability set.\n @@ -3265,6 +3215,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_frame_acknowledge_capability_set(wStream* s, UINT16 length) { @@ -3278,6 +3229,7 @@ WLog_INFO(TAG, "\tframeAcknowledge: 0x%08"PRIX32"", frameAcknowledge); return TRUE; } +#endif static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wStream* s, UINT16 length, rdpSettings* settings) @@ -3305,6 +3257,7 @@ return TRUE; } +#ifdef WITH_DEBUG_CAPABILITIES static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wStream* s, UINT16 length) { @@ -3532,6 +3485,7 @@ return TRUE; } +#endif static BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCapabilities) @@ -3835,7 +3789,7 @@ if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId)) { - WLog_ERR(TAG, "unexpected MCS channel id %04"PRIx16" received", *pChannelId); + WLog_ERR(TAG, "unexpected MCS channel id %04"PRIx16" received", *pChannelId); return FALSE; } } @@ -3892,10 +3846,8 @@ return FALSE; Stream_Read_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */ - Stream_Read_UINT16(s, - lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ - Stream_Read_UINT16(s, - lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + Stream_Read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ if (!Stream_SafeSeek(s, lengthSourceDescriptor) || Stream_GetRemainingLength(s) < 4) /* sourceDescriptor */ @@ -4009,10 +3961,8 @@ Stream_Seek_UINT32(s); /* shareId (4 bytes) */ Stream_Seek_UINT16(s); /* originatorId (2 bytes) */ - Stream_Read_UINT16(s, - lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ - Stream_Read_UINT16(s, - lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + Stream_Read_UINT16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + Stream_Read_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ if (((int) Stream_GetRemainingLength(s)) < lengthSourceDescriptor + 4) return FALSE; @@ -4078,8 +4028,7 @@ lengthSourceDescriptor);/* lengthSourceDescriptor (2 bytes) */ lm = Stream_GetPosition(s); Stream_Seek_UINT16(s); /* lengthCombinedCapabilities (2 bytes) */ - Stream_Write(s, SOURCE_DESCRIPTOR, - lengthSourceDescriptor); /* sourceDescriptor */ + Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor); /* sourceDescriptor */ bm = Stream_GetPosition(s); Stream_Seek_UINT16(s); /* numberCapabilities (2 bytes) */ Stream_Write_UINT16(s, 0); /* pad2Octets (2 bytes) */ @@ -4199,8 +4148,7 @@ em = Stream_GetPosition(s); Stream_SetPosition(s, lm); /* go back to lengthCombinedCapabilities */ lengthCombinedCapabilities = (em - bm); - Stream_Write_UINT16(s, - lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + Stream_Write_UINT16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ Stream_SetPosition(s, bm); /* go back to numberCapabilities */ Stream_Write_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ #ifdef WITH_DEBUG_CAPABILITIES diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/client.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/client.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/client.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/client.c 2017-03-03 08:39:24.000000000 +0000 @@ -34,7 +34,8 @@ static WINPR_TLS void* g_pInterface = NULL; static WINPR_TLS rdpChannels* g_channels = NULL; /* use only for VirtualChannelInit hack */ -static volatile LONG g_OpenHandleSeq = 1; /* use global counter to ensure uniqueness across channel manager instances */ +static volatile LONG g_OpenHandleSeq = + 1; /* use global counter to ensure uniqueness across channel manager instances */ static WINPR_TLS rdpChannelHandles g_ChannelHandles = { NULL, NULL }; static CHANNEL_OPEN_DATA* freerdp_channels_find_channel_open_data_by_name( @@ -105,9 +106,6 @@ void freerdp_channels_free(rdpChannels* channels) { - int index; - CHANNEL_OPEN_DATA* pChannelOpenData; - if (!channels) return; @@ -119,23 +117,6 @@ channels->queue = NULL; } - for (index = 0; index < channels->clientDataCount; index++) - { - pChannelOpenData = &channels->openDataList[index]; - - if (pChannelOpenData->pInterface) - { - free(pChannelOpenData->pInterface); - pChannelOpenData->pInterface = NULL; - } - - freerdp_channel_remove_open_handle_data(&g_ChannelHandles, pChannelOpenData->OpenHandle); - - if (channels->openHandles) - HashTable_Remove(channels->openHandles, - (void*)(UINT_PTR)pChannelOpenData->OpenHandle); - } - if (channels->openHandles) HashTable_Free(channels->openHandles); @@ -253,7 +234,6 @@ rdpChannels* channels; CHANNEL_CLIENT_DATA* pChannelClientData; channels = instance->context->channels; - channels->connected = 1; hostname = instance->settings->ServerHostname; hostnameLength = (int) strlen(hostname); @@ -311,7 +291,6 @@ rdpChannels* channels; CHANNEL_CLIENT_DATA* pChannelClientData; channels = instance->context->channels; - channels->connected = 1; hostname = instance->settings->ServerHostname; hostnameLength = (int) strlen(hostname); @@ -372,7 +351,7 @@ char* hostname; int hostnameLength; CHANNEL_CLIENT_DATA* pChannelClientData; - channels->connected = 1; + channels->connected = TRUE; hostname = instance->settings->ServerHostname; hostnameLength = (int) strlen(hostname); @@ -611,19 +590,18 @@ { UINT error = CHANNEL_RC_OK; int index; - char* name; CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_CLIENT_DATA* pChannelClientData; if (!channels->connected) return 0; - channels->connected = 0; freerdp_channels_check_fds(channels, instance); /* tell all libraries we are shutting down */ for (index = 0; index < channels->clientDataCount; index++) { + char name[9]; ChannelDisconnectedEventArgs e; pChannelClientData = &channels->clientDataList[index]; @@ -639,30 +617,25 @@ } if (getChannelError(instance->context) != CHANNEL_RC_OK) - goto fail; + continue; pChannelOpenData = &channels->openDataList[index]; - name = (char*) malloc(9); - - if (!name) - return -1; - CopyMemory(name, pChannelOpenData->name, 8); name[8] = '\0'; EventArgsInit(&e, "freerdp"); e.name = name; e.pInterface = pChannelOpenData->pInterface; PubSub_OnChannelDisconnected(instance->context->pubSub, instance->context, &e); - free(name); } -fail: + channels->connected = FALSE; return error; } void freerdp_channels_close(rdpChannels* channels, freerdp* instance) { int index; + CHANNEL_OPEN_DATA* pChannelOpenData; CHANNEL_CLIENT_DATA* pChannelClientData; freerdp_channels_check_fds(channels, instance); @@ -683,7 +656,29 @@ } } + channels->clientDataCount = 0; MessageQueue_PostQuit(channels->queue, 0); + + for (index = 0; index < channels->openDataCount; index++) + { + pChannelOpenData = &channels->openDataList[index]; + + if (pChannelOpenData->pInterface) + { + free(pChannelOpenData->pInterface); + pChannelOpenData->pInterface = NULL; + } + + freerdp_channel_remove_open_handle_data(&g_ChannelHandles, pChannelOpenData->OpenHandle); + + if (channels->openHandles) + HashTable_Remove(channels->openHandles, + (void*)(UINT_PTR)pChannelOpenData->OpenHandle); + } + + channels->openDataCount = 0; + channels->initDataCount = 0; + instance->settings->ChannelCount = 0; } static UINT VCAPITYPE FreeRDP_VirtualChannelInitEx(LPVOID lpUserParam, LPVOID clientContext, @@ -837,7 +832,8 @@ pChannelOpenData = &channels->openDataList[channels->openDataCount]; pChannelOpenData->OpenHandle = InterlockedIncrement(&g_OpenHandleSeq); pChannelOpenData->channels = channels; - freerdp_channel_add_open_handle_data(&g_ChannelHandles, pChannelOpenData->OpenHandle, (void*) channels); + freerdp_channel_add_open_handle_data(&g_ChannelHandles, pChannelOpenData->OpenHandle, + (void*) channels); HashTable_Add(channels->openHandles, (void*)(UINT_PTR) pChannelOpenData->OpenHandle, (void*) pChannelOpenData); pChannelOpenData->flags = 1; /* init */ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -21,6 +21,7 @@ freerdp_definition_add(-DEXT_PATH="${FREERDP_EXTENSION_PATH}") freerdp_include_directory_add(${OPENSSL_INCLUDE_DIR}) +freerdp_include_directory_add(${KRB5_INCLUDE_DIRS}) set(${MODULE_PREFIX}_GATEWAY_DIR "gateway") @@ -140,6 +141,10 @@ freerdp_library_add(${OPENSSL_LIBRARIES}) +if (WITH_KRB5) + freerdp_library_add(${KRB5_LIBRARIES}) +endif(WITH_KRB5) + if(BUILD_TESTING) add_subdirectory(test) endif() diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/connection.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/connection.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/connection.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/connection.c 2017-03-03 08:39:24.000000000 +0000 @@ -178,17 +178,6 @@ BOOL status; rdpSettings* settings = rdp->settings; - if (rdp->settingsCopy) - { - freerdp_settings_free(rdp->settingsCopy); - rdp->settingsCopy = NULL; - } - - rdp->settingsCopy = freerdp_settings_clone(settings); - - if (!rdp->settingsCopy) - return FALSE; - nego_init(rdp->nego); nego_set_target(rdp->nego, settings->ServerHostname, settings->ServerPort); @@ -313,12 +302,6 @@ { BOOL status; - if (rdp->settingsCopy) - { - freerdp_settings_free(rdp->settingsCopy); - rdp->settingsCopy = NULL; - } - status = nego_disconnect(rdp->nego); rdp_reset(rdp); @@ -1162,12 +1145,17 @@ BOOL rdp_server_accept_confirm_active(rdpRdp* rdp, wStream* s) { + freerdp_peer *peer = rdp->context->peer; + if (rdp->state != CONNECTION_STATE_CAPABILITIES_EXCHANGE) return FALSE; if (!rdp_recv_confirm_active(rdp, s)) return FALSE; + if (peer->ClientCapabilities && !peer->ClientCapabilities(peer)) + return FALSE; + if (rdp->settings->SaltedChecksum) rdp->do_secure_checksum = TRUE; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/errconnect.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/errconnect.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/errconnect.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/errconnect.c 2017-03-03 08:39:24.000000000 +0000 @@ -35,43 +35,55 @@ /* Protocol-independent codes */ #define ERRCONNECT_PRE_CONNECT_FAILED_STRING \ - "A configuration error prevented a connection to be established." + "A configuration error prevented a connection to be established." #define ERRCONNECT_CONNECT_UNDEFINED_STRING \ - "A undefined connection error occurred." + "A undefined connection error occurred." #define ERRCONNECT_POST_CONNECT_FAILED_STRING \ - "The connection attempt was aborted due to post connect configuration errors." + "The connection attempt was aborted due to post connect configuration errors." #define ERRCONNECT_DNS_ERROR_STRING \ - "The DNS entry could not be resolved." + "The DNS entry could not be resolved." #define ERRCONNECT_DNS_NAME_NOT_FOUND_STRING \ - "The DNS host name was not found." + "The DNS host name was not found." #define ERRCONNECT_CONNECT_FAILED_STRING \ - "The connection failed." + "The connection failed." #define ERRCONNECT_MCS_CONNECT_INITIAL_ERROR_STRING \ - "The connection failed at initial MCS connect" + "The connection failed at initial MCS connect" #define ERRCONNECT_TLS_CONNECT_FAILED_STRING \ - "The connection failed at TLS connect." + "The connection failed at TLS connect." #define ERRCONNECT_AUTHENTICATION_FAILED_STRING \ - "An authentication failure aborted the connection." + "An authentication failure aborted the connection." #define ERRCONNECT_INSUFFICIENT_PRIVILEGES_STRING \ - "Insufficient privileges to establish a connection." + "Insufficient privileges to establish a connection." #define ERRCONNECT_CONNECT_CANCELLED_STRING \ - "The connection was cancelled." + "The connection was cancelled." #define ERRCONNECT_SECURITY_NEGO_CONNECT_FAILED_STRING \ - "The connection failed at negotiating security settings." + "The connection failed at negotiating security settings." #define ERRCONNECT_CONNECT_TRANSPORT_FAILED_STRING \ - "The connection transport layer failed." + "The connection transport layer failed." + +#define ERRCONNECT_PASSWORD_EXPIRED_STRING \ + "The password has expired and must be changed." + +#define ERRCONNECT_PASSWORD_CERTAINLY_EXPIRED_STRING \ + "The password has certainly expired and must be changed." + +#define ERRCONNECT_CLIENT_REVOKED_STRING \ + "The client has been revoked." + +#define ERRCONNECT_KDC_UNREACHABLE_STRING \ + "The KDC is unreachable." /* Special codes */ #define ERRCONNECT_SUCCESS_STRING "Success." @@ -79,29 +91,32 @@ static const ERRINFO ERRCONNECT_CODES[] = { - ERRCONNECT_DEFINE(SUCCESS), + ERRCONNECT_DEFINE(SUCCESS), - ERRCONNECT_DEFINE(PRE_CONNECT_FAILED), - ERRCONNECT_DEFINE(CONNECT_UNDEFINED), - ERRCONNECT_DEFINE(POST_CONNECT_FAILED), - ERRCONNECT_DEFINE(DNS_ERROR), - ERRCONNECT_DEFINE(DNS_NAME_NOT_FOUND), - ERRCONNECT_DEFINE(CONNECT_FAILED), - ERRCONNECT_DEFINE(MCS_CONNECT_INITIAL_ERROR), - ERRCONNECT_DEFINE(TLS_CONNECT_FAILED), - ERRCONNECT_DEFINE(AUTHENTICATION_FAILED), - ERRCONNECT_DEFINE(INSUFFICIENT_PRIVILEGES), - ERRCONNECT_DEFINE(CONNECT_CANCELLED), - ERRCONNECT_DEFINE(SECURITY_NEGO_CONNECT_FAILED), - ERRCONNECT_DEFINE(CONNECT_TRANSPORT_FAILED), + ERRCONNECT_DEFINE(PRE_CONNECT_FAILED), + ERRCONNECT_DEFINE(CONNECT_UNDEFINED), + ERRCONNECT_DEFINE(POST_CONNECT_FAILED), + ERRCONNECT_DEFINE(DNS_ERROR), + ERRCONNECT_DEFINE(DNS_NAME_NOT_FOUND), + ERRCONNECT_DEFINE(CONNECT_FAILED), + ERRCONNECT_DEFINE(MCS_CONNECT_INITIAL_ERROR), + ERRCONNECT_DEFINE(TLS_CONNECT_FAILED), + ERRCONNECT_DEFINE(AUTHENTICATION_FAILED), + ERRCONNECT_DEFINE(INSUFFICIENT_PRIVILEGES), + ERRCONNECT_DEFINE(CONNECT_CANCELLED), + ERRCONNECT_DEFINE(SECURITY_NEGO_CONNECT_FAILED), + ERRCONNECT_DEFINE(CONNECT_TRANSPORT_FAILED), + ERRCONNECT_DEFINE(PASSWORD_EXPIRED), + ERRCONNECT_DEFINE(PASSWORD_CERTAINLY_EXPIRED), + ERRCONNECT_DEFINE(CLIENT_REVOKED), + ERRCONNECT_DEFINE(KDC_UNREACHABLE), - ERRCONNECT_DEFINE(NONE) + ERRCONNECT_DEFINE(NONE) }; const char* freerdp_get_error_connect_string(UINT32 code) { const ERRINFO* errInfo; - errInfo = &ERRCONNECT_CODES[0]; while (errInfo->code != ERRCONNECT_NONE) @@ -120,7 +135,6 @@ const char* freerdp_get_error_connect_name(UINT32 code) { const ERRINFO* errInfo; - errInfo = &ERRCONNECT_CODES[0]; while (errInfo->code != ERRCONNECT_NONE) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/freerdp.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/freerdp.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/freerdp.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/freerdp.c 2017-03-03 08:39:24.000000000 +0000 @@ -867,6 +867,54 @@ } } +const char* freerdp_get_logon_error_info_type(UINT32 type) +{ + switch (type) + { + case LOGON_MSG_DISCONNECT_REFUSED: + return "LOGON_MSG_DISCONNECT_REFUSED"; + + case LOGON_MSG_NO_PERMISSION: + return "LOGON_MSG_NO_PERMISSION"; + + case LOGON_MSG_BUMP_OPTIONS: + return "LOGON_MSG_BUMP_OPTIONS"; + + case LOGON_MSG_RECONNECT_OPTIONS: + return "LOGON_MSG_RECONNECT_OPTIONS"; + + case LOGON_MSG_SESSION_TERMINATE: + return "LOGON_MSG_SESSION_TERMINATE"; + + case LOGON_MSG_SESSION_CONTINUE: + return "LOGON_MSG_SESSION_CONTINUE"; + + default: + return "UNKNOWN"; + } +} + +const char* freerdp_get_logon_error_info_data(UINT32 data) +{ + switch (data) + { + case LOGON_FAILED_BAD_PASSWORD: + return "LOGON_FAILED_BAD_PASSWORD"; + + case LOGON_FAILED_UPDATE_PASSWORD: + return "LOGON_FAILED_UPDATE_PASSWORD"; + + case LOGON_FAILED_OTHER: + return "LOGON_FAILED_OTHER"; + + case LOGON_WARNING: + return "LOGON_WARNING"; + + default: + return "SESSION_ID"; + } +} + /** Allocator function for the rdp_freerdp structure. * @return an allocated structure filled with 0s. Need to be deallocated using freerdp_free() */ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/gateway/tsg.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/gateway/tsg.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/gateway/tsg.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/gateway/tsg.c 2017-03-03 08:39:24.000000000 +0000 @@ -90,7 +90,6 @@ UINT32 buffer3Length; UINT32 numBuffers = 0; UINT32 totalDataBytes = 0; - tsg = (rdpTsg*) IDL_handle; buffer1Length = buffer2Length = buffer3Length = 0; @@ -132,6 +131,7 @@ WLog_ERR(TAG, "Stream_New failed!"); return -1; } + /* PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE_NR (20 bytes) */ Stream_Write(s, &tsg->ChannelContext.ContextType, 4); /* ContextType (4 bytes) */ Stream_Write(s, tsg->ChannelContext.ContextUuid, 16); /* ContextUuid (16 bytes) */ @@ -157,7 +157,8 @@ Stream_Write(s, buffer3, buffer3Length); /* buffer3 (variable) */ Stream_SealLength(s); - status = rpc_client_write_call(tsg->rpc, Stream_Buffer(s), Stream_Length(s), TsProxySendToServerOpnum); + status = rpc_client_write_call(tsg->rpc, Stream_Buffer(s), Stream_Length(s), + TsProxySendToServerOpnum); Stream_Free(s, TRUE); if (status <= 0) @@ -187,14 +188,12 @@ UINT32 offset = 0; BYTE* buffer = NULL; rdpRpc* rpc = tsg->rpc; - WLog_DBG(TAG, "TsProxyCreateTunnelWriteRequest"); if (tsgPacket->packetId == TSG_PACKET_TYPE_VERSIONCAPS) { PTSG_PACKET_VERSIONCAPS packetVersionCaps = tsgPacket->tsgPacket.packetVersionCaps; PTSG_CAPABILITY_NAP tsgCapNap = &packetVersionCaps->tsgCaps->tsgPacket.tsgCapNap; - length = 108; buffer = (BYTE*) malloc(length); @@ -210,25 +209,24 @@ *((UINT32*) &buffer[20]) = packetVersionCaps->numCapabilities; /* NumCapabilities (4 bytes) */ *((UINT16*) &buffer[24]) = packetVersionCaps->majorVersion; /* MajorVersion (2 bytes) */ *((UINT16*) &buffer[26]) = packetVersionCaps->minorVersion; /* MinorVersion (2 bytes) */ - *((UINT16*) &buffer[28]) = packetVersionCaps->quarantineCapabilities; /* QuarantineCapabilities (2 bytes) */ + *((UINT16*) &buffer[28]) = + packetVersionCaps->quarantineCapabilities; /* QuarantineCapabilities (2 bytes) */ /* 4-byte alignment (30 + 2) */ *((UINT16*) &buffer[30]) = 0x0000; /* pad (2 bytes) */ *((UINT32*) &buffer[32]) = packetVersionCaps->numCapabilities; /* MaxCount (4 bytes) */ - *((UINT32*) &buffer[36]) = packetVersionCaps->tsgCaps->capabilityType; /* CapabilityType (4 bytes) */ + *((UINT32*) &buffer[36]) = + packetVersionCaps->tsgCaps->capabilityType; /* CapabilityType (4 bytes) */ *((UINT32*) &buffer[40]) = packetVersionCaps->tsgCaps->capabilityType; /* SwitchValue (4 bytes) */ *((UINT32*) &buffer[44]) = tsgCapNap->capabilities; /* capabilities (4 bytes) */ offset = 48; - /** * The following 60-byte structure is apparently undocumented, * but parts of it can be matched to known C706 data structures. */ - /* * 8-byte constant (8A E3 13 71 02 F4 36 71) also observed here: * http://lists.samba.org/archive/cifs-protocol/2010-July/001543.html */ - buffer[offset + 0] = 0x8A; buffer[offset + 1] = 0xE3; buffer[offset + 2] = 0x13; @@ -237,28 +235,19 @@ buffer[offset + 5] = 0xF4; buffer[offset + 6] = 0x36; buffer[offset + 7] = 0x71; - *((UINT32*) &buffer[offset + 8]) = 0x00040001; /* 1.4 (version?) */ *((UINT32*) &buffer[offset + 12]) = 0x00000001; /* 1 (element count?) */ - /* p_cont_list_t */ - buffer[offset + 16] = 2; /* ncontext_elem */ buffer[offset + 17] = 0x40; /* reserved1 */ *((UINT16*) &buffer[offset + 18]) = 0x0028; /* reserved2 */ - /* p_syntax_id_t */ - CopyMemory(&buffer[offset + 20], &TSGU_UUID, sizeof(p_uuid_t)); *((UINT32*) &buffer[offset + 36]) = TSGU_SYNTAX_IF_VERSION; - /* p_syntax_id_t */ - CopyMemory(&buffer[offset + 40], &NDR_UUID, sizeof(p_uuid_t)); *((UINT32*) &buffer[offset + 56]) = NDR_SYNTAX_IF_VERSION; - status = rpc_client_write_call(rpc, buffer, length, TsProxyCreateTunnelOpnum); - free(buffer); if (status <= 0) @@ -269,7 +258,6 @@ PTSG_PACKET_REAUTH packetReauth = tsgPacket->tsgPacket.packetReauth; PTSG_PACKET_VERSIONCAPS packetVersionCaps = packetReauth->tsgInitialPacket.packetVersionCaps; PTSG_CAPABILITY_NAP tsgCapNap = &packetVersionCaps->tsgCaps->tsgPacket.tsgCapNap; - length = 72; buffer = (BYTE*) malloc(length); @@ -282,27 +270,29 @@ *((UINT32*) &buffer[12]) = 0; /* ??? (4 bytes) */ *((UINT64*) &buffer[16]) = packetReauth->tunnelContext; /* TunnelContext (8 bytes) */ offset = 24; - *((UINT32*) &buffer[offset + 0]) = TSG_PACKET_TYPE_VERSIONCAPS; /* PacketId (4 bytes) */ *((UINT32*) &buffer[offset + 4]) = TSG_PACKET_TYPE_VERSIONCAPS; /* SwitchValue (4 bytes) */ *((UINT32*) &buffer[offset + 8]) = 0x00020004; /* PacketVersionCapsPtr (4 bytes) */ - *((UINT16*) &buffer[offset + 12]) = packetVersionCaps->tsgHeader.ComponentId; /* ComponentId (2 bytes) */ + *((UINT16*) &buffer[offset + 12]) = + packetVersionCaps->tsgHeader.ComponentId; /* ComponentId (2 bytes) */ *((UINT16*) &buffer[offset + 14]) = packetVersionCaps->tsgHeader.PacketId; /* PacketId (2 bytes) */ *((UINT32*) &buffer[offset + 16]) = 0x00020008; /* TsgCapsPtr (4 bytes) */ - *((UINT32*) &buffer[offset + 20]) = packetVersionCaps->numCapabilities; /* NumCapabilities (4 bytes) */ + *((UINT32*) &buffer[offset + 20]) = + packetVersionCaps->numCapabilities; /* NumCapabilities (4 bytes) */ *((UINT16*) &buffer[offset + 24]) = packetVersionCaps->majorVersion; /* MajorVersion (2 bytes) */ *((UINT16*) &buffer[offset + 26]) = packetVersionCaps->minorVersion; /* MinorVersion (2 bytes) */ - *((UINT16*) &buffer[offset + 28]) = packetVersionCaps->quarantineCapabilities; /* QuarantineCapabilities (2 bytes) */ + *((UINT16*) &buffer[offset + 28]) = + packetVersionCaps->quarantineCapabilities; /* QuarantineCapabilities (2 bytes) */ /* 4-byte alignment (30 + 2) */ *((UINT16*) &buffer[offset + 30]) = 0x0000; /* pad (2 bytes) */ *((UINT32*) &buffer[offset + 32]) = packetVersionCaps->numCapabilities; /* MaxCount (4 bytes) */ - *((UINT32*) &buffer[offset + 36]) = packetVersionCaps->tsgCaps->capabilityType; /* CapabilityType (4 bytes) */ - *((UINT32*) &buffer[offset + 40]) = packetVersionCaps->tsgCaps->capabilityType; /* SwitchValue (4 bytes) */ + *((UINT32*) &buffer[offset + 36]) = + packetVersionCaps->tsgCaps->capabilityType; /* CapabilityType (4 bytes) */ + *((UINT32*) &buffer[offset + 40]) = + packetVersionCaps->tsgCaps->capabilityType; /* SwitchValue (4 bytes) */ *((UINT32*) &buffer[offset + 44]) = tsgCapNap->capabilities; /* capabilities (4 bytes) */ offset += 48; - status = rpc_client_write_call(rpc, buffer, length, TsProxyCreateTunnelOpnum); - free(buffer); if (status <= 0) @@ -312,7 +302,8 @@ return TRUE; } -BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* tunnelContext, UINT32* tunnelId) +BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* tunnelContext, + UINT32* tunnelId) { BYTE* buffer; UINT32 count; @@ -328,7 +319,6 @@ PTSG_PACKET_VERSIONCAPS versionCaps; PTSG_PACKET_CAPS_RESPONSE packetCapsResponse; PTSG_PACKET_QUARENC_RESPONSE packetQuarEncResponse; - WLog_DBG(TAG, "TsProxyCreateTunnelReadResponse"); if (!pdu) @@ -349,7 +339,8 @@ packet->packetId = *((UINT32*) &buffer[offset]); /* PacketId (4 bytes) */ SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue (4 bytes) */ - if ((packet->packetId == TSG_PACKET_TYPE_CAPS_RESPONSE) && (SwitchValue == TSG_PACKET_TYPE_CAPS_RESPONSE)) + if ((packet->packetId == TSG_PACKET_TYPE_CAPS_RESPONSE) && + (SwitchValue == TSG_PACKET_TYPE_CAPS_RESPONSE)) { packetCapsResponse = (PTSG_PACKET_CAPS_RESPONSE) calloc(1, sizeof(TSG_PACKET_CAPS_RESPONSE)); @@ -361,10 +352,13 @@ packet->tsgPacket.packetCapsResponse = packetCapsResponse; /* PacketQuarResponsePtr (4 bytes) */ - packetCapsResponse->pktQuarEncResponse.flags = *((UINT32*) &buffer[offset + 12]); /* Flags (4 bytes) */ - packetCapsResponse->pktQuarEncResponse.certChainLen = *((UINT32*) &buffer[offset + 16]); /* CertChainLength (4 bytes) */ + packetCapsResponse->pktQuarEncResponse.flags = *((UINT32*) &buffer[offset + + 12]); /* Flags (4 bytes) */ + packetCapsResponse->pktQuarEncResponse.certChainLen = *((UINT32*) &buffer[offset + + 16]); /* CertChainLength (4 bytes) */ /* CertChainDataPtr (4 bytes) */ - CopyMemory(&packetCapsResponse->pktQuarEncResponse.nonce, &buffer[offset + 24], 16); /* Nonce (16 bytes) */ + CopyMemory(&packetCapsResponse->pktQuarEncResponse.nonce, &buffer[offset + 24], + 16); /* Nonce (16 bytes) */ offset += 40; Pointer = *((UINT32*) &buffer[offset]); /* VersionCapsPtr (4 bytes) */ offset += 4; @@ -419,7 +413,7 @@ if (versionCaps->tsgHeader.ComponentId != TS_GATEWAY_TRANSPORT) { WLog_ERR(TAG, "Unexpected ComponentId: 0x%04"PRIX16", Expected TS_GATEWAY_TRANSPORT", - versionCaps->tsgHeader.ComponentId); + versionCaps->tsgHeader.ComponentId); free(packetCapsResponse); free(versionCaps); free(packet); @@ -430,7 +424,8 @@ versionCaps->numCapabilities = *((UINT32*) &buffer[offset + 4]); /* NumCapabilities (4 bytes) */ versionCaps->majorVersion = *((UINT16*) &buffer[offset + 8]); /* MajorVersion (2 bytes) */ versionCaps->minorVersion = *((UINT16*) &buffer[offset + 10]); /* MinorVersion (2 bytes) */ - versionCaps->quarantineCapabilities = *((UINT16*) &buffer[offset + 12]); /* QuarantineCapabilities (2 bytes) */ + versionCaps->quarantineCapabilities = *((UINT16*) &buffer[offset + + 12]); /* QuarantineCapabilities (2 bytes) */ offset += 14; /* 4-byte alignment */ rpc_offset_align(&offset, 4); @@ -450,10 +445,11 @@ SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue (4 bytes) */ offset += 8; - if ((SwitchValue != TSG_CAPABILITY_TYPE_NAP) || (tsgCaps->capabilityType != TSG_CAPABILITY_TYPE_NAP)) + if ((SwitchValue != TSG_CAPABILITY_TYPE_NAP) || + (tsgCaps->capabilityType != TSG_CAPABILITY_TYPE_NAP)) { WLog_ERR(TAG, "Unexpected CapabilityType: 0x%08"PRIX32", Expected TSG_CAPABILITY_TYPE_NAP", - tsgCaps->capabilityType); + tsgCaps->capabilityType); free(tsgCaps); free(versionCaps); free(packetCapsResponse); @@ -461,7 +457,8 @@ return FALSE; } - tsgCaps->tsgPacket.tsgCapNap.capabilities = *((UINT32*) &buffer[offset]); /* Capabilities (4 bytes) */ + tsgCaps->tsgPacket.tsgCapNap.capabilities = *((UINT32*) + &buffer[offset]); /* Capabilities (4 bytes) */ offset += 4; switch (MessageSwitchValue) @@ -510,22 +507,21 @@ } rpc_offset_align(&offset, 4); - /* TunnelContext (20 bytes) */ CopyMemory(&tunnelContext->ContextType, &buffer[offset], 4); /* ContextType (4 bytes) */ CopyMemory(&tunnelContext->ContextUuid, &buffer[offset + 4], 16); /* ContextUuid (16 bytes) */ offset += 20; - *tunnelId = *((UINT32*) &buffer[offset]); /* TunnelId (4 bytes) */ /* ReturnValue (4 bytes) */ - free(tsgCaps); free(versionCaps); free(packetCapsResponse); } - else if ((packet->packetId == TSG_PACKET_TYPE_QUARENC_RESPONSE) && (SwitchValue == TSG_PACKET_TYPE_QUARENC_RESPONSE)) + else if ((packet->packetId == TSG_PACKET_TYPE_QUARENC_RESPONSE) && + (SwitchValue == TSG_PACKET_TYPE_QUARENC_RESPONSE)) { - packetQuarEncResponse = (PTSG_PACKET_QUARENC_RESPONSE) calloc(1, sizeof(TSG_PACKET_QUARENC_RESPONSE)); + packetQuarEncResponse = (PTSG_PACKET_QUARENC_RESPONSE) calloc(1, + sizeof(TSG_PACKET_QUARENC_RESPONSE)); if (!packetQuarEncResponse) { @@ -536,7 +532,8 @@ packet->tsgPacket.packetQuarEncResponse = packetQuarEncResponse; /* PacketQuarResponsePtr (4 bytes) */ packetQuarEncResponse->flags = *((UINT32*) &buffer[offset + 12]); /* Flags (4 bytes) */ - packetQuarEncResponse->certChainLen = *((UINT32*) &buffer[offset + 16]); /* CertChainLength (4 bytes) */ + packetQuarEncResponse->certChainLen = *((UINT32*) &buffer[offset + + 16]); /* CertChainLength (4 bytes) */ /* CertChainDataPtr (4 bytes) */ CopyMemory(&packetQuarEncResponse->nonce, &buffer[offset + 24], 16); /* Nonce (16 bytes) */ offset += 40; @@ -581,7 +578,7 @@ if (versionCaps->tsgHeader.ComponentId != TS_GATEWAY_TRANSPORT) { WLog_ERR(TAG, "Unexpected ComponentId: 0x%04"PRIX16", Expected TS_GATEWAY_TRANSPORT", - versionCaps->tsgHeader.ComponentId); + versionCaps->tsgHeader.ComponentId); free(versionCaps); free(packetQuarEncResponse); free(packet); @@ -592,7 +589,8 @@ versionCaps->numCapabilities = *((UINT32*) &buffer[offset + 4]); /* NumCapabilities (4 bytes) */ versionCaps->majorVersion = *((UINT16*) &buffer[offset + 8]); /* MajorVersion (2 bytes) */ versionCaps->majorVersion = *((UINT16*) &buffer[offset + 10]); /* MinorVersion (2 bytes) */ - versionCaps->quarantineCapabilities = *((UINT16*) &buffer[offset + 12]); /* QuarantineCapabilities (2 bytes) */ + versionCaps->quarantineCapabilities = *((UINT16*) &buffer[offset + + 12]); /* QuarantineCapabilities (2 bytes) */ offset += 14; /* 4-byte alignment */ rpc_offset_align(&offset, 4); @@ -601,19 +599,17 @@ offset += 4; /* 0x00000001 (4 bytes) */ offset += 4; /* 0x00000001 (4 bytes) */ offset += 4; /* 0x00000002 (4 bytes) */ - /* TunnelContext (20 bytes) */ CopyMemory(&tunnelContext->ContextType, &buffer[offset], 4); /* ContextType (4 bytes) */ CopyMemory(&tunnelContext->ContextUuid, &buffer[offset + 4], 16); /* ContextUuid (16 bytes) */ offset += 20; - free(versionCaps); free(packetQuarEncResponse); } else { WLog_ERR(TAG, "Unexpected PacketId: 0x%08"PRIX32", Expected TSG_PACKET_TYPE_CAPS_RESPONSE " - "or TSG_PACKET_TYPE_QUARENC_RESPONSE", packet->packetId); + "or TSG_PACKET_TYPE_QUARENC_RESPONSE", packet->packetId); free(packet); return FALSE; } @@ -642,15 +638,12 @@ UINT32 length; UINT32 offset; rdpRpc* rpc = tsg->rpc; - WLog_DBG(TAG, "TsProxyAuthorizeTunnelWriteRequest"); - count = _wcslen(tsg->MachineName) + 1; offset = 64 + (count * 2); rpc_offset_align(&offset, 4); offset += 4; length = offset; - buffer = (BYTE*) malloc(length); if (!buffer) @@ -679,9 +672,7 @@ ZeroMemory(&buffer[offset - pad], pad); *((UINT32*) &buffer[offset]) = 0x00000000; /* MaxCount (4 bytes) */ offset += 4; - status = rpc_client_write_call(rpc, buffer, length, TsProxyAuthorizeTunnelOpnum); - free(buffer); if (status <= 0) @@ -701,7 +692,6 @@ UINT32 idleTimeout; PTSG_PACKET packet; PTSG_PACKET_RESPONSE packetResponse; - WLog_DBG(TAG, "TsProxyAuthorizeTunnelReadResponse"); if (!pdu) @@ -733,7 +723,7 @@ if ((packet->packetId != TSG_PACKET_TYPE_RESPONSE) || (SwitchValue != TSG_PACKET_TYPE_RESPONSE)) { WLog_ERR(TAG, "Unexpected PacketId: 0x%08"PRIX32", Expected TSG_PACKET_TYPE_RESPONSE", - packet->packetId); + packet->packetId); free(packet); return FALSE; } @@ -752,8 +742,9 @@ if (packetResponse->flags != TSG_PACKET_TYPE_QUARREQUEST) { - WLog_ERR(TAG, "Unexpected Packet Response Flags: 0x%08"PRIX32", Expected TSG_PACKET_TYPE_QUARREQUEST", - packetResponse->flags); + WLog_ERR(TAG, + "Unexpected Packet Response Flags: 0x%08"PRIX32", Expected TSG_PACKET_TYPE_QUARREQUEST", + packetResponse->flags); free(packet); free(packetResponse); return FALSE; @@ -761,15 +752,24 @@ /* Reserved (4 bytes) */ Pointer = *((UINT32*) &buffer[offset + 20]); /* ResponseDataPtr (4 bytes) */ - packetResponse->responseDataLen = *((UINT32*) &buffer[offset + 24]); /* ResponseDataLength (4 bytes) */ - packetResponse->redirectionFlags.enableAllRedirections = *((UINT32*) &buffer[offset + 28]); /* EnableAllRedirections (4 bytes) */ - packetResponse->redirectionFlags.disableAllRedirections = *((UINT32*) &buffer[offset + 32]); /* DisableAllRedirections (4 bytes) */ - packetResponse->redirectionFlags.driveRedirectionDisabled = *((UINT32*) &buffer[offset + 36]); /* DriveRedirectionDisabled (4 bytes) */ - packetResponse->redirectionFlags.printerRedirectionDisabled = *((UINT32*) &buffer[offset + 40]); /* PrinterRedirectionDisabled (4 bytes) */ - packetResponse->redirectionFlags.portRedirectionDisabled = *((UINT32*) &buffer[offset + 44]); /* PortRedirectionDisabled (4 bytes) */ - packetResponse->redirectionFlags.reserved = *((UINT32*) &buffer[offset + 48]); /* Reserved (4 bytes) */ - packetResponse->redirectionFlags.clipboardRedirectionDisabled = *((UINT32*) &buffer[offset + 52]); /* ClipboardRedirectionDisabled (4 bytes) */ - packetResponse->redirectionFlags.pnpRedirectionDisabled = *((UINT32*) &buffer[offset + 56]); /* PnpRedirectionDisabled (4 bytes) */ + packetResponse->responseDataLen = *((UINT32*) &buffer[offset + + 24]); /* ResponseDataLength (4 bytes) */ + packetResponse->redirectionFlags.enableAllRedirections = *((UINT32*) &buffer[offset + + 28]); /* EnableAllRedirections (4 bytes) */ + packetResponse->redirectionFlags.disableAllRedirections = *((UINT32*) &buffer[offset + + 32]); /* DisableAllRedirections (4 bytes) */ + packetResponse->redirectionFlags.driveRedirectionDisabled = *((UINT32*) &buffer[offset + + 36]); /* DriveRedirectionDisabled (4 bytes) */ + packetResponse->redirectionFlags.printerRedirectionDisabled = *((UINT32*) &buffer[offset + + 40]); /* PrinterRedirectionDisabled (4 bytes) */ + packetResponse->redirectionFlags.portRedirectionDisabled = *((UINT32*) &buffer[offset + + 44]); /* PortRedirectionDisabled (4 bytes) */ + packetResponse->redirectionFlags.reserved = *((UINT32*) &buffer[offset + + 48]); /* Reserved (4 bytes) */ + packetResponse->redirectionFlags.clipboardRedirectionDisabled = *((UINT32*) &buffer[offset + + 52]); /* ClipboardRedirectionDisabled (4 bytes) */ + packetResponse->redirectionFlags.pnpRedirectionDisabled = *((UINT32*) &buffer[offset + + 56]); /* PnpRedirectionDisabled (4 bytes) */ offset += 60; SizeValue = *((UINT32*) &buffer[offset]); /* (4 bytes) */ offset += 4; @@ -777,12 +777,12 @@ if (SizeValue != packetResponse->responseDataLen) { WLog_ERR(TAG, "Unexpected size value: %"PRIu32", expected: %"PRIu32"", - SizeValue, packetResponse->responseDataLen); + SizeValue, packetResponse->responseDataLen); free(packetResponse); free(packet); return FALSE; } - + if (SizeValue == 4) { idleTimeout = *((UINT32*) &buffer[offset]); @@ -792,10 +792,9 @@ { offset += SizeValue; /* ResponseData */ } - + free(packetResponse); free(packet); - return TRUE; } @@ -816,9 +815,7 @@ BYTE* buffer; UINT32 length; rdpRpc* rpc = tsg->rpc; - WLog_DBG(TAG, "TsProxyMakeTunnelCallWriteRequest"); - length = 40; buffer = (BYTE*) malloc(length); @@ -834,9 +831,7 @@ *((UINT32*) &buffer[28]) = TSG_PACKET_TYPE_MSGREQUEST_PACKET; /* SwitchValue (4 bytes) */ *((UINT32*) &buffer[32]) = 0x00020000; /* PacketMsgRequestPtr (4 bytes) */ *((UINT32*) &buffer[36]) = 0x00000001; /* MaxMessagesPerBatch (4 bytes) */ - status = rpc_client_write_call(rpc, buffer, length, TsProxyMakeTunnelCallOpnum); - free(buffer); if (status <= 0) @@ -860,7 +855,6 @@ PTSG_PACKET_MSG_RESPONSE packetMsgResponse = NULL; PTSG_PACKET_STRING_MESSAGE packetStringMessage = NULL; PTSG_PACKET_REAUTH_MESSAGE packetReauthMessage = NULL; - WLog_DBG(TAG, "TsProxyMakeTunnelCallReadResponse"); /* This is an asynchronous response */ @@ -883,10 +877,11 @@ packet->packetId = *((UINT32*) &buffer[offset]); /* PacketId (4 bytes) */ SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue (4 bytes) */ - if ((packet->packetId != TSG_PACKET_TYPE_MESSAGE_PACKET) || (SwitchValue != TSG_PACKET_TYPE_MESSAGE_PACKET)) + if ((packet->packetId != TSG_PACKET_TYPE_MESSAGE_PACKET) || + (SwitchValue != TSG_PACKET_TYPE_MESSAGE_PACKET)) { WLog_ERR(TAG, "Unexpected PacketId: 0x%08"PRIX32", Expected TSG_PACKET_TYPE_MESSAGE_PACKET", - packet->packetId); + packet->packetId); free(packet); return FALSE; } @@ -919,14 +914,17 @@ packetMsgResponse->messagePacket.consentMessage = packetStringMessage; Pointer = *((UINT32*) &buffer[offset + 28]); /* ConsentMessagePtr (4 bytes) */ - packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + 32]); /* IsDisplayMandatory (4 bytes) */ - packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + 36]); /* IsConsentMandatory (4 bytes) */ + packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + + 32]); /* IsDisplayMandatory (4 bytes) */ + packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + + 36]); /* IsConsentMandatory (4 bytes) */ packetStringMessage->msgBytes = *((UINT32*) &buffer[offset + 40]); /* MsgBytes (4 bytes) */ Pointer = *((UINT32*) &buffer[offset + 44]); /* MsgPtr (4 bytes) */ MaxCount = *((UINT32*) &buffer[offset + 48]); /* MaxCount (4 bytes) */ /* Offset (4 bytes) */ ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount (4 bytes) */ - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, NULL); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, + NULL); WLog_INFO(TAG, "Consent Message: %s", messageText); free(messageText); break; @@ -942,14 +940,17 @@ packetMsgResponse->messagePacket.serviceMessage = packetStringMessage; Pointer = *((UINT32*) &buffer[offset + 28]); /* ServiceMessagePtr (4 bytes) */ - packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + 32]); /* IsDisplayMandatory (4 bytes) */ - packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + 36]); /* IsConsentMandatory (4 bytes) */ + packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + + 32]); /* IsDisplayMandatory (4 bytes) */ + packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + + 36]); /* IsConsentMandatory (4 bytes) */ packetStringMessage->msgBytes = *((UINT32*) &buffer[offset + 40]); /* MsgBytes (4 bytes) */ Pointer = *((UINT32*) &buffer[offset + 44]); /* MsgPtr (4 bytes) */ MaxCount = *((UINT32*) &buffer[offset + 48]); /* MaxCount (4 bytes) */ /* Offset (4 bytes) */ ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount (4 bytes) */ - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, NULL); + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, + NULL); WLog_INFO(TAG, "Service Message: %s", messageText); free(messageText); break; @@ -966,7 +967,8 @@ packetMsgResponse->messagePacket.reauthMessage = packetReauthMessage; Pointer = *((UINT32*) &buffer[offset + 28]); /* ReauthMessagePtr (4 bytes) */ /* alignment pad (4 bytes) */ - packetReauthMessage->tunnelContext = *((UINT64*) &buffer[offset + 36]); /* TunnelContext (8 bytes) */ + packetReauthMessage->tunnelContext = *((UINT64*) &buffer[offset + + 36]); /* TunnelContext (8 bytes) */ /* ReturnValue (4 bytes) */ tsg->ReauthTunnelContext = packetReauthMessage->tunnelContext; break; @@ -978,6 +980,7 @@ } out: + if (packet) { if (packet->tsgPacket.packetMsgResponse) @@ -1011,9 +1014,7 @@ UINT32 length; rdpRpc* rpc = tsg->rpc; count = _wcslen(tsg->Hostname) + 1; - WLog_DBG(TAG, "TsProxyCreateChannelWriteRequest"); - length = 60 + (count * 2); buffer = (BYTE*) malloc(length); @@ -1038,9 +1039,7 @@ *((UINT32*) &buffer[52]) = 0; /* Offset (4 bytes) */ *((UINT32*) &buffer[56]) = count; /* ActualCount (4 bytes) */ CopyMemory(&buffer[60], tsg->Hostname, count * 2); /* Array */ - status = rpc_client_write_call(rpc, buffer, length, TsProxyCreateChannelOpnum); - free(buffer); if (status <= 0) @@ -1049,33 +1048,28 @@ return TRUE; } -BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* channelContext, UINT32* channelId) +BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* channelContext, + UINT32* channelId) { BYTE* buffer; - UINT32 length; UINT32 offset; - WLog_DBG(TAG, "TsProxyCreateChannelReadResponse"); if (!pdu) return FALSE; - length = Stream_Length(pdu->s); buffer = Stream_Buffer(pdu->s); if (!(pdu->Flags & RPC_PDU_FLAG_STUB)) buffer = &buffer[24]; offset = 0; - /* ChannelContext (20 bytes) */ CopyMemory(&channelContext->ContextType, &buffer[offset], 4); /* ContextType (4 bytes) */ CopyMemory(&channelContext->ContextUuid, &buffer[offset + 4], 16); /* ContextUuid (16 bytes) */ offset += 20; - *channelId = *((UINT32*) &buffer[offset]); /* ChannelId (4 bytes) */ /* ReturnValue (4 bytes) */ - return TRUE; } @@ -1091,7 +1085,6 @@ BYTE* buffer; UINT32 length; rdpRpc* rpc = tsg->rpc; - WLog_DBG(TAG, "TsProxyCloseChannelWriteRequest"); if (!context) @@ -1106,9 +1099,7 @@ /* ChannelContext (20 bytes) */ CopyMemory(&buffer[0], &context->ContextType, 4); /* ContextType (4 bytes) */ CopyMemory(&buffer[4], &context->ContextUuid, 16); /* ContextUuid (16 bytes) */ - status = rpc_client_write_call(rpc, buffer, length, TsProxyCloseChannelOpnum); - free(buffer); if (status <= 0) @@ -1120,29 +1111,20 @@ BOOL TsProxyCloseChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* context) { BYTE* buffer; - UINT32 length; - UINT32 offset; - WLog_DBG(TAG, "TsProxyCloseChannelReadResponse"); if (!pdu) return FALSE; - length = Stream_Length(pdu->s); buffer = Stream_Buffer(pdu->s); if (!(pdu->Flags & RPC_PDU_FLAG_STUB)) buffer = &buffer[24]; - offset = 0; - /* ChannelContext (20 bytes) */ - CopyMemory(&context->ContextType, &buffer[offset], 4); /* ContextType (4 bytes) */ - CopyMemory(&context->ContextUuid, &buffer[offset + 4], 16); /* ContextUuid (16 bytes) */ - offset += 20; - + CopyMemory(&context->ContextType, &buffer[0], 4); /* ContextType (4 bytes) */ + CopyMemory(&context->ContextUuid, &buffer[4], 16); /* ContextUuid (16 bytes) */ /* ReturnValue (4 bytes) */ - return TRUE; } @@ -1158,9 +1140,7 @@ BYTE* buffer; UINT32 length; rdpRpc* rpc = tsg->rpc; - WLog_DBG(TAG, "TsProxyCloseTunnelWriteRequest"); - length = 20; buffer = (BYTE*) malloc(length); @@ -1170,9 +1150,7 @@ /* TunnelContext (20 bytes) */ CopyMemory(&buffer[0], &context->ContextType, 4); /* ContextType (4 bytes) */ CopyMemory(&buffer[4], &context->ContextUuid, 16); /* ContextUuid (16 bytes) */ - status = rpc_client_write_call(rpc, buffer, length, TsProxyCloseTunnelOpnum); - free(buffer); if (status <= 0) @@ -1184,29 +1162,20 @@ BOOL TsProxyCloseTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* context) { BYTE* buffer; - UINT32 length; - UINT32 offset; - WLog_DBG(TAG, "TsProxyCloseTunnelReadResponse"); if (!pdu) return FALSE; - length = Stream_Length(pdu->s); buffer = Stream_Buffer(pdu->s); if (!(pdu->Flags & RPC_PDU_FLAG_STUB)) buffer = &buffer[24]; - offset = 0; - /* TunnelContext (20 bytes) */ - CopyMemory(&context->ContextType, &buffer[offset], 4); /* ContextType (4 bytes) */ - CopyMemory(&context->ContextUuid, &buffer[offset + 4], 16); /* ContextUuid (16 bytes) */ - offset += 20; - + CopyMemory(&context->ContextType, &buffer[0], 4); /* ContextType (4 bytes) */ + CopyMemory(&context->ContextUuid, &buffer[4], 16); /* ContextUuid (16 bytes) */ /* ReturnValue (4 bytes) */ - return TRUE; } @@ -1224,9 +1193,7 @@ BYTE* buffer; UINT32 length; rdpRpc* rpc = tsg->rpc; - WLog_DBG(TAG, "TsProxySetupReceivePipeWriteRequest"); - length = 20; buffer = (BYTE*) malloc(length); @@ -1236,9 +1203,7 @@ /* ChannelContext (20 bytes) */ CopyMemory(&buffer[0], &channelContext->ContextType, 4); /* ContextType (4 bytes) */ CopyMemory(&buffer[4], &channelContext->ContextUuid, 16); /* ContextUuid (16 bytes) */ - status = rpc_client_write_call(rpc, buffer, length, TsProxySetupReceivePipeOpnum); - free(buffer); if (status <= 0) @@ -1250,7 +1215,6 @@ BOOL TsProxySetupReceivePipeReadResponse(rdpTsg* tsg, RPC_PDU* pdu) { WLog_DBG(TAG, "TsProxySetupReceivePipeReadResponse"); - return TRUE; } @@ -1295,7 +1259,6 @@ tsg->state = state; WLog_DBG(TAG, "%s", str); - return 1; } @@ -1304,24 +1267,18 @@ TSG_PACKET tsgPacket; PTSG_CAPABILITY_NAP tsgCapNap; PTSG_PACKET_VERSIONCAPS packetVersionCaps; - packetVersionCaps = &tsg->packetVersionCaps; packetVersionCaps->tsgCaps = &tsg->tsgCaps; tsgCapNap = &tsg->tsgCaps.tsgPacket.tsgCapNap; - tsgPacket.packetId = TSG_PACKET_TYPE_VERSIONCAPS; tsgPacket.tsgPacket.packetVersionCaps = packetVersionCaps; - packetVersionCaps->tsgHeader.ComponentId = TS_GATEWAY_TRANSPORT; packetVersionCaps->tsgHeader.PacketId = TSG_PACKET_TYPE_VERSIONCAPS; - packetVersionCaps->numCapabilities = 1; packetVersionCaps->majorVersion = 1; packetVersionCaps->minorVersion = 1; packetVersionCaps->quarantineCapabilities = 0; - packetVersionCaps->tsgCaps->capabilityType = TSG_CAPABILITY_TYPE_NAP; - /* * Using reduced capabilities appears to trigger * TSG_PACKET_TYPE_QUARENC_RESPONSE instead of TSG_PACKET_TYPE_CAPS_RESPONSE @@ -1329,13 +1286,12 @@ * However, reduced capabilities may break connectivity with servers enforcing features, such as * "Only allow connections from Remote Desktop Services clients that support RD Gateway messaging" */ - tsgCapNap->capabilities = - TSG_NAP_CAPABILITY_QUAR_SOH | - TSG_NAP_CAPABILITY_IDLE_TIMEOUT | - TSG_MESSAGING_CAP_CONSENT_SIGN | - TSG_MESSAGING_CAP_SERVICE_MSG | - TSG_MESSAGING_CAP_REAUTH; + TSG_NAP_CAPABILITY_QUAR_SOH | + TSG_NAP_CAPABILITY_IDLE_TIMEOUT | + TSG_MESSAGING_CAP_CONSENT_SIGN | + TSG_MESSAGING_CAP_SERVICE_MSG | + TSG_MESSAGING_CAP_REAUTH; if (!TsProxyCreateTunnelWriteRequest(tsg, &tsgPacket)) { @@ -1345,7 +1301,6 @@ } tsg_transition_to_state(tsg, TSG_STATE_INITIAL); - return 1; } @@ -1354,15 +1309,11 @@ TSG_PACKET tsgPacket; PTSG_PACKET_REAUTH packetReauth; PTSG_PACKET_VERSIONCAPS packetVersionCaps; - tsg->reauthSequence = TRUE; - packetReauth = &tsg->packetReauth; packetVersionCaps = &tsg->packetVersionCaps; - tsgPacket.packetId = TSG_PACKET_TYPE_REAUTH; tsgPacket.tsgPacket.packetReauth = &tsg->packetReauth; - packetReauth->tunnelContext = tsg->ReauthTunnelContext; packetReauth->packetId = TSG_PACKET_TYPE_VERSIONCAPS; packetReauth->tsgInitialPacket.packetVersionCaps = packetVersionCaps; @@ -1382,7 +1333,6 @@ } tsg_transition_to_state(tsg, TSG_STATE_INITIAL); - return 1; } @@ -1397,7 +1347,6 @@ case TSG_STATE_INITIAL: { CONTEXT_HANDLE* TunnelContext; - TunnelContext = (tsg->reauthSequence) ? &tsg->NewTunnelContext : &tsg->TunnelContext; if (!TsProxyCreateTunnelReadResponse(tsg, pdu, TunnelContext, &tsg->TunnelId)) @@ -1421,7 +1370,6 @@ case TSG_STATE_CONNECTED: { CONTEXT_HANDLE* TunnelContext; - TunnelContext = (tsg->reauthSequence) ? &tsg->NewTunnelContext : &tsg->TunnelContext; if (!TsProxyAuthorizeTunnelReadResponse(tsg, pdu)) @@ -1509,7 +1457,6 @@ tsg_transition_to_state(tsg, TSG_STATE_PIPE_CREATED); tsg->reauthSequence = FALSE; - status = 1; } else @@ -1586,7 +1533,8 @@ return FALSE; } - if (!TsProxyMakeTunnelCallWriteRequest(tsg, &tsg->TunnelContext, TSG_TUNNEL_CANCEL_ASYNC_MSG_REQUEST)) + if (!TsProxyMakeTunnelCallWriteRequest(tsg, &tsg->TunnelContext, + TSG_TUNNEL_CANCEL_ASYNC_MSG_REQUEST)) { WLog_ERR(TAG, "TsProxyMakeTunnelCall failure"); return FALSE; @@ -1607,7 +1555,6 @@ } tsg_transition_to_state(tsg, TSG_STATE_FINAL); - status = 1; } break; @@ -1622,7 +1569,6 @@ int tsg_check_event_handles(rdpTsg* tsg) { int status; - status = rpc_client_in_channel_recv(tsg->rpc); if (status < 0) @@ -1701,9 +1647,7 @@ { free(tsg->Hostname); tsg->Hostname = NULL; - ConvertToUnicode(CP_UTF8, 0, hostname, -1, &tsg->Hostname, 0); - return TRUE; } @@ -1711,9 +1655,7 @@ { free(tsg->MachineName); tsg->MachineName = NULL; - ConvertToUnicode(CP_UTF8, 0, machineName, -1, &tsg->MachineName, 0); - return TRUE; } @@ -1722,12 +1664,8 @@ DWORD nCount; HANDLE events[64]; rdpRpc* rpc = tsg->rpc; - RpcInChannel* inChannel; - RpcOutChannel* outChannel; - RpcVirtualConnection* connection; rdpSettings* settings = rpc->settings; rdpTransport* transport = rpc->transport; - tsg->Port = port; tsg->transport = transport; @@ -1743,10 +1681,6 @@ return FALSE; } - connection = rpc->VirtualConnection; - inChannel = connection->DefaultInChannel; - outChannel = connection->DefaultOutChannel; - nCount = tsg_get_event_handles(tsg, events, 64); if (nCount == 0) @@ -1765,14 +1699,12 @@ } WLog_INFO(TAG, "TS Gateway Connection Success"); - tsg->bio = BIO_new(BIO_s_tsg()); if (!tsg->bio) return FALSE; BIO_set_data(tsg->bio, (void*) tsg); - return TRUE; } @@ -1797,7 +1729,6 @@ * |<-------------TsProxyCloseTunnel Response----------| * | | */ - if (!tsg) return FALSE; @@ -1893,7 +1824,6 @@ rdpTsg* tsg_new(rdpTransport* transport) { rdpTsg* tsg; - tsg = (rdpTsg*) calloc(1, sizeof(rdpTsg)); if (!tsg) @@ -1901,7 +1831,6 @@ tsg->transport = transport; tsg->settings = transport->settings; - tsg->rpc = rpc_new(tsg->transport); if (!tsg->rpc) @@ -1925,7 +1854,6 @@ free(tsg->Hostname); free(tsg->MachineName); - free(tsg); } } @@ -1939,9 +1867,7 @@ { int status; rdpTsg* tsg = (rdpTsg*) BIO_get_data(bio); - BIO_clear_flags(bio, BIO_FLAGS_WRITE); - status = tsg_write(tsg, (BYTE*) buf, num); if (status < 0) @@ -1966,9 +1892,7 @@ { int status; rdpTsg* tsg = (rdpTsg*) BIO_get_data(bio); - BIO_clear_flags(bio, BIO_FLAGS_READ); - status = tsg_read(tsg, (BYTE*) buf, size); if (status < 0) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/gcc.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/gcc.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/gcc.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/gcc.c 2017-03-03 08:39:24.000000000 +0000 @@ -836,6 +836,9 @@ settings->SupportMonitorLayoutPdu = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) ? TRUE : FALSE; + if (settings->SupportStatusInfoPdu) + settings->SupportStatusInfoPdu = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_STATUSINFO_PDU) ? TRUE : FALSE; + if (!(earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE)) connectionType = 0; @@ -937,6 +940,9 @@ if (settings->SupportMonitorLayoutPdu) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU; + if (settings->SupportStatusInfoPdu) + earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_STATUSINFO_PDU; + Stream_Write_UINT16(s, highColorDepth); /* highColorDepth */ Stream_Write_UINT16(s, supportedColorDepths); /* supportedColorDepths */ Stream_Write_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ @@ -1699,6 +1705,16 @@ Stream_Read_UINT32(s, flags); /* flags */ Stream_Read_UINT32(s, monitorCount); /* monitorCount */ + /* 2.2.1.3.6 Client Monitor Data - + * monitorCount (4 bytes): A 32-bit, unsigned integer. The number of display + * monitor definitions in the monitorDefArray field (the maximum allowed is 16). + */ + if (monitorCount > 16) + { + WLog_ERR(TAG, "announced monitors(%"PRIu32") exceed the 16 limit", monitorCount); + return FALSE; + } + if (monitorCount > settings->MonitorDefArraySize) { WLog_ERR(TAG, "too many announced monitors(%"PRIu32"), clamping to %"PRIu32"", monitorCount, diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/info.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/info.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/info.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/info.c 2017-03-03 08:39:24.000000000 +0000 @@ -43,25 +43,21 @@ "Logon Extended Info" }; -BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) +static BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp) { BYTE ClientRandom[32]; BYTE AutoReconnectRandom[32]; ARC_SC_PRIVATE_PACKET* serverCookie; ARC_CS_PRIVATE_PACKET* clientCookie; rdpSettings* settings = rdp->settings; - serverCookie = settings->ServerAutoReconnectCookie; clientCookie = settings->ClientAutoReconnectCookie; - clientCookie->cbLen = 28; clientCookie->version = serverCookie->version; clientCookie->logonId = serverCookie->logonId; ZeroMemory(clientCookie->securityVerifier, 16); - ZeroMemory(AutoReconnectRandom, sizeof(AutoReconnectRandom)); CopyMemory(AutoReconnectRandom, serverCookie->arcRandomBits, 16); - ZeroMemory(ClientRandom, sizeof(ClientRandom)); if (settings->SelectedProtocol == PROTOCOL_RDP) @@ -69,7 +65,8 @@ /* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */ - if (!winpr_HMAC(WINPR_MD_MD5, AutoReconnectRandom, 16, ClientRandom, 32, clientCookie->securityVerifier, 16)) + if (!winpr_HMAC(WINPR_MD_MD5, AutoReconnectRandom, 16, ClientRandom, 32, + clientCookie->securityVerifier, 16)) return FALSE; return TRUE; @@ -82,18 +79,18 @@ * @param settings settings */ -BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s, logon_info_ex *info) +static BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s, logon_info_ex* info) { BYTE* p; ARC_SC_PRIVATE_PACKET* autoReconnectCookie; rdpSettings* settings = rdp->settings; - autoReconnectCookie = settings->ServerAutoReconnectCookie; if (Stream_GetRemainingLength(s) < 28) return FALSE; Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ + if (autoReconnectCookie->cbLen != 28) { WLog_ERR(TAG, "ServerAutoReconnectCookie.cbLen != 28"); @@ -103,16 +100,13 @@ Stream_Read_UINT32(s, autoReconnectCookie->version); /* Version (4 bytes) */ Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* ArcRandomBits (16 bytes) */ - p = autoReconnectCookie->arcRandomBits; - WLog_DBG(TAG, "ServerAutoReconnectCookie: Version: %"PRIu32" LogonId: %"PRIu32" SecurityVerifier: " - "%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"" - "%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"", - autoReconnectCookie->version, autoReconnectCookie->logonId, - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], - p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); - + "%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"" + "%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"", + autoReconnectCookie->version, autoReconnectCookie->logonId, + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); info->LogonId = autoReconnectCookie->logonId; CopyMemory(info->ArcRandomBits, p, 16); @@ -134,11 +128,10 @@ * @param settings settings */ -BOOL rdp_read_client_auto_reconnect_cookie(rdpRdp* rdp, wStream* s) +static BOOL rdp_read_client_auto_reconnect_cookie(rdpRdp* rdp, wStream* s) { ARC_CS_PRIVATE_PACKET* autoReconnectCookie; rdpSettings* settings = rdp->settings; - autoReconnectCookie = settings->ClientAutoReconnectCookie; if (Stream_GetRemainingLength(s) < 28) @@ -148,7 +141,6 @@ Stream_Read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ Stream_Read(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */ - return TRUE; } @@ -159,23 +151,19 @@ * @param settings settings */ -void rdp_write_client_auto_reconnect_cookie(rdpRdp* rdp, wStream* s) +static void rdp_write_client_auto_reconnect_cookie(rdpRdp* rdp, wStream* s) { BYTE* p; ARC_CS_PRIVATE_PACKET* autoReconnectCookie; rdpSettings* settings = rdp->settings; - autoReconnectCookie = settings->ClientAutoReconnectCookie; - p = autoReconnectCookie->securityVerifier; - WLog_DBG(TAG, "ClientAutoReconnectCookie: Version: %"PRIu32" LogonId: %"PRIu32" ArcRandomBits: " - "%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"" - "%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"", - autoReconnectCookie->version, autoReconnectCookie->logonId, - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], - p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); - + "%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"" + "%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"%02"PRIX8"", + autoReconnectCookie->version, autoReconnectCookie->logonId, + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); Stream_Write_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ Stream_Write_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ Stream_Write_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ @@ -189,7 +177,7 @@ * @param settings settings */ -BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) +static BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) { UINT16 clientAddressFamily; UINT16 cbClientAddress; @@ -231,16 +219,19 @@ if (cbClientAddress) { wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbClientAddress / 2 - 1]) { WLog_ERR(TAG, "protocol error: clientAddress must be null terminated"); return FALSE; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->ClientAddress, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert client address"); return FALSE; } + Stream_Seek(s, cbClientAddress); WLog_DBG(TAG, "rdp client address: [%s]", settings->ClientAddress); } @@ -276,16 +267,20 @@ if (cbClientDir) { wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbClientDir / 2 - 1]) { WLog_ERR(TAG, "protocol error: clientDir must be null terminated"); return FALSE; } - if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), -1, &settings->ClientDir, 0, NULL, NULL) < 1) + + if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), -1, &settings->ClientDir, 0, NULL, + NULL) < 1) { WLog_ERR(TAG, "failed to convert client directory"); return FALSE; } + Stream_Seek(s, cbClientDir); WLog_DBG(TAG, "rdp client dir: [%s]", settings->ClientDir); } @@ -298,29 +293,36 @@ /* optional: clientTimeZone (172 bytes) */ if (Stream_GetRemainingLength(s) == 0) return TRUE; + if (!rdp_read_client_time_zone(s, settings)) return FALSE; /* optional: clientSessionId (4 bytes), should be set to 0 */ if (Stream_GetRemainingLength(s) == 0) return TRUE; + if (Stream_GetRemainingLength(s) < 4) return FALSE; + Stream_Seek_UINT32(s); /* optional: performanceFlags (4 bytes) */ if (Stream_GetRemainingLength(s) == 0) return TRUE; + if (Stream_GetRemainingLength(s) < 4) return FALSE; + Stream_Read_UINT32(s, settings->PerformanceFlags); freerdp_performance_flags_split(settings); /* optional: cbAutoReconnectLen (2 bytes) */ if (Stream_GetRemainingLength(s) == 0) return TRUE; + if (Stream_GetRemainingLength(s) < 2) return FALSE; + Stream_Read_UINT16(s, cbAutoReconnectLen); /* optional: autoReconnectCookie (28 bytes) */ @@ -329,13 +331,11 @@ return rdp_read_client_auto_reconnect_cookie(rdp, s); /* TODO */ - /* reserved1 (2 bytes) */ /* reserved2 (2 bytes) */ /* cbDynamicDSTTimeZoneKeyName (2 bytes) */ /* dynamicDSTTimeZoneKeyName (variable) */ /* dynamicDaylightTimeDisabled (2 bytes) */ - return TRUE; } @@ -346,7 +346,7 @@ * @param settings settings */ -void rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s) +static void rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s) { int clientAddressFamily; WCHAR* clientAddress = NULL; @@ -355,44 +355,33 @@ int cbClientDir; int cbAutoReconnectCookie; rdpSettings* settings = rdp->settings; - clientAddressFamily = settings->IPv6Enabled ? ADDRESS_FAMILY_INET6 : ADDRESS_FAMILY_INET; - cbClientAddress = ConvertToUnicode(CP_UTF8, 0, settings->ClientAddress, -1, &clientAddress, 0) * 2; - cbClientDir = ConvertToUnicode(CP_UTF8, 0, settings->ClientDir, -1, &clientDir, 0) * 2; - cbAutoReconnectCookie = (int) settings->ServerAutoReconnectCookie->cbLen; - Stream_Write_UINT16(s, clientAddressFamily); /* clientAddressFamily (2 bytes) */ - Stream_Write_UINT16(s, cbClientAddress + 2); /* cbClientAddress (2 bytes) */ if (cbClientAddress > 0) Stream_Write(s, clientAddress, cbClientAddress); /* clientAddress */ - Stream_Write_UINT16(s, 0); + Stream_Write_UINT16(s, 0); Stream_Write_UINT16(s, cbClientDir + 2); /* cbClientDir (2 bytes) */ if (cbClientDir > 0) Stream_Write(s, clientDir, cbClientDir); /* clientDir */ - Stream_Write_UINT16(s, 0); + Stream_Write_UINT16(s, 0); rdp_write_client_time_zone(s, settings); /* clientTimeZone (172 bytes) */ - Stream_Write_UINT32(s, 0); /* clientSessionId (4 bytes), should be set to 0 */ - freerdp_performance_flags_make(settings); Stream_Write_UINT32(s, settings->PerformanceFlags); /* performanceFlags (4 bytes) */ - Stream_Write_UINT16(s, cbAutoReconnectCookie); /* cbAutoReconnectCookie (2 bytes) */ if (cbAutoReconnectCookie > 0) { rdp_compute_client_auto_reconnect_cookie(rdp); - rdp_write_client_auto_reconnect_cookie(rdp, s); /* autoReconnectCookie */ - Stream_Write_UINT16(s, 0); /* reserved1 (2 bytes) */ Stream_Write_UINT16(s, 0); /* reserved2 (2 bytes) */ } @@ -408,7 +397,7 @@ * @param settings settings */ -BOOL rdp_read_info_packet(rdpRdp* rdp, wStream* s) +static BOOL rdp_read_info_packet(rdpRdp* rdp, wStream* s) { UINT32 flags; UINT16 cbDomain; @@ -425,13 +414,13 @@ Stream_Seek_UINT32(s); /* CodePage (4 bytes ) */ Stream_Read_UINT32(s, flags); /* flags (4 bytes) */ - settings->AudioCapture = ((flags & INFO_AUDIOCAPTURE) ? TRUE : FALSE); settings->AudioPlayback = ((flags & INFO_NOAUDIOPLAYBACK) ? FALSE : TRUE); settings->AutoLogonEnabled = ((flags & INFO_AUTOLOGON) ? TRUE : FALSE); settings->RemoteApplicationMode = ((flags & INFO_RAIL) ? TRUE : FALSE); settings->RemoteConsoleAudio = ((flags & INFO_REMOTECONSOLEAUDIO) ? TRUE : FALSE); settings->CompressionEnabled = ((flags & INFO_COMPRESSION) ? TRUE : FALSE); + settings->LogonNotify = ((flags & INFO_LOGONNOTIFY) ? TRUE : FALSE); if (flags & INFO_COMPRESSION) { @@ -451,7 +440,7 @@ Stream_Read_UINT16(s, cbAlternateShell); /* cbAlternateShell (2 bytes) */ Stream_Read_UINT16(s, cbWorkingDir); /* cbWorkingDir (2 bytes) */ - if (Stream_GetRemainingLength(s) < (size_t) (cbDomain + 2)) + if (Stream_GetRemainingLength(s) < (size_t)(cbDomain + 2)) return FALSE; if (cbDomain > 0) @@ -465,22 +454,27 @@ WLog_ERR(TAG, "protocol error: invalid cbDomain value: %"PRIu16"", cbDomain); return FALSE; } + wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbDomain / 2]) { WLog_ERR(TAG, "protocol error: Domain must be null terminated"); return FALSE; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->Domain, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert Domain string"); return FALSE; } + Stream_Seek(s, cbDomain); } + Stream_Seek(s, 2); - if (Stream_GetRemainingLength(s) < (size_t) (cbUserName + 2)) + if (Stream_GetRemainingLength(s) < (size_t)(cbUserName + 2)) return FALSE; if (cbUserName > 0) @@ -494,22 +488,27 @@ WLog_ERR(TAG, "protocol error: invalid cbUserName value: %"PRIu16"", cbUserName); return FALSE; } + wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbUserName / 2]) { WLog_ERR(TAG, "protocol error: UserName must be null terminated"); return FALSE; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->Username, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert UserName string"); return FALSE; } + Stream_Seek(s, cbUserName); } + Stream_Seek(s, 2); - if (Stream_GetRemainingLength(s) < (size_t) (cbPassword + 2)) + if (Stream_GetRemainingLength(s) < (size_t)(cbPassword + 2)) return FALSE; if (cbPassword > 0) @@ -523,22 +522,27 @@ WLog_ERR(TAG, "protocol error: invalid cbPassword value: %"PRIu16"", cbPassword); return FALSE; } + wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbPassword / 2]) { WLog_ERR(TAG, "protocol error: Password must be null terminated"); return FALSE; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->Password, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert Password string"); return FALSE; } + Stream_Seek(s, cbPassword); } + Stream_Seek(s, 2); - if (Stream_GetRemainingLength(s) < (size_t) (cbAlternateShell + 2)) + if (Stream_GetRemainingLength(s) < (size_t)(cbAlternateShell + 2)) return FALSE; if (cbAlternateShell > 0) @@ -552,22 +556,27 @@ WLog_ERR(TAG, "protocol error: invalid cbAlternateShell value: %"PRIu16"", cbAlternateShell); return FALSE; } + wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbAlternateShell / 2]) { WLog_ERR(TAG, "protocol error: AlternateShell must be null terminated"); return FALSE; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->AlternateShell, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert AlternateShell string"); return FALSE; } + Stream_Seek(s, cbAlternateShell); } + Stream_Seek(s, 2); - if (Stream_GetRemainingLength(s) < (size_t) (cbWorkingDir + 2)) + if (Stream_GetRemainingLength(s) < (size_t)(cbWorkingDir + 2)) return FALSE; if (cbWorkingDir > 0) @@ -581,19 +590,24 @@ WLog_ERR(TAG, "protocol error: invalid cbWorkingDir value: %"PRIu16"", cbWorkingDir); return FALSE; } + wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbWorkingDir / 2]) { WLog_ERR(TAG, "protocol error: WorkingDir must be null terminated"); return FALSE; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->ShellWorkingDirectory, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert AlternateShell string"); return FALSE; } + Stream_Seek(s, cbWorkingDir); } + Stream_Seek(s, 2); if (settings->RdpVersion >= 5) @@ -609,7 +623,7 @@ * @param settings settings */ -void rdp_write_info_packet(rdpRdp* rdp, wStream* s) +static void rdp_write_info_packet(rdpRdp* rdp, wStream* s) { UINT32 flags; WCHAR* domainW = NULL; @@ -624,11 +638,9 @@ int cbWorkingDir = 0; BOOL usedPasswordCookie = FALSE; rdpSettings* settings = rdp->settings; - flags = INFO_MOUSE | INFO_UNICODE | INFO_LOGONERRORS | - INFO_LOGONNOTIFY | INFO_MAXIMIZESHELL | INFO_ENABLEWINDOWSKEY | INFO_DISABLECTRLALTDEL; @@ -660,6 +672,9 @@ flags |= ((settings->CompressionLevel << 9) & 0x00001E00); } + if (settings->LogonNotify) + flags |= INFO_LOGONNOTIFY; + if (settings->Domain) { cbDomain = ConvertToUnicode(CP_UTF8, 0, settings->Domain, -1, &domainW, 0) * 2; @@ -701,7 +716,8 @@ if (!settings->RemoteAssistanceMode) { - cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, settings->AlternateShell, -1, &alternateShellW, 0) * 2; + cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, settings->AlternateShell, -1, &alternateShellW, + 0) * 2; } else { @@ -713,23 +729,25 @@ else { /* This field must contain the remote assistance password */ - cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistancePassword, -1, &alternateShellW, 0) * 2; + cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistancePassword, -1, + &alternateShellW, 0) * 2; } } if (!settings->RemoteAssistanceMode) { - cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->ShellWorkingDirectory, -1, &workingDirW, 0) * 2; + cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->ShellWorkingDirectory, -1, &workingDirW, + 0) * 2; } else { /* Remote Assistance Session Id */ - cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistanceSessionId, -1, &workingDirW, 0) * 2; + cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistanceSessionId, -1, &workingDirW, + 0) * 2; } Stream_Write_UINT32(s, 0); /* CodePage (4 bytes) */ Stream_Write_UINT32(s, flags); /* flags (4 bytes) */ - Stream_Write_UINT16(s, cbDomain); /* cbDomain (2 bytes) */ Stream_Write_UINT16(s, cbUserName); /* cbUserName (2 bytes) */ Stream_Write_UINT16(s, cbPassword); /* cbPassword (2 bytes) */ @@ -738,24 +756,28 @@ if (cbDomain > 0) Stream_Write(s, domainW, cbDomain); + Stream_Write_UINT16(s, 0); if (cbUserName > 0) Stream_Write(s, userNameW, cbUserName); + Stream_Write_UINT16(s, 0); if (cbPassword > 0) Stream_Write(s, passwordW, cbPassword); + Stream_Write_UINT16(s, 0); if (cbAlternateShell > 0) Stream_Write(s, alternateShellW, cbAlternateShell); + Stream_Write_UINT16(s, 0); if (cbWorkingDir > 0) Stream_Write(s, workingDirW, cbWorkingDir); - Stream_Write_UINT16(s, 0); + Stream_Write_UINT16(s, 0); free(domainW); free(userNameW); free(alternateShellW); @@ -821,9 +843,7 @@ { wStream* s; BOOL status; - rdp->sec_flags |= SEC_INFO_PKT; - s = Stream_New(NULL, 2048); if (!s) @@ -833,22 +853,17 @@ } rdp_init_stream(rdp, s); - rdp_write_info_packet(rdp, s); - status = rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID); - Stream_Free(s, TRUE); - return status; } -BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s, logon_info *info) +static BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s, logon_info* info) { UINT32 cbDomain; UINT32 cbUserName; WCHAR* wstr; - ZeroMemory(info, sizeof(*info)); if (Stream_GetRemainingLength(s) < 576) @@ -866,21 +881,23 @@ WLog_ERR(TAG, "protocol error: invalid cbDomain value: %"PRIu32"", cbDomain); goto fail; } + wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbDomain / 2 - 1]) { WLog_ERR(TAG, "protocol error: Domain must be null terminated"); goto fail; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &info->domain, 0, NULL, FALSE) < 1) { WLog_ERR(TAG, "failed to convert the Domain string"); goto fail; } } - Stream_Seek(s, 52); /* domain (52 bytes) */ - + Stream_Seek(s, 52); /* domain (52 bytes) */ Stream_Read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */ /* cbUserName is the size of the Unicode character data (including the mandatory @@ -893,27 +910,27 @@ WLog_ERR(TAG, "protocol error: invalid cbUserName value: %"PRIu32"", cbUserName); goto fail; } + wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbUserName / 2 - 1]) { WLog_ERR(TAG, "protocol error: UserName must be null terminated"); goto fail; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &info->username, 0, NULL, FALSE) < 1) { WLog_ERR(TAG, "failed to convert the UserName string"); goto fail; } } - Stream_Seek(s, 512); /* userName (512 bytes) */ + Stream_Seek(s, 512); /* userName (512 bytes) */ Stream_Read_UINT32(s, info->sessionId); /* SessionId (4 bytes) */ - WLog_DBG(TAG, "LogonInfoV1: SessionId: 0x%08"PRIX32" UserName: [%s] Domain: [%s]", - info->sessionId, info->username, info->domain); - + info->sessionId, info->username, info->domain); return TRUE; - fail: free(info->username); info->username = NULL; @@ -922,14 +939,13 @@ return FALSE; } -BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info *info) +static BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info* info) { UINT16 Version; UINT32 Size; UINT32 cbDomain; UINT32 cbUserName; WCHAR* wstr; - ZeroMemory(info, sizeof(*info)); if (Stream_GetRemainingLength(s) < 576) @@ -942,7 +958,6 @@ Stream_Read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */ Stream_Seek(s, 558); /* pad (558 bytes) */ - /* cbDomain is the size in bytes of the Unicode character data in the Domain field. * The size of the mandatory null terminator is include in this value. * Note: Since MS-RDPBCGR 2.2.10.1.1.2 does not mention any size limits we assume @@ -956,23 +971,28 @@ WLog_ERR(TAG, "protocol error: invalid cbDomain value: %"PRIu32"", cbDomain); goto fail; } + if (Stream_GetRemainingLength(s) < (size_t) cbDomain) { WLog_ERR(TAG, "insufficient remaining stream length"); goto fail; } + wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbDomain / 2 - 1]) { WLog_ERR(TAG, "protocol error: Domain field must be null terminated"); goto fail; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &info->domain, 0, NULL, FALSE) < 1) { WLog_ERR(TAG, "failed to convert the Domain string"); goto fail; } } + Stream_Seek(s, cbDomain); /* domain */ /* cbUserName is the size in bytes of the Unicode character data in the UserName field. @@ -988,30 +1008,32 @@ WLog_ERR(TAG, "protocol error: invalid cbUserName value: %"PRIu32"", cbUserName); goto fail; } + if (Stream_GetRemainingLength(s) < (size_t) cbUserName) { WLog_ERR(TAG, "insufficient remaining stream length"); goto fail; } + wstr = (WCHAR*) Stream_Pointer(s); + if (wstr[cbUserName / 2 - 1]) { WLog_ERR(TAG, "protocol error: UserName field must be null terminated"); goto fail; } + if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &info->username, 0, NULL, FALSE) < 1) { WLog_ERR(TAG, "failed to convert the Domain string"); goto fail; } } - Stream_Seek(s, cbUserName); /* userName */ + Stream_Seek(s, cbUserName); /* userName */ WLog_DBG(TAG, "LogonInfoV2: SessionId: 0x%08"PRIX32" UserName: [%s] Domain: [%s]", - info->sessionId, info->username, info->domain); - + info->sessionId, info->username, info->domain); return TRUE; - fail: free(info->username); info->username = NULL; @@ -1020,19 +1042,17 @@ return FALSE; } -BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, wStream* s) +static BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, wStream* s) { if (Stream_GetRemainingLength(s) < 576) return FALSE; Stream_Seek(s, 576); /* pad (576 bytes) */ - WLog_DBG(TAG, "LogonPlainNotify"); - return TRUE; } -BOOL rdp_recv_logon_error_info(rdpRdp* rdp, wStream* s, logon_info_ex *info) +static BOOL rdp_recv_logon_error_info(rdpRdp* rdp, wStream* s, logon_info_ex* info) { UINT32 errorNotificationType; UINT32 errorNotificationData; @@ -1042,18 +1062,15 @@ Stream_Read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */ Stream_Read_UINT32(s, errorNotificationData); /* errorNotificationData (4 bytes) */ - WLog_DBG(TAG, "LogonErrorInfo: Data: 0x%08"PRIX32" Type: 0x%08"PRIX32"", - errorNotificationData, errorNotificationType); - + errorNotificationData, errorNotificationType); IFCALL(rdp->instance->LogonErrorInfo, rdp->instance, errorNotificationData, errorNotificationType); - info->ErrorNotificationType = errorNotificationType; info->ErrorNotificationData = errorNotificationData; return TRUE; } -BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s, logon_info_ex *info) +static BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s, logon_info_ex* info) { UINT32 cbFieldData; UINT32 fieldsPresent; @@ -1090,6 +1107,7 @@ if (fieldsPresent & LOGON_EX_LOGONERRORS) { info->haveErrorInfo = TRUE; + if (Stream_GetRemainingLength(s) < 4) return FALSE; @@ -1106,7 +1124,6 @@ return FALSE; Stream_Seek(s, 570); /* pad (570 bytes) */ - return TRUE; } @@ -1116,8 +1133,8 @@ BOOL status; logon_info logonInfo; logon_info_ex logonInfoEx; - rdpContext *context = rdp->context; - rdpUpdate *update = rdp->context->update; + rdpContext* context = rdp->context; + rdpUpdate* update = rdp->context->update; if (Stream_GetRemainingLength(s) < 4) return FALSE; @@ -1129,8 +1146,10 @@ case INFO_TYPE_LOGON: ZeroMemory(&logonInfo, sizeof(logonInfo)); status = rdp_recv_logon_info_v1(rdp, s, &logonInfo); + if (status && update->SaveSessionInfo) status = update->SaveSessionInfo(context, infoType, &logonInfo); + free(logonInfo.domain); free(logonInfo.username); break; @@ -1138,23 +1157,29 @@ case INFO_TYPE_LOGON_LONG: ZeroMemory(&logonInfo, sizeof(logonInfo)); status = rdp_recv_logon_info_v2(rdp, s, &logonInfo); + if (status && update->SaveSessionInfo) status = update->SaveSessionInfo(context, infoType, &logonInfo); + free(logonInfo.domain); free(logonInfo.username); break; case INFO_TYPE_LOGON_PLAIN_NOTIFY: status = rdp_recv_logon_plain_notify(rdp, s); + if (status && update->SaveSessionInfo) status = update->SaveSessionInfo(context, infoType, NULL); + break; case INFO_TYPE_LOGON_EXTENDED_INF: ZeroMemory(&logonInfoEx, sizeof(logonInfoEx)); status = rdp_recv_logon_info_extended(rdp, s, &logonInfoEx); + if (status && update->SaveSessionInfo) status = update->SaveSessionInfo(context, infoType, &logonInfoEx); + break; default: @@ -1166,26 +1191,29 @@ if (!status) { WLog_DBG(TAG, "SaveSessionInfo error: infoType: %s (%"PRIu32")", - infoType < 4 ? INFO_TYPE_LOGON_STRINGS[infoType % 4] : "Unknown", infoType); + infoType < 4 ? INFO_TYPE_LOGON_STRINGS[infoType % 4] : "Unknown", infoType); } return status; } -static BOOL rdp_write_logon_info_v1(wStream *s, logon_info *info) +static BOOL rdp_write_logon_info_v1(wStream* s, logon_info* info) { int sz = 4 + 52 + 4 + 512 + 4; int len; - WCHAR *wString = NULL; + WCHAR* wString = NULL; if (!Stream_EnsureRemainingCapacity(s, sz)) return FALSE; /* domain */ len = ConvertToUnicode(CP_UTF8, 0, info->domain, -1, &wString, 0); + if (len < 0) return FALSE; + len *= 2; + if (len > 52) return FALSE; @@ -1193,13 +1221,14 @@ Stream_Write(s, wString, len); Stream_Seek(s, 52 - len); free(wString); - /* username */ len = ConvertToUnicode(CP_UTF8, 0, info->username, -1, &wString, 0); + if (len < 0) return FALSE; len *= 2; + if (len > 512) return FALSE; @@ -1207,18 +1236,16 @@ Stream_Write(s, wString, len); Stream_Seek(s, 512 - len); free(wString); - /* sessionId */ Stream_Write_UINT32(s, info->sessionId); - return TRUE; } -static BOOL rdp_write_logon_info_v2(wStream *s, logon_info *info) +static BOOL rdp_write_logon_info_v2(wStream* s, logon_info* info) { int Size = 2 + 4 + 4 + 4 + 4 + 558; int domainLen, usernameLen, len; - WCHAR *wString; + WCHAR* wString; if (!Stream_EnsureRemainingCapacity(s, Size)) return FALSE; @@ -1226,23 +1253,20 @@ Stream_Write_UINT16(s, SAVE_SESSION_PDU_VERSION_ONE); Stream_Write_UINT32(s, Size); Stream_Write_UINT32(s, info->sessionId); - domainLen = strlen(info->domain); Stream_Write_UINT32(s, (domainLen + 1) * 2); - usernameLen = strlen(info->username); Stream_Write_UINT32(s, (usernameLen + 1) * 2); - Stream_Seek(s, 558); - len = ConvertToUnicode(CP_UTF8, 0, info->domain, -1, &wString, 0); + if (len < 0) return FALSE; Stream_Write(s, wString, len * 2); free(wString); - len = ConvertToUnicode(CP_UTF8, 0, info->username, -1, &wString, 0); + if (len < 0) return FALSE; @@ -1251,7 +1275,7 @@ return TRUE; } -static BOOL rdp_write_logon_info_plain(wStream *s) +static BOOL rdp_write_logon_info_plain(wStream* s) { if (!Stream_EnsureRemainingCapacity(s, 576)) return FALSE; @@ -1260,7 +1284,7 @@ return TRUE; } -static BOOL rdp_write_logon_info_ex(wStream *s, logon_info_ex *info) +static BOOL rdp_write_logon_info_ex(wStream* s, logon_info_ex* info) { UINT32 FieldsPresent = 0; UINT16 Size = 2 + 4 + 570; @@ -1286,7 +1310,6 @@ if (info->haveCookie) { Stream_Write_UINT32(s, 28); /* cbFieldData (4 bytes) */ - Stream_Write_UINT32(s, 28); /* cbLen (4 bytes) */ Stream_Write_UINT32(s, AUTO_RECONNECT_VERSION_1); /* Version (4 bytes) */ Stream_Write_UINT32(s, info->LogonId); /* LogonId (4 bytes) */ @@ -1296,7 +1319,6 @@ if (info->haveErrorInfo) { Stream_Write_UINT32(s, 8); /* cbFieldData (4 bytes) */ - Stream_Write_UINT32(s, info->ErrorNotificationType); /* ErrorNotificationType (4 bytes) */ Stream_Write_UINT32(s, info->ErrorNotificationData); /* ErrorNotificationData (4 bytes) */ } @@ -1305,13 +1327,13 @@ return TRUE; } -BOOL rdp_send_save_session_info(rdpContext *context, UINT32 type, void *data) +BOOL rdp_send_save_session_info(rdpContext* context, UINT32 type, void* data) { - wStream *s; + wStream* s; BOOL status; - rdpRdp *rdp = context->rdp; - + rdpRdp* rdp = context->rdp; s = rdp_data_pdu_init(rdp); + if (!s) return FALSE; @@ -1319,27 +1341,32 @@ switch (type) { - case INFO_TYPE_LOGON: - status = rdp_write_logon_info_v1(s, (logon_info *)data); - break; - case INFO_TYPE_LOGON_LONG: - status = rdp_write_logon_info_v2(s, (logon_info *)data); - break; - case INFO_TYPE_LOGON_PLAIN_NOTIFY: - status = rdp_write_logon_info_plain(s); - break; - case INFO_TYPE_LOGON_EXTENDED_INF: - status = rdp_write_logon_info_ex(s, (logon_info_ex *)data); - break; - default: - WLog_ERR(TAG, "saveSessionInfo type 0x%"PRIx32" not handled", type); - status = FALSE; - break; + case INFO_TYPE_LOGON: + status = rdp_write_logon_info_v1(s, (logon_info*)data); + break; + + case INFO_TYPE_LOGON_LONG: + status = rdp_write_logon_info_v2(s, (logon_info*)data); + break; + + case INFO_TYPE_LOGON_PLAIN_NOTIFY: + status = rdp_write_logon_info_plain(s); + break; + + case INFO_TYPE_LOGON_EXTENDED_INF: + status = rdp_write_logon_info_ex(s, (logon_info_ex*)data); + break; + + default: + WLog_ERR(TAG, "saveSessionInfo type 0x%"PRIx32" not handled", type); + status = FALSE; + break; } if (status) status = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SAVE_SESSION_INFO, rdp->mcs->userId); else Stream_Free(s, TRUE); + return status; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/info.h freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/info.h --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/info.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/info.h 2017-03-03 08:39:24.000000000 +0000 @@ -58,16 +58,7 @@ #define SAVE_SESSION_PDU_VERSION_ONE 0x0001 - -FREERDP_LOCAL BOOL rdp_read_client_auto_reconnect_cookie(rdpRdp* rdp, - wStream* s); -FREERDP_LOCAL void rdp_write_client_auto_reconnect_cookie(rdpRdp* rdp, - wStream* s); FREERDP_LOCAL void rdp_write_auto_reconnect_cookie(rdpRdp* rdp, wStream* s); -FREERDP_LOCAL BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s); -FREERDP_LOCAL void rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s); -FREERDP_LOCAL BOOL rdp_read_info_packet(rdpRdp* rdp, wStream* s); -FREERDP_LOCAL void rdp_write_info_packet(rdpRdp* rdp, wStream* s); FREERDP_LOCAL BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s); FREERDP_LOCAL BOOL rdp_send_client_info(rdpRdp* rdp); FREERDP_LOCAL BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/peer.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/peer.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/peer.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/peer.c 2017-03-03 08:39:24.000000000 +0000 @@ -575,7 +575,7 @@ { WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_LICENSING - license_send_valid_client_error_packet() fail"); - return FALSE; + return -1; } rdp_server_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE); @@ -585,7 +585,9 @@ case CONNECTION_STATE_CAPABILITIES_EXCHANGE: if (!rdp->AwaitCapabilities) { - IFCALL(client->Capabilities, client); + + if (client->Capabilities && !client->Capabilities(client)) + return -1; if (!rdp_send_demand_active(rdp)) { diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/rdp.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/rdp.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/rdp.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/rdp.c 2017-03-03 08:39:24.000000000 +0000 @@ -1694,7 +1694,6 @@ winpr_Cipher_Free(rdp->fips_encrypt); winpr_Cipher_Free(rdp->fips_decrypt); freerdp_settings_free(rdp->settings); - freerdp_settings_free(rdp->settingsCopy); transport_free(rdp->transport); license_free(rdp->license); input_free(rdp->input); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/rdp.h freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/rdp.h --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/rdp.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/rdp.h 2017-03-03 08:39:24.000000000 +0000 @@ -175,7 +175,6 @@ BOOL resendFocus; BOOL deactivation_reactivation; BOOL AwaitCapabilities; - rdpSettings* settingsCopy; }; FREERDP_LOCAL BOOL rdp_read_security_header(wStream* s, UINT16* flags); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/settings.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/settings.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/settings.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/settings.c 2017-03-03 08:39:24.000000000 +0000 @@ -252,13 +252,28 @@ BOOL settings_get_computer_name(rdpSettings* settings) { - DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1; - CHAR computerName[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD nSize = 0; + CHAR* computerName; + + if (GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize) || (GetLastError() != ERROR_MORE_DATA) || + (nSize < 2)) + return FALSE; + + computerName = calloc(nSize, sizeof(CHAR)); + + if (!computerName) + return FALSE; if (!GetComputerNameExA(ComputerNameNetBIOS, computerName, &nSize)) + { + free(computerName); return FALSE; + } + + if (nSize > MAX_COMPUTERNAME_LENGTH) + computerName[MAX_COMPUTERNAME_LENGTH] = '\0'; - settings->ComputerName = _strdup(computerName); + settings->ComputerName = computerName; if (!settings->ComputerName) return FALSE; @@ -319,6 +334,7 @@ settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; settings->CompressionEnabled = TRUE; + settings->LogonNotify = TRUE; if (settings->ServerMode) settings->CompressionLevel = PACKET_COMPR_TYPE_RDP61; @@ -490,6 +506,7 @@ settings->GatewayUdpTransport = TRUE; settings->FastPathInput = TRUE; settings->FastPathOutput = TRUE; + settings->LongCredentialsSupported = TRUE; settings->FrameAcknowledge = 2; settings->MouseMotion = TRUE; settings->NSCodecColorLossLevel = 3; @@ -591,6 +608,7 @@ if (!settings->SettingsModified) goto out_fail; + settings->ActionScript = _strdup("~/.config/freerdp/action.sh"); return settings; out_fail: free(settings->HomePath); @@ -680,6 +698,7 @@ CHECKED_STRDUP(RemoteApplicationCmdLine); /* 2118 */ CHECKED_STRDUP(ImeFileName); /* 2628 */ CHECKED_STRDUP(DrivesToRedirect); /* 4290 */ + CHECKED_STRDUP(ActionScript); /** * Manual Code */ @@ -1080,6 +1099,7 @@ free(settings->DrivesToRedirect); free(settings->WindowTitle); free(settings->WmClass); + free(settings->ActionScript); freerdp_target_net_addresses_free(settings); freerdp_device_collection_free(settings); freerdp_static_channel_collection_free(settings); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/test/TestConnect.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/test/TestConnect.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/test/TestConnect.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/test/TestConnect.c 2017-03-03 08:39:24.000000000 +0000 @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -59,7 +60,7 @@ NULL }; int rc; - snprintf(arg1, 18, "/v:192.0.2.1:%d", port); + _snprintf(arg1, 18, "/v:192.0.2.1:%d", port); argv[1] = arg1; start = GetTickCount(); rc = runInstance(2, argv, NULL); @@ -97,7 +98,7 @@ }; int rc; struct testThreadArgs* args = arg; - snprintf(arg1, 18, "/v:192.0.2.1:%d", args->port); + _snprintf(arg1, 18, "/v:192.0.2.1:%d", args->port); argv[1] = arg1; rc = runInstance(2, argv, args->arg); @@ -165,7 +166,7 @@ static int testSuccess(int port) { int rc; - STARTUPINFO si; + STARTUPINFOA si; PROCESS_INFORMATION process; char arg1[] = "/v:127.0.0.1:XXXXX"; char* clientArgs[] = @@ -183,7 +184,7 @@ char* wpath = TESTING_SRC_DIRECTORY; char* exe = GetCombinedPath(path, "server"); char* wexe = GetCombinedPath(wpath, "server"); - snprintf(arg1, 18, "/v:127.0.0.1:%d", port); + _snprintf(arg1, 18, "/v:127.0.0.1:%d", port); clientArgs[1] = arg1; if (!exe || !wexe) @@ -237,7 +238,7 @@ return -2; } - snprintf(commandLine, commandLineLen, "%s --port=%d", exe, port); + _snprintf(commandLine, commandLineLen, "%s --port=%d", exe, port); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); @@ -275,7 +276,9 @@ int TestConnect(int argc, char* argv[]) { int randomPort; - randomPort = 3389 + (random() % 200); + int random; + winpr_RAND((BYTE*)&random, sizeof(random)); + randomPort = 3389 + (random % 200); /* Test connect to not existing server, * check if timeout is honored. */ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/transport.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/transport.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/transport.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/transport.c 2017-03-03 08:39:24.000000000 +0000 @@ -59,17 +59,149 @@ static void* transport_client_thread(void* arg); +#ifdef WITH_KRB5 + +#include +#include +static UINT32 transport_krb5_check_account(rdpTransport* transport, char* username, char* domain, + char* passwd) +{ + krb5_error_code ret; + krb5_context context = NULL; + krb5_principal principal = NULL; + char address[256]; + krb5_ccache ccache; + krb5_init_creds_context ctx = NULL; + _snprintf(address, sizeof(address), "%s@%s", username, domain); + + /* Create a krb5 library context */ + if ((ret = krb5_init_context(&context)) != 0) + WLog_Print(transport->log, WLOG_ERROR, "krb5_init_context failed with error %d", (int)ret); + else if ((ret = krb5_parse_name_flags(context, address, 0, &principal)) != 0) + WLog_Print(transport->log, WLOG_ERROR, "krb5_parse_name_flags failed with error %d", (int)ret); + /* Find a credential cache with a specified client principal */ + else if ((ret = krb5_cc_cache_match(context, principal, &ccache)) != 0) + { + if ((ret = krb5_cc_default(context, &ccache)) != 0) + WLog_Print(transport->log, WLOG_ERROR, "krb5 failed to resolve credentials cache with error %d", + (int)ret); + } + + if (ret != KRB5KDC_ERR_NONE) + goto out; + /* Create a context for acquiring initial credentials */ + else if ((ret = krb5_init_creds_init(context, principal, NULL, NULL, 0, NULL, &ctx)) != 0) + { + WLog_Print(transport->log, WLOG_WARN, "krb5_init_creds_init returned error %d", (int)ret); + goto out; + } + /* Set a password for acquiring initial credentials */ + else if ((ret = krb5_init_creds_set_password(context, ctx, passwd)) != 0) + { + WLog_Print(transport->log, WLOG_WARN, "krb5_init_creds_set_password returned error %d", ret); + goto out; + } + + /* Acquire credentials using an initial credential context */ + ret = krb5_init_creds_get(context, ctx); +out: + + switch (ret) + { + case KRB5KDC_ERR_NONE: + break; + + case KRB5_KDC_UNREACH: + WLog_Print(transport->log, WLOG_WARN, "krb5_init_creds_get: KDC unreachable"); + ret = FREERDP_ERROR_CONNECT_KDC_UNREACHABLE; + break; + + case KRB5KRB_AP_ERR_BAD_INTEGRITY: + case KRB5KRB_AP_ERR_MODIFIED: + case KRB5KDC_ERR_PREAUTH_FAILED: + case KRB5_GET_IN_TKT_LOOP: + WLog_Print(transport->log, WLOG_WARN, "krb5_init_creds_get: Password incorrect"); + ret = FREERDP_ERROR_AUTHENTICATION_FAILED; + break; + + case KRB5KDC_ERR_KEY_EXP: + WLog_Print(transport->log, WLOG_WARN, "krb5_init_creds_get: Password has expired"); + ret = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED; + break; + + case KRB5KDC_ERR_CLIENT_REVOKED: + WLog_Print(transport->log, WLOG_WARN, "krb5_init_creds_get: Password revoked"); + ret = FREERDP_ERROR_CONNECT_CLIENT_REVOKED; + break; + + case KRB5KDC_ERR_POLICY: + ret = FREERDP_ERROR_INSUFFICIENT_PRIVILEGES; + break; + + default: + WLog_Print(transport->log, WLOG_WARN, "krb5_init_creds_get"); + ret = FREERDP_ERROR_CONNECT_TRANSPORT_FAILED; + break; + } + + if (ctx) + krb5_init_creds_free(context, ctx); + + krb5_free_context(context); + return ret; +} +#endif /* WITH_KRB5 */ static void transport_ssl_cb(SSL* ssl, int where, int ret) { - rdpTransport* transport; - - if ((where | SSL_CB_ALERT) && (ret == 561)) + if (where & SSL_CB_ALERT) { - transport = (rdpTransport*) SSL_get_app_data(ssl); + rdpTransport* transport = (rdpTransport*) SSL_get_app_data(ssl); + + switch (ret) + { + case (SSL3_AL_FATAL << 8) | SSL_AD_ACCESS_DENIED: + { + if (!freerdp_get_last_error(transport->context)) + { + freerdp_set_last_error(transport->context, FREERDP_ERROR_AUTHENTICATION_FAILED); + } + } + break; - if (!freerdp_get_last_error(transport->context)) - freerdp_set_last_error(transport->context, FREERDP_ERROR_AUTHENTICATION_FAILED); + case (SSL3_AL_FATAL << 8) | SSL_AD_INTERNAL_ERROR: + { + if (transport->NlaMode) + { + UINT32 kret = 0; +#ifdef WITH_KRB5 + + if ((strlen(transport->settings->Domain) != 0) && + (strncmp(transport->settings->Domain, ".", 1) != 0)) + { + kret = transport_krb5_check_account(transport, transport->settings->Username, + transport->settings->Domain, + transport->settings->Password); + } + else +#endif /* WITH_KRB5 */ + kret = FREERDP_ERROR_CONNECT_PASSWORD_CERTAINLY_EXPIRED; + + if (!freerdp_get_last_error(transport->context)) + freerdp_set_last_error(transport->context, kret); + } + + break; + + case (SSL3_AL_WARNING << 8) | SSL3_AD_CLOSE_NOTIFY: + break; + + default: + WLog_Print(transport->log, WLOG_WARN, "Unhandled SSL error (where=%d, ret=%d [%s, %s])", where, ret, + SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret)); + break; + } + } } } @@ -165,7 +297,7 @@ if (!transport->frontBio) { - WLog_ERR(TAG, "unable to prepend a filtering TLS bio"); + WLog_Print(transport->log, WLOG_ERROR, "unable to prepend a filtering TLS bio"); return FALSE; } @@ -289,14 +421,14 @@ { if (!(transport->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { - WLog_ERR(TAG, "Failed to create transport stop event"); + WLog_Print(transport->log, WLOG_ERROR, "Failed to create transport stop event"); return FALSE; } if (!(transport->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL))) { - WLog_ERR(TAG, "Failed to create transport client thread"); + WLog_Print(transport->log, WLOG_ERROR, "Failed to create transport client thread"); CloseHandle(transport->stopEvent); transport->stopEvent = NULL; return FALSE; @@ -357,7 +489,7 @@ if (nla_authenticate(transport->nla) < 0) { - WLog_ERR(TAG, "client authentication failure"); + WLog_Print(transport->log, WLOG_ERROR, "client authentication failure"); transport_set_nla_mode(transport, FALSE); nla_free(transport->nla); transport->nla = NULL; @@ -372,32 +504,26 @@ return TRUE; } -#define WLog_ERR_BIO(tag, biofunc, bio) \ - transport_bio_error_log(tag, biofunc, bio, __FILE__, __FUNCTION__, __LINE__) +#define WLog_ERR_BIO(transport, biofunc, bio) \ + transport_bio_error_log(transport, biofunc, bio, __FILE__, __FUNCTION__, __LINE__) -static void transport_bio_error_log(LPCSTR tag, LPCSTR biofunc, BIO* bio, +static void transport_bio_error_log(rdpTransport* transport, LPCSTR biofunc, BIO* bio, LPCSTR file, LPCSTR func, DWORD line) { unsigned long sslerr; char* buf; - wLog* log; int saveerrno; DWORD level; saveerrno = errno; - log = WLog_Get(tag); - - if (!log) - return; - level = WLOG_ERROR; - if (level < WLog_GetLogLevel(log)) + if (level < WLog_GetLogLevel(transport->log)) return; if (ERR_peek_error() == 0) { const char* fmt = "%s returned a system error %d: %s"; - WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, level, line, file, func, fmt, biofunc, + WLog_PrintMessage(transport->log, WLOG_MESSAGE_TEXT, level, line, file, func, fmt, biofunc, saveerrno, strerror(saveerrno)); return; } @@ -411,7 +537,7 @@ while ((sslerr = ERR_get_error())) { ERR_error_string_n(sslerr, buf, 120); - WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, level, line, file, func, fmt, biofunc, + WLog_PrintMessage(transport->log, WLOG_MESSAGE_TEXT, level, line, file, func, fmt, biofunc, buf); } @@ -441,11 +567,11 @@ /* something unexpected happened, let's close */ if (!transport->frontBio) { - WLog_ERR(TAG, "BIO_read: transport->frontBio null"); + WLog_Print(transport->log, WLOG_ERROR, "BIO_read: transport->frontBio null"); return -1; } - WLog_ERR_BIO(TAG, "BIO_read", transport->frontBio); + WLog_ERR_BIO(transport, "BIO_read", transport->frontBio); transport->layer = TRANSPORT_LAYER_CLOSED; return -1; } @@ -457,7 +583,7 @@ /* blocking means that we can't continue until we have read the number of requested bytes */ if (BIO_wait_read(transport->frontBio, 100) < 0) { - WLog_ERR_BIO(TAG, "BIO_wait_read", transport->frontBio); + WLog_ERR_BIO(transport, "BIO_wait_read", transport->frontBio); return -1; } @@ -519,7 +645,6 @@ int position; int pduLength; BYTE* header; - position = 0; pduLength = 0; if (!transport) @@ -581,7 +706,7 @@ } else { - WLog_ERR(TAG, "Error reading TSRequest!"); + WLog_Print(transport->log, WLOG_ERROR, "Error reading TSRequest!"); return -1; } } @@ -607,7 +732,7 @@ /* min and max values according to ITU-T Rec. T.123 (01/2007) section 8 */ if (pduLength < 7 || pduLength > 0xFFFF) { - WLog_ERR(TAG, "tpkt - invalid pduLength: %d", pduLength); + WLog_Print(transport->log, WLOG_ERROR, "tpkt - invalid pduLength: %d", pduLength); return -1; } } @@ -633,7 +758,7 @@ */ if (pduLength < 3 || pduLength > 0x8000) { - WLog_ERR(TAG, "fast path - invalid pduLength: %d", pduLength); + WLog_Print(transport->log, WLOG_ERROR, "fast path - invalid pduLength: %d", pduLength); return -1; } } @@ -649,7 +774,7 @@ return status; if (Stream_GetPosition(s) >= pduLength) - WLog_Packet(WLog_Get(TAG), WLOG_TRACE, Stream_Buffer(s), pduLength, + WLog_Packet(transport->log, WLOG_TRACE, Stream_Buffer(s), pduLength, WLOG_PACKET_INBOUND); Stream_SealLength(s); @@ -679,7 +804,7 @@ if (length > 0) { - WLog_Packet(WLog_Get(TAG), WLOG_TRACE, Stream_Buffer(s), length, + WLog_Packet(transport->log, WLOG_TRACE, Stream_Buffer(s), length, WLOG_PACKET_OUTBOUND); } @@ -695,20 +820,20 @@ */ if (!BIO_should_retry(transport->frontBio)) { - WLog_ERR_BIO(TAG, "BIO_should_retry", transport->frontBio); + WLog_ERR_BIO(transport, "BIO_should_retry", transport->frontBio); goto out_cleanup; } /* non-blocking can live with blocked IOs */ if (!transport->blocking) { - WLog_ERR_BIO(TAG, "BIO_write", transport->frontBio); + WLog_ERR_BIO(transport, "BIO_write", transport->frontBio); goto out_cleanup; } if (BIO_wait_write(transport->frontBio, 100) < 0) { - WLog_ERR_BIO(TAG, "BIO_wait_write", transport->frontBio); + WLog_ERR_BIO(transport, "BIO_wait_write", transport->frontBio); status = -1; goto out_cleanup; } @@ -722,14 +847,14 @@ { if (BIO_wait_write(transport->frontBio, 100) < 0) { - WLog_ERR(TAG, "error when selecting for write"); + WLog_Print(transport->log, WLOG_ERROR, "error when selecting for write"); status = -1; goto out_cleanup; } if (BIO_flush(transport->frontBio) < 1) { - WLog_ERR(TAG, "error when flushing outputBuffer"); + WLog_Print(transport->log, WLOG_ERROR, "error when flushing outputBuffer"); status = -1; goto out_cleanup; } @@ -764,7 +889,7 @@ { if (count < 1) { - WLog_ERR(TAG, "%s: provided handles array is too small", __FUNCTION__); + WLog_Print(transport->log, WLOG_ERROR, "%s: provided handles array is too small", __FUNCTION__); return 0; } @@ -779,14 +904,15 @@ { if (nCount > count) { - WLog_ERR(TAG, "%s: provided handles array is too small (count=%"PRIu32" nCount=%"PRIu32")", - __FUNCTION__, count, nCount); + WLog_Print(transport->log, WLOG_ERROR, + "%s: provided handles array is too small (count=%"PRIu32" nCount=%"PRIu32")", + __FUNCTION__, count, nCount); return 0; } if (BIO_get_event(transport->frontBio, &events[1]) != 1) { - WLog_ERR(TAG, "%s: error getting the frontBio handle", __FUNCTION__); + WLog_Print(transport->log, WLOG_ERROR, "%s: error getting the frontBio handle", __FUNCTION__); return 0; } } @@ -858,11 +984,13 @@ int recv_status; wStream* received; DWORD now = GetTickCount(); - DWORD dueDate = now + transport->settings->MaxTimeInCheckLoop; + DWORD dueDate = 0; if (!transport) return -1; + dueDate = now + transport->settings->MaxTimeInCheckLoop; + if (transport->haveMoreBytesToRead) { transport->haveMoreBytesToRead = FALSE; @@ -883,7 +1011,7 @@ if ((status = transport_read_pdu(transport, transport->ReceiveBuffer)) <= 0) { if (status < 0) - WLog_DBG(TAG, "transport_check_fds: transport_read_pdu() - %i", status); + WLog_Print(transport->log, WLOG_DEBUG, "transport_check_fds: transport_read_pdu() - %i", status); return status; } @@ -911,8 +1039,8 @@ if (recv_status < 0) { - WLog_ERR(TAG, "transport_check_fds: transport->ReceiveCallback() - %i", - recv_status); + WLog_Print(transport->log, WLOG_ERROR, "transport_check_fds: transport->ReceiveCallback() - %i", + recv_status); return -1; } @@ -1011,7 +1139,7 @@ rdpTransport* transport = (rdpTransport*) arg; rdpContext* context = transport->context; rdpRdp* rdp = context->rdp; - WLog_DBG(TAG, "Asynchronous transport thread started"); + WLog_Print(transport->log, WLOG_DEBUG, "Asynchronous transport thread started"); nCount = 0; handles[nCount++] = transport->stopEvent; handles[nCount++] = transport->connectedEvent; @@ -1020,15 +1148,16 @@ switch (status) { case WAIT_OBJECT_0: - WLog_DBG(TAG, "stopEvent triggered"); + WLog_Print(transport->log, WLOG_DEBUG, "stopEvent triggered"); goto out; case WAIT_OBJECT_0 + 1: - WLog_DBG(TAG, "connectedEvent event triggered"); + WLog_Print(transport->log, WLOG_DEBUG, "connectedEvent event triggered"); break; default: - WLog_ERR(TAG, "WaitForMultipleObjects failed with status 0x%08"PRIX32"", status); + WLog_Print(transport->log, WLOG_ERROR, "WaitForMultipleObjects failed with status 0x%08"PRIX32"", + status); dwExitCode = 1; goto out; } @@ -1040,7 +1169,7 @@ if (!(nCountTmp = freerdp_get_event_handles(context, &handles[nCount], 64 - nCount))) { - WLog_ERR(TAG, "freerdp_get_event_handles failed"); + WLog_Print(transport->log, WLOG_ERROR, "freerdp_get_event_handles failed"); break; } @@ -1049,21 +1178,21 @@ if (transport->layer == TRANSPORT_LAYER_CLOSED) { - WLog_DBG(TAG, "TRANSPORT_LAYER_CLOSED"); + WLog_Print(transport->log, WLOG_DEBUG, "TRANSPORT_LAYER_CLOSED"); rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED); break; } if (status == WAIT_OBJECT_0) { - WLog_DBG(TAG, "stopEvent triggered"); + WLog_Print(transport->log, WLOG_DEBUG, "stopEvent triggered"); break; } else if (status > WAIT_OBJECT_0 && status < (WAIT_OBJECT_0 + nCount)) { if (!freerdp_check_event_handles(context)) { - WLog_ERR(TAG, "freerdp_check_event_handles()"); + WLog_Print(transport->log, WLOG_ERROR, "freerdp_check_event_handles()"); rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED); break; } @@ -1071,9 +1200,9 @@ else { if (status == WAIT_TIMEOUT) - WLog_ERR(TAG, "WaitForMultipleObjects returned WAIT_TIMEOUT"); + WLog_Print(transport->log, WLOG_ERROR, "WaitForMultipleObjects returned WAIT_TIMEOUT"); else - WLog_ERR(TAG, "WaitForMultipleObjects returned 0x%08"PRIX32"", status); + WLog_Print(transport->log, WLOG_ERROR, "WaitForMultipleObjects returned 0x%08"PRIX32"", status); dwExitCode = 1; break; @@ -1081,7 +1210,7 @@ } out: - WLog_DBG(TAG, "Terminating transport thread"); + WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread"); ExitThread(dwExitCode); return NULL; } @@ -1094,6 +1223,11 @@ if (!transport) return NULL; + transport->log = WLog_Get(TAG); + + if (!transport->log) + goto out_free_transport; + transport->context = context; transport->settings = context->settings; transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/transport.h freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/transport.h --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/core/transport.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/core/transport.h 2017-03-03 08:39:24.000000000 +0000 @@ -81,6 +81,7 @@ ULONG written; HANDLE rereadEvent; BOOL haveMoreBytesToRead; + wLog* log; }; FREERDP_LOCAL wStream* transport_send_stream_init(rdpTransport* transport, diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/freerdp.pc.in freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/freerdp.pc.in --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/freerdp.pc.in 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/freerdp.pc.in 2017-03-03 08:39:24.000000000 +0000 @@ -2,7 +2,7 @@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=${prefix}/@FREERDP_INCLUDE_DIR@ -libs=-lfreerdp +libs=-lfreerdp@FREERDP_API_VERSION@ Name: FreeRDP Description: FreeRDP: A Remote Desktop Protocol Implementation diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/gdi/bitmap.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/gdi/bitmap.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/gdi/bitmap.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/gdi/bitmap.c 2017-03-03 08:39:24.000000000 +0000 @@ -483,9 +483,9 @@ hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject; hDstBmp = (HGDI_BITMAP) hdcDest->selectedObject; - if (!freerdp_image_copy(hDstBmp->data, hdcDest->format, hDstBmp->scanline, + if (!freerdp_image_copy(hDstBmp->data, hDstBmp->format, hDstBmp->scanline, nXDest, nYDest, nWidth, nHeight, - hSrcBmp->data, hdcSrc->format, hSrcBmp->scanline, nXSrc, nYSrc, palette, FREERDP_FLIP_NONE)) + hSrcBmp->data, hSrcBmp->format, hSrcBmp->scanline, nXSrc, nYSrc, palette, FREERDP_FLIP_NONE)) return FALSE; break; @@ -494,9 +494,9 @@ hSrcBmp = (HGDI_BITMAP) hdcDest->selectedObject; hDstBmp = (HGDI_BITMAP) hdcDest->selectedObject; - if (!freerdp_image_copy(hDstBmp->data, hdcDest->format, hDstBmp->scanline, + if (!freerdp_image_copy(hDstBmp->data, hDstBmp->format, hDstBmp->scanline, nXDest, nYDest, nWidth, nHeight, - hSrcBmp->data, hdcSrc->format, hSrcBmp->scanline, nXSrc, nYSrc, palette, FREERDP_FLIP_NONE)) + hSrcBmp->data, hSrcBmp->format, hSrcBmp->scanline, nXSrc, nYSrc, palette, FREERDP_FLIP_NONE)) return FALSE; break; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/gdi/gdi.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/gdi/gdi.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/gdi/gdi.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/gdi/gdi.c 2017-03-03 08:39:24.000000000 +0000 @@ -322,13 +322,41 @@ INLINE BOOL gdi_decode_color(rdpGdi* gdi, const UINT32 srcColor, UINT32* color, UINT32* format) { - UINT32 SrcFormat = gdi_get_pixel_format(gdi->context->settings->ColorDepth); + UINT32 SrcFormat; + UINT32 ColorDepth; + + if (!gdi || !color || !gdi->context || !gdi->context->settings) + return FALSE; + + ColorDepth = gdi->context->settings->ColorDepth; + + switch (ColorDepth) + { + case 32: + case 24: + SrcFormat = PIXEL_FORMAT_BGR24; + break; + + case 16: + SrcFormat = PIXEL_FORMAT_RGB16; + break; + + case 15: + SrcFormat = PIXEL_FORMAT_RGB15; + break; + + case 8: + SrcFormat = PIXEL_FORMAT_RGB8; + break; + + default: + return FALSE; + } if (format) - *format = SrcFormat; + *format = gdi->dstFormat; - *color = ConvertColor(srcColor, SrcFormat, - gdi->dstFormat, &gdi->palette); + *color = ConvertColor(srcColor, SrcFormat, gdi->dstFormat, &gdi->palette); return TRUE; } @@ -340,12 +368,12 @@ UINT32 gdi_get_pixel_format(UINT32 bitsPerPixel) { - UINT32 format = PIXEL_FORMAT_XBGR32; + UINT32 format; switch (bitsPerPixel) { case 32: - format = PIXEL_FORMAT_ABGR32; + format = PIXEL_FORMAT_BGRA32; break; case 24: @@ -363,6 +391,11 @@ case 8: format = PIXEL_FORMAT_RGB8; break; + + default: + WLog_ERR(TAG, "Unsupported color depth %"PRIu32, bitsPerPixel); + format = 0; + break; } return format; @@ -417,15 +450,10 @@ const BITMAP_UPDATE* bitmapUpdate) { UINT32 index; - rdpGdi* gdi; - rdpCodecs* codecs; if (!context || !bitmapUpdate || !context->gdi || !context->codecs) return FALSE; - gdi = context->gdi; - codecs = context->codecs; - for (index = 0; index < bitmapUpdate->number; index++) { const BITMAP_DATA* bitmap = &(bitmapUpdate->rectangles[index]); @@ -1131,7 +1159,8 @@ if (!gdi || !gdi->primary) return FALSE; - if (gdi->width == width && gdi->height == height) + if (gdi->width == width && gdi->height == height && + (!buffer || gdi->primary_buffer == buffer)) return TRUE; if (gdi->drawing == gdi->primary) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/gdi/gfx.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/gdi/gfx.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/gdi/gfx.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/gdi/gfx.c 2017-03-03 08:39:24.000000000 +0000 @@ -208,10 +208,13 @@ UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; - surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) - return ERROR_INTERNAL_ERROR; + { + WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); + return ERROR_NOT_FOUND; + } if (!freerdp_image_copy(surface->data, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, @@ -245,10 +248,13 @@ { UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; - surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) - return ERROR_INTERNAL_ERROR; + { + WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); + return ERROR_NOT_FOUND; + } rfx_context_set_pixel_format(surface->codecs->rfx, cmd->format); @@ -283,10 +289,13 @@ UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; - surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) - return ERROR_INTERNAL_ERROR; + { + WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); + return ERROR_NOT_FOUND; + } rc = clear_decompress(surface->codecs->clear, cmd->data, cmd->length, cmd->width, cmd->height, @@ -328,10 +337,13 @@ BYTE* DstData = NULL; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; - surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) - return ERROR_INTERNAL_ERROR; + { + WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); + return ERROR_NOT_FOUND; + } DstData = surface->data; @@ -373,10 +385,13 @@ gdiGfxSurface* surface; RDPGFX_H264_METABLOCK* meta; RDPGFX_AVC420_BITMAP_STREAM* bs; - surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) - return ERROR_INTERNAL_ERROR; + { + WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); + return ERROR_NOT_FOUND; + } bs = (RDPGFX_AVC420_BITMAP_STREAM*) cmd->extra; @@ -429,10 +444,13 @@ RDPGFX_AVC420_BITMAP_STREAM* avc2; RDPGFX_H264_METABLOCK* meta2; RECTANGLE_16* regionRects = NULL; - surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) - return ERROR_INTERNAL_ERROR; + { + WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); + return ERROR_NOT_FOUND; + } bs = (RDPGFX_AVC444_BITMAP_STREAM*) cmd->extra; @@ -494,10 +512,13 @@ UINT32 color; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; - surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) - return ERROR_INTERNAL_ERROR; + { + WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); + return ERROR_NOT_FOUND; + } WLog_WARN(TAG, "TODO gdi_SurfaceCommand_Alpha: status: %"PRIu32"", status); /* fill with green for now to distinguish from the rest */ @@ -536,10 +557,13 @@ UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; - surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) - return ERROR_INTERNAL_ERROR; + { + WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); + return ERROR_NOT_FOUND; + } rc = progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId, @@ -700,7 +724,7 @@ } surface->scanline = gfx_align_scanline(surface->width * 4, 16); - surface->data = (BYTE*) calloc(1, surface->scanline * surface->height); + surface->data = (BYTE*) _aligned_malloc(surface->scanline * surface->height, 16); if (!surface->data) { @@ -731,7 +755,7 @@ { region16_uninit(&surface->invalidRegion); codecs = surface->codecs; - free(surface->data); + _aligned_free(surface->data); free(surface); } @@ -1051,6 +1075,7 @@ gfx->MapSurfaceToOutput = gdi_MapSurfaceToOutput; gfx->MapSurfaceToWindow = gdi_MapSurfaceToWindow; gfx->UpdateSurfaces = gdi_UpdateSurfaces; + PROFILER_CREATE(gfx->SurfaceProfiler, "GFX-PROFILER"); } void gdi_graphics_pipeline_uninit(rdpGdi* gdi, RdpgfxClientContext* gfx) @@ -1058,5 +1083,9 @@ region16_uninit(&(gdi->invalidRegion)); gdi->gfx = NULL; gfx->custom = NULL; + PROFILER_PRINT_HEADER; + PROFILER_PRINT(gfx->SurfaceProfiler); + PROFILER_PRINT_FOOTER; + PROFILER_FREE(gfx->SurfaceProfiler); } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/gdi/graphics.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/gdi/graphics.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/gdi/graphics.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/gdi/graphics.c 2017-03-03 08:39:24.000000000 +0000 @@ -136,12 +136,10 @@ { UINT32 SrcSize = length; UINT32 SrcFormat; - UINT32 bytesPerPixel; rdpGdi* gdi = context->gdi; bitmap->compressed = FALSE; bitmap->format = gdi->dstFormat; bitmap->length = DstWidth * DstHeight * GetBytesPerPixel(bitmap->format); - bytesPerPixel = GetBytesPerPixel(bpp); bitmap->data = (BYTE*) _aligned_malloc(bitmap->length, 16); if (!bitmap->data) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_colors.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_colors.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_colors.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_colors.c 2017-03-03 08:39:24.000000000 +0000 @@ -32,38 +32,38 @@ ((_v_) < (_l_) ? (_l_) : ((_v_) > (_h_) ? (_h_) : (_v_))) #endif /* !MINMAX */ /* ------------------------------------------------------------------------- */ -static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R( +static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_BGRX( const INT16* pSrc[3], UINT32 srcStep, - BYTE* pDst, UINT32 DstFormat, UINT32 dstStep, + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, const prim_size_t* roi) { UINT32 x, y; - INT16 R, G, B; - float Y, Cb, Cr; BYTE* pRGB = pDst; const INT16* pY = pSrc[0]; const INT16* pCb = pSrc[1]; const INT16* pCr = pSrc[2]; int srcPad = (srcStep - (roi->width * 2)) / 2; int dstPad = (dstStep - (roi->width * 4)) / 4; - fkt_writePixel writePixel = getPixelWriteFunction(DstFormat); const DWORD formatSize = GetBytesPerPixel(DstFormat); for (y = 0; y < roi->height; y++) { for (x = 0; x < roi->width; x++) { - Y = (float)(pY[0] + 4096); - Cb = (float)(pCb[0]); - Cr = (float)(pCr[0]); - R = ((INT16)(((Cr * 1.402525f) + Y + 16.0f)) >> 5); - G = ((INT16)((Y - (Cb * 0.343730f) - (Cr * 0.714401f) + 16.0f)) >> 5); - B = ((INT16)(((Cb * 1.769905f) + Y + 16.0f)) >> 5); - pRGB = (*writePixel)(pRGB, formatSize, DstFormat, CLIP(R), CLIP(G), - CLIP(B), 0xFF); - pY++; - pCb++; - pCr++; + INT16 R, G, B; + const INT32 divisor = 16; + const INT32 Y = ((*pY++) + 4096) << divisor; + const INT32 Cb = (*pCb++); + const INT32 Cr = (*pCr++); + const INT32 CrR = Cr * (INT32)(1.402525f * (1 << divisor)); + const INT32 CrG = Cr * (INT32)(0.714401f * (1 << divisor)); + const INT32 CbG = Cb * (INT32)(0.343730f * (1 << divisor)); + const INT32 CbB = Cb * (INT32)(1.769905f * (1 << divisor)); + R = ((INT16)((CrR + Y) >> divisor) >> 5); + G = ((INT16)((Y - CbG - CrG) >> divisor) >> 5); + B = ((INT16)((CbB + Y) >> divisor) >> 5); + pRGB = writePixelBGRX(pRGB, formatSize, DstFormat, CLIP(R), CLIP(G), + CLIP(B), 0xFF); } pY += srcPad; @@ -75,20 +75,18 @@ return PRIMITIVES_SUCCESS; } -static pstatus_t general_yCbCrToBGR_16s8u_P3AC4R( +static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_general( const INT16* pSrc[3], UINT32 srcStep, - BYTE* pDst, UINT32 DstFormat, UINT32 dstStep, + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, const prim_size_t* roi) { UINT32 x, y; - INT16 R, G, B; - float Y, Cb, Cr; BYTE* pRGB = pDst; const INT16* pY = pSrc[0]; const INT16* pCb = pSrc[1]; const INT16* pCr = pSrc[2]; - UINT32 srcPad = (srcStep - (roi->width * 2)) / 2; - UINT32 dstPad = (dstStep - (roi->width * 4)) / 4; + int srcPad = (srcStep - (roi->width * 2)) / 2; + int dstPad = (dstStep - (roi->width * 4)) / 4; fkt_writePixel writePixel = getPixelWriteFunction(DstFormat); const DWORD formatSize = GetBytesPerPixel(DstFormat); @@ -96,17 +94,20 @@ { for (x = 0; x < roi->width; x++) { - Y = (float)(pY[0] + 4096); - Cb = (float)(pCb[0]); - Cr = (float)(pCr[0]); - R = ((INT16)(((Cr * 1.402525f) + Y + 16.0f)) >> 5); - G = ((INT16)((Y - (Cb * 0.343730f) - (Cr * 0.714401f) + 16.0f)) >> 5); - B = ((INT16)(((Cb * 1.769905f) + Y + 16.0f)) >> 5); + INT16 R, G, B; + const INT32 divisor = 16; + const INT32 Y = ((*pY++) + 4096) << divisor; + const INT32 Cb = (*pCb++); + const INT32 Cr = (*pCr++); + const INT32 CrR = Cr * (INT32)(1.402525f * (1 << divisor)); + const INT32 CrG = Cr * (INT32)(0.714401f * (1 << divisor)); + const INT32 CbG = Cb * (INT32)(0.343730f * (1 << divisor)); + const INT32 CbB = Cb * (INT32)(1.769905f * (1 << divisor)); + R = ((INT16)((CrR + Y) >> divisor) >> 5); + G = ((INT16)((Y - CbG - CrG) >> divisor) >> 5); + B = ((INT16)((CbB + Y) >> divisor) >> 5); pRGB = (*writePixel)(pRGB, formatSize, DstFormat, CLIP(R), CLIP(G), CLIP(B), 0xFF); - pY++; - pCb++; - pCr++; } pY += srcPad; @@ -118,6 +119,22 @@ return PRIMITIVES_SUCCESS; } +static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R( + const INT16* pSrc[3], UINT32 srcStep, + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + const prim_size_t* roi) +{ + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return general_yCbCrToRGB_16s8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + + default: + return general_yCbCrToRGB_16s8u_P3AC4R_general(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} + /* ------------------------------------------------------------------------- */ static pstatus_t general_yCbCrToRGB_16s16s_P3P3( @@ -285,9 +302,9 @@ for (x = 0; x < width; x++) { - const BYTE R = *r++; - const BYTE G = *g++; - const BYTE B = *b++; + const BYTE R = CLIP(*r++); + const BYTE G = CLIP(*g++); + const BYTE B = CLIP(*b++); *dst++ = R; *dst++ = G; *dst++ = B; @@ -301,9 +318,9 @@ for (x = 0; x < width; x++) { - const BYTE R = *r++; - const BYTE G = *g++; - const BYTE B = *b++; + const BYTE R = CLIP(*r++); + const BYTE G = CLIP(*g++); + const BYTE B = CLIP(*b++); *dst++ = B; *dst++ = G; *dst++ = R; @@ -317,9 +334,9 @@ for (x = 0; x < width; x++) { - const BYTE R = *r++; - const BYTE G = *g++; - const BYTE B = *b++; + const BYTE R = CLIP(*r++); + const BYTE G = CLIP(*g++); + const BYTE B = CLIP(*b++); *dst++ = B; *dst++ = G; *dst++ = R; @@ -334,9 +351,9 @@ for (x = 0; x < width; x++) { - const BYTE R = *r++; - const BYTE G = *g++; - const BYTE B = *b++; + const BYTE R = CLIP(*r++); + const BYTE G = CLIP(*g++); + const BYTE B = CLIP(*b++); *dst++ = R; *dst++ = G; *dst++ = B; @@ -351,9 +368,9 @@ for (x = 0; x < width; x++) { - const BYTE R = *r++; - const BYTE G = *g++; - const BYTE B = *b++; + const BYTE R = CLIP(*r++); + const BYTE G = CLIP(*g++); + const BYTE B = CLIP(*b++); *dst++ = 0xFF; *dst++ = B; *dst++ = G; @@ -368,9 +385,9 @@ for (x = 0; x < width; x++) { - const BYTE R = *r++; - const BYTE G = *g++; - const BYTE B = *b++; + const BYTE R = CLIP(*r++); + const BYTE G = CLIP(*g++); + const BYTE B = CLIP(*b++); *dst++ = 0xFF; *dst++ = R; *dst++ = G; @@ -413,7 +430,7 @@ } /* ------------------------------------------------------------------------- */ -static pstatus_t general_RGBToRGB_16s8u_P3AC4R( +static pstatus_t general_RGBToRGB_16s8u_P3AC4R_general( const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ UINT32 srcStep, /* bytes between rows in source data */ BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ @@ -441,11 +458,55 @@ return PRIMITIVES_SUCCESS; } +static pstatus_t general_RGBToRGB_16s8u_P3AC4R_BGRX( + const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ + UINT32 srcStep, /* bytes between rows in source data */ + BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ + UINT32 dstStep, /* bytes between rows in dest data */ + UINT32 DstFormat, + const prim_size_t* roi) /* region of interest */ +{ + const INT16* r = pSrc[0]; + const INT16* g = pSrc[1]; + const INT16* b = pSrc[2]; + UINT32 y; + const DWORD srcAdd = srcStep / sizeof(INT16); + const DWORD formatSize = GetBytesPerPixel(DstFormat); + + for (y = 0; y < roi->height; ++y) + { + writeScanlineBGRX(pDst, formatSize, DstFormat, r, g, b, roi->width); + pDst += dstStep; + r += srcAdd; + g += srcAdd; + b += srcAdd; + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t general_RGBToRGB_16s8u_P3AC4R( + const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ + UINT32 srcStep, /* bytes between rows in source data */ + BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ + UINT32 dstStep, /* bytes between rows in dest data */ + UINT32 DstFormat, + const prim_size_t* roi) /* region of interest */ +{ + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return general_RGBToRGB_16s8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + + default: + return general_RGBToRGB_16s8u_P3AC4R_general(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} /* ------------------------------------------------------------------------- */ void primitives_init_colors(primitives_t* prims) { prims->yCbCrToRGB_16s8u_P3AC4R = general_yCbCrToRGB_16s8u_P3AC4R; - prims->yCbCrToBGR_16s8u_P3AC4R = general_yCbCrToBGR_16s8u_P3AC4R; prims->yCbCrToRGB_16s16s_P3P3 = general_yCbCrToRGB_16s16s_P3P3; prims->RGBToYCbCr_16s16s_P3P3 = general_RGBToYCbCr_16s16s_P3P3; prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_colors_opt.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_colors_opt.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_colors_opt.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_colors_opt.c 2017-03-03 08:39:24.000000000 +0000 @@ -202,6 +202,414 @@ } /*---------------------------------------------------------------------------*/ +static pstatus_t sse2_yCbCrToRGB_16s8u_P3AC4R_BGRX( + const INT16* pSrc[3], UINT32 srcStep, + BYTE* pDst, UINT32 dstStep, + const prim_size_t* roi) /* region of interest */ +{ + const __m128i zero = _mm_setzero_si128(); + const __m128i max = _mm_set1_epi16(255); + const __m128i r_cr = _mm_set1_epi16(22986); /* 1.403 << 14 */ + const __m128i g_cb = _mm_set1_epi16(-5636); /* -0.344 << 14 */ + const __m128i g_cr = _mm_set1_epi16(-11698); /* -0.714 << 14 */ + const __m128i b_cb = _mm_set1_epi16(28999); /* 1.770 << 14 */ + const __m128i c4096 = _mm_set1_epi16(4096); + const INT16* y_buf = (INT16*)pSrc[0]; + const INT16* cb_buf = (INT16*)pSrc[1]; + const INT16* cr_buf = (INT16*)pSrc[2]; + const UINT32 pad = roi->width % 16; + const UINT32 step = sizeof(__m128i) / sizeof(INT16); + const UINT32 imax = (roi->width - pad) * sizeof(INT16) / sizeof(__m128i); + BYTE* d_buf = pDst; + int yp; + const size_t dstPad = (dstStep - roi->width * 4); +#ifdef DO_PREFETCH + + /* Prefetch Y's, Cb's, and Cr's. */ + for (yp = 0; yp < roi->height; yp++) + { + int i; + + for (i = 0; i < imax; + i += (CACHE_LINE_BYTES / sizeof(__m128i))) + { + _mm_prefetch((char*)(&((__m128i*)y_buf)[i]), _MM_HINT_NTA); + _mm_prefetch((char*)(&((__m128i*)cb_buf)[i]), _MM_HINT_NTA); + _mm_prefetch((char*)(&((__m128i*)cr_buf)[i]), _MM_HINT_NTA); + } + + y_buf += srcStep / sizeof(INT16); + cb_buf += srcStep / sizeof(INT16); + cr_buf += srcStep / sizeof(INT16); + } + + y_buf = (INT16*)pSrc[0]; + cb_buf = (INT16*)pSrc[1]; + cr_buf = (INT16*)pSrc[2]; +#endif /* DO_PREFETCH */ + + for (yp = 0; yp < roi->height; ++yp) + { + UINT32 i; + + for (i = 0; i < imax; i += 2) + { + /* In order to use SSE2 signed 16-bit integer multiplication + * we need to convert the floating point factors to signed int + * without losing information. + * The result of this multiplication is 32 bit and we have two + * SSE instructions that return either the hi or lo word. + * Thus we will multiply the factors by the highest possible 2^n, + * take the upper 16 bits of the signed 32-bit result + * (_mm_mulhi_epi16) and correct this result by multiplying + * it by 2^(16-n). + * + * For the given factors in the conversion matrix the best + * possible n is 14. + * + * Example for calculating r: + * r = (y>>5) + 128 + (cr*1.403)>>5 // our base formula + * r = (y>>5) + 128 + (HIWORD(cr*(1.403<<14)<<2))>>5 // see above + * r = (y+4096)>>5 + (HIWORD(cr*22986)<<2)>>5 // simplification + * r = ((y+4096)>>2 + HIWORD(cr*22986)) >> 3 + */ + /* y = (y_r_buf[i] + 4096) >> 2 */ + __m128i y1, y2, cb1, cb2, cr1, cr2, r1, r2, g1, g2, b1, b2; + y1 = _mm_load_si128((__m128i*)y_buf); + y_buf += step; + y1 = _mm_add_epi16(y1, c4096); + y1 = _mm_srai_epi16(y1, 2); + /* cb = cb_g_buf[i]; */ + cb1 = _mm_load_si128((__m128i*)cb_buf); + cb_buf += step; + /* cr = cr_b_buf[i]; */ + cr1 = _mm_load_si128((__m128i*)cr_buf); + cr_buf += step; + /* (y + HIWORD(cr*22986)) >> 3 */ + r1 = _mm_add_epi16(y1, _mm_mulhi_epi16(cr1, r_cr)); + r1 = _mm_srai_epi16(r1, 3); + /* r_buf[i] = CLIP(r); */ + _mm_between_epi16(r1, zero, max); + /* (y + HIWORD(cb*-5636) + HIWORD(cr*-11698)) >> 3 */ + g1 = _mm_add_epi16(y1, _mm_mulhi_epi16(cb1, g_cb)); + g1 = _mm_add_epi16(g1, _mm_mulhi_epi16(cr1, g_cr)); + g1 = _mm_srai_epi16(g1, 3); + /* g_buf[i] = CLIP(g); */ + _mm_between_epi16(g1, zero, max); + /* (y + HIWORD(cb*28999)) >> 3 */ + b1 = _mm_add_epi16(y1, _mm_mulhi_epi16(cb1, b_cb)); + b1 = _mm_srai_epi16(b1, 3); + /* b_buf[i] = CLIP(b); */ + _mm_between_epi16(b1, zero, max); + y2 = _mm_load_si128((__m128i*)y_buf); + y_buf += step; + y2 = _mm_add_epi16(y2, c4096); + y2 = _mm_srai_epi16(y2, 2); + /* cb = cb_g_buf[i]; */ + cb2 = _mm_load_si128((__m128i*)cb_buf); + cb_buf += step; + /* cr = cr_b_buf[i]; */ + cr2 = _mm_load_si128((__m128i*)cr_buf); + cr_buf += step; + /* (y + HIWORD(cr*22986)) >> 3 */ + r2 = _mm_add_epi16(y2, _mm_mulhi_epi16(cr2, r_cr)); + r2 = _mm_srai_epi16(r2, 3); + /* r_buf[i] = CLIP(r); */ + _mm_between_epi16(r2, zero, max); + /* (y + HIWORD(cb*-5636) + HIWORD(cr*-11698)) >> 3 */ + g2 = _mm_add_epi16(y2, _mm_mulhi_epi16(cb2, g_cb)); + g2 = _mm_add_epi16(g2, _mm_mulhi_epi16(cr2, g_cr)); + g2 = _mm_srai_epi16(g2, 3); + /* g_buf[i] = CLIP(g); */ + _mm_between_epi16(g2, zero, max); + /* (y + HIWORD(cb*28999)) >> 3 */ + b2 = _mm_add_epi16(y2, _mm_mulhi_epi16(cb2, b_cb)); + b2 = _mm_srai_epi16(b2, 3); + /* b_buf[i] = CLIP(b); */ + _mm_between_epi16(b2, zero, max); + { + __m128i R0, R1, R2, R3, R4; + /* The comments below pretend these are 8-byte registers + * rather than 16-byte, for readability. + */ + R0 = b1; /* R0 = 00B300B200B100B0 */ + R1 = b2; /* R1 = 00B700B600B500B4 */ + R0 = _mm_packus_epi16(R0, R1); /* R0 = B7B6B5B4B3B2B1B0 */ + R1 = g1; /* R1 = 00G300G200G100G0 */ + R2 = g2; /* R2 = 00G700G600G500G4 */ + R1 = _mm_packus_epi16(R1, R2); /* R1 = G7G6G5G4G3G2G1G0 */ + R2 = R1; /* R2 = G7G6G5G4G3G2G1G0 */ + R2 = _mm_unpacklo_epi8(R0, R2); /* R2 = B3G3B2G2B1G1B0G0 */ + R1 = _mm_unpackhi_epi8(R0, R1); /* R1 = B7G7B6G6B5G5B4G4 */ + R0 = r1; /* R0 = 00R300R200R100R0 */ + R3 = r2; /* R3 = 00R700R600R500R4 */ + R0 = _mm_packus_epi16(R0, R3); /* R0 = R7R6R5R4R3R2R1R0 */ + R3 = _mm_set1_epi32(0xFFFFFFFFU); /* R3 = FFFFFFFFFFFFFFFF */ + R4 = R3; /* R4 = FFFFFFFFFFFFFFFF */ + R4 = _mm_unpacklo_epi8(R0, R4); /* R4 = R3FFR2FFR1FFR0FF */ + R3 = _mm_unpackhi_epi8(R0, R3); /* R3 = R7FFR6FFR5FFR4FF */ + R0 = R4; /* R0 = R4 */ + R0 = _mm_unpacklo_epi16(R2, R0); /* R0 = B1G1R1FFB0G0R0FF */ + R4 = _mm_unpackhi_epi16(R2, R4); /* R4 = B3G3R3FFB2G2R2FF */ + R2 = R3; /* R2 = R3 */ + R2 = _mm_unpacklo_epi16(R1, R2); /* R2 = B5G5R5FFB4G4R4FF */ + R3 = _mm_unpackhi_epi16(R1, R3); /* R3 = B7G7R7FFB6G6R6FF */ + _mm_store_si128((__m128i*)d_buf, R0); /* B1G1R1FFB0G0R0FF */ + d_buf += sizeof(__m128i); + _mm_store_si128((__m128i*)d_buf, R4); /* B3G3R3FFB2G2R2FF */ + d_buf += sizeof(__m128i); + _mm_store_si128((__m128i*)d_buf, R2); /* B5G5R5FFB4G4R4FF */ + d_buf += sizeof(__m128i); + _mm_store_si128((__m128i*)d_buf, R3); /* B7G7R7FFB6G6R6FF */ + d_buf += sizeof(__m128i); + } + } + + for (i = 0; i < pad; i++) + { + const INT32 divisor = 16; + const INT32 Y = ((*y_buf++) + 4096) << divisor; + const INT32 Cb = (*cb_buf++); + const INT32 Cr = (*cr_buf++); + const INT32 CrR = Cr * (INT32)(1.402525f * (1 << divisor)); + const INT32 CrG = Cr * (INT32)(0.714401f * (1 << divisor)); + const INT32 CbG = Cb * (INT32)(0.343730f * (1 << divisor)); + const INT32 CbB = Cb * (INT32)(1.769905f * (1 << divisor)); + const INT16 R = ((INT16)((CrR + Y) >> divisor) >> 5); + const INT16 G = ((INT16)((Y - CbG - CrG) >> divisor) >> 5); + const INT16 B = ((INT16)((CbB + Y) >> divisor) >> 5); + *d_buf++ = CLIP(B); + *d_buf++ = CLIP(G); + *d_buf++ = CLIP(R); + *d_buf++ = 0xFF; + } + + d_buf += dstPad; + } + + return PRIMITIVES_SUCCESS; +} + +/*---------------------------------------------------------------------------*/ +static pstatus_t sse2_yCbCrToRGB_16s8u_P3AC4R_RGBX( + const INT16* pSrc[3], UINT32 srcStep, + BYTE* pDst, UINT32 dstStep, + const prim_size_t* roi) /* region of interest */ +{ + const __m128i zero = _mm_setzero_si128(); + const __m128i max = _mm_set1_epi16(255); + const __m128i r_cr = _mm_set1_epi16(22986); /* 1.403 << 14 */ + const __m128i g_cb = _mm_set1_epi16(-5636); /* -0.344 << 14 */ + const __m128i g_cr = _mm_set1_epi16(-11698); /* -0.714 << 14 */ + const __m128i b_cb = _mm_set1_epi16(28999); /* 1.770 << 14 */ + const __m128i c4096 = _mm_set1_epi16(4096); + const INT16* y_buf = (INT16*)pSrc[0]; + const INT16* cb_buf = (INT16*)pSrc[1]; + const INT16* cr_buf = (INT16*)pSrc[2]; + const UINT32 pad = roi->width % 16; + const UINT32 step = sizeof(__m128i) / sizeof(INT16); + const UINT32 imax = (roi->width - pad) * sizeof(INT16) / sizeof(__m128i); + BYTE* d_buf = pDst; + int yp; + const size_t dstPad = (dstStep - roi->width * 4); +#ifdef DO_PREFETCH + + /* Prefetch Y's, Cb's, and Cr's. */ + for (yp = 0; yp < roi->height; yp++) + { + int i; + + for (i = 0; i < imax; + i += (CACHE_LINE_BYTES / sizeof(__m128i))) + { + _mm_prefetch((char*)(&((__m128i*)y_buf)[i]), _MM_HINT_NTA); + _mm_prefetch((char*)(&((__m128i*)cb_buf)[i]), _MM_HINT_NTA); + _mm_prefetch((char*)(&((__m128i*)cr_buf)[i]), _MM_HINT_NTA); + } + + y_buf += srcStep / sizeof(INT16); + cb_buf += srcStep / sizeof(INT16); + cr_buf += srcStep / sizeof(INT16); + } + + y_buf = (INT16*)(pSrc[0]); + cb_buf = (INT16*)(pSrc[1]); + cr_buf = (INT16*)(pSrc[2]); +#endif /* DO_PREFETCH */ + + for (yp = 0; yp < roi->height; ++yp) + { + UINT32 i; + + for (i = 0; i < imax; i += 2) + { + /* In order to use SSE2 signed 16-bit integer multiplication + * we need to convert the floating point factors to signed int + * without losing information. + * The result of this multiplication is 32 bit and we have two + * SSE instructions that return either the hi or lo word. + * Thus we will multiply the factors by the highest possible 2^n, + * take the upper 16 bits of the signed 32-bit result + * (_mm_mulhi_epi16) and correct this result by multiplying + * it by 2^(16-n). + * + * For the given factors in the conversion matrix the best + * possible n is 14. + * + * Example for calculating r: + * r = (y>>5) + 128 + (cr*1.403)>>5 // our base formula + * r = (y>>5) + 128 + (HIWORD(cr*(1.403<<14)<<2))>>5 // see above + * r = (y+4096)>>5 + (HIWORD(cr*22986)<<2)>>5 // simplification + * r = ((y+4096)>>2 + HIWORD(cr*22986)) >> 3 + */ + /* y = (y_r_buf[i] + 4096) >> 2 */ + __m128i y1, y2, cb1, cb2, cr1, cr2, r1, r2, g1, g2, b1, b2; + y1 = _mm_load_si128((__m128i*)y_buf); + y_buf += step; + y1 = _mm_add_epi16(y1, c4096); + y1 = _mm_srai_epi16(y1, 2); + /* cb = cb_g_buf[i]; */ + cb1 = _mm_load_si128((__m128i*)cb_buf); + cb_buf += step; + /* cr = cr_b_buf[i]; */ + cr1 = _mm_load_si128((__m128i*)cr_buf); + cr_buf += step; + /* (y + HIWORD(cr*22986)) >> 3 */ + r1 = _mm_add_epi16(y1, _mm_mulhi_epi16(cr1, r_cr)); + r1 = _mm_srai_epi16(r1, 3); + /* r_buf[i] = CLIP(r); */ + _mm_between_epi16(r1, zero, max); + /* (y + HIWORD(cb*-5636) + HIWORD(cr*-11698)) >> 3 */ + g1 = _mm_add_epi16(y1, _mm_mulhi_epi16(cb1, g_cb)); + g1 = _mm_add_epi16(g1, _mm_mulhi_epi16(cr1, g_cr)); + g1 = _mm_srai_epi16(g1, 3); + /* g_buf[i] = CLIP(g); */ + _mm_between_epi16(g1, zero, max); + /* (y + HIWORD(cb*28999)) >> 3 */ + b1 = _mm_add_epi16(y1, _mm_mulhi_epi16(cb1, b_cb)); + b1 = _mm_srai_epi16(b1, 3); + /* b_buf[i] = CLIP(b); */ + _mm_between_epi16(b1, zero, max); + y2 = _mm_load_si128((__m128i*)y_buf); + y_buf += step; + y2 = _mm_add_epi16(y2, c4096); + y2 = _mm_srai_epi16(y2, 2); + /* cb = cb_g_buf[i]; */ + cb2 = _mm_load_si128((__m128i*)cb_buf); + cb_buf += step; + /* cr = cr_b_buf[i]; */ + cr2 = _mm_load_si128((__m128i*)cr_buf); + cr_buf += step; + /* (y + HIWORD(cr*22986)) >> 3 */ + r2 = _mm_add_epi16(y2, _mm_mulhi_epi16(cr2, r_cr)); + r2 = _mm_srai_epi16(r2, 3); + /* r_buf[i] = CLIP(r); */ + _mm_between_epi16(r2, zero, max); + /* (y + HIWORD(cb*-5636) + HIWORD(cr*-11698)) >> 3 */ + g2 = _mm_add_epi16(y2, _mm_mulhi_epi16(cb2, g_cb)); + g2 = _mm_add_epi16(g2, _mm_mulhi_epi16(cr2, g_cr)); + g2 = _mm_srai_epi16(g2, 3); + /* g_buf[i] = CLIP(g); */ + _mm_between_epi16(g2, zero, max); + /* (y + HIWORD(cb*28999)) >> 3 */ + b2 = _mm_add_epi16(y2, _mm_mulhi_epi16(cb2, b_cb)); + b2 = _mm_srai_epi16(b2, 3); + /* b_buf[i] = CLIP(b); */ + _mm_between_epi16(b2, zero, max); + { + __m128i R0, R1, R2, R3, R4; + /* The comments below pretend these are 8-byte registers + * rather than 16-byte, for readability. + */ + R0 = r1; /* R0 = 00R300R200R100R0 */ + R1 = r2; /* R1 = 00R700R600R500R4 */ + R0 = _mm_packus_epi16(R0, R1); /* R0 = R7R6R5R4R3R2R1R0 */ + R1 = g1; /* R1 = 00G300G200G100G0 */ + R2 = g2; /* R2 = 00G700G600G500G4 */ + R1 = _mm_packus_epi16(R1, R2); /* R1 = G7G6G5G4G3G2G1G0 */ + R2 = R1; /* R2 = G7G6G5G4G3G2G1G0 */ + R2 = _mm_unpacklo_epi8(R0, R2); /* R2 = R3G3R2G2R1G1R0G0 */ + R1 = _mm_unpackhi_epi8(R0, R1); /* R1 = R7G7R6G6R5G5R4G4 */ + R0 = b1; /* R0 = 00B300B200B100B0 */ + R3 = b2; /* R3 = 00B700B600B500B4 */ + R0 = _mm_packus_epi16(R0, R3); /* R0 = B7B6B5B4B3B2B1B0 */ + R3 = _mm_set1_epi32(0xFFFFFFFFU); /* R3 = FFFFFFFFFFFFFFFF */ + R4 = R3; /* R4 = FFFFFFFFFFFFFFFF */ + R4 = _mm_unpacklo_epi8(R0, R4); /* R4 = B3FFB2FFB1FFB0FF */ + R3 = _mm_unpackhi_epi8(R0, R3); /* R3 = B7FFB6FFB5FFB4FF */ + R0 = R4; /* R0 = R4 */ + R0 = _mm_unpacklo_epi16(R2, R0); /* R0 = R1G1B1FFR0G0B0FF */ + R4 = _mm_unpackhi_epi16(R2, R4); /* R4 = R3G3B3FFR2G2B2FF */ + R2 = R3; /* R2 = R3 */ + R2 = _mm_unpacklo_epi16(R1, R2); /* R2 = R5G5B5FFR4G4B4FF */ + R3 = _mm_unpackhi_epi16(R1, R3); /* R3 = R7G7B7FFR6G6B6FF */ + _mm_store_si128((__m128i*)d_buf, R0); /* R1G1B1FFR0G0B0FF */ + d_buf += sizeof(__m128i); + _mm_store_si128((__m128i*)d_buf, R4); /* R3G3B3FFR2G2B2FF */ + d_buf += sizeof(__m128i); + _mm_store_si128((__m128i*)d_buf, R2); /* R5G5B5FFR4G4B4FF */ + d_buf += sizeof(__m128i); + _mm_store_si128((__m128i*)d_buf, R3); /* R7G7B7FFR6G6B6FF */ + d_buf += sizeof(__m128i); + } + } + + for (i = 0; i < pad; i++) + { + const INT32 divisor = 16; + const INT32 Y = ((*y_buf++) + 4096) << divisor; + const INT32 Cb = (*cb_buf++); + const INT32 Cr = (*cr_buf++); + const INT32 CrR = Cr * (INT32)(1.402525f * (1 << divisor)); + const INT32 CrG = Cr * (INT32)(0.714401f * (1 << divisor)); + const INT32 CbG = Cb * (INT32)(0.343730f * (1 << divisor)); + const INT32 CbB = Cb * (INT32)(1.769905f * (1 << divisor)); + const INT16 R = ((INT16)((CrR + Y) >> divisor) >> 5); + const INT16 G = ((INT16)((Y - CbG - CrG) >> divisor) >> 5); + const INT16 B = ((INT16)((CbB + Y) >> divisor) >> 5); + *d_buf++ = CLIP(R); + *d_buf++ = CLIP(G); + *d_buf++ = CLIP(B); + *d_buf++ = 0xFF; + } + + d_buf += dstPad; + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t sse2_yCbCrToRGB_16s8u_P3AC4R( + const INT16* pSrc[3], UINT32 srcStep, + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + const prim_size_t* roi) /* region of interest */ +{ + if (((ULONG_PTR)(pSrc[0]) & 0x0f) + || ((ULONG_PTR)(pSrc[1]) & 0x0f) + || ((ULONG_PTR)(pSrc[2]) & 0x0f) + || ((ULONG_PTR)(pDst) & 0x0f) + || (srcStep & 0x0f) + || (dstStep & 0x0f)) + { + /* We can't maintain 16-byte alignment. */ + return generic->yCbCrToRGB_16s8u_P3AC4R(pSrc, srcStep, + pDst, dstStep, DstFormat, roi); + } + + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return sse2_yCbCrToRGB_16s8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, roi); + + case PIXEL_FORMAT_RGBA32: + case PIXEL_FORMAT_RGBX32: + return sse2_yCbCrToRGB_16s8u_P3AC4R_RGBX(pSrc, srcStep, pDst, dstStep, roi); + + default: + return generic->yCbCrToRGB_16s8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} /* The encodec YCbCr coeffectients are represented as 11.5 fixed-point * numbers. See the general code above. */ @@ -337,131 +745,463 @@ } /*---------------------------------------------------------------------------*/ -#define LOAD128(_src_) \ - _mm_load_si128((__m128i *) _src_) -#define STORE128(_dst_, _src_) \ - _mm_store_si128((__m128i *) _dst_, _src_) -#define PUNPCKLBW(_dst_, _src_) \ - _dst_ = _mm_unpacklo_epi8(_src_, _dst_) -#define PUNPCKHBW(_dst_, _src_) \ - _dst_ = _mm_unpackhi_epi8(_src_, _dst_) -#define PUNPCKLWD(_dst_, _src_) \ - _dst_ = _mm_unpacklo_epi16(_src_, _dst_) -#define PUNPCKHWD(_dst_, _src_) \ - _dst_ = _mm_unpackhi_epi16(_src_, _dst_) -#define PACKUSWB(_dst_, _src_) \ - _dst_ = _mm_packus_epi16(_dst_, _src_) -#define PREFETCH(_ptr_) \ - _mm_prefetch((const void *) _ptr_, _MM_HINT_T0) -#define XMM_ALL_ONES \ - _mm_set1_epi32(0xFFFFFFFFU) +static pstatus_t sse2_RGBToRGB_16s8u_P3AC4R_BGRX( + const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ + UINT32 srcStep, /* bytes between rows in source data */ + BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ + UINT32 dstStep, /* bytes between rows in dest data */ + const prim_size_t* roi) /* region of interest */ +{ + const UINT16* pr = (const UINT16*)(pSrc[0]); + const UINT16* pg = (const UINT16*)(pSrc[1]); + const UINT16* pb = (const UINT16*)(pSrc[2]); + const UINT32 pad = roi->width % 16; + const __m128i a = _mm_set1_epi32(0xFFFFFFFFU); + BYTE* out; + UINT32 srcbump, dstbump, y; + out = (BYTE*) pDst; + srcbump = (srcStep - (roi->width * sizeof(UINT16))) / sizeof(UINT16); + dstbump = (dstStep - (roi->width * sizeof(UINT32))); + + for (y = 0; y < roi->height; ++y) + { + UINT32 x; + + for (x = 0; x < roi->width - pad; x += 16) + { + __m128i r, g, b; + /* The comments below pretend these are 8-byte registers + * rather than 16-byte, for readability. + */ + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pb); + pb += 8; /* R0 = 00B300B200B100B0 */ + R1 = _mm_load_si128((__m128i*)pb); + pb += 8; /* R1 = 00B700B600B500B4 */ + b = _mm_packus_epi16(R0, R1); /* b = B7B6B5B4B3B2B1B0 */ + } + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pg); + pg += 8; /* R1 = 00G300G200G100G0 */ + R1 = _mm_load_si128((__m128i*)pg); + pg += 8; /* R2 = 00G700G600G500G4 */ + g = _mm_packus_epi16(R0, R1); /* g = G7G6G5G4G3G2G1G0 */ + } + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pr); + pr += 8; /* R0 = 00R300R200R100R0 */ + R1 = _mm_load_si128((__m128i*)pr); + pr += 8; /* R3 = 00R700R600R500R4 */ + r = _mm_packus_epi16(R0, R1); /* r = R7R6R5R4R3R2R1R0 */ + } + { + __m128i gbHi, gbLo, arHi, arLo; + { + gbLo = _mm_unpacklo_epi8(b, g); /* R0 = G7G6G5G4G3G2G1G0 */ + gbHi = _mm_unpackhi_epi8(b, g); /* R1 = G7B7G6B7G5B5G4B4 */ + arLo = _mm_unpacklo_epi8(r, a); /* R4 = FFR3FFR2FFR1FFR0 */ + arHi = _mm_unpackhi_epi8(r, a); /* R3 = FFR7FFR6FFR5FFR4 */ + } + { + const __m128i bgrx = _mm_unpacklo_epi16(gbLo, arLo); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR1G1B1FFR0G0B0 */ + } + { + const __m128i bgrx = _mm_unpackhi_epi16(gbLo, arLo); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR3G3B3FFR2G2B2 */ + } + { + const __m128i bgrx = _mm_unpacklo_epi16(gbHi, arHi); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR5G5B5FFR4G4B4 */ + } + { + const __m128i bgrx = _mm_unpackhi_epi16(gbHi, arHi); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR7G7B7FFR6G6B6 */ + } + } + } + + for (x = 0; x < pad; x++) + { + const BYTE R = CLIP(*pr++); + const BYTE G = CLIP(*pg++); + const BYTE B = CLIP(*pb++); + *out++ = B; + *out++ = G; + *out++ = R; + *out++ = 0xFF; + } + + /* Jump to next row. */ + pr += srcbump; + pg += srcbump; + pb += srcbump; + out += dstbump; + } -pstatus_t sse2_RGBToRGB_16s8u_P3AC4R( + return PRIMITIVES_SUCCESS; +} + +static pstatus_t sse2_RGBToRGB_16s8u_P3AC4R_RGBX( const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ UINT32 srcStep, /* bytes between rows in source data */ BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ UINT32 dstStep, /* bytes between rows in dest data */ - UINT32 DstFormat, const prim_size_t* roi) /* region of interest */ { - const UINT16* r = (const UINT16*)(pSrc[0]); - const UINT16* g = (const UINT16*)(pSrc[1]); - const UINT16* b = (const UINT16*)(pSrc[2]); + const UINT16* pr = (const UINT16*)(pSrc[0]); + const UINT16* pg = (const UINT16*)(pSrc[1]); + const UINT16* pb = (const UINT16*)(pSrc[2]); + const UINT32 pad = roi->width % 16; + const __m128i a = _mm_set1_epi32(0xFFFFFFFFU); BYTE* out; - int srcbump, dstbump, y; + UINT32 srcbump, dstbump, y; + out = (BYTE*) pDst; + srcbump = (srcStep - (roi->width * sizeof(UINT16))) / sizeof(UINT16); + dstbump = (dstStep - (roi->width * sizeof(UINT32))); - /* Ensure 16-byte alignment on all pointers, - * that width is a multiple of 8, - * and that the next row will also remain aligned. - * Since this is usually used for 64x64 aligned arrays, - * these checks should presumably pass. - */ - if ((((ULONG_PTR)(pSrc[0]) & 0x0f) != 0) - || (((ULONG_PTR)(pSrc[1]) & 0x0f) != 0) - || (((ULONG_PTR)(pSrc[2]) & 0x0f) != 0) - || (((ULONG_PTR) pDst & 0x0f) != 0) - || (roi->width & 0x0f) - || (srcStep & 0x0f) - || (dstStep & 0x0f)) + for (y = 0; y < roi->height; ++y) { - return generic->RGBToRGB_16s8u_P3AC4R(pSrc, srcStep, pDst, - dstStep, DstFormat, roi); + UINT32 x; + + for (x = 0; x < roi->width - pad; x += 16) + { + __m128i r, g, b; + /* The comments below pretend these are 8-byte registers + * rather than 16-byte, for readability. + */ + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pb); + pb += 8; /* R0 = 00B300B200B100B0 */ + R1 = _mm_load_si128((__m128i*)pb); + pb += 8; /* R1 = 00B700B600B500B4 */ + b = _mm_packus_epi16(R0, R1); /* b = B7B6B5B4B3B2B1B0 */ + } + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pg); + pg += 8; /* R1 = 00G300G200G100G0 */ + R1 = _mm_load_si128((__m128i*)pg); + pg += 8; /* R2 = 00G700G600G500G4 */ + g = _mm_packus_epi16(R0, R1); /* g = G7G6G5G4G3G2G1G0 */ + } + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pr); + pr += 8; /* R0 = 00R300R200R100R0 */ + R1 = _mm_load_si128((__m128i*)pr); + pr += 8; /* R3 = 00R700R600R500R4 */ + r = _mm_packus_epi16(R0, R1); /* r = R7R6R5R4R3R2R1R0 */ + } + { + __m128i gbHi, gbLo, arHi, arLo; + { + gbLo = _mm_unpacklo_epi8(r, g); /* R0 = G7G6G5G4G3G2G1G0 */ + gbHi = _mm_unpackhi_epi8(r, g); /* R1 = G7B7G6B7G5B5G4B4 */ + arLo = _mm_unpacklo_epi8(b, a); /* R4 = FFR3FFR2FFR1FFR0 */ + arHi = _mm_unpackhi_epi8(b, a); /* R3 = FFR7FFR6FFR5FFR4 */ + } + { + const __m128i bgrx = _mm_unpacklo_epi16(gbLo, arLo); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR1G1B1FFR0G0B0 */ + } + { + const __m128i bgrx = _mm_unpackhi_epi16(gbLo, arLo); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR3G3B3FFR2G2B2 */ + } + { + const __m128i bgrx = _mm_unpacklo_epi16(gbHi, arHi); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR5G5B5FFR4G4B4 */ + } + { + const __m128i bgrx = _mm_unpackhi_epi16(gbHi, arHi); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR7G7B7FFR6G6B6 */ + } + } + } + + for (x = 0; x < pad; x++) + { + const BYTE R = CLIP(*pr++); + const BYTE G = CLIP(*pg++); + const BYTE B = CLIP(*pb++); + *out++ = R; + *out++ = G; + *out++ = B; + *out++ = 0xFF; + } + + /* Jump to next row. */ + pr += srcbump; + pg += srcbump; + pb += srcbump; + out += dstbump; } - // TODO: Need to update SSE code to allow color conversion!!! - return generic->RGBToRGB_16s8u_P3AC4R(pSrc, srcStep, pDst, - dstStep, DstFormat, roi); + return PRIMITIVES_SUCCESS; +} + +static pstatus_t sse2_RGBToRGB_16s8u_P3AC4R_XBGR( + const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ + UINT32 srcStep, /* bytes between rows in source data */ + BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ + UINT32 dstStep, /* bytes between rows in dest data */ + const prim_size_t* roi) /* region of interest */ +{ + const UINT16* pr = (const UINT16*)(pSrc[0]); + const UINT16* pg = (const UINT16*)(pSrc[1]); + const UINT16* pb = (const UINT16*)(pSrc[2]); + const UINT32 pad = roi->width % 16; + const __m128i a = _mm_set1_epi32(0xFFFFFFFFU); + BYTE* out; + UINT32 srcbump, dstbump, y; out = (BYTE*) pDst; srcbump = (srcStep - (roi->width * sizeof(UINT16))) / sizeof(UINT16); dstbump = (dstStep - (roi->width * sizeof(UINT32))); for (y = 0; y < roi->height; ++y) { - int width = roi->width; + UINT32 x; - do + for (x = 0; x < roi->width - pad; x += 16) { - __m128i R0, R1, R2, R3, R4; + __m128i r, g, b; /* The comments below pretend these are 8-byte registers * rather than 16-byte, for readability. */ - R0 = LOAD128(b); - b += 8; /* R0 = 00B300B200B100B0 */ - R1 = LOAD128(b); - b += 8; /* R1 = 00B700B600B500B4 */ - PACKUSWB(R0, R1); /* R0 = B7B6B5B4B3B2B1B0 */ - R1 = LOAD128(g); - g += 8; /* R1 = 00G300G200G100G0 */ - R2 = LOAD128(g); - g += 8; /* R2 = 00G700G600G500G4 */ - PACKUSWB(R1, R2); /* R1 = G7G6G5G4G3G2G1G0 */ - R2 = R1; /* R2 = G7G6G5G4G3G2G1G0 */ - PUNPCKLBW(R2, R0); /* R2 = G3B3G2B2G1B1G0B0 */ - PUNPCKHBW(R1, R0); /* R1 = G7B7G6B7G5B5G4B4 */ - R0 = LOAD128(r); - r += 8; /* R0 = 00R300R200R100R0 */ - R3 = LOAD128(r); - r += 8; /* R3 = 00R700R600R500R4 */ - PACKUSWB(R0, R3); /* R0 = R7R6R5R4R3R2R1R0 */ - R3 = XMM_ALL_ONES; /* R3 = FFFFFFFFFFFFFFFF */ - R4 = R3; /* R4 = FFFFFFFFFFFFFFFF */ - PUNPCKLBW(R4, R0); /* R4 = FFR3FFR2FFR1FFR0 */ - PUNPCKHBW(R3, R0); /* R3 = FFR7FFR6FFR5FFR4 */ - R0 = R4; /* R0 = R4 */ - PUNPCKLWD(R0, R2); /* R0 = FFR1G1B1FFR0G0B0 */ - PUNPCKHWD(R4, R2); /* R4 = FFR3G3B3FFR2G2B2 */ - R2 = R3; /* R2 = R3 */ - PUNPCKLWD(R2, R1); /* R2 = FFR5G5B5FFR4G4B4 */ - PUNPCKHWD(R3, R1); /* R3 = FFR7G7B7FFR6G6B6 */ - STORE128(out, R0); - out += 16; /* FFR1G1B1FFR0G0B0 */ - STORE128(out, R4); - out += 16; /* FFR3G3B3FFR2G2B2 */ - STORE128(out, R2); - out += 16; /* FFR5G5B5FFR4G4B4 */ - STORE128(out, R3); - out += 16; /* FFR7G7B7FFR6G6B6 */ + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pb); + pb += 8; /* R0 = 00B300B200B100B0 */ + R1 = _mm_load_si128((__m128i*)pb); + pb += 8; /* R1 = 00B700B600B500B4 */ + b = _mm_packus_epi16(R0, R1); /* b = B7B6B5B4B3B2B1B0 */ + } + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pg); + pg += 8; /* R1 = 00G300G200G100G0 */ + R1 = _mm_load_si128((__m128i*)pg); + pg += 8; /* R2 = 00G700G600G500G4 */ + g = _mm_packus_epi16(R0, R1); /* g = G7G6G5G4G3G2G1G0 */ + } + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pr); + pr += 8; /* R0 = 00R300R200R100R0 */ + R1 = _mm_load_si128((__m128i*)pr); + pr += 8; /* R3 = 00R700R600R500R4 */ + r = _mm_packus_epi16(R0, R1); /* r = R7R6R5R4R3R2R1R0 */ + } + { + __m128i gbHi, gbLo, arHi, arLo; + { + gbLo = _mm_unpacklo_epi8(a, b); /* R0 = G7G6G5G4G3G2G1G0 */ + gbHi = _mm_unpackhi_epi8(a, b); /* R1 = G7B7G6B7G5B5G4B4 */ + arLo = _mm_unpacklo_epi8(g, r); /* R4 = FFR3FFR2FFR1FFR0 */ + arHi = _mm_unpackhi_epi8(g, r); /* R3 = FFR7FFR6FFR5FFR4 */ + } + { + const __m128i bgrx = _mm_unpacklo_epi16(gbLo, arLo); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR1G1B1FFR0G0B0 */ + } + { + const __m128i bgrx = _mm_unpackhi_epi16(gbLo, arLo); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR3G3B3FFR2G2B2 */ + } + { + const __m128i bgrx = _mm_unpacklo_epi16(gbHi, arHi); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR5G5B5FFR4G4B4 */ + } + { + const __m128i bgrx = _mm_unpackhi_epi16(gbHi, arHi); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR7G7B7FFR6G6B6 */ + } + } + } + + for (x = 0; x < pad; x++) + { + const BYTE R = CLIP(*pr++); + const BYTE G = CLIP(*pg++); + const BYTE B = CLIP(*pb++); + *out++ = 0xFF; + *out++ = B; + *out++ = G; + *out++ = R; + } + + /* Jump to next row. */ + pr += srcbump; + pg += srcbump; + pb += srcbump; + out += dstbump; + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t sse2_RGBToRGB_16s8u_P3AC4R_XRGB( + const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ + UINT32 srcStep, /* bytes between rows in source data */ + BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ + UINT32 dstStep, /* bytes between rows in dest data */ + const prim_size_t* roi) /* region of interest */ +{ + const UINT16* pr = (const UINT16*)(pSrc[0]); + const UINT16* pg = (const UINT16*)(pSrc[1]); + const UINT16* pb = (const UINT16*)(pSrc[2]); + const __m128i a = _mm_set1_epi32(0xFFFFFFFFU); + const UINT32 pad = roi->width % 16; + BYTE* out; + UINT32 srcbump, dstbump, y; + out = (BYTE*) pDst; + srcbump = (srcStep - (roi->width * sizeof(UINT16))) / sizeof(UINT16); + dstbump = (dstStep - (roi->width * sizeof(UINT32))); + + for (y = 0; y < roi->height; ++y) + { + UINT32 x; + + for (x = 0; x < roi->width - pad; x += 16) + { + __m128i r, g, b; + /* The comments below pretend these are 8-byte registers + * rather than 16-byte, for readability. + */ + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pb); + pb += 8; /* R0 = 00B300B200B100B0 */ + R1 = _mm_load_si128((__m128i*)pb); + pb += 8; /* R1 = 00B700B600B500B4 */ + b = _mm_packus_epi16(R0, R1); /* b = B7B6B5B4B3B2B1B0 */ + } + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pg); + pg += 8; /* R1 = 00G300G200G100G0 */ + R1 = _mm_load_si128((__m128i*)pg); + pg += 8; /* R2 = 00G700G600G500G4 */ + g = _mm_packus_epi16(R0, R1); /* g = G7G6G5G4G3G2G1G0 */ + } + { + __m128i R0, R1; + R0 = _mm_load_si128((__m128i*)pr); + pr += 8; /* R0 = 00R300R200R100R0 */ + R1 = _mm_load_si128((__m128i*)pr); + pr += 8; /* R3 = 00R700R600R500R4 */ + r = _mm_packus_epi16(R0, R1); /* r = R7R6R5R4R3R2R1R0 */ + } + { + __m128i gbHi, gbLo, arHi, arLo; + { + gbLo = _mm_unpacklo_epi8(a, r); /* R0 = G7G6G5G4G3G2G1G0 */ + gbHi = _mm_unpackhi_epi8(a, r); /* R1 = G7B7G6B7G5B5G4B4 */ + arLo = _mm_unpacklo_epi8(g, b); /* R4 = FFR3FFR2FFR1FFR0 */ + arHi = _mm_unpackhi_epi8(g, b); /* R3 = FFR7FFR6FFR5FFR4 */ + } + { + const __m128i bgrx = _mm_unpacklo_epi16(gbLo, arLo); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR1G1B1FFR0G0B0 */ + } + { + const __m128i bgrx = _mm_unpackhi_epi16(gbLo, arLo); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR3G3B3FFR2G2B2 */ + } + { + const __m128i bgrx = _mm_unpacklo_epi16(gbHi, arHi); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR5G5B5FFR4G4B4 */ + } + { + const __m128i bgrx = _mm_unpackhi_epi16(gbHi, arHi); + _mm_store_si128((__m128i*)out, bgrx); + out += 16; /* FFR7G7B7FFR6G6B6 */ + } + } + } + + for (x = 0; x < pad; x++) + { + const BYTE R = CLIP(*pr++); + const BYTE G = CLIP(*pg++); + const BYTE B = CLIP(*pb++); + *out++ = 0xFF; + *out++ = R; + *out++ = G; + *out++ = B; } - while (width -= 16); /* Jump to next row. */ - r += srcbump; - g += srcbump; - b += srcbump; + pr += srcbump; + pg += srcbump; + pb += srcbump; out += dstbump; } return PRIMITIVES_SUCCESS; } + +static pstatus_t sse2_RGBToRGB_16s8u_P3AC4R( + const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ + UINT32 srcStep, /* bytes between rows in source data */ + BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ + UINT32 dstStep, /* bytes between rows in dest data */ + UINT32 DstFormat, + const prim_size_t* roi) +{ + if (((ULONG_PTR)pSrc[0] & 0x0f) || ((ULONG_PTR)pSrc[1] & 0x0f) || ((ULONG_PTR)pSrc[2] & 0x0f) || + (srcStep & 0x0f) || ((ULONG_PTR)pDst & 0x0f) || (dstStep & 0x0f)) + return generic->RGBToRGB_16s8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return sse2_RGBToRGB_16s8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, roi); + + case PIXEL_FORMAT_RGBA32: + case PIXEL_FORMAT_RGBX32: + return sse2_RGBToRGB_16s8u_P3AC4R_RGBX(pSrc, srcStep, pDst, dstStep, roi); + + case PIXEL_FORMAT_ABGR32: + case PIXEL_FORMAT_XBGR32: + return sse2_RGBToRGB_16s8u_P3AC4R_XBGR(pSrc, srcStep, pDst, dstStep, roi); + + case PIXEL_FORMAT_ARGB32: + case PIXEL_FORMAT_XRGB32: + return sse2_RGBToRGB_16s8u_P3AC4R_XRGB(pSrc, srcStep, pDst, dstStep, roi); + + default: + return generic->RGBToRGB_16s8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} #endif /* WITH_SSE2 */ /*---------------------------------------------------------------------------*/ #ifdef WITH_NEON static pstatus_t neon_yCbCrToRGB_16s16s_P3P3( - const INT16* pSrc[3], - int srcStep, - INT16* pDst[3], - int dstStep, + const INT16* pSrc[3], INT32 srcStep, + INT16* pDst[3], INT32 dstStep, const prim_size_t* roi) /* region of interest */ { /* TODO: If necessary, check alignments and call the general version. */ @@ -545,9 +1285,241 @@ return PRIMITIVES_SUCCESS; } -#endif /* WITH_NEON */ +static pstatus_t neon_yCbCrToRGB_16s8u_P3AC4R_X( + const INT16* pSrc[3], UINT32 srcStep, + BYTE* pDst, UINT32 dstStep, + const prim_size_t* roi, + uint8_t rPos, + uint8_t gPos, + uint8_t bPos, + uint8_t aPos) +{ + UINT32 x, y; + BYTE* pRGB = pDst; + const INT16* pY = pSrc[0]; + const INT16* pCb = pSrc[1]; + const INT16* pCr = pSrc[2]; + const size_t srcPad = (srcStep - (roi->width * sizeof(INT16))) / sizeof(INT16); + const size_t dstPad = (dstStep - (roi->width * 4)) / 4; + const size_t pad = roi->width % 8; + const int16x4_t c4096 = vdup_n_s16(4096); + + for (y = 0; y < roi->height; y++) + { + for (x = 0; x < roi->width - pad; x += 8) + { + const int16x8_t Y = vld1q_s16(pY); + const int16x4_t Yh = vget_high_s16(Y); + const int16x4_t Yl = vget_low_s16(Y); + const int32x4_t YhAdd = vaddl_s16(Yh, c4096); /* Y + 4096 */ + const int32x4_t YlAdd = vaddl_s16(Yl, c4096); /* Y + 4096 */ + const int32x4_t YhW = vshlq_n_s32(YhAdd, 16); + const int32x4_t YlW = vshlq_n_s32(YlAdd, 16); + const int16x8_t Cr = vld1q_s16(pCr); + const int16x4_t Crh = vget_high_s16(Cr); + const int16x4_t Crl = vget_low_s16(Cr); + const int16x8_t Cb = vld1q_s16(pCb); + const int16x4_t Cbh = vget_high_s16(Cb); + const int16x4_t Cbl = vget_low_s16(Cb); + uint8x8x4_t bgrx; + { + /* R */ + const int32x4_t CrhR = vmulq_n_s32(vmovl_s16(Crh), 91916); /* 1.402525 * 2^16 */ + const int32x4_t CrlR = vmulq_n_s32(vmovl_s16(Crl), 91916); /* 1.402525 * 2^16 */ + const int32x4_t CrhRa = vaddq_s32(CrhR, YhW); + const int32x4_t CrlRa = vaddq_s32(CrlR, YlW); + const int16x4_t Rsh = vmovn_s32(vshrq_n_s32(CrhRa, 21)); + const int16x4_t Rsl = vmovn_s32(vshrq_n_s32(CrlRa, 21)); + const int16x8_t Rs = vcombine_s16(Rsl, Rsh); + bgrx.val[rPos] = vqmovun_s16(Rs); + } + { + /* G */ + const int32x4_t CbGh = vmull_n_s16(Cbh, 22527); /* 0.343730 * 2^16 */ + const int32x4_t CbGl = vmull_n_s16(Cbl, 22527); /* 0.343730 * 2^16 */ + const int32x4_t CrGh = vmulq_n_s32(vmovl_s16(Crh), 46819); /* 0.714401 * 2^16 */ + const int32x4_t CrGl = vmulq_n_s32(vmovl_s16(Crl), 46819); /* 0.714401 * 2^16 */ + const int32x4_t CbCrGh = vaddq_s32(CbGh, CrGh); + const int32x4_t CbCrGl = vaddq_s32(CbGl, CrGl); + const int32x4_t YCbCrGh = vsubq_s32(YhW, CbCrGh); + const int32x4_t YCbCrGl = vsubq_s32(YlW, CbCrGl); + const int16x4_t Gsh = vmovn_s32(vshrq_n_s32(YCbCrGh, 21)); + const int16x4_t Gsl = vmovn_s32(vshrq_n_s32(YCbCrGl, 21)); + const int16x8_t Gs = vcombine_s16(Gsl, Gsh); + const uint8x8_t G = vqmovun_s16(Gs); + bgrx.val[gPos] = G; + } + { + /* B */ + const int32x4_t CbBh = vmulq_n_s32(vmovl_s16(Cbh), 115992); /* 1.769905 * 2^16 */ + const int32x4_t CbBl = vmulq_n_s32(vmovl_s16(Cbl), 115992); /* 1.769905 * 2^16 */ + const int32x4_t YCbBh = vaddq_s32(CbBh, YhW); + const int32x4_t YCbBl = vaddq_s32(CbBl, YlW); + const int16x4_t Bsh = vmovn_s32(vshrq_n_s32(YCbBh, 21)); + const int16x4_t Bsl = vmovn_s32(vshrq_n_s32(YCbBl, 21)); + const int16x8_t Bs = vcombine_s16(Bsl, Bsh); + const uint8x8_t B = vqmovun_s16(Bs); + bgrx.val[bPos] = B; + } + /* A */ + { + bgrx.val[aPos] = vdup_n_u8(0xFF); + } + vst4_u8(pRGB, bgrx); + pY += 8; + pCb += 8; + pCr += 8; + pRGB += 32; + } + + for (x = 0; x < pad; x++) + { + const INT32 divisor = 16; + const INT32 Y = ((*pY++) + 4096) << divisor; + const INT32 Cb = (*pCb++); + const INT32 Cr = (*pCr++); + const INT32 CrR = Cr * (INT32)(1.402525f * (1 << divisor)); + const INT32 CrG = Cr * (INT32)(0.714401f * (1 << divisor)); + const INT32 CbG = Cb * (INT32)(0.343730f * (1 << divisor)); + const INT32 CbB = Cb * (INT32)(1.769905f * (1 << divisor)); + INT16 R = ((INT16)((CrR + Y) >> divisor) >> 5); + INT16 G = ((INT16)((Y - CbG - CrG) >> divisor) >> 5); + INT16 B = ((INT16)((CbB + Y) >> divisor) >> 5); + BYTE bgrx[4]; + bgrx[bPos] = CLIP(B); + bgrx[gPos] = CLIP(G); + bgrx[rPos] = CLIP(R); + bgrx[aPos] = 0xFF; + *pRGB++ = bgrx[0]; + *pRGB++ = bgrx[1]; + *pRGB++ = bgrx[2]; + *pRGB++ = bgrx[3]; + } + + pY += srcPad; + pCb += srcPad; + pCr += srcPad; + pRGB += dstPad; + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t neon_yCbCrToRGB_16s8u_P3AC4R( + const INT16* pSrc[3], UINT32 srcStep, + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + const prim_size_t* roi) +{ + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return neon_yCbCrToRGB_16s8u_P3AC4R_X(pSrc, srcStep, pDst, dstStep, roi, 2, 1, 0, 3); + + case PIXEL_FORMAT_RGBA32: + case PIXEL_FORMAT_RGBX32: + return neon_yCbCrToRGB_16s8u_P3AC4R_X(pSrc, srcStep, pDst, dstStep, roi, 0, 1, 2, 3); + + case PIXEL_FORMAT_ARGB32: + case PIXEL_FORMAT_XRGB32: + return neon_yCbCrToRGB_16s8u_P3AC4R_X(pSrc, srcStep, pDst, dstStep, roi, 1, 2, 3, 0); + + case PIXEL_FORMAT_ABGR32: + case PIXEL_FORMAT_XBGR32: + return neon_yCbCrToRGB_16s8u_P3AC4R_X(pSrc, srcStep, pDst, dstStep, roi, 3, 2, 1, 0); + + default: + return generic->yCbCrToRGB_16s8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} + +static pstatus_t neon_RGBToRGB_16s8u_P3AC4R_X( + const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ + UINT32 srcStep, /* bytes between rows in source data */ + BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ + UINT32 dstStep, /* bytes between rows in dest data */ + const prim_size_t* roi, /* region of interest */ + uint8_t rPos, + uint8_t gPos, + uint8_t bPos, + uint8_t aPos) +{ + UINT32 x, y; + UINT32 pad = roi->width % 8; + + for (y = 0; y < roi->height; y++) + { + const INT16* pr = (INT16*)(((BYTE*)pSrc[0]) + y * srcStep); + const INT16* pg = (INT16*)(((BYTE*)pSrc[1]) + y * srcStep); + const INT16* pb = (INT16*)(((BYTE*)pSrc[2]) + y * srcStep); + BYTE* dst = pDst + y * dstStep; + + for (x = 0; x < roi->width - pad; x += 8) + { + int16x8_t r = vld1q_s16(pr); + int16x8_t g = vld1q_s16(pg); + int16x8_t b = vld1q_s16(pb); + uint8x8x4_t bgrx; + bgrx.val[aPos] = vdup_n_u8(0xFF); + bgrx.val[rPos] = vqmovun_s16(r); + bgrx.val[gPos] = vqmovun_s16(g); + bgrx.val[bPos] = vqmovun_s16(b); + vst4_u8(dst, bgrx); + pr += 8; + pg += 8; + pb += 8; + dst += 32; + } + + for (x = 0; x < pad; x ++) + { + BYTE bgrx[4]; + bgrx[bPos] = *pb++; + bgrx[gPos] = *pg++; + bgrx[rPos] = *pr++; + bgrx[aPos] = 0xFF; + *dst++ = bgrx[0]; + *dst++ = bgrx[1]; + *dst++ = bgrx[2]; + *dst++ = bgrx[3]; + } + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t neon_RGBToRGB_16s8u_P3AC4R( + const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */ + UINT32 srcStep, /* bytes between rows in source data */ + BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */ + UINT32 dstStep, /* bytes between rows in dest data */ + UINT32 DstFormat, + const prim_size_t* roi) /* region of interest */ +{ + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return neon_RGBToRGB_16s8u_P3AC4R_X(pSrc, srcStep, pDst, dstStep, roi, 2, 1, 0, 3); + + case PIXEL_FORMAT_RGBA32: + case PIXEL_FORMAT_RGBX32: + return neon_RGBToRGB_16s8u_P3AC4R_X(pSrc, srcStep, pDst, dstStep, roi, 0, 1, 2, 3); + + case PIXEL_FORMAT_ARGB32: + case PIXEL_FORMAT_XRGB32: + return neon_RGBToRGB_16s8u_P3AC4R_X(pSrc, srcStep, pDst, dstStep, roi, 1, 2, 3, 0); + + case PIXEL_FORMAT_ABGR32: + case PIXEL_FORMAT_XBGR32: + return neon_RGBToRGB_16s8u_P3AC4R_X(pSrc, srcStep, pDst, dstStep, roi, 3, 2, 1, 0); + default: + return generic->RGBToRGB_16s8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} +#endif /* WITH_NEON */ /* I don't see a direct IPP version of this, since the input is INT16 * YCbCr. It may be possible via Deinterleave and then YCbCrToRGB_. * But that would likely be slower. @@ -564,6 +1536,7 @@ { prims->RGBToRGB_16s8u_P3AC4R = sse2_RGBToRGB_16s8u_P3AC4R; prims->yCbCrToRGB_16s16s_P3P3 = sse2_yCbCrToRGB_16s16s_P3P3; + prims->yCbCrToRGB_16s8u_P3AC4R = sse2_yCbCrToRGB_16s8u_P3AC4R; prims->RGBToYCbCr_16s16s_P3P3 = sse2_RGBToYCbCr_16s16s_P3P3; } @@ -571,6 +1544,8 @@ if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) { + prims->RGBToRGB_16s8u_P3AC4R = neon_RGBToRGB_16s8u_P3AC4R; + prims->yCbCrToRGB_16s8u_P3AC4R = neon_yCbCrToRGB_16s8u_P3AC4R; prims->yCbCrToRGB_16s16s_P3P3 = neon_yCbCrToRGB_16s16s_P3P3; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_internal.h freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_internal.h --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_internal.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_internal.h 2017-03-03 08:39:24.000000000 +0000 @@ -28,6 +28,15 @@ #include #include + +#ifdef __GNUC__ +#define PRIM_ALIGN_128 __attribute__((aligned(16))) +#else +#ifdef _WIN32 +#define PRIM_ALIGN_128 __declspec(align(16)) +#endif +#endif + /* Use lddqu for unaligned; load for 16-byte aligned. */ #define LOAD_SI128(_ptr_) \ (((ULONG_PTR) (_ptr_) & 0x0f) \ @@ -120,6 +129,47 @@ return X; } +/** + * | R | ( | 256 0 403 | | Y | ) + * | G | = ( | 256 -48 -120 | | U - 128 | ) >> 8 + * | B | ( | 256 475 0 | | V - 128 | ) + */ +static INLINE INT32 C(INT32 Y) +{ + return (Y) - 0L; +} + +static INLINE INT32 D(INT32 U) +{ + return (U) - 128L; +} + +static INLINE INT32 E(INT32 V) +{ + return (V) - 128L; +} + +static INLINE BYTE YUV2R(INT32 Y, INT32 U, INT32 V) +{ + const INT32 r = (256L * C(Y) + 0L * D(U) + 403L * E(V)); + const INT32 r8 = r >> 8L; + return CLIP(r8); +} + +static INLINE BYTE YUV2G(INT32 Y, INT32 U, INT32 V) +{ + const INT32 g = (256L * C(Y) - 48L * D(U) - 120L * E(V)); + const INT32 g8 = g >> 8L; + return CLIP(g8); +} + +static INLINE BYTE YUV2B(INT32 Y, INT32 U, INT32 V) +{ + const INT32 b = (256L * C(Y) + 475L * D(U) + 0L * E(V)); + const INT32 b8 = b >> 8L; + return CLIP(b8); +} + /* Function prototypes for all the init/deinit routines. */ FREERDP_LOCAL void primitives_init_copy(primitives_t* prims); FREERDP_LOCAL void primitives_init_set(primitives_t* prims); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_shift.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_shift.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_shift.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_shift.c 2017-03-03 08:39:24.000000000 +0000 @@ -22,7 +22,7 @@ #include "prim_internal.h" /* ------------------------------------------------------------------------- */ -static pstatus_t general_lShiftC_16s( +static INLINE pstatus_t general_lShiftC_16s( const INT16* pSrc, UINT32 val, INT16* pDst, @@ -36,7 +36,7 @@ } /* ------------------------------------------------------------------------- */ -static pstatus_t general_rShiftC_16s( +static INLINE pstatus_t general_rShiftC_16s( const INT16* pSrc, UINT32 val, INT16* pDst, @@ -50,7 +50,7 @@ } /* ------------------------------------------------------------------------- */ -static pstatus_t general_lShiftC_16u( +static INLINE pstatus_t general_lShiftC_16u( const UINT16* pSrc, UINT32 val, UINT16* pDst, @@ -64,7 +64,7 @@ } /* ------------------------------------------------------------------------- */ -static pstatus_t general_rShiftC_16u( +static INLINE pstatus_t general_rShiftC_16u( const UINT16* pSrc, UINT32 val, UINT16* pDst, @@ -78,7 +78,7 @@ } /* ------------------------------------------------------------------------- */ -static pstatus_t general_shiftC_16s( +static INLINE pstatus_t general_shiftC_16s( const INT16* pSrc, INT32 val, INT16* pDst, @@ -91,7 +91,7 @@ } /* ------------------------------------------------------------------------- */ -static pstatus_t general_shiftC_16u( +static INLINE pstatus_t general_shiftC_16u( const UINT16* pSrc, INT32 val, UINT16* pDst, diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_templates.h freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_templates.h --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_templates.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_templates.h 2017-03-03 08:39:24.000000000 +0000 @@ -46,7 +46,7 @@ #define SSE3_SCD_ROUTINE(_name_, _type_, _fallback_, _op_, _slowWay_) \ static pstatus_t _name_(const _type_ *pSrc, UINT32 val, _type_ *pDst, UINT32 len) \ { \ - INT32 shifts; \ + INT32 shifts = 0; \ UINT32 offBeatMask; \ const _type_ *sptr = pSrc; \ _type_ *dptr = pDst; \ @@ -190,7 +190,7 @@ #define SSE3_SCD_PRE_ROUTINE(_name_, _type_, _fallback_, _op_, _slowWay_) \ pstatus_t _name_(const _type_ *pSrc, _type_ val, _type_ *pDst, INT32 len) \ { \ - int shifts; \ + int shifts = 0; \ UINT32 offBeatMask; \ const _type_ *sptr = pSrc; \ _type_ *dptr = pDst; \ @@ -295,7 +295,7 @@ #define SSE3_SSD_ROUTINE(_name_, _type_, _fallback_, _op_, _slowWay_) \ pstatus_t _name_(const _type_ *pSrc1, const _type_ *pSrc2, _type_ *pDst, UINT32 len) \ { \ - int shifts; \ + int shifts = 0; \ UINT32 offBeatMask; \ const _type_ *sptr1 = pSrc1; \ const _type_ *sptr2 = pSrc2; \ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_YCoCg_opt.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_YCoCg_opt.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_YCoCg_opt.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_YCoCg_opt.c 2017-03-03 08:39:24.000000000 +0000 @@ -50,7 +50,7 @@ BYTE* dptr = (BYTE*) pDst; int sRowBump = srcStep - width * sizeof(UINT32); int dRowBump = dstStep - width * sizeof(UINT32); - UINT32 h; + UINT32 h; /* Shift left by "shift" and divide by two is the same as shift * left by "shift-1". */ @@ -70,28 +70,30 @@ { /* Too small, or we'll never hit a 16-byte boundary. Punt. */ return generic->YCoCgToRGB_8u_AC4R( - pSrc, srcStep, pDst, DstFormat, dstStep, - width, height, shift, withAlpha); + pSrc, srcStep, pDst, DstFormat, dstStep, + width, height, shift, withAlpha); } for (h = 0; h < height; h++) { - UINT32 w = width; + UINT32 w = width; BOOL onStride; /* Get to a 16-byte destination boundary. */ if ((ULONG_PTR) dptr & 0x0f) { pstatus_t status; - UINT32 startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4; + UINT32 startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4; if (startup > width) startup = width; status = generic->YCoCgToRGB_8u_AC4R( - sptr, srcStep, dptr, DstFormat, dstStep, - startup, 1, shift, withAlpha); + sptr, srcStep, dptr, DstFormat, dstStep, + startup, 1, shift, withAlpha); + if (status != PRIMITIVES_SUCCESS) return status; + sptr += startup * sizeof(UINT32); dptr += startup * sizeof(UINT32); w -= startup; @@ -201,8 +203,9 @@ { pstatus_t status; status = generic->YCoCgToRGB_8u_AC4R( - sptr, srcStep, dptr, DstFormat, dstStep, - w, 1, shift, withAlpha); + sptr, srcStep, dptr, DstFormat, dstStep, + w, 1, shift, withAlpha); + if (status != PRIMITIVES_SUCCESS) return status; @@ -229,7 +232,7 @@ BYTE* dptr = (BYTE*) pDst; int sRowBump = srcStep - width * sizeof(UINT32); int dRowBump = dstStep - width * sizeof(UINT32); - UINT32 h; + UINT32 h; /* Shift left by "shift" and divide by two is the same as shift * left by "shift-1". */ @@ -249,8 +252,8 @@ { /* Too small, or we'll never hit a 16-byte boundary. Punt. */ return generic->YCoCgToRGB_8u_AC4R( - pSrc, srcStep, pDst, DstFormat, dstStep, - width, height, shift, withAlpha); + pSrc, srcStep, pDst, DstFormat, dstStep, + width, height, shift, withAlpha); } for (h = 0; h < height; h++) @@ -262,13 +265,14 @@ if ((ULONG_PTR) dptr & 0x0f) { pstatus_t status; - UINT32 startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4; + UINT32 startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4; if (startup > width) startup = width; status = generic->YCoCgToRGB_8u_AC4R( - sptr, srcStep, dptr, DstFormat, - dstStep, startup, 1, shift, withAlpha); + sptr, srcStep, dptr, DstFormat, + dstStep, startup, 1, shift, withAlpha); + if (status != PRIMITIVES_SUCCESS) return status; @@ -385,8 +389,9 @@ { pstatus_t status; status = generic->YCoCgToRGB_8u_AC4R( - sptr, srcStep, dptr, DstFormat, dstStep, - w, 1, shift, withAlpha); + sptr, srcStep, dptr, DstFormat, dstStep, + w, 1, shift, withAlpha); + if (status != PRIMITIVES_SUCCESS) return status; @@ -411,24 +416,151 @@ UINT8 shift, BOOL withAlpha) { - // TODO: Need to implement proper color conversion!!! - return generic->YCoCgToRGB_8u_AC4R(pSrc, srcStep, pDst, DstFormat, - dstStep, width, height, shift, withAlpha); + switch (DstFormat) + { + case PIXEL_FORMAT_BGRX32: + case PIXEL_FORMAT_BGRA32: + return ssse3_YCoCgRToRGB_8u_AC4R_no_invert( + pSrc, srcStep, pDst, DstFormat, dstStep, + width, height, shift, withAlpha); + + case PIXEL_FORMAT_RGBX32: + case PIXEL_FORMAT_RGBA32: + return ssse3_YCoCgRToRGB_8u_AC4R_invert( + pSrc, srcStep, pDst, DstFormat, dstStep, + width, height, shift, withAlpha); + + default: + return generic->YCoCgToRGB_8u_AC4R(pSrc, srcStep, pDst, DstFormat, + dstStep, width, height, shift, withAlpha); + } +} +#elif defined(WITH_NEON) + +static pstatus_t neon_YCoCgToRGB_8u_X( + const BYTE* pSrc, INT32 srcStep, + BYTE* pDst, UINT32 DstFormat, INT32 dstStep, + UINT32 width, UINT32 height, + UINT8 shift, BYTE rPos, BYTE gPos, BYTE bPos, BYTE aPos, BOOL alpha) +{ + UINT32 y; + BYTE* dptr = pDst; + const BYTE* sptr = pSrc; + const DWORD formatSize = GetBytesPerPixel(DstFormat); + const int8_t cll = shift - 1; /* -1 builds in the /2's */ + const UINT32 srcPad = srcStep - (width * 4); + const UINT32 dstPad = dstStep - (width * formatSize); + const UINT32 pad = width % 8; + const uint8x8_t aVal = vdup_n_u8(0xFF); + const int8x8_t cllv = vdup_n_s8(cll); - switch(DstFormat) + for (y = 0; y < height; y++) { - case PIXEL_FORMAT_BGRX32: - case PIXEL_FORMAT_BGRA32: - return ssse3_YCoCgRToRGB_8u_AC4R_invert( - pSrc, srcStep, pDst, DstFormat, dstStep, - width, height, shift, withAlpha); - case PIXEL_FORMAT_RGBX32: - case PIXEL_FORMAT_RGBA32: - return ssse3_YCoCgRToRGB_8u_AC4R_no_invert( - pSrc, srcStep, pDst, DstFormat, dstStep, - width, height, shift, withAlpha); - default: - return -1; + UINT32 x; + + for (x = 0; x < width - pad; x += 8) + { + /* Note: shifts must be done before sign-conversion. */ + const uint8x8x4_t raw = vld4_u8(sptr); + const int8x8_t CgRaw = vreinterpret_s8_u8(vshl_u8(raw.val[0], cllv)); + const int8x8_t CoRaw = vreinterpret_s8_u8(vshl_u8(raw.val[1], cllv)); + const int16x8_t Cg = vmovl_s8(CgRaw); + const int16x8_t Co = vmovl_s8(CoRaw); + const int16x8_t Y = vreinterpretq_s16_u16(vmovl_u8(raw.val[2])); /* UINT8 -> INT16 */ + const int16x8_t T = vsubq_s16(Y, Cg); + const int16x8_t R = vaddq_s16(T, Co); + const int16x8_t G = vaddq_s16(Y, Cg); + const int16x8_t B = vsubq_s16(T, Co); + uint8x8x4_t bgrx; + bgrx.val[bPos] = vqmovun_s16(B); + bgrx.val[gPos] = vqmovun_s16(G); + bgrx.val[rPos] = vqmovun_s16(R); + + if (alpha) + bgrx.val[aPos] = raw.val[3]; + else + bgrx.val[aPos] = aVal; + + vst4_u8(dptr, bgrx); + sptr += sizeof(raw); + dptr += sizeof(bgrx); + } + + for (x = 0; x < pad; x++) + { + /* Note: shifts must be done before sign-conversion. */ + const INT16 Cg = (INT16)((INT8)((*sptr++) << cll)); + const INT16 Co = (INT16)((INT8)((*sptr++) << cll)); + const INT16 Y = (INT16)(*sptr++); /* UINT8->INT16 */ + const INT16 T = Y - Cg; + const INT16 R = T + Co; + const INT16 G = Y + Cg; + const INT16 B = T - Co; + BYTE bgra[4]; + bgra[bPos] = CLIP(B); + bgra[gPos] = CLIP(G); + bgra[rPos] = CLIP(R); + bgra[aPos] = *sptr++; + + if (!alpha) + bgra[aPos] = 0xFF; + + *dptr++ = bgra[0]; + *dptr++ = bgra[1]; + *dptr++ = bgra[2]; + *dptr++ = bgra[3]; + } + + sptr += srcPad; + dptr += dstPad; + } + + return PRIMITIVES_SUCCESS; +} +static pstatus_t neon_YCoCgToRGB_8u_AC4R( + const BYTE* pSrc, INT32 srcStep, + BYTE* pDst, UINT32 DstFormat, INT32 dstStep, + UINT32 width, UINT32 height, + UINT8 shift, + BOOL withAlpha) +{ + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + return neon_YCoCgToRGB_8u_X(pSrc, srcStep, pDst, DstFormat, dstStep, width, height, shift, 2, 1, 0, + 3, withAlpha); + + case PIXEL_FORMAT_BGRX32: + return neon_YCoCgToRGB_8u_X(pSrc, srcStep, pDst, DstFormat, dstStep, width, height, shift, 2, 1, 0, + 3, withAlpha); + + case PIXEL_FORMAT_RGBA32: + return neon_YCoCgToRGB_8u_X(pSrc, srcStep, pDst, DstFormat, dstStep, width, height, shift, 0, 1, 2, + 3, withAlpha); + + case PIXEL_FORMAT_RGBX32: + return neon_YCoCgToRGB_8u_X(pSrc, srcStep, pDst, DstFormat, dstStep, width, height, shift, 0, 1, 2, + 3, withAlpha); + + case PIXEL_FORMAT_ARGB32: + return neon_YCoCgToRGB_8u_X(pSrc, srcStep, pDst, DstFormat, dstStep, width, height, shift, 1, 2, 3, + 0, withAlpha); + + case PIXEL_FORMAT_XRGB32: + return neon_YCoCgToRGB_8u_X(pSrc, srcStep, pDst, DstFormat, dstStep, width, height, shift, 1, 2, 3, + 0, withAlpha); + + case PIXEL_FORMAT_ABGR32: + return neon_YCoCgToRGB_8u_X(pSrc, srcStep, pDst, DstFormat, dstStep, width, height, shift, 3, 2, 1, + 0, withAlpha); + + case PIXEL_FORMAT_XBGR32: + return neon_YCoCgToRGB_8u_X(pSrc, srcStep, pDst, DstFormat, dstStep, width, height, shift, 3, 2, 1, + 0, withAlpha); + + default: + return generic->YCoCgToRGB_8u_AC4R(pSrc, srcStep, pDst, DstFormat, dstStep, width, height, shift, + withAlpha); } } #endif /* WITH_SSE2 */ @@ -450,5 +582,12 @@ prims->YCoCgToRGB_8u_AC4R = ssse3_YCoCgRToRGB_8u_AC4R; } +#elif defined(WITH_NEON) + + if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) + { + prims->YCoCgToRGB_8u_AC4R = neon_YCoCgToRGB_8u_AC4R; + } + #endif /* WITH_SSE2 */ } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_YUV.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_YUV.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_YUV.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_YUV.c 2017-03-03 08:39:24.000000000 +0000 @@ -1,7 +1,12 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation + * Generic YUV/RGB conversion operations * * Copyright 2014 Marc-Andre Moreau + * Copyright 2015-2017 Armin Novak + * Copyright 2015-2017 Norbert Federa + * Copyright 2015-2017 Vic Lee + * Copyright 2015-2017 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. @@ -62,7 +67,7 @@ halfWidth = (nWidth) / 2; halfHeight = (nHeight) / 2; - if (pMainSrc) + if (pMainSrc && pMainSrc[0] && pMainSrc[1] && pMainSrc[2]) { /* Y data is already here... */ /* B1 */ @@ -102,7 +107,7 @@ } } - if (!pAuxSrc) + if (!pAuxSrc || !pAuxSrc[0] || !pAuxSrc[1] || !pAuxSrc[2]) return PRIMITIVES_SUCCESS; /* The second half of U and V is a bit more tricky... */ @@ -275,48 +280,41 @@ return PRIMITIVES_SUCCESS; } -/** - * | R | ( | 256 0 403 | | Y | ) - * | G | = ( | 256 -48 -120 | | U - 128 | ) >> 8 - * | B | ( | 256 475 0 | | V - 128 | ) - */ -static INLINE INT32 C(INT32 Y) -{ - return (Y) - 0L; -} - -static INLINE INT32 D(INT32 U) -{ - return (U) - 128L; -} - -static INLINE INT32 E(INT32 V) +static pstatus_t general_YUV444ToRGB_8u_P3AC4R_general( + const BYTE* pSrc[3], const UINT32 srcStep[3], + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + const prim_size_t* roi) { - return (V) - 128L; -} + UINT32 x, y; + UINT32 nWidth, nHeight; + const DWORD formatSize = GetBytesPerPixel(DstFormat); + fkt_writePixel writePixel = getPixelWriteFunction(DstFormat); + nWidth = roi->width; + nHeight = roi->height; -static INLINE BYTE YUV2R(INT32 Y, INT32 U, INT32 V) -{ - const INT32 r = (256L * C(Y) + 0L * D(U) + 403L * E(V)); - const INT32 r8 = r >> 8L; - return CLIP(r8); -} + for (y = 0; y < nHeight; y++) + { + const BYTE* pY = pSrc[0] + y * srcStep[0]; + const BYTE* pU = pSrc[1] + y * srcStep[1]; + const BYTE* pV = pSrc[2] + y * srcStep[2]; + BYTE* pRGB = pDst + y * dstStep; -static INLINE BYTE YUV2G(INT32 Y, INT32 U, INT32 V) -{ - const INT32 g = (256L * C(Y) - 48L * D(U) - 120L * E(V)); - const INT32 g8 = g >> 8L; - return CLIP(g8); -} + for (x = 0; x < nWidth; x++) + { + const BYTE Y = pY[x]; + const BYTE U = pU[x]; + const BYTE V = pV[x]; + const BYTE r = YUV2R(Y, U, V); + const BYTE g = YUV2G(Y, U, V); + const BYTE b = YUV2B(Y, U, V); + pRGB = (*writePixel)(pRGB, formatSize, DstFormat, r, g, b, 0xFF); + } + } -static INLINE BYTE YUV2B(INT32 Y, INT32 U, INT32 V) -{ - const INT32 b = (256L * C(Y) + 475L * D(U) + 0L * E(V)); - const INT32 b8 = b >> 8L; - return CLIP(b8); + return PRIMITIVES_SUCCESS; } -static pstatus_t general_YUV444ToRGB_8u_P3AC4R( +static pstatus_t general_YUV444ToRGB_8u_P3AC4R_BGRX( const BYTE* pSrc[3], const UINT32 srcStep[3], BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, const prim_size_t* roi) @@ -324,7 +322,6 @@ UINT32 x, y; UINT32 nWidth, nHeight; const DWORD formatSize = GetBytesPerPixel(DstFormat); - fkt_writePixel writePixel = getPixelWriteFunction(DstFormat); nWidth = roi->width; nHeight = roi->height; @@ -338,18 +335,33 @@ for (x = 0; x < nWidth; x++) { const BYTE Y = pY[x]; - const INT32 U = pU[x]; - const INT32 V = pV[x]; + const BYTE U = pU[x]; + const BYTE V = pV[x]; const BYTE r = YUV2R(Y, U, V); const BYTE g = YUV2G(Y, U, V); const BYTE b = YUV2B(Y, U, V); - pRGB = (*writePixel)(pRGB, formatSize, DstFormat, r, g, b, 0xFF); + pRGB = writePixelBGRX(pRGB, formatSize, DstFormat, r, g, b, 0xFF); } } return PRIMITIVES_SUCCESS; } +static pstatus_t general_YUV444ToRGB_8u_P3AC4R( + const BYTE* pSrc[3], const UINT32 srcStep[3], + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + const prim_size_t* roi) +{ + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return general_YUV444ToRGB_8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + + default: + return general_YUV444ToRGB_8u_P3AC4R_general(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} /** * | R | ( | 256 0 403 | | Y | ) * | G | = ( | 256 -48 -120 | | U - 128 | ) >> 8 @@ -485,25 +497,19 @@ * | U | = ( | -29 -99 128 | | G | ) >> 8 + | 128 | * | V | ( | 128 -116 -12 | | B | ) | 128 | */ -static INLINE BYTE RGB2Y(INT32 R, INT32 G, INT32 B) +static INLINE BYTE RGB2Y(BYTE R, BYTE G, BYTE B) { - const INT32 y = (54L * (R) + 183L * (G) + 18L * (B)); - const INT32 y8 = (y >> 8L); - return CLIP(y8); + return (54 * R + 183 * G + 18 * B) >> 8; } -static INLINE BYTE RGB2U(INT32 R, INT32 G, INT32 B) +static INLINE BYTE RGB2U(BYTE R, BYTE G, BYTE B) { - const INT32 u = (-29L * (R) - 99L * (G) + 128L * (B)); - const INT32 u8 = (u >> 8L) + 128L; - return CLIP(u8); + return ((-29 * R - 99 * G + 128 * B) >> 8) + 128; } static INLINE BYTE RGB2V(INT32 R, INT32 G, INT32 B) { - const INT32 v = (128L * (R) - 116L * (G) - 12L * (B)); - const INT32 v8 = (v >> 8L) + 128L; - return CLIP(v8); + return ((128L * R - 116 * G - 12 * B) >> 8) + 128; } static pstatus_t general_RGBToYUV444_8u_P3AC4R( @@ -537,90 +543,413 @@ return PRIMITIVES_SUCCESS; } -static pstatus_t general_RGBToYUV420_8u_P3AC4R( - const BYTE* pSrc, UINT32 SrcFormat, UINT32 srcStep, + +static INLINE pstatus_t general_RGBToYUV420_BGRX( + const BYTE* pSrc, UINT32 srcStep, BYTE* pDst[3], UINT32 dstStep[3], const prim_size_t* roi) { - const UINT32 bpp = GetBytesPerPixel(SrcFormat); - UINT32 x, y; - UINT32 halfWidth; - UINT32 halfHeight; - UINT32 nWidth, nHeight; - nWidth = roi->width + roi->width % 2; - nHeight = roi->height + roi->height % 2; - halfWidth = (nWidth + nWidth % 2) / 2; - halfHeight = (nHeight + nHeight % 2) / 2; + UINT32 x, y, i; + size_t x1 = 0, x2 = 4, x3 = srcStep, x4 = srcStep + 4; + size_t y1 = 0, y2 = 1, y3 = dstStep[0], y4 = dstStep[0] + 1; + UINT32 max_x = roi->width - 1; + UINT32 max_y = roi->height - 1; + + for (y = i = 0; y < roi->height; y += 2, i++) + { + const BYTE* src = pSrc + y * srcStep; + BYTE* ydst = pDst[0] + y * dstStep[0]; + BYTE* udst = pDst[1] + i * dstStep[1]; + BYTE* vdst = pDst[2] + i * dstStep[2]; - for (y = 0; y < halfHeight; y++) - { - const UINT32 val2y = (y * 2); - const UINT32 val2y1 = val2y + 1; - const BYTE* pRGB = pSrc + val2y * srcStep; - const BYTE* pRGB1 = pSrc + val2y1 * srcStep; - BYTE* pY = pDst[0] + val2y * dstStep[0]; - BYTE* pY1 = pDst[0] + val2y1 * dstStep[0]; - BYTE* pU = pDst[1] + y * dstStep[1]; - BYTE* pV = pDst[2] + y * dstStep[2]; + for (x = 0; x < roi->width; x += 2) + { + BYTE R, G, B; + INT32 Ra, Ga, Ba; + /* row 1, pixel 1 */ + Ba = B = *(src + x1 + 0); + Ga = G = *(src + x1 + 1); + Ra = R = *(src + x1 + 2); + ydst[y1] = RGB2Y(R, G, B); - for (x = 0; x < halfWidth; x++) + if (x < max_x) + { + /* row 1, pixel 2 */ + Ba += B = *(src + x2 + 0); + Ga += G = *(src + x2 + 1); + Ra += R = *(src + x2 + 2); + ydst[y2] = RGB2Y(R, G, B); + } + + if (y < max_y) + { + /* row 2, pixel 1 */ + Ba += B = *(src + x3 + 0); + Ga += G = *(src + x3 + 1); + Ra += R = *(src + x3 + 2); + ydst[y3] = RGB2Y(R, G, B); + + if (x < max_x) + { + /* row 2, pixel 2 */ + Ba += B = *(src + x4 + 0); + Ga += G = *(src + x4 + 1); + Ra += R = *(src + x4 + 2); + ydst[y4] = RGB2Y(R, G, B); + } + } + + Ba >>= 2; + Ga >>= 2; + Ra >>= 2; + *udst++ = RGB2U(Ra, Ga, Ba); + *vdst++ = RGB2V(Ra, Ga, Ba); + ydst += 2; + src += 8; + } + } + + return PRIMITIVES_SUCCESS; +} + +static INLINE pstatus_t general_RGBToYUV420_ANY( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pDst[3], UINT32 dstStep[3], const prim_size_t* roi) +{ + const UINT32 bpp = GetBytesPerPixel(srcFormat); + UINT32 x, y, i; + size_t x1 = 0, x2 = bpp, x3 = srcStep, x4 = srcStep + bpp; + size_t y1 = 0, y2 = 1, y3 = dstStep[0], y4 = dstStep[0] + 1; + UINT32 max_x = roi->width - 1; + UINT32 max_y = roi->height - 1; + + for (y = i = 0; y < roi->height; y += 2, i++) + { + const BYTE* src = pSrc + y * srcStep; + BYTE* ydst = pDst[0] + y * dstStep[0]; + BYTE* udst = pDst[1] + i * dstStep[1]; + BYTE* vdst = pDst[2] + i * dstStep[2]; + + for (x = 0; x < roi->width; x += 2) { - UINT32 color; + BYTE R, G, B; INT32 Ra, Ga, Ba; - const UINT32 val2x = (x * 2); - const UINT32 val2x1 = val2x + 1; - BYTE B, G, R; - /* 1st pixel */ - color = ReadColor(&pRGB[val2x * bpp], SrcFormat); - SplitColor(color, SrcFormat, &R, &G, &B, NULL, NULL); - Ba = B; - Ga = G; + UINT32 color; + /* row 1, pixel 1 */ + color = ReadColor(src + x1, srcFormat); + SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL); Ra = R; - pY[val2x] = RGB2Y(R, G, B); + Ga = G; + Ba = B; + ydst[y1] = RGB2Y(R, G, B); - if (val2x1 < nWidth) + if (x < max_x) { - /* 2nd pixel */ - color = ReadColor(&pRGB[val2x1 * bpp], SrcFormat); - SplitColor(color, SrcFormat, &R, &G, &B, NULL, NULL); - Ba += B; - Ga += G; + /* row 1, pixel 2 */ + color = ReadColor(src + x2, srcFormat); + SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL); Ra += R; - pY[val2x1] = RGB2Y(R, G, B); + Ga += G; + Ba += B; + ydst[y2] = RGB2Y(R, G, B); } - if (val2y1 < nHeight) + if (y < max_y) { - /* 3rd pixel */ - color = ReadColor(&pRGB1[val2x * bpp], SrcFormat); - SplitColor(color, SrcFormat, &R, &G, &B, NULL, NULL); - Ba += B; - Ga += G; + /* row 2, pixel 1 */ + color = ReadColor(src + x3, srcFormat); + SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL); Ra += R; - pY1[val2x] = RGB2Y(R, G, B); + Ga += G; + Ba += B; + ydst[y3] = RGB2Y(R, G, B); - if (val2x1 < nWidth) + if (x < max_x) { - /* 4th pixel */ - color = ReadColor(&pRGB1[val2x1 * bpp], SrcFormat); - SplitColor(color, SrcFormat, &R, &G, &B, NULL, NULL); - Ba += B; - Ga += G; + /* row 2, pixel 2 */ + color = ReadColor(src + x4, srcFormat); + SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL); Ra += R; - pY1[val2x1] = RGB2Y(R, G, B); + Ga += G; + Ba += B; + ydst[y4] = RGB2Y(R, G, B); } } - Ba >>= 2; - Ga >>= 2; Ra >>= 2; - pU[x] = RGB2U(Ra, Ga, Ba); - pV[x] = RGB2V(Ra, Ga, Ba); + Ga >>= 2; + Ba >>= 2; + *udst++ = RGB2U(Ra, Ga, Ba); + *vdst++ = RGB2V(Ra, Ga, Ba); + ydst += 2; + src += 2 * bpp; + } + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t general_RGBToYUV420_8u_P3AC4R( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pDst[3], UINT32 dstStep[3], const prim_size_t* roi) +{ + switch (srcFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return general_RGBToYUV420_BGRX(pSrc, srcStep, pDst, dstStep, roi); + + default: + return general_RGBToYUV420_ANY(pSrc, srcFormat, srcStep, pDst, dstStep, roi); + } +} + +static INLINE pstatus_t general_RGBToAVC444YUV_BGRX( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pDst1[3], const UINT32 dst1Step[3], + BYTE* pDst2[3], const UINT32 dst2Step[3], + const prim_size_t* roi) +{ + /** + * Note: + * Read information in function general_RGBToAVC444YUV_ANY below ! + */ + + UINT32 x, y, n, numRows, numCols; + BOOL evenRow = TRUE; + BYTE *b1, *b2, *b3, *b4, *b5, *b6, *b7; + const BYTE* pMaxSrc = pSrc + (roi->height - 1) * srcStep; + + numRows = (roi->height + 1) & ~1; + numCols = (roi->width + 1) & ~1; + + for (y = 0; y < numRows; y++, evenRow = !evenRow) + { + const BYTE* src = y < roi->height ? pSrc + y * srcStep : pMaxSrc; + UINT32 i = y >> 1; + + b1 = pDst1[0] + y * dst1Step[0]; + + if (evenRow) + { + b2 = pDst1[1] + i * dst1Step[1]; + b3 = pDst1[2] + i * dst1Step[2]; + b6 = pDst2[1] + i * dst2Step[1]; + b7 = pDst2[2] + i * dst2Step[2]; + } + else + { + n = (i & ~7) + i; + b4 = pDst2[0] + dst2Step[0] * n; + b5 = b4 + 8 * dst2Step[0]; + } + + for (x = 0; x < numCols; x += 2) + { + BYTE R, G, B, Y1, Y2, U1, U2, V1, V2; + + B = src[0]; + G = src[1]; + R = src[2]; + + Y1 = Y2 = RGB2Y(R, G, B); + U1 = U2 = RGB2U(R, G, B); + V1 = V2 = RGB2V(R, G, B); + + if (x + 1 < roi->width) + { + B = src[4]; + G = src[5]; + R = src[6]; + Y2 = RGB2Y(R, G, B); + U2 = RGB2U(R, G, B); + V2 = RGB2V(R, G, B); + } + + *b1++ = Y1; + *b1++ = Y2; + + if (evenRow) + { + *b2++ = U1; + *b3++ = V1; + *b6++ = U2; + *b7++ = V2; + } + else + { + *b4++ = U1; + *b4++ = U2; + *b5++ = V1; + *b5++ = V2; + } + + src += 8; } } return PRIMITIVES_SUCCESS; } +static INLINE pstatus_t general_RGBToAVC444YUV_ANY( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pDst1[3], const UINT32 dst1Step[3], + BYTE* pDst2[3], const UINT32 dst2Step[3], + const prim_size_t* roi) +{ + /** + * Note: According to [MS-RDPEGFX 2.2.4.4 RFX_AVC420_BITMAP_STREAM] the + * width and height of the MPEG-4 AVC/H.264 codec bitstream MUST be aligned + * to a multiple of 16. + * Hence the passed destination YUV420/CHROMA420 buffers must have been + * allocated accordingly !! + */ + + /** + * [MS-RDPEGFX 3.3.8.3.2 YUV420p Stream Combination] defines the following "Bx areas": + * + * YUV420 frame (main view): + * B1: From Y444 all pixels + * B2: From U444 all pixels in even rows with even columns + * B3: From V444 all pixels in even rows with even columns + * + * Chroma420 frame (auxillary view): + * B45: From U444 and V444 all pixels from all odd rows + * (The odd U444 and V444 rows must be interleaved in 8-line blocks in B45 !!!) + * B6: From U444 all pixels in even rows with odd columns + * B7: From V444 all pixels in even rows with odd columns + * + * Microsoft's horrible unclear description in MS-RDPEGFX translated to pseudo code looks like this: + * + * for (y = 0; y < fullHeight; y++) + * { + * for (x = 0; x < fullWidth; x++) + * { + * B1[x,y] = Y444[x,y]; + * } + * } + * + * for (y = 0; y < halfHeight; y++) + * { + * for (x = 0; x < halfWidth; x++) + * { + * B2[x,y] = U444[2 * x, 2 * y]; + * B3[x,y] = V444[2 * x, 2 * y]; + * B6[x,y] = U444[2 * x + 1, 2 * y]; + * B7[x,y] = V444[2 * x + 1, 2 * y]; + * } + * } + * + * for (y = 0; y < halfHeight; y++) + * { + * yU = (y / 8) * 16; // identify first row of correct 8-line U block in B45 + * yU += (y % 8); // add offset rows in destination block + * yV = yU + 8; // the corresponding v line is always 8 rows ahead + * + * for (x = 0; x < fullWidth; x++) + * { + * B45[x,yU] = U444[x, 2 * y + 1]; + * B45[x,yV] = V444[x, 2 * y + 1]; + * } + * } + * + */ + + const UINT32 bpp = GetBytesPerPixel(srcFormat); + UINT32 x, y, n, numRows, numCols; + BOOL evenRow = TRUE; + BYTE *b1, *b2, *b3, *b4, *b5, *b6, *b7; + const BYTE* pMaxSrc = pSrc + (roi->height - 1) * srcStep; + + numRows = (roi->height + 1) & ~1; + numCols = (roi->width + 1) & ~1; + + for (y = 0; y < numRows; y++, evenRow = !evenRow) + { + const BYTE* src = y < roi->height ? pSrc + y * srcStep : pMaxSrc; + UINT32 i = y >> 1; + + b1 = pDst1[0] + y * dst1Step[0]; + + if (evenRow) + { + b2 = pDst1[1] + i * dst1Step[1]; + b3 = pDst1[2] + i * dst1Step[2]; + b6 = pDst2[1] + i * dst2Step[1]; + b7 = pDst2[2] + i * dst2Step[2]; + } + else + { + n = (i & ~7) + i; + b4 = pDst2[0] + dst2Step[0] * n; + b5 = b4 + 8 * dst2Step[0]; + } + + for (x = 0; x < numCols; x += 2) + { + BYTE R, G, B, Y1, Y2, U1, U2, V1, V2; + UINT32 color; + + color = ReadColor(src, srcFormat); + SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL); + + Y1 = Y2 = RGB2Y(R, G, B); + U1 = U2 = RGB2U(R, G, B); + V1 = V2 = RGB2V(R, G, B); + + if (x + 1 < roi->width) + { + color = ReadColor(src + bpp, srcFormat); + SplitColor(color, srcFormat, &R, &G, &B, NULL, NULL); + + Y2 = RGB2Y(R, G, B); + U2 = RGB2U(R, G, B); + V2 = RGB2V(R, G, B); + } + + *b1++ = Y1; + *b1++ = Y2; + + if (evenRow) + { + *b2++ = U1; + *b3++ = V1; + *b6++ = U2; + *b7++ = V2; + } + else + { + *b4++ = U1; + *b4++ = U2; + *b5++ = V1; + *b5++ = V2; + } + + src += 2 * bpp; + } + } + + return PRIMITIVES_SUCCESS; +} + +static INLINE pstatus_t general_RGBToAVC444YUV( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pDst1[3], const UINT32 dst1Step[3], + BYTE* pDst2[3], const UINT32 dst2Step[3], + const prim_size_t* roi) +{ + switch (srcFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return general_RGBToAVC444YUV_BGRX(pSrc, srcFormat, srcStep, pDst1, dst1Step, pDst2, dst2Step, roi); + + default: + return general_RGBToAVC444YUV_ANY(pSrc, srcFormat, srcStep, pDst1, dst1Step, pDst2, dst2Step, roi); + } + + return !PRIMITIVES_SUCCESS; +} + void primitives_init_YUV(primitives_t* prims) { prims->YUV420ToRGB_8u_P3AC4R = general_YUV420ToRGB_8u_P3AC4R; @@ -629,5 +958,6 @@ prims->RGBToYUV444_8u_P3AC4R = general_RGBToYUV444_8u_P3AC4R; prims->YUV420CombineToYUV444 = general_YUV420CombineToYUV444; prims->YUV444SplitToYUV420 = general_YUV444SplitToYUV420; + prims->RGBToAVC444YUV = general_RGBToAVC444YUV; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_YUV_opt.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_YUV_opt.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/prim_YUV_opt.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/prim_YUV_opt.c 2017-03-03 08:39:24.000000000 +0000 @@ -1,12 +1,25 @@ -/** function for converting YUV420p data to the RGB format (but without any special upconverting) - * It's completely written in nasm-x86-assembly for intel processors supporting SSSE3 and higher. - * The target dstStep (6th parameter) must be a multiple of 16. - * srcStep[0] must be (target dstStep) / 4 or bigger and srcStep[1] the next multiple of four - * of the half of srcStep[0] or bigger +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Optimized YUV/RGB conversion operations + * + * Copyright 2014 Thomas Erbesdobler + * Copyright 2016-2017 Armin Novak + * Copyright 2016-2017 Norbert Federa + * Copyright 2016-2017 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. + * 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. */ -#include - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -18,16 +31,24 @@ #include "prim_internal.h" -static primitives_t* generic = NULL; - #ifdef WITH_SSE2 #include #include +#elif defined(WITH_NEON) +#include +#endif /* WITH_SSE2 else WITH_NEON */ + +static primitives_t* generic = NULL; -static pstatus_t ssse3_YUV420ToRGB_8u_P3AC4R( +#ifdef WITH_SSE2 +/****************************************************************************/ +/* SSSE3 YUV420 -> RGB conversion */ +/****************************************************************************/ + +static pstatus_t ssse3_YUV420ToRGB_BGRX( const BYTE** pSrc, const UINT32* srcStep, - BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + BYTE* pDst, UINT32 dstStep, UINT32 dstFormat, const prim_size_t* roi) { UINT32 lastRow, lastCol; @@ -35,9 +56,6 @@ UINT32 i, nWidth, nHeight, VaddDst, VaddY, VaddU, VaddV; __m128i r0, r1, r2, r3, r4, r5, r6, r7; __m128i* buffer; - // TODO: Need to implement proper color conversion!!!!! - return generic->YUV420ToRGB_8u_P3AC4R(pSrc, srcStep, pDst, dstStep, - DstFormat, roi); /* last_line: if the last (U,V doubled) line should be skipped, set to 10B * last_column: if it's the last column in a line, set to 10B (for handling line-endings not multiple by four) */ buffer = _aligned_malloc(4 * 16, 16); @@ -324,6 +342,1123 @@ _aligned_free(buffer); return PRIMITIVES_SUCCESS; } + +static pstatus_t ssse3_YUV420ToRGB( + const BYTE** pSrc, const UINT32* srcStep, + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + const prim_size_t* roi) +{ + switch (DstFormat) + { + case PIXEL_FORMAT_BGRX32: + case PIXEL_FORMAT_BGRA32: + return ssse3_YUV420ToRGB_BGRX(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + + default: + return generic->YUV420ToRGB_8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} + +static __m128i* ssse3_YUV444Pixel(__m128i* dst, __m128i Yraw, __m128i Uraw, __m128i Vraw, UINT8 pos) +{ + /* Visual Studio 2010 doesn't like _mm_set_epi32 in array initializer list */ +#if !defined(_MSC_VER) || (_MSC_VER > 1600) + const __m128i mapY[] = + { + _mm_set_epi32(0x80800380, 0x80800280, 0x80800180, 0x80800080), + _mm_set_epi32(0x80800780, 0x80800680, 0x80800580, 0x80800480), + _mm_set_epi32(0x80800B80, 0x80800A80, 0x80800980, 0x80800880), + _mm_set_epi32(0x80800F80, 0x80800E80, 0x80800D80, 0x80800C80) + }; + const __m128i mapUV[] = + { + _mm_set_epi32(0x80038002, 0x80018000, 0x80808080, 0x80808080), + _mm_set_epi32(0x80078006, 0x80058004, 0x80808080, 0x80808080), + _mm_set_epi32(0x800B800A, 0x80098008, 0x80808080, 0x80808080), + _mm_set_epi32(0x800F800E, 0x800D800C, 0x80808080, 0x80808080) + }; + const __m128i mask[] = + { + _mm_set_epi32(0x80038080, 0x80028080, 0x80018080, 0x80008080), + _mm_set_epi32(0x80800380, 0x80800280, 0x80800180, 0x80800080), + _mm_set_epi32(0x80808003, 0x80808002, 0x80808001, 0x80808000) + }; +#else + const __m128i mapY[] = + { + { 0x80, 0x80, 0x03, 0x80, 0x80, 0x80, 0x02, 0x80, 0x80, 0x80, 0x01, 0x80, 0x80, 0x80, 0x00, 0x80}, + { 0x80, 0x80, 0x07, 0x80, 0x80, 0x80, 0x06, 0x80, 0x80, 0x80, 0x05, 0x80, 0x80, 0x80, 0x04, 0x80}, + { 0x80, 0x80, 0x0B, 0x80, 0x80, 0x80, 0x0A, 0x80, 0x80, 0x80, 0x09, 0x80, 0x80, 0x80, 0x08, 0x80}, + { 0x80, 0x80, 0x0F, 0x80, 0x80, 0x80, 0x0E, 0x80, 0x80, 0x80, 0x0D, 0x80, 0x80, 0x80, 0x0C, 0x80} + }; + const __m128i mapUV[] = + { + { 0x80, 0x03, 0x80, 0x02, 0x80, 0x01, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, + { 0x80, 0x07, 0x80, 0x06, 0x80, 0x05, 0x80, 0x04, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, + { 0x80, 0x0B, 0x80, 0x0A, 0x80, 0x09, 0x80, 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, + { 0x80, 0x0F, 0x80, 0x0E, 0x80, 0x0D, 0x80, 0x0C, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80} + }; + const __m128i mask[] = + { + { 0x80, 0x03, 0x80, 0x80, 0x80, 0x02, 0x80, 0x80, 0x80, 0x01, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80}, + { 0x80, 0x80, 0x03, 0x80, 0x80, 0x80, 0x02, 0x80, 0x80, 0x80, 0x01, 0x80, 0x80, 0x80, 0x00, 0x80}, + { 0x80, 0x80, 0x80, 0x03, 0x80, 0x80, 0x80, 0x02, 0x80, 0x80, 0x80, 0x01, 0x80, 0x80, 0x80, 0x00} + }; +#endif + const __m128i c128 = _mm_set1_epi16(128); + __m128i BGRX = _mm_set_epi32(0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000); + { + __m128i C, D, E; + /* Load Y values and expand to 32 bit */ + { + C = _mm_shuffle_epi8(Yraw, mapY[pos]); /* Reorder and multiply by 256 */ + } + /* Load U values and expand to 32 bit */ + { + const __m128i U = _mm_shuffle_epi8(Uraw, mapUV[pos]); /* Reorder dcba */ + D = _mm_sub_epi16(U, c128); /* D = U - 128 */ + } + /* Load V values and expand to 32 bit */ + { + const __m128i V = _mm_shuffle_epi8(Vraw, mapUV[pos]); /* Reorder dcba */ + E = _mm_sub_epi16(V, c128); /* E = V - 128 */ + } + /* Get the R value */ + { + const __m128i c403 = _mm_set1_epi16(403); + const __m128i e403 = _mm_unpackhi_epi16(_mm_mullo_epi16(E, c403), _mm_mulhi_epi16(E, c403)); + const __m128i Rs = _mm_add_epi32(C, e403); + const __m128i R32 = _mm_srai_epi32(Rs, 8); + const __m128i R16 = _mm_packs_epi32(R32, _mm_setzero_si128()); + const __m128i R = _mm_packus_epi16(R16, _mm_setzero_si128()); + const __m128i packed = _mm_shuffle_epi8(R, mask[0]); + BGRX = _mm_or_si128(BGRX, packed); + } + /* Get the G value */ + { + const __m128i c48 = _mm_set1_epi16(48); + const __m128i d48 = _mm_unpackhi_epi16(_mm_mullo_epi16(D, c48), _mm_mulhi_epi16(D, c48)); + const __m128i c120 = _mm_set1_epi16(120); + const __m128i e120 = _mm_unpackhi_epi16(_mm_mullo_epi16(E, c120), _mm_mulhi_epi16(E, c120)); + const __m128i de = _mm_add_epi32(d48, e120); + const __m128i Gs = _mm_sub_epi32(C, de); + const __m128i G32 = _mm_srai_epi32(Gs, 8); + const __m128i G16 = _mm_packs_epi32(G32, _mm_setzero_si128()); + const __m128i G = _mm_packus_epi16(G16, _mm_setzero_si128()); + const __m128i packed = _mm_shuffle_epi8(G, mask[1]); + BGRX = _mm_or_si128(BGRX, packed); + } + /* Get the B value */ + { + const __m128i c475 = _mm_set1_epi16(475); + const __m128i d475 = _mm_unpackhi_epi16(_mm_mullo_epi16(D, c475), _mm_mulhi_epi16(D, c475)); + const __m128i Bs = _mm_add_epi32(C, d475); + const __m128i B32 = _mm_srai_epi32(Bs, 8); + const __m128i B16 = _mm_packs_epi32(B32, _mm_setzero_si128()); + const __m128i B = _mm_packus_epi16(B16, _mm_setzero_si128()); + const __m128i packed = _mm_shuffle_epi8(B, mask[2]); + BGRX = _mm_or_si128(BGRX, packed); + } + } + _mm_store_si128(dst++, BGRX); + return dst; +} + +static pstatus_t ssse3_YUV444ToRGB_8u_P3AC4R_BGRX( + const BYTE** pSrc, const UINT32* srcStep, + BYTE* pDst, UINT32 dstStep, + const prim_size_t* roi) +{ + const UINT32 nWidth = roi->width; + const UINT32 nHeight = roi->height; + const UINT32 pad = roi->width % 16; + UINT32 y; + + for (y = 0; y < nHeight; y++) + { + UINT32 x; + __m128i* dst = (__m128i*)(pDst + dstStep * y); + const BYTE* YData = pSrc[0] + y * srcStep[0]; + const BYTE* UData = pSrc[1] + y * srcStep[1]; + const BYTE* VData = pSrc[2] + y * srcStep[2]; + + for (x = 0; x < nWidth - pad; x += 16) + { + __m128i Y = _mm_load_si128((__m128i*)YData); + __m128i U = _mm_load_si128((__m128i*)UData); + __m128i V = _mm_load_si128((__m128i*)VData); + YData += 16; + UData += 16; + VData += 16; + dst = ssse3_YUV444Pixel(dst, Y, U, V, 0); + dst = ssse3_YUV444Pixel(dst, Y, U, V, 1); + dst = ssse3_YUV444Pixel(dst, Y, U, V, 2); + dst = ssse3_YUV444Pixel(dst, Y, U, V, 3); + } + + for (x = 0; x < pad; x++) + { + const BYTE Y = *YData++; + const BYTE U = *UData++; + const BYTE V = *VData++; + const BYTE r = YUV2R(Y, U, V); + const BYTE g = YUV2G(Y, U, V); + const BYTE b = YUV2B(Y, U, V); + dst = (__m128i*)writePixelBGRX((BYTE*)dst, 4, PIXEL_FORMAT_BGRX32, r, g, b, 0xFF); + } + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t ssse3_YUV444ToRGB_8u_P3AC4R(const BYTE** pSrc, const UINT32* srcStep, + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + const prim_size_t* roi) +{ + if ((unsigned long)pSrc[0] % 16 || (unsigned long)pSrc[1] % 16 || (unsigned long)pSrc[2] % 16 || + (unsigned long)pDst % 16 || dstStep % 16 || srcStep[0] % 16 || srcStep[1] % 16 || srcStep[2] % 16) + return generic->YUV444ToRGB_8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + + switch (DstFormat) + { + case PIXEL_FORMAT_BGRX32: + case PIXEL_FORMAT_BGRA32: + return ssse3_YUV444ToRGB_8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, roi); + + default: + return generic->YUV444ToRGB_8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} + +/****************************************************************************/ +/* SSSE3 RGB -> YUV420 conversion **/ +/****************************************************************************/ + + +/** + * Note (nfedera): + * The used forward transformation factors from RGB to YUV are based on the + * values specified in [Rec. ITU-R BT.709-6] Section 3: + * http://www.itu.int/rec/R-REC-BT.709-6-201506-I/en + * + * Y = 0.21260 * R + 0.71520 * G + 0.07220 * B + 0; + * U = -0.11457 * R - 0.38543 * G + 0.50000 * B + 128; + * V = 0.50000 * R - 0.45415 * G - 0.04585 * B + 128; + * + * The most accurate integer arithmetic approximation when using 8-bit signed + * integer factors with 16-bit signed integer intermediate results is: + * + * Y = ( ( 27 * R + 92 * G + 9 * B) >> 7 ); + * U = ( (-15 * R - 49 * G + 64 * B) >> 7 ) + 128; + * V = ( ( 64 * R - 58 * G - 6 * B) >> 7 ) + 128; + * + */ + +PRIM_ALIGN_128 static const BYTE bgrx_y_factors[] = +{ + 9, 92, 27, 0, 9, 92, 27, 0, 9, 92, 27, 0, 9, 92, 27, 0 +}; +PRIM_ALIGN_128 static const BYTE bgrx_u_factors[] = +{ + 64, -49, -15, 0, 64, -49, -15, 0, 64, -49, -15, 0, 64, -49, -15, 0 +}; +PRIM_ALIGN_128 static const BYTE bgrx_v_factors[] = +{ + -6, -58, 64, 0, -6, -58, 64, 0, -6, -58, 64, 0, -6, -58, 64, 0 +}; + +PRIM_ALIGN_128 static const BYTE const_buf_128b[] = +{ + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 +}; + +/* +TODO: +RGB[AX] can simply be supported using the following factors. And instead of loading the +globals directly the functions below could be passed pointers to the correct vectors +depending on the source picture format. + +PRIM_ALIGN_128 static const BYTE rgbx_y_factors[] = { + 27, 92, 9, 0, 27, 92, 9, 0, 27, 92, 9, 0, 27, 92, 9, 0 +}; +PRIM_ALIGN_128 static const BYTE rgbx_u_factors[] = { + -15, -49, 64, 0, -15, -49, 64, 0, -15, -49, 64, 0, -15, -49, 64, 0 +}; +PRIM_ALIGN_128 static const BYTE rgbx_v_factors[] = { + 64, -58, -6, 0, 64, -58, -6, 0, 64, -58, -6, 0, 64, -58, -6, 0 +}; +*/ + + +/* compute the luma (Y) component from a single rgb source line */ + +static INLINE void ssse3_RGBToYUV420_BGRX_Y( + const BYTE* src, BYTE* dst, UINT32 width) +{ + UINT32 x; + __m128i y_factors, x0, x1, x2, x3; + const __m128i* argb = (const __m128i*) src; + __m128i* ydst = (__m128i*) dst; + y_factors = _mm_load_si128((__m128i*)bgrx_y_factors); + + for (x = 0; x < width; x += 16) + { + /* store 16 rgba pixels in 4 128 bit registers */ + x0 = _mm_load_si128(argb++); // 1st 4 pixels + x1 = _mm_load_si128(argb++); // 2nd 4 pixels + x2 = _mm_load_si128(argb++); // 3rd 4 pixels + x3 = _mm_load_si128(argb++); // 4th 4 pixels + /* multiplications and subtotals */ + x0 = _mm_maddubs_epi16(x0, y_factors); + x1 = _mm_maddubs_epi16(x1, y_factors); + x2 = _mm_maddubs_epi16(x2, y_factors); + x3 = _mm_maddubs_epi16(x3, y_factors); + /* the total sums */ + x0 = _mm_hadd_epi16(x0, x1); + x2 = _mm_hadd_epi16(x2, x3); + /* shift the results */ + x0 = _mm_srli_epi16(x0, 7); + x2 = _mm_srli_epi16(x2, 7); + /* pack the 16 words into bytes */ + x0 = _mm_packus_epi16(x0, x2); + /* save to y plane */ + _mm_storeu_si128(ydst++, x0); + } +} + +/* compute the chrominance (UV) components from two rgb source lines */ + +static INLINE void ssse3_RGBToYUV420_BGRX_UV( + const BYTE* src1, const BYTE* src2, + BYTE* dst1, BYTE* dst2, UINT32 width) +{ + UINT32 x; + __m128i vector128, u_factors, v_factors, x0, x1, x2, x3, x4, x5; + const __m128i* rgb1 = (const __m128i*)src1; + const __m128i* rgb2 = (const __m128i*)src2; + __m64* udst = (__m64*)dst1; + __m64* vdst = (__m64*)dst2; + vector128 = _mm_load_si128((__m128i*)const_buf_128b); + u_factors = _mm_load_si128((__m128i*)bgrx_u_factors); + v_factors = _mm_load_si128((__m128i*)bgrx_v_factors); + + for (x = 0; x < width; x += 16) + { + /* subsample 16x2 pixels into 16x1 pixels */ + x0 = _mm_load_si128(rgb1++); + x4 = _mm_load_si128(rgb2++); + x0 = _mm_avg_epu8(x0, x4); + x1 = _mm_load_si128(rgb1++); + x4 = _mm_load_si128(rgb2++); + x1 = _mm_avg_epu8(x1, x4); + x2 = _mm_load_si128(rgb1++); + x4 = _mm_load_si128(rgb2++); + x2 = _mm_avg_epu8(x2, x4); + x3 = _mm_load_si128(rgb1++); + x4 = _mm_load_si128(rgb2++); + x3 = _mm_avg_epu8(x3, x4); + /* subsample these 16x1 pixels into 8x1 pixels */ + + /** + * shuffle controls + * c = a[0],a[2],b[0],b[2] == 10 00 10 00 = 0x88 + * c = a[1],a[3],b[1],b[3] == 11 01 11 01 = 0xdd + */ + x4 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(x0), _mm_castsi128_ps(x1), 0x88)); + x0 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(x0), _mm_castsi128_ps(x1), 0xdd)); + x0 = _mm_avg_epu8(x0, x4); + x4 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(x2), _mm_castsi128_ps(x3), 0x88)); + x1 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(x2), _mm_castsi128_ps(x3), 0xdd)); + x1 = _mm_avg_epu8(x1, x4); + /* multiplications and subtotals */ + x2 = _mm_maddubs_epi16(x0, u_factors); + x3 = _mm_maddubs_epi16(x1, u_factors); + x4 = _mm_maddubs_epi16(x0, v_factors); + x5 = _mm_maddubs_epi16(x1, v_factors); + /* the total sums */ + x0 = _mm_hadd_epi16(x2, x3); + x1 = _mm_hadd_epi16(x4, x5); + /* shift the results */ + x0 = _mm_srai_epi16(x0, 7); + x1 = _mm_srai_epi16(x1, 7); + /* pack the 16 words into bytes */ + x0 = _mm_packs_epi16(x0, x1); + /* add 128 */ + x0 = _mm_add_epi8(x0, vector128); + /* the lower 8 bytes go to the u plane */ + _mm_storel_pi(udst++, _mm_castsi128_ps(x0)); + /* the upper 8 bytes go to the v plane */ + _mm_storeh_pi(vdst++, _mm_castsi128_ps(x0)); + } +} + +static pstatus_t ssse3_RGBToYUV420_BGRX( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pDst[3], UINT32 dstStep[3], + const prim_size_t* roi) +{ + UINT32 y; + const BYTE* argb = pSrc; + BYTE* ydst = pDst[0]; + BYTE* udst = pDst[1]; + BYTE* vdst = pDst[2]; + + if (roi->height < 1 || roi->width < 1) + { + return !PRIMITIVES_SUCCESS; + } + + if (roi->width % 16 || (unsigned long)pSrc % 16 || srcStep % 16) + { + return generic->RGBToYUV420_8u_P3AC4R(pSrc, srcFormat, srcStep, pDst, dstStep, roi); + } + + for (y = 0; y < roi->height - 1; y += 2) + { + const BYTE* line1 = argb; + const BYTE* line2 = argb + srcStep; + ssse3_RGBToYUV420_BGRX_UV(line1, line2, udst, vdst, roi->width); + ssse3_RGBToYUV420_BGRX_Y(line1, ydst, roi->width); + ssse3_RGBToYUV420_BGRX_Y(line2, ydst + dstStep[0], roi->width); + argb += 2 * srcStep; + ydst += 2 * dstStep[0]; + udst += 1 * dstStep[1]; + vdst += 1 * dstStep[2]; + } + + if (roi->height & 1) + { + /* pass the same last line of an odd height twice for UV */ + ssse3_RGBToYUV420_BGRX_UV(argb, argb, udst, vdst, roi->width); + ssse3_RGBToYUV420_BGRX_Y(argb, ydst, roi->width); + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t ssse3_RGBToYUV420( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pDst[3], UINT32 dstStep[3], + const prim_size_t* roi) +{ + switch (srcFormat) + { + case PIXEL_FORMAT_BGRX32: + case PIXEL_FORMAT_BGRA32: + return ssse3_RGBToYUV420_BGRX(pSrc, srcFormat, srcStep, pDst, dstStep, roi); + + default: + return generic->RGBToYUV420_8u_P3AC4R(pSrc, srcFormat, srcStep, pDst, dstStep, roi); + } +} + + +/****************************************************************************/ +/* SSSE3 RGB -> AVC444-YUV conversion **/ +/****************************************************************************/ + +static INLINE void ssse3_RGBToAVC444YUV_BGRX_ROW( + const BYTE* src, BYTE* ydst, BYTE* udst1, BYTE* udst2, BYTE* vdst1, BYTE* vdst2, BOOL isEvenRow, UINT32 width) +{ + UINT32 x; + __m128i vector128, y_factors, u_factors, v_factors, smask; + __m128i x1, x2, x3, x4, y, y1, y2, u, u1, u2, v, v1, v2; + const __m128i* argb = (const __m128i*) src; + __m128i* py = (__m128i*) ydst; + __m64* pu1 = (__m64*) udst1; + __m64* pu2 = (__m64*) udst2; + __m64* pv1 = (__m64*) vdst1; + __m64* pv2 = (__m64*) vdst2; + y_factors = _mm_load_si128((__m128i*)bgrx_y_factors); + u_factors = _mm_load_si128((__m128i*)bgrx_u_factors); + v_factors = _mm_load_si128((__m128i*)bgrx_v_factors); + vector128 = _mm_load_si128((__m128i*)const_buf_128b); + + smask = _mm_set_epi8(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0); + + for (x = 0; x < width; x += 16) + { + /* store 16 rgba pixels in 4 128 bit registers */ + x1 = _mm_load_si128(argb++); // 1st 4 pixels + x2 = _mm_load_si128(argb++); // 2nd 4 pixels + x3 = _mm_load_si128(argb++); // 3rd 4 pixels + x4 = _mm_load_si128(argb++); // 4th 4 pixels + + /* Y: multiplications with subtotals and horizontal sums */ + y1 = _mm_hadd_epi16(_mm_maddubs_epi16(x1, y_factors), _mm_maddubs_epi16(x2, y_factors)); + y2 = _mm_hadd_epi16(_mm_maddubs_epi16(x3, y_factors), _mm_maddubs_epi16(x4, y_factors)); + /* Y: shift the results (logical) */ + y1 = _mm_srli_epi16(y1, 7); + y2 = _mm_srli_epi16(y2, 7); + /* Y: pack (unsigned) 16 words into bytes */ + y = _mm_packus_epi16(y1, y2); + + /* U: multiplications with subtotals and horizontal sums */ + u1 = _mm_hadd_epi16(_mm_maddubs_epi16(x1, u_factors), _mm_maddubs_epi16(x2, u_factors)); + u2 = _mm_hadd_epi16(_mm_maddubs_epi16(x3, u_factors), _mm_maddubs_epi16(x4, u_factors)); + /* U: shift the results (arithmetic) */ + u1 = _mm_srai_epi16(u1, 7); + u2 = _mm_srai_epi16(u2, 7); + /* U: pack (signed) 16 words into bytes */ + u = _mm_packs_epi16(u1, u2); + /* U: add 128 */ + u = _mm_add_epi8(u, vector128); + + /* V: multiplications with subtotals and horizontal sums */ + v1 = _mm_hadd_epi16(_mm_maddubs_epi16(x1, v_factors), _mm_maddubs_epi16(x2, v_factors)); + v2 = _mm_hadd_epi16(_mm_maddubs_epi16(x3, v_factors), _mm_maddubs_epi16(x4, v_factors)); + /* V: shift the results (arithmetic) */ + v1 = _mm_srai_epi16(v1, 7); + v2 = _mm_srai_epi16(v2, 7); + /* V: pack (signed) 16 words into bytes */ + v = _mm_packs_epi16(v1, v2); + /* V: add 128 */ + v = _mm_add_epi8(v, vector128); + + + /* store y */ + _mm_storeu_si128(py++, y); + + /* store u and v */ + if (isEvenRow) + { + u = _mm_shuffle_epi8(u, smask); + v = _mm_shuffle_epi8(v, smask); + _mm_storel_pi(pu1++, _mm_castsi128_ps(u)); + _mm_storeh_pi(pu2++, _mm_castsi128_ps(u)); + _mm_storel_pi(pv1++, _mm_castsi128_ps(v)); + _mm_storeh_pi(pv2++, _mm_castsi128_ps(v)); + } + else + { + _mm_storel_pi(pu1, _mm_castsi128_ps(u)); + _mm_storeh_pi(pu2, _mm_castsi128_ps(u)); + _mm_storel_pi(pv1, _mm_castsi128_ps(v)); + _mm_storeh_pi(pv2, _mm_castsi128_ps(v)); + pu1 += 2; + pu2 += 2; + pv1 += 2; + pv2 += 2; + } + } +} + + +static pstatus_t ssse3_RGBToAVC444YUV_BGRX( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pDst1[3], const UINT32 dst1Step[3], + BYTE* pDst2[3], const UINT32 dst2Step[3], + const prim_size_t* roi) +{ + UINT32 y, numRows; + BOOL evenRow = TRUE; + BYTE *b1, *b2, *b3, *b4, *b5, *b6, *b7; + const BYTE* pMaxSrc = pSrc + (roi->height - 1) * srcStep; + + if (roi->height < 1 || roi->width < 1) + { + return !PRIMITIVES_SUCCESS; + } + + if (roi->width % 16 || (unsigned long)pSrc % 16 || srcStep % 16) + { + return generic->RGBToAVC444YUV(pSrc, srcFormat, srcStep, pDst1, dst1Step, pDst2, dst2Step, roi); + } + + numRows = (roi->height + 1) & ~1; + + for (y = 0; y < numRows; y++, evenRow = !evenRow) + { + const BYTE *src = y < roi->height ? pSrc + y * srcStep : pMaxSrc; + UINT32 i = y >> 1; + + b1 = pDst1[0] + y * dst1Step[0]; + + if (evenRow) + { + b2 = pDst1[1] + i * dst1Step[1]; + b3 = pDst1[2] + i * dst1Step[2]; + b6 = pDst2[1] + i * dst2Step[1]; + b7 = pDst2[2] + i * dst2Step[2]; + ssse3_RGBToAVC444YUV_BGRX_ROW(src, b1, b2, b6, b3, b7, TRUE, roi->width); + } + else + { + b4 = pDst2[0] + dst2Step[0] * ((i & ~7) + i); + b5 = b4 + 8 * dst2Step[0]; + ssse3_RGBToAVC444YUV_BGRX_ROW(src, b1, b4, b4 + 8, b5, b5 + 8, FALSE, roi->width); + } + } + + return PRIMITIVES_SUCCESS; +} + + +static pstatus_t ssse3_RGBToAVC444YUV( + const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep, + BYTE* pDst1[3], const UINT32 dst1Step[3], + BYTE* pDst2[3], const UINT32 dst2Step[3], + const prim_size_t* roi) +{ + switch (srcFormat) + { + case PIXEL_FORMAT_BGRX32: + case PIXEL_FORMAT_BGRA32: + return ssse3_RGBToAVC444YUV_BGRX(pSrc, srcFormat, srcStep, pDst1, dst1Step, pDst2, dst2Step, roi); + + default: + return generic->RGBToAVC444YUV(pSrc, srcFormat, srcStep, pDst1, dst1Step, pDst2, dst2Step, roi); + } +} + +#elif defined(WITH_NEON) + +static INLINE uint8x8_t neon_YUV2R(int32x4_t Ch, int32x4_t Cl, + int16x4_t Dh, int16x4_t Dl, + int16x4_t Eh, int16x4_t El) +{ + /* R = (256 * Y + 403 * (V - 128)) >> 8 */ + const int16x4_t c403 = vdup_n_s16(403); + const int32x4_t CEh = vmlal_s16(Ch, Eh, c403); + const int32x4_t CEl = vmlal_s16(Cl, El, c403); + const int32x4_t Rh = vrshrq_n_s32(CEh, 8); + const int32x4_t Rl = vrshrq_n_s32(CEl, 8); + const int16x8_t R = vcombine_s16(vqmovn_s32(Rl), vqmovn_s32(Rh)); + return vqmovun_s16(R); +} + +static INLINE uint8x8_t neon_YUV2G(int32x4_t Ch, int32x4_t Cl, + int16x4_t Dh, int16x4_t Dl, + int16x4_t Eh, int16x4_t El) +{ + /* G = (256L * Y - 48 * (U - 128) - 120 * (V - 128)) >> 8 */ + const int16x4_t c48 = vdup_n_s16(48); + const int16x4_t c120 = vdup_n_s16(120); + const int32x4_t CDh = vmlsl_s16(Ch, Dh, c48); + const int32x4_t CDl = vmlsl_s16(Cl, Dl, c48); + const int32x4_t CDEh = vmlsl_s16(CDh, Eh, c120); + const int32x4_t CDEl = vmlsl_s16(CDl, El, c120); + const int32x4_t Gh = vrshrq_n_s32(CDEh, 8); + const int32x4_t Gl = vrshrq_n_s32(CDEl, 8); + const int16x8_t G = vcombine_s16(vqmovn_s32(Gl), vqmovn_s32(Gh)); + return vqmovun_s16(G); +} + +static INLINE uint8x8_t neon_YUV2B(int32x4_t Ch, int32x4_t Cl, + int16x4_t Dh, int16x4_t Dl, + int16x4_t Eh, int16x4_t El) +{ + /* B = (256L * Y + 475 * (U - 128)) >> 8*/ + const int16x4_t c475 = vdup_n_s16(475); + const int32x4_t CDh = vmlal_s16(Ch, Dh, c475); + const int32x4_t CDl = vmlal_s16(Ch, Dl, c475); + const int32x4_t Bh = vrshrq_n_s32(CDh, 8); + const int32x4_t Bl = vrshrq_n_s32(CDl, 8); + const int16x8_t B = vcombine_s16(vqmovn_s32(Bl), vqmovn_s32(Bh)); + return vqmovun_s16(B); +} + +static INLINE pstatus_t neon_YUV420ToX( + const BYTE* pSrc[3], const UINT32 srcStep[3], + BYTE* pDst, UINT32 dstStep, + const prim_size_t* roi, const uint8_t rPos, const uint8_t gPos, + const uint8_t bPos, const uint8_t aPos) +{ + UINT32 y; + const UINT32 nWidth = roi->width; + const UINT32 nHeight = roi->height; + const int16x8_t c128 = vdupq_n_s16(128); + + for (y = 0; y < nHeight; y += 2) + { + const uint8_t* pY1 = pSrc[0] + y * srcStep[0]; + const uint8_t* pY2 = pY1 + srcStep[0]; + const uint8_t* pU = pSrc[1] + (y / 2) * srcStep[1]; + const uint8_t* pV = pSrc[2] + (y / 2) * srcStep[2]; + uint8_t* pRGB1 = pDst + y * dstStep; + uint8_t* pRGB2 = pRGB1 + dstStep; + UINT32 x; + const BOOL lastY = y >= nHeight - 1; + + for (x = 0; x < nWidth;) + { + const BOOL lastX = (nWidth - x) < 16; + const uint8x8_t Uraw = vld1_u8(pU); + const uint8x8x2_t Uu = vzip_u8(Uraw, Uraw); + const int16x8_t U1 = vreinterpretq_s16_u16(vmovl_u8(Uu.val[0])); + const int16x8_t U2 = vreinterpretq_s16_u16(vmovl_u8(Uu.val[1])); + const uint8x8_t Vraw = vld1_u8(pV); + const uint8x8x2_t Vu = vzip_u8(Vraw, Vraw); + const int16x8_t V1 = vreinterpretq_s16_u16(vmovl_u8(Vu.val[0])); + const int16x8_t V2 = vreinterpretq_s16_u16(vmovl_u8(Vu.val[1])); + const int16x8_t D1 = vsubq_s16(U1, c128); + const int16x4_t D1h = vget_high_s16(D1); + const int16x4_t D1l = vget_low_s16(D1); + const int16x8_t E1 = vsubq_s16(V1, c128); + const int16x4_t E1h = vget_high_s16(E1); + const int16x4_t E1l = vget_low_s16(E1); + const int16x8_t D2 = vsubq_s16(U2, c128); + const int16x4_t D2h = vget_high_s16(D2); + const int16x4_t D2l = vget_low_s16(D2); + const int16x8_t E2 = vsubq_s16(V2, c128); + const int16x4_t E2h = vget_high_s16(E2); + const int16x4_t E2l = vget_low_s16(E2); + uint8x8x4_t bgrx; + bgrx.val[aPos] = vdup_n_u8(0xFF); + { + const uint8x8_t Y1u = vld1_u8(pY1); + const int16x8_t Y1 = vreinterpretq_s16_u16(vmovl_u8(Y1u)); + const int32x4_t Ch = vmulq_n_s32(vmovl_s16(vget_high_s16(Y1)), 256); /* Y * 256 */ + const int32x4_t Cl = vmulq_n_s32(vmovl_s16(vget_low_s16(Y1)), 256); /* Y * 256 */ + bgrx.val[rPos] = neon_YUV2R(Ch, Cl, D1h, D1l, E1h, E1l); + bgrx.val[gPos] = neon_YUV2G(Ch, Cl, D1h, D1l, E1h, E1l); + bgrx.val[bPos] = neon_YUV2B(Ch, Cl, D1h, D1l, E1h, E1l); + vst4_u8(pRGB1, bgrx); + pRGB1 += 32; + pY1 += 8; + x += 8; + } + + if (!lastX) + { + const uint8x8_t Y1u = vld1_u8(pY1); + const int16x8_t Y1 = vreinterpretq_s16_u16(vmovl_u8(Y1u)); + const int32x4_t Ch = vmulq_n_s32(vmovl_s16(vget_high_s16(Y1)), 256); /* Y * 256 */ + const int32x4_t Cl = vmulq_n_s32(vmovl_s16(vget_low_s16(Y1)), 256); /* Y * 256 */ + bgrx.val[rPos] = neon_YUV2R(Ch, Cl, D2h, D2l, E2h, E2l); + bgrx.val[gPos] = neon_YUV2G(Ch, Cl, D2h, D2l, E2h, E2l); + bgrx.val[bPos] = neon_YUV2B(Ch, Cl, D2h, D2l, E2h, E2l); + vst4_u8(pRGB1, bgrx); + pRGB1 += 32; + pY1 += 8; + x += 8; + } + + if (!lastY) + { + const uint8x8_t Y2u = vld1_u8(pY2); + const int16x8_t Y2 = vreinterpretq_s16_u16(vmovl_u8(Y2u)); + const int32x4_t Ch = vmulq_n_s32(vmovl_s16(vget_high_s16(Y2)), 256); /* Y * 256 */ + const int32x4_t Cl = vmulq_n_s32(vmovl_s16(vget_low_s16(Y2)), 256); /* Y * 256 */ + bgrx.val[rPos] = neon_YUV2R(Ch, Cl, D1h, D1l, E1h, E1l); + bgrx.val[gPos] = neon_YUV2G(Ch, Cl, D1h, D1l, E1h, E1l); + bgrx.val[bPos] = neon_YUV2B(Ch, Cl, D1h, D1l, E1h, E1l); + vst4_u8(pRGB2, bgrx); + pRGB2 += 32; + pY2 += 8; + + if (!lastX) + { + const uint8x8_t Y2u = vld1_u8(pY2); + const int16x8_t Y2 = vreinterpretq_s16_u16(vmovl_u8(Y2u)); + const int32x4_t Ch = vmulq_n_s32(vmovl_s16(vget_high_s16(Y2)), 256); /* Y * 256 */ + const int32x4_t Cl = vmulq_n_s32(vmovl_s16(vget_low_s16(Y2)), 256); /* Y * 256 */ + bgrx.val[rPos] = neon_YUV2R(Ch, Cl, D2h, D2l, E2h, E2l); + bgrx.val[gPos] = neon_YUV2G(Ch, Cl, D2h, D2l, E2h, E2l); + bgrx.val[bPos] = neon_YUV2B(Ch, Cl, D2h, D2l, E2h, E2l); + vst4_u8(pRGB2, bgrx); + pRGB2 += 32; + pY2 += 8; + } + } + + pU += 8; + pV += 8; + } + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t neon_YUV420ToRGB_8u_P3AC4R( + const BYTE* pSrc[3], const UINT32 srcStep[3], + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + const prim_size_t* roi) +{ + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return neon_YUV420ToX(pSrc, srcStep, pDst, dstStep, roi, 2, 1, 0, 3); + + case PIXEL_FORMAT_RGBA32: + case PIXEL_FORMAT_RGBX32: + return neon_YUV420ToX(pSrc, srcStep, pDst, dstStep, roi, 0, 1, 2, 3); + + case PIXEL_FORMAT_ARGB32: + case PIXEL_FORMAT_XRGB32: + return neon_YUV420ToX(pSrc, srcStep, pDst, dstStep, roi, 1, 2, 3, 0); + + case PIXEL_FORMAT_ABGR32: + case PIXEL_FORMAT_XBGR32: + return neon_YUV420ToX(pSrc, srcStep, pDst, dstStep, roi, 3, 2, 1, 0); + + default: + return generic->YUV420ToRGB_8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} + +static INLINE pstatus_t neon_YUV444ToX( + const BYTE* pSrc[3], const UINT32 srcStep[3], + BYTE* pDst, UINT32 dstStep, + const prim_size_t* roi, const uint8_t rPos, const uint8_t gPos, + const uint8_t bPos, const uint8_t aPos) +{ + UINT32 y; + const UINT32 nWidth = roi->width; + const UINT32 nHeight = roi->height; + const UINT32 yPad = srcStep[0] - roi->width; + const UINT32 uPad = srcStep[1] - roi->width; + const UINT32 vPad = srcStep[2] - roi->width; + const UINT32 dPad = dstStep - roi->width * 4; + const uint8_t* pY = pSrc[0]; + const uint8_t* pU = pSrc[1]; + const uint8_t* pV = pSrc[2]; + uint8_t* pRGB = pDst; + const int16x8_t c128 = vdupq_n_s16(128); + const int16x4_t c48 = vdup_n_s16(48); + const int16x4_t c120 = vdup_n_s16(120); + const int16x4_t c403 = vdup_n_s16(403); + const int16x4_t c475 = vdup_n_s16(475); + const DWORD pad = nWidth % 8; + + for (y = 0; y < nHeight; y++) + { + UINT32 x; + + for (x = 0; x < nWidth - pad; x += 8) + { + const uint8x8_t Yu = vld1_u8(pY); + const int16x8_t Y = vreinterpretq_s16_u16(vmovl_u8(Yu)); + const uint8x8_t Uu = vld1_u8(pU); + const int16x8_t U = vreinterpretq_s16_u16(vmovl_u8(Uu)); + const uint8x8_t Vu = vld1_u8(pV); + const int16x8_t V = vreinterpretq_s16_u16(vmovl_u8(Vu)); + /* Do the calculations on Y in 32bit width, the result of 255 * 256 does not fit + * a signed 16 bit value. */ + const int32x4_t Ch = vmulq_n_s32(vmovl_s16(vget_high_s16(Y)), 256); /* Y * 256 */ + const int32x4_t Cl = vmulq_n_s32(vmovl_s16(vget_low_s16(Y)), 256); /* Y * 256 */ + const int16x8_t D = vsubq_s16(U, c128); + const int16x4_t Dh = vget_high_s16(D); + const int16x4_t Dl = vget_low_s16(D); + const int16x8_t E = vsubq_s16(V, c128); + const int16x4_t Eh = vget_high_s16(E); + const int16x4_t El = vget_low_s16(E); + uint8x8x4_t bgrx; + { + /* B = (256L * Y + 475 * (U - 128)) >> 8*/ + const int32x4_t CDh = vmlal_s16(Ch, Dh, c475); + const int32x4_t CDl = vmlal_s16(Cl, Dl, c475); + const int32x4_t Bh = vrshrq_n_s32(CDh, 8); + const int32x4_t Bl = vrshrq_n_s32(CDl, 8); + const int16x8_t B = vcombine_s16(vqmovn_s32(Bl), vqmovn_s32(Bh)); + bgrx.val[bPos] = vqmovun_s16(B); + } + { + /* G = (256L * Y - 48 * (U - 128) - 120 * (V - 128)) >> 8 */ + const int32x4_t CDh = vmlsl_s16(Ch, Dh, c48); + const int32x4_t CDl = vmlsl_s16(Cl, Dl, c48); + const int32x4_t CDEh = vmlsl_s16(CDh, Eh, c120); + const int32x4_t CDEl = vmlsl_s16(CDl, El, c120); + const int32x4_t Gh = vrshrq_n_s32(CDEh, 8); + const int32x4_t Gl = vrshrq_n_s32(CDEl, 8); + const int16x8_t G = vcombine_s16(vqmovn_s32(Gl), vqmovn_s32(Gh)); + bgrx.val[gPos] = vqmovun_s16(G); + } + { + /* R = (256 * Y + 403 * (V - 128)) >> 8 */ + const int32x4_t CEh = vmlal_s16(Ch, Eh, c403); + const int32x4_t CEl = vmlal_s16(Cl, El, c403); + const int32x4_t Rh = vrshrq_n_s32(CEh, 8); + const int32x4_t Rl = vrshrq_n_s32(CEl, 8); + const int16x8_t R = vcombine_s16(vqmovn_s32(Rl), vqmovn_s32(Rh)); + bgrx.val[rPos] = vqmovun_s16(R); + } + { + /* A */ + bgrx.val[aPos] = vdup_n_u8(0xFF); + } + vst4_u8(pRGB, bgrx); + pRGB += 32; + pY += 8; + pU += 8; + pV += 8; + } + + for (x = 0; x < pad; x++) + { + const BYTE Y = *pY++; + const BYTE U = *pU++; + const BYTE V = *pV++; + const BYTE r = YUV2R(Y, U, V); + const BYTE g = YUV2G(Y, U, V); + const BYTE b = YUV2B(Y, U, V); + pRGB[aPos] = 0xFF; + pRGB[rPos] = r; + pRGB[gPos] = g; + pRGB[bPos] = b; + pRGB += 4; + } + + pRGB += dPad; + pY += yPad; + pU += uPad; + pV += vPad; + } + + return PRIMITIVES_SUCCESS; +} + +static pstatus_t neon_YUV444ToRGB_8u_P3AC4R( + const BYTE* pSrc[3], const UINT32 srcStep[3], + BYTE* pDst, UINT32 dstStep, UINT32 DstFormat, + const prim_size_t* roi) +{ + switch (DstFormat) + { + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + return neon_YUV444ToX(pSrc, srcStep, pDst, dstStep, roi, 2, 1, 0, 3); + + case PIXEL_FORMAT_RGBA32: + case PIXEL_FORMAT_RGBX32: + return neon_YUV444ToX(pSrc, srcStep, pDst, dstStep, roi, 0, 1, 2, 3); + + case PIXEL_FORMAT_ARGB32: + case PIXEL_FORMAT_XRGB32: + return neon_YUV444ToX(pSrc, srcStep, pDst, dstStep, roi, 1, 2, 3, 0); + + case PIXEL_FORMAT_ABGR32: + case PIXEL_FORMAT_XBGR32: + return neon_YUV444ToX(pSrc, srcStep, pDst, dstStep, roi, 3, 2, 1, 0); + + default: + return generic->YUV444ToRGB_8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi); + } +} + +static pstatus_t neon_YUV420CombineToYUV444( + const BYTE* pMainSrc[3], const UINT32 srcMainStep[3], + const BYTE* pAuxSrc[3], const UINT32 srcAuxStep[3], + BYTE* pDst[3], const UINT32 dstStep[3], + const prim_size_t* roi) +{ + UINT32 x, y; + const UINT32 nWidth = roi->width; + const UINT32 nHeight = roi->height; + const UINT32 halfWidth = nWidth / 2, halfHeight = nHeight / 2; + const UINT32 oddY = 1; + const UINT32 evenY = 0; + /* The auxilary frame is aligned to multiples of 16x16. + * We need the padded height for B4 and B5 conversion. */ + const UINT32 padHeigth = roi->height + 16 - roi->height % 16; + + if (pMainSrc && pMainSrc[0] && pMainSrc[1] && pMainSrc[2]) + { + /* Y data is already here... */ + /* B1 */ + for (y = 0; y < nHeight; y++) + { + const BYTE* Ym = pMainSrc[0] + srcMainStep[0] * y; + BYTE* pY = pDst[0] + dstStep[0] * y; + memcpy(pY, Ym, nWidth); + } + + /* The first half of U, V are already here part of this frame. */ + /* B2 and B3 */ + for (y = 0; y < halfHeight; y++) + { + const UINT32 val2y = (2 * y + evenY); + const BYTE* Um = pMainSrc[1] + srcMainStep[1] * y; + const BYTE* Vm = pMainSrc[2] + srcMainStep[2] * y; + BYTE* pU = pDst[1] + dstStep[1] * val2y; + BYTE* pV = pDst[2] + dstStep[2] * val2y; + BYTE* pU1 = pU + dstStep[1]; + BYTE* pV1 = pV + dstStep[2]; + + for (x = 0; x + 16 < halfWidth; x += 16) + { + { + const uint8x16_t u = vld1q_u8(Um); + uint8x16x2_t u2x; + u2x.val[0] = u; + u2x.val[1] = u; + vst2q_u8(pU, u2x); + vst2q_u8(pU1, u2x); + Um += 16; + pU += 32; + pU1 += 32; + } + { + const uint8x16_t v = vld1q_u8(Vm); + uint8x16x2_t v2x; + v2x.val[0] = v; + v2x.val[1] = v; + vst2q_u8(pV, v2x); + vst2q_u8(pV1, v2x); + Vm += 16; + pV += 32; + pV1 += 32; + } + } + + for (; x < halfWidth; x++) + { + const BYTE u = *Um++; + const BYTE v = *Vm++; + *pU++ = u; + *pU++ = u; + *pU1++ = u; + *pU1++ = u; + *pV++ = v; + *pV++ = v; + *pV1++ = v; + *pV1++ = v; + } + } + } + + if (!pAuxSrc || !pAuxSrc[0] || !pAuxSrc[1] || !pAuxSrc[2]) + return PRIMITIVES_SUCCESS; + + /* The second half of U and V is a bit more tricky... */ + /* B4 and B5 */ + for (y = 0; y < padHeigth; y += 16) + { + const BYTE* Ya = pAuxSrc[0] + srcAuxStep[0] * y; + UINT32 x; + BYTE* pU = pDst[1] + dstStep[1] * (y + 1); + BYTE* pV = pDst[2] + dstStep[2] * (y + 1); + + for (x = 0; x < 8; x++) + { + if (y + x >= nHeight) + continue; + + memcpy(pU, Ya, nWidth); + pU += dstStep[1] * 2; + Ya += srcAuxStep[0]; + } + + for (x = 0; x < 8; x++) + { + if (y + x >= nHeight) + continue; + + memcpy(pV, Ya, nWidth); + pV += dstStep[1] * 2; + Ya += srcAuxStep[0]; + } + } + + /* B6 and B7 */ + for (y = 0; y < halfHeight; y++) + { + const UINT32 val2y = (y * 2 + evenY); + const BYTE* Ua = pAuxSrc[1] + srcAuxStep[1] * y; + const BYTE* Va = pAuxSrc[2] + srcAuxStep[2] * y; + BYTE* pU = pDst[1] + dstStep[1] * val2y; + BYTE* pV = pDst[2] + dstStep[2] * val2y; + + for (x = 0; x + 16 < halfWidth; x += 16) + { + { + const uint8x16_t u = vld1q_u8(Ua); + uint8x16x2_t uu = vld2q_u8(pU); + uu.val[1] = u; + vst2q_u8(pU, uu); + Ua += 16; + pU += 32; + } + { + const uint8x16_t v = vld1q_u8(Va); + uint8x16x2_t vv = vld2q_u8(pV); + vv.val[1] = v; + vst2q_u8(pV, vv); + Va += 16; + pV += 32; + } + } + + for (; x < halfWidth; x++) + { + pU++; + *pU++ = *Ua++; + pV++; + *pV++ = *Va++; + } + } + + /* Filter */ + for (y = 0; y < halfHeight; y++) + { + const UINT32 val2y = (y * 2 + evenY); + const UINT32 val2y1 = val2y + oddY; + BYTE* pU = pDst[1] + dstStep[1] * val2y; + BYTE* pV = pDst[2] + dstStep[2] * val2y; + BYTE* pU1 = pU + dstStep[1]; + BYTE* pV1 = pV + dstStep[2]; + + if (val2y1 > nHeight) + continue; + + for (x = 0; x + 16 < halfWidth; x += 16) + { + { + /* U = (U2x,2y << 2) - U2x1,2y - U2x,2y1 - U2x1,2y1 */ + uint8x8x2_t u = vld2_u8(pU); + const int16x8_t up = vreinterpretq_s16_u16(vshll_n_u8(u.val[0], 2)); /* Ux2,2y << 2 */ + const uint8x8x2_t u1 = vld2_u8(pU1); + const uint16x8_t usub = vaddl_u8(u1.val[1], u1.val[0]); /* U2x,2y1 + U2x1,2y1 */ + const int16x8_t us = vreinterpretq_s16_u16(vaddw_u8(usub, + u.val[1])); /* U2x1,2y + U2x,2y1 + U2x1,2y1 */ + const int16x8_t un = vsubq_s16(up, us); + const uint8x8_t u8 = vqmovun_s16(un); /* CLIP(un) */ + u.val[0] = u8; + vst2_u8(pU, u); + pU += 16; + pU1 += 16; + } + { + /* V = (V2x,2y << 2) - V2x1,2y - V2x,2y1 - V2x1,2y1 */ + uint8x8x2_t v = vld2_u8(pV); + const int16x8_t vp = vreinterpretq_s16_u16(vshll_n_u8(v.val[0], 2)); /* Vx2,2y << 2 */ + const uint8x8x2_t v1 = vld2_u8(pV1); + const uint16x8_t vsub = vaddl_u8(v1.val[1], v1.val[0]); /* V2x,2y1 + V2x1,2y1 */ + const int16x8_t vs = vreinterpretq_s16_u16(vaddw_u8(vsub, + v.val[1])); /* V2x1,2y + V2x,2y1 + V2x1,2y1 */ + const int16x8_t vn = vsubq_s16(vp, vs); + const uint8x8_t v8 = vqmovun_s16(vn); /* CLIP(vn) */ + v.val[0] = v8; + vst2_u8(pV, v); + pV += 16; + pV1 += 16; + } + } + + for (; x < halfWidth; x++) + { + const UINT32 val2x = 0; + const UINT32 val2x1 = val2x + 1; + const INT32 up = pU[val2x] * 4; + const INT32 vp = pV[val2x] * 4; + INT32 u2020; + INT32 v2020; + + if (val2x1 > nWidth) + continue; + + u2020 = up - pU[val2x1] - pU1[val2x] - pU1[val2x1]; + v2020 = vp - pV[val2x1] - pV1[val2x] - pV1[val2x1]; + *pU = CLIP(u2020); + *pV = CLIP(v2020); + pU += 2; + pV += 2; + } + } + + return PRIMITIVES_SUCCESS; +} #endif void primitives_init_YUV_opt(primitives_t* prims) @@ -335,7 +1470,19 @@ if (IsProcessorFeaturePresentEx(PF_EX_SSSE3) && IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) { - prims->YUV420ToRGB_8u_P3AC4R = ssse3_YUV420ToRGB_8u_P3AC4R; + prims->RGBToYUV420_8u_P3AC4R = ssse3_RGBToYUV420; + prims->RGBToAVC444YUV = ssse3_RGBToAVC444YUV; + prims->YUV420ToRGB_8u_P3AC4R = ssse3_YUV420ToRGB; + prims->YUV444ToRGB_8u_P3AC4R = ssse3_YUV444ToRGB_8u_P3AC4R; + } + +#elif defined(WITH_NEON) + + if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) + { + prims->YUV420ToRGB_8u_P3AC4R = neon_YUV420ToRGB_8u_P3AC4R; + prims->YUV444ToRGB_8u_P3AC4R = neon_YUV444ToRGB_8u_P3AC4R; + prims->YUV420CombineToYUV444 = neon_YUV420CombineToYUV444; } #endif diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/measure.h freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/measure.h --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/measure.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/measure.h 2017-03-03 08:39:24.000000000 +0000 @@ -22,8 +22,12 @@ * Define GOOGLE_PROFILER if you want gperftools included. */ -#ifndef __MEASURE_H_INCLUDED__ -#define __MEASURE_H_INCLUDED__ +#ifndef TEST_MEASURE_H_INCLUDED +#define TEST_MEASURE_H_INCLUDED + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesColors.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesColors.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesColors.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesColors.c 2017-03-03 08:39:24.000000000 +0000 @@ -17,58 +17,104 @@ #endif #include -#include "prim_test.h" +#include -static const int RGB_TRIAL_ITERATIONS = 1000; -static const int YCBCR_TRIAL_ITERATIONS = 1000; -static const float TEST_TIME = 4.0; +#include "prim_test.h" /* ------------------------------------------------------------------------- */ -static BOOL test_RGBToRGB_16s8u_P3AC4R_func(void) +static BOOL test_RGBToRGB_16s8u_P3AC4R_func(prim_size_t roi, DWORD DstFormat) { - INT16 ALIGN(r[4096]), ALIGN(g[4096]), ALIGN(b[4096]); - UINT32 ALIGN(out1[4096]); - UINT32 ALIGN(out2[4096]); + INT16* r; + INT16* g; + INT16* b; + BYTE* out1; + BYTE* out2; int i; BOOL failed = FALSE; - INT16* ptrs[3]; - prim_size_t roi = { 64, 64 }; + const INT16* ptrs[3]; + const UINT32 rgbStride = roi.width * 2; + const UINT32 dstStride = roi.width * 4; + PROFILER_DEFINE(genericProf); + PROFILER_DEFINE(optProf); + PROFILER_CREATE(genericProf, "RGBToRGB_16s8u_P3AC4R-GENERIC"); + PROFILER_CREATE(optProf, "RGBToRGB_16s8u_P3AC4R-OPTIMIZED"); + r = _aligned_malloc(rgbStride * roi.height, 16); + g = _aligned_malloc(rgbStride * roi.height, 16); + b = _aligned_malloc(rgbStride * roi.height, 16); + out1 = _aligned_malloc(dstStride * roi.height, 16); + out2 = _aligned_malloc(dstStride * roi.height, 16); - winpr_RAND((BYTE*)r, sizeof(r)); - winpr_RAND((BYTE*)g, sizeof(g)); - winpr_RAND((BYTE*)b, sizeof(b)); + if (!r || !g || !b || !out1 || !out2) + goto fail; - /* clear upper bytes */ - for (i = 0; i < 4096; ++i) +#if 0 { - r[i] &= 0x00FFU; - g[i] &= 0x00FFU; - b[i] &= 0x00FFU; - } + UINT32 x, y; + for (y = 0; y < roi.height; y++) + { + for (x = 0; x < roi.width; x++) + { + r[y * roi.width + x] = 0x01; + g[y * roi.width + x] = 0x02; + b[y * roi.width + x] = 0x04; + } + } + } +#else + winpr_RAND((BYTE*)r, rgbStride * roi.height); + winpr_RAND((BYTE*)g, rgbStride * roi.height); + winpr_RAND((BYTE*)b, rgbStride * roi.height); +#endif ptrs[0] = r; ptrs[1] = g; ptrs[2] = b; - if (generic->RGBToRGB_16s8u_P3AC4R((const INT16**) ptrs, 64 * 2, - (BYTE*) out1, 64 * 4, PIXEL_FORMAT_RGBA32, - &roi) != PRIMITIVES_SUCCESS) - return FALSE; + PROFILER_ENTER(genericProf); - if (optimized->RGBToRGB_16s8u_P3AC4R((const INT16**) ptrs, 64 * 2, - (BYTE*) out2, 64 * 4, PIXEL_FORMAT_RGBA32, - &roi) != PRIMITIVES_SUCCESS) - return FALSE; + if (generic->RGBToRGB_16s8u_P3AC4R(ptrs, rgbStride, + out1, dstStride, DstFormat, + &roi) != PRIMITIVES_SUCCESS) + goto fail; - for (i = 0; i < 4096; ++i) + PROFILER_EXIT(genericProf); + PROFILER_ENTER(optProf); + + if (optimized->RGBToRGB_16s8u_P3AC4R(ptrs, rgbStride, + out2, dstStride, DstFormat, + &roi) != PRIMITIVES_SUCCESS) + goto fail; + + PROFILER_EXIT(optProf); + + if (memcmp(out1, out2, dstStride * roi.height) != 0) { - if (out1[i] != out2[i]) + for (i = 0; i < roi.width * roi.height; ++i) { - printf("RGBToRGB-SSE FAIL: out1[%d]=0x%08"PRIx32" out2[%d]=0x%08"PRIx32"\n", - i, out1[i], i, out2[i]); - failed = TRUE; + const UINT32 o1 = ReadColor(out1 + 4 * i, DstFormat); + const UINT32 o2 = ReadColor(out2 + 4 * i, DstFormat); + + if (o1 != o2) + { + printf("RGBToRGB_16s8u_P3AC4R FAIL: out1[%d]=0x%08"PRIx32" out2[%d]=0x%08"PRIx32"\n", + i, out1[i], i, out2[i]); + failed = TRUE; + } } } + printf("Results for %lux%lu [%s]", roi.width, roi.height, GetColorFormatName(DstFormat)); + PROFILER_PRINT_HEADER; + PROFILER_PRINT(genericProf); + PROFILER_PRINT(optProf); + PROFILER_PRINT_FOOTER; +fail: + PROFILER_FREE(genericProf); + PROFILER_FREE(optProf); + _aligned_free(r); + _aligned_free(g); + _aligned_free(b); + _aligned_free(out1); + _aligned_free(out2); return !failed; } @@ -76,11 +122,10 @@ static BOOL test_RGBToRGB_16s8u_P3AC4R_speed(void) { const prim_size_t roi64x64 = { 64, 64 }; - INT16 ALIGN(r[4096+1]), ALIGN(g[4096+1]), ALIGN(b[4096+1]); - UINT32 ALIGN(dst[4096+1]); + INT16 ALIGN(r[4096 + 1]), ALIGN(g[4096 + 1]), ALIGN(b[4096 + 1]); + UINT32 ALIGN(dst[4096 + 1]); int i; INT16* ptrs[3]; - winpr_RAND((BYTE*)r, sizeof(r)); winpr_RAND((BYTE*)g, sizeof(g)); winpr_RAND((BYTE*)b, sizeof(b)); @@ -93,20 +138,20 @@ b[i] &= 0x00FFU; } - ptrs[0] = r+1; - ptrs[1] = g+1; - ptrs[2] = b+1; + ptrs[0] = r + 1; + ptrs[1] = g + 1; + ptrs[2] = b + 1; if (!speed_test("RGBToRGB_16s8u_P3AC4R", "aligned", g_Iterations, - (speed_test_fkt)generic->RGBToRGB_16s8u_P3AC4R, - (speed_test_fkt)optimized->RGBToRGB_16s8u_P3AC4R, - (const INT16**) ptrs, 64 * 2, (BYTE*) dst, 64 * 4, &roi64x64)) + (speed_test_fkt)generic->RGBToRGB_16s8u_P3AC4R, + (speed_test_fkt)optimized->RGBToRGB_16s8u_P3AC4R, + (const INT16**) ptrs, 64 * 2, (BYTE*) dst, 64 * 4, &roi64x64)) return FALSE; if (!speed_test("RGBToRGB_16s8u_P3AC4R", "unaligned", g_Iterations, - (speed_test_fkt)generic->RGBToRGB_16s8u_P3AC4R, - (speed_test_fkt)optimized->RGBToRGB_16s8u_P3AC4R, - (const INT16**) ptrs, 64 * 2, ((BYTE*) dst)+1, 64 * 4, &roi64x64)) + (speed_test_fkt)generic->RGBToRGB_16s8u_P3AC4R, + (speed_test_fkt)optimized->RGBToRGB_16s8u_P3AC4R, + (const INT16**) ptrs, 64 * 2, ((BYTE*) dst) + 1, 64 * 4, &roi64x64)) return FALSE; return TRUE; @@ -124,7 +169,6 @@ INT16* out1[3]; INT16* out2[3]; prim_size_t roi = { 64, 64 }; - winpr_RAND((BYTE*)y, sizeof(y)); winpr_RAND((BYTE*)cb, sizeof(cb)); winpr_RAND((BYTE*)cr, sizeof(cr)); @@ -152,12 +196,13 @@ out2[0] = r2; out2[1] = g2; out2[2] = b2; - status = generic->yCbCrToRGB_16s16s_P3P3(in, 64 * 2, out1, 64 * 2, &roi); + if (status != PRIMITIVES_SUCCESS) return FALSE; status = optimized->yCbCrToRGB_16s16s_P3P3(in, 64 * 2, out2, 64 * 2, &roi); + if (status != PRIMITIVES_SUCCESS) return FALSE; @@ -167,7 +212,8 @@ || (ABS(g1[i] - g2[i]) > 1) || (ABS(b1[i] - b2[i]) > 1)) { - printf("YCbCrToRGB-SSE FAIL[%d]: %"PRId16",%"PRId16",%"PRId16" vs %"PRId16",%"PRId16",%"PRId16"\n", i, + printf("YCbCrToRGB-SSE FAIL[%d]: %"PRId16",%"PRId16",%"PRId16" vs %"PRId16",%"PRId16",%"PRId16"\n", + i, r1[i], g1[i], b1[i], r2[i], g2[i], b2[i]); return FALSE; } @@ -185,7 +231,6 @@ int i; const INT16* input[3]; INT16* output[3]; - winpr_RAND((BYTE*)y, sizeof(y)); winpr_RAND((BYTE*)cb, sizeof(cb)); winpr_RAND((BYTE*)cr, sizeof(cr)); @@ -206,9 +251,9 @@ output[2] = b; if (!speed_test("yCbCrToRGB_16s16s_P3P3", "aligned", g_Iterations, - (speed_test_fkt)generic->yCbCrToRGB_16s16s_P3P3, - (speed_test_fkt)optimized->yCbCrToRGB_16s16s_P3P3, - input, 64 * 2, output, 64 * 2, &roi)) + (speed_test_fkt)generic->yCbCrToRGB_16s16s_P3P3, + (speed_test_fkt)optimized->yCbCrToRGB_16s16s_P3P3, + input, 64 * 2, output, 64 * 2, &roi)) return FALSE; return TRUE; @@ -216,24 +261,44 @@ int TestPrimitivesColors(int argc, char* argv[]) { + const DWORD formats[] = + { + PIXEL_FORMAT_ARGB32, + PIXEL_FORMAT_XRGB32, + PIXEL_FORMAT_ABGR32, + PIXEL_FORMAT_XBGR32, + PIXEL_FORMAT_RGBA32, + PIXEL_FORMAT_RGBX32, + PIXEL_FORMAT_BGRA32, + PIXEL_FORMAT_BGRX32 + }; + DWORD x; + prim_size_t roi = { 1920, 1080}; prim_test_setup(FALSE); - if (!test_RGBToRGB_16s8u_P3AC4R_func()) - return 1; - - if (g_TestPrimitivesPerformance) + for (x = 0; x < sizeof(formats) / sizeof(formats[0]); x++) { - if (!test_RGBToRGB_16s8u_P3AC4R_speed()) + if (!test_RGBToRGB_16s8u_P3AC4R_func(roi, formats[x])) return 1; - } - if (!test_yCbCrToRGB_16s16s_P3P3_func()) - return 1; +#if 0 - if (g_TestPrimitivesPerformance) - { - if (!test_yCbCrToRGB_16s16s_P3P3_speed()) + if (g_TestPrimitivesPerformance) + { + if (!test_RGBToRGB_16s8u_P3AC4R_speed()) + return 1; + } + + if (!test_yCbCrToRGB_16s16s_P3P3_func()) return 1; + + if (g_TestPrimitivesPerformance) + { + if (!test_yCbCrToRGB_16s16s_P3P3_speed()) + return 1; + } + +#endif } return 0; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesSign.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesSign.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesSign.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesSign.c 2017-03-03 08:39:24.000000000 +0000 @@ -25,16 +25,19 @@ static BOOL test_sign16s_func(void) { pstatus_t status; - INT16 ALIGN(src[TEST_BUFFER_SIZE]); - INT16 ALIGN(d1[TEST_BUFFER_SIZE]); - INT16 ALIGN(d2[TEST_BUFFER_SIZE]); - + INT16 ALIGN(src[TEST_BUFFER_SIZE + 16]); + INT16 ALIGN(d1[TEST_BUFFER_SIZE + 16]); + INT16 ALIGN(d2[TEST_BUFFER_SIZE + 16]); winpr_RAND((BYTE*)src, sizeof(src)); - + memset(d1, 0, sizeof(d1)); + memset(d2, 0, sizeof(d2)); status = generic->sign_16s(src + 1, d1 + 1, TEST_BUFFER_SIZE); + if (status != PRIMITIVES_SUCCESS) return FALSE; + status = optimized->sign_16s(src + 1, d2 + 1, TEST_BUFFER_SIZE); + if (status != PRIMITIVES_SUCCESS) return FALSE; @@ -42,9 +45,12 @@ return FALSE; status = generic->sign_16s(src + 1, d1 + 2, TEST_BUFFER_SIZE); + if (status != PRIMITIVES_SUCCESS) return FALSE; + status = optimized->sign_16s(src + 1, d2 + 2, TEST_BUFFER_SIZE); + if (status != PRIMITIVES_SUCCESS) return FALSE; @@ -60,15 +66,15 @@ winpr_RAND((BYTE*)src, sizeof(src)); if (!speed_test("sign16s", "aligned", g_Iterations, - (speed_test_fkt)generic->sign_16s, - (speed_test_fkt)optimized->sign_16s, src + 1, dst + 1, - MAX_TEST_SIZE)) + (speed_test_fkt)generic->sign_16s, + (speed_test_fkt)optimized->sign_16s, src + 1, dst + 1, + MAX_TEST_SIZE)) return FALSE; if (!speed_test("sign16s", "unaligned", g_Iterations, - (speed_test_fkt)generic->sign_16s, - (speed_test_fkt)optimized->sign_16s, src + 1, dst + 2, - MAX_TEST_SIZE)) + (speed_test_fkt)generic->sign_16s, + (speed_test_fkt)optimized->sign_16s, src + 1, dst + 2, + MAX_TEST_SIZE)) return FALSE; return TRUE; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesYCbCr.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesYCbCr.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesYCbCr.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesYCbCr.c 2017-03-03 08:39:24.000000000 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include "config.h" @@ -11,7 +12,7 @@ #define TAG __FILE__ -static INT16 TEST_Y_COMPONENT[4096] = +static const INT16 TEST_Y_COMPONENT[4096] = { -32, +16, +64, +272, -32, -16, +0, -16, -32, -24, -16, -8, +0, -24, -48, -72, @@ -527,7 +528,7 @@ +8, -24, -56, -88, -120, -120, -120, -120 }; -static INT16 TEST_CB_COMPONENT[4096] = +static const INT16 TEST_CB_COMPONENT[4096] = { +1728, +1730, +1732, +1734, +1736, +1738, +1740, +1742, +1744, +1740, +1736, +1732, +1728, +1796, +1864, +1804, @@ -1043,7 +1044,7 @@ +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192 }; -static INT16 TEST_CR_COMPONENT[4096] = +static const INT16 TEST_CR_COMPONENT[4096] = { -2112, -2114, -2116, -2118, -2120, -2122, -2124, -2126, -2128, -2118, -2108, -2098, -2088, -2150, -2212, -2146, @@ -1563,7 +1564,7 @@ * 64x64 XRGB Image */ -static UINT32 TEST_XRGB_IMAGE[4096] = +static const UINT32 TEST_XRGB_IMAGE[4096] = { 0xFF229cdf, 0xFF249de0, 0xFF259fe2, 0xFF2ca5e8, 0xFF229cdf, 0xFF229ce0, 0xFF239de0, 0xFF229ce0, 0xFF229cdf, 0xFF229cdf, 0xFF239ce0, 0xFF249ce0, 0xFF249ce0, 0xFF219ce3, 0xFF1e9ce6, 0xFF209ae2, @@ -2080,7 +2081,7 @@ }; static int test_bmp_cmp_count(const BYTE* mem1, const BYTE* mem2, int size, - int channel, int margin) + int channel, int margin) { int error; int count = 0; @@ -2107,7 +2108,7 @@ } static int test_bmp_cmp_dump(const BYTE* actual, const BYTE* expected, int size, - int channel, int margin) + int channel, int margin) { int x, y; int error[3]; @@ -2154,211 +2155,269 @@ return count; } -static void test_fill_bitmap_channel(BYTE* data, int width, int height, - BYTE value, int nChannel) +static int test_PrimitivesYCbCr(const primitives_t* prims, UINT32 format, prim_size_t roi, + BOOL compare) { - int x, y; - BYTE* pChannel; - pChannel = data + nChannel; - - for (y = 0; y < height; y++) - { - for (x = 0; x < width; x++) - { - *pChannel = value; - pChannel += 4; - } - } -} - -#define TEST_FP_TYPE float - -static TEST_FP_TYPE TEST_YCbCrToRGB_01[4] = { 1.403f, 0.344f, 0.714f, 1.770f }; -static TEST_FP_TYPE TEST_YCbCrToRGB_02[4] = { 1.402525f, 0.343730f, 0.714401f, 1.769905f }; -static TEST_FP_TYPE TEST_YCbCrToRGB_03[4] = { 1.402524948120117L, 0.3437300026416779L, 0.7144010066986084L, 1.769904971122742L }; - -static INT16 TEST_YCbCr_01[3] = { +3443, -1863, +272 }; -static BYTE TEST_RGB_01[3] = { 247, 249, 132 }; - -static INT16 TEST_YCbCr_02[3] = { +1086, +1584, -2268 }; -static BYTE TEST_RGB_02[3] = { 62, 195, 249 }; - -static INT16 TEST_YCbCr_03[3] = { -576, +2002, -2179 }; -static BYTE TEST_RGB_03[3] = { 15, 137, 221 }; - -int test_YCbCr_fp(TEST_FP_TYPE coeffs[4], INT16 YCbCr[3], BYTE RGB[3]) -{ - INT16 R, G, B; - TEST_FP_TYPE Y, Cb, Cr; - TEST_FP_TYPE fR, fG, fB; - TEST_FP_TYPE fR1, fR2; - Y = (TEST_FP_TYPE)(YCbCr[0] + 4096); - Cb = (TEST_FP_TYPE)(YCbCr[1]); - Cr = (TEST_FP_TYPE)(YCbCr[2]); -#if 1 - fR1 = Cr * coeffs[0]; - fR2 = fR1 + Y + 16.0f; - fR = ((Cr * coeffs[0]) + Y + 16.0f); - fG = (Y - (Cb * coeffs[1]) - (Cr * coeffs[2]) + 16.0f); - fB = ((Cb * coeffs[3]) + Y + 16.0f); - printf("fR: %f fG: %f fB: %f fY: %f\n", fR, fG, fB, Y); - R = (INT16) fR; - G = (INT16) fG; - B = (INT16) fB; - printf("mR: %d mG: %d mB: %d\n", (R - 16) % 32, (G - 16) % 32, (B - 16) % 32); - printf("iR: %"PRId16" iG: %"PRId16" iB: %"PRId16"\n", R, G, B); - R >>= 5; - G >>= 5; - B >>= 5; - printf("R5: %"PRId16" G5: %"PRId16" B5: %"PRId16"\n", R, G, B); -#else - R = ((INT16)(((Cr * coeffs[0]) + Y + 16.0f)) >> 5); - G = ((INT16)((Y - (Cb * coeffs[1]) - (Cr * coeffs[2]) + 16.0f)) >> 5); - B = ((INT16)(((Cb * coeffs[3]) + Y + 16.0f)) >> 5); -#endif - - if (R < 0) - R = 0; - else if (R > 255) - R = 255; - - if (G < 0) - G = 0; - else if (G > 255) - G = 255; - - if (B < 0) - B = 0; - else if (B > 255) - B = 255; - - printf("--------------------------------\n"); - printf("R: A: %3"PRId16" E: %3"PRIu8" %s\n", R, RGB[0], (R == RGB[0]) ? "" : "***"); - printf("G: A: %3"PRId16" E: %3"PRIu8" %s\n", G, RGB[1], (G == RGB[1]) ? "" : "***"); - printf("B: A: %3"PRId16" E: %3"PRIu8" %s\n", B, RGB[2], (B == RGB[2]) ? "" : "***"); - printf("Y: %+5"PRId16" Cb: %+5"PRId16" Cr: %+5"PRId16"\n", YCbCr[0], YCbCr[1], YCbCr[2]); - //printf("[0]: %20.20lf\n", coeffs[0]); - //printf("[1]: %20.20lf\n", coeffs[1]); - //printf("[2]: %20.20lf\n", coeffs[2]); - //printf("[3]: %20.20lf\n", coeffs[3]); - printf("--------------------------------\n\n"); - return 0; -} - -int test_YCbCr_pixels() -{ - if (0) - { - test_YCbCr_fp(TEST_YCbCrToRGB_01, TEST_YCbCr_01, TEST_RGB_01); - test_YCbCr_fp(TEST_YCbCrToRGB_01, TEST_YCbCr_02, TEST_RGB_02); - test_YCbCr_fp(TEST_YCbCrToRGB_01, TEST_YCbCr_03, TEST_RGB_03); - } - - if (1) - { - test_YCbCr_fp(TEST_YCbCrToRGB_02, TEST_YCbCr_01, TEST_RGB_01); - test_YCbCr_fp(TEST_YCbCrToRGB_02, TEST_YCbCr_02, TEST_RGB_02); - test_YCbCr_fp(TEST_YCbCrToRGB_02, TEST_YCbCr_03, TEST_RGB_03); - } - - if (0) - { - test_YCbCr_fp(TEST_YCbCrToRGB_03, TEST_YCbCr_01, TEST_RGB_01); - test_YCbCr_fp(TEST_YCbCrToRGB_03, TEST_YCbCr_02, TEST_RGB_02); - test_YCbCr_fp(TEST_YCbCrToRGB_03, TEST_YCbCr_03, TEST_RGB_03); - } - - return 0; -} - -int TestPrimitivesYCbCr(int argc, char* argv[]) -{ - pstatus_t status = PRIMITIVES_SUCCESS; - int size; + pstatus_t status = -1; int cnt[3]; float err[3]; BYTE* actual; + BYTE* actual1; BYTE* expected; int margin = 1; INT16* pYCbCr[3]; - const primitives_t* prims = primitives_get(); - static const prim_size_t roi_64x64 = { 64, 64 }; + const UINT32 srcStride = roi.width * 2; + const UINT32 dstStride = roi.width * GetBytesPerPixel(format); + const UINT32 srcSize = srcStride * roi.height; + const UINT32 dstSize = dstStride * roi.height; + PROFILER_DEFINE(prof); + PROFILER_DEFINE(prof1); + PROFILER_DEFINE(prof2); //return test_YCbCr_pixels(); expected = (BYTE*) TEST_XRGB_IMAGE; - size = 64 * 64 * 4; - actual = _aligned_malloc(size, 16); + actual = _aligned_malloc(dstSize, 16); + actual1 = _aligned_malloc(dstSize, 16); + PROFILER_CREATE(prof, "yCbCrToRGB_16s8u"); + PROFILER_CREATE(prof1, "yCbCrToRGB16s16s"); + PROFILER_CREATE(prof2, "RGBToRGB_16s8u"); + + if (!actual || !actual1) + goto fail; + + ZeroMemory(actual, dstSize); + ZeroMemory(actual1, dstSize); + pYCbCr[0] = _aligned_malloc(srcSize, 16); + pYCbCr[1] = _aligned_malloc(srcSize, 16); + pYCbCr[2] = _aligned_malloc(srcSize, 16); + + if (!pYCbCr[0] || !pYCbCr[1] || !pYCbCr[2]) + goto fail; + + winpr_RAND((BYTE*)pYCbCr[0], srcSize); + winpr_RAND((BYTE*)pYCbCr[1], srcSize); + winpr_RAND((BYTE*)pYCbCr[2], srcSize); - if (!actual) - return 1; - - ZeroMemory(actual, size); - pYCbCr[0] = TEST_Y_COMPONENT; - pYCbCr[1] = TEST_CB_COMPONENT; - pYCbCr[2] = TEST_CR_COMPONENT; + if (compare) + { + memcpy(pYCbCr[0], TEST_Y_COMPONENT, srcSize); + memcpy(pYCbCr[1], TEST_CB_COMPONENT, srcSize); + memcpy(pYCbCr[2], TEST_CR_COMPONENT, srcSize); + } - if (1) { - status = prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pYCbCr, 64 * 2, - actual, PIXEL_FORMAT_BGRA32, - 64 * 4, &roi_64x64); + PROFILER_ENTER(prof); + status = prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pYCbCr, srcStride, + actual, dstStride, format, + &roi); + PROFILER_EXIT(prof); } - else + { INT16* pSrcDst[3]; - pSrcDst[0] = _aligned_malloc(4096 * 2, 16); - pSrcDst[1] = _aligned_malloc(4096 * 2, 16); - pSrcDst[2] = _aligned_malloc(4096 * 2, 16); - CopyMemory(pSrcDst[0], pYCbCr[0], 4096 * 2); - CopyMemory(pSrcDst[1], pYCbCr[1], 4096 * 2); - CopyMemory(pSrcDst[2], pYCbCr[2], 4096 * 2); - prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * 2, - pSrcDst, 64 * 2, &roi_64x64); - prims->RGBToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, - actual, 64 * 4, PIXEL_FORMAT_BGRA32, &roi_64x64); + pSrcDst[0] = _aligned_malloc(srcSize, 16); + pSrcDst[1] = _aligned_malloc(srcSize, 16); + pSrcDst[2] = _aligned_malloc(srcSize, 16); + CopyMemory(pSrcDst[0], pYCbCr[0], srcSize); + CopyMemory(pSrcDst[1], pYCbCr[1], srcSize); + CopyMemory(pSrcDst[2], pYCbCr[2], srcSize); + PROFILER_ENTER(prof1); + status = prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, srcStride, + pSrcDst, srcStride, &roi); + PROFILER_EXIT(prof1); + + if (status != PRIMITIVES_SUCCESS) + goto fail2; + + PROFILER_ENTER(prof2); + status = prims->RGBToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, srcStride, + actual1, dstStride, format, &roi); + PROFILER_EXIT(prof2); + fail2: _aligned_free(pSrcDst[0]); _aligned_free(pSrcDst[1]); _aligned_free(pSrcDst[2]); + + if (status != PRIMITIVES_SUCCESS) + goto fail; } - if (0) + if (compare) { - test_fill_bitmap_channel(actual, 64, 64, 0, 2); /* red */ - test_fill_bitmap_channel(expected, 64, 64, 0, 2); /* red */ + cnt[2] = test_bmp_cmp_count(actual, expected, dstSize, 2, margin); /* red */ + err[2] = ((float) cnt[2]) / ((float) dstSize / 4) * 100.0f; + cnt[1] = test_bmp_cmp_count(actual, expected, dstSize, 1, margin); /* green */ + err[1] = ((float) cnt[1]) / ((float) dstSize / 4) * 100.0f; + cnt[0] = test_bmp_cmp_count(actual, expected, dstSize, 0, margin); /* blue */ + err[0] = ((float) cnt[0]) / ((float) dstSize / 4) * 100.0f; + + if (cnt[0] || cnt[1] || cnt[2]) + { + printf("Summary information yCbCrToRGB_16s8u_P3AC4R\n"); + printf("Red Error Dump:\n"); + test_bmp_cmp_dump(actual, expected, dstSize, 2, margin); /* red */ + printf("Green Error Dump:\n"); + test_bmp_cmp_dump(actual, expected, dstSize, 1, margin); /* green */ + printf("Blue Error Dump:\n"); + test_bmp_cmp_dump(actual, expected, dstSize, 0, margin); /* blue */ + printf("R: diff: %d (%f%%)\n", cnt[2], err[2]); + printf("G: diff: %d (%f%%)\n", cnt[1], err[1]); + printf("B: diff: %d (%f%%)\n", cnt[0], err[0]); + } + + cnt[2] = test_bmp_cmp_count(actual1, expected, dstSize, 2, margin); /* red */ + err[2] = ((float) cnt[2]) / ((float) dstSize / 4) * 100.0f; + cnt[1] = test_bmp_cmp_count(actual1, expected, dstSize, 1, margin); /* green */ + err[1] = ((float) cnt[1]) / ((float) dstSize / 4) * 100.0f; + cnt[0] = test_bmp_cmp_count(actual1, expected, dstSize, 0, margin); /* blue */ + err[0] = ((float) cnt[0]) / ((float) dstSize / 4) * 100.0f; + + if (cnt[0] || cnt[1] || cnt[2]) + { + printf("Summary information yCbCrToRGB_16s16s_P3P3 & RGBToRGB_16s8u_P3AC4R\n"); + printf("Red Error Dump:\n"); + test_bmp_cmp_dump(actual1, expected, dstSize, 2, margin); /* red */ + printf("Green Error Dump:\n"); + test_bmp_cmp_dump(actual1, expected, dstSize, 1, margin); /* green */ + printf("Blue Error Dump:\n"); + test_bmp_cmp_dump(actual1, expected, dstSize, 0, margin); /* blue */ + printf("R: diff: %d (%f%%)\n", cnt[2], err[2]); + printf("G: diff: %d (%f%%)\n", cnt[1], err[1]); + printf("B: diff: %d (%f%%)\n", cnt[0], err[0]); + } } - if (0) + PROFILER_PRINT_HEADER; + PROFILER_PRINT(prof); + PROFILER_PRINT(prof1); + PROFILER_PRINT(prof2); + PROFILER_PRINT_FOOTER; +fail: + _aligned_free((BYTE*)pYCbCr[0]); + _aligned_free((BYTE*)pYCbCr[1]); + _aligned_free((BYTE*)pYCbCr[2]); + _aligned_free(actual); + _aligned_free(actual1); + PROFILER_FREE(prof); + PROFILER_FREE(prof1); + PROFILER_FREE(prof2); + return status; +} + +int TestPrimitivesYCbCr(int argc, char* argv[]) +{ + const UINT32 formats[] = { - test_fill_bitmap_channel(actual, 64, 64, 0, 1); /* green */ - test_fill_bitmap_channel(expected, 64, 64, 0, 1); /* green */ - } + PIXEL_FORMAT_XRGB32, + PIXEL_FORMAT_XBGR32, + PIXEL_FORMAT_ARGB32, + PIXEL_FORMAT_ABGR32, + PIXEL_FORMAT_RGBA32, + PIXEL_FORMAT_RGBX32, + PIXEL_FORMAT_BGRA32, + PIXEL_FORMAT_BGRX32 + }; + const primitives_t* prims = primitives_get(); + const primitives_t* generics = primitives_get_generic(); + UINT32 x; - if (0) + if (argc < 2) { - test_fill_bitmap_channel(actual, 64, 64, 0, 0); /* blue */ - test_fill_bitmap_channel(expected, 64, 64, 0, 0); /* blue */ - } + { + /* Do content comparison. */ + for (x = 0; x < sizeof(formats) / sizeof(formats[0]); x++) + { + prim_size_t roi = { 64, 64 }; + int rc; + printf("----------------------- GENERIC %s [%"PRIu32"x%"PRIu32"] COMPARE CONTENT ----\n", + GetColorFormatName(formats[x]), roi.width, roi.height); + rc = test_PrimitivesYCbCr(generics, formats[x], roi, TRUE); + + if (rc != PRIMITIVES_SUCCESS) + return rc; + + printf("------------------------- END %s ----------------------\n", + GetColorFormatName(formats[x])); + printf("---------------------- OPTIMIZED %s [%"PRIu32"x%"PRIu32"] COMPARE CONTENT ----\n", + GetColorFormatName(formats[x]), roi.width, roi.height); + rc = test_PrimitivesYCbCr(prims, formats[x], roi, TRUE); - cnt[2] = test_bmp_cmp_count(actual, expected, size, 2, margin); /* red */ - err[2] = ((float) cnt[2]) / ((float) size / 4) * 100.0f; - cnt[1] = test_bmp_cmp_count(actual, expected, size, 1, margin); /* green */ - err[1] = ((float) cnt[1]) / ((float) size / 4) * 100.0f; - cnt[0] = test_bmp_cmp_count(actual, expected, size, 0, margin); /* blue */ - err[0] = ((float) cnt[0]) / ((float) size / 4) * 100.0f; + if (rc != PRIMITIVES_SUCCESS) + return rc; - if (cnt[0] || cnt[1] || cnt[2]) + printf("------------------------- END %s ----------------------\n", + GetColorFormatName(formats[x])); + } + } + /* Do random data conversion with random sizes */ + { + prim_size_t roi; + + do + { + winpr_RAND((BYTE*)&roi.width, sizeof(roi.width)); + roi.width %= 2048; + } + while (roi.width < 16); + + do + { + winpr_RAND((BYTE*)&roi.height, sizeof(roi.height)); + roi.height %= 2048; + } + while (roi.height < 16); + + for (x = 0; x < sizeof(formats) / sizeof(formats[0]); x++) + { + int rc; + printf("----------------------- GENERIC %s [%"PRIu32"x%"PRIu32"] COMPARE CONTENT ----\n", + GetColorFormatName(formats[x]), roi.width, roi.height); + rc = test_PrimitivesYCbCr(generics, formats[x], roi, FALSE); + + if (rc != PRIMITIVES_SUCCESS) + return rc; + + printf("------------------------- END %s ----------------------\n", + GetColorFormatName(formats[x])); + printf("---------------------- OPTIMIZED %s [%"PRIu32"x%"PRIu32"] COMPARE CONTENT ----\n", + GetColorFormatName(formats[x]), roi.width, roi.height); + rc = test_PrimitivesYCbCr(prims, formats[x], roi, FALSE); + + if (rc != PRIMITIVES_SUCCESS) + return rc; + + printf("------------------------- END %s ----------------------\n", + GetColorFormatName(formats[x])); + } + } + } + /* Do a performance run with full HD */ + else { - printf("Red Error Dump:\n"); - test_bmp_cmp_dump(actual, expected, size, 2, margin); /* red */ - printf("Green Error Dump:\n"); - test_bmp_cmp_dump(actual, expected, size, 1, margin); /* green */ - printf("Blue Error Dump:\n"); - test_bmp_cmp_dump(actual, expected, size, 0, margin); /* blue */ - printf("R: diff: %d (%f%%)\n", cnt[2], err[2]); - printf("G: diff: %d (%f%%)\n", cnt[1], err[1]); - printf("B: diff: %d (%f%%)\n", cnt[0], err[0]); + prim_size_t roi = { 1928, 1080 }; + + for (x = 0; x < sizeof(formats) / sizeof(formats[0]); x++) + { + int rc; + printf("----------------------- GENERIC %s [%"PRIu32"x%"PRIu32"] COMPARE CONTENT ----\n", + GetColorFormatName(formats[x]), roi.width, roi.height); + rc = test_PrimitivesYCbCr(generics, formats[x], roi, FALSE); + + if (rc != PRIMITIVES_SUCCESS) + return rc; + + printf("------------------------- END %s ----------------------\n", + GetColorFormatName(formats[x])); + printf("---------------------- OPTIMIZED %s [%"PRIu32"x%"PRIu32"] COMPARE CONTENT ----\n", + GetColorFormatName(formats[x]), roi.width, roi.height); + rc = test_PrimitivesYCbCr(prims, formats[x], roi, FALSE); + + if (rc != PRIMITIVES_SUCCESS) + return rc; + + printf("------------------------- END %s ----------------------\n", + GetColorFormatName(formats[x])); + } } - _aligned_free(actual); - return (status == PRIMITIVES_SUCCESS) ? 0 : 1; + return 0; } - diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesYCoCg.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesYCoCg.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesYCoCg.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesYCoCg.c 2017-03-03 08:39:24.000000000 +0000 @@ -22,18 +22,20 @@ #include #include "prim_test.h" +#include /* ------------------------------------------------------------------------- */ -static BOOL test_YCoCgRToRGB_8u_AC4R_func(void) +static BOOL test_YCoCgRToRGB_8u_AC4R_func(UINT32 width, UINT32 height) { - BOOL result = TRUE; - pstatus_t status; - INT32 ALIGN(out_sse[4098]), ALIGN(out_sse_inv[4098]); - INT32 ALIGN(in[4098]); - INT32 ALIGN(out_c[4098]), ALIGN(out_c_inv[4098]); - + pstatus_t status = -1; + BYTE* out_sse = NULL; + BYTE* in = NULL; + BYTE* out_c = NULL; UINT32 i, x; - const UINT32 formats[] = { + const UINT32 srcStride = width * 4; + const UINT32 size = srcStride * height; + const UINT32 formats[] = + { PIXEL_FORMAT_ARGB32, PIXEL_FORMAT_ABGR32, PIXEL_FORMAT_RGBA32, @@ -41,86 +43,114 @@ PIXEL_FORMAT_BGRA32, PIXEL_FORMAT_BGRX32 }; + PROFILER_DEFINE(genericProf); + PROFILER_DEFINE(optProf); + in = _aligned_malloc(size, 16); + out_c = _aligned_malloc(size, 16); + out_sse = _aligned_malloc(size, 16); - winpr_RAND((BYTE*)in, sizeof(in)); + if (!in || !out_c || !out_sse) + goto fail; - for (x=0; xYCoCgToRGB_8u_AC4R( - (const BYTE*)(in + 1), 63 * 4, - (BYTE*) out_c, format, 63 * 4, 63, 61, 2, TRUE); - if (status != PRIMITIVES_SUCCESS) - return FALSE; - status = generic->YCoCgToRGB_8u_AC4R( - (const BYTE*)(in + 1), 63 * 4, - (BYTE*) out_c_inv, format, 63 * 4, 63, 61, 2, TRUE); - if (status != PRIMITIVES_SUCCESS) - return FALSE; + in, srcStride, + out_c, format, dstStride, width, height, 2, TRUE); + PROFILER_EXIT(genericProf); - status = optimized->YCoCgToRGB_8u_AC4R( - (const BYTE*)(in + 1), 63 * 4, - (BYTE*) out_sse, format, 63 * 4, 63, 61, 2, TRUE); if (status != PRIMITIVES_SUCCESS) - return FALSE; + goto loop_fail; + + PROFILER_ENTER(optProf); status = optimized->YCoCgToRGB_8u_AC4R( - (const BYTE*)(in + 1), 63 * 4, - (BYTE*) out_sse_inv, format, 63 * 4, 63, 61, 2, TRUE); + in, srcStride, + out_sse, format, dstStride, width, height, 2, TRUE); + PROFILER_EXIT(optProf); + if (status != PRIMITIVES_SUCCESS) - return FALSE; + goto loop_fail; - for (i = 0; i < 63 * 61; ++i) + if (memcmp(out_c, out_sse, dstStride * height) != 0) { - if (out_c[i] != out_sse[i]) + for (i = 0; i < width * height; ++i) { - printf("optimized->YCoCgRToRGB FAIL[%"PRIu32"]: 0x%08"PRIx32" -> C 0x%08"PRIx32" vs optimized 0x%08"PRIx32"\n", - i, in[i + 1], out_c[i], out_sse[i]); - result = FALSE; - } - } + const UINT32 c = ReadColor(out_c + 4 * i, format); + const UINT32 sse = ReadColor(out_sse + 4 * i, format); - for (i = 0; i < 63 * 61; ++i) - { - if (out_c_inv[i] != out_sse_inv[i]) - { - printf("optimized->YCoCgRToRGB inverted FAIL[%"PRIu32"]: 0x%08"PRIu32" -> C 0x%08"PRIx32" vs optimized 0x%08"PRIx32"\n", - i, in[i + 1], out_c_inv[i], out_sse_inv[i]); - result = FALSE; + if (c != sse) + { + printf("optimized->YCoCgRToRGB FAIL[%s] [%"PRIu32"]: 0x%08"PRIx32" -> C 0x%08"PRIx32" vs optimized 0x%08"PRIx32"\n", + formatName, i, in[i + 1], c, sse); + status = -1; + } } } - } - return result; -} - -static int test_YCoCgRToRGB_8u_AC4R_speed(void) -{ - INT32 ALIGN(in[4096]); - INT32 ALIGN(out[4096]); - winpr_RAND((BYTE*)in, sizeof(in)); + printf("--------------------------- [%s] [%"PRIu32"x%"PRIu32"] ---------------------------\n", + formatName, width, height); + PROFILER_PRINT_HEADER; + PROFILER_PRINT(genericProf); + PROFILER_PRINT(optProf); + PROFILER_PRINT_FOOTER; + loop_fail: + PROFILER_FREE(genericProf); + PROFILER_FREE(optProf); - if (!speed_test("YCoCgToRGB_8u_AC4R", "aligned", g_Iterations, - (speed_test_fkt)generic->YCoCgToRGB_8u_AC4R, - (speed_test_fkt)optimized->YCoCgToRGB_8u_AC4R, - in, 64 * 4, out, 64 * 4, 64, 64, 2, FALSE, FALSE)) - return FALSE; + if (status != PRIMITIVES_SUCCESS) + goto fail; + } - return TRUE; +fail: + _aligned_free(in); + _aligned_free(out_c); + _aligned_free(out_sse); + return status == PRIMITIVES_SUCCESS; } int TestPrimitivesYCoCg(int argc, char* argv[]) { prim_test_setup(FALSE); - if (!test_YCoCgRToRGB_8u_AC4R_func()) - return 1; - - if (g_TestPrimitivesPerformance) + /* Random resolution tests */ + if (argc < 2) { - if (!test_YCoCgRToRGB_8u_AC4R_speed()) - return 1; + UINT32 x; + + for (x = 0; x < 10; x++) + { + UINT32 w, h; + + do + { + winpr_RAND((BYTE*)&w, sizeof(w)); + w %= 2048; + } + while (w < 16); + + do + { + winpr_RAND((BYTE*)&h, sizeof(h)); + h %= 2048; + } + while (h < 16); + + if (!test_YCoCgRToRGB_8u_AC4R_func(w, h)) + return 1; + } } + /* Test once with full HD */ + if (!test_YCoCgRToRGB_8u_AC4R_func(1920, 1080)) + return 1; + return 0; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesYUV.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesYUV.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/primitives/test/TestPrimitivesYUV.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/primitives/test/TestPrimitivesYUV.c 2017-03-03 08:39:24.000000000 +0000 @@ -1,13 +1,14 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "prim_test.h" #include #include #include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +#include #define TAG __FILE__ @@ -21,7 +22,7 @@ { int diff = src[x] - dst[x]; - if (abs(diff) > 2) + if (abs(diff) > 4) { fprintf(stderr, "%"PRIuz" %02"PRIX8" : %02"PRIX8" diff=%d\n", x, src[x], dst[x], abs(diff)); return FALSE; @@ -31,17 +32,64 @@ return TRUE; } -static void get_size(UINT32* width, UINT32* height) +static BOOL similarRGB(const BYTE* src, const BYTE* dst, size_t size, UINT32 format) +{ + size_t x; + const UINT32 bpp = GetBytesPerPixel(format); + const BOOL alpha = ColorHasAlpha(format); + + for (x = 0; x < size; x++) + { + UINT32 sColor, dColor; + BYTE sR, sG, sB, sA; + BYTE dR, dG, dB, dA; + sColor = ReadColor(src, format); + dColor = ReadColor(dst, format); + src += bpp; + dst += bpp; + SplitColor(sColor, format, &sR, &sG, &sB, &sA, NULL); + SplitColor(sColor, format, &dR, &dG, &dB, &dA, NULL); + + if ((abs(sR - dR) > 2) || (abs(sG - dG) > 2) || (abs(sB - dB) > 2)) + { + fprintf(stderr, "Color value mismatch R[%02X %02X], G[%02X %02X], B[%02X %02X] at position %lu", + sR, dR, sG, dG, sA, dA, x); + return FALSE; + } + + if (alpha) + { + if (abs(sA - dA) > 2) + { + fprintf(stderr, "Alpha value mismatch %02X %02X at position %lu", sA, dA, x); + return FALSE; + } + } + else + { + if (dA != 0xFF) + { + fprintf(stderr, "Invalid destination alpha value %02X at position %lu", dA, x); + return FALSE; + } + } + } + + return TRUE; +} + +static void get_size(BOOL large, UINT32* width, UINT32* height) { + UINT32 shift = large ? 8 : 1; winpr_RAND((BYTE*)width, sizeof(*width)); winpr_RAND((BYTE*)height, sizeof(*height)); // TODO: Algorithm only works on even resolutions... - *width = (*width % 64) << 1; - *height = (*height % 64 << 1); + *width = (*width % 64 + 1) << shift; + *height = (*height % 64 + 1) << shift; } static BOOL check_padding(const BYTE* psrc, size_t size, size_t padding, - const char* buffer) + const char* buffer) { size_t x; BOOL rc = TRUE; @@ -68,7 +116,7 @@ x++; fprintf(stderr, "Buffer underflow detected %02"PRIx8" != %02X %s [%"PRIuz"-%"PRIuz"]\n", - d, 'A', buffer, start, x); + d, 'A', buffer, start, x); return FALSE; } @@ -80,7 +128,7 @@ x++; fprintf(stderr, "Buffer overflow detected %02"PRIx8" != %02X %s [%"PRIuz"-%"PRIuz"]\n", - d, 'A', buffer, start, x); + d, 'A', buffer, start, x); return FALSE; } } @@ -92,18 +140,19 @@ { size_t halfPad = (padding + 1) / 2; BYTE* psrc; - BYTE* src = calloc(1, size + 2 * halfPad); + BYTE* src = _aligned_malloc(size + 2 * halfPad, 16); if (!src) return NULL; memset(&src[0], 'A', halfPad); + memset(&src[halfPad], 0, size); memset(&src[halfPad + size], 'A', halfPad); psrc = &src[halfPad]; if (!check_padding(psrc, size, padding, "init")) { - free(src); + _aligned_free(src); return NULL; } @@ -118,12 +167,12 @@ return; ptr = ((BYTE*)src) - (padding + 1) / 2; - free(ptr); + _aligned_free(ptr); } /* Create 2 pseudo YUV420 frames of same size. * Combine them and check, if the data is at the expected position. */ -static BOOL TestPrimitiveYUVCombine(void) +static BOOL TestPrimitiveYUVCombine(primitives_t* prims, prim_size_t roi) { UINT32 x, y, i; UINT32 awidth, aheight; @@ -137,13 +186,14 @@ UINT32 chromaStride[3]; UINT32 yuvStride[3]; size_t padding = 10000; - prim_size_t roi; - primitives_t* prims = primitives_get(); - get_size(&roi.width, &roi.height); + PROFILER_DEFINE(yuvCombine); + PROFILER_DEFINE(yuvSplit); awidth = roi.width + 16 - roi.width % 16; aheight = roi.height + 16 - roi.height % 16; fprintf(stderr, "Running YUVCombine on frame size %"PRIu32"x%"PRIu32" [%"PRIu32"x%"PRIu32"]\n", - roi.width, roi.height, awidth, aheight); + roi.width, roi.height, awidth, aheight); + PROFILER_CREATE(yuvCombine, "YUV420CombineToYUV444"); + PROFILER_CREATE(yuvSplit, "YUV444SplitToYUV420"); if (!prims || !prims->YUV420CombineToYUV444) goto fail; @@ -193,10 +243,17 @@ goto fail; } + PROFILER_ENTER(yuvCombine); + if (prims->YUV420CombineToYUV444((const BYTE**)luma, lumaStride, - (const BYTE**)chroma, chromaStride, - yuv, yuvStride, &roi) != PRIMITIVES_SUCCESS) + (const BYTE**)chroma, chromaStride, + yuv, yuvStride, &roi) != PRIMITIVES_SUCCESS) + { + PROFILER_EXIT(yuvCombine); goto fail; + } + + PROFILER_EXIT(yuvCombine); for (x = 0; x < 3; x++) { @@ -214,9 +271,16 @@ goto fail; } + PROFILER_ENTER(yuvSplit); + if (prims->YUV444SplitToYUV420((const BYTE**)yuv, yuvStride, pmain, lumaStride, - paux, chromaStride, &roi) != PRIMITIVES_SUCCESS) + paux, chromaStride, &roi) != PRIMITIVES_SUCCESS) + { + PROFILER_EXIT(yuvSplit); goto fail; + } + + PROFILER_EXIT(yuvSplit); for (x = 0; x < 3; x++) { @@ -251,8 +315,8 @@ } if (!similar(luma[i] + y * lstride, - pmain[i] + y * lstride, - w)) + pmain[i] + y * lstride, + w)) goto fail; /* Need to ignore lines of destination Y plane, @@ -270,14 +334,20 @@ } if (!similar(chroma[i] + y * cstride, - paux[i] + y * cstride, - w)) + paux[i] + y * cstride, + w)) goto fail; } } + PROFILER_PRINT_HEADER; + PROFILER_PRINT(yuvSplit); + PROFILER_PRINT(yuvCombine); + PROFILER_PRINT_FOOTER; rc = TRUE; fail: + PROFILER_FREE(yuvCombine); + PROFILER_FREE(yuvSplit); for (x = 0; x < 3; x++) { @@ -291,22 +361,34 @@ return rc; } -static BOOL TestPrimitiveYUV(BOOL use444) +static BOOL TestPrimitiveYUV(primitives_t* prims, prim_size_t roi, BOOL use444) { BOOL rc = FALSE; UINT32 x, y; UINT32 awidth, aheight; BYTE* yuv[3] = {0}; UINT32 yuv_step[3]; - prim_size_t roi; BYTE* rgb = NULL; BYTE* rgb_dst = NULL; size_t size; - primitives_t* prims = primitives_get(); size_t uvsize, uvwidth; - size_t padding = 10000; - size_t stride; - get_size(&roi.width, &roi.height); + size_t padding = 100 * 16; + UINT32 stride; + const UINT32 formats[] = + { + PIXEL_FORMAT_XRGB32, + PIXEL_FORMAT_XBGR32, + PIXEL_FORMAT_ARGB32, + PIXEL_FORMAT_ABGR32, + PIXEL_FORMAT_RGBA32, + PIXEL_FORMAT_RGBX32, + PIXEL_FORMAT_BGRA32, + PIXEL_FORMAT_BGRX32 + }; + PROFILER_DEFINE(rgbToYUV420); + PROFILER_DEFINE(rgbToYUV444); + PROFILER_DEFINE(yuv420ToRGB); + PROFILER_DEFINE(yuv444ToRGB); /* Buffers need to be 16x16 aligned. */ awidth = roi.width + 16 - roi.width % 16; aheight = roi.height + 16 - roi.height % 16; @@ -331,7 +413,7 @@ } fprintf(stderr, "Running AVC%s on frame size %"PRIu32"x%"PRIu32"\n", use444 ? "444" : "420", - roi.width, roi.height); + roi.width, roi.height); /* Test RGB to YUV444 conversion and vice versa */ if (!(rgb = set_padding(size * sizeof(UINT32), padding))) @@ -366,52 +448,119 @@ yuv_step[1] = uvwidth; yuv_step[2] = uvwidth; - if (use444) + for (x = 0; x < sizeof(formats) / sizeof(formats[0]); x++) { - if (prims->RGBToYUV444_8u_P3AC4R(rgb, PIXEL_FORMAT_BGRA32, - stride, yuv, yuv_step, - &roi) != PRIMITIVES_SUCCESS) - goto fail; - } - else if (prims->RGBToYUV420_8u_P3AC4R(rgb, PIXEL_FORMAT_BGRA32, - stride, yuv, yuv_step, - &roi) != PRIMITIVES_SUCCESS) - goto fail; + pstatus_t rc; + const UINT32 DstFormat = formats[x]; + printf("Testing destination color format %s\n", GetColorFormatName(DstFormat)); + PROFILER_CREATE(rgbToYUV420, "RGBToYUV420"); + PROFILER_CREATE(rgbToYUV444, "RGBToYUV444"); + PROFILER_CREATE(yuv420ToRGB, "YUV420ToRGB"); + PROFILER_CREATE(yuv444ToRGB, "YUV444ToRGB"); - if (!check_padding(rgb, size * sizeof(UINT32), padding, "rgb")) - goto fail; + if (use444) + { + PROFILER_ENTER(rgbToYUV444); + rc = prims->RGBToYUV444_8u_P3AC4R(rgb, DstFormat, + stride, yuv, yuv_step, + &roi); + PROFILER_EXIT(rgbToYUV444); + + if (rc != PRIMITIVES_SUCCESS) + goto loop_fail; + + PROFILER_PRINT_HEADER; + PROFILER_PRINT(rgbToYUV444); + PROFILER_PRINT_FOOTER; + } + else + { + PROFILER_ENTER(rgbToYUV420); + rc = prims->RGBToYUV420_8u_P3AC4R(rgb, DstFormat, + stride, yuv, yuv_step, + &roi); + PROFILER_EXIT(rgbToYUV420); + + if (rc != PRIMITIVES_SUCCESS) + goto loop_fail; + + PROFILER_PRINT_HEADER; + PROFILER_PRINT(rgbToYUV420); + PROFILER_PRINT_FOOTER; + } - if ((!check_padding(yuv[0], size, padding, "Y")) || - (!check_padding(yuv[1], uvsize, padding, "U")) || - (!check_padding(yuv[2], uvsize, padding, "V"))) - goto fail; + if (!check_padding(rgb, size * sizeof(UINT32), padding, "rgb")) + { + rc = -1; + goto loop_fail; + } - if (use444) - { - if (prims->YUV444ToRGB_8u_P3AC4R((const BYTE**)yuv, yuv_step, rgb_dst, stride, - PIXEL_FORMAT_BGRA32, - &roi) != PRIMITIVES_SUCCESS) - goto fail; - } - else if (prims->YUV420ToRGB_8u_P3AC4R((const BYTE**)yuv, yuv_step, rgb_dst, - stride, PIXEL_FORMAT_BGRA32, &roi) != PRIMITIVES_SUCCESS) - goto fail; + if ((!check_padding(yuv[0], size, padding, "Y")) || + (!check_padding(yuv[1], uvsize, padding, "U")) || + (!check_padding(yuv[2], uvsize, padding, "V"))) + { + rc = -1; + goto loop_fail; + } - if (!check_padding(rgb_dst, size * sizeof(UINT32), padding, "rgb dst")) - goto fail; + if (use444) + { + PROFILER_ENTER(yuv444ToRGB); + rc = prims->YUV444ToRGB_8u_P3AC4R((const BYTE**)yuv, yuv_step, rgb_dst, stride, + DstFormat, + &roi); + PROFILER_EXIT(yuv444ToRGB); + + if (rc != PRIMITIVES_SUCCESS) + goto loop_fail; + + loop_fail: + PROFILER_EXIT(yuv444ToRGB); + PROFILER_PRINT_HEADER; + PROFILER_PRINT(yuv444ToRGB); + PROFILER_PRINT_FOOTER; - if ((!check_padding(yuv[0], size, padding, "Y")) || - (!check_padding(yuv[1], uvsize, padding, "U")) || - (!check_padding(yuv[2], uvsize, padding, "V"))) - goto fail; + if (rc != PRIMITIVES_SUCCESS) + goto fail; + } + else + { + PROFILER_ENTER(yuv420ToRGB); - for (y = 0; y < roi.height; y++) - { - BYTE* srgb = &rgb[y * stride]; - BYTE* drgb = &rgb_dst[y * stride]; + if (prims->YUV420ToRGB_8u_P3AC4R((const BYTE**)yuv, yuv_step, rgb_dst, + stride, DstFormat, &roi) != PRIMITIVES_SUCCESS) + { + PROFILER_EXIT(yuv420ToRGB); + goto fail; + } - if (!similar(srgb, drgb, roi.width * sizeof(UINT32))) + PROFILER_EXIT(yuv420ToRGB); + PROFILER_PRINT_HEADER; + PROFILER_PRINT(yuv420ToRGB); + PROFILER_PRINT_FOOTER; + } + + if (!check_padding(rgb_dst, size * sizeof(UINT32), padding, "rgb dst")) + goto fail; + + if ((!check_padding(yuv[0], size, padding, "Y")) || + (!check_padding(yuv[1], uvsize, padding, "U")) || + (!check_padding(yuv[2], uvsize, padding, "V"))) goto fail; + + for (y = 0; y < roi.height; y++) + { + BYTE* srgb = &rgb[y * stride]; + BYTE* drgb = &rgb_dst[y * stride]; + + if (!similarRGB(srgb, drgb, roi.width, DstFormat)) + goto fail; + } + + PROFILER_FREE(rgbToYUV420); + PROFILER_FREE(rgbToYUV444); + PROFILER_FREE(yuv420ToRGB); + PROFILER_FREE(yuv444ToRGB); } rc = TRUE; @@ -426,21 +575,81 @@ int TestPrimitivesYUV(int argc, char* argv[]) { + BOOL large = (argc > 1); UINT32 x; int rc = -1; - prim_test_setup(FALSE); + primitives_t* prims = primitives_get(); + primitives_t* generic = primitives_get_generic(); for (x = 0; x < 10; x++) { - if (!TestPrimitiveYUV(TRUE)) + prim_size_t roi; + + if (argc > 1) + { + roi.width = 1920; + roi.height = 1080; + } + else + get_size(large, &roi.width, &roi.height); + + printf("-------------------- GENERIC ------------------------\n"); + + if (!TestPrimitiveYUV(generic, roi, TRUE)) + { + printf("TestPrimitiveYUV (444) failed.\n"); + goto end; + } + + printf("---------------------- END --------------------------\n"); +#if 1 + printf("------------------- OPTIMIZED -----------------------\n"); + + if (!TestPrimitiveYUV(prims, roi, TRUE)) + { + printf("TestPrimitiveYUV (444) failed.\n"); + goto end; + } + + printf("---------------------- END --------------------------\n"); +#endif + printf("-------------------- GENERIC ------------------------\n"); + + if (!TestPrimitiveYUV(generic, roi, FALSE)) + { + printf("TestPrimitiveYUV (420) failed.\n"); goto end; + } + + printf("---------------------- END --------------------------\n"); + printf("------------------- OPTIMIZED -----------------------\n"); + + if (!TestPrimitiveYUV(prims, roi, FALSE)) + { + printf("TestPrimitiveYUV (420) failed.\n"); + goto end; + } - if (!TestPrimitiveYUV(FALSE)) + printf("---------------------- END --------------------------\n"); + printf("-------------------- GENERIC ------------------------\n"); + + if (!TestPrimitiveYUVCombine(generic, roi)) + { + printf("TestPrimitiveYUVCombine failed.\n"); goto end; + } + + printf("---------------------- END --------------------------\n"); + printf("------------------- OPTIMIZED -----------------------\n"); - if (!TestPrimitiveYUVCombine()) + if (!TestPrimitiveYUVCombine(prims, roi)) + { + printf("TestPrimitiveYUVCombine failed.\n"); goto end; + } + + printf("---------------------- END --------------------------\n"); } rc = 0; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/utils/profiler.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/utils/profiler.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/utils/profiler.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/utils/profiler.c 2017-03-03 08:39:24.000000000 +0000 @@ -32,13 +32,14 @@ PROFILER* profiler_create(char* name) { PROFILER* profiler; - profiler = (PROFILER*) malloc(sizeof(PROFILER)); + if (!profiler) return NULL; - + profiler->name = name; profiler->stopwatch = stopwatch_create(); + if (!profiler->stopwatch) { free(profiler); @@ -49,9 +50,8 @@ } void profiler_free(PROFILER* profiler) -{ +{ stopwatch_free(profiler->stopwatch); - free(profiler); } @@ -65,24 +65,32 @@ stopwatch_stop(profiler->stopwatch); } -void profiler_print_header() +void profiler_print_header(void) { - WLog_INFO(TAG, " |-----------------------|"); - WLog_INFO(TAG, " PROFILER | elapsed seconds |"); - WLog_INFO(TAG, "|--------------------------------------------|-----------------------|"); - WLog_INFO(TAG, "| code section | iterations | total | avg. |"); - WLog_INFO(TAG, "|-------------------------------|------------|-----------|-----------|"); + WLog_INFO(TAG, + " |-----------------------|-----------------------|"); + WLog_INFO(TAG, + " PROFILER | elapsed seconds | FPS |"); + WLog_INFO(TAG, + "|--------------------------------------------|-----------------------|-----------------------"); + WLog_INFO(TAG, + "| code section | iterations | total | avg. | total | avg. |"); + WLog_INFO(TAG, + "|-------------------------------|------------|-----------|-----------|-----------|-----------|"); } void profiler_print(PROFILER* profiler) { - double elapsed_sec = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch); - double avg_sec = elapsed_sec / (double) profiler->stopwatch->count; - WLog_INFO(TAG, "| %-30.30s| %10"PRIu32" | %9f | %9f |", - profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec); + const double elapsed_sec = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch); + const double avg_sec = elapsed_sec / (double) profiler->stopwatch->count; + const double fps = 1.0 / elapsed_sec; + const double avg_fps = 1.0 / avg_sec; + WLog_INFO(TAG, "| %-30.30s| %10"PRIu32" | %9f | %9f | %9f | %9f |", + profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec, + fps, avg_fps); } -void profiler_print_footer() +void profiler_print_footer(void) { WLog_INFO(TAG, "|--------------------------------------------------------------------|"); } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/utils/signal.c freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/utils/signal.c --- freerdp-2.0.0~dev201701161718+dfsg/libfreerdp/utils/signal.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/libfreerdp/utils/signal.c 2017-03-03 08:39:24.000000000 +0000 @@ -109,7 +109,7 @@ sigset_t orig_set; struct sigaction orig_sigaction; struct sigaction fatal_sigaction; - WLog_INFO(TAG, "Registering signal hook..."); + WLog_DBG(TAG, "Registering signal hook..."); sigfillset(&(fatal_sigaction.sa_mask)); sigdelset(&(fatal_sigaction.sa_mask), SIGCONT); pthread_sigmask(SIG_BLOCK, &(fatal_sigaction.sa_mask), &orig_set); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/packaging/deb/freerdp-nightly/freerdp-nightly.install freerdp-2.0.0~dev201703030839+dfsg/packaging/deb/freerdp-nightly/freerdp-nightly.install --- freerdp-2.0.0~dev201701161718+dfsg/packaging/deb/freerdp-nightly/freerdp-nightly.install 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/packaging/deb/freerdp-nightly/freerdp-nightly.install 2017-03-03 08:39:24.000000000 +0000 @@ -1,4 +1,7 @@ opt/freerdp-nightly/lib/*.so.* opt/freerdp-nightly/bin +opt/freerdp-nightly/share/man/man1/freerdp-shadow-cli.1* +opt/freerdp-nightly/share/man/man1/winpr-makecert.1* +opt/freerdp-nightly/share/man/man1/winpr-hash.1* opt/freerdp-nightly/share/man/man1/xfreerdp.1* opt/freerdp-nightly/share/man/man7/wlog.7* diff -Nru freerdp-2.0.0~dev201701161718+dfsg/packaging/rpm/freerdp-nightly.spec freerdp-2.0.0~dev201703030839+dfsg/packaging/rpm/freerdp-nightly.spec --- freerdp-2.0.0~dev201701161718+dfsg/packaging/rpm/freerdp-nightly.spec 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/packaging/rpm/freerdp-nightly.spec 2017-03-03 08:39:24.000000000 +0000 @@ -139,6 +139,9 @@ %{INSTALL_PREFIX}/%{_lib}/*.so.* %{INSTALL_PREFIX}/bin/ %{INSTALL_PREFIX}/share/man/man1/xfreerdp.1* +%{INSTALL_PREFIX}/share/man/man1/freerdp-shadow-cli.1* +%{INSTALL_PREFIX}/share/man/man1/winpr-makecert.1* +%{INSTALL_PREFIX}/share/man/man1/winpr-hash.1* %{INSTALL_PREFIX}/share/man/man7/wlog.7* %files devel diff -Nru freerdp-2.0.0~dev201701161718+dfsg/scripts/0001-64bit-architecture-support.patch freerdp-2.0.0~dev201703030839+dfsg/scripts/0001-64bit-architecture-support.patch --- freerdp-2.0.0~dev201701161718+dfsg/scripts/0001-64bit-architecture-support.patch 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/scripts/0001-64bit-architecture-support.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -From 6e9a00d9ac02c3b3adc0613798678eadb0c4dae5 Mon Sep 17 00:00:00 2001 -From: Armin Novak -Date: Thu, 2 Jun 2016 13:55:27 +0200 -Subject: [PATCH] 64bit architecture support. - ---- - Configure | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/Configure b/Configure -index c98107a..fa20eca 100755 ---- a/Configure -+++ b/Configure -@@ -473,6 +473,9 @@ my %table=( - "android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", - "android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", - "android-mips","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"android64", "gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib64 -m64 -DL_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:android:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", -+"android64-aarch64","gcc:-march=armv8-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${aarch64_asm}:linux64:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"android64-mips64","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib64 -mabi=64 -O3 -Wall -DBN_DIV3W::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC:-mabi=64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", - - #### *BSD [do see comment about ${BSDthreads} above!] - "BSD-generic32","gcc:-O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", --- -2.1.4 - diff -Nru freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-32.conf freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-32.conf --- freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-32.conf 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-32.conf 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Android build confguration +# +# Note: This is a simple configuration to build all +# architectures in one rush. +# Since android 64 bit support was introduced with NDK API 21 +# this is the minimal common denominator. +# If you require support for older NDK API levels, +# create seperate configurations for each NDK API level +# and architecture you want to support. +WITH_JPEG=0 +WITH_OPENH264=0 +WITH_OPENSSL=1 +BUILD_DEPS=1 +DEPS_ONLY=0 +NDK_TARGET=14 + +JPEG_TAG=master +OPENH264_TAG=v1.6.0 +OPENSSL_TAG=OpenSSL_1_1_0c + +SRC_DIR=$SCRIPT_PATH/.. +BUILD_DST=$SCRIPT_PATH/../client/Android/Studio/freeRDPCore/src/main/jniLibs +BUILD_SRC=$SRC_DIR/build + +CMAKE_BUILD_TYPE=Release + +BUILD_ARCH="armeabi armeabi-v7a x86 mips" diff -Nru freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-64.conf freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-64.conf --- freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-64.conf 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-64.conf 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Android build confguration +# +# Note: This is a simple configuration to build all +# architectures in one rush. +# Since android 64 bit support was introduced with NDK API 21 +# this is the minimal common denominator. +# If you require support for older NDK API levels, +# create seperate configurations for each NDK API level +# and architecture you want to support. +WITH_JPEG=0 +WITH_OPENH264=0 +WITH_OPENSSL=1 +BUILD_DEPS=1 +DEPS_ONLY=0 +NDK_TARGET=21 + +JPEG_TAG=master +OPENH264_TAG=v1.6.0 +OPENSSL_TAG=OpenSSL_1_1_0c + +SRC_DIR=$SCRIPT_PATH/.. +BUILD_DST=$SCRIPT_PATH/../client/Android/Studio/freeRDPCore/src/main/jniLibs +BUILD_SRC=$SRC_DIR/build + +CMAKE_BUILD_TYPE=Release + +BUILD_ARCH="arm64-v8a x86_64 mips64" diff -Nru freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-common.sh freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-common.sh --- freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-common.sh 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-common.sh 2017-03-03 08:39:24.000000000 +0000 @@ -1,5 +1,8 @@ #!/bin/bash +SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}") +SCRIPT_PATH=$(realpath "$SCRIPT_PATH") + if [ -z $BUILD_ARCH ]; then BUILD_ARCH="armeabi armeabi-v7a mips mips64 x86 x86_64 arm64-v8a" fi @@ -8,6 +11,10 @@ NDK_TARGET=21 fi +if [ -z $CCACHE ]; then + CCACHE=$(which ccache) +fi + if [ -z $ANDROID_NDK ]; then ANDROID_NDK="missing" fi diff -Nru freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build.conf freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build.conf --- freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build.conf 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build.conf 2017-03-03 08:39:24.000000000 +0000 @@ -9,9 +9,6 @@ # If you require support for older NDK API levels, # create seperate configurations for each NDK API level # and architecture you want to support. -SCRIPT_PATH=$(dirname "${BASH_SOURCE[0]}") -SCRIPT_PATH=$(realpath "$SCRIPT_PATH") - WITH_JPEG=0 WITH_OPENH264=0 WITH_OPENSSL=1 @@ -21,7 +18,7 @@ JPEG_TAG=master OPENH264_TAG=v1.6.0 -OPENSSL_TAG=OpenSSL_1_0_2h +OPENSSL_TAG=OpenSSL_1_1_0e SRC_DIR=$SCRIPT_PATH/.. BUILD_DST=$SCRIPT_PATH/../client/Android/Studio/freeRDPCore/src/main/jniLibs diff -Nru freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-openh264.sh freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-openh264.sh --- freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-openh264.sh 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-openh264.sh 2017-03-03 08:39:24.000000000 +0000 @@ -11,6 +11,12 @@ PATH=$ANDROID_NDK:$PATH MAKE="make PATH=$PATH OS=android NDKROOT=$ANDROID_NDK TARGET=android-$2 NDKLEVEL=$2 ARCH=$1 -j libraries" common_run git clean -xdf + common_run export QUIET_AR="$CCACHE " + common_run export QUIET_ASM="$CCACHE " + common_run export QUIET_CC="$CCACHE " + common_run export QUIET_CCAR="$CCACHE " + common_run export QUIET_CXX="$CCACHE " + common_run $MAKE # Install creates a non optimal directory layout, fix that common_run $MAKE PREFIX=$BUILD_SRC/libs/$1 install diff -Nru freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-openssl.sh freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-openssl.sh --- freerdp-2.0.0~dev201701161718+dfsg/scripts/android-build-openssl.sh 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/scripts/android-build-openssl.sh 2017-03-03 08:39:24.000000000 +0000 @@ -30,7 +30,7 @@ common_run export CROSS_SYSROOT=$ANDROID_NDK/platforms/android-$NDK_TARGET/$PLATFORM_PREFIX common_run export ANDROID_DEV=$ANDROID_NDK/platforms/android-$NDK_TARGET/$PLATFORM_PREFIX/usr - common_run export CROSS_COMPILE=$ARCH_PREFIX + common_run export CROSS_COMPILE="$CCACHE $ARCH_PREFIX" common_run export PATH=$ANDROID_NDK/toolchains/$TOOLCHAIN_PREFIX$COMPILER/prebuilt/$HOST_PLATFORM/bin/:$ORG_PATH echo "CONFIG=$CONFIG" @@ -45,9 +45,8 @@ BASE=$(pwd) DST_DIR=$BUILD_DST/$DST_PREFIX common_run cd $BUILD_SRC - common_run git am $(dirname "${BASH_SOURCE[0]}")/0001-64bit-architecture-support.patch common_run git clean -xdf - common_run ./Configure --openssldir=$DST_DIR $CONFIG shared + common_run ./Configure --config=$SCRIPT_PATH/openssl-mips64.conf --openssldir=$DST_DIR $CONFIG no-shared common_run make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" depend common_run make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" build_libs @@ -56,8 +55,8 @@ common_run mkdir -p $DST_DIR fi - common_run cp -L libssl.so $DST_DIR - common_run cp -L libcrypto.so $DST_DIR + SONAME=libfreerdp-openssl.so + common_run ${CROSS_COMPILE}gcc --sysroot=${CROSS_SYSROOT} -shared -fPIC -Wl,-soname,$SONAME -o $DST_DIR/$SONAME -Wl,-whole-archive libcrypto.a libssl.a -Wl,-no-whole-archive common_run cd $BASE } @@ -77,7 +76,7 @@ $ARCH "arm-linux-androideabi-" "arch-arm" ;; "armeabi-v7a") - build "android-armv7" "arm-linux-androideabi-" \ + build "android-armeabi" "arm-linux-androideabi-" \ $ARCH "arm-linux-androideabi-" "arch-arm" ;; "mips") @@ -111,5 +110,5 @@ then common_run mkdir -p $BUILD_DST/include fi -common_run cp -L -r $BUILD_SRC/include/openssl $BUILD_DST/include/ +common_run cp -L -R $BUILD_SRC/include/openssl $BUILD_DST/include/ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/scripts/openssl-mips64.conf freerdp-2.0.0~dev201703030839+dfsg/scripts/openssl-mips64.conf --- freerdp-2.0.0~dev201701161718+dfsg/scripts/openssl-mips64.conf 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/scripts/openssl-mips64.conf 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,6 @@ +%targets = ( +"android64-mips64" => { + inherit_from => [ "android64" ], + }, +); + diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/common/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/server/common/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/server/common/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/common/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -54,6 +54,7 @@ endif() add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${FREERDP_API_VERSION}) if (WITH_LIBRARY_VERSIONING) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) @@ -64,7 +65,8 @@ install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT FreeRDP-ServerTargets) if (WITH_DEBUG_SYMBOLS AND MSVC AND BUILD_SHARED_LIBS) - install(FILES ${CMAKE_PDB_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) + get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME) + install(FILES ${CMAKE_PDB_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/Common") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/freerdp-server.pc.in freerdp-2.0.0~dev201703030839+dfsg/server/freerdp-server.pc.in --- freerdp-2.0.0~dev201701161718+dfsg/server/freerdp-server.pc.in 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/freerdp-server.pc.in 2017-03-03 08:39:24.000000000 +0000 @@ -2,7 +2,7 @@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=${prefix}/@FREERDP_INCLUDE_DIR@ -libs=-lfreerdp-server +libs=-lfreerdp-server@FREERDP_API_VERSION@ Name: FreeRDP server Description: FreeRDP: A Remote Desktop Protocol Implementation diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/Mac/mf_event.c freerdp-2.0.0~dev201703030839+dfsg/server/Mac/mf_event.c --- freerdp-2.0.0~dev201701161718+dfsg/server/Mac/mf_event.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/Mac/mf_event.c 2017-03-03 08:39:24.000000000 +0000 @@ -192,7 +192,10 @@ event_queue->events = (mfEvent**) malloc(sizeof(mfEvent*) * event_queue->size); if (pipe(event_queue->pipe_fd) < 0) + { + free(event_queue); return NULL; + } pthread_mutex_init(&(event_queue->mutex), NULL); } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/server/shadow/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -81,6 +81,7 @@ target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${${MODULE_PREFIX}_LIBS}) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${FREERDP_VERSION_MAJOR}) if (WITH_LIBRARY_VERSIONING) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) endif() @@ -88,7 +89,8 @@ install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT server EXPORT FreeRDP-ShadowTargets) if (WITH_DEBUG_SYMBOLS AND MSVC) - install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) + get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME) + install(FILES ${CMAKE_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/shadow") @@ -284,6 +286,7 @@ target_link_libraries(${MODULE_NAME} ${PRIVATE_KEYWORD} ${${MODULE_PREFIX}_LIBS}) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${FREERDP_API_VERSION}) if (WITH_LIBRARY_VERSIONING) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) endif() @@ -291,7 +294,8 @@ install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT server EXPORT FreeRDP-ShadowTargets) if (WITH_DEBUG_SYMBOLS AND MSVC) - install(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} + get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME) + install(FILES ${CMAKE_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) endif() @@ -336,6 +340,9 @@ set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/shadow") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/freerdp-shadow.pc.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp-shadow${FREERDP_VERSION_MAJOR}.pc @ONLY) +configure_file(freerdp-shadow-cli.1.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp-shadow-cli.1) +install_freerdp_man(${CMAKE_CURRENT_BINARY_DIR}/freerdp-shadow-cli.1 1) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freerdp-shadow${FREERDP_VERSION_MAJOR}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) if(${CMAKE_VERSION} VERSION_GREATER "2.8.10") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/freerdp-shadow-cli.1.in freerdp-2.0.0~dev201703030839+dfsg/server/shadow/freerdp-shadow-cli.1.in --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/freerdp-shadow-cli.1.in 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/freerdp-shadow-cli.1.in 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,85 @@ +.de URL +\\$2 \(laURL: \\$1 \(ra\\$3 +.. +.if \n[.g] .mso www.tmac)) +.TH freerdp\-shadow\-cli 1 2017-01-12 "@FREERDP_VERSION_FULL@" "FreeRDP" +.SH NAME +freerdp\-shadow\-cli \- A utility for sharing a X display via RDP. +.SH SYNOPSIS +.B freerdp\-shadow\-cli +[\fB/port:\fP\fI\fP] +[\fB/ipc-socket:\fP\fI\fP] +[\fB/monitors:\fP\fI<0,1,2,...>\fP] +[\fB/rect:\fP\fI\fP] +[\fB+auth\fP] +[\fB-may-view\fP] +[\fB-may-interact\fP] +[\fB/sec:\fP\fI\fP] +[\fB-sec-rdp\fP] +[\fB-sec-tls\fP] +[\fB-sec-nla\fP] +[\fB-sec-ext\fP] +[\fB/sam-file:\fP\fI\fP] +[\fB/version\fP] +[\fB/help\fP] +.SH DESCRIPTION +.B freerdp\-shadow\-cli +can be used to share a running X display like with VNC but by using the RDP +instead. It is also possibly to share only parts (rect) of the display. +.SH OPTIONS +.IP /ipc-socket: +If this option is set an ipc socket with the path \fIipc-socket\fP is used +instead of a TCP socket. +.IP /port: +Set the port to use. Default is 3389. +This option is ignored if ipc-socket is used. +.IP /monitors:<1,2,3,...> +Select the monitor(s) to share. +.IP /rect: +Select rectangle within monitor to share. +.IP -auth +Disable authentication. If authentication is enabled PAM is used with the +X11 subsystem. Running as root is not necessary, however if run as user only +the same user that started freerdp\-shadow\-cli can authenticate. +.br +\fBWarning\fP: If authentication is disabled \fIeveryone\fP can connect. +.IP -may-view +Clients may view without prompt. +.IP -may-interact +Clients may interact without prompt. +.IP /sec: +Force a specific protocol security +.IP -sec-rdp (default:on) +Disable RDP security +.IP -sec-tls (default:on) +Disable TLS protocol security +.IP -sec-nla (default:on) +Disable NLA protocol security +.IP +sec-ext (default:off) +Use NLA extended protocol security +.IP /sam-file: +NTLM SAM file for NLA authentication +.IP /version +Print the version and exit. +.IP /help +Print the help and exit. + +.SH EXAMPLES +freerdp-shadow-cli /port:12345 + +When run as user within a X session (for example from an xterm) a socket on +12345 is opened and the current display is shared via RDP. + +.SH EXIT STATUS +.TP +.B 0 +Successful program execution. +.TP +.B 1 +Otherweise. + +.SH SEE ALSO +wlog(7) + +.SH AUTHOR +FreeRDP diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/freerdp-shadow.pc.in freerdp-2.0.0~dev201703030839+dfsg/server/shadow/freerdp-shadow.pc.in --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/freerdp-shadow.pc.in 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/freerdp-shadow.pc.in 2017-03-03 08:39:24.000000000 +0000 @@ -2,14 +2,14 @@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=${prefix}/@FREERDP_INCLUDE_DIR@ -libs=-lfreerdp-shadow -lfreerdp-shadow-subsystem +libs=-lfreerdp-shadow@FREERDP_API_VERSION@ -lfreerdp-shadow-subsystem@FREERDP_API_VERSION@ Name: FreeRDP shadow Description: FreeRDP: A Remote Desktop Protocol Implementation URL: http://www.freerdp.com/ Version: @FREERDP_VERSION@ Requires: -Requires.private: @WINPR_PKG_CONFIG_FILENAME@ freerdp@FREERDP_VERSION_MAJOR@ +Requires.private: @WINPR_PKG_CONFIG_FILENAME@ freerdp@FREERDP_API_VERSION@ Libs: -L${libdir} ${libs} Libs.private: -ldl -lpthread Cflags: -I${includedir} diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/.gitignore freerdp-2.0.0~dev201703030839+dfsg/server/shadow/.gitignore --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/.gitignore 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/.gitignore 2017-03-03 08:39:24.000000000 +0000 @@ -1,2 +1,2 @@ freerdp-shadow-cli - +freerdp-shadow-cli.1 diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow.c freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow.c --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow.c 2017-03-03 08:39:24.000000000 +0000 @@ -36,6 +36,7 @@ #endif #include +#define TAG SERVER_TAG("shadow") int main(int argc, char** argv) { @@ -52,6 +53,7 @@ if (!server) { status = -1; + WLog_ERR(TAG, "Server new failed"); goto fail_server_new; } @@ -70,14 +72,21 @@ if ((status = shadow_server_parse_command_line(server, argc, argv)) < 0) { shadow_server_command_line_status_print(server, argc, argv, status); + WLog_ERR(TAG, "Problem parsing the command line."); goto fail_parse_command_line; } if ((status = shadow_server_init(server)) < 0) + { + WLog_ERR(TAG, "Server initialization failed."); goto fail_server_init; + } if ((status = shadow_server_start(server)) < 0) + { + WLog_ERR(TAG, "Failed to start server."); goto fail_server_start; + } if (g_MessagePump) { diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_capture.c freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_capture.c --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_capture.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_capture.c 2017-03-03 08:39:24.000000000 +0000 @@ -230,7 +230,10 @@ capture->server = server; if (!InitializeCriticalSectionAndSpinCount(&(capture->lock), 4000)) + { + free(capture); return NULL; + } return capture; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_client.c freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_client.c --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_client.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_client.c 2017-03-03 08:39:24.000000000 +0000 @@ -594,21 +594,19 @@ UINT32 frameId) { shadow_client_common_frame_acknowledge(client, frameId); + /* + * Reset queueDepth for legacy none RDPGFX acknowledge + */ + client->encoder->queueDepth = QUEUE_DEPTH_UNAVAILABLE; return TRUE; } static UINT shadow_client_rdpgfx_frame_acknowledge(RdpgfxServerContext* context, RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge) { - shadow_client_common_frame_acknowledge((rdpShadowClient*)context->custom, - frameAcknowledge->frameId); - return CHANNEL_RC_OK; -} -static UINT shadow_client_rdpgfx_qoe_frame_acknowledge(RdpgfxServerContext* - context, RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge) -{ - shadow_client_common_frame_acknowledge((rdpShadowClient*)context->custom, - qoeFrameAcknowledge->frameId); + rdpShadowClient* client = (rdpShadowClient*)context->custom; + shadow_client_common_frame_acknowledge(client, frameAcknowledge->frameId); + client->encoder->queueDepth = frameAcknowledge->queueDepth; return CHANNEL_RC_OK; } @@ -1602,8 +1600,6 @@ !gfxstatus.gfxOpened) { client->rdpgfx->FrameAcknowledge = shadow_client_rdpgfx_frame_acknowledge; - client->rdpgfx->QoeFrameAcknowledge = - shadow_client_rdpgfx_qoe_frame_acknowledge; client->rdpgfx->CapsAdvertise = shadow_client_rdpgfx_caps_advertise; if (!client->rdpgfx->Open(client->rdpgfx)) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_encoder.c freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_encoder.c --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_encoder.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_encoder.c 2017-03-03 08:39:24.000000000 +0000 @@ -34,12 +34,15 @@ UINT32 shadow_encoder_inflight_frames(rdpShadowEncoder* encoder) { - /* Return inflight frame count = + /* Return inflight frame count. + * If queueDepth is SUSPEND_FRAME_ACKNOWLEDGEMENT, count = 0 + * Otherwise, calculate count = * - * Note: This function is exported so that subsystem could * implement its own strategy to tune fps. */ - return encoder->frameId - encoder->lastAckframeId; + return (encoder->queueDepth == SUSPEND_FRAME_ACKNOWLEDGEMENT) ? 0 : encoder->frameId - + encoder->lastAckframeId; } UINT32 shadow_encoder_create_frame_id(rdpShadowEncoder* encoder) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_encoder.h freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_encoder.h --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_encoder.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_encoder.h 2017-03-03 08:39:24.000000000 +0000 @@ -56,6 +56,7 @@ BOOL frameAck; UINT32 frameId; UINT32 lastAckframeId; + UINT32 queueDepth; }; #ifdef __cplusplus diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_server.c freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_server.c --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/shadow_server.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/shadow_server.c 2017-03-03 08:39:24.000000000 +0000 @@ -453,12 +453,18 @@ server->screen = shadow_screen_new(server); if (!server->screen) + { + WLog_ERR(TAG, "screen_new failed"); return -1; + } server->capture = shadow_capture_new(server); if (!server->capture) + { + WLog_ERR(TAG, "capture_new failed"); return -1; + } if (!server->ipcSocket) status = server->listener->Open(server->listener, NULL, (UINT16) server->port); @@ -466,7 +472,10 @@ status = server->listener->OpenLocal(server->listener, server->ipcSocket); if (!status) + { + WLog_ERR(TAG, "Problem creating listener. (Port already used or insufficient permissions?)"); return -1; + } if (!(server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) shadow_server_thread, (void*) server, 0, NULL))) @@ -779,9 +788,6 @@ server->settings = freerdp_settings_new(FREERDP_SETTINGS_SERVER_MODE); - if (!server) - return NULL; - return server; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/Win/win_wds.c freerdp-2.0.0~dev201703030839+dfsg/server/shadow/Win/win_wds.c --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/Win/win_wds.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/Win/win_wds.c 2017-03-03 08:39:24.000000000 +0000 @@ -752,6 +752,14 @@ return -1; } + file = subsystem->pAssistanceFile = freerdp_assistance_file_new(); + + if (!file) + { + WLog_ERR(TAG, "freerdp_assistance_file_new() failed"); + return -1; + } + status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) bstrConnectionString, ((UINT32*) bstrConnectionString)[-1], &(file->ConnectionString2), 0, NULL, NULL); @@ -763,14 +771,6 @@ return -1; } - file = subsystem->pAssistanceFile = freerdp_assistance_file_new(); - - if (!file) - { - WLog_ERR(TAG, "freerdp_assistance_file_new() failed"); - return -1; - } - status = freerdp_assistance_parse_connection_string2(file); if (status < 0) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/shadow/X11/x11_shadow.c freerdp-2.0.0~dev201703030839+dfsg/server/shadow/X11/x11_shadow.c --- freerdp-2.0.0~dev201701161718+dfsg/server/shadow/X11/x11_shadow.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/shadow/X11/x11_shadow.c 2017-03-03 08:39:24.000000000 +0000 @@ -440,7 +440,7 @@ static int x11_shadow_query_cursor(x11ShadowSubsystem* subsystem, BOOL getImage) { - int x, y, n, k; + int x = 0, y = 0, n, k; rdpShadowServer* server; rdpShadowSurface* surface; server = subsystem->server; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_interface.c freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_interface.c --- freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_interface.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_interface.c 2017-03-03 08:39:24.000000000 +0000 @@ -39,6 +39,8 @@ #include "wf_interface.h" +#define TAG SERVER_TAG("windows") + #define SERVER_KEY "Software\\"FREERDP_VENDOR_STRING"\\" \ FREERDP_PRODUCT_STRING"\\Server" diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_mirage.c freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_mirage.c --- freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_mirage.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_mirage.c 2017-03-03 08:39:24.000000000 +0000 @@ -316,7 +316,7 @@ if (status == 0) { - WLog_ERR(TAG, "Failed to release DC!")); + WLog_ERR(TAG, "Failed to release DC!"); } } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_peer.c freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_peer.c --- freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_peer.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_peer.c 2017-03-03 08:39:24.000000000 +0000 @@ -40,6 +40,8 @@ #include "wf_peer.h" #include +#define TAG SERVER_TAG("windows") + #define SERVER_KEY "Software\\"FREERDP_VENDOR_STRING"\\" \ FREERDP_PRODUCT_STRING @@ -279,11 +281,11 @@ if (!client->Initialize(client)) goto fail_client_initialize; + context = (wfPeerContext*) client->context; + if (context->socketClose) goto fail_socked_closed; - context = (wfPeerContext*) client->context; - wfi = context->info; if (wfi->input_disabled) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_rdpsnd.c freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_rdpsnd.c --- freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_rdpsnd.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_rdpsnd.c 2017-03-03 08:39:24.000000000 +0000 @@ -40,6 +40,8 @@ #endif +#define TAG SERVER_TAG("windows") + static const AUDIO_FORMAT supported_audio_formats[] = { { WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL }, diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_update.c freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_update.c --- freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_update.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_update.c 2017-03-03 08:39:24.000000000 +0000 @@ -35,6 +35,8 @@ #include "wf_update.h" +#define TAG SERVER_TAG("windows") + DWORD WINAPI wf_update_thread(LPVOID lpParam) { int index; @@ -179,7 +181,7 @@ if (wfi->rfx_context) { - rfx_context_reset(wfi->rfx_context); + rfx_context_reset(wfi->rfx_context, wfi->servscreen_width, wfi->servscreen_height); } else { @@ -187,7 +189,7 @@ wfi->rfx_context->mode = RLGR3; wfi->rfx_context->width = wfi->servscreen_width; wfi->rfx_context->height = wfi->servscreen_height; - rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_BGRA32); + rfx_context_set_pixel_format(wfi->rfx_context, PIXEL_FORMAT_BGRA32); wfi->s = Stream_New(NULL, 0xFFFF); } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_wasapi.c freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_wasapi.c --- freerdp-2.0.0~dev201701161718+dfsg/server/Windows/wf_wasapi.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/server/Windows/wf_wasapi.c 2017-03-03 08:39:24.000000000 +0000 @@ -7,6 +7,8 @@ #include #include +#define TAG SERVER_TAG("windows") + //#define REFTIMES_PER_SEC 10000000 //#define REFTIMES_PER_MILLISEC 10000 diff -Nru freerdp-2.0.0~dev201701161718+dfsg/uwac/libuwac/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/uwac/libuwac/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/uwac/libuwac/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/uwac/libuwac/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -64,6 +64,7 @@ add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${UWAC_API_VERSION}) if (WITH_LIBRARY_VERSIONING) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${UWAC_VERSION} SOVERSION ${UWAC_API_VERSION}) endif() diff -Nru freerdp-2.0.0~dev201701161718+dfsg/uwac/libuwac/uwac-display.c freerdp-2.0.0~dev201703030839+dfsg/uwac/libuwac/uwac-display.c --- freerdp-2.0.0~dev201701161718+dfsg/uwac/libuwac/uwac-display.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/uwac/libuwac/uwac-display.c 2017-03-03 08:39:24.000000000 +0000 @@ -70,6 +70,7 @@ va_list args; va_start(args, msg); vfprintf(stderr, "%s", args); + va_end(args); return false; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/uwac/uwac.pc.in freerdp-2.0.0~dev201703030839+dfsg/uwac/uwac.pc.in --- freerdp-2.0.0~dev201701161718+dfsg/uwac/uwac.pc.in 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/uwac/uwac.pc.in 2017-03-03 08:39:24.000000000 +0000 @@ -2,7 +2,7 @@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=${prefix}/@UWAC_INCLUDE_DIR@ -libs=-luwac +libs=-luwac@UWAC_VERSION_MAJOR@ Name: uwac Description: uwac: using wayland as a client diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/winpr/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/winpr/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -176,14 +176,7 @@ add_subdirectory(test) endif() -if(WITH_MANPAGES) - if(OPENBSD) - install(FILES wlog.7 DESTINATION man/man7) - else() - install(FILES wlog.7 DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/man/man7) - endif() -endif(WITH_MANPAGES) - +install_freerdp_man(wlog.7 7) # Exporting if(${CMAKE_VERSION} VERSION_GREATER "2.8.10") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/include/winpr/library.h freerdp-2.0.0~dev201703030839+dfsg/winpr/include/winpr/library.h --- freerdp-2.0.0~dev201701161718+dfsg/winpr/include/winpr/library.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/include/winpr/library.h 2017-03-03 08:39:24.000000000 +0000 @@ -60,7 +60,7 @@ #endif -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__CYGWIN__) #ifdef __cplusplus extern "C" { diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/include/winpr/platform.h freerdp-2.0.0~dev201703030839+dfsg/winpr/include/winpr/platform.h --- freerdp-2.0.0~dev201701161718+dfsg/winpr/include/winpr/platform.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/include/winpr/platform.h 2017-03-03 08:39:24.000000000 +0000 @@ -86,6 +86,15 @@ #endif #endif +/* MIPS64 (_M_MIPS64) */ + +#if defined(mips64) || defined(__mips64) || \ + defined(__mips64__) || defined(__MIPS64__) +#ifndef _M_MIPS64 +#define _M_MIPS64 1 +#endif +#endif + /* PowerPC (_M_PPC) */ #if defined(__ppc__) || defined(__powerpc) || \ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/include/winpr/sysinfo.h freerdp-2.0.0~dev201703030839+dfsg/winpr/include/winpr/sysinfo.h --- freerdp-2.0.0~dev201701161718+dfsg/winpr/include/winpr/sysinfo.h 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/include/winpr/sysinfo.h 2017-03-03 08:39:24.000000000 +0000 @@ -44,6 +44,8 @@ #define PROCESSOR_ARCHITECTURE_AMD64 9 #define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10 #define PROCESSOR_ARCHITECTURE_NEUTRAL 11 +#define PROCESSOR_ARCHITECTURE_ARM64 12 +#define PROCESSOR_ARCHITECTURE_MIPS64 13 #define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF #define PROCESSOR_INTEL_386 386 @@ -189,7 +191,8 @@ WINPR_API BOOL SetLocalTime(CONST SYSTEMTIME* lpSystemTime); WINPR_API VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime); -WINPR_API BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement, PBOOL lpTimeAdjustmentDisabled); +WINPR_API BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement, + PBOOL lpTimeAdjustmentDisabled); WINPR_API BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -120,6 +120,7 @@ add_library(${MODULE_NAME} ${WINPR_SRCS}) set_target_properties(${MODULE_NAME} PROPERTIES LINKER_LANGUAGE C) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${WINPR_API_VERSION}) if (WITH_LIBRARY_VERSIONING) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION} SOVERSION ${WINPR_API_VERSION}) endif() @@ -132,6 +133,7 @@ endif(WIN32) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT WinPRTargets) if (WITH_DEBUG_SYMBOLS AND MSVC AND BUILD_SHARED_LIBS) - install(FILES ${CMAKE_PDB_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) + get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME) + install(FILES ${CMAKE_PDB_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/libwinpr") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/comm/comm_serial_sys.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/comm/comm_serial_sys.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/comm/comm_serial_sys.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/comm/comm_serial_sys.c 2017-03-03 08:39:24.000000000 +0000 @@ -37,6 +37,12 @@ #include #include +/* Undocumented flag, not supported everywhere. + * Provide a sensible fallback to avoid compilation problems. */ +#ifndef CMSPAR +#define CMSPAR 010000000000 +#endif + /* hard-coded in N_TTY */ #define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */ #define TTY_THRESHOLD_UNTHROTTLE 128 diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/crt/unicode.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/crt/unicode.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/crt/unicode.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/crt/unicode.c 2017-03-03 08:39:24.000000000 +0000 @@ -142,7 +142,7 @@ */ int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, - int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar) + int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar) { int length; LPWSTR targetStart; @@ -168,25 +168,20 @@ { sourceStart = (const BYTE*) lpMultiByteStr; targetStart = (WCHAR*) NULL; - result = ConvertUTF8toUTF16(&sourceStart, &sourceStart[cbMultiByte], - &targetStart, NULL, strictConversion); - + &targetStart, NULL, strictConversion); length = targetStart - ((WCHAR*) NULL); - cchWideChar = length; } else { sourceStart = (const BYTE*) lpMultiByteStr; targetStart = lpWideCharStr; - result = ConvertUTF8toUTF16(&sourceStart, &sourceStart[cbMultiByte], - &targetStart, &targetStart[cchWideChar], strictConversion); - + &targetStart, &targetStart[cchWideChar], strictConversion); length = targetStart - ((WCHAR*) lpWideCharStr); - cchWideChar = length; } + cchWideChar = (result == conversionOK) ? length : 0; return cchWideChar; } @@ -226,7 +221,7 @@ */ int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, - LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar) + LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar) { int length; BYTE* targetStart; @@ -252,25 +247,20 @@ { sourceStart = (WCHAR*) lpWideCharStr; targetStart = (BYTE*) NULL; - result = ConvertUTF16toUTF8(&sourceStart, &sourceStart[cchWideChar], - &targetStart, NULL, strictConversion); - + &targetStart, NULL, strictConversion); length = targetStart - ((BYTE*) NULL); - cbMultiByte = length; } else { sourceStart = (WCHAR*) lpWideCharStr; targetStart = (BYTE*) lpMultiByteStr; - result = ConvertUTF16toUTF8(&sourceStart, &sourceStart[cchWideChar], - &targetStart, &targetStart[cbMultiByte], strictConversion); - + &targetStart, &targetStart[cbMultiByte], strictConversion); length = targetStart - ((BYTE*) lpMultiByteStr); - cbMultiByte = length; } + cbMultiByte = (result == conversionOK) ? length : 0; return cbMultiByte; } @@ -290,7 +280,7 @@ */ int ConvertToUnicode(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, - int cbMultiByte, LPWSTR* lpWideCharStr, int cchWideChar) + int cbMultiByte, LPWSTR* lpWideCharStr, int cchWideChar) { int status; BOOL allocate = FALSE; @@ -302,7 +292,7 @@ return 0; if (cbMultiByte == -1) - cbMultiByte = (int) (strlen(lpMultiByteStr) + 1); + cbMultiByte = (int)(strlen(lpMultiByteStr) + 1); if (cchWideChar == 0) { @@ -327,7 +317,8 @@ } } - status = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, *lpWideCharStr, cchWideChar); + status = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, *lpWideCharStr, + cchWideChar); if (status != cchWideChar) { @@ -336,6 +327,7 @@ free(*lpWideCharStr); *lpWideCharStr = NULL; } + status = 0; } @@ -356,7 +348,7 @@ */ int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, - LPSTR* lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar) + LPSTR* lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar) { int status; BOOL allocate = FALSE; @@ -368,11 +360,12 @@ return 0; if (cchWideChar == -1) - cchWideChar = (int) (_wcslen(lpWideCharStr) + 1); + cchWideChar = (int)(_wcslen(lpWideCharStr) + 1); if (cbMultiByte == 0) { - cbMultiByte = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, NULL, NULL); + cbMultiByte = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, NULL, + NULL); allocate = TRUE; } @@ -394,7 +387,7 @@ } status = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, - *lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar); + *lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar); if ((status != cbMultiByte) && allocate) { diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/file/file.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/file/file.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/file/file.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/file/file.c 2017-03-03 08:39:24.000000000 +0000 @@ -353,8 +353,18 @@ return TRUE; } -static BOOL FileSetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, - const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime) +static UINT64 FileTimeToUS(const FILETIME* ft) +{ + const UINT64 EPOCH_DIFF = 11644473600ULL * 1000000ULL; + UINT64 tmp = ((UINT64)ft->dwHighDateTime) << 32 + | ft->dwLowDateTime; + tmp /= 10; /* 100ns steps to 1us step */ + tmp -= EPOCH_DIFF; + return tmp; +} + +static BOOL FileSetFileTime(HANDLE hFile, const FILETIME* lpCreationTime, + const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime) { int rc; #if defined(__APPLE__) || defined(ANDROID) || defined(__FreeBSD__) @@ -365,16 +375,18 @@ struct timespec times[2]; /* last access, last modification */ #endif WINPR_FILE* pFile = (WINPR_FILE*)hFile; - const UINT64 EPOCH_DIFF = 11644473600ULL; if (!hFile) return FALSE; #if defined(__APPLE__) || defined(ANDROID) || defined(__FreeBSD__) rc = fstat(fileno(pFile->fp), &buf); + if (rc < 0) return FALSE; + #endif + if (!lpLastAccessTime) { #if defined(__FreeBSD__) || defined(__APPLE__) @@ -394,21 +406,16 @@ } else { - UINT64 tmp = ((UINT64)lpLastAccessTime->dwHighDateTime) << 32 - | lpLastAccessTime->dwLowDateTime; - tmp -= EPOCH_DIFF; - tmp /= 10ULL; - + UINT64 tmp = FileTimeToUS(lpLastAccessTime); #if defined(ANDROID) || defined(__FreeBSD__) || defined(__APPLE__) - tmp /= 10000ULL; - - timevals[0].tv_sec = tmp / 10000ULL; - timevals[0].tv_usec = tmp % 10000ULL; + timevals[0].tv_sec = tmp / 1000000ULL; + timevals[0].tv_usec = tmp % 1000000ULL; #else - times[0].tv_sec = tmp / 10000000ULL; - times[0].tv_nsec = tmp % 10000000ULL; + times[0].tv_sec = tmp / 1000000ULL; + times[0].tv_nsec = (tmp % 1000000ULL) * 1000ULL; #endif } + if (!lpLastWriteTime) { #if defined(__FreeBSD__) || defined(__APPLE__) @@ -428,19 +435,13 @@ } else { - UINT64 tmp = ((UINT64)lpLastWriteTime->dwHighDateTime) << 32 - | lpLastWriteTime->dwLowDateTime; - tmp -= EPOCH_DIFF; - tmp /= 10ULL; - + UINT64 tmp = FileTimeToUS(lpLastWriteTime); #if defined(ANDROID) || defined(__FreeBSD__) || defined(__APPLE__) - tmp /= 10000ULL; - - timevals[1].tv_sec = tmp / 10000ULL; - timevals[1].tv_usec = tmp % 10000ULL; + timevals[1].tv_sec = tmp / 1000000ULL; + timevals[1].tv_usec = tmp % 1000000ULL; #else - times[1].tv_sec = tmp / 10000000ULL; - times[1].tv_nsec = tmp % 10000000ULL; + times[1].tv_sec = tmp / 1000000ULL; + times[1].tv_nsec = (tmp % 1000000ULL) * 1000ULL; #endif } @@ -450,11 +451,11 @@ #else rc = futimens(fileno(pFile->fp), times); #endif + if (rc != 0) return FALSE; return TRUE; - } static HANDLE_OPS fileOps = { @@ -759,6 +760,8 @@ { HANDLE hFile; WCHAR* lpFileNameW = NULL; + + ConvertToUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameW, 0); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/library/library.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/library/library.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/library/library.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/library/library.c 2017-03-03 08:39:24.000000000 +0000 @@ -166,7 +166,7 @@ #endif -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__CYGWIN__) FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName) { diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/path/shell.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/path/shell.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/path/shell.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/path/shell.c 2017-03-03 08:39:24.000000000 +0000 @@ -97,7 +97,7 @@ #ifdef _WIN32 path = GetEnvAlloc("TEMP"); #elif defined(__IOS__) - path = ios_get_temp(); + path = ios_get_temp(); #else path = GetEnvAlloc("TMPDIR"); @@ -366,7 +366,11 @@ if (!env) return NULL; - nSize = GetEnvironmentVariableA(name, env, nSize); + if (GetEnvironmentVariableA(name, env, nSize) != nSize) + { + free(env); + return NULL; + } } return env; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/smartcard/smartcard_pcsc.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/smartcard/smartcard_pcsc.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/smartcard/smartcard_pcsc.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/smartcard/smartcard_pcsc.c 2017-03-03 08:39:24.000000000 +0000 @@ -159,7 +159,7 @@ char SMARTCARD_PNP_NOTIFICATION_A[] = "\\\\?PnP?\\Notification"; WCHAR SMARTCARD_PNP_NOTIFICATION_W[] = -{ '\\','\\','?','P','n','P','?','\\','N','o','t','i','f','i','c','a','t','i','o','n','\0' }; +{ '\\', '\\', '?', 'P', 'n', 'P', '?', '\\', 'N', 'o', 't', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', '\0' }; const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT0Pci = { SCARD_PROTOCOL_T0, sizeof(PCSC_SCARD_IO_REQUEST) }; const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(PCSC_SCARD_IO_REQUEST) }; @@ -167,7 +167,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPCVOID pvMem); WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, - LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); + LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); WINSCARDAPI LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext); LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) @@ -312,12 +312,14 @@ return NULL; pContext->hContext = hContext; + if (!InitializeCriticalSectionAndSpinCount(&(pContext->lock), 4000)) goto error_spinlock; if (!g_CardContexts) { g_CardContexts = ListDictionary_New(TRUE); + if (!g_CardContexts) goto errors; } @@ -325,15 +327,17 @@ if (!g_Readers) { g_Readers = ArrayList_New(TRUE); + if (!g_Readers) goto errors; + ArrayList_Object(g_Readers)->fnObjectFree = (OBJECT_FREE_FN) PCSC_ReaderAliasFree; } if (!ListDictionary_Add(g_CardContexts, (void*) hContext, (void*) pContext)) goto errors; - return pContext; + return pContext; errors: DeleteCriticalSection(&(pContext->lock)); error_spinlock: @@ -426,7 +430,6 @@ if (!hCard) { /* SCardConnect */ - pContext = PCSC_GetCardContextData(hContext); if (!pContext) @@ -436,7 +439,6 @@ return TRUE; /* wait for card ownership */ - return TRUE; } @@ -447,7 +449,6 @@ shared = pCard->shared; hContext = pCard->hSharedContext; - pContext = PCSC_GetCardContextData(hContext); if (!pContext) @@ -456,7 +457,6 @@ if (!pContext->owner) { /* card is not owned */ - if (!shared) pContext->owner = hCard; @@ -483,7 +483,6 @@ if (!hCard) { /* release current owner */ - pContext = PCSC_GetCardContextData(hContext); if (!pContext) @@ -500,9 +499,7 @@ return FALSE; /* release card ownership */ - pContext->owner = 0; - return TRUE; } @@ -512,7 +509,6 @@ return FALSE; hContext = pCard->hSharedContext; - pContext = PCSC_GetCardContextData(hContext); if (!pContext) @@ -521,7 +517,6 @@ if (pContext->owner == hCard) { /* release card ownership */ - pContext->owner = 0; } @@ -541,6 +536,7 @@ } pCard = (PCSC_SCARDHANDLE*) calloc(1, sizeof(PCSC_SCARDHANDLE)); + if (!pCard) return NULL; @@ -549,6 +545,7 @@ if (!g_CardHandles) { g_CardHandles = ListDictionary_New(TRUE); + if (!g_CardHandles) goto error; } @@ -558,7 +555,6 @@ pContext->dwCardHandleCount++; return pCard; - error: free(pCard); return NULL; @@ -568,7 +564,6 @@ { PCSC_SCARDHANDLE* pCard; PCSC_SCARDCONTEXT* pContext; - pCard = PCSC_GetCardHandleData(hCard); if (!pCard) @@ -623,20 +618,24 @@ return TRUE; reader = (PCSC_READER*) calloc(1, sizeof(PCSC_READER)); + if (!reader) return FALSE; reader->namePCSC = _strdup(namePCSC); + if (!reader->namePCSC) goto error_namePSC; reader->nameWinSCard = _strdup(nameWinSCard); + if (!reader->nameWinSCard) goto error_nameWinSCard; + if (ArrayList_Add(g_Readers, reader) < 0) goto error_add; - return TRUE; + return TRUE; error_add: free(reader->nameWinSCard); error_nameWinSCard: @@ -673,7 +672,8 @@ char* p, *q; char* tokens[64][2]; char* nameWinSCard; - char *checkAliasName; + char* checkAliasName; + /** * pcsc-lite reader name format: * name [interface] (serial) index slot @@ -716,8 +716,8 @@ */ if (!name) return NULL; - memset(tokens, 0, sizeof(tokens)); + memset(tokens, 0, sizeof(tokens)); length = strlen(name); if (length < 10) @@ -802,8 +802,8 @@ */ index = 0; sprintf_s(nameWinSCard, size, "%.*s %d", length, p, index); - checkAliasName = PCSC_GetReaderNameFromAlias(nameWinSCard); + while ((checkAliasName != NULL) && (strcmp(checkAliasName, name) != 0)) { index++; @@ -817,7 +817,6 @@ char* PCSC_GetReaderAliasFromName(char* namePCSC) { char* nameWinSCard = NULL; - nameWinSCard = PCSC_ConvertReaderNameToWinSCard(namePCSC); if (nameWinSCard) @@ -914,6 +913,7 @@ if (!g_MemoryBlocks) { g_MemoryBlocks = ListDictionary_New(TRUE); + if (!g_MemoryBlocks) return FALSE; } @@ -942,6 +942,7 @@ free(pvMem); return NULL; } + return pvMem; } @@ -950,7 +951,7 @@ */ WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, - LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) + LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) { LONG status = SCARD_S_SUCCESS; PCSC_DWORD pcsc_dwScope = (PCSC_DWORD) dwScope; @@ -965,7 +966,7 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope, - LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) + LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) { LONG status = SCARD_S_SUCCESS; status = PCSC_SCardEstablishContext_Internal(dwScope, pvReserved1, pvReserved2, phContext); @@ -1017,11 +1018,73 @@ return status; } +WINSCARDAPI LONG WINAPI PCSC_SCardListReaderGroups_Internal(SCARDCONTEXT hContext, + LPSTR mszGroups, LPDWORD pcchGroups) +{ + LONG status = SCARD_S_SUCCESS; + char* mszGroupsWinSCard = NULL; + BOOL pcchGroupsAlloc = FALSE; + LPSTR* pMszGroups = (LPSTR*) mszGroups; + PCSC_DWORD pcsc_cchGroups = 0; + + if (!pcchGroups) + return SCARD_E_INVALID_PARAMETER; + + if (!g_PCSC.pfnSCardListReaderGroups) + return SCARD_E_NO_SERVICE; + + if (*pcchGroups == SCARD_AUTOALLOCATE) + pcchGroupsAlloc = TRUE; + + pcsc_cchGroups = pcchGroupsAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) * pcchGroups; + + if (pcchGroupsAlloc && !g_SCardAutoAllocate) + { + pcsc_cchGroups = 0; + status = (LONG) g_PCSC.pfnSCardListReaderGroups(hContext, NULL, &pcsc_cchGroups); + + if (status == SCARD_S_SUCCESS) + { + *pMszGroups = calloc(1, pcsc_cchGroups); + + if (!*pMszGroups) + return SCARD_E_NO_MEMORY; + + status = (LONG) g_PCSC.pfnSCardListReaderGroups(hContext, *pMszGroups, &pcsc_cchGroups); + + if (status != SCARD_S_SUCCESS) + free(*pMszGroups); + else + PCSC_AddMemoryBlock(hContext, *pMszGroups); + } + } + else + { + status = (LONG) g_PCSC.pfnSCardListReaderGroups(hContext, mszGroups, &pcsc_cchGroups); + } + + status = PCSC_MapErrorCodeToWinSCard(status); + *pcchGroups = (DWORD) pcsc_cchGroups; + + if (status == SCARD_S_SUCCESS) + { + mszGroupsWinSCard = PCSC_ConvertReaderNamesToWinSCard(*pMszGroups, pcchGroups); + + if (mszGroupsWinSCard) + { + PCSC_SCardFreeMemory_Internal(hContext, *pMszGroups); + *pMszGroups = mszGroupsWinSCard; + PCSC_AddMemoryBlock(hContext, *pMszGroups); + } + } + + return status; +} + WINSCARDAPI LONG WINAPI PCSC_SCardListReaderGroupsA(SCARDCONTEXT hContext, - LPSTR mszGroups, LPDWORD pcchGroups) + LPSTR mszGroups, LPDWORD pcchGroups) { LONG status = SCARD_S_SUCCESS; - PCSC_DWORD pcsc_cchGroups = (PCSC_DWORD) *pcchGroups; if (!g_PCSC.pfnSCardListReaderGroups) return SCARD_E_NO_SERVICE; @@ -1029,9 +1092,7 @@ if (!PCSC_LockCardContext(hContext)) return SCARD_E_INVALID_HANDLE; - status = (LONG) g_PCSC.pfnSCardListReaderGroups(hContext, mszGroups, &pcsc_cchGroups); - status = PCSC_MapErrorCodeToWinSCard(status); - *pcchGroups = (DWORD) pcsc_cchGroups; + status = PCSC_SCardListReaderGroups_Internal(hContext, mszGroups, pcchGroups); if (!PCSC_UnlockCardContext(hContext)) return SCARD_E_INVALID_HANDLE; @@ -1040,10 +1101,11 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardListReaderGroupsW(SCARDCONTEXT hContext, - LPWSTR mszGroups, LPDWORD pcchGroups) + LPWSTR mszGroups, LPDWORD pcchGroups) { + LPSTR mszGroupsA = NULL; + LPSTR* pMszGroupsA = &mszGroupsA; LONG status = SCARD_S_SUCCESS; - PCSC_DWORD pcsc_cchGroups = (PCSC_DWORD) *pcchGroups; if (!g_PCSC.pfnSCardListReaderGroups) return SCARD_E_NO_SERVICE; @@ -1051,13 +1113,14 @@ if (!PCSC_LockCardContext(hContext)) return SCARD_E_INVALID_HANDLE; - mszGroups = NULL; - pcchGroups = 0; - /* FIXME: unicode conversion */ - status = (LONG) g_PCSC.pfnSCardListReaderGroups(hContext, (LPSTR) mszGroups, &pcsc_cchGroups); - status = PCSC_MapErrorCodeToWinSCard(status); - if (pcchGroups) - *pcchGroups = (DWORD) pcsc_cchGroups; + status = PCSC_SCardListReaderGroups_Internal(hContext, (LPSTR) &mszGroupsA, pcchGroups); + + if (status == SCARD_S_SUCCESS) + { + *pcchGroups = ConvertToUnicode(CP_UTF8, 0, *pMszGroupsA, *pcchGroups, (WCHAR**) mszGroups, 0); + PCSC_AddMemoryBlock(hContext, mszGroups); + PCSC_SCardFreeMemory_Internal(hContext, *pMszGroupsA); + } if (!PCSC_UnlockCardContext(hContext)) return SCARD_E_INVALID_HANDLE; @@ -1066,7 +1129,7 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext, - LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) + LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) { LONG status = SCARD_S_SUCCESS; char* mszReadersWinSCard = NULL; @@ -1085,7 +1148,7 @@ if (*pcchReaders == SCARD_AUTOALLOCATE) pcchReadersAlloc = TRUE; - pcsc_cchReaders = pcchReadersAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) *pcchReaders; + pcsc_cchReaders = pcchReadersAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) * pcchReaders; if (pcchReadersAlloc && !g_SCardAutoAllocate) { @@ -1131,7 +1194,7 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardListReadersA(SCARDCONTEXT hContext, - LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) + LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) { BOOL nullCardContext = FALSE; LONG status = SCARD_S_SUCCESS; @@ -1166,7 +1229,7 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext, - LPCWSTR mszGroups, LPWSTR mszReaders, LPDWORD pcchReaders) + LPCWSTR mszGroups, LPWSTR mszReaders, LPDWORD pcchReaders) { LPSTR mszGroupsA = NULL; LPSTR mszReadersA = NULL; @@ -1218,49 +1281,51 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardListCardsA(SCARDCONTEXT hContext, - LPCBYTE pbAtr, LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount, CHAR* mszCards, LPDWORD pcchCards) + LPCBYTE pbAtr, LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount, CHAR* mszCards, + LPDWORD pcchCards) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardListCardsW(SCARDCONTEXT hContext, - LPCBYTE pbAtr, LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount, WCHAR* mszCards, LPDWORD pcchCards) + LPCBYTE pbAtr, LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount, WCHAR* mszCards, + LPDWORD pcchCards) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardListInterfacesA(SCARDCONTEXT hContext, - LPCSTR szCard, LPGUID pguidInterfaces, LPDWORD pcguidInterfaces) + LPCSTR szCard, LPGUID pguidInterfaces, LPDWORD pcguidInterfaces) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardListInterfacesW(SCARDCONTEXT hContext, - LPCWSTR szCard, LPGUID pguidInterfaces, LPDWORD pcguidInterfaces) + LPCWSTR szCard, LPGUID pguidInterfaces, LPDWORD pcguidInterfaces) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardGetProviderIdA(SCARDCONTEXT hContext, - LPCSTR szCard, LPGUID pguidProviderId) + LPCSTR szCard, LPGUID pguidProviderId) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardGetProviderIdW(SCARDCONTEXT hContext, - LPCWSTR szCard, LPGUID pguidProviderId) + LPCWSTR szCard, LPGUID pguidProviderId) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardGetCardTypeProviderNameA(SCARDCONTEXT hContext, - LPCSTR szCardName, DWORD dwProviderId, CHAR* szProvider, LPDWORD pcchProvider) + LPCSTR szCardName, DWORD dwProviderId, CHAR* szProvider, LPDWORD pcchProvider) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardGetCardTypeProviderNameW(SCARDCONTEXT hContext, - LPCWSTR szCardName, DWORD dwProviderId, WCHAR* szProvider, LPDWORD pcchProvider) + LPCWSTR szCardName, DWORD dwProviderId, WCHAR* szProvider, LPDWORD pcchProvider) { return 0; } @@ -1286,13 +1351,13 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardIntroduceReaderA(SCARDCONTEXT hContext, - LPCSTR szReaderName, LPCSTR szDeviceName) + LPCSTR szReaderName, LPCSTR szDeviceName) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardIntroduceReaderW(SCARDCONTEXT hContext, - LPCWSTR szReaderName, LPCWSTR szDeviceName) + LPCWSTR szReaderName, LPCWSTR szDeviceName) { return 0; } @@ -1308,51 +1373,51 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardAddReaderToGroupA(SCARDCONTEXT hContext, - LPCSTR szReaderName, LPCSTR szGroupName) + LPCSTR szReaderName, LPCSTR szGroupName) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardAddReaderToGroupW(SCARDCONTEXT hContext, - LPCWSTR szReaderName, LPCWSTR szGroupName) + LPCWSTR szReaderName, LPCWSTR szGroupName) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardRemoveReaderFromGroupA(SCARDCONTEXT hContext, - LPCSTR szReaderName, LPCSTR szGroupName) + LPCSTR szReaderName, LPCSTR szGroupName) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardRemoveReaderFromGroupW(SCARDCONTEXT hContext, - LPCWSTR szReaderName, LPCWSTR szGroupName) + LPCWSTR szReaderName, LPCWSTR szGroupName) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardIntroduceCardTypeA(SCARDCONTEXT hContext, - LPCSTR szCardName, LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces, - DWORD dwInterfaceCount, LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen) + LPCSTR szCardName, LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces, + DWORD dwInterfaceCount, LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardIntroduceCardTypeW(SCARDCONTEXT hContext, - LPCWSTR szCardName, LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces, - DWORD dwInterfaceCount, LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen) + LPCWSTR szCardName, LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces, + DWORD dwInterfaceCount, LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardSetCardTypeProviderNameA(SCARDCONTEXT hContext, - LPCSTR szCardName, DWORD dwProviderId, LPCSTR szProvider) + LPCSTR szCardName, DWORD dwProviderId, LPCSTR szProvider) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardSetCardTypeProviderNameW(SCARDCONTEXT hContext, - LPCWSTR szCardName, DWORD dwProviderId, LPCWSTR szProvider) + LPCWSTR szCardName, DWORD dwProviderId, LPCWSTR szProvider) { return 0; } @@ -1454,31 +1519,31 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardLocateCardsA(SCARDCONTEXT hContext, - LPCSTR mszCards, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) + LPCSTR mszCards, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardLocateCardsW(SCARDCONTEXT hContext, - LPCWSTR mszCards, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders) + LPCWSTR mszCards, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardLocateCardsByATRA(SCARDCONTEXT hContext, - LPSCARD_ATRMASK rgAtrMasks, DWORD cAtrs, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) + LPSCARD_ATRMASK rgAtrMasks, DWORD cAtrs, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardLocateCardsByATRW(SCARDCONTEXT hContext, - LPSCARD_ATRMASK rgAtrMasks, DWORD cAtrs, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders) + LPSCARD_ATRMASK rgAtrMasks, DWORD cAtrs, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext, - DWORD dwTimeout, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) + DWORD dwTimeout, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) { int i, j; int* map; @@ -1498,7 +1563,6 @@ /* pcsc-lite interprets value 0 as INFINITE, work around the problem by using value 1 */ pcsc_dwTimeout = pcsc_dwTimeout ? pcsc_dwTimeout : 1; - /** * Apple's SmartCard Services (not vanilla pcsc-lite) appears to have trouble with the * "\\\\?PnP?\\Notification" reader name. I am always getting EXC_BAD_ACCESS with it. @@ -1521,7 +1585,7 @@ if (!states) { - free (map); + free(map); return SCARD_E_NO_MEMORY; } @@ -1555,7 +1619,7 @@ if (cMappedReaders > 0) { status = (LONG) g_PCSC.pfnSCardGetStatusChange(hContext, - pcsc_dwTimeout, states, cMappedReaders); + pcsc_dwTimeout, states, cMappedReaders); status = PCSC_MapErrorCodeToWinSCard(status); } else @@ -1572,7 +1636,6 @@ rgReaderStates[i].dwCurrentState = states[j].dwCurrentState; rgReaderStates[i].cbAtr = states[j].cbAtr; CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[j].rgbAtr), PCSC_MAX_ATR_SIZE); - dwEventState = states[j].dwEventState & ~SCARD_STATE_CHANGED; if (dwEventState != rgReaderStates[i].dwCurrentState) @@ -1598,6 +1661,7 @@ free(map); free(states); + if ((status == SCARD_S_SUCCESS) && !stateChanged) status = SCARD_E_TIMEOUT; else if ((status == SCARD_E_TIMEOUT) && stateChanged) @@ -1607,7 +1671,7 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChangeA(SCARDCONTEXT hContext, - DWORD dwTimeout, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) + DWORD dwTimeout, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) { LONG status = SCARD_S_SUCCESS; @@ -1623,7 +1687,7 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChangeW(SCARDCONTEXT hContext, - DWORD dwTimeout, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders) + DWORD dwTimeout, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders) { DWORD index; LPSCARD_READERSTATEA states; @@ -1647,7 +1711,7 @@ { states[index].szReader = NULL; ConvertFromUnicode(CP_UTF8, 0, rgReaderStates[index].szReader, -1, - (char**) &(states[index].szReader), 0, NULL, NULL); + (char**) & (states[index].szReader), 0, NULL, NULL); states[index].pvUserData = rgReaderStates[index].pvUserData; states[index].dwCurrentState = rgReaderStates[index].dwCurrentState; states[index].dwEventState = rgReaderStates[index].dwEventState; @@ -1688,8 +1752,8 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, - LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, - LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) + LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, + LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) { BOOL shared; BOOL access; @@ -1704,9 +1768,7 @@ return SCARD_E_NO_SERVICE; shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE; - access = PCSC_WaitForCardAccess(hContext, 0, shared); - szReaderPCSC = PCSC_GetReaderNameFromAlias((char*) szReader); if (!szReaderPCSC) @@ -1723,15 +1785,13 @@ pcsc_dwPreferredProtocols = (PCSC_DWORD) PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols); status = (LONG) g_PCSC.pfnSCardConnect(hContext, szReaderPCSC, - pcsc_dwShareMode, pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol); - + pcsc_dwShareMode, pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol); status = PCSC_MapErrorCodeToWinSCard(status); if (status == SCARD_S_SUCCESS) { pCard = PCSC_ConnectCardHandle(hContext, *phCard); *pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwActiveProtocol); - pCard->shared = shared; PCSC_WaitForCardAccess(hContext, pCard->hSharedContext, shared); } @@ -1740,8 +1800,8 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardConnectA(SCARDCONTEXT hContext, - LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, - LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) + LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, + LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) { LONG status = SCARD_S_SUCCESS; @@ -1749,7 +1809,7 @@ return SCARD_E_INVALID_HANDLE; status = PCSC_SCardConnect_Internal(hContext, szReader, dwShareMode, - dwPreferredProtocols, phCard, pdwActiveProtocol); + dwPreferredProtocols, phCard, pdwActiveProtocol); if (!PCSC_UnlockCardContext(hContext)) return SCARD_E_INVALID_HANDLE; @@ -1758,8 +1818,8 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardConnectW(SCARDCONTEXT hContext, - LPCWSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, - LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) + LPCWSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, + LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) { LPSTR szReaderA = NULL; LONG status = SCARD_S_SUCCESS; @@ -1771,7 +1831,7 @@ ConvertFromUnicode(CP_UTF8, 0, szReader, -1, &szReaderA, 0, NULL, NULL); status = PCSC_SCardConnect_Internal(hContext, szReaderA, dwShareMode, - dwPreferredProtocols, phCard, pdwActiveProtocol); + dwPreferredProtocols, phCard, pdwActiveProtocol); free(szReaderA); if (!PCSC_UnlockCardContext(hContext)) @@ -1781,7 +1841,7 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardReconnect(SCARDHANDLE hCard, - DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol) + DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol) { BOOL shared; BOOL access; @@ -1795,15 +1855,12 @@ return SCARD_E_NO_SERVICE; shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE; - access = PCSC_WaitForCardAccess(0, hCard, shared); - pcsc_dwPreferredProtocols = (PCSC_DWORD) PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols); status = (LONG) g_PCSC.pfnSCardReconnect(hCard, pcsc_dwShareMode, - pcsc_dwPreferredProtocols, pcsc_dwInitialization, &pcsc_dwActiveProtocol); + pcsc_dwPreferredProtocols, pcsc_dwInitialization, &pcsc_dwActiveProtocol); status = PCSC_MapErrorCodeToWinSCard(status); *pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwActiveProtocol); - return status; } @@ -1824,7 +1881,6 @@ } PCSC_ReleaseCardAccess(0, hCard); - return status; } @@ -1852,7 +1908,6 @@ status = (LONG) g_PCSC.pfnSCardBeginTransaction(hCard); status = PCSC_MapErrorCodeToWinSCard(status); - pContext->isTransactionLocked = TRUE; return status; } @@ -1884,9 +1939,7 @@ status = (LONG) g_PCSC.pfnSCardEndTransaction(hCard, pcsc_dwDisposition); status = PCSC_MapErrorCodeToWinSCard(status); - pContext->isTransactionLocked = FALSE; - return status; } @@ -1896,7 +1949,7 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, - LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) + LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { PCSC_DWORD cchReaderLen; SCARDCONTEXT hContext = 0; @@ -1905,7 +1958,7 @@ PCSC_SCARDHANDLE* pCard = NULL; PCSC_DWORD pcsc_dwState = 0; PCSC_DWORD pcsc_dwProtocol = 0; - PCSC_DWORD pcsc_cbAtrLen = (PCSC_DWORD) *pcbAtrLen; + PCSC_DWORD pcsc_cbAtrLen = (PCSC_DWORD) * pcbAtrLen; if (!g_PCSC.pfnSCardStatus) return SCARD_E_NO_SERVICE; @@ -1916,7 +1969,6 @@ return SCARD_E_INVALID_VALUE; PCSC_WaitForCardAccess(0, hCard, pCard->shared); - hContext = PCSC_GetCardContextFromHandle(hCard); if (!hContext) @@ -1924,7 +1976,7 @@ cchReaderLen = SCARD_AUTOALLOCATE; status = (LONG) g_PCSC.pfnSCardStatus(hCard, (LPSTR) &mszReaderNames, &cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen); + &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen); status = PCSC_MapErrorCodeToWinSCard(status); if (mszReaderNames) @@ -1933,13 +1985,12 @@ *pdwState = (DWORD) pcsc_dwState; *pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD) pcsc_dwProtocol); *pcbAtrLen = (DWORD) pcsc_cbAtrLen; - return status; } WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, - LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, - LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) + LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, + LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { SCARDCONTEXT hContext; char* mszReaderNamesWinSCard = NULL; @@ -1963,7 +2014,6 @@ return SCARD_E_INVALID_VALUE; PCSC_WaitForCardAccess(0, hCard, pCard->shared); - hContext = PCSC_GetCardContextFromHandle(hCard); if (!hContext || !pcchReaderLen || !pdwState || !pdwProtocol || !pcbAtrLen) @@ -1972,12 +2022,12 @@ if (*pcchReaderLen == SCARD_AUTOALLOCATE) pcchReaderLenAlloc = TRUE; - pcsc_cchReaderLen = pcchReaderLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) *pcchReaderLen; + pcsc_cchReaderLen = pcchReaderLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) * pcchReaderLen; if (*pcbAtrLen == SCARD_AUTOALLOCATE) pcbAtrLenAlloc = TRUE; - pcsc_cbAtrLen = pcbAtrLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) *pcbAtrLen; + pcsc_cbAtrLen = pcbAtrLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) * pcbAtrLen; if ((pcchReaderLenAlloc || pcbAtrLenAlloc) && !g_SCardAutoAllocate) { @@ -1988,20 +2038,22 @@ pcsc_cbAtrLen = 0; status = (LONG) g_PCSC.pfnSCardStatus(hCard, - (pcchReaderLenAlloc) ? NULL : mszReaderNames, &pcsc_cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, - (pcbAtrLenAlloc) ? NULL : pbAtr, &pcsc_cbAtrLen); + (pcchReaderLenAlloc) ? NULL : mszReaderNames, &pcsc_cchReaderLen, + &pcsc_dwState, &pcsc_dwProtocol, + (pcbAtrLenAlloc) ? NULL : pbAtr, &pcsc_cbAtrLen); if (status == SCARD_S_SUCCESS) { if (pcchReaderLenAlloc) { #ifdef __MACOSX__ + /** * Workaround for SCardStatus Bug in MAC OS X Yosemite */ if (OSXVersion == 0x10100000) pcsc_cchReaderLen++; + #endif *pMszReaderNames = (LPSTR) calloc(1, pcsc_cchReaderLen); @@ -2018,9 +2070,9 @@ } status = (LONG) g_PCSC.pfnSCardStatus(hCard, - *pMszReaderNames, &pcsc_cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, - pbAtr, &pcsc_cbAtrLen); + *pMszReaderNames, &pcsc_cchReaderLen, + &pcsc_dwState, &pcsc_dwProtocol, + pbAtr, &pcsc_cbAtrLen); if (status != SCARD_S_SUCCESS) { @@ -2049,7 +2101,7 @@ else { status = (LONG) g_PCSC.pfnSCardStatus(hCard, mszReaderNames, &pcsc_cchReaderLen, - &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen); + &pcsc_dwState, &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen); } status = PCSC_MapErrorCodeToWinSCard(status); @@ -2071,17 +2123,18 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardStatusA(SCARDHANDLE hCard, - LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, - LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) + LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, + LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { LONG status = SCARD_S_SUCCESS; - status = PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen); + status = PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, + pbAtr, pcbAtrLen); return status; } WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, - LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, - LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) + LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, + LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { SCARDCONTEXT hContext = 0; LPSTR mszReaderNamesA = NULL; @@ -2095,11 +2148,13 @@ if (!hContext) return SCARD_E_INVALID_VALUE; - status = PCSC_SCardStatus_Internal(hCard, (LPSTR) &mszReaderNamesA, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen); + status = PCSC_SCardStatus_Internal(hCard, (LPSTR) &mszReaderNamesA, pcchReaderLen, pdwState, + pdwProtocol, pbAtr, pcbAtrLen); if (mszReaderNamesA) { - *pcchReaderLen = ConvertToUnicode(CP_UTF8, 0, mszReaderNamesA, *pcchReaderLen, (WCHAR**) mszReaderNames, 0); + *pcchReaderLen = ConvertToUnicode(CP_UTF8, 0, mszReaderNamesA, *pcchReaderLen, + (WCHAR**) mszReaderNames, 0); PCSC_AddMemoryBlock(hContext, mszReaderNames); PCSC_SCardFreeMemory_Internal(hContext, mszReaderNamesA); } @@ -2108,8 +2163,8 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, - LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, - LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) + LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, + LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) { LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; @@ -2137,7 +2192,7 @@ if (*pcbRecvLength == SCARD_AUTOALLOCATE) return SCARD_E_INVALID_PARAMETER; - pcsc_cbRecvLength = (PCSC_DWORD) *pcbRecvLength; + pcsc_cbRecvLength = (PCSC_DWORD) * pcbRecvLength; if (!pioSendPci) { @@ -2149,7 +2204,8 @@ * pcsc-lite cannot have a null pioSendPci parameter, unlike WinSCard. * Query the current protocol and use default SCARD_IO_REQUEST for it. */ - status = (LONG) g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, NULL, &cbAtrLen); + status = (LONG) g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, NULL, + &cbAtrLen); if (status == SCARD_S_SUCCESS) { @@ -2184,7 +2240,8 @@ if (!pcsc_pioRecvPci) { if (pioSendPci) - free (pcsc_pioSendPci); + free(pcsc_pioSendPci); + return SCARD_E_NO_MEMORY; } @@ -2196,7 +2253,7 @@ } status = (LONG) g_PCSC.pfnSCardTransmit(hCard, pcsc_pioSendPci, pbSendBuffer, - pcsc_cbSendLength, pcsc_pioRecvPci, pbRecvBuffer, &pcsc_cbRecvLength); + pcsc_cbSendLength, pcsc_pioRecvPci, pbRecvBuffer, &pcsc_cbRecvLength); status = PCSC_MapErrorCodeToWinSCard(status); *pcbRecvLength = (DWORD) pcsc_cbRecvLength; @@ -2218,20 +2275,18 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetTransmitCount(SCARDHANDLE hCard, LPDWORD pcTransmitCount) { PCSC_SCARDHANDLE* pCard = NULL; - pCard = PCSC_GetCardHandleData(hCard); if (!pCard) return SCARD_E_INVALID_VALUE; PCSC_WaitForCardAccess(0, hCard, pCard->shared); - return SCARD_S_SUCCESS; } WINSCARDAPI LONG WINAPI PCSC_SCardControl(SCARDHANDLE hCard, - DWORD dwControlCode, LPCVOID lpInBuffer, DWORD cbInBufferSize, - LPVOID lpOutBuffer, DWORD cbOutBufferSize, LPDWORD lpBytesReturned) + DWORD dwControlCode, LPCVOID lpInBuffer, DWORD cbInBufferSize, + LPVOID lpOutBuffer, DWORD cbOutBufferSize, LPDWORD lpBytesReturned) { DWORD IoCtlMethod = 0; DWORD IoCtlFunction = 0; @@ -2254,7 +2309,6 @@ return SCARD_E_INVALID_VALUE; PCSC_WaitForCardAccess(0, hCard, pCard->shared); - /** * PCSCv2 Part 10: * http://www.pcscworkgroup.com/specifications/files/pcsc10_v2.02.09.pdf @@ -2265,7 +2319,6 @@ * Converting Windows Feature Request IOCTL code to the pcsc-lite control code: * http://musclecard.996296.n3.nabble.com/Converting-Windows-Feature-Request-IOCTL-code-to-the-pcsc-lite-control-code-td4906.html */ - IoCtlMethod = METHOD_FROM_CTL_CODE(dwControlCode); IoCtlFunction = FUNCTION_FROM_CTL_CODE(dwControlCode); IoCtlAccess = ACCESS_FROM_CTL_CODE(dwControlCode); @@ -2278,11 +2331,9 @@ dwControlCode = PCSC_SCARD_CTL_CODE(IoCtlFunction); pcsc_dwControlCode = (PCSC_DWORD) dwControlCode; - status = (LONG) g_PCSC.pfnSCardControl(hCard, - pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize, - lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned); - + pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize, + lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned); status = PCSC_MapErrorCodeToWinSCard(status); *lpBytesReturned = (DWORD) pcsc_BytesReturned; @@ -2307,7 +2358,8 @@ return status; } -WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen) +WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrId, + LPBYTE pbAttr, LPDWORD pcbAttrLen) { SCARDCONTEXT hContext = 0; BOOL pcbAttrLenAlloc = FALSE; @@ -2326,7 +2378,6 @@ return SCARD_E_INVALID_VALUE; PCSC_WaitForCardAccess(0, hCard, pCard->shared); - hContext = PCSC_GetCardContextFromHandle(hCard); if (!hContext) @@ -2338,7 +2389,7 @@ if (*pcbAttrLen == SCARD_AUTOALLOCATE) pcbAttrLenAlloc = TRUE; - pcsc_cbAttrLen = pcbAttrLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) *pcbAttrLen; + pcsc_cbAttrLen = pcbAttrLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD) * pcbAttrLen; if (pcbAttrLenAlloc && !g_SCardAutoAllocate) { @@ -2373,7 +2424,8 @@ return status; } -WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen) +WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwAttrId, + LPBYTE pbAttr, LPDWORD pcbAttrLen) { int length = 0; char* namePCSC = NULL; @@ -2393,18 +2445,21 @@ cbAttrLen = *pcbAttrLen; *pcbAttrLen = SCARD_AUTOALLOCATE; - status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A, (LPBYTE) &pbAttrA, pcbAttrLen); + status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A, (LPBYTE) &pbAttrA, + pcbAttrLen); if (status != SCARD_S_SUCCESS) { pbAttrA = NULL; *pcbAttrLen = SCARD_AUTOALLOCATE; - status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W, (LPBYTE) &pbAttrW, pcbAttrLen); + status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W, (LPBYTE) &pbAttrW, + pcbAttrLen); if (status != SCARD_S_SUCCESS) return status; - length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW, *pcbAttrLen, (char**) &pbAttrA, 0, NULL, NULL); + length = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) pbAttrW, *pcbAttrLen, (char**) &pbAttrA, 0, NULL, + NULL); namePCSC = pbAttrA; PCSC_SCardFreeMemory_Internal(hContext, pbAttrW); } @@ -2499,18 +2554,17 @@ free(namePCSC); free(nameWinSCard); - return status; } -WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen) +WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, + LPDWORD pcbAttrLen) { DWORD cbAttrLen; SCARDCONTEXT hContext; BOOL pcbAttrLenAlloc = FALSE; LONG status = SCARD_S_SUCCESS; LPBYTE* pPbAttr = (LPBYTE*) pbAttr; - cbAttrLen = *pcbAttrLen; if (*pcbAttrLen == SCARD_AUTOALLOCATE) @@ -2524,7 +2578,6 @@ * pcsc-lite returns SCARD_E_INSUFFICIENT_BUFFER if the given * buffer size is larger than PCSC_MAX_BUFFER_SIZE (264) */ - if (*pcbAttrLen > PCSC_MAX_BUFFER_SIZE) *pcbAttrLen = PCSC_MAX_BUFFER_SIZE; } @@ -2534,7 +2587,8 @@ if (!hContext) return SCARD_E_INVALID_HANDLE; - if ((dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A) || (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)) + if ((dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A) || + (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)) { status = PCSC_SCardGetAttrib_FriendlyName(hCard, dwAttrId, pbAttr, pcbAttrLen); return status; @@ -2574,8 +2628,8 @@ PCSC_DWORD cbAtrLen = 0; PCSC_DWORD dwProtocol = 0; PCSC_DWORD cchReaderLen = 0; - - status = (LONG) g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, NULL, &cbAtrLen); + status = (LONG) g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, NULL, + &cbAtrLen); if (status == SCARD_S_SUCCESS) { @@ -2600,7 +2654,6 @@ return SCARD_E_INSUFFICIENT_BUFFER; status = SCARD_S_SUCCESS; - *((DWORD*) pbAttr) = (channelType << 16) | channelNumber; *pcbAttrLen = sizeof(DWORD); } @@ -2670,7 +2723,8 @@ return status; } -WINSCARDAPI LONG WINAPI PCSC_SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen) +WINSCARDAPI LONG WINAPI PCSC_SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, + DWORD cbAttrLen) { LONG status = SCARD_S_SUCCESS; PCSC_SCARDHANDLE* pCard = NULL; @@ -2686,10 +2740,8 @@ return SCARD_E_INVALID_VALUE; PCSC_WaitForCardAccess(0, hCard, pCard->shared); - status = (LONG) g_PCSC.pfnSCardSetAttrib(hCard, pcsc_dwAttrId, pbAttr, pcsc_cbAttrLen); status = PCSC_MapErrorCodeToWinSCard(status); - return status; } @@ -2719,71 +2771,73 @@ } WINSCARDAPI LONG WINAPI PCSC_SCardReadCacheA(SCARDCONTEXT hContext, - UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data, DWORD* DataLen) + UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data, DWORD* DataLen) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardReadCacheW(SCARDCONTEXT hContext, - UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data, DWORD* DataLen) + UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data, DWORD* DataLen) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardWriteCacheA(SCARDCONTEXT hContext, - UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data, DWORD DataLen) + UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data, DWORD DataLen) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardWriteCacheW(SCARDCONTEXT hContext, - UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data, DWORD DataLen) + UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data, DWORD DataLen) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardGetReaderIconA(SCARDCONTEXT hContext, - LPCSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon) + LPCSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardGetReaderIconW(SCARDCONTEXT hContext, - LPCWSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon) + LPCWSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon) { return 0; } -WINSCARDAPI LONG WINAPI PCSC_SCardGetDeviceTypeIdA(SCARDCONTEXT hContext, LPCSTR szReaderName, LPDWORD pdwDeviceTypeId) +WINSCARDAPI LONG WINAPI PCSC_SCardGetDeviceTypeIdA(SCARDCONTEXT hContext, LPCSTR szReaderName, + LPDWORD pdwDeviceTypeId) { return 0; } -WINSCARDAPI LONG WINAPI PCSC_SCardGetDeviceTypeIdW(SCARDCONTEXT hContext, LPCWSTR szReaderName, LPDWORD pdwDeviceTypeId) +WINSCARDAPI LONG WINAPI PCSC_SCardGetDeviceTypeIdW(SCARDCONTEXT hContext, LPCWSTR szReaderName, + LPDWORD pdwDeviceTypeId) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardGetReaderDeviceInstanceIdA(SCARDCONTEXT hContext, - LPCSTR szReaderName, LPSTR szDeviceInstanceId, LPDWORD pcchDeviceInstanceId) + LPCSTR szReaderName, LPSTR szDeviceInstanceId, LPDWORD pcchDeviceInstanceId) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardGetReaderDeviceInstanceIdW(SCARDCONTEXT hContext, - LPCWSTR szReaderName, LPWSTR szDeviceInstanceId, LPDWORD pcchDeviceInstanceId) + LPCWSTR szReaderName, LPWSTR szDeviceInstanceId, LPDWORD pcchDeviceInstanceId) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardListReadersWithDeviceInstanceIdA(SCARDCONTEXT hContext, - LPCSTR szDeviceInstanceId, LPSTR mszReaders, LPDWORD pcchReaders) + LPCSTR szDeviceInstanceId, LPSTR mszReaders, LPDWORD pcchReaders) { return 0; } WINSCARDAPI LONG WINAPI PCSC_SCardListReadersWithDeviceInstanceIdW(SCARDCONTEXT hContext, - LPCWSTR szDeviceInstanceId, LPWSTR mszReaders, LPDWORD pcchReaders) + LPCWSTR szDeviceInstanceId, LPWSTR mszReaders, LPDWORD pcchReaders) { return 0; } @@ -2796,98 +2850,115 @@ #ifdef __MACOSX__ unsigned int determineMacOSXVersion() { - int mib[2]; - size_t len = 0; - char *kernelVersion = NULL; - char *tok = NULL; - unsigned int version = 0; - int majorVersion = 0; - int minorVersion = 0; - int patchVersion = 0; - int count = 0; - - mib[0] = CTL_KERN; - mib[1] = KERN_OSRELEASE; - if (sysctl(mib, 2, NULL, &len, NULL, 0) != 0) - return 0; - kernelVersion = calloc(len, sizeof(char)); - if (!kernelVersion) - return 0; - if (sysctl(mib, 2, kernelVersion, &len, NULL, 0) != 0) - { - free(kernelVersion); - return 0; - } - - tok = strtok(kernelVersion,"."); - while (tok) - { - switch(count) - { - case 0: - majorVersion = atoi(tok); - break; - case 1: - minorVersion = atoi(tok); - break; - case 2: - patchVersion = atoi(tok); - break; - } - tok = strtok(NULL, "."); - count++; - } - - /** - * Source : http://en.wikipedia.org/wiki/Darwin_(operating_system) - **/ - if (majorVersion < 5) - { - if (minorVersion < 4) - version = 0x10000000; - else - version = 0x10010000; - } - else - { - switch (majorVersion) - { - case 5: - version = 0x10010000; - break; - case 6: - version = 0x10020000; - break; - case 7: - version = 0x10030000; - break; - case 8: - version = 0x10040000; - break; - case 9: - version = 0x10050000; - break; - case 10: - version = 0x10060000; - break; - case 11: - version = 0x10070000; - break; - case 12: - version = 0x10080000; - break; - case 13: - version = 0x10090000; - break; - default: - version = 0x10100000; - break; - } - version |= (minorVersion << 8) | (patchVersion); - } + int mib[2]; + size_t len = 0; + char* kernelVersion = NULL; + char* tok = NULL; + unsigned int version = 0; + int majorVersion = 0; + int minorVersion = 0; + int patchVersion = 0; + int count = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_OSRELEASE; + + if (sysctl(mib, 2, NULL, &len, NULL, 0) != 0) + return 0; + + kernelVersion = calloc(len, sizeof(char)); + + if (!kernelVersion) + return 0; + + if (sysctl(mib, 2, kernelVersion, &len, NULL, 0) != 0) + { + free(kernelVersion); + return 0; + } - free(kernelVersion); - return version; + tok = strtok(kernelVersion, "."); + + while (tok) + { + switch (count) + { + case 0: + majorVersion = atoi(tok); + break; + + case 1: + minorVersion = atoi(tok); + break; + + case 2: + patchVersion = atoi(tok); + break; + } + + tok = strtok(NULL, "."); + count++; + } + + /** + * Source : http://en.wikipedia.org/wiki/Darwin_(operating_system) + **/ + if (majorVersion < 5) + { + if (minorVersion < 4) + version = 0x10000000; + else + version = 0x10010000; + } + else + { + switch (majorVersion) + { + case 5: + version = 0x10010000; + break; + + case 6: + version = 0x10020000; + break; + + case 7: + version = 0x10030000; + break; + + case 8: + version = 0x10040000; + break; + + case 9: + version = 0x10050000; + break; + + case 10: + version = 0x10060000; + break; + + case 11: + version = 0x10070000; + break; + + case 12: + version = 0x10080000; + break; + + case 13: + version = 0x10090000; + break; + + default: + version = 0x10100000; + break; + } + + version |= (minorVersion << 8) | (patchVersion); + } + + free(kernelVersion); + return version; } #endif @@ -2983,17 +3054,19 @@ { /* Disable pcsc-lite's (poor) blocking so we can handle it ourselves */ SetEnvironmentVariableA("PCSCLITE_NO_BLOCKING", "1"); - #ifdef __MACOSX__ g_PCSCModule = LoadLibraryA("/System/Library/Frameworks/PCSC.framework/PCSC"); OSXVersion = determineMacOSXVersion(); + if (OSXVersion == 0) return -1; + #else g_PCSCModule = LoadLibraryA("libpcsclite.so.1"); if (!g_PCSCModule) g_PCSCModule = LoadLibraryA("libpcsclite.so"); + #endif if (!g_PCSCModule) @@ -3009,23 +3082,22 @@ g_PCSC.pfnSCardEndTransaction = (void*) GetProcAddress(g_PCSCModule, "SCardEndTransaction"); g_PCSC.pfnSCardStatus = (void*) GetProcAddress(g_PCSCModule, "SCardStatus"); g_PCSC.pfnSCardGetStatusChange = (void*) GetProcAddress(g_PCSCModule, "SCardGetStatusChange"); - #ifdef __MACOSX__ + if (OSXVersion >= 0x10050600) g_PCSC.pfnSCardControl = (void*) GetProcAddress(g_PCSCModule, "SCardControl132"); else g_PCSC.pfnSCardControl = (void*) GetProcAddress(g_PCSCModule, "SCardControl"); + #else g_PCSC.pfnSCardControl = (void*) GetProcAddress(g_PCSCModule, "SCardControl"); #endif - g_PCSC.pfnSCardTransmit = (void*) GetProcAddress(g_PCSCModule, "SCardTransmit"); g_PCSC.pfnSCardListReaderGroups = (void*) GetProcAddress(g_PCSCModule, "SCardListReaderGroups"); g_PCSC.pfnSCardListReaders = (void*) GetProcAddress(g_PCSCModule, "SCardListReaders"); g_PCSC.pfnSCardCancel = (void*) GetProcAddress(g_PCSCModule, "SCardCancel"); g_PCSC.pfnSCardGetAttrib = (void*) GetProcAddress(g_PCSCModule, "SCardGetAttrib"); g_PCSC.pfnSCardSetAttrib = (void*) GetProcAddress(g_PCSCModule, "SCardSetAttrib"); - g_PCSC.pfnSCardFreeMemory = NULL; #ifndef __APPLE__ g_PCSC.pfnSCardFreeMemory = (void*) GetProcAddress(g_PCSCModule, "SCardFreeMemory"); @@ -3038,11 +3110,9 @@ g_PCSC.pfnSCardFreeMemory = NULL; g_SCardAutoAllocate = FALSE; #endif - #ifdef __APPLE__ g_PnP_Notification = FALSE; #endif - return 1; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c 2017-03-03 08:39:24.000000000 +0000 @@ -90,11 +90,11 @@ while (ntlm_av_pair_get_id(pAvPair) != MsvAvEOL) { WLog_INFO(TAG, "\t%s AvId: %"PRIu16" AvLen: %"PRIu16"", - AV_PAIR_STRINGS[ntlm_av_pair_get_id(pAvPair)], - ntlm_av_pair_get_id(pAvPair), - ntlm_av_pair_get_len(pAvPair)); + AV_PAIR_STRINGS[ntlm_av_pair_get_id(pAvPair)], + ntlm_av_pair_get_id(pAvPair), + ntlm_av_pair_get_len(pAvPair)); winpr_HexDump(TAG, WLOG_INFO, ntlm_av_pair_get_value_pointer(pAvPair), - ntlm_av_pair_get_len(pAvPair)); + ntlm_av_pair_get_len(pAvPair)); pAvPair = ntlm_av_pair_get_next_pointer(pAvPair); } } @@ -141,7 +141,8 @@ return NULL; } -NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, NTLM_AV_ID AvId, PBYTE Value, UINT16 AvLen) +NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, NTLM_AV_ID AvId, PBYTE Value, + UINT16 AvLen) { NTLM_AV_PAIR* pAvPair; pAvPair = ntlm_av_pair_get(pAvPairList, MsvAvEOL); @@ -167,8 +168,8 @@ CopyMemory(&pAvPairCopy->AvId, &pAvPair->AvId, 2); CopyMemory(&pAvPairCopy->AvLen, &pAvPair->AvLen, 2); CopyMemory(ntlm_av_pair_get_value_pointer(pAvPairCopy), - ntlm_av_pair_get_value_pointer(pAvPair), - ntlm_av_pair_get_len (pAvPair)); + ntlm_av_pair_get_value_pointer(pAvPair), + ntlm_av_pair_get_len(pAvPair)); return pAvPairCopy; } @@ -176,13 +177,29 @@ { char* name; int status; - CHAR computerName[MAX_COMPUTERNAME_LENGTH + 1]; - DWORD nSize = sizeof(computerName) / sizeof(CHAR); + DWORD nSize = 0; + CHAR* computerName; - if (!GetComputerNameExA(type, computerName, &nSize)) + if (GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize) || (GetLastError() != ERROR_MORE_DATA) || + (nSize < 2)) return -1; - name = _strdup(computerName); + computerName = calloc(nSize, sizeof(CHAR)); + + if (!computerName) + return -1; + + if (!GetComputerNameExA(ComputerNameNetBIOS, computerName, &nSize)) + { + free(computerName); + return -1; + } + + if (nSize > MAX_COMPUTERNAME_LENGTH) + computerName[MAX_COMPUTERNAME_LENGTH] = '\0'; + + name = computerName; + if (!name) return -1; @@ -210,7 +227,6 @@ if (string->Length > 0) { free(string->Buffer); - string->Buffer = NULL; string->Length = 0; string->MaximumLength = 0; @@ -262,7 +278,6 @@ BYTE* ChannelBindingToken; UINT32 ChannelBindingTokenLength; SEC_CHANNEL_BINDINGS* ChannelBindings; - ZeroMemory(context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH); ChannelBindings = context->Bindings.Bindings; @@ -280,17 +295,22 @@ if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->dwInitiatorAddrType)) goto out; + if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->cbInitiatorLength)) goto out; + if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->dwAcceptorAddrType)) goto out; + if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->cbAcceptorLength)) goto out; + if (!ntlm_md5_update_uint32_be(md5, ChannelBindings->cbApplicationDataLength)) goto out; if (!winpr_Digest_Update(md5, (void*) ChannelBindingToken, ChannelBindingTokenLength)) goto out; + if (!winpr_Digest_Final(md5, context->ChannelBindingsHash, WINPR_MD5_DIGEST_LENGTH)) goto out; @@ -348,7 +368,7 @@ AvPairsCount = 5; AvPairsLength = NbDomainName.Length + NbComputerName.Length + - DnsDomainName.Length + DnsComputerName.Length + 8; + DnsDomainName.Length + DnsComputerName.Length + 8; length = ntlm_av_pair_list_size(AvPairsCount, AvPairsLength); if (!sspi_SecBufferAlloc(&context->ChallengeTargetInfo, length)) @@ -358,9 +378,12 @@ AvPairListSize = (ULONG) context->ChallengeTargetInfo.cbBuffer; ntlm_av_pair_list_init(pAvPairList); ntlm_av_pair_add(pAvPairList, MsvAvNbDomainName, (PBYTE) NbDomainName.Buffer, NbDomainName.Length); - ntlm_av_pair_add(pAvPairList, MsvAvNbComputerName, (PBYTE) NbComputerName.Buffer, NbComputerName.Length); - ntlm_av_pair_add(pAvPairList, MsvAvDnsDomainName, (PBYTE) DnsDomainName.Buffer, DnsDomainName.Length); - ntlm_av_pair_add(pAvPairList, MsvAvDnsComputerName, (PBYTE) DnsComputerName.Buffer, DnsComputerName.Length); + ntlm_av_pair_add(pAvPairList, MsvAvNbComputerName, (PBYTE) NbComputerName.Buffer, + NbComputerName.Length); + ntlm_av_pair_add(pAvPairList, MsvAvDnsDomainName, (PBYTE) DnsDomainName.Buffer, + DnsDomainName.Length); + ntlm_av_pair_add(pAvPairList, MsvAvDnsComputerName, (PBYTE) DnsComputerName.Buffer, + DnsComputerName.Length); ntlm_av_pair_add(pAvPairList, MsvAvTimestamp, context->Timestamp, sizeof(context->Timestamp)); ntlm_free_unicode_string(&NbDomainName); ntlm_free_unicode_string(&NbComputerName); @@ -467,6 +490,7 @@ if (!sspi_SecBufferAlloc(&context->AuthenticateTargetInfo, size)) return -1; + AuthenticateTargetInfo = (NTLM_AV_PAIR*) context->AuthenticateTargetInfo.pvBuffer; ntlm_av_pair_list_init(AuthenticateTargetInfo); @@ -498,7 +522,7 @@ if (context->SendSingleHostData) { ntlm_av_pair_add(AuthenticateTargetInfo, MsvAvSingleHost, - (PBYTE) &context->SingleHostData, context->SingleHostData.Size); + (PBYTE) &context->SingleHostData, context->SingleHostData.Size); } if (!context->SuppressExtendedProtection) @@ -508,8 +532,8 @@ if (context->ServicePrincipalName.Length > 0) { ntlm_av_pair_add(AuthenticateTargetInfo, MsvAvTargetName, - (PBYTE) context->ServicePrincipalName.Buffer, - context->ServicePrincipalName.Length); + (PBYTE) context->ServicePrincipalName.Buffer, + context->ServicePrincipalName.Length); } } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sspi/NTLM/ntlm.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sspi/NTLM/ntlm.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sspi/NTLM/ntlm.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sspi/NTLM/ntlm.c 2017-03-03 08:39:24.000000000 +0000 @@ -47,20 +47,38 @@ { int status; char* ws = Workstation; - CHAR computerName[MAX_COMPUTERNAME_LENGTH + 1]; - DWORD nSize = sizeof(computerName) / sizeof(CHAR); + DWORD nSize = 0; + CHAR* computerName; if (!Workstation) { + if (GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize) || (GetLastError() != ERROR_MORE_DATA) || + (nSize < 2)) + return -1; + + computerName = calloc(nSize, sizeof(CHAR)); + + if (!computerName) + return -1; + if (!GetComputerNameExA(ComputerNameNetBIOS, computerName, &nSize)) + { + free(computerName); return -1; - ws = _strdup(computerName); + } + + if (nSize > MAX_COMPUTERNAME_LENGTH) + computerName[MAX_COMPUTERNAME_LENGTH] = '\0'; + + ws = computerName; + if (!ws) return -1; } context->Workstation.Buffer = NULL; status = ConvertToUnicode(CP_UTF8, 0, ws, -1, &context->Workstation.Buffer, 0); + if (!Workstation) free(ws); @@ -69,7 +87,6 @@ context->Workstation.Length = (USHORT)(status - 1); context->Workstation.Length *= 2; - return 1; } @@ -82,13 +99,14 @@ return 1; } - context->ServicePrincipalName.Length = (USHORT) (_wcslen(ServicePrincipalName) * 2); + context->ServicePrincipalName.Length = (USHORT)(_wcslen(ServicePrincipalName) * 2); context->ServicePrincipalName.Buffer = (PWSTR) malloc(context->ServicePrincipalName.Length + 2); if (!context->ServicePrincipalName.Buffer) return -1; - CopyMemory(context->ServicePrincipalName.Buffer, ServicePrincipalName, context->ServicePrincipalName.Length + 2); + CopyMemory(context->ServicePrincipalName.Buffer, ServicePrincipalName, + context->ServicePrincipalName.Length + 2); return 1; } @@ -96,7 +114,8 @@ { int status; context->ServicePrincipalName.Buffer = NULL; - status = ConvertToUnicode(CP_UTF8, 0, ServicePrincipalName, -1, &context->ServicePrincipalName.Buffer, 0); + status = ConvertToUnicode(CP_UTF8, 0, ServicePrincipalName, -1, + &context->ServicePrincipalName.Buffer, 0); if (status <= 0) return -1; @@ -108,16 +127,32 @@ int ntlm_SetContextTargetName(NTLM_CONTEXT* context, char* TargetName) { int status; - CHAR computerName[MAX_COMPUTERNAME_LENGTH + 1]; - DWORD nSize = sizeof(computerName) / sizeof(CHAR); char* name = TargetName; + DWORD nSize = 0; + CHAR* computerName = NULL; if (!name) { - if (!GetComputerNameExA(ComputerNameDnsHostname, computerName, &nSize)) + if (GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize) || (GetLastError() != ERROR_MORE_DATA) || + (nSize < 2)) + return -1; + + computerName = calloc(nSize, sizeof(CHAR)); + + if (!computerName) return -1; - name = _strdup(computerName); + if (!GetComputerNameExA(ComputerNameNetBIOS, computerName, &nSize)) + { + free(computerName); + return -1; + } + + if (nSize > MAX_COMPUTERNAME_LENGTH) + computerName[MAX_COMPUTERNAME_LENGTH] = '\0'; + + name = computerName; + if (!name) return -1; @@ -131,6 +166,7 @@ { if (!TargetName) free(name); + return -1; } @@ -150,7 +186,6 @@ DWORD dwSize; DWORD dwValue; NTLM_CONTEXT* context; - context = (NTLM_CONTEXT*) calloc(1, sizeof(NTLM_CONTEXT)); if (!context) @@ -173,13 +208,16 @@ if (RegQueryValueEx(hKey, _T("UseMIC"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) context->UseMIC = dwValue ? 1 : 0; - if (RegQueryValueEx(hKey, _T("SendVersionInfo"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + if (RegQueryValueEx(hKey, _T("SendVersionInfo"), NULL, &dwType, (BYTE*) &dwValue, + &dwSize) == ERROR_SUCCESS) context->SendVersionInfo = dwValue ? 1 : 0; - if (RegQueryValueEx(hKey, _T("SendSingleHostData"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + if (RegQueryValueEx(hKey, _T("SendSingleHostData"), NULL, &dwType, (BYTE*) &dwValue, + &dwSize) == ERROR_SUCCESS) context->SendSingleHostData = dwValue ? 1 : 0; - if (RegQueryValueEx(hKey, _T("SendWorkstationName"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + if (RegQueryValueEx(hKey, _T("SendWorkstationName"), NULL, &dwType, (BYTE*) &dwValue, + &dwSize) == ERROR_SUCCESS) context->SendWorkstationName = dwValue ? 1 : 0; if (RegQueryValueEx(hKey, _T("WorkstationName"), NULL, &dwType, NULL, &dwSize) == ERROR_SUCCESS) @@ -188,7 +226,7 @@ if (!workstation) { - free (context); + free(context); return NULL; } @@ -213,11 +251,13 @@ * but enabling it in WinPR breaks TS Gateway at this point */ context->SuppressExtendedProtection = FALSE; - status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\LSA"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\LSA"), 0, + KEY_READ | KEY_WOW64_64KEY, &hKey); if (status == ERROR_SUCCESS) { - if (RegQueryValueEx(hKey, _T("SuppressExtendedProtection"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + if (RegQueryValueEx(hKey, _T("SuppressExtendedProtection"), NULL, &dwType, (BYTE*) &dwValue, + &dwSize) == ERROR_SUCCESS) context->SuppressExtendedProtection = dwValue ? 1 : 0; RegCloseKey(hKey); @@ -253,16 +293,17 @@ free(context); } -SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, - ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, - void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) +SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, + SEC_WCHAR* pszPackage, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, + void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SSPI_CREDENTIALS* credentials; SEC_WINNT_AUTH_IDENTITY* identity; if ((fCredentialUse != SECPKG_CRED_OUTBOUND) && - (fCredentialUse != SECPKG_CRED_INBOUND) && - (fCredentialUse != SECPKG_CRED_BOTH)) + (fCredentialUse != SECPKG_CRED_INBOUND) && + (fCredentialUse != SECPKG_CRED_BOTH)) { return SEC_E_INVALID_PARAMETER; } @@ -285,16 +326,17 @@ return SEC_E_OK; } -SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, - ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, - void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) +SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, + SEC_CHAR* pszPackage, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, + void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SSPI_CREDENTIALS* credentials; SEC_WINNT_AUTH_IDENTITY* identity; if ((fCredentialUse != SECPKG_CRED_OUTBOUND) && - (fCredentialUse != SECPKG_CRED_INBOUND) && - (fCredentialUse != SECPKG_CRED_BOTH)) + (fCredentialUse != SECPKG_CRED_INBOUND) && + (fCredentialUse != SECPKG_CRED_BOTH)) { return SEC_E_INVALID_PARAMETER; } @@ -333,7 +375,8 @@ return SEC_E_OK; } -SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer) +SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesW(PCredHandle phCredential, + ULONG ulAttribute, void* pBuffer) { if (ulAttribute == SECPKG_CRED_ATTR_NAMES) { @@ -343,7 +386,8 @@ return SEC_E_UNSUPPORTED_FUNCTION; } -SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer) +SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA(PCredHandle phCredential, + ULONG ulAttribute, void* pBuffer) { return ntlm_QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer); } @@ -351,9 +395,10 @@ /** * @see http://msdn.microsoft.com/en-us/library/windows/desktop/aa374707 */ -SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, - PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp) +SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(PCredHandle phCredential, + PCtxtHandle phContext, + PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp) { NTLM_CONTEXT* context; SECURITY_STATUS status; @@ -462,10 +507,11 @@ return SEC_E_OK; } -SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, - SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, - PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) +SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredential, + PCtxtHandle phContext, + SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, + PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { NTLM_CONTEXT* context; SECURITY_STATUS status; @@ -577,10 +623,11 @@ /** * @see http://msdn.microsoft.com/en-us/library/windows/desktop/aa375512%28v=vs.85%29.aspx */ -SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, - SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, - PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) +SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredential, + PCtxtHandle phContext, + SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, + PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { SECURITY_STATUS status; SEC_WCHAR* pszTargetNameW = NULL; @@ -592,10 +639,8 @@ } status = ntlm_InitializeSecurityContextW(phCredential, phContext, pszTargetNameW, fContextReq, - Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); - + Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); free(pszTargetNameW); - return status; } @@ -632,7 +677,8 @@ /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa379337/ */ -SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer) +SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, + void* pBuffer) { NTLM_CONTEXT* context; @@ -663,23 +709,27 @@ context->UseSamFileDatabase = FALSE; credentials = context->credentials; ZeroMemory(AuthIdentity, sizeof(SecPkgContext_AuthIdentity)); - UserA = AuthIdentity->User; - if (credentials->identity.UserLength > 0) { + + if (credentials->identity.UserLength > 0) + { status = ConvertFromUnicode(CP_UTF8, 0, - (WCHAR *)credentials->identity.User, - credentials->identity.UserLength, &UserA, 256, NULL, - NULL); + (WCHAR*)credentials->identity.User, + credentials->identity.UserLength, &UserA, 256, NULL, + NULL); + if (status <= 0) return SEC_E_INTERNAL_ERROR; } DomainA = AuthIdentity->Domain; - if (credentials->identity.DomainLength > 0) { + + if (credentials->identity.DomainLength > 0) + { status = ConvertFromUnicode(CP_UTF8, 0, - (WCHAR *)credentials->identity.Domain, - credentials->identity.DomainLength, &DomainA, 256, - NULL, NULL); + (WCHAR*)credentials->identity.Domain, + credentials->identity.DomainLength, &DomainA, 256, + NULL, NULL); if (status <= 0) return SEC_E_INTERNAL_ERROR; @@ -689,16 +739,15 @@ } else if (ulAttribute == SECPKG_ATTR_AUTH_NTLM_NTPROOF_VALUE) { - BYTE *blob; - SecBuffer *ntproof, *target; - - ntproof = (SecBuffer *)pBuffer; + BYTE* blob; + SecBuffer* ntproof, *target; + ntproof = (SecBuffer*)pBuffer; target = &context->ChallengeTargetInfo; if (!sspi_SecBufferAlloc(ntproof, 36 + target->cbBuffer)) return (SEC_E_INSUFFICIENT_MEMORY); - blob = (BYTE *)ntproof->pvBuffer; + blob = (BYTE*)ntproof->pvBuffer; /* Server challenge. */ CopyMemory(blob, context->ServerChallenge, 8); /* Response version. */ @@ -713,74 +762,65 @@ /* Reserved 4B. */ /* Server name. */ CopyMemory(&blob[36], target->pvBuffer, target->cbBuffer); - return (SEC_E_OK); } else if (ulAttribute == SECPKG_ATTR_AUTH_NTLM_RANDKEY) { - SecBuffer *randkey; + SecBuffer* randkey; + randkey = (SecBuffer*) pBuffer; - randkey = (SecBuffer *) pBuffer; if (!sspi_SecBufferAlloc(randkey, 16)) return (SEC_E_INSUFFICIENT_MEMORY); CopyMemory(randkey->pvBuffer, context->EncryptedRandomSessionKey, 16); - return (SEC_E_OK); } else if (ulAttribute == SECPKG_ATTR_AUTH_NTLM_MIC) { - SecBuffer *mic; - NTLM_AUTHENTICATE_MESSAGE *message; - - mic = (SecBuffer *) pBuffer; + SecBuffer* mic; + NTLM_AUTHENTICATE_MESSAGE* message; + mic = (SecBuffer*) pBuffer; message = &context->AUTHENTICATE_MESSAGE; if (!sspi_SecBufferAlloc(mic, 16)) return (SEC_E_INSUFFICIENT_MEMORY); CopyMemory(mic->pvBuffer, message->MessageIntegrityCheck, 16); - return (SEC_E_OK); } else if (ulAttribute == SECPKG_ATTR_AUTH_NTLM_MIC_VALUE) { - BYTE *blob; - SecBuffer *micvalue; + BYTE* blob; + SecBuffer* micvalue; ULONG msgSize = context->NegotiateMessage.cbBuffer + context->ChallengeMessage.cbBuffer + - context->AuthenticateMessage.cbBuffer; - - micvalue = (SecBuffer *) pBuffer; + context->AuthenticateMessage.cbBuffer; + micvalue = (SecBuffer*) pBuffer; if (!sspi_SecBufferAlloc(micvalue, msgSize)) return (SEC_E_INSUFFICIENT_MEMORY); - blob = (BYTE *) micvalue->pvBuffer; - + blob = (BYTE*) micvalue->pvBuffer; CopyMemory(blob, context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer); blob += context->NegotiateMessage.cbBuffer; - CopyMemory(blob, context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer); blob += context->ChallengeMessage.cbBuffer; - CopyMemory(blob, context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer); - blob += context->MessageIntegrityCheckOffset; ZeroMemory(blob, 16); - return (SEC_E_OK); } - return SEC_E_UNSUPPORTED_FUNCTION; } -SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer) +SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, + void* pBuffer) { return ntlm_QueryContextAttributesW(phContext, ulAttribute, pBuffer); } -SECURITY_STATUS SEC_ENTRY ntlm_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer) +SECURITY_STATUS SEC_ENTRY ntlm_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, + void* pBuffer, ULONG cbBuffer) { NTLM_CONTEXT* context; @@ -809,7 +849,6 @@ else if (ulAttribute == SECPKG_ATTR_AUTH_NTLM_SAM_FILE) { const char* filename = (char*) pBuffer; - free(context->SamFile); context->SamFile = NULL; @@ -833,22 +872,28 @@ if (AuthNtlmMessage->type == 1) { sspi_SecBufferFree(&context->NegotiateMessage); + if (!sspi_SecBufferAlloc(&context->NegotiateMessage, AuthNtlmMessage->length)) return SEC_E_INSUFFICIENT_MEMORY; + CopyMemory(context->NegotiateMessage.pvBuffer, AuthNtlmMessage->buffer, AuthNtlmMessage->length); } else if (AuthNtlmMessage->type == 2) { sspi_SecBufferFree(&context->ChallengeMessage); + if (!sspi_SecBufferAlloc(&context->ChallengeMessage, AuthNtlmMessage->length)) return SEC_E_INSUFFICIENT_MEMORY; + CopyMemory(context->ChallengeMessage.pvBuffer, AuthNtlmMessage->buffer, AuthNtlmMessage->length); } else if (AuthNtlmMessage->type == 3) { sspi_SecBufferFree(&context->AuthenticateMessage); + if (!sspi_SecBufferAlloc(&context->AuthenticateMessage, AuthNtlmMessage->length)) return SEC_E_INSUFFICIENT_MEMORY; + CopyMemory(context->AuthenticateMessage.pvBuffer, AuthNtlmMessage->buffer, AuthNtlmMessage->length); } @@ -870,7 +915,8 @@ } else if (ulAttribute == SECPKG_ATTR_AUTH_NTLM_CLIENT_CHALLENGE) { - SecPkgContext_AuthNtlmClientChallenge* AuthNtlmClientChallenge = (SecPkgContext_AuthNtlmClientChallenge*) pBuffer; + SecPkgContext_AuthNtlmClientChallenge* AuthNtlmClientChallenge = + (SecPkgContext_AuthNtlmClientChallenge*) pBuffer; if (cbBuffer < sizeof(SecPkgContext_AuthNtlmClientChallenge)) return SEC_E_INVALID_PARAMETER; @@ -880,7 +926,8 @@ } else if (ulAttribute == SECPKG_ATTR_AUTH_NTLM_SERVER_CHALLENGE) { - SecPkgContext_AuthNtlmServerChallenge* AuthNtlmServerChallenge = (SecPkgContext_AuthNtlmServerChallenge*) pBuffer; + SecPkgContext_AuthNtlmServerChallenge* AuthNtlmServerChallenge = + (SecPkgContext_AuthNtlmServerChallenge*) pBuffer; if (cbBuffer < sizeof(SecPkgContext_AuthNtlmServerChallenge)) return SEC_E_INVALID_PARAMETER; @@ -892,7 +939,8 @@ return SEC_E_UNSUPPORTED_FUNCTION; } -SECURITY_STATUS SEC_ENTRY ntlm_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer) +SECURITY_STATUS SEC_ENTRY ntlm_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, + void* pBuffer, ULONG cbBuffer) { return ntlm_SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer); } @@ -902,7 +950,8 @@ return SEC_E_OK; } -SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) +SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, + PSecBufferDesc pMessage, ULONG MessageSeqNo) { int index; int length; @@ -944,6 +993,7 @@ CopyMemory(data, data_buffer->pvBuffer, length); /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */ hmac = winpr_HMAC_New(); + if (hmac && winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->SendSigningKey, WINPR_MD5_DIGEST_LENGTH)) { Data_Write_UINT32(&value, SeqNo); @@ -988,7 +1038,8 @@ return SEC_E_OK; } -SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, + ULONG MessageSeqNo, PULONG pfQOP) { int index; int length; @@ -1038,6 +1089,7 @@ /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */ hmac = winpr_HMAC_New(); + if (hmac && winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH)) { Data_Write_UINT32(&value, SeqNo); @@ -1052,6 +1104,7 @@ free(data); return SEC_E_INSUFFICIENT_MEMORY; } + #ifdef WITH_DEBUG_NTLM WLog_DBG(TAG, "Encrypted Data Buffer (length = %d)", length); winpr_HexDump(TAG, WLOG_DEBUG, data, length); @@ -1081,12 +1134,14 @@ return SEC_E_OK; } -SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) +SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG fQOP, + PSecBufferDesc pMessage, ULONG MessageSeqNo) { return SEC_E_UNSUPPORTED_FUNCTION; } -SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, + ULONG MessageSeqNo, PULONG pfQOP) { return SEC_E_UNSUPPORTED_FUNCTION; } @@ -1165,13 +1220,13 @@ "NTLM Security Package" /* Comment */ }; -WCHAR NTLM_SecPkgInfoW_Name[] = { 'N','T','L','M','\0' }; +WCHAR NTLM_SecPkgInfoW_Name[] = { 'N', 'T', 'L', 'M', '\0' }; WCHAR NTLM_SecPkgInfoW_Comment[] = { - 'N','T','L','M',' ', - 'S','e','c','u','r','i','t','y',' ', - 'P','a','c','k','a','g','e','\0' + 'N', 'T', 'L', 'M', ' ', + 'S', 'e', 'c', 'u', 'r', 'i', 't', 'y', ' ', + 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\0' }; const SecPkgInfoW NTLM_SecPkgInfoW = diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sspi/sspi.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sspi/sspi.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sspi/sspi.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sspi/sspi.c 2017-03-03 08:39:24.000000000 +0000 @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -34,7 +35,7 @@ static wLog* g_Log = NULL; -static BOOL g_Initialized = FALSE; +static INIT_ONCE g_Initialized = INIT_ONCE_STATIC_INIT; #if defined(WITH_NATIVE_SSPI) static HMODULE g_SspiModule = NULL; #endif @@ -46,7 +47,6 @@ static BOOL ShouldUseNativeSspi(void); static BOOL InitializeSspiModule_Native(void); #endif -static void InitializeSspiModule(DWORD flags); #if defined(WITH_NATIVE_SSPI) BOOL ShouldUseNativeSspi(void) @@ -55,15 +55,16 @@ #ifdef _WIN32 DWORD nSize; char* env = NULL; - nSize = GetEnvironmentVariableA("WINPR_NATIVE_SSPI", NULL, 0); if (!nSize) return TRUE; env = (LPSTR) malloc(nSize); + if (!env) return TRUE; + nSize = GetEnvironmentVariableA("WINPR_NATIVE_SSPI", env, nSize); if (strcmp(env, "0") == 0) @@ -82,7 +83,6 @@ { INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW; INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA; - g_SspiModule = LoadLibraryA("secur32.dll"); if (!g_SspiModule) @@ -91,8 +91,10 @@ if (!g_SspiModule) return FALSE; - pInitSecurityInterfaceW = (INIT_SECURITY_INTERFACE_W) GetProcAddress(g_SspiModule, "InitSecurityInterfaceW"); - pInitSecurityInterfaceA = (INIT_SECURITY_INTERFACE_A) GetProcAddress(g_SspiModule, "InitSecurityInterfaceA"); + pInitSecurityInterfaceW = (INIT_SECURITY_INTERFACE_W) GetProcAddress(g_SspiModule, + "InitSecurityInterfaceW"); + pInitSecurityInterfaceA = (INIT_SECURITY_INTERFACE_A) GetProcAddress(g_SspiModule, + "InitSecurityInterfaceA"); if (pInitSecurityInterfaceW) g_SspiW = pInitSecurityInterfaceW(); @@ -104,20 +106,18 @@ } #endif -void InitializeSspiModule(DWORD flags) +static BOOL CALLBACK InitializeSspiModuleInt(PINIT_ONCE once, PVOID param, PVOID* context) { BOOL status = FALSE; + DWORD flags = 0; - if (g_Initialized) - return; - - g_Initialized = TRUE; + if (param) + flags = *(DWORD*)param; sspi_GlobalInit(); - g_Log = WLog_Get("com.winpr.sspi"); - #if defined(WITH_NATIVE_SSPI) + if (flags && (flags & SSPI_INTERFACE_NATIVE)) { status = InitializeSspiModule_Native(); @@ -133,6 +133,7 @@ { status = InitializeSspiModule_Native(); } + #endif if (!status) @@ -140,6 +141,8 @@ g_SspiW = winpr_InitSecurityInterfaceW(); g_SspiA = winpr_InitSecurityInterfaceA(); } + + return TRUE; } const char* GetSecurityStatusString(SECURITY_STATUS status) @@ -148,170 +151,253 @@ { case SEC_E_OK: return "SEC_E_OK"; + case SEC_E_INSUFFICIENT_MEMORY: return "SEC_E_INSUFFICIENT_MEMORY"; + case SEC_E_INVALID_HANDLE: return "SEC_E_INVALID_HANDLE"; + case SEC_E_UNSUPPORTED_FUNCTION: return "SEC_E_UNSUPPORTED_FUNCTION"; + case SEC_E_TARGET_UNKNOWN: return "SEC_E_TARGET_UNKNOWN"; + case SEC_E_INTERNAL_ERROR: return "SEC_E_INTERNAL_ERROR"; + case SEC_E_SECPKG_NOT_FOUND: return "SEC_E_SECPKG_NOT_FOUND"; + case SEC_E_NOT_OWNER: return "SEC_E_NOT_OWNER"; + case SEC_E_CANNOT_INSTALL: return "SEC_E_CANNOT_INSTALL"; + case SEC_E_INVALID_TOKEN: return "SEC_E_INVALID_TOKEN"; + case SEC_E_CANNOT_PACK: return "SEC_E_CANNOT_PACK"; + case SEC_E_QOP_NOT_SUPPORTED: return "SEC_E_QOP_NOT_SUPPORTED"; + case SEC_E_NO_IMPERSONATION: return "SEC_E_NO_IMPERSONATION"; + case SEC_E_LOGON_DENIED: return "SEC_E_LOGON_DENIED"; + case SEC_E_UNKNOWN_CREDENTIALS: return "SEC_E_UNKNOWN_CREDENTIALS"; + case SEC_E_NO_CREDENTIALS: return "SEC_E_NO_CREDENTIALS"; + case SEC_E_MESSAGE_ALTERED: return "SEC_E_MESSAGE_ALTERED"; + case SEC_E_OUT_OF_SEQUENCE: return "SEC_E_OUT_OF_SEQUENCE"; + case SEC_E_NO_AUTHENTICATING_AUTHORITY: return "SEC_E_NO_AUTHENTICATING_AUTHORITY"; + case SEC_E_BAD_PKGID: return "SEC_E_BAD_PKGID"; + case SEC_E_CONTEXT_EXPIRED: return "SEC_E_CONTEXT_EXPIRED"; + case SEC_E_INCOMPLETE_MESSAGE: return "SEC_E_INCOMPLETE_MESSAGE"; + case SEC_E_INCOMPLETE_CREDENTIALS: return "SEC_E_INCOMPLETE_CREDENTIALS"; + case SEC_E_BUFFER_TOO_SMALL: return "SEC_E_BUFFER_TOO_SMALL"; + case SEC_E_WRONG_PRINCIPAL: return "SEC_E_WRONG_PRINCIPAL"; + case SEC_E_TIME_SKEW: return "SEC_E_TIME_SKEW"; + case SEC_E_UNTRUSTED_ROOT: return "SEC_E_UNTRUSTED_ROOT"; + case SEC_E_ILLEGAL_MESSAGE: return "SEC_E_ILLEGAL_MESSAGE"; + case SEC_E_CERT_UNKNOWN: return "SEC_E_CERT_UNKNOWN"; + case SEC_E_CERT_EXPIRED: return "SEC_E_CERT_EXPIRED"; + case SEC_E_ENCRYPT_FAILURE: return "SEC_E_ENCRYPT_FAILURE"; + case SEC_E_DECRYPT_FAILURE: return "SEC_E_DECRYPT_FAILURE"; + case SEC_E_ALGORITHM_MISMATCH: return "SEC_E_ALGORITHM_MISMATCH"; + case SEC_E_SECURITY_QOS_FAILED: return "SEC_E_SECURITY_QOS_FAILED"; + case SEC_E_UNFINISHED_CONTEXT_DELETED: return "SEC_E_UNFINISHED_CONTEXT_DELETED"; + case SEC_E_NO_TGT_REPLY: return "SEC_E_NO_TGT_REPLY"; + case SEC_E_NO_IP_ADDRESSES: return "SEC_E_NO_IP_ADDRESSES"; + case SEC_E_WRONG_CREDENTIAL_HANDLE: return "SEC_E_WRONG_CREDENTIAL_HANDLE"; + case SEC_E_CRYPTO_SYSTEM_INVALID: return "SEC_E_CRYPTO_SYSTEM_INVALID"; + case SEC_E_MAX_REFERRALS_EXCEEDED: return "SEC_E_MAX_REFERRALS_EXCEEDED"; + case SEC_E_MUST_BE_KDC: return "SEC_E_MUST_BE_KDC"; + case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED: return "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED"; + case SEC_E_TOO_MANY_PRINCIPALS: return "SEC_E_TOO_MANY_PRINCIPALS"; + case SEC_E_NO_PA_DATA: return "SEC_E_NO_PA_DATA"; + case SEC_E_PKINIT_NAME_MISMATCH: return "SEC_E_PKINIT_NAME_MISMATCH"; + case SEC_E_SMARTCARD_LOGON_REQUIRED: return "SEC_E_SMARTCARD_LOGON_REQUIRED"; + case SEC_E_SHUTDOWN_IN_PROGRESS: return "SEC_E_SHUTDOWN_IN_PROGRESS"; + case SEC_E_KDC_INVALID_REQUEST: return "SEC_E_KDC_INVALID_REQUEST"; + case SEC_E_KDC_UNABLE_TO_REFER: return "SEC_E_KDC_UNABLE_TO_REFER"; + case SEC_E_KDC_UNKNOWN_ETYPE: return "SEC_E_KDC_UNKNOWN_ETYPE"; + case SEC_E_UNSUPPORTED_PREAUTH: return "SEC_E_UNSUPPORTED_PREAUTH"; + case SEC_E_DELEGATION_REQUIRED: return "SEC_E_DELEGATION_REQUIRED"; + case SEC_E_BAD_BINDINGS: return "SEC_E_BAD_BINDINGS"; + case SEC_E_MULTIPLE_ACCOUNTS: return "SEC_E_MULTIPLE_ACCOUNTS"; + case SEC_E_NO_KERB_KEY: return "SEC_E_NO_KERB_KEY"; + case SEC_E_CERT_WRONG_USAGE: return "SEC_E_CERT_WRONG_USAGE"; + case SEC_E_DOWNGRADE_DETECTED: return "SEC_E_DOWNGRADE_DETECTED"; + case SEC_E_SMARTCARD_CERT_REVOKED: return "SEC_E_SMARTCARD_CERT_REVOKED"; + case SEC_E_ISSUING_CA_UNTRUSTED: return "SEC_E_ISSUING_CA_UNTRUSTED"; + case SEC_E_REVOCATION_OFFLINE_C: return "SEC_E_REVOCATION_OFFLINE_C"; + case SEC_E_PKINIT_CLIENT_FAILURE: return "SEC_E_PKINIT_CLIENT_FAILURE"; + case SEC_E_SMARTCARD_CERT_EXPIRED: return "SEC_E_SMARTCARD_CERT_EXPIRED"; + case SEC_E_NO_S4U_PROT_SUPPORT: return "SEC_E_NO_S4U_PROT_SUPPORT"; + case SEC_E_CROSSREALM_DELEGATION_FAILURE: return "SEC_E_CROSSREALM_DELEGATION_FAILURE"; + case SEC_E_REVOCATION_OFFLINE_KDC: return "SEC_E_REVOCATION_OFFLINE_KDC"; + case SEC_E_ISSUING_CA_UNTRUSTED_KDC: return "SEC_E_ISSUING_CA_UNTRUSTED_KDC"; + case SEC_E_KDC_CERT_EXPIRED: return "SEC_E_KDC_CERT_EXPIRED"; + case SEC_E_KDC_CERT_REVOKED: return "SEC_E_KDC_CERT_REVOKED"; + case SEC_E_INVALID_PARAMETER: return "SEC_E_INVALID_PARAMETER"; + case SEC_E_DELEGATION_POLICY: return "SEC_E_DELEGATION_POLICY"; + case SEC_E_POLICY_NLTM_ONLY: return "SEC_E_POLICY_NLTM_ONLY"; + case SEC_E_NO_CONTEXT: return "SEC_E_NO_CONTEXT"; + case SEC_E_PKU2U_CERT_FAILURE: return "SEC_E_PKU2U_CERT_FAILURE"; + case SEC_E_MUTUAL_AUTH_FAILED: return "SEC_E_MUTUAL_AUTH_FAILED"; + case SEC_I_CONTINUE_NEEDED: return "SEC_I_CONTINUE_NEEDED"; + case SEC_I_COMPLETE_NEEDED: return "SEC_I_COMPLETE_NEEDED"; + case SEC_I_COMPLETE_AND_CONTINUE: return "SEC_I_COMPLETE_AND_CONTINUE"; + case SEC_I_LOCAL_LOGON: return "SEC_I_LOCAL_LOGON"; + case SEC_I_CONTEXT_EXPIRED: return "SEC_I_CONTEXT_EXPIRED"; + case SEC_I_INCOMPLETE_CREDENTIALS: return "SEC_I_INCOMPLETE_CREDENTIALS"; + case SEC_I_RENEGOTIATE: return "SEC_I_RENEGOTIATE"; + case SEC_I_NO_LSA_CONTEXT: return "SEC_I_NO_LSA_CONTEXT"; + case SEC_I_SIGNATURE_NEEDED: return "SEC_I_SIGNATURE_NEEDED"; + case SEC_I_NO_RENEGOTIATION: return "SEC_I_NO_RENEGOTIATION"; } @@ -345,21 +431,15 @@ SecurityFunctionTableW* SEC_ENTRY InitSecurityInterfaceExW(DWORD flags) { - if (!g_Initialized) - InitializeSspiModule(flags); - + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, &flags, NULL); WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceExW"); - return g_SspiW; } SecurityFunctionTableA* SEC_ENTRY InitSecurityInterfaceExA(DWORD flags) { - if (!g_Initialized) - InitializeSspiModule(flags); - + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, &flags, NULL); WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceExA"); - return g_SspiA; } @@ -369,558 +449,484 @@ /* Package Management */ -SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesW(ULONG* pcPackages, PSecPkgInfoW* ppPackageInfo) +SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesW(ULONG* pcPackages, + PSecPkgInfoW* ppPackageInfo) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->EnumerateSecurityPackagesW)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->EnumerateSecurityPackagesW(pcPackages, ppPackageInfo); - - WLog_Print(g_Log, WLOG_DEBUG, "EnumerateSecurityPackagesW: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "EnumerateSecurityPackagesW: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesA(ULONG* pcPackages, PSecPkgInfoA* ppPackageInfo) +SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesA(ULONG* pcPackages, + PSecPkgInfoA* ppPackageInfo) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiA && g_SspiA->EnumerateSecurityPackagesA)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiA->EnumerateSecurityPackagesA(pcPackages, ppPackageInfo); - - WLog_Print(g_Log, WLOG_DEBUG, "EnumerateSecurityPackagesA: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "EnumerateSecurityPackagesA: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } SecurityFunctionTableW* SEC_ENTRY sspi_InitSecurityInterfaceW(void) { - if (!g_Initialized) - InitializeSspiModule(0); - + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceW"); - return g_SspiW; } SecurityFunctionTableA* SEC_ENTRY sspi_InitSecurityInterfaceA(void) { - if (!g_Initialized) - InitializeSspiModule(0); - + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceA"); - return g_SspiA; } -SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName, PSecPkgInfoW* ppPackageInfo) +SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName, + PSecPkgInfoW* ppPackageInfo) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->QuerySecurityPackageInfoW)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->QuerySecurityPackageInfoW(pszPackageName, ppPackageInfo); - - WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityPackageInfoW: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityPackageInfoW: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName, PSecPkgInfoA* ppPackageInfo) +SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName, + PSecPkgInfoA* ppPackageInfo) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiA && g_SspiA->QuerySecurityPackageInfoA)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiA->QuerySecurityPackageInfoA(pszPackageName, ppPackageInfo); - - WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityPackageInfoA: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityPackageInfoA: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } /* Credential Management */ -SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, - ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, - void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) +SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, + SEC_WCHAR* pszPackage, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, + void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->AcquireCredentialsHandleW)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse, - pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); - - WLog_Print(g_Log, WLOG_DEBUG, "AcquireCredentialsHandleW: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); + WLog_Print(g_Log, WLOG_DEBUG, "AcquireCredentialsHandleW: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, - ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, - void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) +SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, + SEC_CHAR* pszPackage, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, + void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiA && g_SspiA->AcquireCredentialsHandleA)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiA->AcquireCredentialsHandleA(pszPrincipal, pszPackage, fCredentialUse, - pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); - - WLog_Print(g_Log, WLOG_DEBUG, "AcquireCredentialsHandleA: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); + WLog_Print(g_Log, WLOG_DEBUG, "AcquireCredentialsHandleA: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags, PSecBuffer pPackedContext, HANDLE* pToken) +SECURITY_STATUS SEC_ENTRY sspi_ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags, + PSecBuffer pPackedContext, HANDLE* pToken) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->ExportSecurityContext)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->ExportSecurityContext(phContext, fFlags, pPackedContext, pToken); - - WLog_Print(g_Log, WLOG_DEBUG, "ExportSecurityContext: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "ExportSecurityContext: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } SECURITY_STATUS SEC_ENTRY sspi_FreeCredentialsHandle(PCredHandle phCredential) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->FreeCredentialsHandle)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->FreeCredentialsHandle(phCredential); - - WLog_Print(g_Log, WLOG_DEBUG, "FreeCredentialsHandle: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "FreeCredentialsHandle: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextW(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext) +SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextW(SEC_WCHAR* pszPackage, + PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->ImportSecurityContextW)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->ImportSecurityContextW(pszPackage, pPackedContext, pToken, phContext); - - WLog_Print(g_Log, WLOG_DEBUG, "ImportSecurityContextW: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "ImportSecurityContextW: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextA(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext) +SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextA(SEC_CHAR* pszPackage, + PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiA && g_SspiA->ImportSecurityContextA)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiA->ImportSecurityContextA(pszPackage, pPackedContext, pToken, phContext); - - WLog_Print(g_Log, WLOG_DEBUG, "ImportSecurityContextA: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "ImportSecurityContextA: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer) +SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesW(PCredHandle phCredential, + ULONG ulAttribute, void* pBuffer) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->QueryCredentialsAttributesW)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer); - - WLog_Print(g_Log, WLOG_DEBUG, "QueryCredentialsAttributesW: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "QueryCredentialsAttributesW: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer) +SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesA(PCredHandle phCredential, + ULONG ulAttribute, void* pBuffer) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiA && g_SspiA->QueryCredentialsAttributesA)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiA->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer); - - WLog_Print(g_Log, WLOG_DEBUG, "QueryCredentialsAttributesA: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "QueryCredentialsAttributesA: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } /* Context Management */ -SECURITY_STATUS SEC_ENTRY sspi_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, - PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp) +SECURITY_STATUS SEC_ENTRY sspi_AcceptSecurityContext(PCredHandle phCredential, + PCtxtHandle phContext, + PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->AcceptSecurityContext)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, - TargetDataRep, phNewContext, pOutput, pfContextAttr, ptsTimeStamp); - - WLog_Print(g_Log, WLOG_DEBUG, "AcceptSecurityContext: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + TargetDataRep, phNewContext, pOutput, pfContextAttr, ptsTimeStamp); + WLog_Print(g_Log, WLOG_DEBUG, "AcceptSecurityContext: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } SECURITY_STATUS SEC_ENTRY sspi_ApplyControlToken(PCtxtHandle phContext, PSecBufferDesc pInput) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->ApplyControlToken)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->ApplyControlToken(phContext, pInput); - - WLog_Print(g_Log, WLOG_DEBUG, "ApplyControlToken: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "ApplyControlToken: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } SECURITY_STATUS SEC_ENTRY sspi_CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->CompleteAuthToken)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->CompleteAuthToken(phContext, pToken); - - WLog_Print(g_Log, WLOG_DEBUG, "CompleteAuthToken: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "CompleteAuthToken: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } SECURITY_STATUS SEC_ENTRY sspi_DeleteSecurityContext(PCtxtHandle phContext) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->DeleteSecurityContext)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->DeleteSecurityContext(phContext); - - WLog_Print(g_Log, WLOG_DEBUG, "DeleteSecurityContext: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "DeleteSecurityContext: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } SECURITY_STATUS SEC_ENTRY sspi_FreeContextBuffer(void* pvContextBuffer) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->FreeContextBuffer)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->FreeContextBuffer(pvContextBuffer); - - WLog_Print(g_Log, WLOG_DEBUG, "FreeContextBuffer: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "FreeContextBuffer: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } SECURITY_STATUS SEC_ENTRY sspi_ImpersonateSecurityContext(PCtxtHandle phContext) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->ImpersonateSecurityContext)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->ImpersonateSecurityContext(phContext); - - WLog_Print(g_Log, WLOG_DEBUG, "ImpersonateSecurityContext: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "ImpersonateSecurityContext: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, - SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, - PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) +SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextW(PCredHandle phCredential, + PCtxtHandle phContext, + SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, + PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->InitializeSecurityContextW)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->InitializeSecurityContextW(phCredential, phContext, - pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, - Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); - - WLog_Print(g_Log, WLOG_DEBUG, "InitializeSecurityContextW: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, + Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); + WLog_Print(g_Log, WLOG_DEBUG, "InitializeSecurityContextW: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, - SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, - PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) +SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextA(PCredHandle phCredential, + PCtxtHandle phContext, + SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, + PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiA && g_SspiA->InitializeSecurityContextA)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiA->InitializeSecurityContextA(phCredential, phContext, - pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, - Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); - - WLog_Print(g_Log, WLOG_DEBUG, "InitializeSecurityContextA: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, + Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); + WLog_Print(g_Log, WLOG_DEBUG, "InitializeSecurityContextA: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer) +SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, + void* pBuffer) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->QueryContextAttributesW)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->QueryContextAttributesW(phContext, ulAttribute, pBuffer); - - WLog_Print(g_Log, WLOG_DEBUG, "QueryContextAttributesW: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "QueryContextAttributesW: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer) +SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, + void* pBuffer) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiA && g_SspiA->QueryContextAttributesA)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiA->QueryContextAttributesA(phContext, ulAttribute, pBuffer); - - WLog_Print(g_Log, WLOG_DEBUG, "QueryContextAttributesA: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "QueryContextAttributesA: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityContextToken(PCtxtHandle phContext, HANDLE* phToken) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->QuerySecurityContextToken)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->QuerySecurityContextToken(phContext, phToken); - - WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityContextToken: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityContextToken: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer) +SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, + void* pBuffer, ULONG cbBuffer) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->SetContextAttributesW)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer); - - WLog_Print(g_Log, WLOG_DEBUG, "SetContextAttributesW: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "SetContextAttributesW: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer) +SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, + void* pBuffer, ULONG cbBuffer) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiA && g_SspiA->SetContextAttributesA)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiA->SetContextAttributesA(phContext, ulAttribute, pBuffer, cbBuffer); - - WLog_Print(g_Log, WLOG_DEBUG, "SetContextAttributesA: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "SetContextAttributesA: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } SECURITY_STATUS SEC_ENTRY sspi_RevertSecurityContext(PCtxtHandle phContext) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->RevertSecurityContext)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->RevertSecurityContext(phContext); - - WLog_Print(g_Log, WLOG_DEBUG, "RevertSecurityContext: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "RevertSecurityContext: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } /* Message Support */ -SECURITY_STATUS SEC_ENTRY sspi_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +SECURITY_STATUS SEC_ENTRY sspi_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, + ULONG MessageSeqNo, PULONG pfQOP) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->DecryptMessage)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP); - - WLog_Print(g_Log, WLOG_DEBUG, "DecryptMessage: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "DecryptMessage: %s (0x%08"PRIX32")", GetSecurityStatusString(status), + status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) +SECURITY_STATUS SEC_ENTRY sspi_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, + PSecBufferDesc pMessage, ULONG MessageSeqNo) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->EncryptMessage)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo); - - WLog_Print(g_Log, WLOG_DEBUG, "EncryptMessage: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "EncryptMessage: %s (0x%08"PRIX32")", GetSecurityStatusString(status), + status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) +SECURITY_STATUS SEC_ENTRY sspi_MakeSignature(PCtxtHandle phContext, ULONG fQOP, + PSecBufferDesc pMessage, ULONG MessageSeqNo) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->MakeSignature)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo); - - WLog_Print(g_Log, WLOG_DEBUG, "MakeSignature: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "MakeSignature: %s (0x%08"PRIX32")", GetSecurityStatusString(status), + status); return status; } -SECURITY_STATUS SEC_ENTRY sspi_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +SECURITY_STATUS SEC_ENTRY sspi_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, + ULONG MessageSeqNo, PULONG pfQOP) { SECURITY_STATUS status; - - if (!g_Initialized) - InitializeSspiModule(0); + InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL); if (!(g_SspiW && g_SspiW->VerifySignature)) return SEC_E_UNSUPPORTED_FUNCTION; status = g_SspiW->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP); - - WLog_Print(g_Log, WLOG_DEBUG, "VerifySignature: %s (0x%08"PRIX32")", GetSecurityStatusString(status), status); - + WLog_Print(g_Log, WLOG_DEBUG, "VerifySignature: %s (0x%08"PRIX32")", + GetSecurityStatusString(status), status); return status; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sspi/test/TestSchannel.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sspi/test/TestSchannel.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sspi/test/TestSchannel.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sspi/test/TestSchannel.c 2017-03-03 08:39:24.000000000 +0000 @@ -437,6 +437,7 @@ if (!(lpTokenOut = (BYTE*) malloc(cbMaxToken))) { printf("Memory allocation failed\n"); + free(lpTokenIn); return NULL; } fContextReq = ASC_REQ_STREAM | diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/synch/semaphore.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/synch/semaphore.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/synch/semaphore.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/synch/semaphore.c 2017-03-03 08:39:24.000000000 +0000 @@ -133,51 +133,48 @@ semaphore->sem = (winpr_sem_t*) NULL; semaphore->ops = &ops; - if (semaphore) - { #ifdef WINPR_PIPE_SEMAPHORE - if (pipe(semaphore->pipe_fd) < 0) + if (pipe(semaphore->pipe_fd) < 0) + { + WLog_ERR(TAG, "failed to create semaphore"); + free(semaphore); + return NULL; + } + + while (lInitialCount > 0) + { + if (write(semaphore->pipe_fd[1], "-", 1) != 1) { - WLog_ERR(TAG, "failed to create semaphore"); + close(semaphore->pipe_fd[0]); + close(semaphore->pipe_fd[1]); free(semaphore); return NULL; } - while (lInitialCount > 0) - { - if (write(semaphore->pipe_fd[1], "-", 1) != 1) - { - close(semaphore->pipe_fd[0]); - close(semaphore->pipe_fd[1]); - free(semaphore); - return NULL; - } - - lInitialCount--; - } + lInitialCount--; + } #else - semaphore->sem = (winpr_sem_t*) malloc(sizeof(winpr_sem_t)); - if (!semaphore->sem) - { - WLog_ERR(TAG, "failed to allocate semaphore memory"); - free(semaphore); - return NULL; - } + semaphore->sem = (winpr_sem_t*) malloc(sizeof(winpr_sem_t)); + if (!semaphore->sem) + { + WLog_ERR(TAG, "failed to allocate semaphore memory"); + free(semaphore); + return NULL; + } #if defined __APPLE__ - if (semaphore_create(mach_task_self(), semaphore->sem, SYNC_POLICY_FIFO, lMaximumCount) != KERN_SUCCESS) + if (semaphore_create(mach_task_self(), semaphore->sem, SYNC_POLICY_FIFO, lMaximumCount) != KERN_SUCCESS) #else - if (sem_init(semaphore->sem, 0, lMaximumCount) == -1) -#endif - { - WLog_ERR(TAG, "failed to create semaphore"); - free(semaphore->sem); - free(semaphore); - return NULL; - } + if (sem_init(semaphore->sem, 0, lMaximumCount) == -1) #endif + { + WLog_ERR(TAG, "failed to create semaphore"); + free(semaphore->sem); + free(semaphore); + return NULL; } +#endif WINPR_HANDLE_SET_TYPE_AND_MODE(semaphore, HANDLE_TYPE_SEMAPHORE, WINPR_FD_READ); handle = (HANDLE) semaphore; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -15,6 +15,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +if(ANDROID) + add_subdirectory(cpufeatures) +endif() + winpr_module_add(sysinfo.c) if((NOT WIN32) AND (NOT APPLE) AND (NOT ANDROID) AND (NOT OPENBSD)) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,20 @@ +# WinPR: Windows Portable Runtime +# libwinpr-sysinfo cmake build script +# +# Copyright 2017 Armin Novak +# Copyright 2017 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. +# 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. + +winpr_module_add(cpu-features.c cpu-features.h) + diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.c 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,1472 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * 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. + * + * 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 WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* ChangeLog for this library: + * + * NDK r10e?: Add MIPS MSA feature. + * + * NDK r10: Support for 64-bit CPUs (Intel, ARM & MIPS). + * + * NDK r8d: Add android_setCpu(). + * + * NDK r8c: Add new ARM CPU features: VFPv2, VFP_D32, VFP_FP16, + * VFP_FMA, NEON_FMA, IDIV_ARM, IDIV_THUMB2 and iWMMXt. + * + * Rewrite the code to parse /proc/self/auxv instead of + * the "Features" field in /proc/cpuinfo. + * + * Dynamically allocate the buffer that hold the content + * of /proc/cpuinfo to deal with newer hardware. + * + * NDK r7c: Fix CPU count computation. The old method only reported the + * number of _active_ CPUs when the library was initialized, + * which could be less than the real total. + * + * NDK r5: Handle buggy kernels which report a CPU Architecture number of 7 + * for an ARMv6 CPU (see below). + * + * Handle kernels that only report 'neon', and not 'vfpv3' + * (VFPv3 is mandated by the ARM architecture is Neon is implemented) + * + * Handle kernels that only report 'vfpv3d16', and not 'vfpv3' + * + * Fix x86 compilation. Report ANDROID_CPU_FAMILY_X86 in + * android_getCpuFamily(). + * + * NDK r4: Initial release + */ + +#include "cpu-features.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +static pthread_once_t g_once; +static int g_inited; +static AndroidCpuFamily g_cpuFamily; +static uint64_t g_cpuFeatures; +static int g_cpuCount; + +#ifdef __arm__ +static uint32_t g_cpuIdArm; +#endif + +static const int android_cpufeatures_debug = 0; + +#define D(...) \ + do { \ + if (android_cpufeatures_debug) { \ + printf(__VA_ARGS__); fflush(stdout); \ + } \ + } while (0) + +#ifdef __i386__ +static __inline__ void x86_cpuid(int func, int values[4]) +{ + int a, b, c, d; + /* We need to preserve ebx since we're compiling PIC code */ + /* this means we can't use "=b" for the second output register */ + __asm__ __volatile__(\ + "push %%ebx\n" + "cpuid\n" \ + "mov %%ebx, %1\n" + "pop %%ebx\n" + : "=a"(a), "=r"(b), "=c"(c), "=d"(d) \ + : "a"(func) \ + ); + values[0] = a; + values[1] = b; + values[2] = c; + values[3] = d; +} +#elif defined(__x86_64__) +static __inline__ void x86_cpuid(int func, int values[4]) +{ + int64_t a, b, c, d; + /* We need to preserve ebx since we're compiling PIC code */ + /* this means we can't use "=b" for the second output register */ + __asm__ __volatile__(\ + "push %%rbx\n" + "cpuid\n" \ + "mov %%rbx, %1\n" + "pop %%rbx\n" + : "=a"(a), "=r"(b), "=c"(c), "=d"(d) \ + : "a"(func) \ + ); + values[0] = a; + values[1] = b; + values[2] = c; + values[3] = d; +} +#endif + +/* Get the size of a file by reading it until the end. This is needed + * because files under /proc do not always return a valid size when + * using fseek(0, SEEK_END) + ftell(). Nor can they be mmap()-ed. + */ +static int +get_file_size(const char* pathname) +{ + int fd, result = 0; + char buffer[256]; + fd = open(pathname, O_RDONLY); + + if (fd < 0) + { + D("Can't open %s: %s\n", pathname, strerror(errno)); + return -1; + } + + for (;;) + { + int ret = read(fd, buffer, sizeof buffer); + + if (ret < 0) + { + if (errno == EINTR) + continue; + + D("Error while reading %s: %s\n", pathname, strerror(errno)); + break; + } + + if (ret == 0) + break; + + result += ret; + } + + close(fd); + return result; +} + +/* Read the content of /proc/cpuinfo into a user-provided buffer. + * Return the length of the data, or -1 on error. Does *not* + * zero-terminate the content. Will not read more + * than 'buffsize' bytes. + */ +static int +read_file(const char* pathname, char* buffer, size_t buffsize) +{ + int fd, count; + fd = open(pathname, O_RDONLY); + + if (fd < 0) + { + D("Could not open %s: %s\n", pathname, strerror(errno)); + return -1; + } + + count = 0; + + while (count < (int)buffsize) + { + int ret = read(fd, buffer + count, buffsize - count); + + if (ret < 0) + { + if (errno == EINTR) + continue; + + D("Error while reading from %s: %s\n", pathname, strerror(errno)); + + if (count == 0) + count = -1; + + break; + } + + if (ret == 0) + break; + + count += ret; + } + + close(fd); + return count; +} + +#ifdef __arm__ +/* Extract the content of a the first occurence of a given field in + * the content of /proc/cpuinfo and return it as a heap-allocated + * string that must be freed by the caller. + * + * Return NULL if not found + */ +static char* +extract_cpuinfo_field(const char* buffer, int buflen, const char* field) +{ + int fieldlen = strlen(field); + const char* bufend = buffer + buflen; + char* result = NULL; + int len; + const char* p, *q; + /* Look for first field occurence, and ensures it starts the line. */ + p = buffer; + + for (;;) + { + p = memmem(p, bufend - p, field, fieldlen); + + if (p == NULL) + goto EXIT; + + if (p == buffer || p[-1] == '\n') + break; + + p += fieldlen; + } + + /* Skip to the first column followed by a space */ + p += fieldlen; + p = memchr(p, ':', bufend - p); + + if (p == NULL || p[1] != ' ') + goto EXIT; + + /* Find the end of the line */ + p += 2; + q = memchr(p, '\n', bufend - p); + + if (q == NULL) + q = bufend; + + /* Copy the line into a heap-allocated buffer */ + len = q - p; + result = malloc(len + 1); + + if (result == NULL) + goto EXIT; + + memcpy(result, p, len); + result[len] = '\0'; +EXIT: + return result; +} + +/* Checks that a space-separated list of items contains one given 'item'. + * Returns 1 if found, 0 otherwise. + */ +static int +has_list_item(const char* list, const char* item) +{ + const char* p = list; + int itemlen = strlen(item); + + if (list == NULL) + return 0; + + while (*p) + { + const char* q; + + /* skip spaces */ + while (*p == ' ' || *p == '\t') + p++; + + /* find end of current list item */ + q = p; + + while (*q && *q != ' ' && *q != '\t') + q++; + + if (itemlen == q - p && !memcmp(p, item, itemlen)) + return 1; + + /* skip to next item */ + p = q; + } + + return 0; +} +#endif /* __arm__ */ + +/* Parse a number starting from 'input', but not going further + * than 'limit'. Return the value into '*result'. + * + * NOTE: Does not skip over leading spaces, or deal with sign characters. + * NOTE: Ignores overflows. + * + * The function returns NULL in case of error (bad format), or the new + * position after the decimal number in case of success (which will always + * be <= 'limit'). + */ +static const char* +parse_number(const char* input, const char* limit, int base, int* result) +{ + const char* p = input; + int val = 0; + + while (p < limit) + { + int d = (*p - '0'); + + if ((unsigned)d >= 10U) + { + d = (*p - 'a'); + + if ((unsigned)d >= 6U) + d = (*p - 'A'); + + if ((unsigned)d >= 6U) + break; + + d += 10; + } + + if (d >= base) + break; + + val = val * base + d; + p++; + } + + if (p == input) + return NULL; + + *result = val; + return p; +} + +static const char* +parse_decimal(const char* input, const char* limit, int* result) +{ + return parse_number(input, limit, 10, result); +} + +#ifdef __arm__ +static const char* +parse_hexadecimal(const char* input, const char* limit, int* result) +{ + return parse_number(input, limit, 16, result); +} +#endif /* __arm__ */ + +/* This small data type is used to represent a CPU list / mask, as read + * from sysfs on Linux. See http://www.kernel.org/doc/Documentation/cputopology.txt + * + * For now, we don't expect more than 32 cores on mobile devices, so keep + * everything simple. + */ +typedef struct +{ + uint32_t mask; +} CpuList; + +static __inline__ void +cpulist_init(CpuList* list) +{ + list->mask = 0; +} + +static __inline__ void +cpulist_and(CpuList* list1, CpuList* list2) +{ + list1->mask &= list2->mask; +} + +static __inline__ void +cpulist_set(CpuList* list, int index) +{ + if ((unsigned)index < 32) + { + list->mask |= (uint32_t)(1U << index); + } +} + +static __inline__ int +cpulist_count(CpuList* list) +{ + return __builtin_popcount(list->mask); +} + +/* Parse a textual list of cpus and store the result inside a CpuList object. + * Input format is the following: + * - comma-separated list of items (no spaces) + * - each item is either a single decimal number (cpu index), or a range made + * of two numbers separated by a single dash (-). Ranges are inclusive. + * + * Examples: 0 + * 2,4-127,128-143 + * 0-1 + */ +static void +cpulist_parse(CpuList* list, const char* line, int line_len) +{ + const char* p = line; + const char* end = p + line_len; + const char* q; + + /* NOTE: the input line coming from sysfs typically contains a + * trailing newline, so take care of it in the code below + */ + while (p < end && *p != '\n') + { + int val, start_value, end_value; + /* Find the end of current item, and put it into 'q' */ + q = memchr(p, ',', end - p); + + if (q == NULL) + { + q = end; + } + + /* Get first value */ + p = parse_decimal(p, q, &start_value); + + if (p == NULL) + goto BAD_FORMAT; + + end_value = start_value; + + /* If we're not at the end of the item, expect a dash and + * and integer; extract end value. + */ + if (p < q && *p == '-') + { + p = parse_decimal(p + 1, q, &end_value); + + if (p == NULL) + goto BAD_FORMAT; + } + + /* Set bits CPU list bits */ + for (val = start_value; val <= end_value; val++) + { + cpulist_set(list, val); + } + + /* Jump to next item */ + p = q; + + if (p < end) + p++; + } + +BAD_FORMAT: + ; +} + +/* Read a CPU list from one sysfs file */ +static void +cpulist_read_from(CpuList* list, const char* filename) +{ + char file[64]; + int filelen; + cpulist_init(list); + filelen = read_file(filename, file, sizeof file); + + if (filelen < 0) + { + D("Could not read %s: %s\n", filename, strerror(errno)); + return; + } + + cpulist_parse(list, file, filelen); +} +#if defined(__aarch64__) +// see kernel header +#define HWCAP_FP (1 << 0) +#define HWCAP_ASIMD (1 << 1) +#define HWCAP_AES (1 << 3) +#define HWCAP_PMULL (1 << 4) +#define HWCAP_SHA1 (1 << 5) +#define HWCAP_SHA2 (1 << 6) +#define HWCAP_CRC32 (1 << 7) +#endif + +#if defined(__arm__) + +// See kernel header. +#define HWCAP_VFP (1 << 6) +#define HWCAP_IWMMXT (1 << 9) +#define HWCAP_NEON (1 << 12) +#define HWCAP_VFPv3 (1 << 13) +#define HWCAP_VFPv3D16 (1 << 14) +#define HWCAP_VFPv4 (1 << 16) +#define HWCAP_IDIVA (1 << 17) +#define HWCAP_IDIVT (1 << 18) + +// see kernel header +#define HWCAP2_AES (1 << 0) +#define HWCAP2_PMULL (1 << 1) +#define HWCAP2_SHA1 (1 << 2) +#define HWCAP2_SHA2 (1 << 3) +#define HWCAP2_CRC32 (1 << 4) + +// This is the list of 32-bit ARMv7 optional features that are _always_ +// supported by ARMv8 CPUs, as mandated by the ARM Architecture Reference +// Manual. +#define HWCAP_SET_FOR_ARMV8 \ + ( HWCAP_VFP | \ + HWCAP_NEON | \ + HWCAP_VFPv3 | \ + HWCAP_VFPv4 | \ + HWCAP_IDIVA | \ + HWCAP_IDIVT ) +#endif + +#if defined(__mips__) +// see kernel header +#define HWCAP_MIPS_R6 (1 << 0) +#define HWCAP_MIPS_MSA (1 << 1) +#endif + +#if defined(__arm__) || defined(__aarch64__) || defined(__mips__) + +#define AT_HWCAP 16 +#define AT_HWCAP2 26 + +// Probe the system's C library for a 'getauxval' function and call it if +// it exits, or return 0 for failure. This function is available since API +// level 20. +// +// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the +// edge case where some NDK developers use headers for a platform that is +// newer than the one really targetted by their application. +// This is typically done to use newer native APIs only when running on more +// recent Android versions, and requires careful symbol management. +// +// Note that getauxval() can't really be re-implemented here, because +// its implementation does not parse /proc/self/auxv. Instead it depends +// on values that are passed by the kernel at process-init time to the +// C runtime initialization layer. +static uint32_t +get_elf_hwcap_from_getauxval(int hwcap_type) +{ + typedef unsigned long getauxval_func_t(unsigned long); + dlerror(); + void* libc_handle = dlopen("libc.so", RTLD_NOW); + + if (!libc_handle) + { + D("Could not dlopen() C library: %s\n", dlerror()); + return 0; + } + + uint32_t ret = 0; + getauxval_func_t* func = (getauxval_func_t*) + dlsym(libc_handle, "getauxval"); + + if (!func) + { + D("Could not find getauxval() in C library\n"); + } + else + { + // Note: getauxval() returns 0 on failure. Doesn't touch errno. + ret = (uint32_t)(*func)(hwcap_type); + } + + dlclose(libc_handle); + return ret; +} +#endif + +#if defined(__arm__) +// Parse /proc/self/auxv to extract the ELF HW capabilities bitmap for the +// current CPU. Note that this file is not accessible from regular +// application processes on some Android platform releases. +// On success, return new ELF hwcaps, or 0 on failure. +static uint32_t +get_elf_hwcap_from_proc_self_auxv(void) +{ + const char filepath[] = "/proc/self/auxv"; + int fd = TEMP_FAILURE_RETRY(open(filepath, O_RDONLY)); + + if (fd < 0) + { + D("Could not open %s: %s\n", filepath, strerror(errno)); + return 0; + } + + struct + { + uint32_t tag; + uint32_t value; + } entry; + + uint32_t result = 0; + + for (;;) + { + int ret = TEMP_FAILURE_RETRY(read(fd, (char*)&entry, sizeof entry)); + + if (ret < 0) + { + D("Error while reading %s: %s\n", filepath, strerror(errno)); + break; + } + + // Detect end of list. + if (ret == 0 || (entry.tag == 0 && entry.value == 0)) + break; + + if (entry.tag == AT_HWCAP) + { + result = entry.value; + break; + } + } + + close(fd); + return result; +} + +/* Compute the ELF HWCAP flags from the content of /proc/cpuinfo. + * This works by parsing the 'Features' line, which lists which optional + * features the device's CPU supports, on top of its reference + * architecture. + */ +static uint32_t +get_elf_hwcap_from_proc_cpuinfo(const char* cpuinfo, int cpuinfo_len) +{ + uint32_t hwcaps = 0; + long architecture = 0; + char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture"); + + if (cpuArch) + { + architecture = strtol(cpuArch, NULL, 10); + free(cpuArch); + + if (architecture >= 8L) + { + // This is a 32-bit ARM binary running on a 64-bit ARM64 kernel. + // The 'Features' line only lists the optional features that the + // device's CPU supports, compared to its reference architecture + // which are of no use for this process. + D("Faking 32-bit ARM HWCaps on ARMv%ld CPU\n", architecture); + return HWCAP_SET_FOR_ARMV8; + } + } + + char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features"); + + if (cpuFeatures != NULL) + { + D("Found cpuFeatures = '%s'\n", cpuFeatures); + + if (has_list_item(cpuFeatures, "vfp")) + hwcaps |= HWCAP_VFP; + + if (has_list_item(cpuFeatures, "vfpv3")) + hwcaps |= HWCAP_VFPv3; + + if (has_list_item(cpuFeatures, "vfpv3d16")) + hwcaps |= HWCAP_VFPv3D16; + + if (has_list_item(cpuFeatures, "vfpv4")) + hwcaps |= HWCAP_VFPv4; + + if (has_list_item(cpuFeatures, "neon")) + hwcaps |= HWCAP_NEON; + + if (has_list_item(cpuFeatures, "idiva")) + hwcaps |= HWCAP_IDIVA; + + if (has_list_item(cpuFeatures, "idivt")) + hwcaps |= HWCAP_IDIVT; + + if (has_list_item(cpuFeatures, "idiv")) + hwcaps |= HWCAP_IDIVA | HWCAP_IDIVT; + + if (has_list_item(cpuFeatures, "iwmmxt")) + hwcaps |= HWCAP_IWMMXT; + + free(cpuFeatures); + } + + return hwcaps; +} +#endif /* __arm__ */ + +/* Return the number of cpus present on a given device. + * + * To handle all weird kernel configurations, we need to compute the + * intersection of the 'present' and 'possible' CPU lists and count + * the result. + */ +static int +get_cpu_count(void) +{ + CpuList cpus_present[1]; + CpuList cpus_possible[1]; + cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present"); + cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible"); + /* Compute the intersection of both sets to get the actual number of + * CPU cores that can be used on this device by the kernel. + */ + cpulist_and(cpus_present, cpus_possible); + return cpulist_count(cpus_present); +} + +static void +android_cpuInitFamily(void) +{ +#if defined(__arm__) + g_cpuFamily = ANDROID_CPU_FAMILY_ARM; +#elif defined(__i386__) + g_cpuFamily = ANDROID_CPU_FAMILY_X86; +#elif defined(__mips64) + /* Needs to be before __mips__ since the compiler defines both */ + g_cpuFamily = ANDROID_CPU_FAMILY_MIPS64; +#elif defined(__mips__) + g_cpuFamily = ANDROID_CPU_FAMILY_MIPS; +#elif defined(__aarch64__) + g_cpuFamily = ANDROID_CPU_FAMILY_ARM64; +#elif defined(__x86_64__) + g_cpuFamily = ANDROID_CPU_FAMILY_X86_64; +#else + g_cpuFamily = ANDROID_CPU_FAMILY_UNKNOWN; +#endif +} + +static void +android_cpuInit(void) +{ + char* cpuinfo = NULL; + int cpuinfo_len; + android_cpuInitFamily(); + g_cpuFeatures = 0; + g_cpuCount = 1; + g_inited = 1; + cpuinfo_len = get_file_size("/proc/cpuinfo"); + + if (cpuinfo_len < 0) + { + D("cpuinfo_len cannot be computed!"); + return; + } + + cpuinfo = malloc(cpuinfo_len); + + if (cpuinfo == NULL) + { + D("cpuinfo buffer could not be allocated"); + return; + } + + cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, cpuinfo_len); + D("cpuinfo_len is (%d):\n%.*s\n", cpuinfo_len, + cpuinfo_len >= 0 ? cpuinfo_len : 0, cpuinfo); + + if (cpuinfo_len < 0) /* should not happen */ + { + free(cpuinfo); + return; + } + + /* Count the CPU cores, the value may be 0 for single-core CPUs */ + g_cpuCount = get_cpu_count(); + + if (g_cpuCount == 0) + { + g_cpuCount = 1; + } + + D("found cpuCount = %d\n", g_cpuCount); +#ifdef __arm__ + { + /* Extract architecture from the "CPU Architecture" field. + * The list is well-known, unlike the the output of + * the 'Processor' field which can vary greatly. + * + * See the definition of the 'proc_arch' array in + * $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in + * same file. + */ + char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture"); + + if (cpuArch != NULL) + { + char* end; + long archNumber; + int hasARMv7 = 0; + D("found cpuArch = '%s'\n", cpuArch); + /* read the initial decimal number, ignore the rest */ + archNumber = strtol(cpuArch, &end, 10); + + /* Note that ARMv8 is upwards compatible with ARMv7. */ + if (end > cpuArch && archNumber >= 7) + { + hasARMv7 = 1; + } + + /* Unfortunately, it seems that certain ARMv6-based CPUs + * report an incorrect architecture number of 7! + * + * See http://code.google.com/p/android/issues/detail?id=10812 + * + * We try to correct this by looking at the 'elf_format' + * field reported by the 'Processor' field, which is of the + * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for + * an ARMv6-one. + */ + if (hasARMv7) + { + char* cpuProc = extract_cpuinfo_field(cpuinfo, cpuinfo_len, + "Processor"); + + if (cpuProc != NULL) + { + D("found cpuProc = '%s'\n", cpuProc); + + if (has_list_item(cpuProc, "(v6l)")) + { + D("CPU processor and architecture mismatch!!\n"); + hasARMv7 = 0; + } + + free(cpuProc); + } + } + + if (hasARMv7) + { + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7; + } + + /* The LDREX / STREX instructions are available from ARMv6 */ + if (archNumber >= 6) + { + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX; + } + + free(cpuArch); + } + + /* Extract the list of CPU features from ELF hwcaps */ + uint32_t hwcaps = 0; + hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP); + + if (!hwcaps) + { + D("Parsing /proc/self/auxv to extract ELF hwcaps!\n"); + hwcaps = get_elf_hwcap_from_proc_self_auxv(); + } + + if (!hwcaps) + { + // Parsing /proc/self/auxv will fail from regular application + // processes on some Android platform versions, when this happens + // parse proc/cpuinfo instead. + D("Parsing /proc/cpuinfo to extract ELF hwcaps!\n"); + hwcaps = get_elf_hwcap_from_proc_cpuinfo(cpuinfo, cpuinfo_len); + } + + if (hwcaps != 0) + { + int has_vfp = (hwcaps & HWCAP_VFP); + int has_vfpv3 = (hwcaps & HWCAP_VFPv3); + int has_vfpv3d16 = (hwcaps & HWCAP_VFPv3D16); + int has_vfpv4 = (hwcaps & HWCAP_VFPv4); + int has_neon = (hwcaps & HWCAP_NEON); + int has_idiva = (hwcaps & HWCAP_IDIVA); + int has_idivt = (hwcaps & HWCAP_IDIVT); + int has_iwmmxt = (hwcaps & HWCAP_IWMMXT); + + // The kernel does a poor job at ensuring consistency when + // describing CPU features. So lots of guessing is needed. + + // 'vfpv4' implies VFPv3|VFP_FMA|FP16 + if (has_vfpv4) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3 | + ANDROID_CPU_ARM_FEATURE_VFP_FP16 | + ANDROID_CPU_ARM_FEATURE_VFP_FMA; + + // 'vfpv3' or 'vfpv3d16' imply VFPv3. Note that unlike GCC, + // a value of 'vfpv3' doesn't necessarily mean that the D32 + // feature is present, so be conservative. All CPUs in the + // field that support D32 also support NEON, so this should + // not be a problem in practice. + if (has_vfpv3 || has_vfpv3d16) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3; + + // 'vfp' is super ambiguous. Depending on the kernel, it can + // either mean VFPv2 or VFPv3. Make it depend on ARMv7. + if (has_vfp) + { + if (g_cpuFeatures & ANDROID_CPU_ARM_FEATURE_ARMv7) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3; + else + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv2; + } + + // Neon implies VFPv3|D32, and if vfpv4 is detected, NEON_FMA + if (has_neon) + { + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3 | + ANDROID_CPU_ARM_FEATURE_NEON | + ANDROID_CPU_ARM_FEATURE_VFP_D32; + + if (has_vfpv4) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON_FMA; + } + + // VFPv3 implies VFPv2 and ARMv7 + if (g_cpuFeatures & ANDROID_CPU_ARM_FEATURE_VFPv3) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv2 | + ANDROID_CPU_ARM_FEATURE_ARMv7; + + if (has_idiva) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_ARM; + + if (has_idivt) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2; + + if (has_iwmmxt) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_iWMMXt; + } + + /* Extract the list of CPU features from ELF hwcaps2 */ + uint32_t hwcaps2 = 0; + hwcaps2 = get_elf_hwcap_from_getauxval(AT_HWCAP2); + + if (hwcaps2 != 0) + { + int has_aes = (hwcaps2 & HWCAP2_AES); + int has_pmull = (hwcaps2 & HWCAP2_PMULL); + int has_sha1 = (hwcaps2 & HWCAP2_SHA1); + int has_sha2 = (hwcaps2 & HWCAP2_SHA2); + int has_crc32 = (hwcaps2 & HWCAP2_CRC32); + + if (has_aes) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_AES; + + if (has_pmull) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_PMULL; + + if (has_sha1) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA1; + + if (has_sha2) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA2; + + if (has_crc32) + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_CRC32; + } + + /* Extract the cpuid value from various fields */ + // The CPUID value is broken up in several entries in /proc/cpuinfo. + // This table is used to rebuild it from the entries. + static const struct CpuIdEntry + { + const char* field; + char format; + char bit_lshift; + char bit_length; + } cpu_id_entries[] = + { + { "CPU implementer", 'x', 24, 8 }, + { "CPU variant", 'x', 20, 4 }, + { "CPU part", 'x', 4, 12 }, + { "CPU revision", 'd', 0, 4 }, + }; + size_t i; + D("Parsing /proc/cpuinfo to recover CPUID\n"); + + for (i = 0; + i < sizeof(cpu_id_entries) / sizeof(cpu_id_entries[0]); + ++i) + { + const struct CpuIdEntry* entry = &cpu_id_entries[i]; + char* value = extract_cpuinfo_field(cpuinfo, + cpuinfo_len, + entry->field); + + if (value == NULL) + continue; + + D("field=%s value='%s'\n", entry->field, value); + char* value_end = value + strlen(value); + int val = 0; + const char* start = value; + const char* p; + + if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) + { + start += 2; + p = parse_hexadecimal(start, value_end, &val); + } + else if (entry->format == 'x') + p = parse_hexadecimal(value, value_end, &val); + else + p = parse_decimal(value, value_end, &val); + + if (p > (const char*)start) + { + val &= ((1 << entry->bit_length) - 1); + val <<= entry->bit_lshift; + g_cpuIdArm |= (uint32_t) val; + } + + free(value); + } + + // Handle kernel configuration bugs that prevent the correct + // reporting of CPU features. + static const struct CpuFix + { + uint32_t cpuid; + uint64_t or_flags; + } cpu_fixes[] = + { + /* The Nexus 4 (Qualcomm Krait) kernel configuration + * forgets to report IDIV support. */ + { + 0x510006f2, ANDROID_CPU_ARM_FEATURE_IDIV_ARM | + ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 + }, + { + 0x510006f3, ANDROID_CPU_ARM_FEATURE_IDIV_ARM | + ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 + }, + }; + size_t n; + + for (n = 0; n < sizeof(cpu_fixes) / sizeof(cpu_fixes[0]); ++n) + { + const struct CpuFix* entry = &cpu_fixes[n]; + + if (g_cpuIdArm == entry->cpuid) + g_cpuFeatures |= entry->or_flags; + } + + // Special case: The emulator-specific Android 4.2 kernel fails + // to report support for the 32-bit ARM IDIV instruction. + // Technically, this is a feature of the virtual CPU implemented + // by the emulator. Note that it could also support Thumb IDIV + // in the future, and this will have to be slightly updated. + char* hardware = extract_cpuinfo_field(cpuinfo, + cpuinfo_len, + "Hardware"); + + if (hardware) + { + if (!strcmp(hardware, "Goldfish") && + g_cpuIdArm == 0x4100c080 && + (g_cpuFamily & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0) + { + g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_ARM; + } + + free(hardware); + } + } +#endif /* __arm__ */ +#ifdef __aarch64__ + { + /* Extract the list of CPU features from ELF hwcaps */ + uint32_t hwcaps = 0; + hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP); + + if (hwcaps != 0) + { + int has_fp = (hwcaps & HWCAP_FP); + int has_asimd = (hwcaps & HWCAP_ASIMD); + int has_aes = (hwcaps & HWCAP_AES); + int has_pmull = (hwcaps & HWCAP_PMULL); + int has_sha1 = (hwcaps & HWCAP_SHA1); + int has_sha2 = (hwcaps & HWCAP_SHA2); + int has_crc32 = (hwcaps & HWCAP_CRC32); + + if (has_fp == 0) + { + D("ERROR: Floating-point unit missing, but is required by Android on AArch64 CPUs\n"); + } + + if (has_asimd == 0) + { + D("ERROR: ASIMD unit missing, but is required by Android on AArch64 CPUs\n"); + } + + if (has_fp) + g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_FP; + + if (has_asimd) + g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_ASIMD; + + if (has_aes) + g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_AES; + + if (has_pmull) + g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_PMULL; + + if (has_sha1) + g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA1; + + if (has_sha2) + g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA2; + + if (has_crc32) + g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_CRC32; + } + } +#endif /* __aarch64__ */ +#if defined(__i386__) || defined(__x86_64__) + int regs[4]; + /* According to http://en.wikipedia.org/wiki/CPUID */ +#define VENDOR_INTEL_b 0x756e6547 +#define VENDOR_INTEL_c 0x6c65746e +#define VENDOR_INTEL_d 0x49656e69 + x86_cpuid(0, regs); + int vendorIsIntel = (regs[1] == VENDOR_INTEL_b && + regs[2] == VENDOR_INTEL_c && + regs[3] == VENDOR_INTEL_d); + x86_cpuid(1, regs); + + if ((regs[2] & (1 << 9)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSSE3; + } + + if ((regs[2] & (1 << 23)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_POPCNT; + } + + if ((regs[2] & (1 << 19)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_1; + } + + if ((regs[2] & (1 << 20)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_2; + } + + if (vendorIsIntel && (regs[2] & (1 << 22)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_MOVBE; + } + + if ((regs[2] & (1 << 25)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AES_NI; + } + + if ((regs[2] & (1 << 28)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX; + } + + if ((regs[2] & (1 << 30)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_RDRAND; + } + + x86_cpuid(7, regs); + + if ((regs[1] & (1 << 5)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX2; + } + + if ((regs[1] & (1 << 29)) != 0) + { + g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SHA_NI; + } + +#endif +#if defined( __mips__) + { + /* MIPS and MIPS64 */ + /* Extract the list of CPU features from ELF hwcaps */ + uint32_t hwcaps = 0; + hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP); + + if (hwcaps != 0) + { + int has_r6 = (hwcaps & HWCAP_MIPS_R6); + int has_msa = (hwcaps & HWCAP_MIPS_MSA); + + if (has_r6) + g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_R6; + + if (has_msa) + g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_MSA; + } + } +#endif /* __mips__ */ + free(cpuinfo); +} + + +AndroidCpuFamily +android_getCpuFamily(void) +{ + pthread_once(&g_once, android_cpuInit); + return g_cpuFamily; +} + + +uint64_t +android_getCpuFeatures(void) +{ + pthread_once(&g_once, android_cpuInit); + return g_cpuFeatures; +} + + +int +android_getCpuCount(void) +{ + pthread_once(&g_once, android_cpuInit); + return g_cpuCount; +} + +static void +android_cpuInitDummy(void) +{ + g_inited = 1; +} + +int +android_setCpu(int cpu_count, uint64_t cpu_features) +{ + /* Fail if the library was already initialized. */ + if (g_inited) + return 0; + + android_cpuInitFamily(); + g_cpuCount = (cpu_count <= 0 ? 1 : cpu_count); + g_cpuFeatures = cpu_features; + pthread_once(&g_once, android_cpuInitDummy); + return 1; +} + +#ifdef __arm__ +uint32_t +android_getCpuIdArm(void) +{ + pthread_once(&g_once, android_cpuInit); + return g_cpuIdArm; +} + +int +android_setCpuArm(int cpu_count, uint64_t cpu_features, uint32_t cpu_id) +{ + if (!android_setCpu(cpu_count, cpu_features)) + return 0; + + g_cpuIdArm = cpu_id; + return 1; +} +#endif /* __arm__ */ + +/* + * Technical note: Making sense of ARM's FPU architecture versions. + * + * FPA was ARM's first attempt at an FPU architecture. There is no Android + * device that actually uses it since this technology was already obsolete + * when the project started. If you see references to FPA instructions + * somewhere, you can be sure that this doesn't apply to Android at all. + * + * FPA was followed by "VFP", soon renamed "VFPv1" due to the emergence of + * new versions / additions to it. ARM considers this obsolete right now, + * and no known Android device implements it either. + * + * VFPv2 added a few instructions to VFPv1, and is an *optional* extension + * supported by some ARMv5TE, ARMv6 and ARMv6T2 CPUs. Note that a device + * supporting the 'armeabi' ABI doesn't necessarily support these. + * + * VFPv3-D16 adds a few instructions on top of VFPv2 and is typically used + * on ARMv7-A CPUs which implement a FPU. Note that it is also mandated + * by the Android 'armeabi-v7a' ABI. The -D16 suffix in its name means + * that it provides 16 double-precision FPU registers (d0-d15) and 32 + * single-precision ones (s0-s31) which happen to be mapped to the same + * register banks. + * + * VFPv3-D32 is the name of an extension to VFPv3-D16 that provides 16 + * additional double precision registers (d16-d31). Note that there are + * still only 32 single precision registers. + * + * VFPv3xD is a *subset* of VFPv3-D16 that only provides single-precision + * registers. It is only used on ARMv7-M (i.e. on micro-controllers) which + * are not supported by Android. Note that it is not compatible with VFPv2. + * + * NOTE: The term 'VFPv3' usually designate either VFPv3-D16 or VFPv3-D32 + * depending on context. For example GCC uses it for VFPv3-D32, but + * the Linux kernel code uses it for VFPv3-D16 (especially in + * /proc/cpuinfo). Always try to use the full designation when + * possible. + * + * NEON, a.k.a. "ARM Advanced SIMD" is an extension that provides + * instructions to perform parallel computations on vectors of 8, 16, + * 32, 64 and 128 bit quantities. NEON requires VFPv32-D32 since all + * NEON registers are also mapped to the same register banks. + * + * VFPv4-D16, adds a few instructions on top of VFPv3-D16 in order to + * perform fused multiply-accumulate on VFP registers, as well as + * half-precision (16-bit) conversion operations. + * + * VFPv4-D32 is VFPv4-D16 with 32, instead of 16, FPU double precision + * registers. + * + * VPFv4-NEON is VFPv4-D32 with NEON instructions. It also adds fused + * multiply-accumulate instructions that work on the NEON registers. + * + * NOTE: Similarly, "VFPv4" might either reference VFPv4-D16 or VFPv4-D32 + * depending on context. + * + * The following information was determined by scanning the binutils-2.22 + * sources: + * + * Basic VFP instruction subsets: + * + * #define FPU_VFP_EXT_V1xD 0x08000000 // Base VFP instruction set. + * #define FPU_VFP_EXT_V1 0x04000000 // Double-precision insns. + * #define FPU_VFP_EXT_V2 0x02000000 // ARM10E VFPr1. + * #define FPU_VFP_EXT_V3xD 0x01000000 // VFPv3 single-precision. + * #define FPU_VFP_EXT_V3 0x00800000 // VFPv3 double-precision. + * #define FPU_NEON_EXT_V1 0x00400000 // Neon (SIMD) insns. + * #define FPU_VFP_EXT_D32 0x00200000 // Registers D16-D31. + * #define FPU_VFP_EXT_FP16 0x00100000 // Half-precision extensions. + * #define FPU_NEON_EXT_FMA 0x00080000 // Neon fused multiply-add + * #define FPU_VFP_EXT_FMA 0x00040000 // VFP fused multiply-add + * + * FPU types (excluding NEON) + * + * FPU_VFP_V1xD (EXT_V1xD) + * | + * +--------------------------+ + * | | + * FPU_VFP_V1 (+EXT_V1) FPU_VFP_V3xD (+EXT_V2+EXT_V3xD) + * | | + * | | + * FPU_VFP_V2 (+EXT_V2) FPU_VFP_V4_SP_D16 (+EXT_FP16+EXT_FMA) + * | + * FPU_VFP_V3D16 (+EXT_Vx3D+EXT_V3) + * | + * +--------------------------+ + * | | + * FPU_VFP_V3 (+EXT_D32) FPU_VFP_V4D16 (+EXT_FP16+EXT_FMA) + * | | + * | FPU_VFP_V4 (+EXT_D32) + * | + * FPU_VFP_HARD (+EXT_FMA+NEON_EXT_FMA) + * + * VFP architectures: + * + * ARCH_VFP_V1xD (EXT_V1xD) + * | + * +------------------+ + * | | + * | ARCH_VFP_V3xD (+EXT_V2+EXT_V3xD) + * | | + * | ARCH_VFP_V3xD_FP16 (+EXT_FP16) + * | | + * | ARCH_VFP_V4_SP_D16 (+EXT_FMA) + * | + * ARCH_VFP_V1 (+EXT_V1) + * | + * ARCH_VFP_V2 (+EXT_V2) + * | + * ARCH_VFP_V3D16 (+EXT_V3xD+EXT_V3) + * | + * +-------------------+ + * | | + * | ARCH_VFP_V3D16_FP16 (+EXT_FP16) + * | + * +-------------------+ + * | | + * | ARCH_VFP_V4_D16 (+EXT_FP16+EXT_FMA) + * | | + * | ARCH_VFP_V4 (+EXT_D32) + * | | + * | ARCH_NEON_VFP_V4 (+EXT_NEON+EXT_NEON_FMA) + * | + * ARCH_VFP_V3 (+EXT_D32) + * | + * +-------------------+ + * | | + * | ARCH_VFP_V3_FP16 (+EXT_FP16) + * | + * ARCH_VFP_V3_PLUS_NEON_V1 (+EXT_NEON) + * | + * ARCH_NEON_FP16 (+EXT_FP16) + * + * -fpu= values and their correspondance with FPU architectures above: + * + * {"vfp", FPU_ARCH_VFP_V2}, + * {"vfp9", FPU_ARCH_VFP_V2}, + * {"vfp3", FPU_ARCH_VFP_V3}, // For backwards compatbility. + * {"vfp10", FPU_ARCH_VFP_V2}, + * {"vfp10-r0", FPU_ARCH_VFP_V1}, + * {"vfpxd", FPU_ARCH_VFP_V1xD}, + * {"vfpv2", FPU_ARCH_VFP_V2}, + * {"vfpv3", FPU_ARCH_VFP_V3}, + * {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16}, + * {"vfpv3-d16", FPU_ARCH_VFP_V3D16}, + * {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16}, + * {"vfpv3xd", FPU_ARCH_VFP_V3xD}, + * {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16}, + * {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1}, + * {"neon-fp16", FPU_ARCH_NEON_FP16}, + * {"vfpv4", FPU_ARCH_VFP_V4}, + * {"vfpv4-d16", FPU_ARCH_VFP_V4D16}, + * {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16}, + * {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4}, + * + * + * Simplified diagram that only includes FPUs supported by Android: + * Only ARCH_VFP_V3D16 is actually mandated by the armeabi-v7a ABI, + * all others are optional and must be probed at runtime. + * + * ARCH_VFP_V3D16 (EXT_V1xD+EXT_V1+EXT_V2+EXT_V3xD+EXT_V3) + * | + * +-------------------+ + * | | + * | ARCH_VFP_V3D16_FP16 (+EXT_FP16) + * | + * +-------------------+ + * | | + * | ARCH_VFP_V4_D16 (+EXT_FP16+EXT_FMA) + * | | + * | ARCH_VFP_V4 (+EXT_D32) + * | | + * | ARCH_NEON_VFP_V4 (+EXT_NEON+EXT_NEON_FMA) + * | + * ARCH_VFP_V3 (+EXT_D32) + * | + * +-------------------+ + * | | + * | ARCH_VFP_V3_FP16 (+EXT_FP16) + * | + * ARCH_VFP_V3_PLUS_NEON_V1 (+EXT_NEON) + * | + * ARCH_NEON_FP16 (+EXT_FP16) + * + */ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.h freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.h --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.h 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/cpu-features.h 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * 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. + * + * 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 WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef CPU_FEATURES_H +#define CPU_FEATURES_H + +#include +#include + +__BEGIN_DECLS + +/* A list of valid values returned by android_getCpuFamily(). + * They describe the CPU Architecture of the current process. + */ +typedef enum +{ + ANDROID_CPU_FAMILY_UNKNOWN = 0, + ANDROID_CPU_FAMILY_ARM, + ANDROID_CPU_FAMILY_X86, + ANDROID_CPU_FAMILY_MIPS, + ANDROID_CPU_FAMILY_ARM64, + ANDROID_CPU_FAMILY_X86_64, + ANDROID_CPU_FAMILY_MIPS64, + + ANDROID_CPU_FAMILY_MAX /* do not remove */ + +} AndroidCpuFamily; + +/* Return the CPU family of the current process. + * + * Note that this matches the bitness of the current process. I.e. when + * running a 32-bit binary on a 64-bit capable CPU, this will return the + * 32-bit CPU family value. + */ +extern AndroidCpuFamily android_getCpuFamily(void); + +/* Return a bitmap describing a set of optional CPU features that are + * supported by the current device's CPU. The exact bit-flags returned + * depend on the value returned by android_getCpuFamily(). See the + * documentation for the ANDROID_CPU_*_FEATURE_* flags below for details. + */ +extern uint64_t android_getCpuFeatures(void); + +/* The list of feature flags for ANDROID_CPU_FAMILY_ARM that can be + * recognized by the library (see note below for 64-bit ARM). Value details + * are: + * + * VFPv2: + * CPU supports the VFPv2 instruction set. Many, but not all, ARMv6 CPUs + * support these instructions. VFPv2 is a subset of VFPv3 so this will + * be set whenever VFPv3 is set too. + * + * ARMv7: + * CPU supports the ARMv7-A basic instruction set. + * This feature is mandated by the 'armeabi-v7a' ABI. + * + * VFPv3: + * CPU supports the VFPv3-D16 instruction set, providing hardware FPU + * support for single and double precision floating point registers. + * Note that only 16 FPU registers are available by default, unless + * the D32 bit is set too. This feature is also mandated by the + * 'armeabi-v7a' ABI. + * + * VFP_D32: + * CPU VFP optional extension that provides 32 FPU registers, + * instead of 16. Note that ARM mandates this feature is the 'NEON' + * feature is implemented by the CPU. + * + * NEON: + * CPU FPU supports "ARM Advanced SIMD" instructions, also known as + * NEON. Note that this mandates the VFP_D32 feature as well, per the + * ARM Architecture specification. + * + * VFP_FP16: + * Half-width floating precision VFP extension. If set, the CPU + * supports instructions to perform floating-point operations on + * 16-bit registers. This is part of the VFPv4 specification, but + * not mandated by any Android ABI. + * + * VFP_FMA: + * Fused multiply-accumulate VFP instructions extension. Also part of + * the VFPv4 specification, but not mandated by any Android ABI. + * + * NEON_FMA: + * Fused multiply-accumulate NEON instructions extension. Optional + * extension from the VFPv4 specification, but not mandated by any + * Android ABI. + * + * IDIV_ARM: + * Integer division available in ARM mode. Only available + * on recent CPUs (e.g. Cortex-A15). + * + * IDIV_THUMB2: + * Integer division available in Thumb-2 mode. Only available + * on recent CPUs (e.g. Cortex-A15). + * + * iWMMXt: + * Optional extension that adds MMX registers and operations to an + * ARM CPU. This is only available on a few XScale-based CPU designs + * sold by Marvell. Pretty rare in practice. + * + * AES: + * CPU supports AES instructions. These instructions are only + * available for 32-bit applications running on ARMv8 CPU. + * + * CRC32: + * CPU supports CRC32 instructions. These instructions are only + * available for 32-bit applications running on ARMv8 CPU. + * + * SHA2: + * CPU supports SHA2 instructions. These instructions are only + * available for 32-bit applications running on ARMv8 CPU. + * + * SHA1: + * CPU supports SHA1 instructions. These instructions are only + * available for 32-bit applications running on ARMv8 CPU. + * + * PMULL: + * CPU supports 64-bit PMULL and PMULL2 instructions. These + * instructions are only available for 32-bit applications + * running on ARMv8 CPU. + * + * If you want to tell the compiler to generate code that targets one of + * the feature set above, you should probably use one of the following + * flags (for more details, see technical note at the end of this file): + * + * -mfpu=vfp + * -mfpu=vfpv2 + * These are equivalent and tell GCC to use VFPv2 instructions for + * floating-point operations. Use this if you want your code to + * run on *some* ARMv6 devices, and any ARMv7-A device supported + * by Android. + * + * Generated code requires VFPv2 feature. + * + * -mfpu=vfpv3-d16 + * Tell GCC to use VFPv3 instructions (using only 16 FPU registers). + * This should be generic code that runs on any CPU that supports the + * 'armeabi-v7a' Android ABI. Note that no ARMv6 CPU supports this. + * + * Generated code requires VFPv3 feature. + * + * -mfpu=vfpv3 + * Tell GCC to use VFPv3 instructions with 32 FPU registers. + * Generated code requires VFPv3|VFP_D32 features. + * + * -mfpu=neon + * Tell GCC to use VFPv3 instructions with 32 FPU registers, and + * also support NEON intrinsics (see ). + * Generated code requires VFPv3|VFP_D32|NEON features. + * + * -mfpu=vfpv4-d16 + * Generated code requires VFPv3|VFP_FP16|VFP_FMA features. + * + * -mfpu=vfpv4 + * Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32 features. + * + * -mfpu=neon-vfpv4 + * Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32|NEON|NEON_FMA + * features. + * + * -mcpu=cortex-a7 + * -mcpu=cortex-a15 + * Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32| + * NEON|NEON_FMA|IDIV_ARM|IDIV_THUMB2 + * This flag implies -mfpu=neon-vfpv4. + * + * -mcpu=iwmmxt + * Allows the use of iWMMXt instrinsics with GCC. + * + * IMPORTANT NOTE: These flags should only be tested when + * android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM, i.e. this is a + * 32-bit process. + * + * When running a 64-bit ARM process on an ARMv8 CPU, + * android_getCpuFeatures() will return a different set of bitflags + */ +enum +{ + ANDROID_CPU_ARM_FEATURE_ARMv7 = (1 << 0), + ANDROID_CPU_ARM_FEATURE_VFPv3 = (1 << 1), + ANDROID_CPU_ARM_FEATURE_NEON = (1 << 2), + ANDROID_CPU_ARM_FEATURE_LDREX_STREX = (1 << 3), + ANDROID_CPU_ARM_FEATURE_VFPv2 = (1 << 4), + ANDROID_CPU_ARM_FEATURE_VFP_D32 = (1 << 5), + ANDROID_CPU_ARM_FEATURE_VFP_FP16 = (1 << 6), + ANDROID_CPU_ARM_FEATURE_VFP_FMA = (1 << 7), + ANDROID_CPU_ARM_FEATURE_NEON_FMA = (1 << 8), + ANDROID_CPU_ARM_FEATURE_IDIV_ARM = (1 << 9), + ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 = (1 << 10), + ANDROID_CPU_ARM_FEATURE_iWMMXt = (1 << 11), + ANDROID_CPU_ARM_FEATURE_AES = (1 << 12), + ANDROID_CPU_ARM_FEATURE_PMULL = (1 << 13), + ANDROID_CPU_ARM_FEATURE_SHA1 = (1 << 14), + ANDROID_CPU_ARM_FEATURE_SHA2 = (1 << 15), + ANDROID_CPU_ARM_FEATURE_CRC32 = (1 << 16), +}; + +/* The bit flags corresponding to the output of android_getCpuFeatures() + * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM64. Value details + * are: + * + * FP: + * CPU has Floating-point unit. + * + * ASIMD: + * CPU has Advanced SIMD unit. + * + * AES: + * CPU supports AES instructions. + * + * CRC32: + * CPU supports CRC32 instructions. + * + * SHA2: + * CPU supports SHA2 instructions. + * + * SHA1: + * CPU supports SHA1 instructions. + * + * PMULL: + * CPU supports 64-bit PMULL and PMULL2 instructions. + */ +enum +{ + ANDROID_CPU_ARM64_FEATURE_FP = (1 << 0), + ANDROID_CPU_ARM64_FEATURE_ASIMD = (1 << 1), + ANDROID_CPU_ARM64_FEATURE_AES = (1 << 2), + ANDROID_CPU_ARM64_FEATURE_PMULL = (1 << 3), + ANDROID_CPU_ARM64_FEATURE_SHA1 = (1 << 4), + ANDROID_CPU_ARM64_FEATURE_SHA2 = (1 << 5), + ANDROID_CPU_ARM64_FEATURE_CRC32 = (1 << 6), +}; + +/* The bit flags corresponding to the output of android_getCpuFeatures() + * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_X86 or + * ANDROID_CPU_FAMILY_X86_64. + */ +enum +{ + ANDROID_CPU_X86_FEATURE_SSSE3 = (1 << 0), + ANDROID_CPU_X86_FEATURE_POPCNT = (1 << 1), + ANDROID_CPU_X86_FEATURE_MOVBE = (1 << 2), + ANDROID_CPU_X86_FEATURE_SSE4_1 = (1 << 3), + ANDROID_CPU_X86_FEATURE_SSE4_2 = (1 << 4), + ANDROID_CPU_X86_FEATURE_AES_NI = (1 << 5), + ANDROID_CPU_X86_FEATURE_AVX = (1 << 6), + ANDROID_CPU_X86_FEATURE_RDRAND = (1 << 7), + ANDROID_CPU_X86_FEATURE_AVX2 = (1 << 8), + ANDROID_CPU_X86_FEATURE_SHA_NI = (1 << 9), +}; + +/* The bit flags corresponding to the output of android_getCpuFeatures() + * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_MIPS + * or ANDROID_CPU_FAMILY_MIPS64. Values are: + * + * R6: + * CPU executes MIPS Release 6 instructions natively, and + * supports obsoleted R1..R5 instructions only via kernel traps. + * + * MSA: + * CPU supports Mips SIMD Architecture instructions. + */ +enum +{ + ANDROID_CPU_MIPS_FEATURE_R6 = (1 << 0), + ANDROID_CPU_MIPS_FEATURE_MSA = (1 << 1), +}; + + +/* Return the number of CPU cores detected on this device. */ +extern int android_getCpuCount(void); + +/* The following is used to force the CPU count and features + * mask in sandboxed processes. Under 4.1 and higher, these processes + * cannot access /proc, which is the only way to get information from + * the kernel about the current hardware (at least on ARM). + * + * It _must_ be called only once, and before any android_getCpuXXX + * function, any other case will fail. + * + * This function return 1 on success, and 0 on failure. + */ +extern int android_setCpu(int cpu_count, + uint64_t cpu_features); + +#ifdef __arm__ +/* Retrieve the ARM 32-bit CPUID value from the kernel. + * Note that this cannot work on sandboxed processes under 4.1 and + * higher, unless you called android_setCpuArm() before. + */ +extern uint32_t android_getCpuIdArm(void); + +/* An ARM-specific variant of android_setCpu() that also allows you + * to set the ARM CPUID field. + */ +extern int android_setCpuArm(int cpu_count, + uint64_t cpu_features, + uint32_t cpu_id); +#endif + +__END_DECLS + +#endif /* CPU_FEATURES_H */ diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/NOTICE freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/NOTICE --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/NOTICE 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/NOTICE 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,13 @@ +Copyright (C) 2016 The Android Open Source Project + +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. diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/README freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/README --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/cpufeatures/README 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/cpufeatures/README 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,4 @@ +Android CPUFeatures Library + +https://developer.android.com/ndk/guides/cpu-features.html +https://android.googlesource.com/platform/ndk/+/master/sources/android/cpufeatures diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/sysinfo.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/sysinfo.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/sysinfo.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/sysinfo.c 2017-03-03 08:39:24.000000000 +0000 @@ -25,7 +25,11 @@ #include #include -#if defined(__linux__) && defined(__GNUC__) +#if defined(ANDROID) +#include "cpufeatures/cpu-features.h" +#endif + +#if defined(__linux__) #include #include #include @@ -72,19 +76,49 @@ #include #endif -static DWORD GetProcessorArchitecture() +static DWORD GetProcessorArchitecture(void) { DWORD cpuArch = PROCESSOR_ARCHITECTURE_UNKNOWN; -#if defined(_M_AMD64) - cpuArch = PROCESSOR_ARCHITECTURE_AMD64; -#elif defined(_M_IX86) - cpuArch = PROCESSOR_ARCHITECTURE_INTEL; +#if defined(ANDROID) + AndroidCpuFamily family = android_getCpuFamily(); + + switch (family) + { + case ANDROID_CPU_FAMILY_ARM: + return PROCESSOR_ARCHITECTURE_ARM; + + case ANDROID_CPU_FAMILY_X86: + return PROCESSOR_ARCHITECTURE_INTEL; + + case ANDROID_CPU_FAMILY_MIPS: + return PROCESSOR_ARCHITECTURE_MIPS; + + case ANDROID_CPU_FAMILY_ARM64: + return PROCESSOR_ARCHITECTURE_ARM64; + + case ANDROID_CPU_FAMILY_X86_64: + return PROCESSOR_ARCHITECTURE_AMD64; + + case ANDROID_CPU_FAMILY_MIPS64: + return PROCESSOR_ARCHITECTURE_MIPS64; + + default: + return PROCESSOR_ARCHITECTURE_UNKNOWN; + } + #elif defined(_M_ARM) cpuArch = PROCESSOR_ARCHITECTURE_ARM; -#elif defined(_M_IA64) - cpuArch = PROCESSOR_ARCHITECTURE_IA64; +#elif defined(_M_IX86) + cpuArch = PROCESSOR_ARCHITECTURE_INTEL; +#elif defined(_M_MIPS64) + /* Needs to be before __mips__ since the compiler defines both */ + cpuArch = PROCESSOR_ARCHITECTURE_MIPS64; #elif defined(_M_MIPS) cpuArch = PROCESSOR_ARCHITECTURE_MIPS; +#elif defined(_M_ARM64) + cpuArch = PROCESSOR_ARCHITECTURE_ARM64; +#elif defined(_M_AMD64) + cpuArch = PROCESSOR_ARCHITECTURE_AMD64; #elif defined(_M_PPC) cpuArch = PROCESSOR_ARCHITECTURE_PPC; #elif defined(_M_ALPHA) @@ -93,11 +127,13 @@ return cpuArch; } -static DWORD GetNumberOfProcessors() +static DWORD GetNumberOfProcessors(void) { DWORD numCPUs = 1; +#if defined(ANDROID) + return android_getCpuCount(); /* TODO: iOS */ -#if defined(__linux__) || defined(__sun) || defined(_AIX) +#elif defined(__linux__) || defined(__sun) || defined(_AIX) numCPUs = (DWORD) sysconf(_SC_NPROCESSORS_ONLN); #elif defined(__MACOSX__) || \ defined(__FreeBSD__) || defined(__NetBSD__) || \ @@ -130,19 +166,21 @@ return numCPUs; } -static DWORD GetSystemPageSize() +static DWORD GetSystemPageSize(void) { DWORD dwPageSize = 0; long sc_page_size = -1; - #if defined(_SC_PAGESIZE) + if (sc_page_size < 0) sc_page_size = sysconf(_SC_PAGESIZE); -#endif +#endif #if defined(_SC_PAGE_SIZE) + if (sc_page_size < 0) sc_page_size = sysconf(_SC_PAGE_SIZE); + #endif if (sc_page_size > 0) @@ -199,6 +237,7 @@ BOOL SetSystemTime(CONST SYSTEMTIME* lpSystemTime) { + /* TODO: Implement */ return FALSE; } @@ -227,6 +266,7 @@ BOOL SetLocalTime(CONST SYSTEMTIME* lpSystemTime) { + /* TODO: Implement */ return FALSE; } @@ -241,8 +281,10 @@ lpSystemTimeAsFileTime->dwHighDateTime = time64.HighPart; } -BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement, PBOOL lpTimeAdjustmentDisabled) +BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement, + PBOOL lpTimeAdjustmentDisabled) { + /* TODO: Implement */ return FALSE; } @@ -283,9 +325,10 @@ BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation) { #ifdef _UWP + /* Windows 10 Version Info */ if ((lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA)) || - (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA))) + (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA))) { lpVersionInformation->dwMajorVersion = 10; lpVersionInformation->dwMinorVersion = 0; @@ -305,10 +348,12 @@ return TRUE; } + #else + /* Windows 7 SP1 Version Info */ if ((lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA)) || - (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA))) + (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA))) { lpVersionInformation->dwMajorVersion = 6; lpVersionInformation->dwMinorVersion = 1; @@ -328,8 +373,8 @@ return TRUE; } -#endif +#endif return FALSE; } @@ -349,6 +394,12 @@ int length; char hostname[256]; + if (!lpnSize) + { + SetLastError(ERROR_BAD_ARGUMENTS); + return FALSE; + } + if (gethostname(hostname, sizeof(hostname)) == -1) return FALSE; @@ -356,22 +407,18 @@ dot = strchr(hostname, '.'); if (dot) - length = (int) (dot - hostname); + length = (int)(dot - hostname); - if (*lpnSize <= (DWORD) length) + if ((*lpnSize <= (DWORD) length) || !lpBuffer) { SetLastError(ERROR_BUFFER_OVERFLOW); *lpnSize = length + 1; return FALSE; } - if (!lpBuffer) - return FALSE; - CopyMemory(lpBuffer, hostname, length); lpBuffer[length] = '\0'; *lpnSize = length; - return TRUE; } @@ -380,8 +427,24 @@ int length; char hostname[256]; + if (!lpnSize) + { + SetLastError(ERROR_BAD_ARGUMENTS); + return FALSE; + } + if ((NameType == ComputerNameNetBIOS) || (NameType == ComputerNamePhysicalNetBIOS)) - return GetComputerNameA(lpBuffer, lpnSize); + { + BOOL rc = GetComputerNameA(lpBuffer, lpnSize); + + if (!rc) + { + if (GetLastError() == ERROR_BUFFER_OVERFLOW) + SetLastError(ERROR_MORE_DATA); + } + + return rc; + } if (gethostname(hostname, sizeof(hostname)) == -1) return FALSE; @@ -390,37 +453,57 @@ switch (NameType) { - case ComputerNameDnsHostname: - case ComputerNameDnsDomain: - case ComputerNameDnsFullyQualified: - case ComputerNamePhysicalDnsHostname: - case ComputerNamePhysicalDnsDomain: - case ComputerNamePhysicalDnsFullyQualified: - if (*lpnSize <= (DWORD) length) + case ComputerNameDnsHostname: + case ComputerNameDnsDomain: + case ComputerNameDnsFullyQualified: + case ComputerNamePhysicalDnsHostname: + case ComputerNamePhysicalDnsDomain: + case ComputerNamePhysicalDnsFullyQualified: + if ((*lpnSize <= (DWORD) length) || !lpBuffer) { *lpnSize = length + 1; SetLastError(ERROR_MORE_DATA); return FALSE; } - if (!lpBuffer) - return FALSE; - CopyMemory(lpBuffer, hostname, length); lpBuffer[length] = '\0'; - break; + *lpnSize = length; + break; - default: - return FALSE; + default: + return FALSE; } return TRUE; } -BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD nSize) +BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD lpnSize) { - WLog_ERR(TAG, "GetComputerNameExW unimplemented"); - return FALSE; + BOOL rc; + LPSTR lpABuffer = NULL; + + if (!lpnSize) + { + SetLastError(ERROR_BAD_ARGUMENTS); + return FALSE; + } + + if (*lpnSize > 0) + { + lpABuffer = calloc(*lpnSize, sizeof(CHAR)); + + if (!lpABuffer) + return FALSE; + } + + rc = GetComputerNameExA(NameType, lpABuffer, lpnSize); + + if (rc && (*lpnSize > 0)) + ConvertToUnicode(CP_UTF8, 0, lpABuffer, *lpnSize, &lpBuffer, *lpnSize); + + free(lpABuffer); + return rc; } #endif @@ -493,31 +576,31 @@ #define E_BITS_AVX (E_BIT_XMM|E_BIT_YMM) static void cpuid( - unsigned info, - unsigned* eax, - unsigned* ebx, - unsigned* ecx, - unsigned* edx) + unsigned info, + unsigned* eax, + unsigned* ebx, + unsigned* ecx, + unsigned* edx) { #ifdef __GNUC__ *eax = *ebx = *ecx = *edx = 0; __asm volatile ( - /* The EBX (or RBX register on x86_64) is used for the PIC base address + /* The EBX (or RBX register on x86_64) is used for the PIC base address * and must not be corrupted by our inline assembly. */ #ifdef _M_IX86 - "mov %%ebx, %%esi;" - "cpuid;" - "xchg %%ebx, %%esi;" + "mov %%ebx, %%esi;" + "cpuid;" + "xchg %%ebx, %%esi;" #else - "mov %%rbx, %%rsi;" - "cpuid;" - "xchg %%rbx, %%rsi;" -#endif - : "=a"(*eax), "=S"(*ebx), "=c"(*ecx), "=d"(*edx) - : "0"(info) - ); + "mov %%rbx, %%rsi;" + "cpuid;" + "xchg %%rbx, %%rsi;" +#endif + : "=a"(*eax), "=S"(*ebx), "=c"(*ecx), "=d"(*edx) + : "0"(info) + ); #elif defined(_MSC_VER) int a[4]; __cpuid(a, info); @@ -595,86 +678,98 @@ BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature) { BOOL ret = FALSE; -#ifdef _M_ARM +#if defined(ANDROID) + const uint64_t features = android_getCpuFeatures(); + + switch (ProcessorFeature) + { + case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: + case PF_ARM_NEON: + return features & ANDROID_CPU_ARM_FEATURE_NEON; + + default: + return FALSE; + } + +#elif defined(_M_ARM) #ifdef __linux__ - unsigned caps; - caps = GetARMCPUCaps(); + const unsigned caps = GetARMCPUCaps(); switch (ProcessorFeature) { - case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: - case PF_ARM_NEON: - if (caps & HWCAP_NEON) + case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: + case PF_ARM_NEON: + if (caps & HWCAP_NEON) ret = TRUE; - break; + break; - case PF_ARM_THUMB: - if (caps & HWCAP_THUMB) + case PF_ARM_THUMB: + if (caps & HWCAP_THUMB) ret = TRUE; - case PF_ARM_VFP_32_REGISTERS_AVAILABLE: - if (caps & HWCAP_VFPD32) + case PF_ARM_VFP_32_REGISTERS_AVAILABLE: + if (caps & HWCAP_VFPD32) ret = TRUE; - case PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE: - if ((caps & HWCAP_IDIVA) || (caps & HWCAP_IDIVT)) + case PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE: + if ((caps & HWCAP_IDIVA) || (caps & HWCAP_IDIVT)) ret = TRUE; - case PF_ARM_VFP3: - if (caps & HWCAP_VFPv3) + case PF_ARM_VFP3: + if (caps & HWCAP_VFPv3) ret = TRUE; - break; + break; - case PF_ARM_JAZELLE: - if (caps & HWCAP_JAVA) + case PF_ARM_JAZELLE: + if (caps & HWCAP_JAVA) ret = TRUE; - break; + break; - case PF_ARM_DSP: - if (caps & HWCAP_EDSP) + case PF_ARM_DSP: + if (caps & HWCAP_EDSP) ret = TRUE; - break; + break; - case PF_ARM_MPU: - if (caps & HWCAP_EDSP) + case PF_ARM_MPU: + if (caps & HWCAP_EDSP) ret = TRUE; - break; + break; - case PF_ARM_THUMB2: - if ((caps & HWCAP_IDIVT) || (caps & HWCAP_VFPv4)) + case PF_ARM_THUMB2: + if ((caps & HWCAP_IDIVT) || (caps & HWCAP_VFPv4)) ret = TRUE; - break; + break; - case PF_ARM_T2EE: - if (caps & HWCAP_THUMBEE) + case PF_ARM_T2EE: + if (caps & HWCAP_THUMBEE) ret = TRUE; - break; + break; - case PF_ARM_INTEL_WMMX: - if (caps & HWCAP_IWMMXT) + case PF_ARM_INTEL_WMMX: + if (caps & HWCAP_IWMMXT) ret = TRUE; - break; + break; - default: - break; + default: + break; } #elif defined(__APPLE__) // __linux__ switch (ProcessorFeature) { - case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: - case PF_ARM_NEON: - ret = TRUE; - break; + case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: + case PF_ARM_NEON: + ret = TRUE; + break; } #endif // __linux__ @@ -685,38 +780,38 @@ switch (ProcessorFeature) { - case PF_MMX_INSTRUCTIONS_AVAILABLE: - if (d & D_BIT_MMX) + case PF_MMX_INSTRUCTIONS_AVAILABLE: + if (d & D_BIT_MMX) ret = TRUE; - break; + break; - case PF_XMMI_INSTRUCTIONS_AVAILABLE: - if (d & D_BIT_SSE) + case PF_XMMI_INSTRUCTIONS_AVAILABLE: + if (d & D_BIT_SSE) ret = TRUE; - break; + break; - case PF_XMMI64_INSTRUCTIONS_AVAILABLE: - if (d & D_BIT_SSE2) + case PF_XMMI64_INSTRUCTIONS_AVAILABLE: + if (d & D_BIT_SSE2) ret = TRUE; - break; + break; - case PF_3DNOW_INSTRUCTIONS_AVAILABLE: - if (d & D_BIT_3DN) + case PF_3DNOW_INSTRUCTIONS_AVAILABLE: + if (d & D_BIT_3DN) ret = TRUE; - break; + break; - case PF_SSE3_INSTRUCTIONS_AVAILABLE: - if (c & C_BIT_SSE3) + case PF_SSE3_INSTRUCTIONS_AVAILABLE: + if (c & C_BIT_SSE3) ret = TRUE; - break; + break; - default: - break; + default: + break; } #endif // __GNUC__ @@ -731,11 +826,9 @@ #ifdef _WIN32 LARGE_INTEGER freq; LARGE_INTEGER current; - QueryPerformanceFrequency(&freq); QueryPerformanceCounter(¤t); - - return (DWORD) (current.QuadPart * 1000LL / freq.QuadPart); + return (DWORD)(current.QuadPart * 1000LL / freq.QuadPart); #else return GetTickCount(); #endif @@ -751,35 +844,35 @@ switch (ProcessorFeature) { - case PF_EX_ARM_VFP1: - if (caps & HWCAP_VFP) + case PF_EX_ARM_VFP1: + if (caps & HWCAP_VFP) ret = TRUE; - break; + break; - case PF_EX_ARM_VFP3D16: - if (caps & HWCAP_VFPv3D16) + case PF_EX_ARM_VFP3D16: + if (caps & HWCAP_VFPv3D16) ret = TRUE; - break; + break; - case PF_EX_ARM_VFP4: - if (caps & HWCAP_VFPv4) + case PF_EX_ARM_VFP4: + if (caps & HWCAP_VFPv4) ret = TRUE; - break; + break; - case PF_EX_ARM_IDIVA: - if (caps & HWCAP_IDIVA) + case PF_EX_ARM_IDIVA: + if (caps & HWCAP_IDIVA) ret = TRUE; - break; + break; - case PF_EX_ARM_IDIVT: - if (caps & HWCAP_IDIVT) + case PF_EX_ARM_IDIVT: + if (caps & HWCAP_IDIVT) ret = TRUE; - break; + break; } #endif // __linux__ @@ -789,47 +882,48 @@ switch (ProcessorFeature) { - case PF_EX_LZCNT: - { - unsigned a81, b81, c81, d81; + case PF_EX_LZCNT: + { + unsigned a81, b81, c81, d81; cpuid(0x80000001, &a81, &b81, &c81, &d81); + if (c81 & C81_BIT_LZCNT) ret = TRUE; - } - break; + } + break; - case PF_EX_3DNOW_PREFETCH: - if (c & C_BIT_3DNP) + case PF_EX_3DNOW_PREFETCH: + if (c & C_BIT_3DNP) ret = TRUE; - break; + break; - case PF_EX_SSSE3: - if (c & C_BIT_SSSE3) + case PF_EX_SSSE3: + if (c & C_BIT_SSSE3) ret = TRUE; - break; + break; - case PF_EX_SSE41: - if (c & C_BIT_SSE41) + case PF_EX_SSE41: + if (c & C_BIT_SSE41) ret = TRUE; - break; + break; - case PF_EX_SSE42: - if (c & C_BIT_SSE42) + case PF_EX_SSE42: + if (c & C_BIT_SSE42) ret = TRUE; - break; + break; #if defined(__GNUC__) && defined(__AVX__) - case PF_EX_AVX: - case PF_EX_FMA: - case PF_EX_AVX_AES: - case PF_EX_AVX_PCLMULQDQ: - { - /* Check for general AVX support */ - if ((c & C_BITS_AVX) != C_BITS_AVX) + case PF_EX_AVX: + case PF_EX_FMA: + case PF_EX_AVX_AES: + case PF_EX_AVX_PCLMULQDQ: + { + /* Check for general AVX support */ + if ((c & C_BITS_AVX) != C_BITS_AVX) break; int e, f; @@ -840,35 +934,35 @@ { switch (ProcessorFeature) { - case PF_EX_AVX: - ret = TRUE; - break; + case PF_EX_AVX: + ret = TRUE; + break; - case PF_EX_FMA: - if (c & C_BIT_FMA) + case PF_EX_FMA: + if (c & C_BIT_FMA) ret = TRUE; - break; + break; - case PF_EX_AVX_AES: - if (c & C_BIT_AES) + case PF_EX_AVX_AES: + if (c & C_BIT_AES) ret = TRUE; - break; + break; - case PF_EX_AVX_PCLMULQDQ: - if (c & C_BIT_PCLMULQDQ) + case PF_EX_AVX_PCLMULQDQ: + if (c & C_BIT_PCLMULQDQ) ret = TRUE; - break; + break; } } - } - break; + } + break; #endif //__AVX__ - default: - break; + default: + break; } #endif diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/test/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/test/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/test/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/test/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -7,6 +7,7 @@ set(${MODULE_PREFIX}_TESTS TestGetNativeSystemInfo.c TestCPUFeatures.c + TestGetComputerName.c TestSystemTime.c TestLocalTime.c) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/test/TestGetComputerName.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/test/TestGetComputerName.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/sysinfo/test/TestGetComputerName.c 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/sysinfo/test/TestGetComputerName.c 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,344 @@ +#include +#include +#include +#include +#include + + +/* FreeRDP does not seem to export this function */ +#ifndef _WIN32 +BOOL GetComputerNameA(LPSTR lpBuffer, LPDWORD lpnSize); +#endif + +BOOL Test_GetComputerName(void) +{ + /** + * BOOL WINAPI GetComputerName(LPTSTR lpBuffer, LPDWORD lpnSize); + * + * GetComputerName retrieves the NetBIOS name of the local computer. + * + * lpBuffer [out] + * A pointer to a buffer that receives the computer name or the cluster virtual server name. + * The buffer size should be large enough to contain MAX_COMPUTERNAME_LENGTH + 1 characters. + * + * lpnSize [in, out] + * On input, specifies the size of the buffer, in TCHARs. + * On output, the number of TCHARs copied to the destination buffer, not including the terminating null character. + * If the buffer is too small, the function fails and GetLastError returns ERROR_BUFFER_OVERFLOW. + * The lpnSize parameter specifies the size of the buffer required, including the terminating null character + * + */ + + CHAR netbiosName1[MAX_COMPUTERNAME_LENGTH + 1]; + CHAR netbiosName2[MAX_COMPUTERNAME_LENGTH + 1]; + const DWORD netbiosBufferSize = sizeof(netbiosName1) / sizeof(CHAR); + DWORD dwSize; + DWORD dwNameLength; + DWORD dwError; + + memset(netbiosName1, 0xAA, netbiosBufferSize); + memset(netbiosName2, 0xBB, netbiosBufferSize); + + /* test with null buffer and zero size (required if buffer is null) */ + dwSize = 0; + if (GetComputerNameA(NULL, &dwSize) == TRUE) + { + fprintf(stderr, "%s: (1) GetComputerNameA unexpectedly succeeded with null buffer\n", + __FUNCTION__); + return FALSE; + } + if ((dwError = GetLastError()) != ERROR_BUFFER_OVERFLOW) + { + fprintf(stderr, "%s: (2) GetLastError returned 0x%08"PRIX32" (expected ERROR_BUFFER_OVERFLOW)\n", + __FUNCTION__, dwError); + return FALSE; + } + + /* test with valid buffer and zero size */ + dwSize = 0; + if (GetComputerNameA(netbiosName1, &dwSize) == TRUE) + { + fprintf(stderr, "%s: (3) GetComputerNameA unexpectedly succeeded with zero size parameter\n", + __FUNCTION__); + return FALSE; + } + if ((dwError = GetLastError()) != ERROR_BUFFER_OVERFLOW) + { + fprintf(stderr, "%s: (4) GetLastError returned 0x%08"PRIX32" (expected ERROR_BUFFER_OVERFLOW)\n", + __FUNCTION__, dwError); + return FALSE; + } + /* check if returned size is valid: must be the size of the buffer required, including the terminating null character in this case */ + if (dwSize < 2 || dwSize > netbiosBufferSize) + { + fprintf(stderr, "%s: (5) GetComputerNameA returned wrong size %"PRIu32" (expected something in the range from 2 to %"PRIu32")\n", + __FUNCTION__, dwSize, netbiosBufferSize); + return FALSE; + } + dwNameLength = dwSize - 1; + + /* test with returned size */ + if (GetComputerNameA(netbiosName1, &dwSize) == FALSE) + { + fprintf(stderr, "%s: (6) GetComputerNameA failed with error: 0x%08"PRIX32"\n", + __FUNCTION__, GetLastError()); + return FALSE; + } + /* check if returned size is valid */ + if (dwSize != dwNameLength) + { + fprintf(stderr, "%s: (7) GetComputerNameA returned wrong size %"PRIu32" (expected %"PRIu32")\n", + __FUNCTION__, dwSize, dwNameLength); + return FALSE; + } + /* check if string is correctly terminated */ + if (netbiosName1[dwSize] != 0) + { + fprintf(stderr, "%s: (8) string termination error\n", __FUNCTION__); + return FALSE; + } + + /* test with real buffer size */ + dwSize = netbiosBufferSize; + if (GetComputerNameA(netbiosName2, &dwSize) == FALSE) + { + fprintf(stderr, "%s: (9) GetComputerNameA failed with error: 0x%08"PRIX32"\n", + __FUNCTION__, GetLastError()); + return FALSE; + } + /* check if returned size is valid */ + if (dwSize != dwNameLength) + { + fprintf(stderr, "%s: (10) GetComputerNameA returned wrong size %"PRIu32" (expected %"PRIu32")\n", + __FUNCTION__, dwSize, dwNameLength); + return FALSE; + } + /* check if string is correctly terminated */ + if (netbiosName2[dwSize] != 0) + { + fprintf(stderr, "%s: (11) string termination error\n", __FUNCTION__); + return FALSE; + } + + /* compare the results */ + if (strcmp(netbiosName1, netbiosName2)) + { + fprintf(stderr, "%s: (12) string compare mismatch\n", __FUNCTION__); + return FALSE; + } + + /* test with off by one buffer size */ + dwSize = dwNameLength; + if (GetComputerNameA(netbiosName1, &dwSize) == TRUE) + { + fprintf(stderr, "%s: (13) GetComputerNameA unexpectedly succeeded with limited buffer size\n", + __FUNCTION__); + return FALSE; + } + /* check if returned size is valid */ + if (dwSize != dwNameLength + 1) + { + fprintf(stderr, "%s: (14) GetComputerNameA returned wrong size %"PRIu32" (expected %"PRIu32")\n", + __FUNCTION__, dwSize, dwNameLength + 1); + return FALSE; + } + + return TRUE; +} + + +BOOL Test_GetComputerNameEx_Format(COMPUTER_NAME_FORMAT format) +{ + /** + * BOOL WINAPI GetComputerNameEx(COMPUTER_NAME_FORMAT NameType, LPTSTR lpBuffer, LPDWORD lpnSize); + * + * Retrieves a NetBIOS or DNS name associated with the local computer. + * + * NameType [in] + * ComputerNameNetBIOS + * ComputerNameDnsHostname + * ComputerNameDnsDomain + * ComputerNameDnsFullyQualified + * ComputerNamePhysicalNetBIOS + * ComputerNamePhysicalDnsHostname + * ComputerNamePhysicalDnsDomain + * ComputerNamePhysicalDnsFullyQualified + * + * lpBuffer [out] + * A pointer to a buffer that receives the computer name or the cluster virtual server name. + * The length of the name may be greater than MAX_COMPUTERNAME_LENGTH characters because DNS allows longer names. + * To ensure that this buffer is large enough, set this parameter to NULL and use the required buffer size returned in the lpnSize parameter. + * + * lpnSize [in, out] + * On input, specifies the size of the buffer, in TCHARs. + * On output, receives the number of TCHARs copied to the destination buffer, not including the terminating null character. + * If the buffer is too small, the function fails and GetLastError returns ERROR_MORE_DATA. + * This parameter receives the size of the buffer required, including the terminating null character. + * If lpBuffer is NULL, this parameter must be zero. + * + */ + + CHAR computerName1[255 + 1]; + CHAR computerName2[255 + 1]; + + const DWORD nameBufferSize = sizeof(computerName1) / sizeof(CHAR); + DWORD dwSize; + DWORD dwMinSize; + DWORD dwNameLength; + DWORD dwError; + + memset(computerName1, 0xAA, nameBufferSize); + memset(computerName2, 0xBB, nameBufferSize); + + + if (format == ComputerNameDnsDomain || format == ComputerNamePhysicalDnsDomain) + { + /* domain names may be empty, terminating null only */ + dwMinSize = 1; + } + else + { + /* computer names must be at least 1 character */ + dwMinSize = 2; + } + + + /* test with null buffer and zero size (required if buffer is null) */ + dwSize = 0; + if (GetComputerNameExA(format, NULL, &dwSize) == TRUE) + { + fprintf(stderr, "%s: (1/%d) GetComputerNameExA unexpectedly succeeded with null buffer\n", + __FUNCTION__, format); + return FALSE; + } + if ((dwError = GetLastError()) != ERROR_MORE_DATA) + { + fprintf(stderr, "%s: (2/%d) GetLastError returned 0x%08"PRIX32" (expected ERROR_MORE_DATA)\n", + __FUNCTION__, format, dwError); + return FALSE; + } + + /* test with valid buffer and zero size */ + dwSize = 0; + if (GetComputerNameExA(format, computerName1, &dwSize) == TRUE) + { + fprintf(stderr, "%s: (3/%d) GetComputerNameExA unexpectedly succeeded with zero size parameter\n", + __FUNCTION__, format); + return FALSE; + } + if ((dwError = GetLastError()) != ERROR_MORE_DATA) + { + fprintf(stderr, "%s: (4/%d) GetLastError returned 0x%08"PRIX32" (expected ERROR_MORE_DATA)\n", + __FUNCTION__, format, dwError); + return FALSE; + } + /* check if returned size is valid: must be the size of the buffer required, including the terminating null character in this case */ + if (dwSize < dwMinSize || dwSize > nameBufferSize) + { + fprintf(stderr, "%s: (5/%d) GetComputerNameExA returned wrong size %"PRIu32" (expected something in the range from %"PRIu32" to %"PRIu32")\n", + __FUNCTION__, format, dwSize, dwMinSize, nameBufferSize); + return FALSE; + } + dwNameLength = dwSize - 1; + + /* test with returned size */ + if (GetComputerNameExA(format, computerName1, &dwSize) == FALSE) + { + fprintf(stderr, "%s: (6/%D) GetComputerNameExA failed with error: 0x%08"PRIX32"\n", + __FUNCTION__, format, GetLastError()); + return FALSE; + } + /* check if returned size is valid */ + if (dwSize != dwNameLength) + { + fprintf(stderr, "%s: (7/%d) GetComputerNameExA returned wrong size %"PRIu32" (expected %"PRIu32")\n", + __FUNCTION__, format, dwSize, dwNameLength); + return FALSE; + } + /* check if string is correctly terminated */ + if (computerName1[dwSize] != 0) + { + fprintf(stderr, "%s: (8/%d) string termination error\n", __FUNCTION__, format); + return FALSE; + } + + /* test with real buffer size */ + dwSize = nameBufferSize; + if (GetComputerNameExA(format, computerName2, &dwSize) == FALSE) + { + fprintf(stderr, "%s: (9/%d) GetComputerNameExA failed with error: 0x%08"PRIX32"\n", + __FUNCTION__, format, GetLastError()); + return FALSE; + } + /* check if returned size is valid */ + if (dwSize != dwNameLength) + { + fprintf(stderr, "%s: (10/%d) GetComputerNameExA returned wrong size %"PRIu32" (expected %"PRIu32")\n", + __FUNCTION__, format, dwSize, dwNameLength); + return FALSE; + } + /* check if string is correctly terminated */ + if (computerName2[dwSize] != 0) + { + fprintf(stderr, "%s: (11/%d) string termination error\n", __FUNCTION__, format); + return FALSE; + } + + /* compare the results */ + if (strcmp(computerName1, computerName2)) + { + fprintf(stderr, "%s: (12/%d) string compare mismatch\n", __FUNCTION__, format); + return FALSE; + } + + /* test with off by one buffer size */ + dwSize = dwNameLength; + if (GetComputerNameExA(format, computerName1, &dwSize) == TRUE) + { + fprintf(stderr, "%s: (13/%d) GetComputerNameExA unexpectedly succeeded with limited buffer size\n", + __FUNCTION__, format); + return FALSE; + } + /* check if returned size is valid */ + if (dwSize != dwNameLength + 1) + { + fprintf(stderr, "%s: (14/%d) GetComputerNameExA returned wrong size %"PRIu32" (expected %"PRIu32")\n", + __FUNCTION__, format, dwSize, dwNameLength + 1); + return FALSE; + } + + return TRUE; +} + + +int TestGetComputerName(int argc, char* argv[]) +{ + if (!Test_GetComputerName()) + return -1; + + if (!Test_GetComputerNameEx_Format(ComputerNameNetBIOS)) + return -1; + + if (!Test_GetComputerNameEx_Format(ComputerNameDnsHostname)) + return -1; + + if (!Test_GetComputerNameEx_Format(ComputerNameDnsDomain)) + return -1; + + if (!Test_GetComputerNameEx_Format(ComputerNameDnsFullyQualified)) + return -1; + + if (!Test_GetComputerNameEx_Format(ComputerNamePhysicalNetBIOS)) + return -1; + + if (!Test_GetComputerNameEx_Format(ComputerNamePhysicalDnsHostname)) + return -1; + + if (!Test_GetComputerNameEx_Format(ComputerNamePhysicalDnsDomain)) + return -1; + + if (!Test_GetComputerNameEx_Format(ComputerNamePhysicalDnsFullyQualified)) + return -1; + + return 0; +} diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/thread/argv.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/thread/argv.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/thread/argv.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/thread/argv.c 2017-03-03 08:39:24.000000000 +0000 @@ -195,7 +195,10 @@ buffer = (char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, maxBufferSize); if (!buffer) + { + free(lpEscapedChars); return NULL; + } pArgs = (LPSTR*) buffer; pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))]; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/thread/tls.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/thread/tls.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/thread/tls.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/thread/tls.c 2017-03-03 08:39:24.000000000 +0000 @@ -36,16 +36,13 @@ #include -DWORD TlsAlloc(VOID) +DWORD TlsAlloc(void) { - DWORD dwTlsIndex; pthread_key_t key; if (pthread_key_create(&key, NULL) != 0) return TLS_OUT_OF_INDEXES; - dwTlsIndex = (DWORD) key; - return key; } @@ -53,30 +50,24 @@ { LPVOID value; pthread_key_t key; - key = (pthread_key_t) dwTlsIndex; value = (LPVOID) pthread_getspecific(key); - return value; } BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) { pthread_key_t key; - key = (pthread_key_t) dwTlsIndex; pthread_setspecific(key, lpTlsValue); - return TRUE; } BOOL TlsFree(DWORD dwTlsIndex) { pthread_key_t key; - key = (pthread_key_t) dwTlsIndex; pthread_key_delete(key); - return TRUE; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/collections/MessageQueue.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/collections/MessageQueue.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/collections/MessageQueue.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/collections/MessageQueue.c 2017-03-03 08:39:24.000000000 +0000 @@ -86,9 +86,10 @@ goto out; queue->array = new_arr; queue->capacity = new_capacity; - ZeroMemory(&(queue->array[old_capacity]), old_capacity * sizeof(wMessage)); + ZeroMemory(&(queue->array[old_capacity]), (new_capacity - old_capacity) * sizeof(wMessage)); - if (queue->tail < old_capacity) + /* rearrange wrapped entries */ + if (queue->tail <= queue->head) { CopyMemory(&(queue->array[old_capacity]), queue->array, queue->tail * sizeof(wMessage)); queue->tail += old_capacity; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/collections/Queue.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/collections/Queue.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/collections/Queue.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/collections/Queue.c 2017-03-03 08:39:24.000000000 +0000 @@ -164,9 +164,10 @@ queue->capacity = new_capacity; queue->array = newArray; - ZeroMemory(&(queue->array[old_capacity]), old_capacity * sizeof(void*)); + ZeroMemory(&(queue->array[old_capacity]), (new_capacity - old_capacity) * sizeof(void*)); - if (queue->tail < old_capacity) + /* rearrange wrapped entries */ + if (queue->tail <= queue->head) { CopyMemory(&(queue->array[old_capacity]), queue->array, queue->tail * sizeof(void*)); queue->tail += old_capacity; diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/sam.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/sam.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/sam.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/sam.c 2017-03-03 08:39:24.000000000 +0000 @@ -309,7 +309,10 @@ return NULL; if (!SamLookupStart(sam)) + { + free(entry); return NULL; + } while (sam->line != NULL) { diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/test/TestLinkedList.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/test/TestLinkedList.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/test/TestLinkedList.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/test/TestLinkedList.c 2017-03-03 08:39:24.000000000 +0000 @@ -6,15 +6,11 @@ int TestLinkedList(int argc, char* argv[]) { int count; - int number; wLinkedList* list; - list = LinkedList_New(); - - LinkedList_AddFirst(list, (void*) (size_t) 1); - LinkedList_AddLast(list, (void*) (size_t) 2); - LinkedList_AddLast(list, (void*) (size_t) 3); - + LinkedList_AddFirst(list, (void*)(size_t) 1); + LinkedList_AddLast(list, (void*)(size_t) 2); + LinkedList_AddLast(list, (void*)(size_t) 3); count = LinkedList_Count(list); if (count != 3) @@ -29,14 +25,12 @@ { printf("\t%"PRIuz"\n", (size_t) LinkedList_Enumerator_Current(list)); } - printf("\n"); + printf("\n"); printf("LinkedList First: %"PRIuz" Last: %"PRIuz"\n", - (size_t) LinkedList_First(list), (size_t) LinkedList_Last(list)); - + (size_t) LinkedList_First(list), (size_t) LinkedList_Last(list)); LinkedList_RemoveFirst(list); LinkedList_RemoveLast(list); - count = LinkedList_Count(list); if (count != 1) @@ -51,14 +45,12 @@ { printf("\t%"PRIuz"\n", (size_t) LinkedList_Enumerator_Current(list)); } - printf("\n"); + printf("\n"); printf("LinkedList First: %"PRIuz" Last: %"PRIuz"\n", - (size_t) LinkedList_First(list), (size_t) LinkedList_Last(list)); - + (size_t) LinkedList_First(list), (size_t) LinkedList_Last(list)); LinkedList_RemoveFirst(list); LinkedList_RemoveLast(list); - count = LinkedList_Count(list); if (count != 0) @@ -67,10 +59,9 @@ return -1; } - LinkedList_AddFirst(list, (void*) (size_t) 4); - LinkedList_AddLast(list, (void*) (size_t) 5); - LinkedList_AddLast(list, (void*) (size_t) 6); - + LinkedList_AddFirst(list, (void*)(size_t) 4); + LinkedList_AddLast(list, (void*)(size_t) 5); + LinkedList_AddLast(list, (void*)(size_t) 6); count = LinkedList_Count(list); if (count != 3) @@ -85,51 +76,47 @@ { printf("\t%"PRIuz"\n", (size_t) LinkedList_Enumerator_Current(list)); } - printf("\n"); + printf("\n"); printf("LinkedList First: %"PRIuz" Last: %"PRIuz"\n", - (size_t) LinkedList_First(list), (size_t) LinkedList_Last(list)); - - LinkedList_Remove(list, (void*) (size_t) 5); - + (size_t) LinkedList_First(list), (size_t) LinkedList_Last(list)); + LinkedList_Remove(list, (void*)(size_t) 5); LinkedList_Enumerator_Reset(list); while (LinkedList_Enumerator_MoveNext(list)) { printf("\t%"PRIuz"\n", (size_t) LinkedList_Enumerator_Current(list)); } - printf("\n"); + printf("\n"); printf("LinkedList First: %"PRIuz" Last: %"PRIuz"\n", - (size_t) LinkedList_First(list), (size_t) LinkedList_Last(list)); - + (size_t) LinkedList_First(list), (size_t) LinkedList_Last(list)); LinkedList_Free(list); - /* Test enumerator robustness */ - /* enumerator on an empty list */ list = LinkedList_New(); LinkedList_Enumerator_Reset(list); + while (LinkedList_Enumerator_MoveNext(list)) { printf("\terror: %"PRIuz"\n", (size_t) LinkedList_Enumerator_Current(list)); } + printf("\n"); LinkedList_Free(list); - /* Use an enumerator without reset */ list = LinkedList_New(); - LinkedList_AddFirst(list, (void*) (size_t) 4); - LinkedList_AddLast(list, (void*) (size_t) 5); - LinkedList_AddLast(list, (void*) (size_t) 6); + LinkedList_AddFirst(list, (void*)(size_t) 4); + LinkedList_AddLast(list, (void*)(size_t) 5); + LinkedList_AddLast(list, (void*)(size_t) 6); + while (LinkedList_Enumerator_MoveNext(list)) { printf("\t%"PRIuz"\n", (size_t) LinkedList_Enumerator_Current(list)); } + printf("\n"); LinkedList_Free(list); - - return 0; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/wlog/FileAppender.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/wlog/FileAppender.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/wlog/FileAppender.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/wlog/FileAppender.c 2017-03-03 08:39:24.000000000 +0000 @@ -31,12 +31,12 @@ struct _wLogFileAppender { - WLOG_APPENDER_COMMON(); + WLOG_APPENDER_COMMON(); - char* FileName; - char* FilePath; - char* FullFileName; - FILE* FileDescriptor; + char* FileName; + char* FilePath; + char* FullFileName; + FILE* FileDescriptor; }; typedef struct _wLogFileAppender wLogFileAppender; @@ -44,6 +44,7 @@ static BOOL WLog_FileAppender_SetOutputFileName(wLogFileAppender* appender, const char* filename) { appender->FileName = _strdup(filename); + if (!appender->FileName) return FALSE; @@ -53,6 +54,7 @@ static BOOL WLog_FileAppender_SetOutputFilePath(wLogFileAppender* appender, const char* filepath) { appender->FilePath = _strdup(filepath); + if (!appender->FilePath) return FALSE; @@ -61,16 +63,17 @@ static BOOL WLog_FileAppender_Open(wLog* log, wLogAppender* appender) { - wLogFileAppender *fileAppender; + wLogFileAppender* fileAppender; if (!log || !appender) return FALSE; - fileAppender = (wLogFileAppender *)appender; + fileAppender = (wLogFileAppender*)appender; if (!fileAppender->FilePath) { fileAppender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog"); + if (!fileAppender->FilePath) return FALSE; } @@ -78,6 +81,7 @@ if (!fileAppender->FileName) { fileAppender->FileName = (char*) malloc(MAX_PATH); + if (!fileAppender->FileName) return FALSE; @@ -87,6 +91,7 @@ if (!fileAppender->FullFileName) { fileAppender->FullFileName = GetCombinedPath(fileAppender->FilePath, fileAppender->FileName); + if (!fileAppender->FullFileName) return FALSE; } @@ -95,6 +100,7 @@ { if (!PathMakePathA(fileAppender->FilePath, 0)) return FALSE; + UnixChangeFileMode(fileAppender->FilePath, 0xFFFF); } @@ -108,19 +114,18 @@ static BOOL WLog_FileAppender_Close(wLog* log, wLogAppender* appender) { - wLogFileAppender *fileAppender; + wLogFileAppender* fileAppender; + if (!log || !appender) return FALSE; - fileAppender = (wLogFileAppender *)appender; + fileAppender = (wLogFileAppender*)appender; if (!fileAppender->FileDescriptor) return TRUE; fclose(fileAppender->FileDescriptor); - fileAppender->FileDescriptor = NULL; - return TRUE; } @@ -128,13 +133,12 @@ { FILE* fp; char prefix[WLOG_MAX_PREFIX_SIZE]; - wLogFileAppender *fileAppender; + wLogFileAppender* fileAppender; if (!log || !appender || !message) return FALSE; - fileAppender = (wLogFileAppender *)appender; - + fileAppender = (wLogFileAppender*)appender; fp = fileAppender->FileDescriptor; if (!fp) @@ -142,17 +146,15 @@ message->PrefixString = prefix; WLog_Layout_GetMessagePrefix(log, appender->Layout, message); - fprintf(fp, "%s%s\n", message->PrefixString, message->TextString); - fflush(fp); /* slow! */ - return TRUE; } static int g_DataId = 0; -static BOOL WLog_FileAppender_WriteDataMessage(wLog* log, wLogAppender* appender, wLogMessage* message) +static BOOL WLog_FileAppender_WriteDataMessage(wLog* log, wLogAppender* appender, + wLogMessage* message) { int DataId; char* FullFileName; @@ -162,17 +164,15 @@ DataId = g_DataId++; FullFileName = WLog_Message_GetOutputFileName(DataId, "dat"); - WLog_DataMessage_Write(FullFileName, message->Data, message->Length); - free(FullFileName); - return TRUE; } static int g_ImageId = 0; -static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender, wLogMessage* message) +static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender, + wLogMessage* message) { int ImageId; char* FullFileName; @@ -182,26 +182,23 @@ ImageId = g_ImageId++; FullFileName = WLog_Message_GetOutputFileName(ImageId, "bmp"); - WLog_ImageMessage_Write(FullFileName, message->ImageData, - message->ImageWidth, message->ImageHeight, message->ImageBpp); - + message->ImageWidth, message->ImageHeight, message->ImageBpp); free(FullFileName); - return TRUE; } -static BOOL WLog_FileAppender_Set(wLogAppender* appender, const char *setting, void *value) +static BOOL WLog_FileAppender_Set(wLogAppender* appender, const char* setting, void* value) { - wLogFileAppender *fileAppender = (wLogFileAppender *) appender; + wLogFileAppender* fileAppender = (wLogFileAppender*) appender; if (!value || !strlen(value)) return FALSE; if (!strcmp("outputfilename", setting)) - return WLog_FileAppender_SetOutputFileName(fileAppender, (const char *)value); + return WLog_FileAppender_SetOutputFileName(fileAppender, (const char*)value); else if (!strcmp("outputfilepath", setting)) - return WLog_FileAppender_SetOutputFilePath(fileAppender, (const char *)value); + return WLog_FileAppender_SetOutputFilePath(fileAppender, (const char*)value); else return FALSE; @@ -214,7 +211,7 @@ if (appender) { - fileAppender = (wLogFileAppender *)appender; + fileAppender = (wLogFileAppender*)appender; free(fileAppender->FileName); free(fileAppender->FilePath); free(fileAppender->FullFileName); @@ -229,13 +226,12 @@ DWORD nSize; wLogFileAppender* FileAppender; BOOL status; - FileAppender = (wLogFileAppender*) calloc(1, sizeof(wLogFileAppender)); + if (!FileAppender) return NULL; FileAppender->Type = WLOG_APPENDER_FILE; - FileAppender->Open = WLog_FileAppender_Open; FileAppender->Close = WLog_FileAppender_Close; FileAppender->WriteMessage = WLog_FileAppender_WriteMessage; @@ -243,16 +239,22 @@ FileAppender->WriteImageMessage = WLog_FileAppender_WriteImageMessage; FileAppender->Free = WLog_FileAppender_Free; FileAppender->Set = WLog_FileAppender_Set; - name = "WLOG_FILEAPPENDER_OUTPUT_FILE_PATH"; nSize = GetEnvironmentVariableA(name, NULL, 0); + if (nSize) { env = (LPSTR) malloc(nSize); + if (!env) goto error_free; - nSize = GetEnvironmentVariableA(name, env, nSize); + if (GetEnvironmentVariableA(name, env, nSize) != nSize) + { + free(env); + goto error_free; + } + status = WLog_FileAppender_SetOutputFilePath(FileAppender, env); free(env); @@ -262,9 +264,11 @@ name = "WLOG_FILEAPPENDER_OUTPUT_FILE_NAME"; nSize = GetEnvironmentVariableA(name, NULL, 0); + if (nSize) { env = (LPSTR) malloc(nSize); + if (!env) goto error_output_file_name; @@ -276,8 +280,7 @@ goto error_output_file_name; } - return (wLogAppender *)FileAppender; - + return (wLogAppender*)FileAppender; error_output_file_name: free(FileAppender->FilePath); error_free: diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/wlog/Layout.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/wlog/Layout.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/utils/wlog/Layout.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/utils/wlog/Layout.c 2017-03-03 08:39:24.000000000 +0000 @@ -73,9 +73,7 @@ void* args[32]; char format[256]; SYSTEMTIME localTime; - GetLocalTime(&localTime); - index = 0; p = (char*) layout->FormatString; @@ -104,7 +102,6 @@ else if ((p[0] == 'f') && (p[1] == 'l')) /* file */ { char* file; - file = strrchr(message->FileName, '/'); if (!file) @@ -129,14 +126,14 @@ } else if ((p[0] == 'l') && (p[1] == 'n')) /* line number */ { - args[argc++] = (void*) (size_t) message->LineNumber; + args[argc++] = (void*)(size_t) message->LineNumber; format[index++] = '%'; format[index++] = 'u'; p++; } else if ((p[0] == 'p') && (p[1] == 'i') && (p[2] == 'd')) /* process id */ { - args[argc++] = (void*) (size_t) GetCurrentProcessId(); + args[argc++] = (void*)(size_t) GetCurrentProcessId(); format[index++] = '%'; format[index++] = 'u'; p += 2; @@ -145,12 +142,12 @@ { #if defined __linux__ && !defined ANDROID /* On Linux we prefer to see the LWP id */ - args[argc++] = (void*) (size_t) syscall(SYS_gettid);; + args[argc++] = (void*)(size_t) syscall(SYS_gettid);; format[index++] = '%'; format[index++] = 'l'; format[index++] = 'd'; #else - args[argc++] = (void*) (size_t) GetCurrentThreadId(); + args[argc++] = (void*)(size_t) GetCurrentThreadId(); format[index++] = '%'; format[index++] = '0'; format[index++] = '8'; @@ -160,14 +157,14 @@ } else if ((p[0] == 'y') && (p[1] == 'r')) /* year */ { - args[argc++] = (void*) (size_t) localTime.wYear; + args[argc++] = (void*)(size_t) localTime.wYear; format[index++] = '%'; format[index++] = 'u'; p++; } else if ((p[0] == 'm') && (p[1] == 'o')) /* month */ { - args[argc++] = (void*) (size_t) localTime.wMonth; + args[argc++] = (void*)(size_t) localTime.wMonth; format[index++] = '%'; format[index++] = '0'; format[index++] = '2'; @@ -176,7 +173,7 @@ } else if ((p[0] == 'd') && (p[1] == 'w')) /* day of week */ { - args[argc++] = (void*) (size_t) localTime.wDayOfWeek; + args[argc++] = (void*)(size_t) localTime.wDayOfWeek; format[index++] = '%'; format[index++] = '0'; format[index++] = '2'; @@ -185,7 +182,7 @@ } else if ((p[0] == 'd') && (p[1] == 'y')) /* day */ { - args[argc++] = (void*) (size_t) localTime.wDay; + args[argc++] = (void*)(size_t) localTime.wDay; format[index++] = '%'; format[index++] = '0'; format[index++] = '2'; @@ -194,7 +191,7 @@ } else if ((p[0] == 'h') && (p[1] == 'r')) /* hours */ { - args[argc++] = (void*) (size_t) localTime.wHour; + args[argc++] = (void*)(size_t) localTime.wHour; format[index++] = '%'; format[index++] = '0'; format[index++] = '2'; @@ -203,7 +200,7 @@ } else if ((p[0] == 'm') && (p[1] == 'i')) /* minutes */ { - args[argc++] = (void*) (size_t) localTime.wMinute; + args[argc++] = (void*)(size_t) localTime.wMinute; format[index++] = '%'; format[index++] = '0'; format[index++] = '2'; @@ -212,7 +209,7 @@ } else if ((p[0] == 's') && (p[1] == 'e')) /* seconds */ { - args[argc++] = (void*) (size_t) localTime.wSecond; + args[argc++] = (void*)(size_t) localTime.wSecond; format[index++] = '%'; format[index++] = '0'; format[index++] = '2'; @@ -221,7 +218,7 @@ } else if ((p[0] == 'm') && (p[1] == 'l')) /* milliseconds */ { - args[argc++] = (void*) (size_t) localTime.wMilliseconds; + args[argc++] = (void*)(size_t) localTime.wMilliseconds; format[index++] = '%'; format[index++] = '0'; format[index++] = '3'; @@ -264,78 +261,77 @@ case 5: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4]); + args[4]); break; case 6: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5]); + args[4], args[5]); break; case 7: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6]); + args[4], args[5], args[6]); break; case 8: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6], args[7]); + args[4], args[5], args[6], args[7]); break; case 9: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6], args[7], args[8]); + args[4], args[5], args[6], args[7], args[8]); break; case 10: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6], args[7], args[8], args[9]); + args[4], args[5], args[6], args[7], args[8], args[9]); break; case 11: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6], args[7], args[8], args[9], args[10]); + args[4], args[5], args[6], args[7], args[8], args[9], args[10]); break; case 12: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6], args[7], args[8], args[9], args[10], - args[11]); + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11]); break; case 13: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6], args[7], args[8], args[9], args[10], - args[11], args[12]); + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11], args[12]); break; case 14: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6], args[7], args[8], args[9], args[10], - args[11], args[12], args[13]); + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11], args[12], args[13]); break; case 15: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6], args[7], args[8], args[9], args[10], - args[11], args[12], args[13], args[14]); + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11], args[12], args[13], args[14]); break; case 16: WLog_PrintMessagePrefix(log, message, format, args[0], args[1], args[2], args[3], - args[4], args[5], args[6], args[7], args[8], args[9], args[10], - args[11], args[12], args[13], args[14], args[15]); + args[4], args[5], args[6], args[7], args[8], args[9], args[10], + args[11], args[12], args[13], args[14], args[15]); break; } + return TRUE; } wLogLayout* WLog_GetLogLayout(wLog* log) { wLogAppender* appender; - appender = WLog_GetLogAppender(log); - return appender->Layout; } @@ -347,9 +343,11 @@ if (format) { layout->FormatString = _strdup(format); + if (!layout->FormatString) return FALSE; } + return TRUE; } @@ -358,21 +356,29 @@ DWORD nSize; char* env = NULL; wLogLayout* layout; - layout = (wLogLayout*) calloc(1, sizeof(wLogLayout)); + if (!layout) return NULL; nSize = GetEnvironmentVariableA("WLOG_PREFIX", NULL, 0); + if (nSize) { env = (LPSTR) malloc(nSize); + if (!env) { free(layout); return NULL; } - nSize = GetEnvironmentVariableA("WLOG_PREFIX", env, nSize); + + if (GetEnvironmentVariableA("WLOG_PREFIX", env, nSize) != nSize) + { + free(env); + free(layout); + return NULL; + } } if (env) @@ -384,6 +390,7 @@ #else layout->FormatString = _strdup("[%hr:%mi:%se:%ml] [%pid:%tid] [%lv][%mn] - "); #endif + if (!layout->FormatString) { free(layout); @@ -391,7 +398,6 @@ } } - return layout; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/winsock/winsock.c freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/winsock/winsock.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/libwinpr/winsock/winsock.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/libwinpr/winsock/winsock.c 2017-03-03 08:39:24.000000000 +0000 @@ -923,7 +923,7 @@ next_ifreq: -#if !defined(__linux__) && !defined(__sun__) +#if !defined(__linux__) && !defined(__sun__) && !defined(__CYGWIN__) ifreq_len = IFNAMSIZ + ifreq->ifr_addr.sa_len; #else ifreq_len = sizeof(*ifreq); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -104,6 +104,7 @@ add_library(${MODULE_NAME} ${WINPR_TOOLS_SRCS}) set_target_properties(${MODULE_NAME} PROPERTIES LINKER_LANGUAGE C) +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${WINPR_TOOLS_API_VERSION}) if (WITH_LIBRARY_VERSIONING) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_TOOLS_VERSION} SOVERSION ${WINPR_TOOLS_API_VERSION}) endif() @@ -113,7 +114,8 @@ install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT WinPRTargets) if (WITH_DEBUG_SYMBOLS AND MSVC AND BUILD_SHARED_LIBS) - install(FILES ${CMAKE_PDB_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) + get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME) + install(FILES ${CMAKE_PDB_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Tools") diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/.gitignore freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/.gitignore --- freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/.gitignore 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/.gitignore 2017-03-03 08:39:24.000000000 +0000 @@ -1,2 +1,4 @@ makecert-cli/winpr-makecert +makecert-cli/winpr-makecert.1 hash-cli/winpr-hash +hash-cli/winpr-hash.1 diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/hash-cli/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/hash-cli/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/hash-cli/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/hash-cli/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -50,3 +50,5 @@ endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Tools") +configure_file(winpr-hash.1.in ${CMAKE_CURRENT_BINARY_DIR}/winpr-hash.1) +install_freerdp_man(${CMAKE_CURRENT_BINARY_DIR}/winpr-hash.1 1) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/hash-cli/hash.c freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/hash-cli/hash.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/hash-cli/hash.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/hash-cli/hash.c 2017-03-03 08:39:24.000000000 +0000 @@ -44,6 +44,13 @@ * */ +void usage_and_exit() +{ + printf("winpr-hash: NTLM hashing tool\n"); + printf("Usage: winpr-hash -u -p [-d ] [-f <_default_,sam>] [-v <_1_,2>]\n"); + exit(1); +} + int main(int argc, char* argv[]) { int index = 1; @@ -65,8 +72,8 @@ if (index == argc) { - printf("missing domain\n"); - exit(1); + printf("missing domain\n\n"); + usage_and_exit(); } Domain = argv[index]; @@ -77,8 +84,8 @@ if (index == argc) { - printf("missing username\n"); - exit(1); + printf("missing username\n\n"); + usage_and_exit(); } User = argv[index]; @@ -89,8 +96,8 @@ if (index == argc) { - printf("missing password\n"); - exit(1); + printf("missing password\n\n"); + usage_and_exit(); } Password = argv[index]; @@ -101,14 +108,17 @@ if (index == argc) { - printf("missing version\n"); - exit(1); + printf("missing version parameter\n\n"); + usage_and_exit(); } version = atoi(argv[index]); if ((version != 1) && (version != 2)) - version = 1; + { + printf("unkown version %d \n\n", version); + usage_and_exit(); + } } else if (strcmp("-f", argv[index]) == 0) { @@ -116,8 +126,8 @@ if (index == argc) { - printf("missing format\n"); - exit(1); + printf("missing format\n\n"); + usage_and_exit(); } if (strcmp("default", argv[index]) == 0) @@ -127,9 +137,7 @@ } else if (strcmp("-h", argv[index]) == 0) { - printf("winpr-hash: NTLM hashing tool\n"); - printf("Usage: winpr-hash -u -p [-d ] -f -v <1,2>\n"); - exit(1); + usage_and_exit(); } index++; @@ -137,8 +145,8 @@ if ((!User) || (!Password)) { - printf("missing username or password\n"); - exit(1); + printf("missing username or password\n\n"); + usage_and_exit(); } UserLength = strlen(User); @@ -149,8 +157,8 @@ { if (!Domain) { - printf("missing domain\n"); - exit(1); + printf("missing domain (version 2 requires a domain to specified)\n\n"); + usage_and_exit(); } NTOWFv2A(Password, PasswordLength, User, UserLength, Domain, DomainLength, NtHash); diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/hash-cli/winpr-hash.1.in freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/hash-cli/winpr-hash.1.in --- freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/hash-cli/winpr-hash.1.in 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/hash-cli/winpr-hash.1.in 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,42 @@ +.TH winpr-hash 1 2017-01-11 "@FREERDP_VERSION_FULL@" "FreeRDP" +.SH NAME +winpr-hash \- NTLM hashing tool +.SH SYNOPSIS +.B winpr-hash +\fB-u\fP username +\fB-p\fP password +[\fB-d\fP domain] +[\fB-f\fP { \fIdefault\fP | sam }] +[\fB-v\fP { \fI1\fP | 2 }] +.SH DESCRIPTION +.B winpr-hash +is a small utility that can be used to create a NTLM hash from a username and password pair. The created hash can be outputed as plain hash or in SAM format. +.SH OPTIONS +.IP "-u username" +The username to use. +.IP "-p password" +Password to use. +.IP "-d domain" +A optional parameter to specify the domain of the user. +.IP "-f format" +Specify the output format. The \fIdefault\fP outputs only the plain NTLM +hash. The second output format available is \fIsam\fP which outputs the +created hash in a format that it can be used in SAM file: + +user:domain::hash::: +.IP "-v version" +Version allows it to specify the NTLM version to use. The default is to use version 1. In case +version 2 is used a domain needs to be specified. +.SH EXAMPLES +winpr-hash -u \fIuser\fP -p \fIpassword\fP -d \fIdomain\fP -f \fIsam\fP -v \fI2\fP + +Create a version \fI2\fP NTLM hash for \fIuser\fP with \fIdomain\fP and \fIpassword\fP and output it in \fIsam\fP format. +.SH EXIT STATUS +.TP +.B 0 +Successful program execution. +.TP +.B 1 +Missing or invalid arguments. +.SH AUTHOR +FreeRDP diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/makecert/makecert.c freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/makecert/makecert.c --- freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/makecert/makecert.c 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/makecert/makecert.c 2017-03-03 08:39:24.000000000 +0000 @@ -67,7 +67,7 @@ /* Custom Options */ { "rdp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Generate certificate with required options for RDP usage." + "Unsupported - Generate certificate with required options for RDP usage." }, { "silent", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Silently generate certificate without verbose output." @@ -92,82 +92,82 @@ "The simplest method is to specify the name in double quotes, preceded by CN=; for example, -n \"CN=myName\"." }, { "pe", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Marks the generated private key as exportable. This allows the private key to be included in the certificate." + "Unsupported - Marks the generated private key as exportable. This allows the private key to be included in the certificate." }, { "sk", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the subject's key container location, which contains the private key. " + "Unsupported - Specifies the subject's key container location, which contains the private key. " "If a key container does not exist, it will be created." }, { "sr", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the subject's certificate store location. location can be either currentuser (the default) or localmachine." + "Unsupported - Specifies the subject's certificate store location. location can be either currentuser (the default) or localmachine." }, { "ss", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the subject's certificate store name that stores the output certificate." + "Unsupported - Specifies the subject's certificate store name that stores the output certificate." }, { "#", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Specifies a serial number from 1 to 2,147,483,647. The default is a unique value generated by Makecert.exe." }, { "$", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the signing authority of the certificate, which must be set to either commercial " + "Unsupported - Specifies the signing authority of the certificate, which must be set to either commercial " "(for certificates used by commercial software publishers) or individual (for certificates used by individual software publishers)." }, /* Extended Options */ { "a", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the signature algorithm. algorithm must be md5, sha1 (the default), sha256, sha384, or sha512." + "Specifies the signature algorithm. algorithm must be md5, sha1, sha256 (the default), sha384, or sha512." }, { "b", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the start of the validity period. Defaults to the current date." + "Unsupported - Specifies the start of the validity period. Defaults to the current date." }, { "crl", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Generates a certificate relocation list (CRL) instead of a certificate." + "Unsupported - Generates a certificate relocation list (CRL) instead of a certificate." }, { "cy", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the certificate type. Valid values are end for end-entity and authority for certification authority." + "Unsupported - Specifies the certificate type. Valid values are end for end-entity and authority for certification authority." }, { "e", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the end of the validity period. Defaults to 12/31/2039 11:59:59 GMT." + "Unsupported - Specifies the end of the validity period. Defaults to 12/31/2039 11:59:59 GMT." }, { "eku", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Inserts a list of comma-separated, enhanced key usage object identifiers (OIDs) into the certificate." + "Unsupported - Inserts a list of comma-separated, enhanced key usage object identifiers (OIDs) into the certificate." }, { "h", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the maximum height of the tree below this certificate." + "Unsupported - Specifies the maximum height of the tree below this certificate." }, { "ic", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the issuer's certificate file." + "Unsupported - Specifies the issuer's certificate file." }, { "ik", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the issuer's key container name." + "Unsupported - Specifies the issuer's key container name." }, { "iky", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the issuer's key type, which must be one of the following: " + "Unsupported - Specifies the issuer's key type, which must be one of the following: " "signature (which indicates that the key is used for a digital signature), " "exchange (which indicates that the key is used for key encryption and key exchange), " "or an integer that represents a provider type. " "By default, you can pass 1 for an exchange key or 2 for a signature key." }, { "in", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the issuer's certificate common name." + "Unsupported - Specifies the issuer's certificate common name." }, { "ip", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the issuer's CryptoAPI provider name. For information about the CryptoAPI provider name, see the –sp option." + "Unsupported - Specifies the issuer's CryptoAPI provider name. For information about the CryptoAPI provider name, see the –sp option." }, { "ir", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the location of the issuer's certificate store. location can be either currentuser (the default) or localmachine." + "Unsupported - Specifies the location of the issuer's certificate store. location can be either currentuser (the default) or localmachine." }, { "is", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the issuer's certificate store name." + "Unsupported - Specifies the issuer's certificate store name." }, { "iv", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the issuer's .pvk private key file." + "Unsupported - Specifies the issuer's .pvk private key file." }, { "iy", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the issuer's CryptoAPI provider type. For information about the CryptoAPI provider type, see the –sy option." + "Unsupported - Specifies the issuer's CryptoAPI provider type. For information about the CryptoAPI provider type, see the –sy option." }, { "l", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Links to policy information (for example, to a URL)." + "Unsupported - Links to policy information (for example, to a URL)." }, { "len", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Specifies the generated key length, in bits." @@ -179,36 +179,36 @@ "Specifies the duration, in years, of the certificate validity period." }, { "nscp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Includes the Netscape client-authorization extension." + "Unsupported - Includes the Netscape client-authorization extension." }, { "r", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Creates a self-signed certificate." + "Unsupported - Creates a self-signed certificate." }, { "sc", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the subject's certificate file." + "Unsupported - Specifies the subject's certificate file." }, { "sky", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the subject's key type, which must be one of the following: " + "Unsupported - Specifies the subject's key type, which must be one of the following: " "signature (which indicates that the key is used for a digital signature), " "exchange (which indicates that the key is used for key encryption and key exchange), " "or an integer that represents a provider type. " "By default, you can pass 1 for an exchange key or 2 for a signature key." }, { "sp", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the subject's CryptoAPI provider name, which must be defined in the registry subkeys of " + "Unsupported - Specifies the subject's CryptoAPI provider name, which must be defined in the registry subkeys of " "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider. If both –sp and –sy are present, " "the type of the CryptoAPI provider must correspond to the Type value of the provider's subkey." }, { "sv", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the subject's .pvk private key file. The file is created if none exists." + "Unsupported - Specifies the subject's .pvk private key file. The file is created if none exists." }, { "sy", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the subject's CryptoAPI provider type, which must be defined in the registry subkeys of " + "Unsupported - Specifies the subject's CryptoAPI provider type, which must be defined in the registry subkeys of " "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider Types. If both –sy and –sp are present, " "the name of the CryptoAPI provider must correspond to the Name value of the provider type subkey." }, { "tbs", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the certificate or CRL file to be signed." + "Unsupported - Specifies the certificate or CRL file to be signed." }, /* Help */ @@ -354,9 +354,8 @@ context->output_file = _strdup(argv[index]); if (!context->output_file) return -1; + return 1; } - - return 1; } return 0; @@ -389,11 +388,10 @@ do { - if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) + if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT)) continue; CommandLineSwitchStart(arg) - /* Basic Options */ CommandLineSwitchCase(arg, "silent") @@ -474,7 +472,6 @@ CommandLineSwitchDefault(arg) { - } CommandLineSwitchEnd(arg) @@ -579,7 +576,7 @@ goto out_fail; status = BIO_read(bio, x509_str, length); - + if (status < 0) goto out_fail; @@ -634,7 +631,7 @@ goto out_fail; status = BIO_read(bio, x509_str, length); - + if (status < 0) goto out_fail; @@ -692,7 +689,7 @@ goto out_fail; status = BIO_read(bio, x509_str, length); - + if (status < 0) goto out_fail; @@ -880,7 +877,9 @@ ret = makecert_context_parse_arguments(context, argc, argv); if (ret < 1) + { return ret; + } if (!context->default_name && !context->common_name) { @@ -951,7 +950,7 @@ { X509_gmtime_adj(X509_get_notAfter(context->x509), (long) (60 * 60 * 24 * 365 * context->duration_years)); } - + X509_set_pubkey(context->x509, context->pkey); name = X509_get_subject_name(context->x509); @@ -1004,7 +1003,7 @@ arg = CommandLineFindArgumentA(args, "a"); - md = EVP_sha1(); + md = EVP_sha256(); if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) { @@ -1051,14 +1050,14 @@ } status = BIO_read(bio, x509_str, length); - + if (status < 0) { BIO_free(bio); free(x509_str); return -1; } - + offset += status; while (offset >= length) @@ -1074,20 +1073,21 @@ break; } - length = new_len; x509_str = new_str; - status = BIO_read(bio, &x509_str[offset], length); + status = BIO_read(bio, &x509_str[offset], new_len); + if (status < 0) break; + length = length + new_len; offset += status; } if (status < 0) return -1; - + length = offset; x509_str[length] = '\0'; @@ -1106,7 +1106,7 @@ makecert_context_output_certificate_file(context, context->output_path); if (context->crtFormat) - { + { if (makecert_context_output_private_key_file(context, context->output_path) < 0) return -1; } diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/makecert-cli/CMakeLists.txt freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/makecert-cli/CMakeLists.txt --- freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/makecert-cli/CMakeLists.txt 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/makecert-cli/CMakeLists.txt 2017-03-03 08:39:24.000000000 +0000 @@ -50,3 +50,6 @@ if (WITH_DEBUG_SYMBOLS AND MSVC) install(FILES ${CMAKE_PDB_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT symbols) endif() + +configure_file(winpr-makecert.1.in ${CMAKE_CURRENT_BINARY_DIR}/winpr-makecert.1) +install_freerdp_man(${CMAKE_CURRENT_BINARY_DIR}/winpr-makecert.1 1) diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/makecert-cli/winpr-makecert.1.in freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/makecert-cli/winpr-makecert.1.in --- freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/makecert-cli/winpr-makecert.1.in 1970-01-01 00:00:00.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/makecert-cli/winpr-makecert.1.in 2017-03-03 08:39:24.000000000 +0000 @@ -0,0 +1,116 @@ +.de URL +\\$2 \(laURL: \\$1 \(ra\\$3 +.. +.if \n[.g] .mso www.tmac)) +.TH winpr\-makecert 1 2017-01-11 "@FREERDP_VERSION_FULL@" "FreeRDP" +.SH NAME +winpr\-makecert \- A tool to create X.509 certificates. +.SH SYNOPSIS +.B winpr\-makecert +[\fB-rdp\fP] +[\fB-silent\fP] +[\fB-live\fP] +[\fB-format\fP { \fIcrt\fP | \fIpem\fP | \fIpfx\fP }] +[\fB-p\fP password] +[\fB-n\fP common_name] +[\fB-y\fP years] +[\fB-m\fP months] +[\fB-len\fP lenth] +[\fB-#\fP serial] +[\fB-a\fP { \fImd5\fP | \fIsha1\fP | \fIsha256\fP | \fIs384\fP | \fIsha512\fP }] +[\fB-path\fP outputpath] +[outputname] +.SH DESCRIPTION +.B winpr-makecert +is a tool for generating X.509 certificates modeled after the Windows command +MakeCert. winpr-makecert aims to be command line compatible with MakeCert +however not all options are supported or implemented yet. + +Unimplemented features are not described here. They are marked as "Unsupported" +in winpr-makecerts help. + +In contrast to it's Windows counterpart winpr\-makecert does, unless the +\fB\-live\fP option is given, always creates and save a certificate. +If \fIoutputname\fP isn't set it is tried to determine the host name of the +computer the command is run on. +.br +\fBWarning:\fP if the file already exists it will be overwritten without asking. + +Without further options the generated certificates have the following properties: + +* 2048 bit long +.br +* sha256 as hash algorithm +.br +* the detected host name is used as common name +.br +* a time stamp is used as serial number +.br +* validity period of one year +.br +* saved in the current working directory in crt format +.SH OPTIONS +.IP "-rdp" +Dummy parameter. Can be used to quickly generate a certificate with default +properties without specifying any further parameters. +.IP "-silent" +Don't print the generated certificate to stdout. +.IP "-f format" +Three formats are supported: crt, pem and pfx. +.br +\fIcrt\fP outputs the key and the certificate in a separate file each with the file +endings .key and .crt. +.br +\fIpem\fP outputs the key and certificate into a single file with the file ending pem. +.br +And \fIpfx\fP outputs key and certificate into a pkcs12 file with the ending .pfx. +.IP "-p password" +Password to use if the pfx format is used as format. +.IP "-live" +Don't write the key/certificate to disk. When used from the command line this +can be thought as "dummy" mode. +.IP "-n common_name" +The common name to use in the certificate. +.IP "-m months" +Validity period in months. +.IP "-y years" +Validity period in years. If months and years are specified the specified +month parameter will take precedence. +.IP "-len length" +Key length in bits to use. +.IP "-a { \fImd5\fP | \fIsha1\fP | \fIsha256\fP | \fIs384\fP | \fIsha512\fP }" +The hashing algorithm to use. +.IP "-# serial" +The serial number to use for the certificate. +.IP "-path" +A directory where the certificate should be created in. +.IP "outputname" +The base name of the created file(s). A suffix, the format specific suffix is +appended to this name. +.SH EXAMPLES +winpr-makecert -rdp + +Creates a certificate with the default properties, saved to a file in the +current working directory in crt format named like the host. If the host is +named freerdp the created files are called freerdp.key and freerdp.crt. + + +winpr-makecert -len 4096 -a sha384 -path /tmp -# 22 -m 144 -y 1 -format crt mycert + +The command above creates the file /tmp/mycert.pem containing a key and a +certificate with a length of 4096. It will use sha384 as hash algorithm. +The certificate has the serial number 22 and is valid for 12 years (144 months). +.SH EXIT STATUS +.TP +.B 0 +Successful program execution. +.TP +.B 1 +Otherweise. + +.SH SEE ALSO + +.URL "https://msdn.microsoft.com/library/windows/desktop/aa386968.aspx" "MakeCert help page" + +.SH AUTHOR +FreeRDP diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/winpr-tools.pc.in freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/winpr-tools.pc.in --- freerdp-2.0.0~dev201701161718+dfsg/winpr/tools/winpr-tools.pc.in 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/tools/winpr-tools.pc.in 2017-03-03 08:39:24.000000000 +0000 @@ -2,7 +2,7 @@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=${prefix}/@WINPR_INCLUDE_DIR@ -libs=-lwinpr-tools +libs=-lwinpr-tools@WINPR_TOOLS_API_VERSION@ Name: WinPR Description: WinPR: Windows Portable Runtime diff -Nru freerdp-2.0.0~dev201701161718+dfsg/winpr/winpr.pc.in freerdp-2.0.0~dev201703030839+dfsg/winpr/winpr.pc.in --- freerdp-2.0.0~dev201701161718+dfsg/winpr/winpr.pc.in 2017-01-16 17:18:43.000000000 +0000 +++ freerdp-2.0.0~dev201703030839+dfsg/winpr/winpr.pc.in 2017-03-03 08:39:24.000000000 +0000 @@ -2,7 +2,7 @@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=${prefix}/@WINPR_INCLUDE_DIR@ -libs=-lwinpr +libs=-lwinpr@WINPR_API_VERSION@ Name: WinPR Description: WinPR: Windows Portable Runtime