summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspeidy <speidy@gmail.com>2016-12-22 12:04:29 -0500
committerspeidy <speidy@gmail.com>2016-12-22 12:04:29 -0500
commit93c55e58a884270850794c29bd0f4e2df22e22d6 (patch)
tree0eeece185f648a2ddf14d522c54c75c70986afda
parentf4224615c97668236826d115fa37b6ce805bea96 (diff)
parent38253f1371b5e01e05ba995f28b6451ee57b613c (diff)
downloadxrdp-proprietary-93c55e58a884270850794c29bd0f4e2df22e22d6.tar.gz
xrdp-proprietary-93c55e58a884270850794c29bd0f4e2df22e22d6.zip
Merge branch 'devel' of https://github.com/neutrinolabs/xrdp
Conflicts: xorgxrdp
-rw-r--r--.gitignore24
-rw-r--r--.gitmodules10
-rw-r--r--.travis.yml40
-rw-r--r--Coding_Style.odtbin23360 -> 0 bytes
-rw-r--r--Makefile.am40
-rw-r--r--NEWS.md25
-rw-r--r--README.md126
-rwxr-xr-xbootstrap8
-rw-r--r--coding_style.md210
-rw-r--r--common/Makefile.am62
-rw-r--r--common/arch.h25
-rw-r--r--common/d3des.c510
-rw-r--r--common/d3des.h56
-rw-r--r--common/file.c146
-rw-r--r--common/file_loc.h4
-rw-r--r--common/list.c6
-rw-r--r--common/list.h2
-rw-r--r--common/log.c25
-rw-r--r--common/log.h22
-rw-r--r--common/os_calls.c1021
-rw-r--r--common/os_calls.h96
-rw-r--r--common/parse.h4
-rw-r--r--common/pixman-region.c2549
-rw-r--r--common/pixman-region.h76
-rw-r--r--common/pixman-region16.c77
-rw-r--r--common/ssl_calls.c255
-rw-r--r--common/ssl_calls.h9
-rw-r--r--common/thread_calls.c15
-rw-r--r--common/trans.c257
-rw-r--r--common/trans.h27
-rw-r--r--common/xrdp_client_info.h16
-rw-r--r--common/xrdp_constants.h127
-rw-r--r--configure.ac211
-rw-r--r--design.txt2
-rw-r--r--docs/man/Makefile.am4
-rw-r--r--docs/man/sesman.ini.5311
-rw-r--r--docs/man/xrdp-chansrv.86
-rw-r--r--docs/man/xrdp-dis.110
-rw-r--r--docs/man/xrdp-genkeymap.842
-rw-r--r--docs/man/xrdp-keygen.86
-rw-r--r--docs/man/xrdp-sesadmin.82
-rw-r--r--docs/man/xrdp-sesman.826
-rw-r--r--docs/man/xrdp-sesrun.822
-rw-r--r--docs/man/xrdp-sessvc.86
-rw-r--r--docs/man/xrdp-xcon.82
-rw-r--r--docs/man/xrdp.84
-rw-r--r--docs/man/xrdp.ini.5181
-rw-r--r--faq-general.txt8
-rw-r--r--file-loc.txt39
-rw-r--r--fontdump/.gitignore1
-rw-r--r--[-rwxr-xr-x]fontdump/Makefile0
-rw-r--r--[-rwxr-xr-x]fontdump/fontdump.c0
-rw-r--r--genkeymap/Makefile.am11
-rwxr-xr-xgenkeymap/dump-keymaps.sh41
-rw-r--r--genkeymap/genkeymap.c23
-rw-r--r--genkeymap/readme.txt6
-rw-r--r--install.txt6
-rw-r--r--instfiles/Makefile.am95
-rw-r--r--instfiles/default/Makefile.am5
-rw-r--r--instfiles/init.d/Makefile.am6
-rw-r--r--instfiles/init.d/xrdp17
-rw-r--r--instfiles/keymap-names.txt124
-rw-r--r--instfiles/km-00000407.ini (renamed from instfiles/km-0407.ini)0
-rw-r--r--instfiles/km-00000409.ini (renamed from instfiles/km-0409.ini)0
-rw-r--r--instfiles/km-0000040a.ini659
-rw-r--r--instfiles/km-0000040b.ini (renamed from instfiles/km-041d.ini)0
-rw-r--r--instfiles/km-0000040c.ini (renamed from instfiles/km-040c.ini)0
-rw-r--r--instfiles/km-00000410.ini (renamed from instfiles/km-0410.ini)0
-rw-r--r--instfiles/km-00000411.ini (renamed from instfiles/km-0411.ini)32
-rw-r--r--instfiles/km-00000412.ini (renamed from instfiles/km-e0010411.ini)2112
-rw-r--r--instfiles/km-00000414.ini (renamed from instfiles/km-0414.ini)0
-rw-r--r--instfiles/km-00000415.ini (renamed from instfiles/km-0415.ini)0
-rw-r--r--instfiles/km-00000416.ini (renamed from instfiles/km-0416.ini)0
-rw-r--r--instfiles/km-00000419.ini (renamed from instfiles/km-0419.ini)0
-rw-r--r--instfiles/km-0000041d.ini791
-rw-r--r--instfiles/km-00000807.ini (renamed from instfiles/km-0807.ini)0
-rw-r--r--instfiles/km-00000809.ini (renamed from instfiles/km-e0200411.ini)492
-rw-r--r--instfiles/km-0000080c.ini (renamed from instfiles/km-080c.ini)0
-rw-r--r--instfiles/km-00000813.ini (renamed from instfiles/km-0813.ini)0
-rw-r--r--instfiles/km-00000816.ini (renamed from instfiles/km-0816.ini)0
-rw-r--r--instfiles/km-0000100c.ini659
-rw-r--r--instfiles/km-e0210411.ini1055
-rw-r--r--instfiles/pam.d/Makefile.am21
-rw-r--r--instfiles/pam.d/xrdp-sesman.common (renamed from instfiles/pam.d/xrdp-sesman)1
-rw-r--r--instfiles/pam.d/xrdp-sesman.password-auth4
-rw-r--r--instfiles/pulse/Makefile.am5
-rw-r--r--instfiles/rc.d/Makefile.am2
-rw-r--r--instfiles/rc.d/xrdp80
-rw-r--r--instfiles/xrdp-sesman.service4
-rw-r--r--instfiles/xrdp.service3
-rw-r--r--keygen/Makefile.am27
-rw-r--r--keygen/keygen.c23
-rw-r--r--keygen/openssl.conf4
m---------libpainter0
m---------librfxcodec0
-rw-r--r--libxrdp/Makefile.am82
-rw-r--r--libxrdp/libxrdp.c226
-rw-r--r--libxrdp/libxrdp.h4
-rw-r--r--libxrdp/libxrdpinc.h13
-rw-r--r--libxrdp/xrdp_bitmap32_compress.c122
-rw-r--r--libxrdp/xrdp_bitmap_compress.c8
-rw-r--r--libxrdp/xrdp_caps.c139
-rw-r--r--libxrdp/xrdp_channel.c2
-rw-r--r--libxrdp/xrdp_fastpath.c57
-rw-r--r--libxrdp/xrdp_iso.c92
-rw-r--r--libxrdp/xrdp_jpeg_compress.c31
-rw-r--r--libxrdp/xrdp_mcs.c6
-rw-r--r--libxrdp/xrdp_orders.c165
-rw-r--r--libxrdp/xrdp_orders_rail.c6
-rw-r--r--libxrdp/xrdp_rdp.c96
-rw-r--r--libxrdp/xrdp_sec.c125
-rw-r--r--m4/.gitignore2
-rw-r--r--m4/ax_append_compile_flags.m467
-rw-r--r--m4/ax_append_flag.m471
-rw-r--r--m4/ax_cflags_warn_all.m4122
-rw-r--r--m4/ax_check_compile_flag.m474
-rw-r--r--m4/ax_gcc_func_attribute.m4223
-rw-r--r--m4/ax_require_defined.m437
-rw-r--r--m4/ax_type_socklen_t.m461
-rw-r--r--m4/pkg.m4275
-rw-r--r--mc/Makefile.am14
-rw-r--r--mc/mc.c12
-rw-r--r--mc/mc.h27
-rw-r--r--neutrinordp/Makefile.am28
-rw-r--r--neutrinordp/xrdp-color.c30
-rw-r--r--neutrinordp/xrdp-color.h8
-rw-r--r--neutrinordp/xrdp-neutrinordp.c279
-rw-r--r--neutrinordp/xrdp-neutrinordp.h263
-rw-r--r--pkgconfig/.gitignore2
-rw-r--r--pkgconfig/Makefile.am2
-rw-r--r--pkgconfig/xrdp-uninstalled.pc.in7
-rw-r--r--pkgconfig/xrdp.pc.in9
-rw-r--r--prog_std.txt40
-rw-r--r--rdp/Makefile.am23
-rw-r--r--rdp/rdp.c12
-rw-r--r--rdp/rdp.h8
-rw-r--r--rdp/rdp_lic.c15
-rw-r--r--rdp/rdp_mcs.c2
-rw-r--r--rdp/rdp_orders.c21
-rw-r--r--rdp/rdp_rdp.c34
-rw-r--r--rdp/rdp_tcp.c6
-rw-r--r--readme.txt40
-rw-r--r--sesman/Makefile.am40
-rw-r--r--sesman/access.c8
-rw-r--r--sesman/access.h4
-rw-r--r--sesman/auth.h8
-rw-r--r--sesman/chansrv/Makefile.am88
-rw-r--r--sesman/chansrv/chansrv.c87
-rw-r--r--sesman/chansrv/chansrv_fuse.c378
-rw-r--r--sesman/chansrv/clipboard.c61
-rw-r--r--sesman/chansrv/clipboard_common.h3
-rw-r--r--sesman/chansrv/clipboard_file.c29
-rw-r--r--sesman/chansrv/devredir.c73
-rw-r--r--sesman/chansrv/devredir.h24
-rw-r--r--sesman/chansrv/drdynvc.c12
-rw-r--r--sesman/chansrv/fifo.c8
-rw-r--r--sesman/chansrv/irp.c3
-rw-r--r--sesman/chansrv/pcsc/.gitignore1
-rwxr-xr-xsesman/chansrv/pcsc/wrapper/winscard-funcs.h4
-rwxr-xr-xsesman/chansrv/pcsc/wrapper/winscard.c6
-rw-r--r--sesman/chansrv/pulse/.gitignore1
-rw-r--r--sesman/chansrv/pulse/module-xrdp-sink-symdef.h4
-rw-r--r--sesman/chansrv/pulse/module-xrdp-sink.c8
-rw-r--r--sesman/chansrv/pulse/module-xrdp-source-symdef.h4
-rw-r--r--sesman/chansrv/pulse/module-xrdp-source.c9
-rw-r--r--sesman/chansrv/rail.c58
-rw-r--r--sesman/chansrv/smartcard.c11
-rw-r--r--sesman/chansrv/smartcard_pcsc.c10
-rw-r--r--sesman/chansrv/sound.c338
-rw-r--r--sesman/chansrv/wave-format-server.txt467
-rw-r--r--sesman/chansrv/xcommon.c6
-rw-r--r--sesman/config.c81
-rw-r--r--sesman/config.h13
-rw-r--r--sesman/env.c120
-rw-r--r--sesman/env.h8
-rw-r--r--sesman/libscp/Makefile.am31
-rw-r--r--sesman/libscp/libscp_connection.c4
-rw-r--r--sesman/libscp/libscp_init.c2
-rw-r--r--sesman/libscp/libscp_init.h2
-rw-r--r--sesman/libscp/libscp_lock.c30
-rw-r--r--sesman/libscp/libscp_lock.h4
-rw-r--r--sesman/libscp/libscp_session.c74
-rw-r--r--sesman/libscp/libscp_session.h23
-rw-r--r--sesman/libscp/libscp_tcp.c2
-rw-r--r--sesman/libscp/libscp_types.h5
-rw-r--r--sesman/libscp/libscp_v0.c20
-rw-r--r--sesman/libscp/libscp_v0.h2
-rw-r--r--sesman/libscp/libscp_v1c.c8
-rw-r--r--sesman/libscp/libscp_v1c_mng.c2
-rw-r--r--sesman/libscp/libscp_v1s.c31
-rw-r--r--sesman/libscp/libscp_v1s.h11
-rw-r--r--sesman/libscp/libscp_v1s_mng.c6
-rw-r--r--sesman/libscp/libscp_v1s_mng.h6
-rw-r--r--sesman/libscp/libscp_vX.h2
-rw-r--r--sesman/lock.c121
-rw-r--r--sesman/lock.h104
-rw-r--r--sesman/scp.c24
-rw-r--r--sesman/scp_v0.c42
-rw-r--r--sesman/scp_v1.c20
-rw-r--r--sesman/scp_v1_mng.c7
-rw-r--r--sesman/sesman.c58
-rw-r--r--sesman/sesman.h5
-rw-r--r--sesman/sesman.ini111
-rw-r--r--sesman/session.c488
-rw-r--r--sesman/session.h19
-rw-r--r--sesman/sessvc/Makefile.am6
-rw-r--r--sesman/sessvc/sessvc.c5
-rw-r--r--sesman/sig.c17
-rwxr-xr-xsesman/startwm.sh55
-rw-r--r--sesman/thread.c173
-rw-r--r--sesman/tools/Makefile.am19
-rw-r--r--sesman/tools/config.c1
-rw-r--r--sesman/tools/sesadmin.c44
-rw-r--r--sesman/tools/sesrun.c6
-rw-r--r--sesman/tools/sestest.c23
-rw-r--r--sesman/tools/tcp.c2
-rw-r--r--sesman/tools/xcon.c2
-rw-r--r--sesman/verify_user.c17
-rw-r--r--sesman/verify_user_bsd.c8
-rw-r--r--sesman/verify_user_kerberos.c14
-rw-r--r--sesman/verify_user_pam.c10
-rw-r--r--sesman/verify_user_pam_userpass.c8
-rw-r--r--sesman/xauth.c62
-rw-r--r--sesman/xauth.h (renamed from sesman/thread.h)37
-rw-r--r--tcutils/README.txt2
-rw-r--r--tcutils/moc_mainwindow.cpp104
-rw-r--r--tcutils/qrc_resources.cpp1191
-rwxr-xr-xtcutils/tcutilsbin63109 -> 0 bytes
-rw-r--r--tcutils/tcutils.pro30
-rw-r--r--tcutils/ui_mainwindow.h105
-rw-r--r--tests/.gitignore1
-rwxr-xr-xtests/gtcp_proxy/gtcp-proxybin25665 -> 0 bytes
-rw-r--r--tests/gtcp_proxy/gtcp-proxy.c6
-rw-r--r--tests/gtcp_proxy/gtcp.c36
-rw-r--r--tests/tcp_proxy/main.c24
-rw-r--r--vnc/Makefile.am14
-rw-r--r--vnc/vnc.c515
-rw-r--r--vnc/vnc.h38
-rw-r--r--vrplayer/decoderthread.cpp2
-rw-r--r--vrplayer/mainwindow.h2
-rw-r--r--xorg/.gitignore1
-rw-r--r--xorg/X11R7.6/.gitignore3
-rwxr-xr-xxorg/X11R7.6/buildx.sh94
-rw-r--r--xorg/X11R7.6/rdp/Makefile24
-rw-r--r--xorg/X11R7.6/rdp/rdp.h10
-rw-r--r--xorg/X11R7.6/rdp/rdpComposite.c12
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyFillRect.c8
-rw-r--r--xorg/X11R7.6/rdp/rdpdraw.c6
-rw-r--r--xorg/X11R7.6/rdp/rdpglyph.c4
-rw-r--r--xorg/X11R7.6/rdp/rdpinput.c44
-rw-r--r--xorg/X11R7.6/rdp/rdpkeyboardbase.c6
-rw-r--r--xorg/X11R7.6/rdp/rdpkeyboardevdev.c4
-rw-r--r--xorg/X11R7.6/rdp/rdpmain.c19
-rw-r--r--xorg/X11R7.6/rdp/rdpmisc.c4
-rw-r--r--xorg/X11R7.6/rdp/rdprandr.c176
-rw-r--r--xorg/X11R7.6/rdp/rdprandr.h3
-rw-r--r--xorg/X11R7.6/rdp/rdpup.c81
-rw-r--r--xorg/X11R7.6/rdp/rdpxv.c2
-rw-r--r--xorg/X11R7.6/x11_file_list.txt19
-rw-r--r--xorg/X11R7.6/xkeyboard-config-2.0.patch88
-rw-r--r--xorg/tests/randr/trandr.c2
-rw-r--r--xorg/tests/xdemo/bmp_parser.c2
-rw-r--r--xorg/tests/xdemo/xdemo.c2
-rw-r--r--xorg/tests/xdemo/yosemite.bmpbin1843254 -> 1843254 bytes
m---------xorgxrdp0
-rw-r--r--xrdp/Makefile.am74
-rw-r--r--[-rwxr-xr-x]xrdp/ad256.bmpbin19766 -> 19766 bytes
-rw-r--r--xrdp/lang.c22
-rw-r--r--xrdp/rdp-scan-codes.txt2
-rw-r--r--xrdp/rsakeys.ini5
-rw-r--r--[-rwxr-xr-x]xrdp/sans-10.fv1bin658956 -> 658956 bytes
-rw-r--r--xrdp/xrdp.c204
-rw-r--r--xrdp/xrdp.h28
-rw-r--r--xrdp/xrdp.ini194
-rw-r--r--[-rwxr-xr-x]xrdp/xrdp256.bmpbin49278 -> 49278 bytes
-rw-r--r--xrdp/xrdp_bitmap.c55
-rw-r--r--xrdp/xrdp_cache.c6
-rw-r--r--xrdp/xrdp_encoder.c209
-rw-r--r--xrdp/xrdp_encoder.h62
-rw-r--r--xrdp/xrdp_keyboard.ini117
-rw-r--r--xrdp/xrdp_listen.c6
-rw-r--r--xrdp/xrdp_login_wnd.c73
-rw-r--r--xrdp/xrdp_mm.c485
-rw-r--r--xrdp/xrdp_painter.c561
-rw-r--r--xrdp/xrdp_process.c57
-rw-r--r--xrdp/xrdp_region.c295
-rw-r--r--xrdp/xrdp_types.h86
-rw-r--r--xrdp/xrdp_wm.c246
-rw-r--r--xrdp/xrdpwin.c41
-rw-r--r--xrdpapi/Makefile.am27
-rw-r--r--xrdpapi/xrdpapi.c43
-rw-r--r--xrdpvr/Makefile.am25
-rw-r--r--xrdpvr/xrdpvr.c2
-rw-r--r--xup/Makefile.am14
-rw-r--r--xup/xup.c469
-rw-r--r--xup/xup.h35
296 files changed, 16121 insertions, 9803 deletions
diff --git a/.gitignore b/.gitignore
index a579d210..d3096a54 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,12 @@
*~
+*.a
aclocal.m4
AUTHORS
autom4te.cache/
ChangeLog
+compile
config_ac.h
config_ac-h.in
-config.c
config.guess
config.log
config.status
@@ -13,7 +14,10 @@ config.sub
configure
depcomp
.deps/
+genkeymap/xrdp-genkeymap
install-sh
+instfiles/pam.d/xrdp-sesman
+keygen/xrdp-keygen
*.la
.libs
libtool
@@ -22,17 +26,17 @@ ltmain.sh
Makefile
Makefile.in
missing
+mkinstalldirs
NEWS
*.o
README
+sesman/chansrv/xrdp-chansrv
+sesman/sessvc/xrdp-sessvc
+sesman/tools/xrdp-dis
+sesman/tools/xrdp-sesadmin
+sesman/tools/xrdp-sesrun
+sesman/tools/xrdp-sestest
+sesman/tools/xrdp-xcon
+sesman/xrdp-sesman
stamp-h1
-xrdp-chansrv
-xrdp-genkeymap
-xrdp-keygen
-xrdp-sesadmin
-xrdp-sesman
-xrdp-sesrun
-xrdp-sessvc
-xrdp-sestest
-xrdp-dis
xrdp/xrdp
diff --git a/.gitmodules b/.gitmodules
index 52a8a98a..281ee599 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,8 @@
[submodule "librfxcodec"]
path = librfxcodec
- url = git://github.com/neutrinolabs/librfxcodec
-[submodule "xorgxrdp"]
- path = xorgxrdp
- url = git://github.com/neutrinolabs/xorgxrdp
+ url = https://github.com/neutrinolabs/librfxcodec.git
+
+[submodule "libpainter"]
+ path = libpainter
+ url = https://github.com/neutrinolabs/libpainter.git
+ branch = devel
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..baf038ee
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,40 @@
+sudo: false # use new container
+language: c
+
+branches:
+ except: /^(gh-pages|v[0-9]\..*)/
+
+compiler:
+ - clang
+ - gcc
+ - g++
+
+addons:
+ apt:
+ packages:
+ # xrdp
+ - libpam0g-dev
+ - libjpeg-dev
+ - libfuse-dev
+ - libmp3lame-dev
+ - libx11-dev
+ - libxrandr-dev
+ - libpixman-1-dev
+ - nasm
+ # x11rdp
+ #- flex
+ #- bison
+ #- libxml2-dev
+ #- intltool
+ #- xsltproc
+ #- xutils-dev
+ #- python-libxml2
+ #- g++
+ #- xutils
+
+script:
+ # disable librfxcodec as no remotefx for v0.9.1 release
+ #- (cd librfxcodec && ./bootstrap && ./configure && make)
+ - (./bootstrap && ./configure --enable-ipv6 --enable-jpeg --enable-fuse --enable-mp3lame --enable-pixman && make && make distcheck)
+ # disable x11rdp build as it takes long time and it is to be deprecated
+ #- (cd xorg/X11R7.6 && ./buildx.sh default)
diff --git a/Coding_Style.odt b/Coding_Style.odt
deleted file mode 100644
index 23aeef12..00000000
--- a/Coding_Style.odt
+++ /dev/null
Binary files differ
diff --git a/Makefile.am b/Makefile.am
index e8905c98..6d644836 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,27 @@
-EXTRA_DIST = bootstrap COPYING design.txt faq-compile.txt faq-general.txt file-loc.txt install.txt prog_std.txt readme.txt
+ACLOCAL_AMFLAGS = -I m4
+AM_DISTCHECK_CONFIGURE_FLAGS = --without-systemdsystemunitdir
+
+EXTRA_DIST = \
+ COPYING \
+ README.md \
+ NEWS.md \
+ astyle_config.as \
+ bootstrap \
+ coding_style.md \
+ description-pak \
+ design.txt \
+ faq-compile.txt \
+ faq-general.txt \
+ file-loc.txt \
+ fontdump \
+ install.txt \
+ m4 \
+ postinstall-pak \
+ readme.txt \
+ tcutils \
+ tests \
+ vrplayer \
+ xorg
if XRDP_NEUTRINORDP
NEUTRINORDPDIR = neutrinordp
@@ -12,6 +35,18 @@ else
XRDPVRDIR =
endif
+if XRDP_PAINTER
+PAINTERDIR = libpainter
+else
+PAINTERDIR =
+endif
+
+if XRDP_RFXCODEC
+RFXCODECDIR = librfxcodec
+else
+RFXCODECDIR =
+endif
+
SUBDIRS = \
common \
vnc \
@@ -20,6 +55,8 @@ SUBDIRS = \
mc \
$(NEUTRINORDPDIR) \
libxrdp \
+ $(PAINTERDIR) \
+ $(RFXCODECDIR) \
xrdp \
sesman \
keygen \
@@ -27,4 +64,5 @@ SUBDIRS = \
instfiles \
genkeymap \
xrdpapi \
+ pkgconfig \
$(XRDPVRDIR)
diff --git a/NEWS.md b/NEWS.md
new file mode 100644
index 00000000..f98e76cb
--- /dev/null
+++ b/NEWS.md
@@ -0,0 +1,25 @@
+# Release notes for xrdp v0.9.1 (2016/12/21)
+## New features
+ * New xorgxrdp backend using existing Xorg with additional modules
+ * Improvements to X11rdp backend
+ * Support for IPv6 (disabled by default)
+ * Initial support for RemoteFX Codec (disabled by default)
+ * Support for TLS security layer (preferred over RDP layer if supported by the client)
+ * Support for disabling deprecated SSLv3 protocol and for selecting custom cipher suites in xrdp.ini
+ * Support for bidirectional fastpath (enabled in both directions by default)
+ * Support clients that don't support drawing orders, such as MS RDP client for Android, ChromeRDP (disabled by default)
+ * More configurable login screen
+ * Support for new virtual channels:
+ * rdpdr: device redirection
+ * rdpsnd: audio output
+ * cliprdr: clipboard
+ * xrdpvr: xrdp video redirection channel (can be used along with NeutrinoRDP client)
+ * Support for disabling virtual channels globally or by session type
+ * Allow to specify the path for backends (Xorg, X11rdp, Xvnc)
+ * Added files for systemd support
+ * Multi-monitor support
+ * xrdp-chansrv stroes logs in `${XDG_DATA_HOME}/xrdp` now
+
+## Security fixes
+ * User's password could be recovered from the Xvnc password file
+ * X11 authentication was not used
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..07f64e0a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,126 @@
+[![Build Status](https://travis-ci.org/neutrinolabs/xrdp.svg?branch=devel)](https://travis-ci.org/neutrinolabs/xrdp)
+[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp)
+![Apache-License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)
+
+*Current Version:* 0.9.1
+
+# xrdp - an open source RDP server
+
+## Overview
+
+**xrdp** provides a graphical login to remote machines using Microsoft
+Remote Desktop Protocol (RDP). xrdp accepts connections from a variety of
+RDP clients: FreeRDP, rdesktop, NeutrinoRDP and Microsoft Remote Desktop
+Client (for Windows, Mac OS, iOS and Android).
+
+RDP transport is encrypted using TLS by default.
+
+![demo](https://github.com/neutrinolabs/xrdp/raw/gh-pages/xrdp_demo.gif)
+
+## Features
+
+### Remote Desktop Access
+
+ * Connect to a Linux desktop using RDP from anywhere (requires
+ [xorgxrdp](https://github.com/neutrinolabs/xorgxrdp) Xorg module)
+ * Reconnect to an existing session
+ * Session resizing
+ * RDP/VNC proxy (connect to another RDP/VNC server via xrdp)
+
+### Access to Remote Resources
+ * two-way clipboard transfer (text, bitmap, file)
+ * audio redirection
+ * drive redirection (mount local client drives on remote machine)
+
+## Quick Start
+
+Most Linux distributions should distribute the latest release of xrdp in their
+repository. You would need xrdp and xorgxrdp packages for the best
+experience. It is recommended that xrdp depends on xorgxrdp, so it should
+be sufficient to install xrdp. If xorgxrdp is not provided, use Xvnc
+server.
+
+### Ubuntu / Debian
+```bash
+apt-get install xrdp
+```
+
+### RedHat / CentOS / Fedora
+```bash
+yum install xrdp
+```
+
+## Environment
+
+**xrdp** primarily targets to GNU/Linux. Tested on x86, x86_64, SPARC and
+PowerPC.
+
+xorgxrdp and RemoteFX Codec have special optimization for x86 and x86_64 using
+SIMD instructions.
+
+FreeBSD is not a primary target of xrdp. It is working on FreeBSD except
+for the drive redirection feature.
+
+Other operating systems such as Mac OS are not supported so far, but we
+welcome your contributions.
+
+## Compiling
+
+See also https://github.com/neutrinolabs/xrdp/wiki#building-from-sources
+
+### Prerequisites
+
+To compile xrdp from the packaged sources, you need basic build tools - a
+compiler (**gcc** or **clang**) and the **make** program. Additionally,
+you would need **openssl-devel**, **pam-devel**, **libX11-devel**,
+**libXfixes-devel**, **libXrandr-devel**. More additional software would
+be needed depending on your configuration.
+
+To compile xrdp from a checked out git repository, you would additionally
+need **autoconf**, **automake**, **libtool** and **pkgconfig**.
+
+### Get the source and build it
+
+If compiling from the packaged source, unpack the tarball and change to the
+resulting directory.
+
+If compiling from a checked out repository, please make sure you've got the submodules
+cloned too (use `git clone --recursive https://github.com/neutrinolabs/xrdp`)
+
+Then run following commands to compile and install xrdp:
+```bash
+./bootstrap
+./configure
+make
+sudo make install
+```
+
+## Directory Structure
+
+```
+xrdp
+├── common ------ common code
+├── docs -------- documentation
+├── fontdump ---- font dump for Windows
+├── genkeymap --- keymap generator
+├── instfiles --- installable data file
+├── keygen ------ xrdp RSA key pair generator
+├── libpainter -- painter library
+├── librfxcodec - RFX codec library
+├── libxrdp ----- core RDP protocol implementation
+├── m4 ---------- Autoconf macros
+├── mc ---------- media center module
+├── neutrinordp - RDP client module for proxying RDP connections using NeutrinoRDP
+├── pkgconfig --- pkg-config configuration
+├── rdp --------- RDP client module for connecting to another RDP server
+├── sesman ------ session manager for xrdp
+├── tcutils ----- QT based utility program for thin clients
+├── tests ------- tests for the code
+├── vnc --------- VNC client module for xrdp
+├── vrplayer ---- QT player redirecting video/audio to clients over xrdpvr channel
+├── xorg -------- X11rdp, an Xorg backend for xrdp
+├── xrdp -------- main server code
+├── xrdpapi ----- virtual channel API
+├── xrdpvr ------ API for playing media over RDP
+└── xup --------- X11rdp and xorgxrdp client module
+```
diff --git a/bootstrap b/bootstrap
index 61de66ee..be61972e 100755
--- a/bootstrap
+++ b/bootstrap
@@ -14,7 +14,7 @@ then
exit 1
fi
-which libtool
+which libtool || which libtoolize
if ! test $? -eq 0
then
echo "error, install libtool"
@@ -28,10 +28,4 @@ then
exit 1
fi
-touch configure.ac
-touch NEWS
-touch AUTHORS
-touch README
-touch ChangeLog
-ln -s ../config.c $PWD/sesman/tools/config.c
autoreconf -fvi
diff --git a/coding_style.md b/coding_style.md
new file mode 100644
index 00000000..cf096ac8
--- /dev/null
+++ b/coding_style.md
@@ -0,0 +1,210 @@
+XRdp Coding Style
+=================
+
+The coding style used by XRdp is described below.
+
+The XRdp project uses astyle (artistic style) to format the code. Astyle
+requires a configuration file that describes how you want your code
+formatted. This file is present in the XRdp root directory and is named
+`astyle_config.as`.
+
+Here is how we run the astyle command:
+
+ astyle --options=/path/to/file/astyle_config.as "*.c"
+
+This coding style is a work in progress and is still evolving.
+
+
+Language Standard
+-----------------
+
+Try to make all code compile with both C and C++ compiler. C++ is more
+strict, which makes the code safer.
+
+
+Indentation
+-----------
+
+* 4 spaces per indent
+* No tabs for any indents
+
+☞
+
+ if (fd < 0)
+ {
+ return -1;
+ }
+
+
+Line wrapping
+-------------
+
+* Keep lines not longer than 80 chars
+* Align wrapped argument to the first argument
+
+☞
+
+ log_message("connection aborted: error %d",
+ ret);
+
+
+Variable names
+--------------
+
+* Use lowercase with underscores as needed
+* Don't use camelCase
+* Preprocessor constants should be uppercase
+
+☞
+
+ #define BUF_SIZE 1024
+ int fd;
+ int bytes_in_stream;
+
+
+Variable declaration
+--------------------
+
+* Each variable is declared on a separate line
+
+☞
+
+ int i;
+ int j;
+
+
+Whitespace
+----------
+
+* Use blank lines to group statements
+* Use at most one empty line between statements
+* For pointers and references, use a single space before * or & but not after
+* Use one space after a cast
+* No space before square brackets
+
+☞
+
+ char *cptr;
+ int *iptr;
+ cptr = (char *) malloc(1024);
+
+ write(fd, &buf[12], 16);
+
+
+Function declarations
+---------------------
+
+* Use newline before function name
+
+☞
+
+ static int
+ value_ok(int val)
+ {
+ return (val >= 0);
+ }
+
+
+Braces
+------
+
+* Opening brace is always on a separate line
+* Align braces with the line preceding the opening brace
+
+☞
+
+ struct stream
+ {
+ int flags;
+ char *data;
+ };
+
+ void
+ process_data(struct stream *s)
+ {
+ if (stream == NULL)
+ {
+ return;
+ }
+ }
+
+
+`if` statements
+---------------
+
+* Always use braces
+* Put both braces on separate lines
+
+☞
+
+ if (val <= 0xff)
+ {
+ out_uint8(s, val);
+ }
+ else if (val <= 0xffff)
+ {
+ out_uint16_le(s, val);
+ }
+ else
+ {
+ out_uint32_le(s, val);
+ }
+
+
+`for` statements
+----------------
+
+* Always use braces
+* Put both braces on separate lines
+
+☞
+
+ for (i = 0; i < 10; i++)
+ {
+ printf("i = %d\n", i);
+ }
+
+
+`while` and `do while` statements
+---------------------------------
+
+* Always use braces
+* `while` after the closing brace is on the same line
+
+☞
+
+ while (cptr)
+ {
+ cptr—;
+ }
+
+ do
+ {
+ cptr--;
+ } while (cptr);
+
+
+`switch` statements
+-------------------
+
+* Indent `case` once
+* Indent statements under `case` one more time
+* Put both braces on separate lines
+
+☞
+
+ switch (cmd)
+ {
+ case READ:
+ read(fd, buf, 1024);
+ break;
+
+ default:
+ printf("bad cmd\n");
+ }
+
+Comments
+--------
+
+Use /* */ for comments
+Don't use //
diff --git a/common/Makefile.am b/common/Makefile.am
index 8c7aa62c..1bc5851f 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -1,47 +1,57 @@
-EXTRA_DIST = \
- arch.h \
- d3des.h \
- defines.h \
- file.h \
- file_loc.h \
- list.h \
- list16.h \
- fifo.h \
- log.h \
- os_calls.h \
- os_calls.h \
- parse.h \
- rail.h \
- ssl_calls.h \
- thread_calls.h \
- trans.h \
+if XRDP_PIXMAN
+ PIXMAN_SOURCES =
+else
+ PIXMAN_SOURCES = pixman-region16.c pixman-region.h
+endif
+
+EXTRA_DIST = pixman-region.c
+
+include_HEADERS = \
xrdp_client_info.h \
xrdp_constants.h \
- xrdp_rail.h
+ xrdp_rail.h
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
-DXRDP_LOG_PATH=\"${localstatedir}/log\"
-lib_LTLIBRARIES = \
+AM_CFLAGS = $(OPENSSL_CFLAGS)
+
+module_LTLIBRARIES = \
libcommon.la
libcommon_la_SOURCES = \
- d3des.c \
+ arch.h \
+ crc16.h \
+ defines.h \
+ fifo.c \
+ fifo.h \
file.c \
+ file.h \
+ file_loc.h \
list.c \
+ list.h \
list16.c \
- fifo.c \
+ list16.h \
log.c \
+ log.h \
os_calls.c \
+ os_calls.h \
+ os_calls.h \
+ parse.h \
+ rail.h \
ssl_calls.c \
+ ssl_calls.h \
thread_calls.c \
- trans.c
+ thread_calls.h \
+ trans.c \
+ trans.h \
+ $(PIXMAN_SOURCES)
libcommon_la_LIBADD = \
- -lcrypto \
- -lssl \
- -lpthread
+ -lpthread \
+ $(OPENSSL_LIBS) \
+ $(DLOPEN_LIBS)
diff --git a/common/arch.h b/common/arch.h
index 14ab9d7d..7070d6ae 100644
--- a/common/arch.h
+++ b/common/arch.h
@@ -19,10 +19,14 @@
#if !defined(ARCH_H)
#define ARCH_H
+#if defined(HAVE_CONFIG_H)
+#include "config_ac.h"
+#endif
+
/* you can define L_ENDIAN or B_ENDIAN and NEED_ALIGN or NO_NEED_ALIGN
in the makefile to override */
-/* check endianess */
+/* check endianness */
#if !(defined(L_ENDIAN) || defined(B_ENDIAN))
#if !defined(__BYTE_ORDER) && defined(__linux__)
#include <endian.h>
@@ -109,7 +113,6 @@ typedef __int64 tbus;
#else
typedef long tbus;
#endif
-typedef tbus thandle;
typedef tbus tintptr;
/* wide char, socket */
#if defined(_WIN32)
@@ -125,4 +128,22 @@ typedef signed long long tsi64;
#endif
#endif /* DEFINED_Ts */
+/* format string verification */
+#if defined(HAVE_FUNC_ATTRIBUTE_FORMAT)
+#define printflike(arg_format, arg_first_check) \
+ __attribute__((__format__(__printf__, arg_format, arg_first_check)))
+#else
+#define printflike(arg_format, arg_first_check)
+#endif
+
+/* module interface */
+#ifdef __cplusplus
+extern "C" {
+#endif
+ tintptr mod_init();
+ int mod_exit(tintptr);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/common/d3des.c b/common/d3des.c
deleted file mode 100644
index 16ee7cde..00000000
--- a/common/d3des.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * This is D3DES (V5.09) by Richard Outerbridge with the double and
- * triple-length support removed for use in VNC. Also the bytebit[] array
- * has been reversed so that the most significant bit in each byte of the
- * key is ignored, not the least significant.
- *
- * These changes are:
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* D3DES (V5.09) -
- *
- * A portable, public domain, version of the Data Encryption Standard.
- *
- * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
- * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
- * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
- * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
- * for humouring me on.
- *
- * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
- * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
- */
-
-#include "d3des.h"
-
-static void scrunch(unsigned char *, unsigned long *);
-static void unscrun(unsigned long *, unsigned char *);
-static void desfunc(unsigned long *, unsigned long *);
-static void cookey(unsigned long *);
-
-static unsigned long KnL[32] = { 0L };
-/*
-static unsigned long KnR[32] = { 0L };
-static unsigned long Kn3[32] = { 0L };
-static unsigned char Df_Key[24] = {
- 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
- 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
- 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
-*/
-
-static unsigned short bytebit[8] =
-{
- 01, 02, 04, 010, 020, 040, 0100, 0200
-};
-
-static unsigned long bigbyte[24] =
-{
- 0x800000L, 0x400000L, 0x200000L, 0x100000L,
- 0x80000L, 0x40000L, 0x20000L, 0x10000L,
- 0x8000L, 0x4000L, 0x2000L, 0x1000L,
- 0x800L, 0x400L, 0x200L, 0x100L,
- 0x80L, 0x40L, 0x20L, 0x10L,
- 0x8L, 0x4L, 0x2L, 0x1L
-};
-
-/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
-
-static unsigned char pc1[56] =
-{
- 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
- 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
- 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
- 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
-};
-
-static unsigned char totrot[16] =
-{
- 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
-};
-
-static unsigned char pc2[48] =
-{
- 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
- 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
- 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
- 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
-};
-
-/* Thanks to James Gillogly & Phil Karn! */
-void rfbDesKey(unsigned char *key, int edf)
-{
- register int i, j, l, m, n;
- unsigned char pc1m[56], pcr[56];
- unsigned long kn[32];
-
- for ( j = 0; j < 56; j++ )
- {
- l = pc1[j];
- m = l & 07;
- pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
- }
-
- for ( i = 0; i < 16; i++ )
- {
- if ( edf == DE1 )
- {
- m = (15 - i) << 1;
- }
- else
- {
- m = i << 1;
- }
-
- n = m + 1;
- kn[m] = kn[n] = 0L;
-
- for ( j = 0; j < 28; j++ )
- {
- l = j + totrot[i];
-
- if ( l < 28 )
- {
- pcr[j] = pc1m[l];
- }
- else
- {
- pcr[j] = pc1m[l - 28];
- }
- }
-
- for ( j = 28; j < 56; j++ )
- {
- l = j + totrot[i];
-
- if ( l < 56 )
- {
- pcr[j] = pc1m[l];
- }
- else
- {
- pcr[j] = pc1m[l - 28];
- }
- }
-
- for ( j = 0; j < 24; j++ )
- {
- if ( pcr[pc2[j]] )
- {
- kn[m] |= bigbyte[j];
- }
-
- if ( pcr[pc2[j + 24]] )
- {
- kn[n] |= bigbyte[j];
- }
- }
- }
-
- cookey(kn);
- return;
-}
-
-static void cookey(register unsigned long *raw1)
-{
- register unsigned long *cook, *raw0;
- unsigned long dough[32];
- register int i;
-
- cook = dough;
-
- for ( i = 0; i < 16; i++, raw1++ )
- {
- raw0 = raw1++;
- *cook = (*raw0 & 0x00fc0000L) << 6;
- *cook |= (*raw0 & 0x00000fc0L) << 10;
- *cook |= (*raw1 & 0x00fc0000L) >> 10;
- *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
- *cook = (*raw0 & 0x0003f000L) << 12;
- *cook |= (*raw0 & 0x0000003fL) << 16;
- *cook |= (*raw1 & 0x0003f000L) >> 4;
- *cook++ |= (*raw1 & 0x0000003fL);
- }
-
- rfbUseKey(dough);
- return;
-}
-
-void rfbCPKey(register unsigned long *into)
-{
- register unsigned long *from, *endp;
-
- from = KnL, endp = &KnL[32];
-
- while ( from < endp )
- {
- *into++ = *from++;
- }
-
- return;
-}
-
-void rfbUseKey(register unsigned long *from)
-{
- register unsigned long *to, *endp;
-
- to = KnL, endp = &KnL[32];
-
- while ( to < endp )
- {
- *to++ = *from++;
- }
-
- return;
-}
-
-void rfbDes(unsigned char *inblock, unsigned char *outblock)
-{
- unsigned long work[2];
-
- scrunch(inblock, work);
- desfunc(work, KnL);
- unscrun(work, outblock);
- return;
-}
-
-static void scrunch(register unsigned char *outof, register unsigned long *into)
-{
- *into = (*outof++ & 0xffL) << 24;
- *into |= (*outof++ & 0xffL) << 16;
- *into |= (*outof++ & 0xffL) << 8;
- *into++ |= (*outof++ & 0xffL);
- *into = (*outof++ & 0xffL) << 24;
- *into |= (*outof++ & 0xffL) << 16;
- *into |= (*outof++ & 0xffL) << 8;
- *into |= (*outof & 0xffL);
- return;
-}
-
-static void unscrun(register unsigned long *outof, register unsigned char *into)
-{
- *into++ = (unsigned char)((*outof >> 24) & 0xffL);
- *into++ = (unsigned char)((*outof >> 16) & 0xffL);
- *into++ = (unsigned char)((*outof >> 8) & 0xffL);
- *into++ = (unsigned char)( *outof++ & 0xffL);
- *into++ = (unsigned char)((*outof >> 24) & 0xffL);
- *into++ = (unsigned char)((*outof >> 16) & 0xffL);
- *into++ = (unsigned char)((*outof >> 8) & 0xffL);
- *into = (unsigned char)( *outof & 0xffL);
- return;
-}
-
-static unsigned long SP1[64] =
-{
- 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
- 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
- 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
- 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
- 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
- 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
- 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
- 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
- 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
- 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
- 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
- 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
- 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
- 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
- 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
- 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L
-};
-
-static unsigned long SP2[64] =
-{
- 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
- 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
- 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
- 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
- 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
- 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
- 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
- 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
- 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
- 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
- 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
- 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
- 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
- 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
- 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
- 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L
-};
-
-static unsigned long SP3[64] =
-{
- 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
- 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
- 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
- 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
- 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
- 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
- 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
- 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
- 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
- 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
- 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
- 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
- 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
- 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
- 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
- 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L
-};
-
-static unsigned long SP4[64] =
-{
- 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
- 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
- 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
- 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
- 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
- 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
- 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
- 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
- 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
- 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
- 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
- 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
- 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
- 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
- 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
- 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L
-};
-
-static unsigned long SP5[64] =
-{
- 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
- 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
- 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
- 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
- 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
- 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
- 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
- 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
- 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
- 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
- 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
- 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
- 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
- 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
- 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
- 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L
-};
-
-static unsigned long SP6[64] =
-{
- 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
- 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
- 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
- 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
- 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
- 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
- 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
- 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
- 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
- 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
- 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
- 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
- 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
- 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
- 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
- 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L
-};
-
-static unsigned long SP7[64] =
-{
- 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
- 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
- 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
- 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
- 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
- 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
- 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
- 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
- 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
- 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
- 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
- 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
- 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
- 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
- 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
- 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L
-};
-
-static unsigned long SP8[64] =
-{
- 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
- 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
- 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
- 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
- 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
- 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
- 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
- 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
- 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
- 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
- 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
- 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
- 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
- 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
- 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
- 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L
-};
-
-static void desfunc(register unsigned long *block, register unsigned long *keys)
-{
- register unsigned long fval, work, right, leftt;
- register int round;
-
- leftt = block[0];
- right = block[1];
- work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
- right ^= work;
- leftt ^= (work << 4);
- work = ((leftt >> 16) ^ right) & 0x0000ffffL;
- right ^= work;
- leftt ^= (work << 16);
- work = ((right >> 2) ^ leftt) & 0x33333333L;
- leftt ^= work;
- right ^= (work << 2);
- work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
- leftt ^= work;
- right ^= (work << 8);
- right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
- work = (leftt ^ right) & 0xaaaaaaaaL;
- leftt ^= work;
- right ^= work;
- leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
-
- for ( round = 0; round < 8; round++ )
- {
- work = (right << 28) | (right >> 4);
- work ^= *keys++;
- fval = SP7[ work & 0x3fL];
- fval |= SP5[(work >> 8) & 0x3fL];
- fval |= SP3[(work >> 16) & 0x3fL];
- fval |= SP1[(work >> 24) & 0x3fL];
- work = right ^ *keys++;
- fval |= SP8[ work & 0x3fL];
- fval |= SP6[(work >> 8) & 0x3fL];
- fval |= SP4[(work >> 16) & 0x3fL];
- fval |= SP2[(work >> 24) & 0x3fL];
- leftt ^= fval;
- work = (leftt << 28) | (leftt >> 4);
- work ^= *keys++;
- fval = SP7[ work & 0x3fL];
- fval |= SP5[(work >> 8) & 0x3fL];
- fval |= SP3[(work >> 16) & 0x3fL];
- fval |= SP1[(work >> 24) & 0x3fL];
- work = leftt ^ *keys++;
- fval |= SP8[ work & 0x3fL];
- fval |= SP6[(work >> 8) & 0x3fL];
- fval |= SP4[(work >> 16) & 0x3fL];
- fval |= SP2[(work >> 24) & 0x3fL];
- right ^= fval;
- }
-
- right = (right << 31) | (right >> 1);
- work = (leftt ^ right) & 0xaaaaaaaaL;
- leftt ^= work;
- right ^= work;
- leftt = (leftt << 31) | (leftt >> 1);
- work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
- right ^= work;
- leftt ^= (work << 8);
- work = ((leftt >> 2) ^ right) & 0x33333333L;
- right ^= work;
- leftt ^= (work << 2);
- work = ((right >> 16) ^ leftt) & 0x0000ffffL;
- leftt ^= work;
- right ^= (work << 16);
- work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
- leftt ^= work;
- right ^= (work << 4);
- *block++ = right;
- *block = leftt;
- return;
-}
-
-/* Validation sets:
- *
- * Single-length key, single-length plaintext -
- * Key : 0123 4567 89ab cdef
- * Plain : 0123 4567 89ab cde7
- * Cipher : c957 4425 6a5e d31d
- *
- * Double-length key, single-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
- * Plain : 0123 4567 89ab cde7
- * Cipher : 7f1d 0a77 826b 8aff
- *
- * Double-length key, double-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
- * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
- * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
- *
- * Triple-length key, single-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
- * Plain : 0123 4567 89ab cde7
- * Cipher : de0b 7c06 ae5e 0ed5
- *
- * Triple-length key, double-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
- * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
- * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
- *
- * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
- **********************************************************************/
diff --git a/common/d3des.h b/common/d3des.h
deleted file mode 100644
index e3761ca2..00000000
--- a/common/d3des.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef D3DES_H
-#define D3DES_H
-
-/*
- * This is D3DES (V5.09) by Richard Outerbridge with the double and
- * triple-length support removed for use in VNC.
- *
- * These changes are:
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* d3des.h -
- *
- * Headers and defines for d3des.c
- * Graven Imagery, 1992.
- *
- * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
- * (GEnie : OUTER; CIS : [71755,204])
- */
-
-#define EN0 0 /* MODE == encrypt */
-#define DE1 1 /* MODE == decrypt */
-
-extern void rfbDesKey(unsigned char *, int);
-/* hexkey[8] MODE
- * Sets the internal key register according to the hexadecimal
- * key contained in the 8 bytes of hexkey, according to the DES,
- * for encryption or decryption according to MODE.
- */
-
-extern void rfbUseKey(unsigned long *);
-/* cookedkey[32]
- * Loads the internal key register with the data in cookedkey.
- */
-
-extern void rfbCPKey(unsigned long *);
-/* cookedkey[32]
- * Copies the contents of the internal key register into the storage
- * located at &cookedkey[0].
- */
-
-extern void rfbDes(unsigned char *, unsigned char *);
-/* from[8] to[8]
- * Encrypts/Decrypts (according to the key currently loaded in the
- * internal key register) one block of eight bytes at address 'from'
- * into the block at address 'to'. They can be the same.
- */
-
-/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
- ********************************************************************/
-
-#endif
diff --git a/common/file.c b/common/file.c
index b51a37cc..66d781f7 100644
--- a/common/file.c
+++ b/common/file.c
@@ -26,6 +26,48 @@
#define FILE_MAX_LINE_BYTES 2048
+static int APP_CC
+file_read_ini_line(struct stream *s, char *text, int text_bytes);
+
+/*****************************************************************************/
+/* look up for a section name within str (i.e. pattern [section_name])
+ * if a section name is found, this function return 1 and copy the section
+ * inplace of str. */
+static int APP_CC
+line_lookup_for_section_name(char *str, int str_bytes)
+{
+ int name_index_start;
+ int index;
+ char c;
+
+ name_index_start = -1;
+ index = 0;
+ while ((c = str[index]) != 0)
+ {
+ if (c == '[')
+ {
+ name_index_start = index + 1;
+ }
+ else if (c == ']' && name_index_start > 0)
+ {
+ if (name_index_start + index >= str_bytes)
+ {
+ return 0;
+ }
+ for (index = index - name_index_start; index > 0; index--)
+ {
+ str[0] = str[name_index_start];
+ str++;
+ }
+ str[0] = 0;
+ return 1;
+ }
+ ++index;
+ }
+ return 0;
+}
+
+
/*****************************************************************************/
/* returns error
returns 0 if everything is ok
@@ -35,17 +77,11 @@ l_file_read_sections(int fd, int max_file_size, struct list *names)
{
struct stream *s;
char text[FILE_MAX_LINE_BYTES];
- char c;
- int in_it;
- int in_it_index;
int len;
- int index;
int rv;
rv = 0;
g_file_seek(fd, 0);
- in_it_index = 0;
- in_it = 0;
g_memset(text, 0, FILE_MAX_LINE_BYTES);
list_clear(names);
make_stream(s);
@@ -55,26 +91,11 @@ l_file_read_sections(int fd, int max_file_size, struct list *names)
if (len > 0)
{
s->end = s->p + len;
-
- for (index = 0; index < len; index++)
+ while (file_read_ini_line(s, text, FILE_MAX_LINE_BYTES) == 0)
{
- in_uint8(s, c);
-
- if (c == '[')
- {
- in_it = 1;
- }
- else if (c == ']')
+ if (line_lookup_for_section_name(text, FILE_MAX_LINE_BYTES) != 0)
{
list_add_item(names, (tbus)g_strdup(text));
- in_it = 0;
- in_it_index = 0;
- g_memset(text, 0, FILE_MAX_LINE_BYTES);
- }
- else if (in_it)
- {
- text[in_it_index] = c;
- in_it_index++;
}
}
}
@@ -88,15 +109,17 @@ l_file_read_sections(int fd, int max_file_size, struct list *names)
}
/*****************************************************************************/
-/* returns error */
+/* Read a line in the stream 's', removing comments.
+ * returns error
+ * returns 0 if everything is ok
+ * returns 1 if problem reading file */
static int APP_CC
-file_read_line(struct stream *s, char *text, int text_bytes)
+file_read_ini_line(struct stream *s, char *text, int text_bytes)
{
int i;
int skip_to_end;
int at_end;
char c;
- char *hold;
skip_to_end = 0;
@@ -105,7 +128,6 @@ file_read_line(struct stream *s, char *text, int text_bytes)
return 1;
}
- hold = s->p;
i = 0;
in_uint8(s, c);
@@ -163,15 +185,10 @@ file_read_line(struct stream *s, char *text, int text_bytes)
text[i] = 0;
- if (text[0] == '[')
- {
- s->p = hold;
- return 1;
- }
-
return 0;
}
+
/*****************************************************************************/
/* returns error */
static int APP_CC
@@ -227,11 +244,7 @@ l_file_read_section(int fd, int max_file_size, const char *section,
char *name;
char *value;
char *lvalue;
- char c;
- int in_it;
- int in_it_index;
int len;
- int index;
int file_size;
data = (char *) g_malloc(FILE_MAX_LINE_BYTES * 3, 0);
@@ -241,8 +254,6 @@ l_file_read_section(int fd, int max_file_size, const char *section,
file_size = 32 * 1024; /* 32 K file size limit */
g_file_seek(fd, 0);
- in_it_index = 0;
- in_it = 0;
g_memset(text, 0, FILE_MAX_LINE_BYTES);
list_clear(names);
list_clear(values);
@@ -253,36 +264,20 @@ l_file_read_section(int fd, int max_file_size, const char *section,
if (len > 0)
{
s->end = s->p + len;
-
- for (index = 0; index < len; index++)
+ while (file_read_ini_line(s, text, FILE_MAX_LINE_BYTES) == 0)
{
- if (!s_check_rem(s, 1))
- {
- break;
- }
- in_uint8(s, c);
- if ((c == '#') || (c == ';'))
- {
- if (file_read_line(s, text, FILE_MAX_LINE_BYTES) != 0)
- {
- break;
- }
- in_it = 0;
- in_it_index = 0;
- g_memset(text, 0, FILE_MAX_LINE_BYTES);
- continue;
- }
- if (c == '[')
- {
- in_it = 1;
- }
- else if (c == ']')
+ if (line_lookup_for_section_name(text, FILE_MAX_LINE_BYTES) != 0)
{
if (g_strcasecmp(section, text) == 0)
{
- file_read_line(s, text, FILE_MAX_LINE_BYTES);
- while (file_read_line(s, text, FILE_MAX_LINE_BYTES) == 0)
+ while (file_read_ini_line(s, text,
+ FILE_MAX_LINE_BYTES) == 0)
{
+ if (line_lookup_for_section_name(text, FILE_MAX_LINE_BYTES) != 0)
+ {
+ break;
+ }
+
if (g_strlen(text) > 0)
{
file_split_name_value(text, name, value);
@@ -307,27 +302,14 @@ l_file_read_section(int fd, int max_file_size, const char *section,
}
}
}
-
free_stream(s);
g_free(data);
return 0;
}
-
- in_it = 0;
- in_it_index = 0;
- g_memset(text, 0, FILE_MAX_LINE_BYTES);
- }
- else if (in_it)
- {
- text[in_it_index] = c;
- in_it_index++;
- if (in_it_index >= FILE_MAX_LINE_BYTES)
- {
- break;
- }
}
}
}
+
free_stream(s);
g_free(data);
return 1;
@@ -346,7 +328,7 @@ file_read_sections(int fd, struct list *names)
/*****************************************************************************/
/* return error */
-/* this function should be prefered over file_read_sections because it can
+/* this function should be preferred over file_read_sections because it can
read any file size */
int APP_CC
file_by_name_read_sections(const char *file_name, struct list *names)
@@ -362,7 +344,7 @@ file_by_name_read_sections(const char *file_name, struct list *names)
return 1;
}
- fd = g_file_open(file_name);
+ fd = g_file_open_ex(file_name, 1, 0, 0, 0);
if (fd < 0)
{
@@ -386,7 +368,7 @@ file_read_section(int fd, const char *section,
/*****************************************************************************/
/* return error */
-/* this function should be prefered over file_read_section because it can
+/* this function should be preferred over file_read_section because it can
read any file size */
int APP_CC
file_by_name_read_section(const char *file_name, const char *section,
@@ -403,7 +385,7 @@ file_by_name_read_section(const char *file_name, const char *section,
return 1;
}
- fd = g_file_open(file_name);
+ fd = g_file_open_ex(file_name, 1, 0, 0, 0);
if (fd < 0)
{
diff --git a/common/file_loc.h b/common/file_loc.h
index 7389a1ed..8f5146cb 100644
--- a/common/file_loc.h
+++ b/common/file_loc.h
@@ -37,8 +37,8 @@
#define XRDP_SHARE_PATH "/usr/local/share/xrdp"
#endif
-#if !defined(XRDP_LIB_PATH)
-#define XRDP_LIB_PATH "/usr/local/lib/xrdp"
+#if !defined(XRDP_MODULE_PATH)
+#define XRDP_MODULE_PATH "/usr/local/lib/xrdp"
#endif
#if !defined(XRDP_LOG_PATH)
diff --git a/common/list.c b/common/list.c
index 9fde1f6f..47b15737 100644
--- a/common/list.c
+++ b/common/list.c
@@ -82,7 +82,7 @@ list_add_item(struct list *self, tbus item)
/*****************************************************************************/
tbus APP_CC
-list_get_item(struct list *self, int index)
+list_get_item(const struct list *self, int index)
{
if (index < 0 || index >= self->count)
{
@@ -192,7 +192,7 @@ list_insert_item(struct list *self, int index, tbus item)
/*****************************************************************************/
/* append one list to another using strdup for each item in the list */
-/* begins copy at start_index, a zero based index on the soure list */
+/* begins copy at start_index, a zero based index on the source list */
void APP_CC
list_append_list_strdup(struct list *self, struct list *dest, int start_index)
{
@@ -221,6 +221,6 @@ list_dump_items(struct list *self)
for (index = 0; index < self->count; index++)
{
- g_writeln("%d: %s", index, list_get_item(self, index));
+ g_writeln("%d: 0x%lx", index, list_get_item(self, index));
}
}
diff --git a/common/list.h b/common/list.h
index cdc545a0..146aab11 100644
--- a/common/list.h
+++ b/common/list.h
@@ -40,7 +40,7 @@ list_delete(struct list* self);
void APP_CC
list_add_item(struct list* self, tintptr item);
tintptr APP_CC
-list_get_item(struct list* self, int index);
+list_get_item(const struct list *self, int index);
void APP_CC
list_clear(struct list* self);
int APP_CC
diff --git a/common/log.c b/common/log.c
index 97053178..86935acd 100644
--- a/common/log.c
+++ b/common/log.c
@@ -59,6 +59,13 @@ internal_log_file_open(const char *fname)
S_IRUSR | S_IWUSR);
}
+#ifdef FD_CLOEXEC
+ if (ret != -1)
+ {
+ fcntl(ret, F_SETFD, FD_CLOEXEC);
+ }
+#endif
+
return ret;
}
@@ -142,7 +149,7 @@ internal_log_start(struct log_config *l_cfg)
return ret;
}
- /* if progname is NULL, we ureturn error */
+ /* if progname is NULL, we return error */
if (0 == l_cfg->program_name)
{
g_writeln("program_name not properly assigned");
@@ -186,7 +193,7 @@ internal_log_end(struct log_config *l_cfg)
/* closing log file */
log_message(LOG_LEVEL_ALWAYS, "shutting down log subsystem...");
- if (0 > l_cfg->fd)
+ if (-1 != l_cfg->fd)
{
/* closing logfile... */
g_file_close(l_cfg->fd);
@@ -205,12 +212,6 @@ internal_log_end(struct log_config *l_cfg)
l_cfg->log_file = 0;
}
- if (0 != l_cfg->program_name)
- {
- g_free(l_cfg->program_name);
- l_cfg->program_name = 0;
- }
-
ret = LOG_STARTUP_OK;
return ret;
}
@@ -221,7 +222,7 @@ internal_log_end(struct log_config *l_cfg)
* @return
*/
enum logLevels DEFAULT_CC
-internal_log_text2level(char *buf)
+internal_log_text2level(const char *buf)
{
if (0 == g_strcasecmp(buf, "0") ||
0 == g_strcasecmp(buf, "core"))
@@ -329,7 +330,7 @@ internal_config_read_logging(int file, struct log_config *lc,
list_clear(param_n);
/* setting defaults */
- lc->program_name = g_strdup(applicationName);
+ lc->program_name = applicationName;
lc->log_file = 0;
lc->fd = 0;
lc->log_level = LOG_LEVEL_DEBUG;
@@ -394,7 +395,7 @@ enum logReturns DEFAULT_CC
internalInitAndAllocStruct(void)
{
enum logReturns ret = LOG_GENERAL_ERROR;
- g_staticLogConfig = g_malloc(sizeof(struct log_config), 1);
+ g_staticLogConfig = g_new0(struct log_config, 1);
if (g_staticLogConfig != NULL)
{
@@ -448,7 +449,7 @@ log_start_from_param(const struct log_config *iniParams)
g_staticLogConfig->log_level = iniParams->log_level;
g_staticLogConfig->log_lock = iniParams->log_lock;
g_staticLogConfig->log_lock_attr = iniParams->log_lock_attr;
- g_staticLogConfig->program_name = g_strdup(iniParams->program_name);
+ g_staticLogConfig->program_name = iniParams->program_name;
g_staticLogConfig->syslog_level = iniParams->syslog_level;
ret = internal_log_start(g_staticLogConfig);
diff --git a/common/log.h b/common/log.h
index b95c615a..33bb41fd 100644
--- a/common/log.h
+++ b/common/log.h
@@ -65,12 +65,12 @@ enum logReturns
struct log_config
{
- char *program_name;
+ const char *program_name;
char *log_file;
int fd;
- unsigned int log_level;
+ enum logLevels log_level;
int enable_syslog;
- unsigned int syslog_level;
+ enum logLevels syslog_level;
pthread_mutex_t log_lock;
pthread_mutexattr_t log_lock_attr;
};
@@ -81,7 +81,7 @@ struct log_config
/**
*
* @brief Starts the logging subsystem
- * @param l_cfg loggging system configuration
+ * @param l_cfg logging system configuration
* @return
*
*/
@@ -113,7 +113,7 @@ internal_log_lvl2str(const enum logLevels lvl, char *str);
*
*/
enum logLevels DEFAULT_CC
-internal_log_text2level(char *s);
+internal_log_text2level(const char *s);
/**
* A function that init our struct that holds all state and
@@ -171,17 +171,7 @@ log_end(void);
* @return
*/
enum logReturns DEFAULT_CC
-log_message(const enum logLevels lvl, const char *msg, ...);
-
-/**
- *
- * @brief Reads configuration
- * @param s translates the strings "1", "true" and "yes" in 1 (true) and
- * other strings in 0
- * @return 0 on success, 1 on failure
- *
- */
-int APP_CC text2bool(char *s);
+log_message(const enum logLevels lvl, const char *msg, ...) printflike(2, 3);
/**
* This function returns the configured file name for the logfile
diff --git a/common/os_calls.c b/common/os_calls.c
index bfea9031..5db59caa 100644
--- a/common/os_calls.c
+++ b/common/os_calls.c
@@ -86,6 +86,12 @@ extern char **environ;
#include <linux/unistd.h>
#endif
+/* sys/ucred.h needs to be included to use struct xucred
+ * in FreeBSD and OS X. No need for other BSDs */
+#if defined(__FreeBSD__) || defined(__APPLE__)
+#include <sys/ucred.h>
+#endif
+
/* for solaris */
#if !defined(PF_LOCAL)
#define PF_LOCAL AF_UNIX
@@ -94,23 +100,10 @@ extern char **environ;
#define INADDR_NONE ((unsigned long)-1)
#endif
-static char g_temp_base[128] = "";
-static char g_temp_base_org[128] = "";
-
/*****************************************************************************/
int APP_CC
g_rm_temp_dir(void)
{
- if (g_temp_base[0] != 0)
- {
- if (!g_remove_dir(g_temp_base))
- {
- printf("g_rm_temp_dir: removing temp directory [%s] failed\n", g_temp_base);
- }
-
- g_temp_base[0] = 0;
- }
-
return 0;
}
@@ -118,58 +111,19 @@ g_rm_temp_dir(void)
int APP_CC
g_mk_temp_dir(const char *app_name)
{
- if (app_name != 0)
+ if (!g_directory_exist("/tmp/.xrdp"))
{
- if (app_name[0] != 0)
+ if (!g_create_dir("/tmp/.xrdp"))
{
+ /* if failed, still check if it got created by someone else */
if (!g_directory_exist("/tmp/.xrdp"))
{
- if (!g_create_dir("/tmp/.xrdp"))
- {
- /* if failed, still check if it got created by someone else */
- if (!g_directory_exist("/tmp/.xrdp"))
- {
- printf("g_mk_temp_dir: g_create_dir failed\n");
- return 1;
- }
- }
-
- g_chmod_hex("/tmp/.xrdp", 0x1777);
- }
-
- snprintf(g_temp_base, sizeof(g_temp_base),
- "/tmp/.xrdp/%s-XXXXXX", app_name);
- snprintf(g_temp_base_org, sizeof(g_temp_base_org),
- "/tmp/.xrdp/%s-XXXXXX", app_name);
-
- if (mkdtemp(g_temp_base) == 0)
- {
- printf("g_mk_temp_dir: mkdtemp failed [%s]\n", g_temp_base);
+ printf("g_mk_temp_dir: g_create_dir failed\n");
return 1;
}
}
- else
- {
- printf("g_mk_temp_dir: bad app name\n");
- return 1;
- }
+ g_chmod_hex("/tmp/.xrdp", 0x1777);
}
- else
- {
- if (g_temp_base_org[0] == 0)
- {
- printf("g_mk_temp_dir: g_temp_base_org not set\n");
- return 1;
- }
-
- g_strncpy(g_temp_base, g_temp_base_org, 127);
-
- if (mkdtemp(g_temp_base) == 0)
- {
- printf("g_mk_temp_dir: mkdtemp failed [%s]\n", g_temp_base);
- }
- }
-
return 0;
}
@@ -182,7 +136,21 @@ g_init(const char *app_name)
WSAStartup(2, &wsadata);
#endif
- setlocale(LC_CTYPE, "");
+
+ /* In order to get g_mbstowcs and g_wcstombs to work properly with
+ UTF-8 non-ASCII characters, LC_CTYPE cannot be "C" or blank.
+ To select UTF-8 encoding without specifying any countries/languages,
+ "C.UTF-8" is used but provided in few systems.
+
+ See also: https://sourceware.org/glibc/wiki/Proposals/C.UTF-8 */
+ char *lc_ctype;
+ lc_ctype = setlocale(LC_CTYPE, "C.UTF-8");
+ if (lc_ctype == NULL)
+ {
+ /* use en_US.UTF-8 instead if not available */
+ setlocale(LC_CTYPE, "en_US.UTF-8");
+ }
+
g_mk_temp_dir(app_name);
}
@@ -253,14 +221,17 @@ g_sprintf(char *dest, const char *format, ...)
}
/*****************************************************************************/
-void DEFAULT_CC
+int DEFAULT_CC
g_snprintf(char *dest, int len, const char *format, ...)
{
+ int err;
va_list ap;
va_start(ap, format);
- vsnprintf(dest, len, format, ap);
+ err = vsnprintf(dest, len, format, ap);
va_end(ap);
+
+ return err;
}
/*****************************************************************************/
@@ -293,7 +264,7 @@ g_write(const char *format, ...)
/*****************************************************************************/
/* produce a hex dump */
void APP_CC
-g_hexdump(char *p, int len)
+g_hexdump(const char *p, int len)
{
unsigned char *line;
int i;
@@ -328,7 +299,7 @@ g_hexdump(char *p, int len)
g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
}
- g_writeln("");
+ g_writeln("%s", "");
offset += thisline;
line += thisline;
}
@@ -361,13 +332,8 @@ int APP_CC
g_tcp_set_no_delay(int sck)
{
int ret = 1; /* error */
-#if defined(_WIN32)
- int option_value;
- int option_len;
-#else
int option_value;
- unsigned int option_len;
-#endif
+ socklen_t option_len;
option_len = sizeof(option_value);
@@ -405,13 +371,8 @@ int APP_CC
g_tcp_set_keepalive(int sck)
{
int ret = 1; /* error */
-#if defined(_WIN32)
- int option_value;
- int option_len;
-#else
int option_value;
- unsigned int option_len;
-#endif
+ socklen_t option_len;
option_len = sizeof(option_value);
@@ -445,40 +406,56 @@ g_tcp_set_keepalive(int sck)
/*****************************************************************************/
/* returns a newly created socket or -1 on error */
-/* in win32 a socket is an unsigned int, in linux, its an int */
+/* in win32 a socket is an unsigned int, in linux, it's an int */
int APP_CC
g_tcp_socket(void)
{
int rv;
int option_value;
-#if defined(_WIN32)
- int option_len;
-#else
- unsigned int option_len;
-#endif
+ socklen_t option_len;
-#if 0 && !defined(NO_ARPA_INET_H_IP6)
+#if defined(XRDP_ENABLE_IPV6)
rv = (int)socket(AF_INET6, SOCK_STREAM, 0);
+ if (rv < 0)
+ {
+ log_message(LOG_LEVEL_ERROR, "g_tcp_socket: %s", g_get_strerror());
+
+ switch (errno)
+ {
+ case EAFNOSUPPORT: /* if IPv6 not supported, retry IPv4 */
+ log_message(LOG_LEVEL_INFO, "IPv6 not supported, falling back to IPv4");
+ rv = (int)socket(AF_INET, SOCK_STREAM, 0);
+ break;
+
+ default:
+ return -1;
+ }
+ }
#else
rv = (int)socket(AF_INET, SOCK_STREAM, 0);
#endif
if (rv < 0)
{
+ log_message(LOG_LEVEL_ERROR, "g_tcp_socket: %s", g_get_strerror());
return -1;
}
-#if 0 && !defined(NO_ARPA_INET_H_IP6)
+#if defined(XRDP_ENABLE_IPV6)
option_len = sizeof(option_value);
if (getsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&option_value,
&option_len) == 0)
{
if (option_value != 0)
{
+#if defined(XRDP_ENABLE_IPV6ONLY)
+ option_value = 1;
+#else
option_value = 0;
+#endif
option_len = sizeof(option_value);
if (setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&option_value,
option_len) < 0)
{
- log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n");
+ log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed");
}
}
}
@@ -494,7 +471,7 @@ g_tcp_socket(void)
if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
option_len) < 0)
{
- log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n");
+ log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed");
}
}
}
@@ -511,7 +488,7 @@ g_tcp_socket(void)
if (setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
option_len) < 0)
{
- log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n");
+ log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed");
}
}
}
@@ -525,11 +502,7 @@ int APP_CC
g_sck_set_send_buffer_bytes(int sck, int bytes)
{
int option_value;
-#if defined(_WIN32)
- int option_len;
-#else
- unsigned int option_len;
-#endif
+ socklen_t option_len;
option_value = bytes;
option_len = sizeof(option_value);
@@ -547,11 +520,7 @@ int APP_CC
g_sck_get_send_buffer_bytes(int sck, int *bytes)
{
int option_value;
-#if defined(_WIN32)
- int option_len;
-#else
- unsigned int option_len;
-#endif
+ socklen_t option_len;
option_value = 0;
option_len = sizeof(option_value);
@@ -570,11 +539,7 @@ int APP_CC
g_sck_set_recv_buffer_bytes(int sck, int bytes)
{
int option_value;
-#if defined(_WIN32)
- int option_len;
-#else
- unsigned int option_len;
-#endif
+ socklen_t option_len;
option_value = bytes;
option_len = sizeof(option_value);
@@ -592,11 +557,7 @@ int APP_CC
g_sck_get_recv_buffer_bytes(int sck, int *bytes)
{
int option_value;
-#if defined(_WIN32)
- int option_len;
-#else
- unsigned int option_len;
-#endif
+ socklen_t option_len;
option_value = 0;
option_len = sizeof(option_value);
@@ -611,7 +572,7 @@ g_sck_get_recv_buffer_bytes(int sck, int *bytes)
/*****************************************************************************/
int APP_CC
-g_tcp_local_socket(void)
+g_sck_local_socket(void)
{
#if defined(_WIN32)
return 0;
@@ -626,11 +587,7 @@ int APP_CC
g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
{
#if defined(SO_PEERCRED)
-#if defined(_WIN32)
- int ucred_length;
-#else
- unsigned int ucred_length;
-#endif
+ socklen_t ucred_length;
struct myucred
{
pid_t pid;
@@ -656,6 +613,28 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
*gid = credentials.gid;
}
return 0;
+#elif defined(LOCAL_PEERCRED)
+ /* FreeBSD, OS X reach here*/
+ struct xucred xucred;
+ unsigned int xucred_length;
+ xucred_length = sizeof(xucred);
+
+ if (getsockopt(sck, SOL_SOCKET, LOCAL_PEERCRED, &xucred, &xucred_length))
+ {
+ return 1;
+ }
+ if (pid !=0)
+ {
+ *pid = 0; /* can't get pid in FreeBSD, OS X */
+ }
+ if (uid != 0)
+ {
+ *uid = xucred.cr_uid;
+ }
+ if (gid != 0) {
+ *gid = xucred.cr_gid;
+ }
+ return 0;
#else
return 1;
#endif
@@ -663,27 +642,93 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
/*****************************************************************************/
void APP_CC
-g_tcp_close(int sck)
+g_sck_close(int sck)
{
- char ip[256];
-
- if (sck == 0)
- {
- return;
- }
#if defined(_WIN32)
closesocket(sck);
#else
- g_write_ip_address(sck, ip, 255);
- log_message(LOG_LEVEL_INFO, "An established connection closed to "
- "endpoint: %s", ip);
- close(sck);
+ char sockname[128];
+ union
+ {
+ struct sockaddr sock_addr;
+ struct sockaddr_in sock_addr_in;
+#if defined(XRDP_ENABLE_IPV6)
+ struct sockaddr_in6 sock_addr_in6;
+#endif
+ } sock_info;
+ socklen_t sock_len = sizeof(sock_info);
+
+ memset(&sock_info, 0, sizeof(sock_info));
+
+ if (getsockname(sck, &sock_info.sock_addr, &sock_len) == 0)
+ {
+ switch (sock_info.sock_addr.sa_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *sock_addr_in = &sock_info.sock_addr_in;
+
+ g_snprintf(sockname, sizeof(sockname), "AF_INET %s:%d",
+ inet_ntoa(sock_addr_in->sin_addr),
+ ntohs(sock_addr_in->sin_port));
+ break;
+ }
+
+#if defined(XRDP_ENABLE_IPV6)
+
+ case AF_INET6:
+ {
+ char addr[48];
+ struct sockaddr_in6 *sock_addr_in6 = &sock_info.sock_addr_in6;
+
+ g_snprintf(sockname, sizeof(sockname), "AF_INET6 %s port %d",
+ inet_ntop(sock_addr_in6->sin6_family,
+ &sock_addr_in6->sin6_addr, addr, sizeof(addr)),
+ ntohs(sock_addr_in6->sin6_port));
+ break;
+ }
+
+#endif
+
+ case AF_UNIX:
+ g_snprintf(sockname, sizeof(sockname), "AF_UNIX");
+ break;
+
+ default:
+ g_snprintf(sockname, sizeof(sockname), "unknown family %d",
+ sock_info.sock_addr.sa_family);
+ break;
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_WARNING, "getsockname() failed on socket %d: %s",
+ sck, g_get_strerror());
+
+ if (errno == EBADF || errno == ENOTSOCK)
+ {
+ return;
+ }
+
+ g_snprintf(sockname, sizeof(sockname), "unknown");
+ }
+
+ if (close(sck) == 0)
+ {
+ log_message(LOG_LEVEL_DEBUG, "Closed socket %d (%s)", sck, sockname);
+ }
+ else
+ {
+ log_message(LOG_LEVEL_WARNING, "Cannot close socket %d (%s): %s", sck,
+ sockname, g_get_strerror());
+ }
+
#endif
}
/*****************************************************************************/
/* returns error, zero is good */
-#if 0
+#if defined(XRDP_ENABLE_IPV6)
int APP_CC
g_tcp_connect(int sck, const char *address, const char *port)
{
@@ -703,7 +748,6 @@ g_tcp_connect(int sck, const char *address, const char *port)
*/
p.ai_socktype = SOCK_STREAM;
p.ai_protocol = IPPROTO_TCP;
-#if !defined(NO_ARPA_INET_H_IP6)
p.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
p.ai_family = AF_INET6;
if (g_strcmp(address, "127.0.0.1") == 0)
@@ -714,11 +758,11 @@ g_tcp_connect(int sck, const char *address, const char *port)
{
res = getaddrinfo(address, port, &p, &h);
}
-#else
- p.ai_flags = AI_ADDRCONFIG;
- p.ai_family = AF_INET;
- res = getaddrinfo(address, port, &p, &h);
-#endif
+ if (res != 0)
+ {
+ log_message(LOG_LEVEL_ERROR, "g_tcp_connect: getaddrinfo() failed: %s",
+ gai_strerror(res));
+ }
if (res > -1)
{
if (h != NULL)
@@ -735,44 +779,60 @@ g_tcp_connect(int sck, const char *address, const char *port)
}
}
}
+
+ /* Mac OSX connect() returns -1 for already established connections */
+ if (res == -1 && errno == EISCONN)
+ {
+ res = 0;
+ }
+
return res;
}
#else
int APP_CC
g_tcp_connect(int sck, const char* address, const char* port)
{
- struct sockaddr_in s;
- struct hostent* h;
-
- g_memset(&s, 0, sizeof(struct sockaddr_in));
- s.sin_family = AF_INET;
- s.sin_port = htons((tui16)atoi(port));
- s.sin_addr.s_addr = inet_addr(address);
- if (s.sin_addr.s_addr == INADDR_NONE)
- {
- h = gethostbyname(address);
- if (h != 0)
- {
- if (h->h_name != 0)
- {
- if (h->h_addr_list != 0)
+ struct sockaddr_in s;
+ struct hostent* h;
+ int res;
+
+ g_memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = inet_addr(address);
+ if (s.sin_addr.s_addr == INADDR_NONE)
+ {
+ h = gethostbyname(address);
+ if (h != 0)
{
- if ((*(h->h_addr_list)) != 0)
- {
- s.sin_addr.s_addr = *((int*)(*(h->h_addr_list)));
- }
+ if (h->h_name != 0)
+ {
+ if (h->h_addr_list != 0)
+ {
+ if ((*(h->h_addr_list)) != 0)
+ {
+ s.sin_addr.s_addr = *((int*)(*(h->h_addr_list)));
+ }
+ }
+ }
}
- }
}
- }
- return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+ res = connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+
+ /* Mac OSX connect() returns -1 for already established connections */
+ if (res == -1 && errno == EISCONN)
+ {
+ res = 0;
+ }
+
+ return res;
}
#endif
/*****************************************************************************/
/* returns error, zero is good */
int APP_CC
-g_tcp_local_connect(int sck, const char *port)
+g_sck_local_connect(int sck, const char *port)
{
#if defined(_WIN32)
return -1;
@@ -790,7 +850,7 @@ g_tcp_local_connect(int sck, const char *port)
/*****************************************************************************/
int APP_CC
-g_tcp_set_non_blocking(int sck)
+g_sck_set_non_blocking(int sck)
{
unsigned long i;
@@ -802,13 +862,13 @@ g_tcp_set_non_blocking(int sck)
i = i | O_NONBLOCK;
if (fcntl(sck, F_SETFL, i) < 0)
{
- log_message(LOG_LEVEL_ERROR, "g_tcp_set_non_blocking: fcntl() failed\n");
+ log_message(LOG_LEVEL_ERROR, "g_sck_set_non_blocking: fcntl() failed");
}
#endif
return 0;
}
-#if 0
+#if defined(XRDP_ENABLE_IPV6)
/*****************************************************************************/
/* return boolean */
static int APP_CC
@@ -876,7 +936,7 @@ address_match(const char *address, struct addrinfo *j)
}
#endif
-#if 0
+#if defined(XRDP_ENABLE_IPV6)
/*****************************************************************************/
/* returns error, zero is good */
static int APP_CC
@@ -922,19 +982,19 @@ g_tcp_bind(int sck, const char *port)
int APP_CC
g_tcp_bind(int sck, const char* port)
{
- struct sockaddr_in s;
+ struct sockaddr_in s;
- memset(&s, 0, sizeof(struct sockaddr_in));
- s.sin_family = AF_INET;
- s.sin_port = htons((tui16)atoi(port));
- s.sin_addr.s_addr = INADDR_ANY;
- return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = INADDR_ANY;
+ return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
}
#endif
/*****************************************************************************/
int APP_CC
-g_tcp_local_bind(int sck, const char *port)
+g_sck_local_bind(int sck, const char *port)
{
#if defined(_WIN32)
return -1;
@@ -950,7 +1010,7 @@ g_tcp_local_bind(int sck, const char *port)
#endif
}
-#if 0
+#if defined(XRDP_ENABLE_IPV6)
/*****************************************************************************/
/* returns error, zero is good */
int APP_CC
@@ -965,24 +1025,24 @@ g_tcp_bind_address(int sck, const char *port, const char *address)
int APP_CC
g_tcp_bind_address(int sck, const char* port, const char* address)
{
- struct sockaddr_in s;
+ struct sockaddr_in s;
- memset(&s, 0, sizeof(struct sockaddr_in));
- s.sin_family = AF_INET;
- s.sin_port = htons((tui16)atoi(port));
- s.sin_addr.s_addr = INADDR_ANY;
- if (inet_aton(address, &s.sin_addr) < 0)
- {
- return -1; /* bad address */
- }
- return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = INADDR_ANY;
+ if (inet_aton(address, &s.sin_addr) < 0)
+ {
+ return -1; /* bad address */
+ }
+ return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
}
#endif
/*****************************************************************************/
/* returns error, zero is good */
int APP_CC
-g_tcp_listen(int sck)
+g_sck_listen(int sck)
{
return listen(sck, 2);
}
@@ -991,25 +1051,60 @@ g_tcp_listen(int sck)
int APP_CC
g_tcp_accept(int sck)
{
- int ret ;
- char ipAddr[256] ;
- struct sockaddr_in s;
-#if defined(_WIN32)
- signed int i;
-#else
- unsigned int i;
+ int ret;
+ char msg[256];
+ union
+ {
+ struct sockaddr sock_addr;
+ struct sockaddr_in sock_addr_in;
+#if defined(XRDP_ENABLE_IPV6)
+ struct sockaddr_in6 sock_addr_in6;
#endif
+ } sock_info;
- i = sizeof(struct sockaddr_in);
- memset(&s, 0, i);
- ret = accept(sck, (struct sockaddr *)&s, &i);
- if(ret>0)
+ socklen_t sock_len = sizeof(sock_info);
+ memset(&sock_info, 0, sock_len);
+
+ ret = accept(sck, (struct sockaddr *)&sock_info, &sock_len);
+
+ if (ret > 0)
{
- snprintf(ipAddr,255,"A connection received from: %s port %d"
- ,inet_ntoa(s.sin_addr),ntohs(s.sin_port));
- log_message(LOG_LEVEL_INFO,ipAddr);
+ switch(sock_info.sock_addr.sa_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *sock_addr_in = &sock_info.sock_addr_in;
+
+ snprintf(msg, sizeof(msg), "A connection received from %s port %d",
+ inet_ntoa(sock_addr_in->sin_addr),
+ ntohs(sock_addr_in->sin_port));
+ log_message(LOG_LEVEL_INFO, "%s", msg);
+
+ break;
+ }
+
+#if defined(XRDP_ENABLE_IPV6)
+
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sock_addr_in6 = &sock_info.sock_addr_in6;
+ char addr[256];
+
+ inet_ntop(sock_addr_in6->sin6_family,
+ &sock_addr_in6->sin6_addr, addr, sizeof(addr));
+ snprintf(msg, sizeof(msg), "A connection received from %s port %d",
+ addr, ntohs(sock_addr_in6->sin6_port));
+ log_message(LOG_LEVEL_INFO, "%s", msg);
+
+ break;
+
+ }
+
+#endif
+ }
}
- return ret ;
+
+ return ret;
}
/*****************************************************************************/
@@ -1017,33 +1112,65 @@ int APP_CC
g_sck_accept(int sck, char *addr, int addr_bytes, char *port, int port_bytes)
{
int ret;
- char ipAddr[256];
- struct sockaddr_in s;
-#if defined(_WIN32)
- signed int i;
-#else
- unsigned int i;
+ char msg[256];
+ union
+ {
+ struct sockaddr sock_addr;
+ struct sockaddr_in sock_addr_in;
+#if defined(XRDP_ENABLE_IPV6)
+ struct sockaddr_in6 sock_addr_in6;
#endif
+ } sock_info;
+
+ socklen_t sock_len = sizeof(sock_info);
+ memset(&sock_info, 0, sock_len);
+
+ ret = accept(sck, (struct sockaddr *)&sock_info, &sock_len);
- i = sizeof(struct sockaddr_in);
- memset(&s, 0, i);
- ret = accept(sck, (struct sockaddr *)&s, &i);
if (ret > 0)
{
- g_snprintf(ipAddr, 255, "A connection received from: %s port %d",
- inet_ntoa(s.sin_addr), ntohs(s.sin_port));
- log_message(LOG_LEVEL_INFO,ipAddr);
- if (s.sin_family == AF_INET)
+ switch(sock_info.sock_addr.sa_family)
{
- g_snprintf(addr, addr_bytes, "%s", inet_ntoa(s.sin_addr));
- g_snprintf(port, port_bytes, "%d", ntohs(s.sin_port));
- }
- if (s.sin_family == AF_UNIX)
- {
- g_strncpy(addr, "", addr_bytes - 1);
- g_strncpy(port, "", port_bytes - 1);
+ case AF_INET:
+ {
+ struct sockaddr_in *sock_addr_in = &sock_info.sock_addr_in;
+
+ g_snprintf(addr, addr_bytes, "%s", inet_ntoa(sock_addr_in->sin_addr));
+ g_snprintf(port, port_bytes, "%d", ntohs(sock_addr_in->sin_port));
+
+ break;
+ }
+
+#if defined(XRDP_ENABLE_IPV6)
+
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sock_addr_in6 = &sock_info.sock_addr_in6;
+
+ inet_ntop(sock_addr_in6->sin6_family,
+ &sock_addr_in6->sin6_addr, addr, addr_bytes);
+ g_snprintf(port, port_bytes, "%d", ntohs(sock_addr_in6->sin6_port));
+ break;
+ }
+
+#endif
+
+ case AF_UNIX:
+ default:
+ {
+ g_strncpy(addr, "", addr_bytes - 1);
+ g_strncpy(port, "", port_bytes - 1);
+ break;
+ }
}
+
+
+ g_snprintf(msg, sizeof(msg), "A connection received from: %s port %s",
+ addr, port);
+ log_message(LOG_LEVEL_INFO, "%s", msg);
+
}
+
return ret;
}
@@ -1053,11 +1180,7 @@ g_write_ip_address(int rcv_sck, char *ip_address, int bytes)
{
struct sockaddr_in s;
struct in_addr in;
-#if defined(_WIN32)
- int len;
-#else
- unsigned int len;
-#endif
+ socklen_t len;
int ip_port;
int ok;
@@ -1098,7 +1221,7 @@ g_sleep(int msecs)
/*****************************************************************************/
int APP_CC
-g_tcp_last_error_would_block(int sck)
+g_sck_last_error_would_block(int sck)
{
#if defined(_WIN32)
return WSAGetLastError() == WSAEWOULDBLOCK;
@@ -1109,7 +1232,7 @@ g_tcp_last_error_would_block(int sck)
/*****************************************************************************/
int APP_CC
-g_tcp_recv(int sck, void *ptr, int len, int flags)
+g_sck_recv(int sck, void *ptr, int len, int flags)
{
#if defined(_WIN32)
return recv(sck, (char *)ptr, len, flags);
@@ -1120,7 +1243,7 @@ g_tcp_recv(int sck, void *ptr, int len, int flags)
/*****************************************************************************/
int APP_CC
-g_tcp_send(int sck, const void *ptr, int len, int flags)
+g_sck_send(int sck, const void *ptr, int len, int flags)
{
#if defined(_WIN32)
return send(sck, (const char *)ptr, len, flags);
@@ -1132,15 +1255,10 @@ g_tcp_send(int sck, const void *ptr, int len, int flags)
/*****************************************************************************/
/* returns boolean */
int APP_CC
-g_tcp_socket_ok(int sck)
+g_sck_socket_ok(int sck)
{
-#if defined(_WIN32)
- int opt;
- int opt_len;
-#else
int opt;
- unsigned int opt_len;
-#endif
+ socklen_t opt_len;
opt_len = sizeof(opt);
@@ -1159,7 +1277,7 @@ g_tcp_socket_ok(int sck)
/* wait 'millis' milliseconds for the socket to be able to write */
/* returns boolean */
int APP_CC
-g_tcp_can_send(int sck, int millis)
+g_sck_can_send(int sck, int millis)
{
fd_set wfds;
struct timeval time;
@@ -1176,7 +1294,7 @@ g_tcp_can_send(int sck, int millis)
if (rv > 0)
{
- return g_tcp_socket_ok(sck);
+ return 1;
}
}
@@ -1187,12 +1305,13 @@ g_tcp_can_send(int sck, int millis)
/* wait 'millis' milliseconds for the socket to be able to receive */
/* returns boolean */
int APP_CC
-g_tcp_can_recv(int sck, int millis)
+g_sck_can_recv(int sck, int millis)
{
fd_set rfds;
struct timeval time;
int rv;
+ g_memset(&time, 0, sizeof(time));
time.tv_sec = millis / 1000;
time.tv_usec = (millis * 1000) % 1000000;
FD_ZERO(&rfds);
@@ -1204,7 +1323,7 @@ g_tcp_can_recv(int sck, int millis)
if (rv > 0)
{
- return g_tcp_socket_ok(sck);
+ return 1;
}
}
@@ -1213,18 +1332,14 @@ g_tcp_can_recv(int sck, int millis)
/*****************************************************************************/
int APP_CC
-g_tcp_select(int sck1, int sck2)
+g_sck_select(int sck1, int sck2)
{
fd_set rfds;
struct timeval time;
- int max = 0;
- int rv = 0;
+ int max;
+ int rv;
- g_memset(&rfds, 0, sizeof(fd_set));
g_memset(&time, 0, sizeof(struct timeval));
-
- time.tv_sec = 0;
- time.tv_usec = 0;
FD_ZERO(&rfds);
if (sck1 > 0)
@@ -1269,96 +1384,94 @@ g_tcp_select(int sck1, int sck2)
}
/*****************************************************************************/
-/* returns 0 on error */
-tbus APP_CC
-g_create_wait_obj(char *name)
+/* returns boolean */
+static int APP_CC
+g_fd_can_read(int fd)
{
-#ifdef _WIN32
- tbus obj;
-
- obj = (tbus)CreateEvent(0, 1, 0, name);
- return obj;
-#else
- tbus obj;
- struct sockaddr_un sa;
- size_t len;
- tbus sck;
- int i;
- int safety;
- int unnamed;
+ fd_set rfds;
+ struct timeval time;
+ int rv;
- if (g_temp_base[0] == 0)
+ g_memset(&time, 0, sizeof(time));
+ FD_ZERO(&rfds);
+ FD_SET(((unsigned int)fd), &rfds);
+ rv = select(fd + 1, &rfds, 0, 0, &time);
+ if (rv == 1)
{
- return 0;
+ return 1;
}
+ return 0;
+}
- sck = socket(PF_UNIX, SOCK_DGRAM, 0);
+/*****************************************************************************/
+/* returns error */
+/* O_NONBLOCK = 0x00000800 */
+static int APP_CC
+g_set_nonblock(int fd)
+{
+ int error;
+ int flags;
- if (sck < 0)
+ error = fcntl(fd, F_GETFL);
+ if (error < 0)
{
- return 0;
+ return 1;
}
-
- safety = 0;
- g_memset(&sa, 0, sizeof(sa));
- sa.sun_family = AF_UNIX;
- unnamed = 1;
-
- if (name != 0)
+ flags = error;
+ if ((flags & O_NONBLOCK) != O_NONBLOCK)
{
- if (name[0] != 0)
+ flags |= O_NONBLOCK;
+ error = fcntl(fd, F_SETFL, flags);
+ if (error < 0)
{
- unnamed = 0;
+ return 1;
}
}
+ return 0;
+}
- if (unnamed)
- {
- do
- {
- if (safety > 100)
- {
- break;
- }
+/*****************************************************************************/
+/* returns 0 on error */
+tintptr APP_CC
+g_create_wait_obj(const char *name)
+{
+#ifdef _WIN32
+ tintptr obj;
- safety++;
- g_random((char *)&i, sizeof(i));
- len = sizeof(sa.sun_path);
- g_snprintf(sa.sun_path, len, "%s/auto_%8.8x", g_temp_base, i);
- len = sizeof(sa);
- }
- while (bind(sck, (struct sockaddr *)&sa, len) < 0);
+ obj = (tintptr)CreateEvent(0, 1, 0, name);
+ return obj;
+#else
+ int fds[2];
+ int error;
+
+ error = pipe(fds);
+ if (error != 0)
+ {
+ return 0;
}
- else
+ if (g_set_nonblock(fds[0]) != 0)
{
- do
- {
- if (safety > 100)
- {
- break;
- }
-
- safety++;
- g_random((char *)&i, sizeof(i));
- len = sizeof(sa.sun_path);
- g_snprintf(sa.sun_path, len, "%s/%s_%8.8x", g_temp_base, name, i);
- len = sizeof(sa);
- }
- while (bind(sck, (struct sockaddr *)&sa, len) < 0);
+ close(fds[0]);
+ close(fds[1]);
+ return 0;
}
-
- obj = (tbus)sck;
- return obj;
+ if (g_set_nonblock(fds[1]) != 0)
+ {
+ close(fds[0]);
+ close(fds[1]);
+ return 0;
+ }
+ return (fds[1] << 16) | fds[0];
#endif
}
/*****************************************************************************/
/* returns 0 on error */
-tbus APP_CC
-g_create_wait_obj_from_socket(tbus socket, int write)
+tintptr APP_CC
+g_create_wait_obj_from_socket(tintptr socket, int write)
{
#ifdef _WIN32
- /* Create and return corresponding event handle for WaitForMultipleObjets */
+ /* Create and return corresponding event handle for WaitForMultipleObjects */
WSAEVENT event;
long lnetevent = 0;
@@ -1383,7 +1496,7 @@ g_create_wait_obj_from_socket(tbus socket, int write)
/*****************************************************************************/
void APP_CC
-g_delete_wait_obj_from_socket(tbus wait_obj)
+g_delete_wait_obj_from_socket(tintptr wait_obj)
{
#ifdef _WIN32
@@ -1400,54 +1513,60 @@ g_delete_wait_obj_from_socket(tbus wait_obj)
/*****************************************************************************/
/* returns error */
int APP_CC
-g_set_wait_obj(tbus obj)
+g_set_wait_obj(tintptr obj)
{
#ifdef _WIN32
-
if (obj == 0)
{
return 0;
}
-
SetEvent((HANDLE)obj);
return 0;
#else
- socklen_t sa_size;
- int s;
- struct sockaddr_un sa;
+ int error;
+ int fd;
+ int written;
+ int to_write;
+ char buf[4] = "sig";
if (obj == 0)
{
return 0;
}
-
- if (g_tcp_can_recv((int)obj, 0))
+ fd = obj & 0xffff;
+ if (g_fd_can_read(fd))
{
/* already signalled */
return 0;
}
-
- sa_size = sizeof(sa);
-
- if (getsockname((int)obj, (struct sockaddr *)&sa, &sa_size) < 0)
- {
- return 1;
- }
-
- s = socket(PF_UNIX, SOCK_DGRAM, 0);
-
- if (s < 0)
- {
- return 1;
- }
-
- if (sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size) < 0)
+ fd = obj >> 16;
+ to_write = 4;
+ written = 0;
+ while (written < to_write)
{
- close(s);
- return 1;
+ error = write(fd, buf + written, to_write - written);
+ if (error == -1)
+ {
+ error = errno;
+ if ((error == EAGAIN) || (error == EWOULDBLOCK) ||
+ (error == EINPROGRESS) || (error == EINTR))
+ {
+ /* ok */
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else if (error > 0)
+ {
+ written += error;
+ }
+ else
+ {
+ return 1;
+ }
}
-
- close(s);
return 0;
#endif
}
@@ -1455,30 +1574,46 @@ g_set_wait_obj(tbus obj)
/*****************************************************************************/
/* returns error */
int APP_CC
-g_reset_wait_obj(tbus obj)
+g_reset_wait_obj(tintptr obj)
{
#ifdef _WIN32
-
if (obj == 0)
{
return 0;
}
-
ResetEvent((HANDLE)obj);
return 0;
#else
- char buf[64];
+ char buf[4];
+ int error;
+ int fd;
if (obj == 0)
{
return 0;
}
-
- while (g_tcp_can_recv((int)obj, 0))
+ fd = obj & 0xffff;
+ while (g_fd_can_read(fd))
{
- recvfrom((int)obj, &buf, 64, 0, 0, 0);
+ error = read(fd, buf, 4);
+ if (error == -1)
+ {
+ error = errno;
+ if ((error == EAGAIN) || (error == EWOULDBLOCK) ||
+ (error == EINPROGRESS) || (error == EINTR))
+ {
+ /* ok */
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else if (error == 0)
+ {
+ return 1;
+ }
}
-
return 0;
#endif
}
@@ -1486,86 +1621,55 @@ g_reset_wait_obj(tbus obj)
/*****************************************************************************/
/* returns boolean */
int APP_CC
-g_is_wait_obj_set(tbus obj)
+g_is_wait_obj_set(tintptr obj)
{
#ifdef _WIN32
-
if (obj == 0)
{
return 0;
}
-
if (WaitForSingleObject((HANDLE)obj, 0) == WAIT_OBJECT_0)
{
return 1;
}
-
return 0;
#else
-
if (obj == 0)
{
return 0;
}
-
- return g_tcp_can_recv((int)obj, 0);
+ return g_fd_can_read(obj & 0xffff);
#endif
}
/*****************************************************************************/
/* returns error */
int APP_CC
-g_delete_wait_obj(tbus obj)
+g_delete_wait_obj(tintptr obj)
{
#ifdef _WIN32
-
if (obj == 0)
{
return 0;
}
-
/* Close event handle */
CloseHandle((HANDLE)obj);
return 0;
#else
- socklen_t sa_size;
- struct sockaddr_un sa;
-
if (obj == 0)
{
return 0;
}
-
- sa_size = sizeof(sa);
-
- if (getsockname((int)obj, (struct sockaddr *)&sa, &sa_size) < 0)
- {
- return 1;
- }
-
- close((int)obj);
- unlink(sa.sun_path);
+ close(obj & 0xffff);
+ close(obj >> 16);
return 0;
#endif
}
/*****************************************************************************/
/* returns error */
-/* close but do not delete the wait obj, used after fork */
-int APP_CC
-g_close_wait_obj(tbus obj)
-{
-#ifdef _WIN32
-#else
- close((int)obj);
-#endif
- return 0;
-}
-
-/*****************************************************************************/
-/* returns error */
int APP_CC
-g_obj_wait(tbus *read_objs, int rcount, tbus *write_objs, int wcount,
+g_obj_wait(tintptr *read_objs, int rcount, tintptr *write_objs, int wcount,
int mstimeout)
{
#ifdef _WIN32
@@ -1605,24 +1709,20 @@ g_obj_wait(tbus *read_objs, int rcount, tbus *write_objs, int wcount,
fd_set rfds;
fd_set wfds;
struct timeval time;
- struct timeval *ptime = (struct timeval *)NULL;
+ struct timeval *ptime;
int i = 0;
int res = 0;
int max = 0;
int sck = 0;
- g_memset(&rfds, 0, sizeof(fd_set));
- g_memset(&wfds, 0, sizeof(fd_set));
- g_memset(&time, 0, sizeof(struct timeval));
-
max = 0;
-
if (mstimeout < 1)
{
- ptime = (struct timeval *)NULL;
+ ptime = 0;
}
else
{
+ g_memset(&time, 0, sizeof(struct timeval));
time.tv_sec = mstimeout / 1000;
time.tv_usec = (mstimeout % 1000) * 1000;
ptime = &time;
@@ -1636,7 +1736,7 @@ g_obj_wait(tbus *read_objs, int rcount, tbus *write_objs, int wcount,
{
for (i = 0; i < rcount; i++)
{
- sck = (int)(read_objs[i]);
+ sck = read_objs[i] & 0xffff;
if (sck > 0)
{
@@ -1847,9 +1947,9 @@ g_file_read(int fd, char *ptr, int len)
}
/*****************************************************************************/
-/* write to file, returns the number of bytes writen or -1 on error */
+/* write to file, returns the number of bytes written or -1 on error */
int APP_CC
-g_file_write(int fd, char *ptr, int len)
+g_file_write(int fd, const char *ptr, int len)
{
#if defined(_WIN32)
@@ -1986,7 +2086,7 @@ g_get_current_dir(char *dirname, int maxlen)
/*****************************************************************************/
/* returns error, zero on success and -1 on failure */
int APP_CC
-g_set_current_dir(char *dirname)
+g_set_current_dir(const char *dirname)
{
#if defined(_WIN32)
@@ -2023,7 +2123,7 @@ g_directory_exist(const char *dirname)
{
#if defined(_WIN32)
return 0; // use GetFileAttributes and check return value
- // is not -1 and FILE_ATTRIBUT_DIRECTORY bit is set
+ // is not -1 and FILE_ATTRIBUTE_DIRECTORY bit is set
#else
struct stat st;
@@ -2155,7 +2255,7 @@ g_strlen(const char *text)
/*****************************************************************************/
/* locates char in text */
-char* APP_CC
+const char *APP_CC
g_strchr(const char* text, int c)
{
if (text == NULL)
@@ -2244,6 +2344,7 @@ g_strdup(const char *in)
return p;
}
+
/*****************************************************************************/
/* if in = 0, return 0 else return newly alloced copy of input string
* if the input string is larger than maxlen the returned string will be
@@ -2251,7 +2352,7 @@ g_strdup(const char *in)
char *APP_CC
g_strndup(const char *in, const unsigned int maxlen)
{
- int len;
+ unsigned int len;
char *p;
if (in == 0)
@@ -2275,6 +2376,7 @@ g_strndup(const char *in, const unsigned int maxlen)
return p;
}
+
/*****************************************************************************/
int APP_CC
g_strcmp(const char *c1, const char *c2)
@@ -2297,10 +2399,12 @@ g_strncmp_d(const char *s1, const char *s2, const char delim, int n)
char c1;
char c2;
+ c1 = 0;
+ c2 = 0;
while (n > 0)
{
- c1 = *s1++;
- c2 = *s2++;
+ c1 = *(s1++);
+ c2 = *(s2++);
if ((c1 == 0) || (c1 != c2) || (c1 == delim) || (c2 == delim))
{
return c1 - c2;
@@ -2427,10 +2531,38 @@ g_htoi(char *str)
}
/*****************************************************************************/
+/* returns number of bytes copied into out_str */
+int APP_CC
+g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
+ int bytes_out_str)
+{
+ int rv;
+ int index;
+ char *lout_str;
+ const tui8 *lbytes;
+
+ rv = 0;
+ lbytes = (const tui8 *) bytes;
+ lout_str = out_str;
+ for (index = 0; index < num_bytes; index++)
+ {
+ if (bytes_out_str < 3)
+ {
+ break;
+ }
+ g_snprintf(lout_str, bytes_out_str, "%2.2x", lbytes[index]);
+ lout_str += 2;
+ bytes_out_str -= 2;
+ rv += 2;
+ }
+ return rv;
+}
+
+/*****************************************************************************/
int APP_CC
g_pos(const char *str, const char *to_find)
{
- char *pp;
+ const char *pp;
pp = strstr(str, to_find);
@@ -2761,17 +2893,6 @@ g_signal_user_interrupt(void (*func)(int))
/*****************************************************************************/
/* does not work in win32 */
void APP_CC
-g_signal_kill(void (*func)(int))
-{
-#if defined(_WIN32)
-#else
- signal(SIGKILL, func);
-#endif
-}
-
-/*****************************************************************************/
-/* does not work in win32 */
-void APP_CC
g_signal_terminate(void (*func)(int))
{
#if defined(_WIN32)
@@ -2888,6 +3009,28 @@ g_setuid(int pid)
}
/*****************************************************************************/
+int APP_CC
+g_setsid(void)
+{
+#if defined(_WIN32)
+ return -1;
+#else
+ return setsid();
+#endif
+}
+
+/*****************************************************************************/
+int APP_CC
+g_setlogin(const char *name)
+{
+#ifdef BSD
+ return setlogin(name);
+#else
+ return -1;
+#endif
+}
+
+/*****************************************************************************/
/* does not work in win32
returns pid of process that exits or zero if signal occurred */
int APP_CC
@@ -3017,10 +3160,11 @@ g_sigterm(int pid)
/*****************************************************************************/
/* returns 0 if ok */
+/* the caller is responsible to free the buffs */
/* does not work in win32 */
int APP_CC
-g_getuser_info(const char *username, int *gid, int *uid, char *shell,
- char *dir, char *gecos)
+g_getuser_info(const char *username, int *gid, int *uid, char **shell,
+ char **dir, char **gecos)
{
#if defined(_WIN32)
return 1;
@@ -3043,17 +3187,17 @@ g_getuser_info(const char *username, int *gid, int *uid, char *shell,
if (dir != 0)
{
- g_strcpy(dir, pwd_1->pw_dir);
+ *dir = g_strdup(pwd_1->pw_dir);
}
if (shell != 0)
{
- g_strcpy(shell, pwd_1->pw_shell);
+ *shell = g_strdup(pwd_1->pw_shell);
}
if (gecos != 0)
{
- g_strcpy(gecos, pwd_1->pw_gecos);
+ *gecos = g_strdup(pwd_1->pw_gecos);
}
return 0;
@@ -3287,7 +3431,7 @@ g_save_to_bmp(const char* filename, char* data, int stride_bytes,
data -= stride_bytes;
if ((depth == 24) && (bits_per_pixel == 32))
{
- line = malloc(file_stride_bytes);
+ line = (char *) malloc(file_stride_bytes);
memset(line, 0, file_stride_bytes);
for (index = 0; index < height; index++)
{
@@ -3374,3 +3518,60 @@ g_gethostname(char *name, int len)
{
return gethostname(name, len);
}
+
+static unsigned char g_reverse_byte[0x100] =
+{
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+/*****************************************************************************/
+/* mirror each byte while copying */
+int APP_CC
+g_mirror_memcpy(void *dst, const void *src, int len)
+{
+ tui8 *dst8;
+ const tui8 *src8;
+
+ dst8 = (tui8 *) dst;
+ src8 = (const tui8 *) src;
+ while (len > 0)
+ {
+ *dst8 = g_reverse_byte[*src8];
+ dst8++;
+ src8++;
+ len--;
+ }
+ return 0;
+}
+
diff --git a/common/os_calls.h b/common/os_calls.h
index d954a075..6a206726 100644
--- a/common/os_calls.h
+++ b/common/os_calls.h
@@ -25,20 +25,37 @@
#define NULL 0
#endif
+#include <stdlib.h>
#include "arch.h"
+#define g_tcp_can_recv g_sck_can_recv
+#define g_tcp_can_send g_sck_can_send
+#define g_tcp_recv g_sck_recv
+#define g_tcp_send g_sck_send
+#define g_tcp_close g_sck_close
+#define g_tcp_last_error_would_block g_sck_last_error_would_block
+#define g_tcp_set_non_blocking g_sck_set_non_blocking
+#define g_tcp_local_socket g_sck_local_socket
+#define g_tcp_local_connect g_sck_local_connect
+#define g_tcp_listen g_sck_listen
+#define g_tcp_local_bind g_sck_local_bind
+#define g_tcp_select g_sck_select
+#define g_close_wait_obj g_delete_wait_obj
+
int APP_CC g_rm_temp_dir(void);
int APP_CC g_mk_temp_dir(const char* app_name);
void APP_CC g_init(const char* app_name);
void APP_CC g_deinit(void);
void* APP_CC g_malloc(int size, int zero);
void APP_CC g_free(void* ptr);
-void DEFAULT_CC g_printf(const char *format, ...);
-void DEFAULT_CC g_sprintf(char* dest, const char* format, ...);
-void DEFAULT_CC g_snprintf(char* dest, int len, const char* format, ...);
-void DEFAULT_CC g_writeln(const char* format, ...);
-void DEFAULT_CC g_write(const char* format, ...);
-void APP_CC g_hexdump(char* p, int len);
+void DEFAULT_CC g_printf(const char *format, ...) printflike(1, 2);
+void DEFAULT_CC g_sprintf(char* dest, const char* format, ...) \
+ printflike(2, 3);
+int DEFAULT_CC g_snprintf(char* dest, int len, const char* format, ...) \
+ printflike(3, 4);
+void DEFAULT_CC g_writeln(const char* format, ...) printflike(1, 2);
+void DEFAULT_CC g_write(const char* format, ...) printflike(1, 2);
+void APP_CC g_hexdump(const char *p, int len);
void APP_CC g_memset(void* ptr, int val, int size);
void APP_CC g_memcpy(void* d_ptr, const void* s_ptr, int size);
int APP_CC g_getchar(void);
@@ -49,39 +66,36 @@ int APP_CC g_sck_set_send_buffer_bytes(int sck, int bytes);
int APP_CC g_sck_get_send_buffer_bytes(int sck, int *bytes);
int APP_CC g_sck_set_recv_buffer_bytes(int sck, int bytes);
int APP_CC g_sck_get_recv_buffer_bytes(int sck, int *bytes);
-int APP_CC g_tcp_local_socket(void);
+int APP_CC g_sck_local_socket(void);
int APP_CC g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid);
-void APP_CC g_tcp_close(int sck);
+void APP_CC g_sck_close(int sck);
int APP_CC g_tcp_connect(int sck, const char* address, const char* port);
-int APP_CC g_tcp_local_connect(int sck, const char* port);
-int APP_CC g_tcp_force_send(int sck, char* data, int len);
-int APP_CC g_tcp_force_recv(int sck, char* data, int len);
-int APP_CC g_tcp_set_non_blocking(int sck);
+int APP_CC g_sck_local_connect(int sck, const char* port);
+int APP_CC g_sck_set_non_blocking(int sck);
int APP_CC g_tcp_bind(int sck, const char *port);
-int APP_CC g_tcp_local_bind(int sck, const char* port);
+int APP_CC g_sck_local_bind(int sck, const char* port);
int APP_CC g_tcp_bind_address(int sck, const char* port, const char* address);
-int APP_CC g_tcp_listen(int sck);
+int APP_CC g_sck_listen(int sck);
int APP_CC g_tcp_accept(int sck);
int APP_CC g_sck_accept(int sck, char *addr, int addr_bytes,
char *port, int port_bytes);
-int APP_CC g_tcp_recv(int sck, void* ptr, int len, int flags);
-int APP_CC g_tcp_send(int sck, const void* ptr, int len, int flags);
-int APP_CC g_tcp_last_error_would_block(int sck);
-int APP_CC g_tcp_socket_ok(int sck);
-int APP_CC g_tcp_can_send(int sck, int millis);
-int APP_CC g_tcp_can_recv(int sck, int millis);
-int APP_CC g_tcp_select(int sck1, int sck2);
+int APP_CC g_sck_recv(int sck, void* ptr, int len, int flags);
+int APP_CC g_sck_send(int sck, const void* ptr, int len, int flags);
+int APP_CC g_sck_last_error_would_block(int sck);
+int APP_CC g_sck_socket_ok(int sck);
+int APP_CC g_sck_can_send(int sck, int millis);
+int APP_CC g_sck_can_recv(int sck, int millis);
+int APP_CC g_sck_select(int sck1, int sck2);
void APP_CC g_write_ip_address(int rcv_sck, char* ip_address, int bytes);
void APP_CC g_sleep(int msecs);
-tbus APP_CC g_create_wait_obj(char* name);
-tbus APP_CC g_create_wait_obj_from_socket(tbus socket, int write);
-void APP_CC g_delete_wait_obj_from_socket(tbus wait_obj);
-int APP_CC g_set_wait_obj(tbus obj);
-int APP_CC g_reset_wait_obj(tbus obj);
-int APP_CC g_is_wait_obj_set(tbus obj);
-int APP_CC g_delete_wait_obj(tbus obj);
-int APP_CC g_close_wait_obj(tbus obj);
-int APP_CC g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs,
+tintptr APP_CC g_create_wait_obj(const char *name);
+tintptr APP_CC g_create_wait_obj_from_socket(tintptr socket, int write);
+void APP_CC g_delete_wait_obj_from_socket(tintptr wait_obj);
+int APP_CC g_set_wait_obj(tintptr obj);
+int APP_CC g_reset_wait_obj(tintptr obj);
+int APP_CC g_is_wait_obj_set(tintptr obj);
+int APP_CC g_delete_wait_obj(tintptr obj);
+int APP_CC g_obj_wait(tintptr* read_objs, int rcount, tintptr* write_objs,
int wcount,int mstimeout);
void APP_CC g_random(char* data, int len);
int APP_CC g_abs(int i);
@@ -91,14 +105,14 @@ int APP_CC g_file_open_ex(const char *file_name, int aread, int awrite,
int acreate, int atrunc);
int APP_CC g_file_close(int fd);
int APP_CC g_file_read(int fd, char* ptr, int len);
-int APP_CC g_file_write(int fd, char* ptr, int len);
+int APP_CC g_file_write(int fd, const char *ptr, int len);
int APP_CC g_file_seek(int fd, int offset);
int APP_CC g_file_lock(int fd, int start, int len);
int APP_CC g_chmod_hex(const char* filename, int flags);
int APP_CC g_chown(const char* name, int uid, int gid);
int APP_CC g_mkdir(const char* dirname);
char* APP_CC g_get_current_dir(char* dirname, int maxlen);
-int APP_CC g_set_current_dir(char* dirname);
+int APP_CC g_set_current_dir(const char *dirname);
int APP_CC g_file_exist(const char* filename);
int APP_CC g_directory_exist(const char* dirname);
int APP_CC g_create_dir(const char* dirname);
@@ -107,7 +121,7 @@ int APP_CC g_remove_dir(const char* dirname);
int APP_CC g_file_delete(const char* filename);
int APP_CC g_file_get_size(const char* filename);
int APP_CC g_strlen(const char* text);
-char* APP_CC g_strchr(const char* text, int c);
+const char *APP_CC g_strchr(const char *text, int c);
char* APP_CC g_strcpy(char* dest, const char* src);
char* APP_CC g_strncpy(char* dest, const char* src, int len);
char* APP_CC g_strcat(char* dest, const char* src);
@@ -120,6 +134,8 @@ int APP_CC g_strcasecmp(const char* c1, const char* c2);
int APP_CC g_strncasecmp(const char* c1, const char* c2, int len);
int APP_CC g_atoi(const char* str);
int APP_CC g_htoi(char* str);
+int APP_CC g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
+ int bytes_out_str);
int APP_CC g_pos(const char* str, const char* to_find);
int APP_CC g_mbstowcs(twchar* dest, const char* src, int n);
int APP_CC g_wcstombs(char* dest, const twchar* src, int n);
@@ -136,7 +152,6 @@ void APP_CC g_signal_child_stop(void (*func)(int));
void APP_CC g_signal_segfault(void (*func)(int));
void APP_CC g_signal_hang_up(void (*func)(int));
void APP_CC g_signal_user_interrupt(void (*func)(int));
-void APP_CC g_signal_kill(void (*func)(int));
void APP_CC g_signal_terminate(void (*func)(int));
void APP_CC g_signal_pipe(void (*func)(int));
void APP_CC g_signal_usr1(void (*func)(int));
@@ -146,6 +161,8 @@ int APP_CC g_initgroups(const char* user, int gid);
int APP_CC g_getuid(void);
int APP_CC g_getgid(void);
int APP_CC g_setuid(int pid);
+int APP_CC g_setsid(void);
+int APP_CC g_setlogin(const char *name);
int APP_CC g_waitchild(void);
int APP_CC g_waitpid(int pid);
void APP_CC g_clearenv(void);
@@ -154,8 +171,8 @@ char* APP_CC g_getenv(const char* name);
int APP_CC g_exit(int exit_code);
int APP_CC g_getpid(void);
int APP_CC g_sigterm(int pid);
-int APP_CC g_getuser_info(const char* username, int* gid, int* uid, char* shell,
- char* dir, char* gecos);
+int APP_CC g_getuser_info(const char* username, int* gid, int* uid, char** shell,
+ char** dir, char** gecos);
int APP_CC g_getgroup_info(const char* groupname, int* gid);
int APP_CC g_check_user_in_group(const char* username, int gid, int* ok);
int APP_CC g_time1(void);
@@ -167,5 +184,12 @@ int APP_CC g_text2bool(const char *s);
void * APP_CC g_shmat(int shmid);
int APP_CC g_shmdt(const void *shmaddr);
int APP_CC g_gethostname(char *name, int len);
+int APP_CC g_mirror_memcpy(void *dst, const void *src, int len);
+
+/* glib-style wrappers */
+#define g_new(struct_type, n_structs) \
+ (struct_type *) malloc(sizeof(struct_type) * (n_structs))
+#define g_new0(struct_type, n_structs) \
+ (struct_type *) calloc((n_structs), sizeof(struct_type))
#endif
diff --git a/common/parse.h b/common/parse.h
index 2ae3927b..b7f93bfe 100644
--- a/common/parse.h
+++ b/common/parse.h
@@ -40,13 +40,17 @@ struct stream
char *end;
char *data;
int size;
+ int pad0;
/* offsets of various headers */
char *iso_hdr;
char *mcs_hdr;
char *sec_hdr;
char *rdp_hdr;
char *channel_hdr;
+ /* other */
char *next_packet;
+ struct stream *next;
+ int *source;
};
/******************************************************************************/
diff --git a/common/pixman-region.c b/common/pixman-region.c
new file mode 100644
index 00000000..b1949950
--- /dev/null
+++ b/common/pixman-region.c
@@ -0,0 +1,2549 @@
+/*
+ * Copyright 1987, 1988, 1989, 1998 The Open Group
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of The Open Group shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from The Open Group.
+ *
+ * Copyright 1987, 1988, 1989 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define PIXREGION_NIL(reg) ((reg)->data && !(reg)->data->numRects)
+/* not a region */
+#define PIXREGION_NAR(reg) ((reg)->data == pixman_broken_data)
+#define PIXREGION_NUMRECTS(reg) ((reg)->data ? (reg)->data->numRects : 1)
+#define PIXREGION_SIZE(reg) ((reg)->data ? (reg)->data->size : 0)
+#define PIXREGION_RECTS(reg) \
+ ((reg)->data ? (box_type_t *)((reg)->data + 1) \
+ : &(reg)->extents)
+#define PIXREGION_BOXPTR(reg) ((box_type_t *)((reg)->data + 1))
+#define PIXREGION_BOX(reg, i) (&PIXREGION_BOXPTR (reg)[i])
+#define PIXREGION_TOP(reg) PIXREGION_BOX (reg, (reg)->data->numRects)
+#define PIXREGION_END(reg) PIXREGION_BOX (reg, (reg)->data->numRects - 1)
+
+#define GOOD_RECT(rect) ((rect)->x1 < (rect)->x2 && (rect)->y1 < (rect)->y2)
+#define BAD_RECT(rect) ((rect)->x1 > (rect)->x2 || (rect)->y1 > (rect)->y2)
+
+#ifdef DEBUG
+
+#define GOOD(reg) \
+ do \
+ { \
+ if (!PREFIX (_selfcheck (reg))) \
+ _pixman_log_error (FUNC, "Malformed region " # reg); \
+ } while (0)
+
+#else
+
+#define GOOD(reg)
+
+#endif
+
+static const box_type_t PREFIX (_empty_box_) = { 0, 0, 0, 0 };
+static const region_data_type_t PREFIX (_empty_data_) = { 0, 0 };
+#if defined (__llvm__) && !defined (__clang__)
+static const volatile region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
+#else
+static const region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
+#endif
+
+static box_type_t *pixman_region_empty_box =
+ (box_type_t *)&PREFIX (_empty_box_);
+static region_data_type_t *pixman_region_empty_data =
+ (region_data_type_t *)&PREFIX (_empty_data_);
+static region_data_type_t *pixman_broken_data =
+ (region_data_type_t *)&PREFIX (_broken_data_);
+
+static pixman_bool_t
+pixman_break (region_type_t *region);
+
+/*
+ * The functions in this file implement the Region abstraction used extensively
+ * throughout the X11 sample server. A Region is simply a set of disjoint
+ * (non-overlapping) rectangles, plus an "extent" rectangle which is the
+ * smallest single rectangle that contains all the non-overlapping rectangles.
+ *
+ * A Region is implemented as a "y-x-banded" array of rectangles. This array
+ * imposes two degrees of order. First, all rectangles are sorted by top side
+ * y coordinate first (y1), and then by left side x coordinate (x1).
+ *
+ * Furthermore, the rectangles are grouped into "bands". Each rectangle in a
+ * band has the same top y coordinate (y1), and each has the same bottom y
+ * coordinate (y2). Thus all rectangles in a band differ only in their left
+ * and right side (x1 and x2). Bands are implicit in the array of rectangles:
+ * there is no separate list of band start pointers.
+ *
+ * The y-x band representation does not minimize rectangles. In particular,
+ * if a rectangle vertically crosses a band (the rectangle has scanlines in
+ * the y1 to y2 area spanned by the band), then the rectangle may be broken
+ * down into two or more smaller rectangles stacked one atop the other.
+ *
+ * ----------- -----------
+ * | | | | band 0
+ * | | -------- ----------- --------
+ * | | | | in y-x banded | | | | band 1
+ * | | | | form is | | | |
+ * ----------- | | ----------- --------
+ * | | | | band 2
+ * -------- --------
+ *
+ * An added constraint on the rectangles is that they must cover as much
+ * horizontal area as possible: no two rectangles within a band are allowed
+ * to touch.
+ *
+ * Whenever possible, bands will be merged together to cover a greater vertical
+ * distance (and thus reduce the number of rectangles). Two bands can be merged
+ * only if the bottom of one touches the top of the other and they have
+ * rectangles in the same places (of the same width, of course).
+ *
+ * Adam de Boor wrote most of the original region code. Joel McCormack
+ * substantially modified or rewrote most of the core arithmetic routines, and
+ * added pixman_region_validate in order to support several speed improvements
+ * to pixman_region_validate_tree. Bob Scheifler changed the representation
+ * to be more compact when empty or a single rectangle, and did a bunch of
+ * gratuitous reformatting. Carl Worth did further gratuitous reformatting
+ * while re-merging the server and client region code into libpixregion.
+ * Soren Sandmann did even more gratuitous reformatting.
+ */
+
+/* true iff two Boxes overlap */
+#define EXTENTCHECK(r1, r2) \
+ (!( ((r1)->x2 <= (r2)->x1) || \
+ ((r1)->x1 >= (r2)->x2) || \
+ ((r1)->y2 <= (r2)->y1) || \
+ ((r1)->y1 >= (r2)->y2) ) )
+
+/* true iff (x,y) is in Box */
+#define INBOX(r, x, y) \
+ ( ((r)->x2 > x) && \
+ ((r)->x1 <= x) && \
+ ((r)->y2 > y) && \
+ ((r)->y1 <= y) )
+
+/* true iff Box r1 contains Box r2 */
+#define SUBSUMES(r1, r2) \
+ ( ((r1)->x1 <= (r2)->x1) && \
+ ((r1)->x2 >= (r2)->x2) && \
+ ((r1)->y1 <= (r2)->y1) && \
+ ((r1)->y2 >= (r2)->y2) )
+
+static size_t
+PIXREGION_SZOF (size_t n)
+{
+ size_t size = n * sizeof(box_type_t);
+
+ if (n > UINT32_MAX / sizeof(box_type_t))
+ return 0;
+
+ if (sizeof(region_data_type_t) > UINT32_MAX - size)
+ return 0;
+
+ return size + sizeof(region_data_type_t);
+}
+
+static region_data_type_t *
+alloc_data (size_t n)
+{
+ size_t sz = PIXREGION_SZOF (n);
+
+ if (!sz)
+ return NULL;
+
+ return (region_data_type_t *) malloc(sz);
+}
+
+#define FREE_DATA(reg) if ((reg)->data && (reg)->data->size) free ((reg)->data)
+
+#define RECTALLOC_BAIL(region, n, bail) \
+ do \
+ { \
+ if (!(region)->data || \
+ (((region)->data->numRects + (n)) > (region)->data->size)) \
+ { \
+ if (!pixman_rect_alloc (region, n)) \
+ goto bail; \
+ } \
+ } while (0)
+
+#define RECTALLOC(region, n) \
+ do \
+ { \
+ if (!(region)->data || \
+ (((region)->data->numRects + (n)) > (region)->data->size)) \
+ { \
+ if (!pixman_rect_alloc (region, n)) { \
+ return FALSE; \
+ } \
+ } \
+ } while (0)
+
+#define ADDRECT(next_rect, nx1, ny1, nx2, ny2) \
+ do \
+ { \
+ next_rect->x1 = nx1; \
+ next_rect->y1 = ny1; \
+ next_rect->x2 = nx2; \
+ next_rect->y2 = ny2; \
+ next_rect++; \
+ } \
+ while (0)
+
+#define NEWRECT(region, next_rect, nx1, ny1, nx2, ny2) \
+ do \
+ { \
+ if (!(region)->data || \
+ ((region)->data->numRects == (region)->data->size)) \
+ { \
+ if (!pixman_rect_alloc (region, 1)) \
+ return FALSE; \
+ next_rect = PIXREGION_TOP (region); \
+ } \
+ ADDRECT (next_rect, nx1, ny1, nx2, ny2); \
+ region->data->numRects++; \
+ critical_if_fail (region->data->numRects <= region->data->size); \
+ } while (0)
+
+#define DOWNSIZE(reg, numRects) \
+ do \
+ { \
+ if (((numRects) < ((reg)->data->size >> 1)) && \
+ ((reg)->data->size > 50)) \
+ { \
+ region_data_type_t * new_data; \
+ size_t data_size = PIXREGION_SZOF (numRects); \
+ \
+ if (!data_size) \
+ { \
+ new_data = NULL; \
+ } \
+ else \
+ { \
+ new_data = (region_data_type_t *) \
+ realloc ((reg)->data, data_size); \
+ } \
+ \
+ if (new_data) \
+ { \
+ new_data->size = (numRects); \
+ (reg)->data = new_data; \
+ } \
+ } \
+ } while (0)
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_equal) (region_type_t *reg1, region_type_t *reg2)
+{
+ int i;
+ box_type_t *rects1;
+ box_type_t *rects2;
+
+ if (reg1->extents.x1 != reg2->extents.x1)
+ return FALSE;
+
+ if (reg1->extents.x2 != reg2->extents.x2)
+ return FALSE;
+
+ if (reg1->extents.y1 != reg2->extents.y1)
+ return FALSE;
+
+ if (reg1->extents.y2 != reg2->extents.y2)
+ return FALSE;
+
+ if (PIXREGION_NUMRECTS (reg1) != PIXREGION_NUMRECTS (reg2))
+ return FALSE;
+
+ rects1 = PIXREGION_RECTS (reg1);
+ rects2 = PIXREGION_RECTS (reg2);
+
+ for (i = 0; i != PIXREGION_NUMRECTS (reg1); i++)
+ {
+ if (rects1[i].x1 != rects2[i].x1)
+ return FALSE;
+
+ if (rects1[i].x2 != rects2[i].x2)
+ return FALSE;
+
+ if (rects1[i].y1 != rects2[i].y1)
+ return FALSE;
+
+ if (rects1[i].y2 != rects2[i].y2)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int
+PREFIX (_print) (region_type_t *rgn)
+{
+ int num, size;
+ int i;
+ box_type_t * rects;
+
+ num = PIXREGION_NUMRECTS (rgn);
+ size = PIXREGION_SIZE (rgn);
+ rects = PIXREGION_RECTS (rgn);
+
+ fprintf (stderr, "num: %d size: %d\n", num, size);
+ fprintf (stderr, "extents: %d %d %d %d\n",
+ rgn->extents.x1,
+ rgn->extents.y1,
+ rgn->extents.x2,
+ rgn->extents.y2);
+
+ for (i = 0; i < num; i++)
+ {
+ fprintf (stderr, "%d %d %d %d \n",
+ rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
+ }
+
+ fprintf (stderr, "\n");
+
+ return(num);
+}
+
+
+PIXMAN_EXPORT void
+PREFIX (_init) (region_type_t *region)
+{
+ region->extents = *pixman_region_empty_box;
+ region->data = pixman_region_empty_data;
+}
+
+PIXMAN_EXPORT void
+PREFIX (_init_rect) (region_type_t * region,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ region->extents.x1 = x;
+ region->extents.y1 = y;
+ region->extents.x2 = x + width;
+ region->extents.y2 = y + height;
+
+ if (!GOOD_RECT (&region->extents))
+ {
+ if (BAD_RECT (&region->extents))
+ _pixman_log_error (FUNC, "Invalid rectangle passed");
+ PREFIX (_init) (region);
+ return;
+ }
+
+ region->data = NULL;
+}
+
+PIXMAN_EXPORT void
+PREFIX (_init_with_extents) (region_type_t *region, box_type_t *extents)
+{
+ if (!GOOD_RECT (extents))
+ {
+ if (BAD_RECT (extents))
+ _pixman_log_error (FUNC, "Invalid rectangle passed");
+ PREFIX (_init) (region);
+ return;
+ }
+ region->extents = *extents;
+
+ region->data = NULL;
+}
+
+PIXMAN_EXPORT void
+PREFIX (_fini) (region_type_t *region)
+{
+ GOOD (region);
+ FREE_DATA (region);
+}
+
+PIXMAN_EXPORT int
+PREFIX (_n_rects) (region_type_t *region)
+{
+ return PIXREGION_NUMRECTS (region);
+}
+
+PIXMAN_EXPORT box_type_t *
+PREFIX (_rectangles) (region_type_t *region,
+ int *n_rects)
+{
+ if (n_rects)
+ *n_rects = PIXREGION_NUMRECTS (region);
+
+ return PIXREGION_RECTS (region);
+}
+
+static pixman_bool_t
+pixman_break (region_type_t *region)
+{
+ FREE_DATA (region);
+
+ region->extents = *pixman_region_empty_box;
+ region->data = pixman_broken_data;
+
+ return FALSE;
+}
+
+static pixman_bool_t
+pixman_rect_alloc (region_type_t * region,
+ int n)
+{
+ region_data_type_t *data;
+
+ if (!region->data)
+ {
+ n++;
+ region->data = alloc_data (n);
+
+ if (!region->data)
+ return pixman_break (region);
+
+ region->data->numRects = 1;
+ *PIXREGION_BOXPTR (region) = region->extents;
+ }
+ else if (!region->data->size)
+ {
+ region->data = alloc_data (n);
+
+ if (!region->data)
+ return pixman_break (region);
+
+ region->data->numRects = 0;
+ }
+ else
+ {
+ size_t data_size;
+
+ if (n == 1)
+ {
+ n = region->data->numRects;
+ if (n > 500) /* XXX pick numbers out of a hat */
+ n = 250;
+ }
+
+ n += region->data->numRects;
+ data_size = PIXREGION_SZOF (n);
+
+ if (!data_size)
+ {
+ data = NULL;
+ }
+ else
+ {
+ data = (region_data_type_t *)
+ realloc (region->data, PIXREGION_SZOF (n));
+ }
+
+ if (!data)
+ return pixman_break (region);
+
+ region->data = data;
+ }
+
+ region->data->size = n;
+
+ return TRUE;
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_copy) (region_type_t *dst, region_type_t *src)
+{
+ GOOD (dst);
+ GOOD (src);
+
+ if (dst == src)
+ return TRUE;
+
+ dst->extents = src->extents;
+
+ if (!src->data || !src->data->size)
+ {
+ FREE_DATA (dst);
+ dst->data = src->data;
+ return TRUE;
+ }
+
+ if (!dst->data || (dst->data->size < src->data->numRects))
+ {
+ FREE_DATA (dst);
+
+ dst->data = alloc_data (src->data->numRects);
+
+ if (!dst->data)
+ return pixman_break (dst);
+
+ dst->data->size = src->data->numRects;
+ }
+
+ dst->data->numRects = src->data->numRects;
+
+ memmove ((char *)PIXREGION_BOXPTR (dst), (char *)PIXREGION_BOXPTR (src),
+ dst->data->numRects * sizeof(box_type_t));
+
+ return TRUE;
+}
+
+/*======================================================================
+ * Generic Region Operator
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_coalesce --
+ * Attempt to merge the boxes in the current band with those in the
+ * previous one. We are guaranteed that the current band extends to
+ * the end of the rects array. Used only by pixman_op.
+ *
+ * Results:
+ * The new index for the previous band.
+ *
+ * Side Effects:
+ * If coalescing takes place:
+ * - rectangles in the previous band will have their y2 fields
+ * altered.
+ * - region->data->numRects will be decreased.
+ *
+ *-----------------------------------------------------------------------
+ */
+static inline int
+pixman_coalesce (region_type_t * region, /* Region to coalesce */
+ int prev_start, /* Index of start of previous band */
+ int cur_start) /* Index of start of current band */
+{
+ box_type_t *prev_box; /* Current box in previous band */
+ box_type_t *cur_box; /* Current box in current band */
+ int numRects; /* Number rectangles in both bands */
+ int y2; /* Bottom of current band */
+
+ /*
+ * Figure out how many rectangles are in the band.
+ */
+ numRects = cur_start - prev_start;
+ critical_if_fail (numRects == region->data->numRects - cur_start);
+
+ if (!numRects) return cur_start;
+
+ /*
+ * The bands may only be coalesced if the bottom of the previous
+ * matches the top scanline of the current.
+ */
+ prev_box = PIXREGION_BOX (region, prev_start);
+ cur_box = PIXREGION_BOX (region, cur_start);
+ if (prev_box->y2 != cur_box->y1) return cur_start;
+
+ /*
+ * Make sure the bands have boxes in the same places. This
+ * assumes that boxes have been added in such a way that they
+ * cover the most area possible. I.e. two boxes in a band must
+ * have some horizontal space between them.
+ */
+ y2 = cur_box->y2;
+
+ do
+ {
+ if ((prev_box->x1 != cur_box->x1) || (prev_box->x2 != cur_box->x2))
+ return (cur_start);
+
+ prev_box++;
+ cur_box++;
+ numRects--;
+ }
+ while (numRects);
+
+ /*
+ * The bands may be merged, so set the bottom y of each box
+ * in the previous band to the bottom y of the current band.
+ */
+ numRects = cur_start - prev_start;
+ region->data->numRects -= numRects;
+
+ do
+ {
+ prev_box--;
+ prev_box->y2 = y2;
+ numRects--;
+ }
+ while (numRects);
+
+ return prev_start;
+}
+
+/* Quicky macro to avoid trivial reject procedure calls to pixman_coalesce */
+
+#define COALESCE(new_reg, prev_band, cur_band) \
+ do \
+ { \
+ if (cur_band - prev_band == new_reg->data->numRects - cur_band) \
+ prev_band = pixman_coalesce (new_reg, prev_band, cur_band); \
+ else \
+ prev_band = cur_band; \
+ } while (0)
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_append_non_o --
+ * Handle a non-overlapping band for the union and subtract operations.
+ * Just adds the (top/bottom-clipped) rectangles into the region.
+ * Doesn't have to check for subsumption or anything.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * region->data->numRects is incremented and the rectangles overwritten
+ * with the rectangles we're passed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static inline pixman_bool_t
+pixman_region_append_non_o (region_type_t * region,
+ box_type_t * r,
+ box_type_t * r_end,
+ int y1,
+ int y2)
+{
+ box_type_t *next_rect;
+ int new_rects;
+
+ new_rects = r_end - r;
+
+ critical_if_fail (y1 < y2);
+ critical_if_fail (new_rects != 0);
+
+ /* Make sure we have enough space for all rectangles to be added */
+ RECTALLOC (region, new_rects);
+ next_rect = PIXREGION_TOP (region);
+ region->data->numRects += new_rects;
+
+ do
+ {
+ critical_if_fail (r->x1 < r->x2);
+ ADDRECT (next_rect, r->x1, y1, r->x2, y2);
+ r++;
+ }
+ while (r != r_end);
+
+ return TRUE;
+}
+
+#define FIND_BAND(r, r_band_end, r_end, ry1) \
+ do \
+ { \
+ ry1 = r->y1; \
+ r_band_end = r + 1; \
+ while ((r_band_end != r_end) && (r_band_end->y1 == ry1)) { \
+ r_band_end++; \
+ } \
+ } while (0)
+
+#define APPEND_REGIONS(new_reg, r, r_end) \
+ do \
+ { \
+ int new_rects; \
+ if ((new_rects = r_end - r)) { \
+ RECTALLOC_BAIL (new_reg, new_rects, bail); \
+ memmove ((char *)PIXREGION_TOP (new_reg), (char *)r, \
+ new_rects * sizeof(box_type_t)); \
+ new_reg->data->numRects += new_rects; \
+ } \
+ } while (0)
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_op --
+ * Apply an operation to two regions. Called by pixman_region_union, pixman_region_inverse,
+ * pixman_region_subtract, pixman_region_intersect.... Both regions MUST have at least one
+ * rectangle, and cannot be the same object.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * The new region is overwritten.
+ * overlap set to TRUE if overlap_func ever returns TRUE.
+ *
+ * Notes:
+ * The idea behind this function is to view the two regions as sets.
+ * Together they cover a rectangle of area that this function divides
+ * into horizontal bands where points are covered only by one region
+ * or by both. For the first case, the non_overlap_func is called with
+ * each the band and the band's upper and lower extents. For the
+ * second, the overlap_func is called to process the entire band. It
+ * is responsible for clipping the rectangles in the band, though
+ * this function provides the boundaries.
+ * At the end of each band, the new region is coalesced, if possible,
+ * to reduce the number of rectangles in the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+typedef pixman_bool_t (*overlap_proc_ptr) (region_type_t *region,
+ box_type_t * r1,
+ box_type_t * r1_end,
+ box_type_t * r2,
+ box_type_t * r2_end,
+ int y1,
+ int y2);
+
+static pixman_bool_t
+pixman_op (region_type_t * new_reg, /* Place to store result */
+ region_type_t * reg1, /* First region in operation */
+ region_type_t * reg2, /* 2d region in operation */
+ overlap_proc_ptr overlap_func, /* Function to call for over-
+ * lapping bands */
+ int append_non1, /* Append non-overlapping bands
+ * in region 1 ?
+ */
+ int append_non2 /* Append non-overlapping bands
+ * in region 2 ?
+ */
+ )
+{
+ box_type_t *r1; /* Pointer into first region */
+ box_type_t *r2; /* Pointer into 2d region */
+ box_type_t *r1_end; /* End of 1st region */
+ box_type_t *r2_end; /* End of 2d region */
+ int ybot; /* Bottom of intersection */
+ int ytop; /* Top of intersection */
+ region_data_type_t *old_data; /* Old data for new_reg */
+ int prev_band; /* Index of start of
+ * previous band in new_reg */
+ int cur_band; /* Index of start of current
+ * band in new_reg */
+ box_type_t * r1_band_end; /* End of current band in r1 */
+ box_type_t * r2_band_end; /* End of current band in r2 */
+ int top; /* Top of non-overlapping band */
+ int bot; /* Bottom of non-overlapping band*/
+ int r1y1; /* Temps for r1->y1 and r2->y1 */
+ int r2y1;
+ int new_size;
+ int numRects;
+
+ /*
+ * Break any region computed from a broken region
+ */
+ if (PIXREGION_NAR (reg1) || PIXREGION_NAR (reg2))
+ return pixman_break (new_reg);
+
+ /*
+ * Initialization:
+ * set r1, r2, r1_end and r2_end appropriately, save the rectangles
+ * of the destination region until the end in case it's one of
+ * the two source regions, then mark the "new" region empty, allocating
+ * another array of rectangles for it to use.
+ */
+
+ r1 = PIXREGION_RECTS (reg1);
+ new_size = PIXREGION_NUMRECTS (reg1);
+ r1_end = r1 + new_size;
+
+ numRects = PIXREGION_NUMRECTS (reg2);
+ r2 = PIXREGION_RECTS (reg2);
+ r2_end = r2 + numRects;
+
+ critical_if_fail (r1 != r1_end);
+ critical_if_fail (r2 != r2_end);
+
+ old_data = (region_data_type_t *)NULL;
+
+ if (((new_reg == reg1) && (new_size > 1)) ||
+ ((new_reg == reg2) && (numRects > 1)))
+ {
+ old_data = new_reg->data;
+ new_reg->data = pixman_region_empty_data;
+ }
+
+ /* guess at new size */
+ if (numRects > new_size)
+ new_size = numRects;
+
+ new_size <<= 1;
+
+ if (!new_reg->data)
+ new_reg->data = pixman_region_empty_data;
+ else if (new_reg->data->size)
+ new_reg->data->numRects = 0;
+
+ if (new_size > new_reg->data->size)
+ {
+ if (!pixman_rect_alloc (new_reg, new_size))
+ {
+ free (old_data);
+ return FALSE;
+ }
+ }
+
+ /*
+ * Initialize ybot.
+ * In the upcoming loop, ybot and ytop serve different functions depending
+ * on whether the band being handled is an overlapping or non-overlapping
+ * band.
+ * In the case of a non-overlapping band (only one of the regions
+ * has points in the band), ybot is the bottom of the most recent
+ * intersection and thus clips the top of the rectangles in that band.
+ * ytop is the top of the next intersection between the two regions and
+ * serves to clip the bottom of the rectangles in the current band.
+ * For an overlapping band (where the two regions intersect), ytop clips
+ * the top of the rectangles of both regions and ybot clips the bottoms.
+ */
+
+ ybot = MIN (r1->y1, r2->y1);
+
+ /*
+ * prev_band serves to mark the start of the previous band so rectangles
+ * can be coalesced into larger rectangles. qv. pixman_coalesce, above.
+ * In the beginning, there is no previous band, so prev_band == cur_band
+ * (cur_band is set later on, of course, but the first band will always
+ * start at index 0). prev_band and cur_band must be indices because of
+ * the possible expansion, and resultant moving, of the new region's
+ * array of rectangles.
+ */
+ prev_band = 0;
+
+ do
+ {
+ /*
+ * This algorithm proceeds one source-band (as opposed to a
+ * destination band, which is determined by where the two regions
+ * intersect) at a time. r1_band_end and r2_band_end serve to mark the
+ * rectangle after the last one in the current band for their
+ * respective regions.
+ */
+ critical_if_fail (r1 != r1_end);
+ critical_if_fail (r2 != r2_end);
+
+ FIND_BAND (r1, r1_band_end, r1_end, r1y1);
+ FIND_BAND (r2, r2_band_end, r2_end, r2y1);
+
+ /*
+ * First handle the band that doesn't intersect, if any.
+ *
+ * Note that attention is restricted to one band in the
+ * non-intersecting region at once, so if a region has n
+ * bands between the current position and the next place it overlaps
+ * the other, this entire loop will be passed through n times.
+ */
+ if (r1y1 < r2y1)
+ {
+ if (append_non1)
+ {
+ top = MAX (r1y1, ybot);
+ bot = MIN (r1->y2, r2y1);
+ if (top != bot)
+ {
+ cur_band = new_reg->data->numRects;
+ if (!pixman_region_append_non_o (new_reg, r1, r1_band_end, top, bot))
+ goto bail;
+ COALESCE (new_reg, prev_band, cur_band);
+ }
+ }
+ ytop = r2y1;
+ }
+ else if (r2y1 < r1y1)
+ {
+ if (append_non2)
+ {
+ top = MAX (r2y1, ybot);
+ bot = MIN (r2->y2, r1y1);
+
+ if (top != bot)
+ {
+ cur_band = new_reg->data->numRects;
+
+ if (!pixman_region_append_non_o (new_reg, r2, r2_band_end, top, bot))
+ goto bail;
+
+ COALESCE (new_reg, prev_band, cur_band);
+ }
+ }
+ ytop = r1y1;
+ }
+ else
+ {
+ ytop = r1y1;
+ }
+
+ /*
+ * Now see if we've hit an intersecting band. The two bands only
+ * intersect if ybot > ytop
+ */
+ ybot = MIN (r1->y2, r2->y2);
+ if (ybot > ytop)
+ {
+ cur_band = new_reg->data->numRects;
+
+ if (!(*overlap_func)(new_reg,
+ r1, r1_band_end,
+ r2, r2_band_end,
+ ytop, ybot))
+ {
+ goto bail;
+ }
+
+ COALESCE (new_reg, prev_band, cur_band);
+ }
+
+ /*
+ * If we've finished with a band (y2 == ybot) we skip forward
+ * in the region to the next band.
+ */
+ if (r1->y2 == ybot)
+ r1 = r1_band_end;
+
+ if (r2->y2 == ybot)
+ r2 = r2_band_end;
+
+ }
+ while (r1 != r1_end && r2 != r2_end);
+
+ /*
+ * Deal with whichever region (if any) still has rectangles left.
+ *
+ * We only need to worry about banding and coalescing for the very first
+ * band left. After that, we can just group all remaining boxes,
+ * regardless of how many bands, into one final append to the list.
+ */
+
+ if ((r1 != r1_end) && append_non1)
+ {
+ /* Do first non_overlap1Func call, which may be able to coalesce */
+ FIND_BAND (r1, r1_band_end, r1_end, r1y1);
+
+ cur_band = new_reg->data->numRects;
+
+ if (!pixman_region_append_non_o (new_reg,
+ r1, r1_band_end,
+ MAX (r1y1, ybot), r1->y2))
+ {
+ goto bail;
+ }
+
+ COALESCE (new_reg, prev_band, cur_band);
+
+ /* Just append the rest of the boxes */
+ APPEND_REGIONS (new_reg, r1_band_end, r1_end);
+ }
+ else if ((r2 != r2_end) && append_non2)
+ {
+ /* Do first non_overlap2Func call, which may be able to coalesce */
+ FIND_BAND (r2, r2_band_end, r2_end, r2y1);
+
+ cur_band = new_reg->data->numRects;
+
+ if (!pixman_region_append_non_o (new_reg,
+ r2, r2_band_end,
+ MAX (r2y1, ybot), r2->y2))
+ {
+ goto bail;
+ }
+
+ COALESCE (new_reg, prev_band, cur_band);
+
+ /* Append rest of boxes */
+ APPEND_REGIONS (new_reg, r2_band_end, r2_end);
+ }
+
+ free (old_data);
+
+ if (!(numRects = new_reg->data->numRects))
+ {
+ FREE_DATA (new_reg);
+ new_reg->data = pixman_region_empty_data;
+ }
+ else if (numRects == 1)
+ {
+ new_reg->extents = *PIXREGION_BOXPTR (new_reg);
+ FREE_DATA (new_reg);
+ new_reg->data = (region_data_type_t *)NULL;
+ }
+ else
+ {
+ DOWNSIZE (new_reg, numRects);
+ }
+
+ return TRUE;
+
+bail:
+ free (old_data);
+
+ return pixman_break (new_reg);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_set_extents --
+ * Reset the extents of a region to what they should be. Called by
+ * pixman_region_subtract and pixman_region_intersect as they can't
+ * figure it out along the way or do so easily, as pixman_region_union can.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The region's 'extents' structure is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+pixman_set_extents (region_type_t *region)
+{
+ box_type_t *box, *box_end;
+
+ if (!region->data)
+ return;
+
+ if (!region->data->size)
+ {
+ region->extents.x2 = region->extents.x1;
+ region->extents.y2 = region->extents.y1;
+ return;
+ }
+
+ box = PIXREGION_BOXPTR (region);
+ box_end = PIXREGION_END (region);
+
+ /*
+ * Since box is the first rectangle in the region, it must have the
+ * smallest y1 and since box_end is the last rectangle in the region,
+ * it must have the largest y2, because of banding. Initialize x1 and
+ * x2 from box and box_end, resp., as good things to initialize them
+ * to...
+ */
+ region->extents.x1 = box->x1;
+ region->extents.y1 = box->y1;
+ region->extents.x2 = box_end->x2;
+ region->extents.y2 = box_end->y2;
+
+ critical_if_fail (region->extents.y1 < region->extents.y2);
+
+ while (box <= box_end)
+ {
+ if (box->x1 < region->extents.x1)
+ region->extents.x1 = box->x1;
+ if (box->x2 > region->extents.x2)
+ region->extents.x2 = box->x2;
+ box++;
+ }
+
+ critical_if_fail (region->extents.x1 < region->extents.x2);
+}
+
+/*======================================================================
+ * Region Intersection
+ *====================================================================*/
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_intersect_o --
+ * Handle an overlapping band for pixman_region_intersect.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * Rectangles may be added to the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static pixman_bool_t
+pixman_region_intersect_o (region_type_t *region,
+ box_type_t * r1,
+ box_type_t * r1_end,
+ box_type_t * r2,
+ box_type_t * r2_end,
+ int y1,
+ int y2)
+{
+ int x1;
+ int x2;
+ box_type_t * next_rect;
+
+ next_rect = PIXREGION_TOP (region);
+
+ critical_if_fail (y1 < y2);
+ critical_if_fail (r1 != r1_end && r2 != r2_end);
+
+ do
+ {
+ x1 = MAX (r1->x1, r2->x1);
+ x2 = MIN (r1->x2, r2->x2);
+
+ /*
+ * If there's any overlap between the two rectangles, add that
+ * overlap to the new region.
+ */
+ if (x1 < x2)
+ NEWRECT (region, next_rect, x1, y1, x2, y2);
+
+ /*
+ * Advance the pointer(s) with the leftmost right side, since the next
+ * rectangle on that list may still overlap the other region's
+ * current rectangle.
+ */
+ if (r1->x2 == x2)
+ {
+ r1++;
+ }
+ if (r2->x2 == x2)
+ {
+ r2++;
+ }
+ }
+ while ((r1 != r1_end) && (r2 != r2_end));
+
+ return TRUE;
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_intersect) (region_type_t * new_reg,
+ region_type_t * reg1,
+ region_type_t * reg2)
+{
+ GOOD (reg1);
+ GOOD (reg2);
+ GOOD (new_reg);
+
+ /* check for trivial reject */
+ if (PIXREGION_NIL (reg1) || PIXREGION_NIL (reg2) ||
+ !EXTENTCHECK (&reg1->extents, &reg2->extents))
+ {
+ /* Covers about 20% of all cases */
+ FREE_DATA (new_reg);
+ new_reg->extents.x2 = new_reg->extents.x1;
+ new_reg->extents.y2 = new_reg->extents.y1;
+ if (PIXREGION_NAR (reg1) || PIXREGION_NAR (reg2))
+ {
+ new_reg->data = pixman_broken_data;
+ return FALSE;
+ }
+ else
+ {
+ new_reg->data = pixman_region_empty_data;
+ }
+ }
+ else if (!reg1->data && !reg2->data)
+ {
+ /* Covers about 80% of cases that aren't trivially rejected */
+ new_reg->extents.x1 = MAX (reg1->extents.x1, reg2->extents.x1);
+ new_reg->extents.y1 = MAX (reg1->extents.y1, reg2->extents.y1);
+ new_reg->extents.x2 = MIN (reg1->extents.x2, reg2->extents.x2);
+ new_reg->extents.y2 = MIN (reg1->extents.y2, reg2->extents.y2);
+
+ FREE_DATA (new_reg);
+
+ new_reg->data = (region_data_type_t *)NULL;
+ }
+ else if (!reg2->data && SUBSUMES (&reg2->extents, &reg1->extents))
+ {
+ return PREFIX (_copy) (new_reg, reg1);
+ }
+ else if (!reg1->data && SUBSUMES (&reg1->extents, &reg2->extents))
+ {
+ return PREFIX (_copy) (new_reg, reg2);
+ }
+ else if (reg1 == reg2)
+ {
+ return PREFIX (_copy) (new_reg, reg1);
+ }
+ else
+ {
+ /* General purpose intersection */
+
+ if (!pixman_op (new_reg, reg1, reg2, pixman_region_intersect_o, FALSE, FALSE))
+ return FALSE;
+
+ pixman_set_extents (new_reg);
+ }
+
+ GOOD (new_reg);
+ return(TRUE);
+}
+
+#define MERGERECT(r) \
+ do \
+ { \
+ if (r->x1 <= x2) \
+ { \
+ /* Merge with current rectangle */ \
+ if (x2 < r->x2) \
+ x2 = r->x2; \
+ } \
+ else \
+ { \
+ /* Add current rectangle, start new one */ \
+ NEWRECT (region, next_rect, x1, y1, x2, y2); \
+ x1 = r->x1; \
+ x2 = r->x2; \
+ } \
+ r++; \
+ } while (0)
+
+/*======================================================================
+ * Region Union
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_union_o --
+ * Handle an overlapping band for the union operation. Picks the
+ * left-most rectangle each time and merges it into the region.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * region is overwritten.
+ * overlap is set to TRUE if any boxes overlap.
+ *
+ *-----------------------------------------------------------------------
+ */
+static pixman_bool_t
+pixman_region_union_o (region_type_t *region,
+ box_type_t * r1,
+ box_type_t * r1_end,
+ box_type_t * r2,
+ box_type_t * r2_end,
+ int y1,
+ int y2)
+{
+ box_type_t *next_rect;
+ int x1; /* left and right side of current union */
+ int x2;
+
+ critical_if_fail (y1 < y2);
+ critical_if_fail (r1 != r1_end && r2 != r2_end);
+
+ next_rect = PIXREGION_TOP (region);
+
+ /* Start off current rectangle */
+ if (r1->x1 < r2->x1)
+ {
+ x1 = r1->x1;
+ x2 = r1->x2;
+ r1++;
+ }
+ else
+ {
+ x1 = r2->x1;
+ x2 = r2->x2;
+ r2++;
+ }
+ while (r1 != r1_end && r2 != r2_end)
+ {
+ if (r1->x1 < r2->x1)
+ MERGERECT (r1);
+ else
+ MERGERECT (r2);
+ }
+
+ /* Finish off whoever (if any) is left */
+ if (r1 != r1_end)
+ {
+ do
+ {
+ MERGERECT (r1);
+ }
+ while (r1 != r1_end);
+ }
+ else if (r2 != r2_end)
+ {
+ do
+ {
+ MERGERECT (r2);
+ }
+ while (r2 != r2_end);
+ }
+
+ /* Add current rectangle */
+ NEWRECT (region, next_rect, x1, y1, x2, y2);
+
+ return TRUE;
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX(_intersect_rect) (region_type_t *dest,
+ region_type_t *source,
+ int x, int y,
+ unsigned int width,
+ unsigned int height)
+{
+ region_type_t region;
+
+ region.data = NULL;
+ region.extents.x1 = x;
+ region.extents.y1 = y;
+ region.extents.x2 = x + width;
+ region.extents.y2 = y + height;
+
+ return PREFIX(_intersect) (dest, source, &region);
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_union) (region_type_t *new_reg,
+ region_type_t *reg1,
+ region_type_t *reg2)
+{
+ /* Return TRUE if some overlap
+ * between reg1, reg2
+ */
+ GOOD (reg1);
+ GOOD (reg2);
+ GOOD (new_reg);
+
+ /* checks all the simple cases */
+
+ /*
+ * Region 1 and 2 are the same
+ */
+ if (reg1 == reg2)
+ return PREFIX (_copy) (new_reg, reg1);
+
+ /*
+ * Region 1 is empty
+ */
+ if (PIXREGION_NIL (reg1))
+ {
+ if (PIXREGION_NAR (reg1))
+ return pixman_break (new_reg);
+
+ if (new_reg != reg2)
+ return PREFIX (_copy) (new_reg, reg2);
+
+ return TRUE;
+ }
+
+ /*
+ * Region 2 is empty
+ */
+ if (PIXREGION_NIL (reg2))
+ {
+ if (PIXREGION_NAR (reg2))
+ return pixman_break (new_reg);
+
+ if (new_reg != reg1)
+ return PREFIX (_copy) (new_reg, reg1);
+
+ return TRUE;
+ }
+
+ /*
+ * Region 1 completely subsumes region 2
+ */
+ if (!reg1->data && SUBSUMES (&reg1->extents, &reg2->extents))
+ {
+ if (new_reg != reg1)
+ return PREFIX (_copy) (new_reg, reg1);
+
+ return TRUE;
+ }
+
+ /*
+ * Region 2 completely subsumes region 1
+ */
+ if (!reg2->data && SUBSUMES (&reg2->extents, &reg1->extents))
+ {
+ if (new_reg != reg2)
+ return PREFIX (_copy) (new_reg, reg2);
+
+ return TRUE;
+ }
+
+ if (!pixman_op (new_reg, reg1, reg2, pixman_region_union_o, TRUE, TRUE))
+ return FALSE;
+
+ new_reg->extents.x1 = MIN (reg1->extents.x1, reg2->extents.x1);
+ new_reg->extents.y1 = MIN (reg1->extents.y1, reg2->extents.y1);
+ new_reg->extents.x2 = MAX (reg1->extents.x2, reg2->extents.x2);
+ new_reg->extents.y2 = MAX (reg1->extents.y2, reg2->extents.y2);
+
+ GOOD (new_reg);
+
+ return TRUE;
+}
+
+/* Convenience function for performing union of region with a
+ * single rectangle
+ */
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_union_rect) (region_type_t *dest,
+ region_type_t *source,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ region_type_t region;
+
+ region.extents.x1 = x;
+ region.extents.y1 = y;
+ region.extents.x2 = x + width;
+ region.extents.y2 = y + height;
+
+ if (!GOOD_RECT (&region.extents))
+ {
+ if (BAD_RECT (&region.extents))
+ _pixman_log_error (FUNC, "Invalid rectangle passed");
+ return PREFIX (_copy) (dest, source);
+ }
+
+ region.data = NULL;
+
+ return PREFIX (_union) (dest, source, &region);
+}
+
+/*======================================================================
+ * Batch Rectangle Union
+ *====================================================================*/
+
+#define EXCHANGE_RECTS(a, b) \
+ { \
+ box_type_t t; \
+ t = rects[a]; \
+ rects[a] = rects[b]; \
+ rects[b] = t; \
+ }
+
+static void
+quick_sort_rects (
+ box_type_t rects[],
+ int numRects)
+{
+ int y1;
+ int x1;
+ int i, j;
+ box_type_t *r;
+
+ /* Always called with numRects > 1 */
+
+ do
+ {
+ if (numRects == 2)
+ {
+ if (rects[0].y1 > rects[1].y1 ||
+ (rects[0].y1 == rects[1].y1 && rects[0].x1 > rects[1].x1))
+ {
+ EXCHANGE_RECTS (0, 1);
+ }
+
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ EXCHANGE_RECTS (0, numRects >> 1);
+ y1 = rects[0].y1;
+ x1 = rects[0].x1;
+
+ /* Partition array */
+ i = 0;
+ j = numRects;
+
+ do
+ {
+ r = &(rects[i]);
+ do
+ {
+ r++;
+ i++;
+ }
+ while (i != numRects && (r->y1 < y1 || (r->y1 == y1 && r->x1 < x1)));
+
+ r = &(rects[j]);
+ do
+ {
+ r--;
+ j--;
+ }
+ while (y1 < r->y1 || (y1 == r->y1 && x1 < r->x1));
+
+ if (i < j)
+ EXCHANGE_RECTS (i, j);
+ }
+ while (i < j);
+
+ /* Move partition element back to middle */
+ EXCHANGE_RECTS (0, j);
+
+ /* Recurse */
+ if (numRects - j - 1 > 1)
+ quick_sort_rects (&rects[j + 1], numRects - j - 1);
+
+ numRects = j;
+ }
+ while (numRects > 1);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_validate --
+ *
+ * Take a ``region'' which is a non-y-x-banded random collection of
+ * rectangles, and compute a nice region which is the union of all the
+ * rectangles.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * The passed-in ``region'' may be modified.
+ * overlap set to TRUE if any retangles overlapped,
+ * else FALSE;
+ *
+ * Strategy:
+ * Step 1. Sort the rectangles into ascending order with primary key y1
+ * and secondary key x1.
+ *
+ * Step 2. Split the rectangles into the minimum number of proper y-x
+ * banded regions. This may require horizontally merging
+ * rectangles, and vertically coalescing bands. With any luck,
+ * this step in an identity transformation (ala the Box widget),
+ * or a coalescing into 1 box (ala Menus).
+ *
+ * Step 3. Merge the separate regions down to a single region by calling
+ * pixman_region_union. Maximize the work each pixman_region_union call does by using
+ * a binary merge.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+static pixman_bool_t
+validate (region_type_t * badreg)
+{
+ /* Descriptor for regions under construction in Step 2. */
+ typedef struct
+ {
+ region_type_t reg;
+ int prev_band;
+ int cur_band;
+ } region_info_t;
+
+ region_info_t stack_regions[64];
+
+ int numRects; /* Original numRects for badreg */
+ region_info_t *ri; /* Array of current regions */
+ int num_ri; /* Number of entries used in ri */
+ int size_ri; /* Number of entries available in ri */
+ int i; /* Index into rects */
+ int j; /* Index into ri */
+ region_info_t *rit; /* &ri[j] */
+ region_type_t *reg; /* ri[j].reg */
+ box_type_t *box; /* Current box in rects */
+ box_type_t *ri_box; /* Last box in ri[j].reg */
+ region_type_t *hreg; /* ri[j_half].reg */
+ pixman_bool_t ret = TRUE;
+
+ if (!badreg->data)
+ {
+ GOOD (badreg);
+ return TRUE;
+ }
+
+ numRects = badreg->data->numRects;
+ if (!numRects)
+ {
+ if (PIXREGION_NAR (badreg))
+ return FALSE;
+ GOOD (badreg);
+ return TRUE;
+ }
+
+ if (badreg->extents.x1 < badreg->extents.x2)
+ {
+ if ((numRects) == 1)
+ {
+ FREE_DATA (badreg);
+ badreg->data = (region_data_type_t *) NULL;
+ }
+ else
+ {
+ DOWNSIZE (badreg, numRects);
+ }
+
+ GOOD (badreg);
+
+ return TRUE;
+ }
+
+ /* Step 1: Sort the rects array into ascending (y1, x1) order */
+ quick_sort_rects (PIXREGION_BOXPTR (badreg), numRects);
+
+ /* Step 2: Scatter the sorted array into the minimum number of regions */
+
+ /* Set up the first region to be the first rectangle in badreg */
+ /* Note that step 2 code will never overflow the ri[0].reg rects array */
+ ri = stack_regions;
+ size_ri = sizeof (stack_regions) / sizeof (stack_regions[0]);
+ num_ri = 1;
+ ri[0].prev_band = 0;
+ ri[0].cur_band = 0;
+ ri[0].reg = *badreg;
+ box = PIXREGION_BOXPTR (&ri[0].reg);
+ ri[0].reg.extents = *box;
+ ri[0].reg.data->numRects = 1;
+ badreg->extents = *pixman_region_empty_box;
+ badreg->data = pixman_region_empty_data;
+
+ /* Now scatter rectangles into the minimum set of valid regions. If the
+ * next rectangle to be added to a region would force an existing rectangle
+ * in the region to be split up in order to maintain y-x banding, just
+ * forget it. Try the next region. If it doesn't fit cleanly into any
+ * region, make a new one.
+ */
+
+ for (i = numRects; --i > 0;)
+ {
+ box++;
+ /* Look for a region to append box to */
+ for (j = num_ri, rit = ri; --j >= 0; rit++)
+ {
+ reg = &rit->reg;
+ ri_box = PIXREGION_END (reg);
+
+ if (box->y1 == ri_box->y1 && box->y2 == ri_box->y2)
+ {
+ /* box is in same band as ri_box. Merge or append it */
+ if (box->x1 <= ri_box->x2)
+ {
+ /* Merge it with ri_box */
+ if (box->x2 > ri_box->x2)
+ ri_box->x2 = box->x2;
+ }
+ else
+ {
+ RECTALLOC_BAIL (reg, 1, bail);
+ *PIXREGION_TOP (reg) = *box;
+ reg->data->numRects++;
+ }
+
+ goto next_rect; /* So sue me */
+ }
+ else if (box->y1 >= ri_box->y2)
+ {
+ /* Put box into new band */
+ if (reg->extents.x2 < ri_box->x2)
+ reg->extents.x2 = ri_box->x2;
+
+ if (reg->extents.x1 > box->x1)
+ reg->extents.x1 = box->x1;
+
+ COALESCE (reg, rit->prev_band, rit->cur_band);
+ rit->cur_band = reg->data->numRects;
+ RECTALLOC_BAIL (reg, 1, bail);
+ *PIXREGION_TOP (reg) = *box;
+ reg->data->numRects++;
+
+ goto next_rect;
+ }
+ /* Well, this region was inappropriate. Try the next one. */
+ } /* for j */
+
+ /* Uh-oh. No regions were appropriate. Create a new one. */
+ if (size_ri == num_ri)
+ {
+ size_t data_size;
+
+ /* Oops, allocate space for new region information */
+ size_ri <<= 1;
+
+ data_size = size_ri * sizeof(region_info_t);
+ if (data_size / size_ri != sizeof(region_info_t))
+ goto bail;
+
+ if (ri == stack_regions)
+ {
+ rit = (region_info_t *) malloc(data_size);
+ if (!rit)
+ goto bail;
+ memcpy (rit, ri, num_ri * sizeof (region_info_t));
+ }
+ else
+ {
+ rit = (region_info_t *) realloc (ri, data_size);
+ if (!rit)
+ goto bail;
+ }
+ ri = rit;
+ rit = &ri[num_ri];
+ }
+ num_ri++;
+ rit->prev_band = 0;
+ rit->cur_band = 0;
+ rit->reg.extents = *box;
+ rit->reg.data = (region_data_type_t *)NULL;
+
+ /* MUST force allocation */
+ if (!pixman_rect_alloc (&rit->reg, (i + num_ri) / num_ri))
+ goto bail;
+
+ next_rect: ;
+ } /* for i */
+
+ /* Make a final pass over each region in order to COALESCE and set
+ * extents.x2 and extents.y2
+ */
+ for (j = num_ri, rit = ri; --j >= 0; rit++)
+ {
+ reg = &rit->reg;
+ ri_box = PIXREGION_END (reg);
+ reg->extents.y2 = ri_box->y2;
+
+ if (reg->extents.x2 < ri_box->x2)
+ reg->extents.x2 = ri_box->x2;
+
+ COALESCE (reg, rit->prev_band, rit->cur_band);
+
+ if (reg->data->numRects == 1) /* keep unions happy below */
+ {
+ FREE_DATA (reg);
+ reg->data = (region_data_type_t *)NULL;
+ }
+ }
+
+ /* Step 3: Union all regions into a single region */
+ while (num_ri > 1)
+ {
+ int half = num_ri / 2;
+ for (j = num_ri & 1; j < (half + (num_ri & 1)); j++)
+ {
+ reg = &ri[j].reg;
+ hreg = &ri[j + half].reg;
+
+ if (!pixman_op (reg, reg, hreg, pixman_region_union_o, TRUE, TRUE))
+ ret = FALSE;
+
+ if (hreg->extents.x1 < reg->extents.x1)
+ reg->extents.x1 = hreg->extents.x1;
+
+ if (hreg->extents.y1 < reg->extents.y1)
+ reg->extents.y1 = hreg->extents.y1;
+
+ if (hreg->extents.x2 > reg->extents.x2)
+ reg->extents.x2 = hreg->extents.x2;
+
+ if (hreg->extents.y2 > reg->extents.y2)
+ reg->extents.y2 = hreg->extents.y2;
+
+ FREE_DATA (hreg);
+ }
+
+ num_ri -= half;
+
+ if (!ret)
+ goto bail;
+ }
+
+ *badreg = ri[0].reg;
+
+ if (ri != stack_regions)
+ free (ri);
+
+ GOOD (badreg);
+ return ret;
+
+bail:
+ for (i = 0; i < num_ri; i++)
+ FREE_DATA (&ri[i].reg);
+
+ if (ri != stack_regions)
+ free (ri);
+
+ return pixman_break (badreg);
+}
+
+/*======================================================================
+ * Region Subtraction
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_subtract_o --
+ * Overlapping band subtraction. x1 is the left-most point not yet
+ * checked.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * region may have rectangles added to it.
+ *
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static pixman_bool_t
+pixman_region_subtract_o (region_type_t * region,
+ box_type_t * r1,
+ box_type_t * r1_end,
+ box_type_t * r2,
+ box_type_t * r2_end,
+ int y1,
+ int y2)
+{
+ box_type_t * next_rect;
+ int x1;
+
+ x1 = r1->x1;
+
+ critical_if_fail (y1 < y2);
+ critical_if_fail (r1 != r1_end && r2 != r2_end);
+
+ next_rect = PIXREGION_TOP (region);
+
+ do
+ {
+ if (r2->x2 <= x1)
+ {
+ /*
+ * Subtrahend entirely to left of minuend: go to next subtrahend.
+ */
+ r2++;
+ }
+ else if (r2->x1 <= x1)
+ {
+ /*
+ * Subtrahend precedes minuend: nuke left edge of minuend.
+ */
+ x1 = r2->x2;
+ if (x1 >= r1->x2)
+ {
+ /*
+ * Minuend completely covered: advance to next minuend and
+ * reset left fence to edge of new minuend.
+ */
+ r1++;
+ if (r1 != r1_end)
+ x1 = r1->x1;
+ }
+ else
+ {
+ /*
+ * Subtrahend now used up since it doesn't extend beyond
+ * minuend
+ */
+ r2++;
+ }
+ }
+ else if (r2->x1 < r1->x2)
+ {
+ /*
+ * Left part of subtrahend covers part of minuend: add uncovered
+ * part of minuend to region and skip to next subtrahend.
+ */
+ critical_if_fail (x1 < r2->x1);
+ NEWRECT (region, next_rect, x1, y1, r2->x1, y2);
+
+ x1 = r2->x2;
+ if (x1 >= r1->x2)
+ {
+ /*
+ * Minuend used up: advance to new...
+ */
+ r1++;
+ if (r1 != r1_end)
+ x1 = r1->x1;
+ }
+ else
+ {
+ /*
+ * Subtrahend used up
+ */
+ r2++;
+ }
+ }
+ else
+ {
+ /*
+ * Minuend used up: add any remaining piece before advancing.
+ */
+ if (r1->x2 > x1)
+ NEWRECT (region, next_rect, x1, y1, r1->x2, y2);
+
+ r1++;
+
+ if (r1 != r1_end)
+ x1 = r1->x1;
+ }
+ }
+ while ((r1 != r1_end) && (r2 != r2_end));
+
+ /*
+ * Add remaining minuend rectangles to region.
+ */
+ while (r1 != r1_end)
+ {
+ critical_if_fail (x1 < r1->x2);
+
+ NEWRECT (region, next_rect, x1, y1, r1->x2, y2);
+
+ r1++;
+ if (r1 != r1_end)
+ x1 = r1->x1;
+ }
+ return TRUE;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_subtract --
+ * Subtract reg_s from reg_m and leave the result in reg_d.
+ * S stands for subtrahend, M for minuend and D for difference.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * reg_d is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_subtract) (region_type_t *reg_d,
+ region_type_t *reg_m,
+ region_type_t *reg_s)
+{
+ GOOD (reg_m);
+ GOOD (reg_s);
+ GOOD (reg_d);
+
+ /* check for trivial rejects */
+ if (PIXREGION_NIL (reg_m) || PIXREGION_NIL (reg_s) ||
+ !EXTENTCHECK (&reg_m->extents, &reg_s->extents))
+ {
+ if (PIXREGION_NAR (reg_s))
+ return pixman_break (reg_d);
+
+ return PREFIX (_copy) (reg_d, reg_m);
+ }
+ else if (reg_m == reg_s)
+ {
+ FREE_DATA (reg_d);
+ reg_d->extents.x2 = reg_d->extents.x1;
+ reg_d->extents.y2 = reg_d->extents.y1;
+ reg_d->data = pixman_region_empty_data;
+
+ return TRUE;
+ }
+
+ /* Add those rectangles in region 1 that aren't in region 2,
+ do yucky subtraction for overlaps, and
+ just throw away rectangles in region 2 that aren't in region 1 */
+ if (!pixman_op (reg_d, reg_m, reg_s, pixman_region_subtract_o, TRUE, FALSE))
+ return FALSE;
+
+ /*
+ * Can't alter reg_d's extents before we call pixman_op because
+ * it might be one of the source regions and pixman_op depends
+ * on the extents of those regions being unaltered. Besides, this
+ * way there's no checking against rectangles that will be nuked
+ * due to coalescing, so we have to examine fewer rectangles.
+ */
+ pixman_set_extents (reg_d);
+ GOOD (reg_d);
+ return TRUE;
+}
+
+/*======================================================================
+ * Region Inversion
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_inverse --
+ * Take a region and a box and return a region that is everything
+ * in the box but not in the region. The careful reader will note
+ * that this is the same as subtracting the region from the box...
+ *
+ * Results:
+ * TRUE.
+ *
+ * Side Effects:
+ * new_reg is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_inverse) (region_type_t *new_reg, /* Destination region */
+ region_type_t *reg1, /* Region to invert */
+ box_type_t * inv_rect) /* Bounding box for inversion */
+{
+ region_type_t inv_reg; /* Quick and dirty region made from the
+ * bounding box */
+ GOOD (reg1);
+ GOOD (new_reg);
+
+ /* check for trivial rejects */
+ if (PIXREGION_NIL (reg1) || !EXTENTCHECK (inv_rect, &reg1->extents))
+ {
+ if (PIXREGION_NAR (reg1))
+ return pixman_break (new_reg);
+
+ new_reg->extents = *inv_rect;
+ FREE_DATA (new_reg);
+ new_reg->data = (region_data_type_t *)NULL;
+
+ return TRUE;
+ }
+
+ /* Add those rectangles in region 1 that aren't in region 2,
+ * do yucky subtraction for overlaps, and
+ * just throw away rectangles in region 2 that aren't in region 1
+ */
+ inv_reg.extents = *inv_rect;
+ inv_reg.data = (region_data_type_t *)NULL;
+ if (!pixman_op (new_reg, &inv_reg, reg1, pixman_region_subtract_o, TRUE, FALSE))
+ return FALSE;
+
+ /*
+ * Can't alter new_reg's extents before we call pixman_op because
+ * it might be one of the source regions and pixman_op depends
+ * on the extents of those regions being unaltered. Besides, this
+ * way there's no checking against rectangles that will be nuked
+ * due to coalescing, so we have to examine fewer rectangles.
+ */
+ pixman_set_extents (new_reg);
+ GOOD (new_reg);
+ return TRUE;
+}
+
+/* In time O(log n), locate the first box whose y2 is greater than y.
+ * Return @end if no such box exists.
+ */
+static box_type_t *
+find_box_for_y (box_type_t *begin, box_type_t *end, int y)
+{
+ box_type_t *mid;
+
+ if (end == begin)
+ return end;
+
+ if (end - begin == 1)
+ {
+ if (begin->y2 > y)
+ return begin;
+ else
+ return end;
+ }
+
+ mid = begin + (end - begin) / 2;
+ if (mid->y2 > y)
+ {
+ /* If no box is found in [begin, mid], the function
+ * will return @mid, which is then known to be the
+ * correct answer.
+ */
+ return find_box_for_y (begin, mid, y);
+ }
+ else
+ {
+ return find_box_for_y (mid, end, y);
+ }
+}
+
+/*
+ * rect_in(region, rect)
+ * This routine takes a pointer to a region and a pointer to a box
+ * and determines if the box is outside/inside/partly inside the region.
+ *
+ * The idea is to travel through the list of rectangles trying to cover the
+ * passed box with them. Anytime a piece of the rectangle isn't covered
+ * by a band of rectangles, part_out is set TRUE. Any time a rectangle in
+ * the region covers part of the box, part_in is set TRUE. The process ends
+ * when either the box has been completely covered (we reached a band that
+ * doesn't overlap the box, part_in is TRUE and part_out is false), the
+ * box has been partially covered (part_in == part_out == TRUE -- because of
+ * the banding, the first time this is true we know the box is only
+ * partially in the region) or is outside the region (we reached a band
+ * that doesn't overlap the box at all and part_in is false)
+ */
+PIXMAN_EXPORT pixman_region_overlap_t
+PREFIX (_contains_rectangle) (region_type_t * region,
+ box_type_t * prect)
+{
+ box_type_t * pbox;
+ box_type_t * pbox_end;
+ int part_in, part_out;
+ int numRects;
+ int x, y;
+
+ GOOD (region);
+
+ numRects = PIXREGION_NUMRECTS (region);
+
+ /* useful optimization */
+ if (!numRects || !EXTENTCHECK (&region->extents, prect))
+ return(PIXMAN_REGION_OUT);
+
+ if (numRects == 1)
+ {
+ /* We know that it must be PIXMAN_REGION_IN or PIXMAN_REGION_PART */
+ if (SUBSUMES (&region->extents, prect))
+ return(PIXMAN_REGION_IN);
+ else
+ return(PIXMAN_REGION_PART);
+ }
+
+ part_out = FALSE;
+ part_in = FALSE;
+
+ /* (x,y) starts at upper left of rect, moving to the right and down */
+ x = prect->x1;
+ y = prect->y1;
+
+ /* can stop when both part_out and part_in are TRUE, or we reach prect->y2 */
+ for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
+ pbox != pbox_end;
+ pbox++)
+ {
+ /* getting up to speed or skipping remainder of band */
+ if (pbox->y2 <= y)
+ {
+ if ((pbox = find_box_for_y (pbox, pbox_end, y)) == pbox_end)
+ break;
+ }
+
+ if (pbox->y1 > y)
+ {
+ part_out = TRUE; /* missed part of rectangle above */
+ if (part_in || (pbox->y1 >= prect->y2))
+ break;
+ y = pbox->y1; /* x guaranteed to be == prect->x1 */
+ }
+
+ if (pbox->x2 <= x)
+ continue; /* not far enough over yet */
+
+ if (pbox->x1 > x)
+ {
+ part_out = TRUE; /* missed part of rectangle to left */
+ if (part_in)
+ break;
+ }
+
+ if (pbox->x1 < prect->x2)
+ {
+ part_in = TRUE; /* definitely overlap */
+ if (part_out)
+ break;
+ }
+
+ if (pbox->x2 >= prect->x2)
+ {
+ y = pbox->y2; /* finished with this band */
+ if (y >= prect->y2)
+ break;
+ x = prect->x1; /* reset x out to left again */
+ }
+ else
+ {
+ /*
+ * Because boxes in a band are maximal width, if the first box
+ * to overlap the rectangle doesn't completely cover it in that
+ * band, the rectangle must be partially out, since some of it
+ * will be uncovered in that band. part_in will have been set true
+ * by now...
+ */
+ part_out = TRUE;
+ break;
+ }
+ }
+
+ if (part_in)
+ {
+ if (y < prect->y2)
+ return PIXMAN_REGION_PART;
+ else
+ return PIXMAN_REGION_IN;
+ }
+ else
+ {
+ return PIXMAN_REGION_OUT;
+ }
+}
+
+/* PREFIX(_translate) (region, x, y)
+ * translates in place
+ */
+
+PIXMAN_EXPORT void
+PREFIX (_translate) (region_type_t *region, int x, int y)
+{
+ overflow_int_t x1, x2, y1, y2;
+ int nbox;
+ box_type_t * pbox;
+
+ GOOD (region);
+ region->extents.x1 = x1 = region->extents.x1 + x;
+ region->extents.y1 = y1 = region->extents.y1 + y;
+ region->extents.x2 = x2 = region->extents.x2 + x;
+ region->extents.y2 = y2 = region->extents.y2 + y;
+
+ if (((x1 - PIXMAN_REGION_MIN) | (y1 - PIXMAN_REGION_MIN) | (PIXMAN_REGION_MAX - x2) | (PIXMAN_REGION_MAX - y2)) >= 0)
+ {
+ if (region->data && (nbox = region->data->numRects))
+ {
+ for (pbox = PIXREGION_BOXPTR (region); nbox--; pbox++)
+ {
+ pbox->x1 += x;
+ pbox->y1 += y;
+ pbox->x2 += x;
+ pbox->y2 += y;
+ }
+ }
+ return;
+ }
+
+ if (((x2 - PIXMAN_REGION_MIN) | (y2 - PIXMAN_REGION_MIN) | (PIXMAN_REGION_MAX - x1) | (PIXMAN_REGION_MAX - y1)) <= 0)
+ {
+ region->extents.x2 = region->extents.x1;
+ region->extents.y2 = region->extents.y1;
+ FREE_DATA (region);
+ region->data = pixman_region_empty_data;
+ return;
+ }
+
+ if (x1 < PIXMAN_REGION_MIN)
+ region->extents.x1 = PIXMAN_REGION_MIN;
+ else if (x2 > PIXMAN_REGION_MAX)
+ region->extents.x2 = PIXMAN_REGION_MAX;
+
+ if (y1 < PIXMAN_REGION_MIN)
+ region->extents.y1 = PIXMAN_REGION_MIN;
+ else if (y2 > PIXMAN_REGION_MAX)
+ region->extents.y2 = PIXMAN_REGION_MAX;
+
+ if (region->data && (nbox = region->data->numRects))
+ {
+ box_type_t * pbox_out;
+
+ for (pbox_out = pbox = PIXREGION_BOXPTR (region); nbox--; pbox++)
+ {
+ pbox_out->x1 = x1 = pbox->x1 + x;
+ pbox_out->y1 = y1 = pbox->y1 + y;
+ pbox_out->x2 = x2 = pbox->x2 + x;
+ pbox_out->y2 = y2 = pbox->y2 + y;
+
+ if (((x2 - PIXMAN_REGION_MIN) | (y2 - PIXMAN_REGION_MIN) |
+ (PIXMAN_REGION_MAX - x1) | (PIXMAN_REGION_MAX - y1)) <= 0)
+ {
+ region->data->numRects--;
+ continue;
+ }
+
+ if (x1 < PIXMAN_REGION_MIN)
+ pbox_out->x1 = PIXMAN_REGION_MIN;
+ else if (x2 > PIXMAN_REGION_MAX)
+ pbox_out->x2 = PIXMAN_REGION_MAX;
+
+ if (y1 < PIXMAN_REGION_MIN)
+ pbox_out->y1 = PIXMAN_REGION_MIN;
+ else if (y2 > PIXMAN_REGION_MAX)
+ pbox_out->y2 = PIXMAN_REGION_MAX;
+
+ pbox_out++;
+ }
+
+ if (pbox_out != pbox)
+ {
+ if (region->data->numRects == 1)
+ {
+ region->extents = *PIXREGION_BOXPTR (region);
+ FREE_DATA (region);
+ region->data = (region_data_type_t *)NULL;
+ }
+ else
+ {
+ pixman_set_extents (region);
+ }
+ }
+ }
+
+ GOOD (region);
+}
+
+PIXMAN_EXPORT void
+PREFIX (_reset) (region_type_t *region, box_type_t *box)
+{
+ GOOD (region);
+
+ critical_if_fail (GOOD_RECT (box));
+
+ region->extents = *box;
+
+ FREE_DATA (region);
+
+ region->data = NULL;
+}
+
+PIXMAN_EXPORT void
+PREFIX (_clear) (region_type_t *region)
+{
+ GOOD (region);
+ FREE_DATA (region);
+
+ region->extents = *pixman_region_empty_box;
+ region->data = pixman_region_empty_data;
+}
+
+/* box is "return" value */
+PIXMAN_EXPORT int
+PREFIX (_contains_point) (region_type_t * region,
+ int x, int y,
+ box_type_t * box)
+{
+ box_type_t *pbox, *pbox_end;
+ int numRects;
+
+ GOOD (region);
+ numRects = PIXREGION_NUMRECTS (region);
+
+ if (!numRects || !INBOX (&region->extents, x, y))
+ return(FALSE);
+
+ if (numRects == 1)
+ {
+ if (box)
+ *box = region->extents;
+
+ return(TRUE);
+ }
+
+ pbox = PIXREGION_BOXPTR (region);
+ pbox_end = pbox + numRects;
+
+ pbox = find_box_for_y (pbox, pbox_end, y);
+
+ for (;pbox != pbox_end; pbox++)
+ {
+ if ((y < pbox->y1) || (x < pbox->x1))
+ break; /* missed it */
+
+ if (x >= pbox->x2)
+ continue; /* not there yet */
+
+ if (box)
+ *box = *pbox;
+
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
+PIXMAN_EXPORT int
+PREFIX (_not_empty) (region_type_t * region)
+{
+ GOOD (region);
+
+ return(!PIXREGION_NIL (region));
+}
+
+PIXMAN_EXPORT box_type_t *
+PREFIX (_extents) (region_type_t * region)
+{
+ GOOD (region);
+
+ return(&region->extents);
+}
+
+/*
+ * Clip a list of scanlines to a region. The caller has allocated the
+ * space. FSorted is non-zero if the scanline origins are in ascending order.
+ *
+ * returns the number of new, clipped scanlines.
+ */
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_selfcheck) (region_type_t *reg)
+{
+ int i, numRects;
+
+ if ((reg->extents.x1 > reg->extents.x2) ||
+ (reg->extents.y1 > reg->extents.y2))
+ {
+ return FALSE;
+ }
+
+ numRects = PIXREGION_NUMRECTS (reg);
+ if (!numRects)
+ {
+ return ((reg->extents.x1 == reg->extents.x2) &&
+ (reg->extents.y1 == reg->extents.y2) &&
+ (reg->data->size || (reg->data == pixman_region_empty_data)));
+ }
+ else if (numRects == 1)
+ {
+ return (!reg->data);
+ }
+ else
+ {
+ box_type_t * pbox_p, * pbox_n;
+ box_type_t box;
+
+ pbox_p = PIXREGION_RECTS (reg);
+ box = *pbox_p;
+ box.y2 = pbox_p[numRects - 1].y2;
+ pbox_n = pbox_p + 1;
+
+ for (i = numRects; --i > 0; pbox_p++, pbox_n++)
+ {
+ if ((pbox_n->x1 >= pbox_n->x2) ||
+ (pbox_n->y1 >= pbox_n->y2))
+ {
+ return FALSE;
+ }
+
+ if (pbox_n->x1 < box.x1)
+ box.x1 = pbox_n->x1;
+
+ if (pbox_n->x2 > box.x2)
+ box.x2 = pbox_n->x2;
+
+ if ((pbox_n->y1 < pbox_p->y1) ||
+ ((pbox_n->y1 == pbox_p->y1) &&
+ ((pbox_n->x1 < pbox_p->x2) || (pbox_n->y2 != pbox_p->y2))))
+ {
+ return FALSE;
+ }
+ }
+
+ return ((box.x1 == reg->extents.x1) &&
+ (box.x2 == reg->extents.x2) &&
+ (box.y1 == reg->extents.y1) &&
+ (box.y2 == reg->extents.y2));
+ }
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_init_rects) (region_type_t *region,
+ const box_type_t *boxes, int count)
+{
+ box_type_t *rects;
+ int displacement;
+ int i;
+
+ /* if it's 1, then we just want to set the extents, so call
+ * the existing method. */
+ if (count == 1)
+ {
+ PREFIX (_init_rect) (region,
+ boxes[0].x1,
+ boxes[0].y1,
+ boxes[0].x2 - boxes[0].x1,
+ boxes[0].y2 - boxes[0].y1);
+ return TRUE;
+ }
+
+ PREFIX (_init) (region);
+
+ /* if it's 0, don't call pixman_rect_alloc -- 0 rectangles is
+ * a special case, and causing pixman_rect_alloc would cause
+ * us to leak memory (because the 0-rect case should be the
+ * static pixman_region_empty_data data).
+ */
+ if (count == 0)
+ return TRUE;
+
+ if (!pixman_rect_alloc (region, count))
+ return FALSE;
+
+ rects = PIXREGION_RECTS (region);
+
+ /* Copy in the rects */
+ memcpy (rects, boxes, sizeof(box_type_t) * count);
+ region->data->numRects = count;
+
+ /* Eliminate empty and malformed rectangles */
+ displacement = 0;
+
+ for (i = 0; i < count; ++i)
+ {
+ box_type_t *box = &rects[i];
+
+ if (box->x1 >= box->x2 || box->y1 >= box->y2)
+ displacement++;
+ else if (displacement)
+ rects[i - displacement] = rects[i];
+ }
+
+ region->data->numRects -= displacement;
+
+ /* If eliminating empty rectangles caused there
+ * to be only 0 or 1 rectangles, deal with that.
+ */
+ if (region->data->numRects == 0)
+ {
+ FREE_DATA (region);
+ PREFIX (_init) (region);
+
+ return TRUE;
+ }
+
+ if (region->data->numRects == 1)
+ {
+ region->extents = rects[0];
+
+ FREE_DATA (region);
+ region->data = NULL;
+
+ GOOD (region);
+
+ return TRUE;
+ }
+
+ /* Validate */
+ region->extents.x1 = region->extents.x2 = 0;
+
+ return validate (region);
+}
+
diff --git a/common/pixman-region.h b/common/pixman-region.h
new file mode 100644
index 00000000..9c82c4d9
--- /dev/null
+++ b/common/pixman-region.h
@@ -0,0 +1,76 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2016
+ *
+ * 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.
+ *
+ * region, from pixman.h
+ */
+
+#if !defined(PIXMAN_PIXMAN_H__)
+#define PIXMAN_PIXMAN_H__
+
+typedef int pixman_bool_t;
+
+struct pixman_region16_data
+{
+ long size;
+ long numRects;
+};
+
+struct pixman_box16
+{
+ signed short x1, y1, x2, y2;
+};
+
+struct pixman_region16
+{
+ struct pixman_box16 extents;
+ struct pixman_region16_data *data;
+};
+
+enum _pixman_region_overlap_t
+{
+ PIXMAN_REGION_OUT,
+ PIXMAN_REGION_IN,
+ PIXMAN_REGION_PART
+};
+
+typedef enum _pixman_region_overlap_t pixman_region_overlap_t;
+
+typedef struct pixman_region16_data pixman_region16_data_t;
+typedef struct pixman_box16 pixman_box16_t;
+typedef struct pixman_region16 pixman_region16_t;
+
+/* creation/destruction */
+void pixman_region_init (pixman_region16_t *region);
+void pixman_region_init_rect (pixman_region16_t *region,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+void pixman_region_fini (pixman_region16_t *region);
+pixman_bool_t pixman_region_union (pixman_region16_t *new_reg,
+ pixman_region16_t *reg1,
+ pixman_region16_t *reg2);
+pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d,
+ pixman_region16_t *reg_m,
+ pixman_region16_t *reg_s);
+pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg,
+ pixman_region16_t *reg1,
+ pixman_region16_t *reg2);
+pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region,
+ int *n_rects);
+
+#endif
diff --git a/common/pixman-region16.c b/common/pixman-region16.c
new file mode 100644
index 00000000..76f0903b
--- /dev/null
+++ b/common/pixman-region16.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Soren Sandmann <sandmann@redhat.com>
+ */
+
+/* taken from pixman 0.34
+ altered to compile without all of pixman */
+
+#if defined(HAVE_CONFIG_H)
+#include "config_ac.h"
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+#include "pixman-region.h"
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX (4294967295U)
+#endif
+#if !defined(INT16_MIN)
+#define INT16_MIN (-32767-1)
+#endif
+#if !defined(INT16_MAX)
+#define INT16_MAX (32767)
+#endif
+
+#define PIXMAN_EXPORT
+#define FALSE 0
+#define TRUE 1
+
+#define MIN(x1, x2) ((x1) < (x2) ? (x1) : (x2))
+#define MAX(x1, x2) ((x1) > (x2) ? (x1) : (x2))
+
+typedef pixman_box16_t box_type_t;
+typedef pixman_region16_data_t region_data_type_t;
+typedef pixman_region16_t region_type_t;
+typedef signed int overflow_int_t;
+
+#define PREFIX(x) pixman_region##x
+
+#define PIXMAN_REGION_MAX INT16_MAX
+#define PIXMAN_REGION_MIN INT16_MIN
+
+#define FUNC "func"
+
+#define critical_if_fail(expr)
+
+int _pixman_log_error(const char *func, const char *format, ...)
+{
+ return 0;
+}
+
+#include "pixman-region.c"
+
diff --git a/common/ssl_calls.c b/common/ssl_calls.c
index ae30fe71..72ab5eb7 100644
--- a/common/ssl_calls.c
+++ b/common/ssl_calls.c
@@ -40,6 +40,32 @@
#define OLD_RSA_GEN1
#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static inline HMAC_CTX *
+HMAC_CTX_new()
+{
+ HMAC_CTX *hmac_ctx = g_new(HMAC_CTX, 1);
+ HMAC_CTX_init(hmac_ctx);
+ return hmac_ctx;
+}
+
+static inline void
+HMAC_CTX_free(HMAC_CTX *hmac_ctx)
+{
+ HMAC_CTX_cleanup(hmac_ctx);
+ g_free(hmac_ctx);
+}
+
+static inline void
+RSA_get0_key(const RSA *key, const BIGNUM **n, const BIGNUM **e,
+ const BIGNUM **d)
+{
+ *n = key->n;
+ *d = key->d;
+}
+#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
+
+
/*****************************************************************************/
int
ssl_init(void)
@@ -111,7 +137,7 @@ ssl_sha1_clear(void *sha1_info)
/*****************************************************************************/
void APP_CC
-ssl_sha1_transform(void *sha1_info, char *data, int len)
+ssl_sha1_transform(void *sha1_info, const char *data, int len)
{
SHA1_Update((SHA_CTX *)sha1_info, data, len);
}
@@ -170,8 +196,7 @@ ssl_des3_encrypt_info_create(const char *key, const char* ivec)
const tui8 *lkey;
const tui8 *livec;
- des3_ctx = (EVP_CIPHER_CTX *) g_malloc(sizeof(EVP_CIPHER_CTX), 1);
- EVP_CIPHER_CTX_init(des3_ctx);
+ des3_ctx = EVP_CIPHER_CTX_new();
lkey = (const tui8 *) key;
livec = (const tui8 *) ivec;
EVP_EncryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
@@ -187,8 +212,7 @@ ssl_des3_decrypt_info_create(const char *key, const char* ivec)
const tui8 *lkey;
const tui8 *livec;
- des3_ctx = g_malloc(sizeof(EVP_CIPHER_CTX), 1);
- EVP_CIPHER_CTX_init(des3_ctx);
+ des3_ctx = EVP_CIPHER_CTX_new();
lkey = (const tui8 *) key;
livec = (const tui8 *) ivec;
EVP_DecryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
@@ -205,8 +229,7 @@ ssl_des3_info_delete(void *des3)
des3_ctx = (EVP_CIPHER_CTX *) des3;
if (des3_ctx != 0)
{
- EVP_CIPHER_CTX_cleanup(des3_ctx);
- g_free(des3_ctx);
+ EVP_CIPHER_CTX_free(des3_ctx);
}
}
@@ -250,8 +273,7 @@ ssl_hmac_info_create(void)
{
HMAC_CTX *hmac_ctx;
- hmac_ctx = (HMAC_CTX *) g_malloc(sizeof(HMAC_CTX), 1);
- HMAC_CTX_init(hmac_ctx);
+ hmac_ctx = HMAC_CTX_new();
return hmac_ctx;
}
@@ -264,8 +286,7 @@ ssl_hmac_info_delete(void *hmac)
hmac_ctx = (HMAC_CTX *) hmac;
if (hmac_ctx != 0)
{
- HMAC_CTX_cleanup(hmac_ctx);
- g_free(hmac_ctx);
+ HMAC_CTX_free(hmac_ctx);
}
}
@@ -332,10 +353,10 @@ ssl_mod_exp(char *out, int out_len, char *in, int in_len,
char *mod, int mod_len, char *exp, int exp_len)
{
BN_CTX *ctx;
- BIGNUM lmod;
- BIGNUM lexp;
- BIGNUM lin;
- BIGNUM lout;
+ BIGNUM *lmod;
+ BIGNUM *lexp;
+ BIGNUM *lin;
+ BIGNUM *lout;
int rv;
char *l_out;
char *l_in;
@@ -353,15 +374,15 @@ ssl_mod_exp(char *out, int out_len, char *in, int in_len,
ssl_reverse_it(l_mod, mod_len);
ssl_reverse_it(l_exp, exp_len);
ctx = BN_CTX_new();
- BN_init(&lmod);
- BN_init(&lexp);
- BN_init(&lin);
- BN_init(&lout);
- BN_bin2bn((tui8 *)l_mod, mod_len, &lmod);
- BN_bin2bn((tui8 *)l_exp, exp_len, &lexp);
- BN_bin2bn((tui8 *)l_in, in_len, &lin);
- BN_mod_exp(&lout, &lin, &lexp, &lmod, ctx);
- rv = BN_bn2bin(&lout, (tui8 *)l_out);
+ lmod = BN_new();
+ lexp = BN_new();
+ lin = BN_new();
+ lout = BN_new();
+ BN_bin2bn((tui8 *)l_mod, mod_len, lmod);
+ BN_bin2bn((tui8 *)l_exp, exp_len, lexp);
+ BN_bin2bn((tui8 *)l_in, in_len, lin);
+ BN_mod_exp(lout, lin, lexp, lmod, ctx);
+ rv = BN_bn2bin(lout, (tui8 *)l_out);
if (rv <= out_len)
{
@@ -373,10 +394,10 @@ ssl_mod_exp(char *out, int out_len, char *in, int in_len,
rv = 0;
}
- BN_free(&lin);
- BN_free(&lout);
- BN_free(&lexp);
- BN_free(&lmod);
+ BN_free(lin);
+ BN_free(lout);
+ BN_free(lexp);
+ BN_free(lmod);
BN_CTX_free(ctx);
g_free(l_out);
g_free(l_in);
@@ -401,6 +422,7 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len,
tui8 *lexp;
int error;
int len;
+ int diff;
if ((exp_len != 4) || ((mod_len != 64) && (mod_len != 256)) ||
((pri_len != 64) && (pri_len != 256)))
@@ -408,8 +430,9 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len,
return 1;
}
- lmod = (char *)g_malloc(mod_len, 0);
- lpri = (char *)g_malloc(pri_len, 0);
+ diff = 0;
+ lmod = (char *)g_malloc(mod_len, 1);
+ lpri = (char *)g_malloc(pri_len, 1);
lexp = (tui8 *)exp;
my_e = lexp[0];
my_e |= lexp[1] << 8;
@@ -423,24 +446,26 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len,
if (error == 0)
{
len = BN_num_bytes(my_key->n);
- error = len != mod_len;
+ error = (len < 1) || (len > mod_len);
+ diff = mod_len - len;
}
if (error == 0)
{
- BN_bn2bin(my_key->n, (tui8 *)lmod);
+ BN_bn2bin(my_key->n, (tui8 *)(lmod + diff));
ssl_reverse_it(lmod, mod_len);
}
if (error == 0)
{
len = BN_num_bytes(my_key->d);
- error = len != pri_len;
+ error = (len < 1) || (len > pri_len);
+ diff = pri_len - len;
}
if (error == 0)
{
- BN_bn2bin(my_key->d, (tui8 *)lpri);
+ BN_bn2bin(my_key->d, (tui8 *)(lpri + diff));
ssl_reverse_it(lpri, pri_len);
}
@@ -471,6 +496,7 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len,
char *lpri;
int error;
int len;
+ int diff;
if ((exp_len != 4) || ((mod_len != 64) && (mod_len != 256)) ||
((pri_len != 64) && (pri_len != 256)))
@@ -478,9 +504,10 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len,
return 1;
}
- lexp = (char *)g_malloc(exp_len, 0);
- lmod = (char *)g_malloc(mod_len, 0);
- lpri = (char *)g_malloc(pri_len, 0);
+ diff = 0;
+ lexp = (char *)g_malloc(exp_len, 1);
+ lmod = (char *)g_malloc(mod_len, 1);
+ lpri = (char *)g_malloc(pri_len, 1);
g_memcpy(lexp, exp, exp_len);
ssl_reverse_it(lexp, exp_len);
my_e = BN_new();
@@ -488,27 +515,33 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len,
my_key = RSA_new();
error = RSA_generate_key_ex(my_key, key_size_in_bits, my_e, 0) == 0;
+ const BIGNUM *n;
+ const BIGNUM *d;
+ RSA_get0_key(my_key, &n, NULL, &d);
+
if (error == 0)
{
- len = BN_num_bytes(my_key->n);
- error = len != mod_len;
+ len = BN_num_bytes(n);
+ error = (len < 1) || (len > mod_len);
+ diff = mod_len - len;
}
if (error == 0)
{
- BN_bn2bin(my_key->n, (tui8 *)lmod);
+ BN_bn2bin(n, (tui8 *)(lmod + diff));
ssl_reverse_it(lmod, mod_len);
}
if (error == 0)
{
- len = BN_num_bytes(my_key->d);
- error = len != pri_len;
+ len = BN_num_bytes(d);
+ error = (len < 1) || (len > pri_len);
+ diff = pri_len - len;
}
if (error == 0)
{
- BN_bn2bin(my_key->d, (tui8 *)lpri);
+ BN_bn2bin(d, (tui8 *)(lpri + diff));
ssl_reverse_it(lpri, pri_len);
}
@@ -552,7 +585,7 @@ ssl_tls_create(struct trans *trans, const char *key, const char *cert)
/*****************************************************************************/
int APP_CC
-ssl_tls_print_error(char *func, SSL *connection, int value)
+ssl_tls_print_error(const char *func, SSL *connection, int value)
{
switch (SSL_get_error(connection, value))
{
@@ -562,11 +595,7 @@ ssl_tls_print_error(char *func, SSL *connection, int value)
return 1;
case SSL_ERROR_WANT_READ:
- g_writeln("ssl_tls_print_error: SSL_ERROR_WANT_READ");
- return 0;
-
case SSL_ERROR_WANT_WRITE:
- g_writeln("ssl_tls_print_error: SSL_ERROR_WANT_WRITE");
return 0;
case SSL_ERROR_SYSCALL:
@@ -586,18 +615,22 @@ ssl_tls_print_error(char *func, SSL *connection, int value)
/*****************************************************************************/
int APP_CC
-ssl_tls_accept(struct ssl_tls *self)
+ssl_tls_accept(struct ssl_tls *self, int disableSSLv3,
+ const char *tls_ciphers)
{
int connection_status;
long options = 0;
/**
- * SSL_OP_NO_SSLv2:
- *
- * We only want SSLv3 and TLSv1, so disable SSLv2.
+ * SSL_OP_NO_SSLv2
* SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
+ * No SSLv3 if disableSSLv3=yes so only tls used
*/
options |= SSL_OP_NO_SSLv2;
+ if (disableSSLv3)
+ {
+ options |= SSL_OP_NO_SSLv3;
+ }
#if defined(SSL_OP_NO_COMPRESSION)
/**
@@ -634,6 +667,16 @@ ssl_tls_accept(struct ssl_tls *self)
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_options(self->ctx, options);
+
+ if (g_strlen(tls_ciphers) > 1)
+ {
+ if (SSL_CTX_set_cipher_list(self->ctx, tls_ciphers) == 0)
+ {
+ g_writeln("ssl_tls_accept: invalid cipher options");
+ return 1;
+ }
+ }
+
SSL_CTX_set_read_ahead(self->ctx, 1);
if (self->ctx == NULL)
@@ -669,13 +712,24 @@ ssl_tls_accept(struct ssl_tls *self)
return 1;
}
- connection_status = SSL_accept(self->ssl);
+ while(1) {
+ connection_status = SSL_accept(self->ssl);
- if (connection_status <= 0)
- {
- if (ssl_tls_print_error("SSL_accept", self->ssl, connection_status))
+ if (connection_status <= 0)
{
- return 1;
+ if (ssl_tls_print_error("SSL_accept", self->ssl, connection_status))
+ {
+ return 1;
+ }
+ /**
+ * retry when SSL_get_error returns:
+ * SSL_ERROR_WANT_READ
+ * SSL_ERROR_WANT_WRITE
+ */
+ }
+ else
+ {
+ break;
}
}
@@ -709,6 +763,11 @@ ssl_tls_disconnect(struct ssl_tls *self)
{
return 1;
}
+ /**
+ * retry when SSL_get_error returns:
+ * SSL_ERROR_WANT_READ
+ * SSL_ERROR_WANT_WRITE
+ */
}
}
return 0;
@@ -737,23 +796,37 @@ int APP_CC
ssl_tls_read(struct ssl_tls *tls, char *data, int length)
{
int status;
+ int break_flag;
- status = SSL_read(tls->ssl, data, length);
+ while(1) {
+ status = SSL_read(tls->ssl, data, length);
- switch (SSL_get_error(tls->ssl, status))
- {
- case SSL_ERROR_NONE:
- break;
-
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- status = 0;
- break;
+ switch (SSL_get_error(tls->ssl, status))
+ {
+ case SSL_ERROR_NONE:
+ break_flag = 1;
+ break;
+
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ /**
+ * retry when SSL_get_error returns:
+ * SSL_ERROR_WANT_READ
+ * SSL_ERROR_WANT_WRITE
+ */
+ continue;
+
+ default:
+ ssl_tls_print_error("SSL_read", tls->ssl, status);
+ status = -1;
+ break_flag = 1;
+ break;
+ }
- default:
- ssl_tls_print_error("SSL_read", tls->ssl, status);
- status = -1;
+ if (break_flag)
+ {
break;
+ }
}
if (SSL_pending(tls->ssl) > 0)
@@ -769,23 +842,37 @@ int APP_CC
ssl_tls_write(struct ssl_tls *tls, const char *data, int length)
{
int status;
+ int break_flag;
- status = SSL_write(tls->ssl, data, length);
+ while(1) {
+ status = SSL_write(tls->ssl, data, length);
- switch (SSL_get_error(tls->ssl, status))
- {
- case SSL_ERROR_NONE:
- break;
-
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- status = 0;
- break;
+ switch (SSL_get_error(tls->ssl, status))
+ {
+ case SSL_ERROR_NONE:
+ break_flag = 1;
+ break;
+
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ /**
+ * retry when SSL_get_error returns:
+ * SSL_ERROR_WANT_READ
+ * SSL_ERROR_WANT_WRITE
+ */
+ continue;
+
+ default:
+ ssl_tls_print_error("SSL_write", tls->ssl, status);
+ status = -1;
+ break_flag = 1;
+ break;
+ }
- default:
- ssl_tls_print_error("SSL_write", tls->ssl, status);
- status = -1;
+ if (break_flag)
+ {
break;
+ }
}
return status;
@@ -801,6 +888,6 @@ ssl_tls_can_recv(struct ssl_tls *tls, int sck, int millis)
return 1;
}
g_reset_wait_obj(tls->rwo);
- return g_tcp_can_recv(sck, millis);
+ return g_sck_can_recv(sck, millis);
}
diff --git a/common/ssl_calls.h b/common/ssl_calls.h
index 6cfe73a3..1277505c 100644
--- a/common/ssl_calls.h
+++ b/common/ssl_calls.h
@@ -41,7 +41,7 @@ ssl_sha1_info_delete(void* sha1_info);
void APP_CC
ssl_sha1_clear(void* sha1_info);
void APP_CC
-ssl_sha1_transform(void* sha1_info, char* data, int len);
+ssl_sha1_transform(void* sha1_info, const char *data, int len);
void APP_CC
ssl_sha1_complete(void* sha1_info, char* data);
void* APP_CC
@@ -84,8 +84,8 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char* exp, int exp_len,
/* ssl_tls */
struct ssl_tls
{
- void *ssl; /* SSL * */
- void *ctx; /* SSL_CTX * */
+ struct ssl_st *ssl; /* SSL * */
+ struct ssl_ctx_st *ctx; /* SSL_CTX * */
char *cert;
char *key;
struct trans *trans;
@@ -96,7 +96,8 @@ struct ssl_tls
struct ssl_tls *APP_CC
ssl_tls_create(struct trans *trans, const char *key, const char *cert);
int APP_CC
-ssl_tls_accept(struct ssl_tls *self);
+ssl_tls_accept(struct ssl_tls *self, int disableSSLv3,
+ const char *tls_ciphers);
int APP_CC
ssl_tls_disconnect(struct ssl_tls *self);
void APP_CC
diff --git a/common/thread_calls.c b/common/thread_calls.c
index a68e902a..d828b353 100644
--- a/common/thread_calls.c
+++ b/common/thread_calls.c
@@ -20,6 +20,10 @@
#if defined(_WIN32)
#include <windows.h>
+#elif defined(__APPLE__)
+#include <pthread.h>
+#include <dispatch/dispatch.h>
+#include <dispatch/time.h>
#else
#include <pthread.h>
#include <semaphore.h>
@@ -159,6 +163,9 @@ tc_sem_create(int init_count)
sem = CreateSemaphore(0, init_count, init_count + 10, 0);
return (tbus)sem;
+#elif defined(__APPLE__)
+ dispatch_semaphore_t sem = dispatch_semaphore_create(init_count);
+ return (tbus)sem;
#else
sem_t *sem = (sem_t *)NULL;
@@ -174,6 +181,8 @@ tc_sem_delete(tbus sem)
{
#if defined(_WIN32)
CloseHandle((HANDLE)sem);
+#elif defined(__APPLE__)
+ dispatch_release((dispatch_semaphore_t)sem);
#else
sem_t *lsem;
@@ -190,6 +199,9 @@ tc_sem_dec(tbus sem)
#if defined(_WIN32)
WaitForSingleObject((HANDLE)sem, INFINITE);
return 0;
+#elif defined(__APPLE__)
+ dispatch_semaphore_wait((dispatch_semaphore_t)sem, DISPATCH_TIME_FOREVER);
+ return 0;
#else
sem_wait((sem_t *)sem);
return 0;
@@ -203,6 +215,9 @@ tc_sem_inc(tbus sem)
#if defined(_WIN32)
ReleaseSemaphore((HANDLE)sem, 1, 0);
return 0;
+#elif defined(__APPLE__)
+ dispatch_semaphore_signal((dispatch_semaphore_t)sem);
+ return 0;
#else
sem_post((sem_t *)sem);
return 0;
diff --git a/common/trans.c b/common/trans.c
index 3828a174..432b6334 100644
--- a/common/trans.c
+++ b/common/trans.c
@@ -24,9 +24,11 @@
#include "parse.h"
#include "ssl_calls.h"
+#define MAX_SBYTES 0
+
/*****************************************************************************/
int APP_CC
-trans_tls_recv(struct trans *self, void *ptr, int len)
+trans_tls_recv(struct trans *self, char *ptr, int len)
{
if (self->tls == NULL)
{
@@ -37,7 +39,7 @@ trans_tls_recv(struct trans *self, void *ptr, int len)
/*****************************************************************************/
int APP_CC
-trans_tls_send(struct trans *self, const void *data, int len)
+trans_tls_send(struct trans *self, const char *data, int len)
{
if (self->tls == NULL)
{
@@ -59,14 +61,14 @@ trans_tls_can_recv(struct trans *self, int sck, int millis)
/*****************************************************************************/
int APP_CC
-trans_tcp_recv(struct trans *self, void *ptr, int len)
+trans_tcp_recv(struct trans *self, char *ptr, int len)
{
return g_tcp_recv(self->sck, ptr, len, 0);
}
/*****************************************************************************/
int APP_CC
-trans_tcp_send(struct trans *self, const void *data, int len)
+trans_tcp_send(struct trans *self, const char *data, int len)
{
return g_tcp_send(self->sck, data, len, 0);
}
@@ -75,7 +77,7 @@ trans_tcp_send(struct trans *self, const void *data, int len)
int APP_CC
trans_tcp_can_recv(struct trans *self, int sck, int millis)
{
- return g_tcp_can_recv(sck, millis);
+ return g_sck_can_recv(sck, millis);
}
/*****************************************************************************/
@@ -169,13 +171,29 @@ trans_get_wait_objs(struct trans *self, tbus *objs, int *count)
/*****************************************************************************/
int APP_CC
trans_get_wait_objs_rw(struct trans *self, tbus *robjs, int *rcount,
- tbus *wobjs, int *wcount)
+ tbus *wobjs, int *wcount, int *timeout)
{
- if (trans_get_wait_objs(self, robjs, rcount) != 0)
+ if (self == 0)
{
return 1;
}
+ if (self->status != TRANS_STATUS_UP)
+ {
+ return 1;
+ }
+
+ if ((self->si != 0) && (self->si->source[self->my_source] > MAX_SBYTES))
+ {
+ }
+ else
+ {
+ if (trans_get_wait_objs(self, robjs, rcount) != 0)
+ {
+ return 1;
+ }
+ }
+
if (self->wait_s != 0)
{
wobjs[*wcount] = self->sck;
@@ -187,7 +205,7 @@ trans_get_wait_objs_rw(struct trans *self, tbus *robjs, int *rcount,
/*****************************************************************************/
int APP_CC
-send_waiting(struct trans *self, int block)
+trans_send_waiting(struct trans *self, int block)
{
struct stream *temp_s;
int bytes;
@@ -209,9 +227,13 @@ send_waiting(struct trans *self, int block)
if (sent > 0)
{
temp_s->p += sent;
+ if (temp_s->source != 0)
+ {
+ temp_s->source[0] -= sent;
+ }
if (temp_s->p >= temp_s->end)
{
- self->wait_s = (struct stream *) (temp_s->next_packet);
+ self->wait_s = temp_s->next;
free_stream(temp_s);
}
}
@@ -227,6 +249,18 @@ send_waiting(struct trans *self, int block)
}
}
}
+ else if (block)
+ {
+ /* check for term here */
+ if (self->is_term != 0)
+ {
+ if (self->is_term())
+ {
+ /* term */
+ return 1;
+ }
+ }
+ }
}
else
{
@@ -247,6 +281,7 @@ trans_check_wait_objs(struct trans *self)
int to_read = 0;
int read_so_far = 0;
int rv = 0;
+ int cur_source;
if (self == 0)
{
@@ -262,7 +297,7 @@ trans_check_wait_objs(struct trans *self)
if (self->type1 == TRANS_TYPE_LISTENER) /* listening */
{
- if (g_tcp_can_recv(self->sck, 0))
+ if (g_sck_can_recv(self->sck, 0))
{
in_sck = g_sck_accept(self->sck, self->addr, sizeof(self->addr),
self->port, sizeof(self->port));
@@ -295,7 +330,7 @@ trans_check_wait_objs(struct trans *self)
sizeof(self->addr) - 1);
g_strncpy(in_trans->port, self->port,
sizeof(self->port) - 1);
-
+ g_sck_set_non_blocking(in_sck);
if (self->trans_conn_in(self, in_trans) != 0)
{
trans_delete(in_trans);
@@ -310,8 +345,17 @@ trans_check_wait_objs(struct trans *self)
}
else /* connected server or client (2 or 3) */
{
- if (self->trans_can_recv(self, self->sck, 0))
+ if (self->si != 0 && self->si->source[self->my_source] > MAX_SBYTES)
{
+ }
+ else if (self->trans_can_recv(self, self->sck, 0))
+ {
+ cur_source = 0;
+ if (self->si != 0)
+ {
+ cur_source = self->si->cur_source;
+ self->si->cur_source = self->my_source;
+ }
read_so_far = (int) (self->in_s->end - self->in_s->data);
to_read = self->header_size - read_so_far;
@@ -329,6 +373,10 @@ trans_check_wait_objs(struct trans *self)
{
/* error */
self->status = TRANS_STATUS_DOWN;
+ if (self->si != 0)
+ {
+ self->si->cur_source = cur_source;
+ }
return 1;
}
}
@@ -336,6 +384,10 @@ trans_check_wait_objs(struct trans *self)
{
/* error */
self->status = TRANS_STATUS_DOWN;
+ if (self->si != 0)
+ {
+ self->si->cur_source = cur_source;
+ }
return 1;
}
else
@@ -357,8 +409,12 @@ trans_check_wait_objs(struct trans *self)
}
}
}
+ if (self->si != 0)
+ {
+ self->si->cur_source = cur_source;
+ }
}
- if (send_waiting(self, 0) != 0)
+ if (trans_send_waiting(self, 0) != 0)
{
/* error */
self->status = TRANS_STATUS_DOWN;
@@ -368,6 +424,7 @@ trans_check_wait_objs(struct trans *self)
return rv;
}
+
/*****************************************************************************/
int APP_CC
trans_force_read_s(struct trans *self, struct stream *in_s, int size)
@@ -378,7 +435,6 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size)
{
return 1;
}
-
while (size > 0)
{
/* make sure stream has room */
@@ -386,14 +442,12 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size)
{
return 1;
}
-
rcvd = self->trans_recv(self, in_s->end, size);
-
if (rcvd == -1)
{
if (g_tcp_last_error_would_block(self->sck))
{
- if (!g_tcp_can_recv(self->sck, 100))
+ if (!self->trans_can_recv(self, self->sck, 100))
{
/* check for term here */
if (self->is_term != 0)
@@ -426,7 +480,6 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size)
size -= rcvd;
}
}
-
return 0;
}
@@ -449,20 +502,16 @@ trans_force_write_s(struct trans *self, struct stream *out_s)
{
return 1;
}
-
size = (int) (out_s->end - out_s->data);
total = 0;
-
- if (send_waiting(self, 1) != 0)
+ if (trans_send_waiting(self, 1) != 0)
{
self->status = TRANS_STATUS_DOWN;
return 1;
}
-
while (total < size)
{
sent = self->trans_send(self, out_s->data + total, size - total);
-
if (sent == -1)
{
if (g_tcp_last_error_would_block(self->sck))
@@ -499,7 +548,6 @@ trans_force_write_s(struct trans *self, struct stream *out_s)
total = total + sent;
}
}
-
return 0;
}
@@ -512,23 +560,69 @@ trans_force_write(struct trans *self)
/*****************************************************************************/
int APP_CC
-trans_write_copy(struct trans *self)
+trans_write_copy_s(struct trans *self, struct stream *out_s)
{
int size;
- struct stream *out_s;
+ int sent;
struct stream *wait_s;
struct stream *temp_s;
+ char *out_data;
if (self->status != TRANS_STATUS_UP)
{
return 1;
}
-
- out_s = self->out_s;
+ /* try to send any left over */
+ if (trans_send_waiting(self, 0) != 0)
+ {
+ /* error */
+ self->status = TRANS_STATUS_DOWN;
+ return 1;
+ }
+ out_data = out_s->data;
+ sent = 0;
size = (int) (out_s->end - out_s->data);
+ if (self->wait_s == 0)
+ {
+ /* if no left over, try to send this new data */
+ if (g_tcp_can_send(self->sck, 0))
+ {
+ sent = self->trans_send(self, out_s->data, size);
+ if (sent > 0)
+ {
+ out_data += sent;
+ size -= sent;
+ }
+ else if (sent == 0)
+ {
+ return 1;
+ }
+ else
+ {
+ if (!g_tcp_last_error_would_block(self->sck))
+ {
+ return 1;
+ }
+ }
+ }
+ }
+ if (size < 1)
+ {
+ return 0;
+ }
+ /* did not send right away, have to copy */
make_stream(wait_s);
init_stream(wait_s, size);
- out_uint8a(wait_s, out_s->data, size);
+ if (self->si != 0)
+ {
+ if ((self->si->cur_source != 0) &&
+ (self->si->cur_source != self->my_source))
+ {
+ self->si->source[self->si->cur_source] += size;
+ wait_s->source = self->si->source + self->si->cur_source;
+ }
+ }
+ out_uint8a(wait_s, out_data, size);
s_mark_end(wait_s);
wait_s->p = wait_s->data;
if (self->wait_s == 0)
@@ -538,53 +632,110 @@ trans_write_copy(struct trans *self)
else
{
temp_s = self->wait_s;
- while (temp_s->next_packet != 0)
+ while (temp_s->next != 0)
{
- temp_s = (struct stream *) (temp_s->next_packet);
+ temp_s = temp_s->next;
}
- temp_s->next_packet = (char *) wait_s;
- }
-
- /* try to send */
- if (send_waiting(self, 0) != 0)
- {
- /* error */
- self->status = TRANS_STATUS_DOWN;
- return 1;
+ temp_s->next = wait_s;
}
-
return 0;
}
/*****************************************************************************/
int APP_CC
+trans_write_copy(struct trans* self)
+{
+ return trans_write_copy_s(self, self->out_s);
+}
+
+/*****************************************************************************/
+int APP_CC
trans_connect(struct trans *self, const char *server, const char *port,
int timeout)
{
int error;
+ int now;
+ int start_time;
+
+ start_time = g_time3();
if (self->sck != 0)
{
g_tcp_close(self->sck);
+ self->sck = 0;
}
if (self->mode == TRANS_MODE_TCP) /* tcp */
{
self->sck = g_tcp_socket();
if (self->sck < 0)
+ {
+ self->status = TRANS_STATUS_DOWN;
return 1;
-
+ }
g_tcp_set_non_blocking(self->sck);
- error = g_tcp_connect(self->sck, server, port);
+ while (1)
+ {
+ error = g_tcp_connect(self->sck, server, port);
+ if (error == 0)
+ {
+ break;
+ }
+ else
+ {
+ if (timeout < 1)
+ {
+ self->status = TRANS_STATUS_DOWN;
+ return 1;
+ }
+ now = g_time3();
+ if (now - start_time < timeout)
+ {
+ g_sleep(timeout / 5);
+ }
+ else
+ {
+ self->status = TRANS_STATUS_DOWN;
+ return 1;
+ }
+ }
+ }
}
else if (self->mode == TRANS_MODE_UNIX) /* unix socket */
{
self->sck = g_tcp_local_socket();
if (self->sck < 0)
+ {
+ self->status = TRANS_STATUS_DOWN;
return 1;
-
+ }
g_tcp_set_non_blocking(self->sck);
- error = g_tcp_local_connect(self->sck, port);
+ while (1)
+ {
+ error = g_tcp_local_connect(self->sck, port);
+ if (error == 0)
+ {
+ break;
+ }
+ else
+ {
+ if (timeout < 1)
+ {
+ self->status = TRANS_STATUS_DOWN;
+ return 1;
+ }
+ now = g_time3();
+ if (now - start_time < timeout)
+ {
+ g_sleep(timeout / 5);
+ }
+ else
+ {
+ self->status = TRANS_STATUS_DOWN;
+ return 1;
+ }
+ }
+ }
}
else
{
@@ -596,6 +747,15 @@ trans_connect(struct trans *self, const char *server, const char *port,
{
if (g_tcp_last_error_would_block(self->sck))
{
+ now = g_time3();
+ if (now - start_time < timeout)
+ {
+ timeout = timeout - (now - start_time);
+ }
+ else
+ {
+ timeout = 0;
+ }
if (g_tcp_can_send(self->sck, timeout))
{
self->status = TRANS_STATUS_UP; /* ok */
@@ -717,10 +877,12 @@ trans_get_out_s(struct trans *self, int size)
return rv;
}
+
/*****************************************************************************/
/* returns error */
int APP_CC
-trans_set_tls_mode(struct trans *self, const char *key, const char *cert)
+trans_set_tls_mode(struct trans *self, const char *key, const char *cert,
+ int disableSSLv3, const char *tls_ciphers)
{
self->tls = ssl_tls_create(self, key, cert);
if (self->tls == NULL)
@@ -729,7 +891,7 @@ trans_set_tls_mode(struct trans *self, const char *key, const char *cert)
return 1;
}
- if (ssl_tls_accept(self->tls) != 0)
+ if (ssl_tls_accept(self->tls, disableSSLv3, tls_ciphers) != 0)
{
g_writeln("trans_set_tls_mode: ssl_tls_accept failed");
return 1;
@@ -742,6 +904,7 @@ trans_set_tls_mode(struct trans *self, const char *key, const char *cert)
return 0;
}
+
/*****************************************************************************/
/* returns error */
int APP_CC
diff --git a/common/trans.h b/common/trans.h
index c2a10762..39fba5c0 100644
--- a/common/trans.h
+++ b/common/trans.h
@@ -41,10 +41,24 @@ typedef int (DEFAULT_CC *ttrans_data_in)(struct trans* self);
typedef int (DEFAULT_CC *ttrans_conn_in)(struct trans* self,
struct trans* new_self);
typedef int (DEFAULT_CC *tis_term)(void);
-typedef int (APP_CC *trans_recv_proc) (struct trans *self, void *ptr, int len);
-typedef int (APP_CC *trans_send_proc) (struct trans *self, const void *data, int len);
+typedef int (APP_CC *trans_recv_proc) (struct trans *self, char *ptr, int len);
+typedef int (APP_CC *trans_send_proc) (struct trans *self, const char *data, int len);
typedef int (APP_CC *trans_can_recv_proc) (struct trans *self, int sck, int millis);
+/* optional source info */
+
+#define XRDP_SOURCE_NONE 0
+#define XRDP_SOURCE_CLIENT 1
+#define XRDP_SOURCE_SESMAN 2
+#define XRDP_SOURCE_CHANSRV 3
+#define XRDP_SOURCE_MOD 4
+
+struct source_info
+{
+ int cur_source;
+ int source[7];
+};
+
struct trans
{
tbus sck; /* socket handle */
@@ -68,6 +82,8 @@ struct trans
trans_recv_proc trans_recv;
trans_send_proc trans_send;
trans_can_recv_proc trans_can_recv;
+ struct source_info *si;
+ int my_source;
};
struct trans* APP_CC
@@ -79,7 +95,7 @@ trans_get_wait_objs(struct trans* self, tbus* objs, int* count);
int APP_CC
trans_get_wait_objs_rw(struct trans *self,
tbus *robjs, int *rcount,
- tbus *wobjs, int *wcount);
+ tbus *wobjs, int *wcount, int *timeout);
int APP_CC
trans_check_wait_objs(struct trans* self);
int APP_CC
@@ -93,6 +109,8 @@ trans_force_write(struct trans* self);
int APP_CC
trans_write_copy(struct trans* self);
int APP_CC
+trans_write_copy_s(struct trans* self, struct stream* out_s);
+int APP_CC
trans_connect(struct trans* self, const char* server, const char* port,
int timeout);
int APP_CC
@@ -104,7 +122,8 @@ trans_get_in_s(struct trans* self);
struct stream* APP_CC
trans_get_out_s(struct trans* self, int size);
int APP_CC
-trans_set_tls_mode(struct trans *self, const char *key, const char *cert);
+trans_set_tls_mode(struct trans *self, const char *key, const char *cert,
+ int disableSSLv3, const char *tls_ciphers);
int APP_CC
trans_shutdown_tls_mode(struct trans *self);
int APP_CC
diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h
index 8313d0ae..e71f8d71 100644
--- a/common/xrdp_client_info.h
+++ b/common/xrdp_client_info.h
@@ -110,6 +110,7 @@ struct xrdp_client_info
int multimon; /* 0 = deny , 1 = allow */
int monitorCount; /* number of monitors detected (max = 16) */
struct monitor_info minfo[16]; /* client monitor data */
+ struct monitor_info minfo_wm[16]; /* client monitor data, non-negative values */
int keyboard_type;
int keyboard_subtype;
@@ -134,6 +135,21 @@ struct xrdp_client_info
char variant[16];
char options[256];
+ /* codec */
+ int h264_codec_id;
+ int h264_prop_len;
+ char h264_prop[64];
+
+ int use_frame_acks;
+ int max_unacknowledged_frame_count;
+
+ int disableSSLv3; /* 0 = no, 1 = yes */
+ char tls_ciphers[64];
+
+ int client_os_major;
+ int client_os_minor;
+
+ int no_orders_supported;
};
#endif
diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h
index 25d9495f..6a055678 100644
--- a/common/xrdp_constants.h
+++ b/common/xrdp_constants.h
@@ -160,6 +160,7 @@
#define RDP_INPUT_CODEPOINT 1
#define RDP_INPUT_VIRTKEY 2
#define RDP_INPUT_SCANCODE 4
+#define RDP_INPUT_UNICODE 5
#define RDP_INPUT_MOUSE 0x8001
#define RDP_INPUT_MOUSEX 0x8002
@@ -217,8 +218,25 @@
/* RDP capabilities */
#define RDP_CAPSET_GENERAL 1
#define RDP_CAPLEN_GENERAL 0x18
-#define OS_MAJOR_TYPE_UNIX 4
-#define OS_MINOR_TYPE_XSERVER 7
+#define OSMAJORTYPE_UNSPECIFIED 0x0000
+#define OSMAJORTYPE_WINDOWS 0x0001
+#define OSMAJORTYPE_OS2 0x0002
+#define OSMAJORTYPE_MACINTOSH 0x0003
+#define OSMAJORTYPE_UNIX 0x0004
+#define OSMAJORTYPE_IOS 0x0005
+#define OSMAJORTYPE_OSX 0x0006
+#define OSMAJORTYPE_ANDROID 0x0007
+#define OSMAJORTYPE_CHROME_OS 0x0008
+#define OSMINORTYPE_UNSPECIFIED 0x0000
+#define OSMINORTYPE_WINDOWS_31X 0x0001
+#define OSMINORTYPE_WINDOWS_95 0x0002
+#define OSMINORTYPE_WINDOWS_NT 0x0003
+#define OSMINORTYPE_OS2_V21 0x0004
+#define OSMINORTYPE_POWER_PC 0x0005
+#define OSMINORTYPE_MACINTOSH 0x0006
+#define OSMINORTYPE_NATIVE_XSERVER 0x0007
+#define OSMINORTYPE_PSEUDO_XSERVER 0x0008
+#define OSMINORTYPE_WINDOWS_RT 0x0009
#define RDP_CAPSET_BITMAP 2
#define RDP_CAPLEN_BITMAP 0x1C
@@ -266,6 +284,24 @@
#define RDP_CAPSET_VIRCHAN 20
#define RDP_CAPLEN_VIRCHAN 0x08
+#define RDP_CAPSET_MULTIFRAGMENT 0x001A
+#define RDP_CAPLEN_MULTIFRAGMENT 0x08
+
+#define RDP_CAPSET_FRAME_ACKNOWLEDGE 0x001E
+#define RDP_CAPLEN_FRAME_ACKNOWLEDGE 0x08
+
+#define RDP_CAPSET_SURFCMDS 0x1C
+#define RDP_CAPLEN_SURFCMDS 0x0C
+
+#define RDP_CAPSET_BMPCODECS 0x1D
+#define RDP_CAPLEN_BMPCODECS 0x1C
+
+#define RDP_CAPSET_COMPDESK 0x19
+#define RDP_CAPLEN_COMPDESK 0x06
+
+#define RDP_CAPSET_LPOINTER 0x1B
+#define RDP_CAPLEN_LPOINTER 0x06
+
#define RDP_SOURCE "MSTSC"
/* Logon flags */
@@ -459,6 +495,40 @@
#define XR_ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT 0x0004
#define XR_ORDERFLAGS_EX_OFFSCREEN_COMPOSITE_SUPPORT 0x0100
+/* orders negotiation indexes */
+#define TS_NEG_DSTBLT_INDEX 0x00
+#define TS_NEG_PATBLT_INDEX 0x01
+#define TS_NEG_SCRBLT_INDEX 0x02
+#define TS_NEG_MEMBLT_INDEX 0x03
+#define TS_NEG_MEM3BLT_INDEX 0x04
+ /* 0x05 */
+ /* 0x06 */
+#define TS_NEG_DRAWNINEGRID_INDEX 0x07
+#define TS_NEG_LINETO_INDEX 0x08
+#define TS_NEG_MULTI_DRAWNINEGRID_INDEX 0x09
+ /* 0x0A */
+#define TS_NEG_SAVEBITMAP_INDEX 0x0B
+ /* 0x0C */
+ /* 0x0D */
+ /* 0x0E */
+#define TS_NEG_MULTIDSTBLT_INDEX 0x0F
+#define TS_NEG_MULTIPATBLT_INDEX 0x10
+#define TS_NEG_MULTISCRBLT_INDEX 0x11
+#define TS_NEG_MULTIOPAQUERECT_INDEX 0x12
+#define TS_NEG_FAST_INDEX_INDEX 0x13
+#define TS_NEG_POLYGON_SC_INDEX 0x14
+#define TS_NEG_POLYGON_CB_INDEX 0x15
+#define TS_NEG_POLYLINE_INDEX 0x16
+ /* 0x17 */
+#define TS_NEG_FAST_GLYPH_INDEX 0x18
+#define TS_NEG_ELLIPSE_SC_INDEX 0x19
+#define TS_NEG_ELLIPSE_CB_INDEX 0x1A
+#define TS_NEG_INDEX_INDEX 0x1B
+ /* 0x1C */
+ /* 0x1D */
+ /* 0x1E */
+ /* 0x1F */
+
/* drawable types */
#define WND_TYPE_BITMAP 0
#define WND_TYPE_WND 1
@@ -499,29 +569,13 @@
#define CB_ITEMCHANGE 300
-#define OSMAJORTYPE_UNSPECIFIED 0x0000
-#define OSMAJORTYPE_WINDOWS 0x0001
-#define OSMAJORTYPE_OS2 0x0002
-#define OSMAJORTYPE_MACINTOSH 0x0003
-#define OSMAJORTYPE_UNIX 0x0004
-
-#define OSMINORTYPE_UNSPECIFIED 0x0000
-#define OSMINORTYPE_WINDOWS_31X 0x0001
-#define TS_OSMINORTYPE_WINDOWS_95 0x0002
-#define TS_OSMINORTYPE_WINDOWS_NT 0x0003
-#define TS_OSMINORTYPE_OS2_V21 0x0004
-
-#define TS_OSMINORTYPE_POWER_PC 0x0005
-#define TS_OSMINORTYPE_MACINTOSH 0x0006
-#define TS_OSMINORTYPE_NATIVE_XSERVER 0x0007
-#define TS_OSMINORTYPE_PSEUDO_XSERVER 0x0008
#define TS_CAPS_PROTOCOLVERSION 0x0200
#define FASTPATH_OUTPUT_SUPPORTED 0x0001
#define NO_BITMAP_COMPRESSION_HDR 0x0400
#define LONG_CREDENTIALS_SUPPORTED 0x0004
#define AUTORECONNECT_SUPPORTED 0x0008
-#define ENC_SALTED_CHEKSUM 0x0010
+#define ENC_SALTED_CHECKSUM 0x0010
#define NEGOTIATEORDERSUPPORT 0x0002
#define ZEROBOUNDSDELTASUPPORT 0x0008
#define COLORINDEXSUPPORT 0x0020
@@ -537,34 +591,33 @@
#define COMPDESK_NOT_SUPPORTED 0x0000
#define COMPDESK_SUPPORTED 0x0001
-#define SURCMDS_SETSURFACEBITS 0x00000002
-#define SURCMDS_FRAMEMARKER 0x00000010
-#define SURCMDS_STREAMSUFRACEBITS 0x00000040
+#define SURFCMDS_SETSURFACEBITS 0x00000002
+#define SURFCMDS_FRAMEMARKER 0x00000010
+#define SURFCMDS_STREAMSUFRACEBITS 0x00000040
-/* CODEC_GUID_NSCODEC 0xCA8D1BB9000F154F589FAE2D1A87E2D6 */
+/* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589FAE2D1A87E2D6 */
#define XR_CODEC_GUID_NSCODEC \
"\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
-/* CODEC_GUID_REMOTEFX 0x76772F12BD724463AFB3B73C9C6F7886 */
+/* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3B73C9C6F7886 */
#define XR_CODEC_GUID_REMOTEFX \
"\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
-/* CODEC_GUID_JPEG 0x1BAF4CE6 9EED 430C 869ACB8B37B66237 */
+/* CODEC_GUID_IMAGE_REMOTEFX 2744CCD4-9D8A-4E74-803C-0ECBEEA19C54 */
+#define XR_CODEC_GUID_IMAGE_REMOTEFX \
+ "\xD4\xCC\x44\x27\x8A\x9D\x74\x4E\x80\x3C\x0E\xCB\xEE\xA1\x9C\x54"
+
+/* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869ACB8B37B66237 */
#define XR_CODEC_GUID_JPEG \
"\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
-/* CODEC_GUID_PNG 0xOE0C858D 28E0 45DB ADAA0F83E57CC560 */
+/* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA0F83E57CC560 */
#define XR_CODEC_GUID_PNG \
"\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60"
-#define RDP_CAPSET_SURFCMDS 0x1c
-#define RDP_CAPLEN_SURFCMDS 0x0c
-#define RDP_CAPSET_BMPCODECS 0x1d
-#define RDP_CAPLEN_BMPCODECS 0x1c
-#define RDP_CAPSET_COMPDESK 0x19
-#define RDP_CAPLEN_COMPDESK 0x06
-#define RDP_CAPSET_LPOINTER 0x27
-#define RDP_CAPLEN_LPOINTER 0x06
+/* MFVideoFormat_H264 0x34363248-0000-0010-800000AA00389B71 */
+#define XR_CODEC_GUID_H264 \
+ "\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"
/* fastpath input */
#define FASTPATH_INPUT_SECURE_CHECKSUM 0x1
@@ -617,4 +670,10 @@
#define XRDP_MAX_BITMAP_CACHE_IDX 2000
#define XRDP_BITMAP_CACHE_ENTRIES 2048
+#define XR_MIN_KEY_CODE 8
+#define XR_MAX_KEY_CODE 256
+
+#define XR_RDP_SCAN_LSHIFT 42
+#define XR_RDP_SCAN_ALT 56
+
#endif
diff --git a/configure.ac b/configure.ac
index e1a150e8..5c73168a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,13 +1,45 @@
# Process this file with autoconf to produce a configure script
-AC_PREREQ(2.59)
-AC_INIT([xrdp], [0.9.0], [xrdp-devel@lists.sourceforge.net])
+AC_PREREQ(2.65)
+AC_INIT([xrdp], [0.9.1], [xrdp-devel@googlegroups.com])
AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in)
-AM_INIT_AUTOMAKE([1.6 foreign])
+AM_INIT_AUTOMAKE([1.7.2 foreign])
+AC_CONFIG_MACRO_DIR([m4])
AC_PROG_CC
AC_C_CONST
AC_PROG_LIBTOOL
PKG_PROG_PKG_CONFIG
+
+AC_CONFIG_SUBDIRS([libpainter librfxcodec])
+
+# Use silent rules by default if supported by Automake
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+AX_CFLAGS_WARN_ALL
+AX_APPEND_COMPILE_FLAGS([-Wwrite-strings])
+AX_GCC_FUNC_ATTRIBUTE([format])
+AX_TYPE_SOCKLEN_T
+
+case $host_os in
+ *linux*)
+ linux=yes
+ ;;
+ *freebsd*)
+ freebsd=yes
+ ;;
+ *netbsd*)
+ netbsd=yes
+ ;;
+ *openbsd*)
+ openbsd=yes
+ ;;
+esac
+
+AM_CONDITIONAL(LINUX, [test "x$linux" = xyes])
+AM_CONDITIONAL(FREEBSD, [test "x$freebsd" = xyes])
+AM_CONDITIONAL(OPENBSD, [test "x$openbsd" = xyes])
+AM_CONDITIONAL(NETBSD, [test "x$netbsd" = xyes])
+
AC_ARG_WITH([systemdsystemunitdir],
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
[], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
@@ -29,6 +61,12 @@ AC_ARG_ENABLE(nopam, AS_HELP_STRING([--enable-nopam],
fi
])
AM_CONDITIONAL(SESMAN_NOPAM, [test x$enable_pam != xyes])
+AC_ARG_ENABLE(ipv6, AS_HELP_STRING([--enable-ipv6],
+ [Build IPv6 support (default: no, experimental)]),
+ [], [enable_ipv6=no])
+AC_ARG_ENABLE(ipv6only, AS_HELP_STRING([--enable-ipv6only],
+ [Build IPv6-only (default: no)]),
+ [], [enable_ipv6only=no])
AC_ARG_ENABLE(kerberos, AS_HELP_STRING([--enable-kerberos],
[Build kerberos support (default: no)]),
[], [enable_kerberos=no])
@@ -69,13 +107,48 @@ AC_ARG_ENABLE(rfxcodec, AS_HELP_STRING([--enable-rfxcodec],
[Build using librfxcodec (default: no)]),
[], [enable_rfxcodec=no])
AM_CONDITIONAL(XRDP_RFXCODEC, [test x$enable_rfxcodec = xyes])
+AC_ARG_ENABLE(opus, AS_HELP_STRING([--enable-opus],
+ [Build opus(audio codec) (default: no)]),
+ [], [enable_opus=no])
+AM_CONDITIONAL(XRDP_OPUS, [test x$enable_opus = xyes])
+AC_ARG_ENABLE(mp3lame, AS_HELP_STRING([--enable-mp3lame],
+ [Build lame mp3(audio codec) (default: no)]),
+ [], [enable_mp3lame=no])
+AM_CONDITIONAL(XRDP_MP3LAME, [test x$enable_mp3lame = xyes])
+AC_ARG_ENABLE(pixman, AS_HELP_STRING([--enable-pixman],
+ [Use pixman library (default: no)]),
+ [], [enable_pixman=no])
+AM_CONDITIONAL(XRDP_PIXMAN, [test x$enable_pixman = xyes])
+AM_CONDITIONAL(XRDP_PAINTER, [test x$enable_painter = xyes])
+AC_ARG_ENABLE(painter, AS_HELP_STRING([--enable-painter],
+ [Use painter library (default: no)]),
+ [], [enable_painter=no])
+AM_CONDITIONAL(XRDP_PAINTER, [test x$enable_painter = xyes])
+
+# Don't fail without working nasm if rfxcodec is not enabled
+if test "x$enable_rfxcodec" != xyes; then
+ with_simd=no
+ export with_simd
+fi
-AM_CONDITIONAL(GOT_PREFIX, test "x${prefix}" != "xNONE"])
+# Check if -ldl is needed to use dlopen()
+DLOPEN_LIBS=
+AC_CHECK_FUNC(dlopen, [],
+ [AC_CHECK_LIB(dl, dlopen, [DLOPEN_LIBS=-ldl])])
+AC_SUBST(DLOPEN_LIBS)
# checking for openssl
-AC_CHECK_HEADER([openssl/rc4.h], [],
- [AC_MSG_ERROR([please install libssl-dev or openssl-devel])],
- [#include <stdlib.h>])
+PKG_CHECK_MODULES([OPENSSL], [openssl >= 0], [],
+ [AC_MSG_ERROR([please install libssl-dev or openssl-devel])])
+
+# checking for pam variation
+# Linux-PAM is used in Linux systems
+# OpenPAM is used by FreeBSD, NetBSD, DragonFly BSD and OS X
+# OpenBSD uses BSD Authentication rather than both PAMs
+AC_CHECK_HEADER([security/_pam_types.h],
+ [AC_DEFINE([HAVE__PAM_TYPES_H], 1, [Using Linux-PAM], [])])
+AC_CHECK_HEADER([security/pam_constants.h],
+ [AC_DEFINE([HAVE_PAM_CONSTANTS_H], 1, [Using OpenPAM], [])])
# checking if pam should be autodetected.
if test "x$enable_pam" = "xyes"
@@ -90,10 +163,16 @@ then
fi
fi
-AC_CHECK_MEMBER([struct in6_addr.s6_addr],
- [],
- [AC_DEFINE(NO_ARPA_INET_H_IP6, 1, [for IPv6])],
- [#include <arpa/inet.h>])
+if test "x$enable_ipv6only" = "xyes"
+then
+ enable_ipv6=yes
+ AC_DEFINE([XRDP_ENABLE_IPV6ONLY],1,[Enable IPv6 only])
+fi
+
+if test "x$enable_ipv6" = "xyes"
+then
+ AC_DEFINE([XRDP_ENABLE_IPV6],1,[Enable IPv6])
+fi
if test "x$enable_pam" != "xyes" || test "x$bsd" = "xtrue"
then
@@ -117,11 +196,26 @@ fi
# checking for fuse
if test "x$enable_fuse" = "xyes"
then
- AC_CHECK_HEADER([fuse.h], [],
- [AC_MSG_ERROR([please install libfuse-dev or fuse-devel])],
- [#define _FILE_OFFSET_BITS 64])
+ PKG_CHECK_MODULES([FUSE], [fuse >= 2.6], [],
+ [AC_MSG_ERROR([please install libfuse-dev or fuse-devel])])
+fi
+
+# checking for opus
+if test "x$enable_opus" = "xyes"
+then
+ AC_CHECK_HEADER([opus/opus.h], [],
+ [AC_MSG_ERROR([please install libopus-dev or opus-devel])])
+fi
+
+# checking for lame mp3
+if test "x$enable_mp3lame" = "xyes"
+then
+ AC_CHECK_HEADER([lame/lame.h], [],
+ [AC_MSG_ERROR([please install libmp3lame-dev or lamemp3-devel])])
fi
+AS_IF( [test "x$enable_pixman" = "xyes"] , [PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.1.0)] )
+
# checking for TurboJPEG
if test "x$enable_tjpeg" = "xyes"
then
@@ -152,54 +246,67 @@ else
fi
fi
-# checking for Xlib, Xfixes
-AC_CHECK_HEADER([X11/Xlib.h], [],
- [AC_MSG_ERROR([please install libx11-dev or libX11-devel])])
+AC_PATH_XTRA
+if test "x$no_x" == "xyes"; then
+ AC_MSG_ERROR([please install libx11-dev or libX11-devel])
+fi
+
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $X_CFLAGS"
+
+# checking for Xfixes
AC_CHECK_HEADER([X11/extensions/Xfixes.h], [],
[AC_MSG_ERROR([please install libx11-dev and libxfixes-dev or libXfixes-devel])],
[#include <X11/Xlib.h>])
+
+# checking for Xrandr
AC_CHECK_HEADER([X11/extensions/Xrandr.h], [],
[AC_MSG_ERROR([please install libxrandr-dev or libXrandr-devel])],
[#include <X11/Xlib.h>])
-libdir="${libdir}/xrdp";
+CFLAGS="$save_CFLAGS"
+
+AC_SUBST([moduledir], '${libdir}/xrdp')
+
if test "x${prefix}" = "xNONE" ; then
sysconfdir="/etc";
localstatedir="/var";
fi
-AC_CONFIG_FILES([Makefile
- common/Makefile
- vnc/Makefile
- rdp/Makefile
- libxrdp/Makefile
- xup/Makefile
- mc/Makefile
- neutrinordp/Makefile
- xrdp/Makefile
- sesman/Makefile
- sesman/libscp/Makefile
- sesman/tools/Makefile
- sesman/sessvc/Makefile
- sesman/chansrv/Makefile
- keygen/Makefile
- docs/Makefile
- docs/man/Makefile
- instfiles/Makefile
- instfiles/pam.d/Makefile
- instfiles/init.d/Makefile
- instfiles/default/Makefile
- instfiles/pulse/Makefile
- genkeymap/Makefile
- xrdpapi/Makefile
- xrdpvr/Makefile
+
+PKG_INSTALLDIR
+
+AC_CHECK_HEADERS([sys/prctl.h])
+
+AC_CONFIG_FILES([
+ common/Makefile
+ docs/Makefile
+ docs/man/Makefile
+ genkeymap/Makefile
+ instfiles/default/Makefile
+ instfiles/init.d/Makefile
+ instfiles/Makefile
+ instfiles/pam.d/Makefile
+ instfiles/pulse/Makefile
+ instfiles/rc.d/Makefile
+ keygen/Makefile
+ libxrdp/Makefile
+ Makefile
+ mc/Makefile
+ neutrinordp/Makefile
+ pkgconfig/Makefile
+ pkgconfig/xrdp.pc
+ pkgconfig/xrdp-uninstalled.pc
+ rdp/Makefile
+ sesman/chansrv/Makefile
+ sesman/libscp/Makefile
+ sesman/Makefile
+ sesman/sessvc/Makefile
+ sesman/tools/Makefile
+ vnc/Makefile
+ xrdpapi/Makefile
+ xrdp/Makefile
+ xrdpvr/Makefile
+ xup/Makefile
])
-# fontdump/Makefile
-# xrdp/cursors/Makefile
-# Xserver/hw/rdp/Makefile
-AC_OUTPUT
-# example of how to check for a struct in a header
-#AC_CHECK_MEMBER([struct in6_addr.s6_addr],
-# [],
-# [AC_DEFINE(NO_ARPA_INET_H_IP6, 1, [for IPv6])],
-# [#include <arpa/inet.h>])
+AC_OUTPUT
diff --git a/design.txt b/design.txt
index 431bcbd1..3b120c89 100644
--- a/design.txt
+++ b/design.txt
@@ -31,5 +31,5 @@ is lost, the session remains.
For X11, start the XServer after the user is
authenticated. First check for the next available X11 display,
-create a user session, start the XServer and set the DISPLAY enviromenet
+create a user session, start the XServer and set the DISPLAY environment
variable.
diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am
index 507809bd..48c26559 100644
--- a/docs/man/Makefile.am
+++ b/docs/man/Makefile.am
@@ -1,4 +1,4 @@
-man_MANS = \
+dist_man_MANS = \
xrdp-dis.1 \
sesman.ini.5 \
xrdp.ini.5 \
@@ -14,4 +14,4 @@ man_MANS = \
noinst_man_MANS = \
xrdp-xcon.8
-EXTRA_DIST = $(man_MANS) $(noinst_man_MANS)
+EXTRA_DIST = $(noinst_man_MANS)
diff --git a/docs/man/sesman.ini.5 b/docs/man/sesman.ini.5
index a1ba3a50..b8ced28f 100644
--- a/docs/man/sesman.ini.5
+++ b/docs/man/sesman.ini.5
@@ -1,206 +1,225 @@
-.\"
-.TH "sesman.ini" "5" "0.1.0" "xrdp team" ""
+.\"
+.TH "sesman.ini" "5" "0.9.1" "xrdp team" ""
.SH "NAME"
-\fBsesman.ini\fR \- Configuration file for \fBsesman\fR(8)
+\fBsesman.ini\fR \- Configuration file for \fBxrdp-sesman\fR(8)
.SH "DESCRIPTION"
-This is the man page for \fBsesman.ini\fR, \fBsesman\fR(8) configuration file.
-It is composed by a number of sections, each one composed by a section name, enclosed by square brackets, folowed by a list of \fI<parameter>\fR=\fI<value>\fR lines.
+\fBsesman.ini\fR consists of several sections. Each section starts with
+the section name in square brackets, followed by a list of
+\fIparameter\fR=\fIvalue\fR lines. Following sections are recognized:
-\fBsesman.ini\fR supports the following sections:
+.TP
+\fB[Globals]\fR
+Global configuration
-.TP
-\fB[Globals]\fR \- sesman global configuration section,
+.TP
+\fB[Logging]\fR
+Logging subsystem
-.TP
-\fB[Logging]\fR \- logging subsystem parameters
+.TP
+\fB[Sessions]\fR
+Session management
-.TP
-\fB[Security]\fR \- Access control parameters
+.TP
+\fB[Security]\fR
+Access control
-.TP
-\fB[Sessions]\fR \- Session management parameters
+.TP
+\fB[X11rdp]\fR, \fB[Xvnc]\fR, \fB[Xorg]\fR
+X11 server settings for supported servers
-.LP
-All options and values (except for file names and paths) are case insensitive, and are described in detail below.
+.TP
+\fB[Chansrv]\fR
+Settings for xrdp-chansrv(8)
-.LP
-For any of the following parameter, if it's specified more than one time the last entry encountered will be used.
+.TP
+\fB[SessionVariables]\fR
+Environment variables for the session
-\fBNOTE\fR: if any of these options is specified outside its section, it will be \fIignored\fR.
+.LP
+All parameters and values (except for file names and paths) are case
+insensitive, and are described in detail below. If any parameter is
+specified more than once, the last entry will be used. Options specified
+outside their proper section will be \fIignored\fR.
.SH "GLOBALS"
-The options to be specified in the \fB[globals]\fR section are the following:
+Following parameters can be used in the \fB[Globals]\fR section.
-.TP
+.TP
\fBListenAddress\fR=\fIip address\fR
-Specifies sesman listening address. Default is 0.0.0.0 (all interfaces)
+xrdp-sesman listening address. If not specified, defaults to \fI0.0.0.0\fR
+(all interfaces).
-.TP
+.TP
\fBListenPort\fR=\fIport number\fR
-Specifies sesman listening port. Default is 3350
+xrdp-sesman listening port. If not specified, defaults to \fI3350\fR.
-.TP
-\fBEnableUserWindowManager\fR=\fI[0|1]\fR
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables user specific window manager, that is, anyone can define it's own script executed by sesman when starting a new session, specified by \fBUserWindowManager\fR
+.TP
+\fBEnableUserWindowManager\fR=\fI[true|false]\fR
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables user
+specific startup script. That is, xrdp-sesman will execute the script
+specified by \fBUserWindowManager\fR if it exists.
-.TP
-\fBUserWindowManager\fR=\fIstartwm.sh\fR
-This option specifies the script run by sesman when starting a session and per\-user window manager is enabled.
-.br
-The path is relative to user's HOME directory
+.TP
+\fBUserWindowManager\fR=\fIfilename\fR
+Name of the startup script relative to the user's home directory. If
+present and enabled by \fBEnableUserWindowManager\fR, that script is
+executed instead of \fBDefaultWindowManager\fR.
-.TP
-\fBDefaultWindowManager\fR=\fI${SESMAN_BIN_DIR}/startwm.sh\fR
-This contains full path to the default window manager startup script used by sesman to start a session
+.TP
+\fBDefaultWindowManager\fR=\fIfilename\fR
+Full path to the default startup script used by xrdp-sesman to start a
+session if the user script is disabled or missing.
.SH "LOGGING"
-The following parameters can be used in the \fB[logging]\fR section:
+Following parameters can be used in the \fB[Logging]\fR section.
-.TP
-\fBLogFile\fR=\fI${SESMAN_LOG_DIR}/sesman.log\fR
-This options contains the path to logfile. It can be either absolute or relative, and the default is \fI${SESMAN_LOG_DIR}/sesman.log\fR
+.TP
+\fBLogFile\fR=\fIfilename\fR
+Log file path. It can be either absolute or relative. If not specified,
+defaults to \fI./sesman.log\fR
-.TP
+.TP
\fBLogLevel\fR=\fIlevel\fR
This option can have one of the following values:
-\fBCORE\fR or \fB0\fR \- Log only core messages. these messages are _always_ logged, regardless the logging level selected.
+\fBCORE\fR or \fB0\fR \- Log only core messages. Those messages are
+logged \fIregardless\fR of the selected logging level.
-\fBERROR\fR or \fB1\fR \- Log only error messages
+\fBERROR\fR or \fB1\fR \- Log only error messages.
-\fBWARNING\fR, \fBWARN\fR or \fB2\fR \- Logs warnings and error messages
+\fBWARNING\fR, \fBWARN\fR or \fB2\fR \- Logs warnings and error messages.
-\fBINFO\fR or \fB3\fR \- Logs errors, warnings and informational messages
+\fBINFO\fR or \fB3\fR \- Log errors, warnings and informational messages.
-\fBDEBUG\fR or \fB4\fR \- Log everything. If \fBsesman\fR is compiled in debug mode, this options will output many more low\-level message, useful for developers
+\fBDEBUG\fR or \fB4\fR \- Log everything. If xrdp-sesman is compiled in
+debug mode, this options will output many more low\-level messages.
-.TP
-\fBEnableSyslog\fR=\fI[0|1]\fR
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables logging to syslog. Otherwise syslog is disabled.
+.TP
+\fBEnableSyslog\fR=\fI[true|false]\fR
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging to
+syslog.
-.TP
+.TP
\fBSyslogLevel\fR=\fIlevel\fR
-This option sets the logging level for syslog. It can have the same values of \fBLogLevel\fR. If \fBSyslogLevel\fR is greater than \fBLogLevel\fR, its value is lowered to that of \fBLogLevel\fR.
+Logging level for syslog. It can have the same values as \fBLogLevel\fR.
+If \fBSyslogLevel\fR and \fBLogLevel\fR differ, the least verbose setting
+takes effect for syslog.
.SH "SESSIONS"
-The following parameters can be used in the \fB[Sessions]\fR section:
-
-.TP
-\fBX11DisplayOffset\fR=\fI<number>\fR
-Specifies the first X display number available for \fBsesman\fP(8). This prevents sesman from interfering with real X11 servers. The default is 10.
-
-.TP
-\fBMaxSessions\fR=\fI<number>\fR
-Sets the maximum number of simultaneous session on terminal server.
-.br
-If unset or set to \fI0\fR, unlimited session are allowed.
-
-.TP
-\fBKillDisconnected\fR=\fI[0|1]\fR
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR, every session will be killed within 60 seconds when the user disconnects.
-.br
-
-.TP
-\fBIdleTimeLimit\fR=\fI<number>\fR
-Sets the the time limit before an idle session is disconnected.
-.br
-If set to \fI0\fR, automatic disconnection is disabled.
-.br
-\fI\-this option is currently ignored!\-\fR
-
-.TP
-\fBDisconnectedTimeLimit\fR=\fI<number>\fR
-Sets the time(in seconds) limit before a disconnected session is killed.
-.br
+Following parameters can be used in the \fB[Sessions]\fR section.
+
+.TP
+\fBX11DisplayOffset\fR=\fInumber\fR
+The first X display number available for xrdp-sesman. This prevents
+xrdp-sesman from interfering with real X11 servers. If not specified,
+defaults to \fI10\fR.
+
+.TP
+\fBMaxSessions\fR=\fInumber\fR
+Sets the maximum number of simultaneous sessions. If not set or set to
+\fI0\fR, unlimited session are allowed.
+
+.TP
+\fBKillDisconnected\fR=\fI[true|false]\fR
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, every session will be killed
+within 60 seconds after the user disconnects.
+
+.TP
+\fBIdleTimeLimit\fR=\fInumber\fR
+\fI\This option is currently ignored!\fR Time limit before an idle
+session is disconnected. If set to \fI0\fR, automatic disconnection is
+disabled.
+
+.TP
+\fBDisconnectedTimeLimit\fR=\fInumber\fR
+Sets the time limit (in seconds) before a disconnected session is killed.
If set to \fI0\fR, automatic killing is disabled.
-.br
-.TP
+.TP
\fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR
-Session allocation policy. By Default, a new session is created
-for the combination <User,BitPerPixel> when using Xrdp, and
+Session allocation policy. By default, a new session is created
+for the combination <User,BitPerPixel> when using Xrdp, and
for the combination <User,BitPerPixel,DisplaySize> when using Xvnc.
-This behaviour can be changed by setting session policy to:
+This behavior can be changed by setting session policy to:
.br
-.br
+.br
\fBUBD\fR - session per <User,BitPerPixel,DisplaySize>
-.br
+.br
\fBUBI\fR - session per <User,BitPerPixel,IPAddr>
-.br
+.br
\fBUBC\fR - session per <User,BitPerPixel,Connection>
-.br
+.br
\fBUBDI\fR - session per <User,BitPerPixel,DisplaySize,IPAddr>
-.br
+.br
\fBUBDC\fR - session per <User,BitPerPixel,DisplaySize,Connection>
.br
.br
-Note that the criteria <User,BitPerPixel> can not be turned off
-and <DisplaySize> will always be checkt when for Xvnc connections.
+Note that the \fBUser\fR and \fBBitPerPixel\fR criteria cannot be turned
+off. For Xvnc connections, \fBDisplaySize\fR is always enabled as well.
.br
.SH "SECURITY"
-The following parameters can be used in the \fB[Sessions]\fR section:
-
-.TP
-\fBAllowRootLogin\fR=\fI[0|1]\fR
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR enables root login on the terminal server
-
-.TP
-\fBMaxLoginRetry\fR=\fI[0|1]\fR
-The number of login attempts that are allowed on terminal server. If set to \fI0\fR, unlimited attempts are allowed. The default value for this field is \fI3\fR.
-
-.TP
-\fBTerminalServerUsers\fR=\fItsusers\fR
-Only the users belonging to the group \fItsusers\fR are allowed to login on terminal server.
-.br
-If unset or set to an invalid or non\-existent group, login for all users is enabled.
-
-.TP
-\fBTerminalServerAdmins\fR=\fItsadmins\fR
-Sets the group which a user shall belong to have session management rights.
-.br
-\fI\-this option is currently ignored!\-\fR
-
-.SH "EXAMPLES"
-This is an example \fBsesman.ini\fR:
-
-.nf
-[Globals]
-ListenAddress=127.0.0.1
-ListenPort=3350
-EnableUserWindowManager=1
-UserWindowManager=startwm.sh
-DefaultWindowManager=startwm.sh
-
-[Logging]
-LogFile=/usr/local/xrdp/sesman.log
-LogLevel=DEBUG
-EnableSyslog=0
-SyslogLevel=DEBUG
-
-[Sessions]
-MaxSessions=10
-KillDisconnected=0
-IdleTimeLimit=0
-DisconnectedTimeLimit=0
-
-[Security]
-AllowRootLogin=1
-MaxLoginRetry=3
-TerminalServerUsers=tsusers
-TerminalServerAdmins=tsadmins
-.fi
+Following parameters can be used in the \fB[Security]\fR section.
+
+.TP
+\fBAllowRootLogin\fR=\fI[true|false]\fR
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, enables root login on the
+terminal server.
+
+.TP
+\fBMaxLoginRetry\fR=\fInumber\fR
+The number of login attempts that are allowed on terminal server. If set
+to \fI0\fR, unlimited attempts are allowed. If not specified, defaults to
+\fI3\fR.
+
+.TP
+\fBTerminalServerUsers\fR=\fIgroup\fR
+Only the users belonging to the specified group are allowed to login on
+terminal server. If unset or set to an invalid or non\-existent group,
+login for all users is enabled.
+
+.TP
+\fBTerminalServerAdmins\fR=\fIgroup\fR
+\fIThis option is currently ignored!\fR Only members of this group can
+have session management rights.
+
+.TP
+\fBAlwaysGroupCheck\fR=\fI[true|false]\fR
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, require group membership even
+if the group specified in \fBTerminalServerUsers\fR doesn't exist.
+
+.SH "X11 SERVER"
+Following parameters can be used in the \fB[X11rdp]\fR, \fB[Xvnc]\fR and
+\fB[Xorg]\fR sections.
+
+.TP
+\fBparam\fR=\fIstring\fR
+Multiple \fIparam\fR lines are supported. This first line specifies the
+path to the X11 server executable. Following lines specify command line
+arguments passed to the X11 server.
+
+.SH "CHANSRV"
+Following parameters can be used in the \fB[Chansrv]\fR section.
+
+.TP
+\fBFuseMountName\fR=\fIstring\fR
+Directory for drive redirection, relative to the user home directory.
+Created if it doesn't exist. If not specified, defaults to \fIxrdp_client\fR.
+
+.SH "SESSIONS VARIABLES"
+All entries in the \fB[SessionVariables]\fR section are set as
+environment variables in the user's session.
.SH "FILES"
-${SESMAN_CFG_DIR}/sesman.ini
+/etc/xrdp/sesman.ini
.SH "SEE ALSO"
-.BR sesman (8),
-.BR sesrun (8),
+.BR xrdp-sesman (8),
+.BR xrdp-sesrun (8),
.BR xrdp (8),
.BR xrdp.ini (5)
-for more info on \fBxrdp\fR see http://xrdp.sf.net
+For more info on \fBxrdp\fR see http://www.xrdp.org/
diff --git a/docs/man/xrdp-chansrv.8 b/docs/man/xrdp-chansrv.8
index aa4747d8..c1deb085 100644
--- a/docs/man/xrdp-chansrv.8
+++ b/docs/man/xrdp-chansrv.8
@@ -1,4 +1,4 @@
-.TH "xrdp\-chansrv" "8" "0.7.0" "xrdp team" ""
+.TH "xrdp\-chansrv" "8" "0.9.1" "xrdp team" ""
.SH "NAME"
\fBxrdp\-chansrv\fR \- \fBxrdp\fR channel server
@@ -36,11 +36,11 @@ UNIX socket used by external programs to implement channels.
.I /tmp/.xrdp/xrdp_api_*
UNIX socket used by \fBxrdp\-chansrv\fP to communicate with \fBxrdp\-sesman\fP.
.TP
-.I $HOME/xrdp-chansrv.log
+.I $XDG_DATA_HOME/xrdp/xrdp-chansrv.log
Log file used by \fBxrdp\-chansrv\fP(8).
.SH "SEE ALSO"
.BR xrdp\-sesman (8),
.BR sesman.ini (5).
-for more info on \fBxrdp\fR see http://xrdp.sf.net
+for more info on \fBxrdp\fR see http://www.xrdp.org/
diff --git a/docs/man/xrdp-dis.1 b/docs/man/xrdp-dis.1
index 089621ae..09de5f10 100644
--- a/docs/man/xrdp-dis.1
+++ b/docs/man/xrdp-dis.1
@@ -1,4 +1,4 @@
-.TH "xrdp-dis" "8" "0.7.0" "xrdp team"
+.TH "xrdp-dis" "1" "0.9.1" "xrdp team"
.SH NAME
xrdp\-dis \- xrdp disconnect utility
@@ -7,7 +7,7 @@ xrdp\-dis \- xrdp disconnect utility
.SH DESCRIPTION
.PP
-\fBxrdp\-dix\fP is run with no parameters to disconnect your xrdp session.
+\fBxrdp\-dis\fP is run with no parameters to disconnect your xrdp session.
.SH ENVIRONMENT
.TP
@@ -19,5 +19,9 @@ to get the default host and display number.
.I /tmp/.xrdp/xrdp_disconnect_display_*
UNIX socket used to communicate with the \fBxrdp\fP(8) session manager.
+.SH KNOWN ISSUES
+.TP
+This utility doesn't support disconnecting xorgxrdp sessions so far.
+
.SH SEE ALSO
-.BR xrdp (1).
+.BR xrdp (8).
diff --git a/docs/man/xrdp-genkeymap.8 b/docs/man/xrdp-genkeymap.8
index 068f04dd..aa9f866c 100644
--- a/docs/man/xrdp-genkeymap.8
+++ b/docs/man/xrdp-genkeymap.8
@@ -1,4 +1,4 @@
-.TH "xrdp\-genkeymap" "8" "0.1.0" "xrdp team" ""
+.TH "xrdp\-genkeymap" "8" "0.9.1" "xrdp team" ""
.de URL
. \\$2 \(laURL: \\$1 \(ra\\$3
..
@@ -21,36 +21,36 @@ The key map information is stored in the file named \fIoutfile\fP.
.SH "FILES"
.TP
-.I /etc/xrdp/km-XXXX.ini
-Files containing the keyboard mapping for language \fIXXXX\fP, which is a 4 digit hexadecimal number identifying the country and language code.
+.I /etc/xrdp/km-XXXXXXXX.ini
+Files containing the keyboard mapping for language \fIXXXXXXXX\fP, which is a 8 digit hexadecimal number identifying the country and language code.
.RS 8
.TP
-.B 0405
-cs czech
+.B 00000405
+cs Czech
.TP
-.B 0407
-de german
+.B 00000407
+de German
.TP
-.B 0409
-en-us us english
+.B 00000409
+en-us US English
.TP
-.B 040c
-fr french
+.B 0000040c
+fr French
.TP
-.B 0410
-it italy
+.B 00000410
+it Italian
.TP
-.B 0416
+.B 00000416
br Portuguese (Brazil)
.TP
-.B 0419
-ru russian
+.B 00000419
+ru Russian
.TP
-.B 041d
-se swedish
+.B 0000041d
+se Swedish
.TP
-.B 0809
-en-uk uk english
+.B 00000809
+en-uk UK English
.RE
.SH "AUTHORS"
@@ -64,4 +64,4 @@ Simone Fedele <ilsimo@users.sourceforge.net>
.BR unicode (7),
.URL "https://github.com/FreeRDP/FreeRDP/wiki/Keyboard" "Description of Keyboard Input mapping" .
-for more info on \fBxrdp\fR see http://xrdp.sf.net
+for more info on \fBxrdp\fR see http://www.xrdp.org/
diff --git a/docs/man/xrdp-keygen.8 b/docs/man/xrdp-keygen.8
index 71269f5c..84d4eafd 100644
--- a/docs/man/xrdp-keygen.8
+++ b/docs/man/xrdp-keygen.8
@@ -1,5 +1,9 @@
.\" Hey, EMACS: -*- nroff -*-
-.TH xrdp\-keygen 8 "0.7.0" "xrdp team"
+.\"-
+.\" Copyright © 2007, 2008 Vincent Bernat <bernat@debian.org>
+.\" License: GPL-2+
+.\"-
+.TH xrdp\-keygen 8 "0.9.1" "xrdp team"
.SH NAME
xrdp\-keygen \- xrdp RSA key generation utility
diff --git a/docs/man/xrdp-sesadmin.8 b/docs/man/xrdp-sesadmin.8
index ade1dd58..29e14c18 100644
--- a/docs/man/xrdp-sesadmin.8
+++ b/docs/man/xrdp-sesadmin.8
@@ -1,4 +1,4 @@
-.TH "xrdp-sesadmin" "8" "0.7.0" "xrdp team"
+.TH "xrdp-sesadmin" "8" "0.9.1" "xrdp team"
.SH NAME
xrdp\-sesadmin \- console XRDP sessions administration tool
diff --git a/docs/man/xrdp-sesman.8 b/docs/man/xrdp-sesman.8
index 9316e926..cca68e3e 100644
--- a/docs/man/xrdp-sesman.8
+++ b/docs/man/xrdp-sesman.8
@@ -1,4 +1,4 @@
-.TH "xrdp\-sesman" "8" "0.1.0" "xrdp team" ""
+.TH "xrdp\-sesman" "8" "0.9.1" "xrdp team" ""
.SH "NAME"
xrdp\-sesman \- \fBxrdp\fR(8) session manager
@@ -8,34 +8,34 @@ xrdp\-sesman \- \fBxrdp\fR(8) session manager
.SH "DESCRIPTION"
\fBxrdp\-sesman\fR is \fBxrdp\fR(8) session manager.
-.br
-It manages user sessions by authenticating the user and starting the appropriate Xserver
+.br
+It manages user sessions by authenticating the user and starting the appropriate Xserver.
.SH "OPTIONS"
-.TP
-\fB\-n\fR, \fB\-\-nodaemon\fR
+.TP
+\fB\-n\fR, \fB\-\-nodaemon\fR
Starts \fBxrdp\-sesman\fR in foreground instead of starting it as a daemon.
-.TP
+.TP
\fB\-k\fR, \fB\-\-kill\fR
Kills running \fBxrdp\-sesman\fR daemon.
-.TP
+.TP
\fB\-h\fR, \fB\-\-help\fR
Output help information and exit.
.SH "FILES"
${SESMAN_BIN_DIR}/sesman
-.br
+.br
${SESMAN_BIN_DIR}/sesrun
-.br
+.br
${SESMAN_CFG_DIR}/sesman.ini
-.br
+.br
${SESMAN_LOG_DIR}/sesman.log
-.br
+.br
${SESMAN_PID_DIR}/sesman.pid
.SH "AUTHORS"
Jay Sorg <jsorg71@users.sourceforge.net>
-.br
+.br
Simone Fedele <ilsimo@users.sourceforge.net>
.SH "SEE ALSO"
@@ -44,4 +44,4 @@ Simone Fedele <ilsimo@users.sourceforge.net>
.BR xrdp (8),
.BR xrdp.ini (5)
-for more info on \fBxrdp\fR see http://xrdp.sf.net
+for more info on \fBxrdp\fR see http://www.xrdp.org/
diff --git a/docs/man/xrdp-sesrun.8 b/docs/man/xrdp-sesrun.8
index c48c7eb5..c66d773c 100644
--- a/docs/man/xrdp-sesrun.8
+++ b/docs/man/xrdp-sesrun.8
@@ -1,4 +1,4 @@
-.TH "xrdp\-sesrun" "8" "0.7.0" "xrdp team" ""
+.TH "xrdp\-sesrun" "8" "0.9.1" "xrdp team" ""
.SH "NAME"
xrdp\-sesrun \- \fBsesman\fR(8) session launcher
@@ -8,37 +8,37 @@ xrdp\-sesrun \- \fBsesman\fR(8) session launcher
.SH "DESCRIPTION"
\fBxrdp\-sesrun\fR starts a session using \fBxrdp\-sesman\fR(8).
-.br
+.br
This is a tool useful for testing, it simply behaves like xrdp when some user logs in a new session and authenticates, thus starting a new session.
.SH "OPTIONS"
-.TP
+.TP
.I server
Server on which sesman is running
-.TP
+.TP
.I username
user name of the session being started
-.TP
+.TP
.I password
user password
-.TP
+.TP
.I width
Screen width
-.TP
+.TP
.I height
Screen height
-.TP
+.TP
.I bpp
Session color depth
.SH "FILES"
${SESMAN_BIN_DIR}/sesman
-.br
+.br
${SESMAN_BIN_DIR}/sesrun
.SH "AUTHORS"
Jay Sorg <jsorg71@users.sourceforge.net>
-.br
+.br
Simone Fedele <ilsimo@users.sourceforge.net>
.SH "SEE ALSO"
@@ -47,4 +47,4 @@ Simone Fedele <ilsimo@users.sourceforge.net>
.BR xrdp (8),
.BR xrdp.ini (5)
-for more info on \fBxrdp\fR see http://xrdp.sf.net
+for more info on \fBxrdp\fR see http://www.xrdp.org/
diff --git a/docs/man/xrdp-sessvc.8 b/docs/man/xrdp-sessvc.8
index 322c968a..9a4e8189 100644
--- a/docs/man/xrdp-sessvc.8
+++ b/docs/man/xrdp-sessvc.8
@@ -1,9 +1,9 @@
-.TH "xrdp\-sessvc" "8" "0.7.0" "xrdp team" ""
+.TH "xrdp\-sessvc" "8" "0.9.1" "xrdp team" ""
.SH "NAME"
xrdp\-sessvc \- \fBxrdp\fR session supervisor
.SH "SYNTAX"
-.B xrdp\-sessman
+.B xrdp\-sessvc
.I x_pid wm_pid
.SH "DESCRIPTION"
@@ -23,4 +23,4 @@ The process ID of the forked Window Manager to monitor.
.SH "SEE ALSO"
.BR xrdp\-sesrun (8).
-for more info on \fBxrdp\fR see http://xrdp.sf.net
+for more info on \fBxrdp\fR see http://www.xrdp.org/
diff --git a/docs/man/xrdp-xcon.8 b/docs/man/xrdp-xcon.8
index 9d83b646..4863bc9e 100644
--- a/docs/man/xrdp-xcon.8
+++ b/docs/man/xrdp-xcon.8
@@ -1,4 +1,4 @@
-.TH "xrdp-xcon" "8" "0.7.0" "xrdp team"
+.TH "xrdp-xcon" "8" "0.9.1" "xrdp team"
.SH NAME
xrdp\-xcon \- X11 event loop debugging helper for XRDP
diff --git a/docs/man/xrdp.8 b/docs/man/xrdp.8
index 6db90076..f838c203 100644
--- a/docs/man/xrdp.8
+++ b/docs/man/xrdp.8
@@ -1,4 +1,4 @@
-.TH "xrdp" "8" "0.1.0" "xrdp team" ""
+.TH "xrdp" "8" "0.9.1" "xrdp team" ""
.SH "NAME"
\fBxrdp\fR \- a Remote Desktop Protocol (RDP) server
@@ -43,4 +43,4 @@ Simone Fedele <ilsimo@users.sourceforge.net>
.BR sesman.ini (5),
.BR sesrun (8)
-for more info on \fBxrdp\fR see http://xrdp.sf.net
+for more info on \fBxrdp\fR see http://www.xrdp.org/
diff --git a/docs/man/xrdp.ini.5 b/docs/man/xrdp.ini.5
index 131c0796..c202b01a 100644
--- a/docs/man/xrdp.ini.5
+++ b/docs/man/xrdp.ini.5
@@ -1,4 +1,4 @@
-.TH "xrdp.ini" "5" "0.7.0" "xrdp team" ""
+.TH "xrdp.ini" "5" "0.9.1" "xrdp team" ""
.SH "NAME"
\fBxrdp.ini\fR \- Configuration file for \fBxrdp\fR(8)
@@ -17,10 +17,7 @@ It is composed by a number of sections, each one composed by a section name, enc
.TP
\fB[Channels]\fP \- channel subsystem parameters
-.TP
-\fI[Connection]\fP \- contain the info on which services \fBxrdp\fR(8) can connect to.
-
-.LP
+.LP
All options and values (except for file names and paths) are case insensitive, and are described in detail below.
.SH "GLOBALS"
@@ -28,65 +25,99 @@ The options to be specified in the \fB[Globals]\fR section are the following:
.TP
\fBaddress\fP=\fIip address\fP
-Specifies xrdp listening address. Default is 0.0.0.0 (all interfaces)
+Specify xrdp listening address. If not specified, defaults to 0.0.0.0 (all interfaces).
.TP
\fBautorun\fP=\fIsession_name\fP
-Automatically run the connection specified by \fIsession_name\fP, which must match a section as described below.
-By default a drop-down list with all available connections is shown.
-A connection can also be chosen by the connecting client by setting the \fBLOGIN DOMAIN\fP to a valid \fIsession name\fP.
+Section name for automatic login. If set and the client supplies valid
+username and password, the user will be logged in automatically using the
+connection specified by \fIsession_name\fP.
+
+If \fIsession_name\fP is empty, the \fBLOGIN DOMAIN\fR from the client
+with be used to select the section. If no domain name is supplied, the
+first suitable section will be used for automatic login.
.TP
-\fBbitmap_cache\fR=\fI[0|1]\fR
+\fBbitmap_cache\fR=\fI[true|false]\fR
If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables bitmap caching in \fBxrdp\fR(8).
.TP
-\fBbitmap_compression\fR=\fI[0|1]\fR
+\fBbitmap_compression\fR=\fI[true|false]\fR
If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables bitmap compression in \fBxrdp\fR(8).
.TP
-\fBbulk_compression\fP=\fI[0|1]\fP
+\fBbulk_compression\fP=\fI[true|false]\fP
If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables compression of bulk data in \fBxrdp\fR(8).
.TP
-\fBchannel_code\fP=\fI[0|1]\fP
+\fBcertificate\fP=\fI/path/to/certificate\fP
+.TP
+\fBkey_file\fP=\fI/path/to/private_key\fP
+Set location of TLS certificate and private key. They must be written in PEM format.
+If not specified, defaults to \fB${XRDP_CFG_DIR}/cert.pem\fP, \fB${XRDP_CFG_DIR}/key.pem\fP.
+
+This parameter is effective only if \fBsecurity_layer\fP is set to \fBtls\fP or \fBnegotiate\fP.
+
+.TP
+\fBchannel_code\fP=\fI[true|false]\fP
If set to \fB0\fR, \fBfalse\fR or \fBno\fR this option disables all channels \fBxrdp\fR(8).
See section \fBCHANNELS\fP below for more fine grained options.
.TP
-\fBcrypt_level\fP=\fIlow|medium|high|fips\fP
+\fBcrypt_level\fP=\fI[low|medium|high|fips]\fP
.\" <http://blogs.msdn.com/b/openspecification/archive/2011/12/08/encryption-negotiation-in-rdp-connection.aspx>
-RDP connection are controlled by two encryption settings: \fIEncryption Level\fP and \fIEncryption Method\fP.
-The only supported \fIEncryption Method\fP is \fB40BIT_ENCRYPTION\fP, \fB128BIT_ENCRYPTION\fP and \fB56BIT_ENCRYPTION\fP are currently not supported.
+Regulate encryption level of Standard RDP Security.
+This parameter is effective only if \fBsecurity_layer\fP is set to \fBrdp\fP or \fBnegotiate\fP.
+
+Encryption in Standard RDP Security is controlled by two settings: \fIEncryption Level\fP
+and \fIEncryption Method\fP. The only supported \fIEncryption Method\fP are \fB40BIT_ENCRYPTION\fP
+and \fB128BIT_ENCRYPTION\fP. \fB56BIT_ENCRYPTION\fP is not supported.
This option controls the \fIEncryption Level\fP:
.RS 8
.TP
.B low
-All data sent from the client to the server is protected by encryption based on the maximum key strength supported by the client.
+All data sent from the client to the server is protected by encryption based on
+the maximum key strength supported by the client.
.I This is the only level that the traffic sent by the server to client is not encrypted.
.TP
.B medium
-All data sent between the client and the server is protected by encryption based on the maximum key strength supported by the client.
+All data sent between the client and the server is protected by encryption based on
+the maximum key strength supported by the client (client compatible).
.TP
.B high
-All data sent between the client and server is protected by encryption based on the server's maximum key strength.
+All data sent between the client and the server is protected by encryption based on
+the server's maximum key strength (sever compatible).
.TP
.B fips
-All data sent between the client and server is protected using Federal Information Processing Standard 140-1 validated encryption methods.
-.I This level is required for Windows clients (mstsc.exe) if the client's group policy enforces FIPS-compliance mode.
+All data sent between the client and server is protected using Federal Information
+Processing Standard 140-1 validated encryption methods.
+.I This level is required for Windows clients (mstsc.exe) if the client's group policy
+.I enforces FIPS-compliance mode.
.RE
.TP
-\fBfork\fP=\fI[0|1]\fP
+\fBdisableSSLv3\fP=\fI[true|false]\fP
+If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP will not accept SSLv3 connections.
+If not specified, defaults to \fBfalse\fP.
+This parameter is effective only if \fBsecurity_layer\fP is set to \fBtls\fP or \fBnegotiate\fP.
+
+.TP
+\fBfork\fP=\fI[true|false]\fP
If set to \fB1\fR, \fBtrue\fR or \fByes\fR for each incoming connection \fBxrdp\fR(8) forks a sub-process instead of using threads.
.TP
-\fBhidelogwindow\fP=\fI[0|1]\fP
+\fBhidelogwindow\fP=\fI[true|false]\fP
If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP will not show a window for log messages.
+If not specified, defaults to \fBfalse\fP.
.TP
-\fBmax_bpp\fP=\fI[8|15|16|24]\fP
+\fBmax_bpp\fP=\fI[8|15|16|24|32]\fP
Limit the color depth by specifying the maximum number of bits per pixel.
+If not specified or set to \fB0\fP, unlimited.
+
+.TP
+\fBpamerrortxt\fP=\fIerror_text\fP
+Specify text passed to PAM when authentication failed. The maximum length is \fB256\fP.
.TP
\fBport\fP=\fIport\fP
@@ -94,16 +125,61 @@ Specify TCP port to listen on for incoming connections.
The default for RDP is \fB3389\fP.
.TP
-\fBtcp_keepalive\fP=\fI[yes|no]\fP
+\fBrequire_credentials\fP=\fI[true|false]\fP
+If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP requires clients to include username and
+password initial connection phase. In other words, xrdp doesn't allow clients to show login
+screen if set to true. If not specified, defaults to \fBfalse\fP.
+
+.TP
+\fBsecurity_layer\fP=\fI[tls|rdp|negotiate]\fP
+Regulate security methods. If not specified, defaults to \fBnegotiate\fP.
+.RS 8
+.TP
+.B tls
+Enhanced RDP Security is used. All security operations (encryption, decryption, data integrity
+verification, and server authentication) are implemented by TLS.
+
+.TP
+.B rdp
+Standard RDP Security, which is not safe from man-in-the-middle attack, is used. The encryption level
+of Standard RDP Security is controlled by \fBcrypt_level\fP.
+
+.TP
+.B negotiate
+Negotiate these security methods with clients.
+.RE
+
+.TP
+\fBtcp_keepalive\fP=\fI[true|false]\fP
Regulate if the listening socket uses socket option \fBSO_KEEPALIVE\fP.
-If set to \fB1\fP, \fBtrue\fP or \fByes\fP and the network connection disappears without closing messages, the connection will be closed.
+If set to \fB1\fP, \fBtrue\fP or \fByes\fP and the network connection disappears
+without closing messages, the connection will be closed.
.TP
-\fBtcp_nodelay\fP=\fI[yes|no]\fP
+\fBtcp_nodelay\fP=\fI[true|false]\fP
Regulate if the listening socket uses socket option \fBTCP_NODELAY\fP.
If set to \fB1\fP, \fBtrue\fP or \fByes\fP, no buffering will be performed in the TCP stack.
.TP
+\fBtcp_send_buffer_bytes\fP=\fIbuffer_size\fP
+.TP
+\fBtcp_recv_buffer_bytes\fP=\fIbuffer_size\fP
+Specify send/recv buffer sizes in bytes. The default value depends on operating system.
+
+.TP
+\fBtls_ciphers\fP=\fIcipher_suite\fP
+Specifies TLS cipher suite. The format of this parameter is equivalent to which
+\fBopenssl\fP(1) ciphers subcommand accepts.
+
+(ex. $ openssl ciphers 'HIGH:!ADH:!SHA1')
+
+This parameter is effective only if \fBsecurity_layer\fP is set to \fBtls\fP or \fBnegotiate\fP.
+
+.TP
+\fBuse_fastpath\fP=\fI[input|output|both|none]\fP
+If not specified, defaults to \fBnone\fP.
+
+.TP
\fBblack\fP=\fI000000\fP
.TP
\fBgrey\fP=\fIc0c0c0\fP
@@ -127,7 +203,7 @@ The lowest value that can be given to one of the light sources is 0 (hex 00).
The highest value is 255 (hex FF).
.SH "LOGGING"
-The following parameters can be used in the \fB[logging]\fR section:
+The following parameters can be used in the \fB[Logging]\fR section:
.TP
\fBLogFile\fR=\fI${SESMAN_LOG_DIR}/sesman.log\fR
@@ -148,7 +224,7 @@ This option can have one of the following values:
\fBDEBUG\fR or \fB4\fR \- Log everything. If \fBsesman\fR is compiled in debug mode, this options will output many more low\-level message, useful for developers
.TP
-\fBEnableSyslog\fR=\fI[0|1]\fR
+\fBEnableSyslog\fR=\fI[true|false]\fR
If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables logging to syslog. Otherwise syslog is disabled.
.TP
@@ -158,70 +234,81 @@ This option sets the logging level for syslog. It can have the same values of \f
.SH "CHANNELS"
The Remote Desktop Protocol supports several channels, which are used to transfer additional data like sound, clipboard data and others.
Channel names not listed here will be blocked by \fBxrdp\fP.
-Not all channels are supported in all cases, so setting a value to \fItrue\fP is a pre-requisite, but does not force it's use.
+Not all channels are supported in all cases, so setting a value to \fItrue\fP is a prerequisite, but does not force its use.
.br
Channels can also be enabled or disabled on a per connection basis by prefixing each setting with \fBchannel.\fP in the channel section.
.TP
-\fBrdpdr\fP=\fI[0|1]\fP
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for device re-direction is allowed.
+\fBrdpdr\fP=\fI[true|false]\fP
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for device redirection is allowed.
.TP
-\fBrdpsnd\fP=\fI[0|1]\fP
+\fBrdpsnd\fP=\fI[true|false]\fP
If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for sound is allowed.
.TP
-\fBdrdynvc\fP=\fI[0|1]\fP
+\fBdrdynvc\fP=\fI[true|false]\fP
If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel to initiate additional dynamic virtual channels is allowed.
.TP
-\fBcliprdr\fP=\fI[0|1]\fP
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for clipboard re-direction is allowed.
+\fBcliprdr\fP=\fI[true|false]\fP
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for clipboard redirection is allowed.
.TP
-\fBrail\fP=\fI[0|1]\fP
+\fBrail\fP=\fI[true|false]\fP
If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for remote applications integrated locally (RAIL) is allowed.
.TP
-\fBxrdpvr\fP=\fI[0|1]\fP
+\fBxrdpvr\fP=\fI[true|false]\fP
If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for XRDP Video streaming is allowed.
.SH "CONNECTIONS"
A connection section is made of a section name, enclosed in square brackets, and the following entries:
-.TP
+.TP
\fBname\fR=\fI<session name>\fR
The name displayed in \fBxrdp\fR(8) login window's combo box.
-.TP
+.TP
\fBlib\fR=\fI../vnc/libvnc.so\fR
Sets the library to be used with this connection.
-.TP
+.TP
\fBusername\fR=\fI<username>\fR|\fIask\fR
Specifies the username used for authenticating in the connection.
If set to \fIask\fR, user name should be provided in the login window.
-.TP
+.TP
\fBpassword\fR=\fI<password>\fR|\fIask\fR
Specifies the password used for authenticating in the connection.
If set to \fIask\fR, password should be provided in the login window.
-.TP
+.TP
\fBip\fR=\fI127.0.0.1\fR
Specifies the ip address of the host to connect to.
-.TP
+.TP
\fBport\fR=\fI<number>\fR|\fI\-1\fR
Specifies the port number to connect to. If set to \fI\-1\fR, the default port for the specified library is used.
+.TP
+\fBxserverbpp\fR=\fI<number>\fR
+Specifies color depth of the backend X server. The default is the color
+depth of the client. Only Xvnc and X11rdp use that setting. Xorg runs at
+\fI24\fR bpp.
+
+.TP
+\fBcode\fR=\fI<number>\fR|\fI0\fR
+Specifies the session type. The default, \fI0\fR, is Xvnc, \fI10\fR is
+X11rdp, and \fI20\fR is Xorg with xorgxrdp modules.
+
.SH "EXAMPLES"
This is an example \fBxrdp.ini\fR:
.nf
[Globals]
-bitmap_cache=yes
-bitmap_compression=yes
+bitmap_cache=true
+bitmap_compression=true
[vnc1]
name=sesman
@@ -241,4 +328,4 @@ ${XRDP_CFG_DIR}/xrdp.ini
.BR sesrun (8),
.BR sesman.ini (5)
-for more info on \fBxrdp\fR see http://xrdp.sf.net
+for more info on \fBxrdp\fR see http://www.xrdp.org/
diff --git a/faq-general.txt b/faq-general.txt
index e63804cb..53dab380 100644
--- a/faq-general.txt
+++ b/faq-general.txt
@@ -2,17 +2,17 @@ General FAQ
Q. What is RDP?
-A. RDP stands for Remote Desktop Protocol. Its the protocol used by Windows
+A. RDP stands for Remote Desktop Protocol. It's the protocol used by Windows
terminal servers to talk to the terminal server clients.
Q. What is xrdp?
-A. xrdp, usually spell lower case, is as open source implementation of the RDP
- protocol.
+A. xrdp, usually spelled in lower case, is as open source implementation of the
+ RDP protocol.
-Q. I can't get it to compile in Ubuntu. What can I do?
+Q. I can't get xrdp to compile in Ubuntu. What can I do?
A. See faq-compile.txt.
diff --git a/file-loc.txt b/file-loc.txt
index 2de02bcf..98894465 100644
--- a/file-loc.txt
+++ b/file-loc.txt
@@ -1,63 +1,80 @@
default build will install the following
-/usr/local/lib/xrdp/
+/usr/local/lib/xrdp
libcommon.so
libmc.so
librdp.so
libscp.so
libvnc.so
libxrdp.so
+ libxrdpapi.so
libxup.so
-/usr/local/bin/
+/usr/local/bin
+ xrdp-dis
xrdp-genkeymap
xrdp-keygen
xrdp-sesadmin
xrdp-sesrun
- xrdp-sestest
-/usr/local/sbin/
+/usr/local/sbin
xrdp
xrdp-sesman
xrdp-sessvc
xrdp-chansrv
-/etc/xrdp/
- km-xxxx.ini
+/etc/xrdp
+ km-xxxxxxxx.ini
sesman.ini
rsakeys.ini
startwm.sh
xrdp.ini
+ xrdp_keyboard.ini
xrdp.sh
-/etc/pam.d/
+/etc/xrdp/pulse
+ default.pa
+
+/etc/pam.d
xrdp-sesman
+/usr/local/share/man/man1
+ xrdp-dis.1
+
/usr/local/share/man/man5
sesman.ini.5
xrdp.ini.5
/usr/local/share/man/man8
- xrdp.8
+ xrdp-chansrv.8
+ xrdp-genkeymap.8
+ xrdp-keygen.8
+ xrdp-sesadmin.8
xrdp-sesman.8
xrdp-sesrun.8
+ xrdp-sessvc.8
+ xrdp.8
/usr/local/share/xrdp
+ ad24b.bmp
ad256.bmp
cursor0.cur
cursor1.cur
sans-10.fv1
+ xrdp24b.bmp
xrdp256.bmp
+ xrdp_logo.bmp
when running, the following are created and written to
-/var/run/
+/var/run
xrdp.pid
sesman.pid
-/var/log/
+/var/log
+ xrdp.log
xrdp-sesman.log
-/tmp
+/tmp/.xrdp
xrdp*
diff --git a/fontdump/.gitignore b/fontdump/.gitignore
new file mode 100644
index 00000000..24600083
--- /dev/null
+++ b/fontdump/.gitignore
@@ -0,0 +1 @@
+!Makefile
diff --git a/fontdump/Makefile b/fontdump/Makefile
index 0a742582..0a742582 100755..100644
--- a/fontdump/Makefile
+++ b/fontdump/Makefile
diff --git a/fontdump/fontdump.c b/fontdump/fontdump.c
index 03609cf0..03609cf0 100755..100644
--- a/fontdump/fontdump.c
+++ b/fontdump/fontdump.c
diff --git a/genkeymap/Makefile.am b/genkeymap/Makefile.am
index aed72512..8c295170 100644
--- a/genkeymap/Makefile.am
+++ b/genkeymap/Makefile.am
@@ -1,9 +1,16 @@
+EXTRA_DIST = \
+ dump-keymaps.sh \
+ readme.txt
+
+AM_CFLAGS = $(X_CFLAGS)
bin_PROGRAMS = \
xrdp-genkeymap
xrdp_genkeymap_SOURCES = genkeymap.c evdev-map.c
+xrdp_genkeymap_LDFLAGS = \
+ $(X_LIBS)
+
xrdp_genkeymap_LDADD = \
- -L/usr/X11R6/lib \
- -lX11
+ $(X_PRE_LIBS) -lX11 $(X_EXTRA_LIBS)
diff --git a/genkeymap/dump-keymaps.sh b/genkeymap/dump-keymaps.sh
index 8a7d1c41..e22610a0 100755
--- a/genkeymap/dump-keymaps.sh
+++ b/genkeymap/dump-keymaps.sh
@@ -7,40 +7,41 @@ then
exit 1
fi
-# English - US 'en-us' 0x0409
+# English - US 'en-us' 0x00000409
setxkbmap -model pc104 -layout us
-./xrdp-genkeymap ../instfiles/km-0409.ini
+./xrdp-genkeymap ../instfiles/km-00000409.ini
-# German 'de' 0x0407
+# English - UK 'en-GB' 0x00000809
+setxkbmap -model pc105 -layout gb
+./xrdp-genkeymap ../instfiles/km-00000809.ini
+
+# German 'de' 0x00000407
setxkbmap -model pc104 -layout de
-./xrdp-genkeymap ../instfiles/km-0407.ini
+./xrdp-genkeymap ../instfiles/km-00000407.ini
-# Italy 'it' 0x0410
+# Italian 'it' 0x00000410
setxkbmap -model pc104 -layout it
-./xrdp-genkeymap ../instfiles/km-0410.ini
+./xrdp-genkeymap ../instfiles/km-00000410.ini
-# Japanese 'jp' 0x0411
-setxkbmap -model jp106 -layout jp -variant OADG109A
-./xrdp-genkeymap ../instfiles/km-0411.ini
-./xrdp-genkeymap ../instfiles/km-e0010411.ini
-./xrdp-genkeymap ../instfiles/km-e0200411.ini
-./xrdp-genkeymap ../instfiles/km-e0210411.ini
+# Japanese 'jp' 0x00000411
+setxkbmap -model pc105 -layout jp -variant OADG109A
+./xrdp-genkeymap ../instfiles/km-00000411.ini
-# Polish 'pl' 0x0415
+# Polish 'pl' 0x00000415
setxkbmap -model pc104 -layout pl
-./xrdp-genkeymap ../instfiles/km-0415.ini
+./xrdp-genkeymap ../instfiles/km-00000415.ini
-# Russia 'ru' 0x0419
+# Russia 'ru' 0x00000419
setxkbmap -model pc104 -layout ru
-./xrdp-genkeymap ../instfiles/km-0419.ini
+./xrdp-genkeymap ../instfiles/km-00000419.ini
-# Sweden 'se' 0x041d
+# Sweden 'se' 0x0000041d
setxkbmap -model pc104 -layout se
-./xrdp-genkeymap ../instfiles/km-041d.ini
+./xrdp-genkeymap ../instfiles/km-0000041d.ini
-# Portuguese -PT 'pt-pt' 0x0816
+# Portuguese -PT 'pt-pt' 0x00000816
setxkbmap -model pc104 -layout pt
-./xrdp-genkeymap ../instfiles/km-0816.ini
+./xrdp-genkeymap ../instfiles/km-00000816.ini
# set back to en-us
setxkbmap -model pc104 -layout us
diff --git a/genkeymap/genkeymap.c b/genkeymap/genkeymap.c
index 088af748..1d640b1f 100644
--- a/genkeymap/genkeymap.c
+++ b/genkeymap/genkeymap.c
@@ -21,15 +21,15 @@
Updated Jay Sorg 2009
- cs czech 0x405
- de german 0x407
- en-us us english 0x409
- fr french 0x40c
- it italy 0x410
+ cs Czech 0x405
+ de German 0x407
+ en-us US English 0x409
+ fr French 0x40c
+ it Italian 0x410
br Portuguese (Brazil) 0x416
- ru russian 0x419
- se swedish 0x41d
- en-uk uk english 0x809
+ ru Russian 0x419
+ se Swedish 0x41d
+ en-uk UK English 0x809
*/
#include <stdio.h>
@@ -48,7 +48,10 @@ int main(int argc, char **argv)
char text[256];
char *displayname = NULL;
char *outfname;
- char *sections[8] = {"noshift", "shift", "altgr", "shiftaltgr", "capslock", "capslockaltgr", "shiftcapslock", "shiftcapslockaltgr"};
+ const char *sections[8] = {
+ "noshift", "shift", "altgr", "shiftaltgr",
+ "capslock", "capslockaltgr", "shiftcapslock", "shiftcapslockaltgr"
+ };
int states[8] = {0, 1, 0x80, 0x81, 2, 0x82, 3, 0x83};
int i;
int idx;
@@ -70,7 +73,7 @@ int main(int argc, char **argv)
if (argc != 2)
{
fprintf(stderr, "Usage: %s out_filename\n", programname);
- fprintf(stderr, "Example: %s /etc/xrdp/km-0409.ini\n", programname);
+ fprintf(stderr, "Example: %s /etc/xrdp/km-00000409.ini\n", programname);
return 1;
}
diff --git a/genkeymap/readme.txt b/genkeymap/readme.txt
index b2b3b890..242fe92e 100644
--- a/genkeymap/readme.txt
+++ b/genkeymap/readme.txt
@@ -3,9 +3,9 @@ Creating a new keymap file.
The names of the files are of the format;
-km-xxxx.ini
+km-xxxxxxxx.ini
-where the xxxx is replaced by the hex number of the layout of interest.
+where the xxxxxxxx is replaced by the hex number of the layout of interest.
The files have 8 sections;
@@ -33,7 +33,7 @@ Key63=65450:42
To create a new file run "xrdp-genkeymap <filename>"
-Example: ./xrdp-genkeymap /etc/xrdp/km-0409.ini
+Example: ./xrdp-genkeymap /etc/xrdp/km-00000409.ini
Note: You need to have enough rights to be able to write to the
/etc/xrdp directory.
diff --git a/install.txt b/install.txt
index 5683d1e5..dd36f4e3 100644
--- a/install.txt
+++ b/install.txt
@@ -11,11 +11,11 @@ You can build sesman without pam, there is a Makefile parameter
for that.
I also have a replacement ssl_calls.c to avoid the openssl dependency
email me(Jay) for it or see http://server1.xrdp.org/xrdp/openssl.
-Due to the licence, I can't include it in this project.
+Due to the license, I can't include it in this project.
http://server1.xrdp.org/xrdp/openssl/
-unpackage the tarball
+unpack the tarball
tar -zxvf xrdp-0.1.tar.gz
@@ -28,7 +28,7 @@ run make
as root, run make install
This will install most of the files in /usr/local/xrdp.
-Some files install in /etc/xrdp. These are configuation
+Some files install in /etc/xrdp. These are configuration
files.
files and location
diff --git a/instfiles/Makefile.am b/instfiles/Makefile.am
index 85b5ffaa..92cc9cf2 100644
--- a/instfiles/Makefile.am
+++ b/instfiles/Makefile.am
@@ -1,38 +1,75 @@
-EXTRA_DIST = xrdp.sh km-0407.ini km-0409.ini km-040c.ini km-0410.ini km-0419.ini km-041d.ini km-0816.ini \
-xrdp-sesman.service \
-xrdp.service
+EXTRA_DIST = \
+ keymap-names.txt \
+ xrdp.sh \
+ xrdp-sesman.service \
+ xrdp.service
-SUBDIRS = \
+#
+# files for all platforms
+#
+startscriptdir=$(sysconfdir)/xrdp
+
+dist_startscript_DATA = \
+ km-00000407.ini \
+ km-00000409.ini \
+ km-0000040a.ini \
+ km-0000040b.ini \
+ km-0000040c.ini \
+ km-00000410.ini \
+ km-00000411.ini \
+ km-00000412.ini \
+ km-00000414.ini \
+ km-00000415.ini \
+ km-00000416.ini \
+ km-00000419.ini \
+ km-0000041d.ini \
+ km-00000807.ini \
+ km-00000809.ini \
+ km-0000080c.ini \
+ km-00000813.ini \
+ km-00000816.ini \
+ km-0000100c.ini
+
+#
+# platform specific files
+#
+SUBDIRS =
+if LINUX
+SUBDIRS += \
pam.d \
- init.d \
- default \
pulse
-
+dist_startscript_SCRIPTS = xrdp.sh
if HAVE_SYSTEMD
-systemdsystemunit_DATA = \
- xrdp-sesman.service \
- xrdp.service
-endif
+dist_systemdsystemunit_DATA = \
+ xrdp-sesman.service \
+ xrdp.service
+else
+SUBDIRS += \
+ default \
+ init.d
+endif # HAVE_SYSTEMD
+endif # LINUX
-startscriptdir=$(sysconfdir)/xrdp
+if FREEBSD
+SUBDIRS += \
+ pam.d \
+ rc.d \
+ pulse
+endif
-startscript_DATA = \
- xrdp.sh \
- km-0407.ini \
- km-0409.ini \
- km-040c.ini \
- km-0410.ini \
- km-0411.ini \
- km-0415.ini \
- km-0419.ini \
- km-041d.ini \
- km-0816.ini \
- km-e0010411.ini \
- km-e0200411.ini \
- km-e0210411.ini
+#
+# install-data-hook for each platform
+#
+if LINUX
+# must be tab below
+install-data-hook:
+ if [ -f $(DESTDIR)$(sysconfdir)/init.d/xrdp ]; then \
+ sed -i 's|__BASE__|$(prefix)|' $(DESTDIR)$(sysconfdir)/init.d/xrdp; \
+ fi
+endif
+if FREEBSD
# must be tab below
install-data-hook:
- chmod 755 $(DESTDIR)$(sysconfdir)/xrdp/xrdp.sh
- chmod 755 $(DESTDIR)$(sysconfdir)/init.d/xrdp
- sed -i 's|__BASE__|$(prefix)|' $(DESTDIR)$(sysconfdir)/init.d/xrdp;
+ sed -i '' 's|%%PREFIX%%|$(prefix)|g' $(DESTDIR)$(sysconfdir)/rc.d/xrdp
+endif
diff --git a/instfiles/default/Makefile.am b/instfiles/default/Makefile.am
index 6a7f4f2b..f379a46d 100644
--- a/instfiles/default/Makefile.am
+++ b/instfiles/default/Makefile.am
@@ -1,3 +1,2 @@
-EXTRA_DIST = xrdp
-startscriptdir=$(sysconfdir)/default
-startscript_DATA = xrdp
+startscriptdir = $(sysconfdir)/default
+dist_startscript_DATA = xrdp
diff --git a/instfiles/init.d/Makefile.am b/instfiles/init.d/Makefile.am
index ae411c20..2ffff4fe 100644
--- a/instfiles/init.d/Makefile.am
+++ b/instfiles/init.d/Makefile.am
@@ -1,4 +1,2 @@
-EXTRA_DIST = xrdp
-startscriptdir=$(sysconfdir)/init.d
-startscript_DATA = xrdp
-
+startscriptdir = $(sysconfdir)/init.d
+dist_startscript_SCRIPTS = xrdp
diff --git a/instfiles/init.d/xrdp b/instfiles/init.d/xrdp
index dcdb01a4..f64e5965 100644
--- a/instfiles/init.d/xrdp
+++ b/instfiles/init.d/xrdp
@@ -18,12 +18,11 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
BASE=__BASE__
DAEMON=${BASE}/sbin/xrdp
SDAEMON=${BASE}/sbin/xrdp-sesman
-PIDDIR=/var/run/xrdp/
+PIDDIR=/var/run/
SESMAN_START=yes
#USERID=xrdp
# the X11rdp backend only works as root at the moment - GH 20/03/2013
USERID=root
-RSAKEYS=/etc/xrdp/rsakeys.ini
NAME=xrdp
DESC="Remote Desktop Protocol server"
@@ -67,18 +66,6 @@ if [ "$(id -u)" = "0" ]; then
mkdir $PIDDIR
fi
chown $USERID:$USERID $PIDDIR
-
- # Check for rsa key
- if [ ! -f $RSAKEYS ] ; then
- log_action_begin_msg "Generating xrdp RSA keys..."
- (umask 077 ; xrdp-keygen xrdp $RSAKEYS)
- chown $USERID:$USERID $RSAKEYS
- if [ ! -f $RSAKEYS ] ; then
- log_action_end_msg 1 "could not create $RSAKEYS"
- exit 1
- fi
- log_action_end_msg 0 "done"
- fi
fi
@@ -139,7 +126,7 @@ case "$1" in
;;
force-stop)
$0 stop
- # because it doesn't allways die the right way
+ # because it doesn't always die the right way
force_stop
;;
restart|force-reload)
diff --git a/instfiles/keymap-names.txt b/instfiles/keymap-names.txt
new file mode 100644
index 00000000..2d9676dd
--- /dev/null
+++ b/instfiles/keymap-names.txt
@@ -0,0 +1,124 @@
+
+0x00000436 af Afrikaans
+0x0000041C sq Albanian
+0x00000001 ar Arabic
+0x00000401 ar-sa Arabic (Saudi Arabia)
+0x00000801 ar-iq Arabic (Iraq)
+0x00000C01 ar-eg Arabic (Egypt)
+0x00001001 ar-ly Arabic (Libya)
+0x00001401 ar-dz Arabic (Algeria)
+0x00001801 ar-ma Arabic (Morocco)
+0x00001C01 ar-tn Arabic (Tunisia)
+0x00002001 ar-om Arabic (Oman)
+0x00002401 ar-ye Arabic (Yemen)
+0x00002801 ar-sy Arabic (Syria)
+0x00002C01 ar-jo Arabic (Jordan)
+0x00003001 ar-lb Arabic (Lebanon)
+0x00003401 ar-kw Arabic (Kuwait)
+0x00003801 ar-ae Arabic (U.A.E.)
+0x00003C01 ar-bh Arabic (Bahrain)
+0x00004001 ar-qa Arabic (Qatar)
+0x0000042D eu Basque
+0x00000402 bg Bulgarian
+0x00000423 be Belarusian
+0x00000403 ca Catalan
+0x00000004 zh Chinese
+0x00000404 zh-tw Chinese (Taiwan)
+0x00000804 zh-cn Chinese (China)
+0x00000C04 zh-hk Chinese (Hong Kong SAR)
+0x00001004 zh-sg Chinese (Singapore)
+0x0000041A hr Croatian
+0x00000405 cs Czech
+0x00000406 da Danish
+0x00000413 nl Dutch (Netherlands)
+0x00000813 nl-be Dutch (Belgium)
+0x00000009 en English
+0x00000409 en-us English (United States)
+0x00000809 en-gb English (United Kingdom)
+0x00000C09 en-au English (Australia)
+0x00001009 en-ca English (Canada)
+0x00001409 en-nz English (New Zealand)
+0x00001809 en-ie English (Ireland)
+0x00001C09 en-za English (South Africa)
+0x00002009 en-jm English (Jamaica)
+0x00002809 en-bz English (Belize)
+0x00002C09 en-tt English (Trinidad)
+0x00000425 et Estonian
+0x00000438 fo Faeroese
+0x00000429 fa Farsi
+0x0000040B fi Finnish
+0x0000040C fr French (France)
+0x0000080C fr-be French (Belgium)
+0x00000C0C fr-ca French (Canada)
+0x0000100C fr-ch French (Switzerland)
+0x0000140C fr-lu French (Luxembourg)
+0x0000043C gd Gaelic
+0x00000407 de German (Germany)
+0x00000807 de-ch German (Switzerland)
+0x00000C07 de-at German (Austria)
+0x00001007 de-lu German (Luxembourg)
+0x00001407 de-li German (Liechtenstein)
+0x00000408 el Greek
+0x0000040D he Hebrew
+0x00000439 hi Hindi
+0x0000040E hu Hungarian
+0x0000040F is Icelandic
+0x00000421 in Indonesian
+0x00000410 it Italian (Italy)
+0x00000810 it-ch Italian (Switzerland)
+0x00000411 ja Japanese
+0x00000412 ko Korean
+0x00000426 lv Latvian
+0x00000427 lt Lithuanian
+0x0000042F mk FYRO Macedonian
+0x0000043E ms Malay (Malaysia)
+0x0000043A mt Maltese
+0x00000414 no Norwegian (Bokmal)
+0x00000814 no Norwegian (Nynorsk)
+0x00000415 pl Polish
+0x00000416 pt-br Portuguese (Brazil)
+0x00000816 pt Portuguese (Portugal)
+0x00000417 rm Rhaeto-Romanic
+0x00000418 ro Romanian
+0x00000818 ro-mo Romanian (Moldova)
+0x00000419 ru Russian
+0x00000819 ru-mo Russian (Moldova)
+0x00000C1A sr Serbian (Cyrillic)
+0x0000081A sr Serbian (Latin)
+0x0000041B sk Slovak
+0x00000424 sl Slovenian
+0x0000042E sb Sorbian
+0x0000040A es Spanish (Traditional Sort)
+0x0000080A es-mx Spanish (Mexico)
+0x00000C0A es Spanish (International Sort)
+0x0000100A es-gt Spanish (Guatemala)
+0x0000140A es-cr Spanish (Costa Rica)
+0x0000180A es-pa Spanish (Panama)
+0x00001C0A es-do Spanish (Dominican Republic)
+0x0000200A es-ve Spanish (Venezuela)
+0x0000240A es-co Spanish (Colombia)
+0x0000280A es-pe Spanish (Peru)
+0x00002C0A es-ar Spanish (Argentina)
+0x0000300A es-ec Spanish (Ecuador)
+0x0000340A es-cl Spanish (Chile)
+0x0000380A es-uy Spanish (Uruguay)
+0x00003C0A es-py Spanish (Paraguay)
+0x0000400A es-bo Spanish (Bolivia)
+0x0000440A es-sv Spanish (El Salvador)
+0x0000480A es-hn Spanish (Honduras)
+0x00004C0A es-ni Spanish (Nicaragua)
+0x0000500A es-pr Spanish (Puerto Rico)
+0x00000430 sx Sutu
+0x0000041D sv Swedish
+0x0000081D sv-fi Swedish (Finland)
+0x0000041E th Thai
+0x00000431 ts Tsonga
+0x00000432 tn Tswana
+0x0000041F tr Turkish
+0x00000422 uk Ukrainian
+0x00000420 ur Urdu
+0x0000042A vi Vietnamese
+0x00000434 xh Xhosa
+0x0000043D ji Yiddish
+0x00000435 zu Zulu
+
diff --git a/instfiles/km-0407.ini b/instfiles/km-00000407.ini
index 6021211d..6021211d 100644
--- a/instfiles/km-0407.ini
+++ b/instfiles/km-00000407.ini
diff --git a/instfiles/km-0409.ini b/instfiles/km-00000409.ini
index a565a9b0..a565a9b0 100644
--- a/instfiles/km-0409.ini
+++ b/instfiles/km-00000409.ini
diff --git a/instfiles/km-0000040a.ini b/instfiles/km-0000040a.ini
new file mode 100644
index 00000000..5a961845
--- /dev/null
+++ b/instfiles/km-0000040a.ini
@@ -0,0 +1,659 @@
+[noshift]
+Key8=0:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=39:39
+Key21=161:161
+Key22=65288:8
+Key23=65289:9
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=121:121
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=65104:96
+Key35=43:43
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=241:241
+Key48=65105:180
+Key49=186:186
+Key50=65505:0
+Key51=231:231
+Key52=122:122
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=44:44
+Key60=46:46
+Key61=45:45
+Key62=65506:0
+Key63=65450:42
+Key64=65364:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=0:0
+Key94=60:60
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65514:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shift]
+Key8=0:0
+Key9=65307:27
+Key10=33:33
+Key11=34:34
+Key12=183:183
+Key13=36:36
+Key14=37:37
+Key15=38:38
+Key16=47:47
+Key17=40:40
+Key18=41:41
+Key19=61:61
+Key20=63:63
+Key21=191:191
+Key22=65288:8
+Key23=65056:0
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=89:89
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=65106:94
+Key35=42:42
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=209:209
+Key48=65111:168
+Key49=170:170
+Key50=65505:0
+Key51=199:199
+Key52=90:90
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=59:59
+Key60=58:58
+Key61=95:95
+Key62=65506:0
+Key63=65450:42
+Key64=65364:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65273:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65454:46
+Key92=0:0
+Key93=0:0
+Key94=62:62
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65512:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[altgr]
+Key8=0:0
+Key9=65307:27
+Key10=124:124
+Key11=64:64
+Key12=35:35
+Key13=126:126
+Key14=189:189
+Key15=172:172
+Key16=123:123
+Key17=91:91
+Key18=93:93
+Key19=125:125
+Key20=92:92
+Key21=126:126
+Key22=65288:8
+Key23=65289:9
+Key24=64:64
+Key25=435:322
+Key26=8364:8364
+Key27=182:182
+Key28=956:359
+Key29=2299:8592
+Key30=2302:8595
+Key31=2301:8594
+Key32=248:248
+Key33=254:254
+Key34=91:91
+Key35=93:93
+Key36=65293:13
+Key37=65507:0
+Key38=230:230
+Key39=223:223
+Key40=240:240
+Key41=496:273
+Key42=959:331
+Key43=689:295
+Key44=106:106
+Key45=930:312
+Key46=435:322
+Key47=126:126
+Key48=123:123
+Key49=92:92
+Key50=65505:0
+Key51=125:125
+Key52=171:171
+Key53=187:187
+Key54=162:162
+Key55=2770:8220
+Key56=2771:8221
+Key57=110:110
+Key58=181:181
+Key59=2211:0
+Key60=183:183
+Key61=65120:0
+Key62=65506:0
+Key63=65450:42
+Key64=65364:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=0:0
+Key94=124:124
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=0:0
+Key112=65455:47
+Key113=65514:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[capslock]
+Key8=0:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=39:39
+Key21=161:161
+Key22=65288:8
+Key23=65289:9
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=89:89
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=65104:96
+Key35=43:43
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=209:209
+Key48=65105:180
+Key49=186:186
+Key50=65505:0
+Key51=199:199
+Key52=90:90
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=44:44
+Key60=46:46
+Key61=45:45
+Key62=65506:0
+Key63=65450:42
+Key64=65364:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=0:0
+Key94=60:60
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65514:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shiftcapslock]
+Key8=0:0
+Key9=65307:27
+Key10=33:33
+Key11=34:34
+Key12=183:183
+Key13=36:36
+Key14=37:37
+Key15=38:38
+Key16=47:47
+Key17=40:40
+Key18=41:41
+Key19=61:61
+Key20=63:63
+Key21=191:191
+Key22=65288:8
+Key23=65056:0
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=121:121
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=65106:94
+Key35=42:42
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=241:241
+Key48=65111:168
+Key49=170:170
+Key50=65505:0
+Key51=231:231
+Key52=122:122
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=59:59
+Key60=58:58
+Key61=95:95
+Key62=65506:0
+Key63=65450:42
+Key64=65364:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65273:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65454:46
+Key92=0:0
+Key93=0:0
+Key94=62:62
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65512:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
diff --git a/instfiles/km-041d.ini b/instfiles/km-0000040b.ini
index 3cf432b2..3cf432b2 100644
--- a/instfiles/km-041d.ini
+++ b/instfiles/km-0000040b.ini
diff --git a/instfiles/km-040c.ini b/instfiles/km-0000040c.ini
index 6895c4a2..6895c4a2 100644
--- a/instfiles/km-040c.ini
+++ b/instfiles/km-0000040c.ini
diff --git a/instfiles/km-0410.ini b/instfiles/km-00000410.ini
index a9723117..a9723117 100644
--- a/instfiles/km-0410.ini
+++ b/instfiles/km-00000410.ini
diff --git a/instfiles/km-0411.ini b/instfiles/km-00000411.ini
index 50ba669f..e860e6fd 100644
--- a/instfiles/km-0411.ini
+++ b/instfiles/km-00000411.ini
@@ -120,9 +120,9 @@ Key125=0:0
Key126=65469:61
Key127=0:0
Key128=0:0
-Key129=0:0
+Key129=65315:0
Key130=0:0
-Key131=0:0
+Key131=65314:0
Key132=0:0
Key133=165:165
Key134=0:0
@@ -252,9 +252,9 @@ Key125=65513:0
Key126=65469:61
Key127=65515:0
Key128=65517:0
-Key129=0:0
+Key129=65315:0
Key130=0:0
-Key131=0:0
+Key131=65314:0
Key132=0:0
Key133=124:124
Key134=0:0
@@ -384,9 +384,9 @@ Key125=0:0
Key126=65469:61
Key127=0:0
Key128=0:0
-Key129=0:0
+Key129=65315:0
Key130=0:0
-Key131=0:0
+Key131=65314:0
Key132=0:0
Key133=165:165
Key134=0:0
@@ -516,9 +516,9 @@ Key125=65513:0
Key126=65469:61
Key127=65515:0
Key128=65517:0
-Key129=0:0
+Key129=65315:0
Key130=0:0
-Key131=0:0
+Key131=65314:0
Key132=0:0
Key133=124:124
Key134=0:0
@@ -648,9 +648,9 @@ Key125=0:0
Key126=65469:61
Key127=0:0
Key128=0:0
-Key129=0:0
+Key129=65315:0
Key130=0:0
-Key131=0:0
+Key131=65314:0
Key132=0:0
Key133=165:165
Key134=0:0
@@ -780,9 +780,9 @@ Key125=0:0
Key126=65469:61
Key127=0:0
Key128=0:0
-Key129=0:0
+Key129=65315:0
Key130=0:0
-Key131=0:0
+Key131=65314:0
Key132=0:0
Key133=165:165
Key134=0:0
@@ -912,9 +912,9 @@ Key125=65513:0
Key126=65469:61
Key127=65515:0
Key128=65517:0
-Key129=0:0
+Key129=65315:0
Key130=0:0
-Key131=0:0
+Key131=65314:0
Key132=0:0
Key133=124:124
Key134=0:0
@@ -1044,9 +1044,9 @@ Key125=65513:0
Key126=65469:61
Key127=65515:0
Key128=65517:0
-Key129=0:0
+Key129=65315:0
Key130=0:0
-Key131=0:0
+Key131=65314:0
Key132=0:0
Key133=124:124
Key134=0:0
diff --git a/instfiles/km-e0010411.ini b/instfiles/km-00000412.ini
index 50ba669f..e8cb305e 100644
--- a/instfiles/km-e0010411.ini
+++ b/instfiles/km-00000412.ini
@@ -1,1055 +1,1057 @@
-[noshift]
-Key8=65406:0
-Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
-Key22=65288:8
-Key23=65289:9
-Key24=113:113
-Key25=119:119
-Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=64:64
-Key35=91:91
-Key36=65293:13
-Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=59:59
-Key48=58:58
-Key49=65322:0
-Key50=65505:0
-Key51=93:93
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
-Key57=110:110
-Key58=109:109
-Key59=44:44
-Key60=46:46
-Key61=47:47
-Key62=65506:0
-Key63=65450:42
-Key64=65513:0
-Key65=32:32
-Key66=65328:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65429:0
-Key80=65431:0
-Key81=65434:0
-Key82=65453:45
-Key83=65430:0
-Key84=65437:0
-Key85=65432:0
-Key86=65451:43
-Key87=65436:0
-Key88=65433:0
-Key89=65435:0
-Key90=65438:0
-Key91=65439:0
-Key92=65377:0
-Key93=0:0
-Key94=60:60
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65514:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=92:92
-Key124=65027:0
-Key125=0:0
-Key126=65469:61
-Key127=0:0
-Key128=0:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=165:165
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[shift]
-Key8=65406:0
-Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
-Key22=65288:8
-Key23=65056:0
-Key24=81:81
-Key25=87:87
-Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=96:96
-Key35=123:123
-Key36=65293:13
-Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=43:43
-Key48=42:42
-Key49=65322:0
-Key50=65505:0
-Key51=125:125
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
-Key57=78:78
-Key58=77:77
-Key59=60:60
-Key60=62:62
-Key61=63:63
-Key62=65506:0
-Key63=65450:42
-Key64=65511:0
-Key65=32:32
-Key66=65509:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65463:55
-Key80=65464:56
-Key81=65465:57
-Key82=65453:45
-Key83=65460:52
-Key84=65461:53
-Key85=65462:54
-Key86=65451:43
-Key87=65457:49
-Key88=65458:50
-Key89=65459:51
-Key90=65456:48
-Key91=65454:46
-Key92=65377:0
-Key93=0:0
-Key94=62:62
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65512:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=95:95
-Key124=65027:0
-Key125=65513:0
-Key126=65469:61
-Key127=65515:0
-Key128=65517:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=124:124
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[altgr]
-Key8=65406:0
-Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
-Key22=65288:8
-Key23=65289:9
-Key24=113:113
-Key25=119:119
-Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=64:64
-Key35=91:91
-Key36=65293:13
-Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=59:59
-Key48=58:58
-Key49=65322:0
-Key50=65505:0
-Key51=93:93
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
-Key57=110:110
-Key58=109:109
-Key59=44:44
-Key60=46:46
-Key61=47:47
-Key62=65506:0
-Key63=65450:42
-Key64=65513:0
-Key65=32:32
-Key66=65328:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65429:0
-Key80=65431:0
-Key81=65434:0
-Key82=65453:45
-Key83=65430:0
-Key84=65437:0
-Key85=65432:0
-Key86=65451:43
-Key87=65436:0
-Key88=65433:0
-Key89=65435:0
-Key90=65438:0
-Key91=65439:0
-Key92=65377:0
-Key93=0:0
-Key94=124:124
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65514:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=0:0
-Key126=65469:61
-Key127=0:0
-Key128=0:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=165:165
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[shiftaltgr]
-Key8=65406:0
-Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
-Key22=65288:8
-Key23=65056:0
-Key24=81:81
-Key25=87:87
-Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=96:96
-Key35=123:123
-Key36=65293:13
-Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=43:43
-Key48=42:42
-Key49=65322:0
-Key50=65505:0
-Key51=125:125
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
-Key57=78:78
-Key58=77:77
-Key59=60:60
-Key60=62:62
-Key61=63:63
-Key62=65506:0
-Key63=65450:42
-Key64=65511:0
-Key65=32:32
-Key66=65509:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65463:55
-Key80=65464:56
-Key81=65465:57
-Key82=65453:45
-Key83=65460:52
-Key84=65461:53
-Key85=65462:54
-Key86=65451:43
-Key87=65457:49
-Key88=65458:50
-Key89=65459:51
-Key90=65456:48
-Key91=65454:46
-Key92=65377:0
-Key93=0:0
-Key94=166:166
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65512:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=65513:0
-Key126=65469:61
-Key127=65515:0
-Key128=65517:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=124:124
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[capslock]
-Key8=65406:0
-Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
-Key22=65288:8
-Key23=65289:9
-Key24=81:81
-Key25=87:87
-Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=64:64
-Key35=91:91
-Key36=65293:13
-Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=59:59
-Key48=58:58
-Key49=65322:0
-Key50=65505:0
-Key51=93:93
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
-Key57=78:78
-Key58=77:77
-Key59=44:44
-Key60=46:46
-Key61=47:47
-Key62=65506:0
-Key63=65450:42
-Key64=65513:0
-Key65=32:32
-Key66=65328:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65429:0
-Key80=65431:0
-Key81=65434:0
-Key82=65453:45
-Key83=65430:0
-Key84=65437:0
-Key85=65432:0
-Key86=65451:43
-Key87=65436:0
-Key88=65433:0
-Key89=65435:0
-Key90=65438:0
-Key91=65439:0
-Key92=65377:0
-Key93=0:0
-Key94=60:60
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65514:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=0:0
-Key126=65469:61
-Key127=0:0
-Key128=0:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=165:165
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[capslockaltgr]
-Key8=65406:0
-Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
-Key22=65288:8
-Key23=65289:9
-Key24=81:81
-Key25=87:87
-Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=64:64
-Key35=91:91
-Key36=65293:13
-Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=59:59
-Key48=58:58
-Key49=65322:0
-Key50=65505:0
-Key51=93:93
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
-Key57=78:78
-Key58=77:77
-Key59=44:44
-Key60=46:46
-Key61=47:47
-Key62=65506:0
-Key63=65450:42
-Key64=65513:0
-Key65=32:32
-Key66=65328:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65429:0
-Key80=65431:0
-Key81=65434:0
-Key82=65453:45
-Key83=65430:0
-Key84=65437:0
-Key85=65432:0
-Key86=65451:43
-Key87=65436:0
-Key88=65433:0
-Key89=65435:0
-Key90=65438:0
-Key91=65439:0
-Key92=65377:0
-Key93=0:0
-Key94=124:124
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65514:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=0:0
-Key126=65469:61
-Key127=0:0
-Key128=0:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=165:165
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[shiftcapslock]
-Key8=65406:0
-Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
-Key22=65288:8
-Key23=65056:0
-Key24=113:113
-Key25=119:119
-Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=96:96
-Key35=123:123
-Key36=65293:13
-Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=43:43
-Key48=42:42
-Key49=65322:0
-Key50=65505:0
-Key51=125:125
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
-Key57=110:110
-Key58=109:109
-Key59=60:60
-Key60=62:62
-Key61=63:63
-Key62=65506:0
-Key63=65450:42
-Key64=65511:0
-Key65=32:32
-Key66=65509:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65463:55
-Key80=65464:56
-Key81=65465:57
-Key82=65453:45
-Key83=65460:52
-Key84=65461:53
-Key85=65462:54
-Key86=65451:43
-Key87=65457:49
-Key88=65458:50
-Key89=65459:51
-Key90=65456:48
-Key91=65454:46
-Key92=65377:0
-Key93=0:0
-Key94=62:62
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65512:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=65513:0
-Key126=65469:61
-Key127=65515:0
-Key128=65517:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=124:124
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[shiftcapslockaltgr]
-Key8=65406:0
-Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
-Key22=65288:8
-Key23=65056:0
-Key24=113:113
-Key25=119:119
-Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=96:96
-Key35=123:123
-Key36=65293:13
-Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=43:43
-Key48=42:42
-Key49=65322:0
-Key50=65505:0
-Key51=125:125
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
-Key57=110:110
-Key58=109:109
-Key59=60:60
-Key60=62:62
-Key61=63:63
-Key62=65506:0
-Key63=65450:42
-Key64=65511:0
-Key65=32:32
-Key66=65509:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65463:55
-Key80=65464:56
-Key81=65465:57
-Key82=65453:45
-Key83=65460:52
-Key84=65461:53
-Key85=65462:54
-Key86=65451:43
-Key87=65457:49
-Key88=65458:50
-Key89=65459:51
-Key90=65456:48
-Key91=65454:46
-Key92=65377:0
-Key93=0:0
-Key94=166:166
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65512:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=65513:0
-Key126=65469:61
-Key127=65515:0
-Key128=65517:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=124:124
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
+[noshift]
+Key8=65406:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=45:45
+Key21=61:61
+Key22=65288:8
+Key23=65289:9
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=121:121
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=91:91
+Key35=93:93
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=59:59
+Key48=39:39
+Key49=96:96
+Key50=65505:0
+Key51=92:92
+Key52=122:122
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=44:44
+Key60=46:46
+Key61=47:47
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=0:0
+Key94=60:60
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65514:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=65454:46
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shift]
+Key8=65406:0
+Key9=65307:27
+Key10=33:33
+Key11=64:64
+Key12=35:35
+Key13=36:36
+Key14=37:37
+Key15=94:94
+Key16=38:38
+Key17=42:42
+Key18=40:40
+Key19=41:41
+Key20=95:95
+Key21=43:43
+Key22=65288:8
+Key23=65056:0
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=89:89
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=123:123
+Key35=125:125
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=58:58
+Key48=34:34
+Key49=126:126
+Key50=65505:0
+Key51=124:124
+Key52=90:90
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=60:60
+Key60=62:62
+Key61=63:63
+Key62=65506:0
+Key63=65450:42
+Key64=65511:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65454:46
+Key92=0:0
+Key93=0:0
+Key94=62:62
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65512:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=65454:46
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[altgr]
+Key8=65406:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=45:45
+Key21=61:61
+Key22=65288:8
+Key23=65289:9
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=121:121
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=91:91
+Key35=93:93
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=59:59
+Key48=39:39
+Key49=96:96
+Key50=65505:0
+Key51=92:92
+Key52=122:122
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=44:44
+Key60=46:46
+Key61=47:47
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=0:0
+Key94=124:124
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65514:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=65454:46
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shiftaltgr]
+Key8=65406:0
+Key9=65307:27
+Key10=33:33
+Key11=64:64
+Key12=35:35
+Key13=36:36
+Key14=37:37
+Key15=94:94
+Key16=38:38
+Key17=42:42
+Key18=40:40
+Key19=41:41
+Key20=95:95
+Key21=43:43
+Key22=65288:8
+Key23=65056:0
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=89:89
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=123:123
+Key35=125:125
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=58:58
+Key48=34:34
+Key49=126:126
+Key50=65505:0
+Key51=124:124
+Key52=90:90
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=60:60
+Key60=62:62
+Key61=63:63
+Key62=65506:0
+Key63=65450:42
+Key64=65511:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65454:46
+Key92=0:0
+Key93=0:0
+Key94=166:166
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65512:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=65454:46
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[capslock]
+Key8=65406:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=45:45
+Key21=61:61
+Key22=65288:8
+Key23=65289:9
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=89:89
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=91:91
+Key35=93:93
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=59:59
+Key48=39:39
+Key49=96:96
+Key50=65505:0
+Key51=92:92
+Key52=90:90
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=44:44
+Key60=46:46
+Key61=47:47
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=0:0
+Key94=60:60
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65514:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=65454:46
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[capslockaltgr]
+Key8=65406:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=45:45
+Key21=61:61
+Key22=65288:8
+Key23=65289:9
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=89:89
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=91:91
+Key35=93:93
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=59:59
+Key48=39:39
+Key49=96:96
+Key50=65505:0
+Key51=92:92
+Key52=90:90
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=44:44
+Key60=46:46
+Key61=47:47
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=0:0
+Key94=124:124
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65514:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=65454:46
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shiftcapslock]
+Key8=65406:0
+Key9=65307:27
+Key10=33:33
+Key11=64:64
+Key12=35:35
+Key13=36:36
+Key14=37:37
+Key15=94:94
+Key16=38:38
+Key17=42:42
+Key18=40:40
+Key19=41:41
+Key20=95:95
+Key21=43:43
+Key22=65288:8
+Key23=65056:0
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=121:121
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=123:123
+Key35=125:125
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=58:58
+Key48=34:34
+Key49=126:126
+Key50=65505:0
+Key51=124:124
+Key52=122:122
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=60:60
+Key60=62:62
+Key61=63:63
+Key62=65506:0
+Key63=65450:42
+Key64=65511:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65454:46
+Key92=0:0
+Key93=0:0
+Key94=62:62
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65512:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=65454:46
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shiftcapslockaltgr]
+Key8=65406:0
+Key9=65307:27
+Key10=33:33
+Key11=64:64
+Key12=35:35
+Key13=36:36
+Key14=37:37
+Key15=94:94
+Key16=38:38
+Key17=42:42
+Key18=40:40
+Key19=41:41
+Key20=95:95
+Key21=43:43
+Key22=65288:8
+Key23=65056:0
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=121:121
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=123:123
+Key35=125:125
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=58:58
+Key48=34:34
+Key49=126:126
+Key50=65505:0
+Key51=124:124
+Key52=122:122
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=60:60
+Key60=62:62
+Key61=63:63
+Key62=65506:0
+Key63=65450:42
+Key64=65511:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65454:46
+Key92=0:0
+Key93=0:0
+Key94=166:166
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65512:0
+Key114=0:0
+Key115=65515:0
+Key116=65516:0
+Key117=65383:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=65454:46
+Key135=0:0
+Key136=0:0
+Key137=0:0
+Key209=65329:0
+Key210=65332:0
diff --git a/instfiles/km-0414.ini b/instfiles/km-00000414.ini
index 08ba2ab8..08ba2ab8 100644
--- a/instfiles/km-0414.ini
+++ b/instfiles/km-00000414.ini
diff --git a/instfiles/km-0415.ini b/instfiles/km-00000415.ini
index 884e534f..884e534f 100644
--- a/instfiles/km-0415.ini
+++ b/instfiles/km-00000415.ini
diff --git a/instfiles/km-0416.ini b/instfiles/km-00000416.ini
index 9f2eb4db..9f2eb4db 100644
--- a/instfiles/km-0416.ini
+++ b/instfiles/km-00000416.ini
diff --git a/instfiles/km-0419.ini b/instfiles/km-00000419.ini
index 81395886..81395886 100644
--- a/instfiles/km-0419.ini
+++ b/instfiles/km-00000419.ini
diff --git a/instfiles/km-0000041d.ini b/instfiles/km-0000041d.ini
new file mode 100644
index 00000000..3cf432b2
--- /dev/null
+++ b/instfiles/km-0000041d.ini
@@ -0,0 +1,791 @@
+[noshift]
+Key8=65406:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=43:43
+Key21=65105:180
+Key22=65288:8
+Key23=65289:9
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=121:121
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=229:229
+Key35=65111:168
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=246:246
+Key48=228:228
+Key49=167:167
+Key50=65505:0
+Key51=39:39
+Key52=122:122
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=44:44
+Key60=46:46
+Key61=45:45
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=65377:0
+Key93=0:0
+Key94=60:60
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65027:0
+Key114=269025049:0
+Key115=65515:0
+Key116=65312:0
+Key117=0:0
+Key118=269025153:0
+Key119=269025093:0
+Key120=269025094:0
+Key121=269025095:0
+Key122=269025096:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shift]
+Key8=65406:0
+Key9=65307:27
+Key10=33:33
+Key11=34:34
+Key12=35:35
+Key13=164:164
+Key14=37:37
+Key15=38:38
+Key16=47:47
+Key17=40:40
+Key18=41:41
+Key19=61:61
+Key20=63:63
+Key21=65104:96
+Key22=65288:8
+Key23=65056:0
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=89:89
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=197:197
+Key35=65106:94
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=214:214
+Key48=196:196
+Key49=189:189
+Key50=65505:0
+Key51=42:42
+Key52=90:90
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=59:59
+Key60=58:58
+Key61=95:95
+Key62=65506:0
+Key63=65450:42
+Key64=65032:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65452:44
+Key92=65377:0
+Key93=0:0
+Key94=62:62
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65027:0
+Key114=269025049:0
+Key115=65515:0
+Key116=65312:0
+Key117=0:0
+Key118=269025153:0
+Key119=269025093:0
+Key120=269025094:0
+Key121=269025095:0
+Key122=269025096:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[altgr]
+Key8=65406:0
+Key9=65307:27
+Key10=161:161
+Key11=64:64
+Key12=163:163
+Key13=36:36
+Key14=8364:8364
+Key15=165:165
+Key16=123:123
+Key17=91:91
+Key18=93:93
+Key19=125:125
+Key20=92:92
+Key21=177:177
+Key22=65288:8
+Key23=65289:9
+Key24=64:64
+Key25=435:322
+Key26=8364:8364
+Key27=174:174
+Key28=254:254
+Key29=2299:8592
+Key30=2302:8595
+Key31=2301:8594
+Key32=5053:339
+Key33=254:254
+Key34=65111:168
+Key35=65107:126
+Key36=65293:13
+Key37=65507:0
+Key38=170:170
+Key39=223:223
+Key40=240:240
+Key41=496:273
+Key42=959:331
+Key43=689:295
+Key44=65121:0
+Key45=930:312
+Key46=435:322
+Key47=248:248
+Key48=230:230
+Key49=182:182
+Key50=65505:0
+Key51=180:180
+Key52=171:171
+Key53=187:187
+Key54=169:169
+Key55=2770:8220
+Key56=2771:8221
+Key57=110:110
+Key58=181:181
+Key59=65115:184
+Key60=183:183
+Key61=65120:0
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=65377:0
+Key93=0:0
+Key94=124:124
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65027:0
+Key114=269025049:0
+Key115=65515:0
+Key116=65312:0
+Key117=0:0
+Key118=269025153:0
+Key119=269025093:0
+Key120=269025094:0
+Key121=269025095:0
+Key122=269025096:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shiftaltgr]
+Key8=65406:0
+Key9=65307:27
+Key10=185:185
+Key11=178:178
+Key12=179:179
+Key13=188:188
+Key14=162:162
+Key15=2757:8541
+Key16=247:247
+Key17=171:171
+Key18=187:187
+Key19=176:176
+Key20=191:191
+Key21=172:172
+Key22=65288:8
+Key23=65056:0
+Key24=2009:937
+Key25=419:321
+Key26=162:162
+Key27=174:174
+Key28=222:222
+Key29=165:165
+Key30=2300:8593
+Key31=697:305
+Key32=5052:338
+Key33=222:222
+Key34=65112:176
+Key35=65114:711
+Key36=65293:13
+Key37=65507:0
+Key38=186:186
+Key39=167:167
+Key40=208:208
+Key41=170:170
+Key42=957:330
+Key43=673:294
+Key44=65122:0
+Key45=38:38
+Key46=419:321
+Key47=216:216
+Key48=198:198
+Key49=190:190
+Key50=65505:0
+Key51=215:215
+Key52=60:60
+Key53=62:62
+Key54=169:169
+Key55=2768:8216
+Key56=2769:8217
+Key57=78:78
+Key58=186:186
+Key59=65116:731
+Key60=65110:729
+Key61=65110:729
+Key62=65506:0
+Key63=65450:42
+Key64=65032:0
+Key65=160:160
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65452:44
+Key92=65377:0
+Key93=0:0
+Key94=166:166
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65027:0
+Key114=269025049:0
+Key115=65515:0
+Key116=65312:0
+Key117=0:0
+Key118=269025153:0
+Key119=269025093:0
+Key120=269025094:0
+Key121=269025095:0
+Key122=269025096:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[capslock]
+Key8=65406:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=43:43
+Key21=65105:180
+Key22=65288:8
+Key23=65289:9
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=89:89
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=197:197
+Key35=65111:168
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=214:214
+Key48=196:196
+Key49=167:167
+Key50=65505:0
+Key51=39:39
+Key52=90:90
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=44:44
+Key60=46:46
+Key61=45:45
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=65377:0
+Key93=0:0
+Key94=60:60
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65027:0
+Key114=269025049:0
+Key115=65515:0
+Key116=65312:0
+Key117=0:0
+Key118=269025153:0
+Key119=269025093:0
+Key120=269025094:0
+Key121=269025095:0
+Key122=269025096:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+[shiftcapslock]
+Key8=65406:0
+Key9=65307:27
+Key10=33:33
+Key11=34:34
+Key12=35:35
+Key13=164:164
+Key14=37:37
+Key15=38:38
+Key16=47:47
+Key17=40:40
+Key18=41:41
+Key19=61:61
+Key20=63:63
+Key21=65104:96
+Key22=65288:8
+Key23=65056:0
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=121:121
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=229:229
+Key35=65106:94
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=246:246
+Key48=228:228
+Key49=189:189
+Key50=65505:0
+Key51=42:42
+Key52=122:122
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=59:59
+Key60=58:58
+Key61=95:95
+Key62=65506:0
+Key63=65450:42
+Key64=65032:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65452:44
+Key92=65377:0
+Key93=0:0
+Key94=62:62
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65027:0
+Key114=269025049:0
+Key115=65515:0
+Key116=65312:0
+Key117=0:0
+Key118=269025153:0
+Key119=269025093:0
+Key120=269025094:0
+Key121=269025095:0
+Key122=269025096:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
diff --git a/instfiles/km-0807.ini b/instfiles/km-00000807.ini
index 7733eaf3..7733eaf3 100644
--- a/instfiles/km-0807.ini
+++ b/instfiles/km-00000807.ini
diff --git a/instfiles/km-e0200411.ini b/instfiles/km-00000809.ini
index 50ba669f..33c3dfa5 100644
--- a/instfiles/km-e0200411.ini
+++ b/instfiles/km-00000809.ini
@@ -12,7 +12,7 @@ Key17=56:56
Key18=57:57
Key19=48:48
Key20=45:45
-Key21=94:94
+Key21=61:61
Key22=65288:8
Key23=65289:9
Key24=113:113
@@ -25,8 +25,8 @@ Key30=117:117
Key31=105:105
Key32=111:111
Key33=112:112
-Key34=64:64
-Key35=91:91
+Key34=91:91
+Key35=93:93
Key36=65293:13
Key37=65507:0
Key38=97:97
@@ -39,10 +39,10 @@ Key44=106:106
Key45=107:107
Key46=108:108
Key47=59:59
-Key48=58:58
-Key49=65322:0
+Key48=39:39
+Key49=96:96
Key50=65505:0
-Key51=93:93
+Key51=35:35
Key52=122:122
Key53=120:120
Key54=99:99
@@ -57,7 +57,7 @@ Key62=65506:0
Key63=65450:42
Key64=65513:0
Key65=32:32
-Key66=65328:0
+Key66=65509:0
Key67=65470:0
Key68=65471:0
Key69=65472:0
@@ -85,7 +85,7 @@ Key90=65438:0
Key91=65439:0
Key92=65377:0
Key93=0:0
-Key94=60:60
+Key94=92:92
Key95=65480:0
Key96=65481:0
Key97=65360:0
@@ -104,7 +104,7 @@ Key109=65508:0
Key110=65299:0
Key111=65377:0
Key112=65455:47
-Key113=65514:0
+Key113=65027:0
Key114=269025049:0
Key115=65515:0
Key116=65516:0
@@ -114,7 +114,7 @@ Key119=269025093:0
Key120=269025094:0
Key121=269025095:0
Key122=269025096:0
-Key123=92:92
+Key123=0:0
Key124=65027:0
Key125=0:0
Key126=65469:61
@@ -124,7 +124,7 @@ Key129=0:0
Key130=0:0
Key131=0:0
Key132=0:0
-Key133=165:165
+Key133=0:0
Key134=0:0
Key135=0:0
Key136=0:0
@@ -135,16 +135,16 @@ Key8=65406:0
Key9=65307:27
Key10=33:33
Key11=34:34
-Key12=35:35
+Key12=163:163
Key13=36:36
Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
+Key15=94:94
+Key16=38:38
+Key17=42:42
+Key18=40:40
+Key19=41:41
+Key20=95:95
+Key21=43:43
Key22=65288:8
Key23=65056:0
Key24=81:81
@@ -157,8 +157,8 @@ Key30=85:85
Key31=73:73
Key32=79:79
Key33=80:80
-Key34=96:96
-Key35=123:123
+Key34=123:123
+Key35=125:125
Key36=65293:13
Key37=65507:0
Key38=65:65
@@ -170,11 +170,11 @@ Key43=72:72
Key44=74:74
Key45=75:75
Key46=76:76
-Key47=43:43
-Key48=42:42
-Key49=65322:0
+Key47=58:58
+Key48=64:64
+Key49=172:172
Key50=65505:0
-Key51=125:125
+Key51=126:126
Key52=90:90
Key53=88:88
Key54=67:67
@@ -217,7 +217,7 @@ Key90=65456:48
Key91=65454:46
Key92=65377:0
Key93=0:0
-Key94=62:62
+Key94=124:124
Key95=65480:0
Key96=65481:0
Key97=65360:0
@@ -236,7 +236,7 @@ Key109=65508:0
Key110=65299:0
Key111=65377:0
Key112=65455:47
-Key113=65512:0
+Key113=65312:0
Key114=269025049:0
Key115=65515:0
Key116=65516:0
@@ -246,7 +246,7 @@ Key119=269025093:0
Key120=269025094:0
Key121=269025095:0
Key122=269025096:0
-Key123=95:95
+Key123=0:0
Key124=65027:0
Key125=65513:0
Key126=65469:61
@@ -256,7 +256,7 @@ Key129=0:0
Key130=0:0
Key131=0:0
Key132=0:0
-Key133=124:124
+Key133=0:0
Key134=0:0
Key135=0:0
Key136=0:0
@@ -265,63 +265,63 @@ Key137=0:0
[altgr]
Key8=65406:0
Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
+Key10=185:185
+Key11=178:178
+Key12=179:179
+Key13=8364:8364
+Key14=189:189
+Key15=190:190
+Key16=123:123
+Key17=91:91
+Key18=93:93
+Key19=125:125
+Key20=92:92
+Key21=65115:184
Key22=65288:8
Key23=65289:9
-Key24=113:113
-Key25=119:119
+Key24=64:64
+Key25=435:322
Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=64:64
-Key35=91:91
+Key27=182:182
+Key28=956:359
+Key29=2299:8592
+Key30=2302:8595
+Key31=2301:8594
+Key32=248:248
+Key33=254:254
+Key34=65111:168
+Key35=65107:126
Key36=65293:13
Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=59:59
-Key48=58:58
-Key49=65322:0
+Key38=230:230
+Key39=223:223
+Key40=240:240
+Key41=496:273
+Key42=959:331
+Key43=689:295
+Key44=65121:0
+Key45=930:312
+Key46=435:322
+Key47=65105:180
+Key48=65106:94
+Key49=124:124
Key50=65505:0
-Key51=93:93
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
+Key51=65104:96
+Key52=171:171
+Key53=187:187
+Key54=162:162
+Key55=2770:8220
+Key56=2771:8221
Key57=110:110
-Key58=109:109
-Key59=44:44
-Key60=46:46
-Key61=47:47
+Key58=181:181
+Key59=2211:0
+Key60=183:183
+Key61=65120:0
Key62=65506:0
Key63=65450:42
Key64=65513:0
Key65=32:32
-Key66=65328:0
+Key66=65509:0
Key67=65470:0
Key68=65471:0
Key69=65472:0
@@ -368,7 +368,7 @@ Key109=65508:0
Key110=65299:0
Key111=65377:0
Key112=65455:47
-Key113=65514:0
+Key113=65027:0
Key114=269025049:0
Key115=65515:0
Key116=65516:0
@@ -388,7 +388,7 @@ Key129=0:0
Key130=0:0
Key131=0:0
Key132=0:0
-Key133=165:165
+Key133=0:0
Key134=0:0
Key135=0:0
Key136=0:0
@@ -397,58 +397,58 @@ Key137=0:0
[shiftaltgr]
Key8=65406:0
Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
+Key10=161:161
+Key11=2755:8539
+Key12=163:163
+Key13=188:188
+Key14=2756:8540
+Key15=2757:8541
+Key16=2758:8542
+Key17=2761:8482
+Key18=177:177
+Key19=176:176
+Key20=191:191
+Key21=65116:731
Key22=65288:8
Key23=65056:0
-Key24=81:81
-Key25=87:87
+Key24=2009:937
+Key25=419:321
Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=96:96
-Key35=123:123
+Key27=174:174
+Key28=940:358
+Key29=165:165
+Key30=2300:8593
+Key31=697:305
+Key32=216:216
+Key33=222:222
+Key34=65112:176
+Key35=65108:175
Key36=65293:13
Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=43:43
-Key48=42:42
-Key49=65322:0
+Key38=198:198
+Key39=167:167
+Key40=208:208
+Key41=170:170
+Key42=957:330
+Key43=673:294
+Key44=65122:0
+Key45=38:38
+Key46=419:321
+Key47=65113:733
+Key48=65114:711
+Key49=124:124
Key50=65505:0
-Key51=125:125
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
+Key51=65109:728
+Key52=60:60
+Key53=62:62
+Key54=169:169
+Key55=2768:8216
+Key56=2769:8217
Key57=78:78
-Key58=77:77
-Key59=60:60
-Key60=62:62
-Key61=63:63
+Key58=186:186
+Key59=215:215
+Key60=247:247
+Key61=65110:729
Key62=65506:0
Key63=65450:42
Key64=65511:0
@@ -500,7 +500,7 @@ Key109=65508:0
Key110=65299:0
Key111=65377:0
Key112=65455:47
-Key113=65512:0
+Key113=65312:0
Key114=269025049:0
Key115=65515:0
Key116=65516:0
@@ -520,7 +520,7 @@ Key129=0:0
Key130=0:0
Key131=0:0
Key132=0:0
-Key133=124:124
+Key133=0:0
Key134=0:0
Key135=0:0
Key136=0:0
@@ -540,7 +540,7 @@ Key17=56:56
Key18=57:57
Key19=48:48
Key20=45:45
-Key21=94:94
+Key21=61:61
Key22=65288:8
Key23=65289:9
Key24=81:81
@@ -553,8 +553,8 @@ Key30=85:85
Key31=73:73
Key32=79:79
Key33=80:80
-Key34=64:64
-Key35=91:91
+Key34=91:91
+Key35=93:93
Key36=65293:13
Key37=65507:0
Key38=65:65
@@ -567,10 +567,10 @@ Key44=74:74
Key45=75:75
Key46=76:76
Key47=59:59
-Key48=58:58
-Key49=65322:0
+Key48=39:39
+Key49=96:96
Key50=65505:0
-Key51=93:93
+Key51=35:35
Key52=90:90
Key53=88:88
Key54=67:67
@@ -585,7 +585,7 @@ Key62=65506:0
Key63=65450:42
Key64=65513:0
Key65=32:32
-Key66=65328:0
+Key66=65509:0
Key67=65470:0
Key68=65471:0
Key69=65472:0
@@ -613,7 +613,7 @@ Key90=65438:0
Key91=65439:0
Key92=65377:0
Key93=0:0
-Key94=60:60
+Key94=92:92
Key95=65480:0
Key96=65481:0
Key97=65360:0
@@ -632,7 +632,7 @@ Key109=65508:0
Key110=65299:0
Key111=65377:0
Key112=65455:47
-Key113=65514:0
+Key113=65027:0
Key114=269025049:0
Key115=65515:0
Key116=65516:0
@@ -652,7 +652,7 @@ Key129=0:0
Key130=0:0
Key131=0:0
Key132=0:0
-Key133=165:165
+Key133=0:0
Key134=0:0
Key135=0:0
Key136=0:0
@@ -661,63 +661,63 @@ Key137=0:0
[capslockaltgr]
Key8=65406:0
Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
+Key10=185:185
+Key11=178:178
+Key12=179:179
+Key13=8364:8364
+Key14=189:189
+Key15=190:190
+Key16=123:123
+Key17=91:91
+Key18=93:93
+Key19=125:125
+Key20=92:92
+Key21=65115:184
Key22=65288:8
Key23=65289:9
-Key24=81:81
-Key25=87:87
+Key24=64:64
+Key25=419:321
Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=64:64
-Key35=91:91
+Key27=182:182
+Key28=940:358
+Key29=2299:8592
+Key30=2302:8595
+Key31=2301:8594
+Key32=216:216
+Key33=222:222
+Key34=65111:168
+Key35=65107:126
Key36=65293:13
Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=59:59
-Key48=58:58
-Key49=65322:0
+Key38=198:198
+Key39=223:223
+Key40=208:208
+Key41=464:272
+Key42=957:330
+Key43=673:294
+Key44=65121:0
+Key45=930:312
+Key46=419:321
+Key47=65105:180
+Key48=65106:94
+Key49=124:124
Key50=65505:0
-Key51=93:93
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
+Key51=65104:96
+Key52=171:171
+Key53=187:187
+Key54=162:162
+Key55=2770:8220
+Key56=2771:8221
Key57=78:78
-Key58=77:77
-Key59=44:44
-Key60=46:46
-Key61=47:47
+Key58=924:0
+Key59=2211:0
+Key60=183:183
+Key61=65120:0
Key62=65506:0
Key63=65450:42
Key64=65513:0
Key65=32:32
-Key66=65328:0
+Key66=65509:0
Key67=65470:0
Key68=65471:0
Key69=65472:0
@@ -764,7 +764,7 @@ Key109=65508:0
Key110=65299:0
Key111=65377:0
Key112=65455:47
-Key113=65514:0
+Key113=65027:0
Key114=269025049:0
Key115=65515:0
Key116=65516:0
@@ -784,7 +784,7 @@ Key129=0:0
Key130=0:0
Key131=0:0
Key132=0:0
-Key133=165:165
+Key133=0:0
Key134=0:0
Key135=0:0
Key136=0:0
@@ -795,16 +795,16 @@ Key8=65406:0
Key9=65307:27
Key10=33:33
Key11=34:34
-Key12=35:35
+Key12=163:163
Key13=36:36
Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
+Key15=94:94
+Key16=38:38
+Key17=42:42
+Key18=40:40
+Key19=41:41
+Key20=95:95
+Key21=43:43
Key22=65288:8
Key23=65056:0
Key24=113:113
@@ -817,8 +817,8 @@ Key30=117:117
Key31=105:105
Key32=111:111
Key33=112:112
-Key34=96:96
-Key35=123:123
+Key34=123:123
+Key35=125:125
Key36=65293:13
Key37=65507:0
Key38=97:97
@@ -830,11 +830,11 @@ Key43=104:104
Key44=106:106
Key45=107:107
Key46=108:108
-Key47=43:43
-Key48=42:42
-Key49=65322:0
+Key47=58:58
+Key48=64:64
+Key49=172:172
Key50=65505:0
-Key51=125:125
+Key51=126:126
Key52=122:122
Key53=120:120
Key54=99:99
@@ -877,7 +877,7 @@ Key90=65456:48
Key91=65454:46
Key92=65377:0
Key93=0:0
-Key94=62:62
+Key94=124:124
Key95=65480:0
Key96=65481:0
Key97=65360:0
@@ -896,7 +896,7 @@ Key109=65508:0
Key110=65299:0
Key111=65377:0
Key112=65455:47
-Key113=65512:0
+Key113=65312:0
Key114=269025049:0
Key115=65515:0
Key116=65516:0
@@ -916,7 +916,7 @@ Key129=0:0
Key130=0:0
Key131=0:0
Key132=0:0
-Key133=124:124
+Key133=0:0
Key134=0:0
Key135=0:0
Key136=0:0
@@ -925,58 +925,58 @@ Key137=0:0
[shiftcapslockaltgr]
Key8=65406:0
Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
+Key10=161:161
+Key11=2755:8539
+Key12=163:163
+Key13=188:188
+Key14=2756:8540
+Key15=2757:8541
+Key16=2758:8542
+Key17=2761:8482
+Key18=177:177
+Key19=176:176
+Key20=191:191
+Key21=65116:731
Key22=65288:8
Key23=65056:0
-Key24=113:113
-Key25=119:119
+Key24=2009:937
+Key25=435:322
Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=96:96
-Key35=123:123
+Key27=174:174
+Key28=956:359
+Key29=165:165
+Key30=2300:8593
+Key31=697:305
+Key32=248:248
+Key33=254:254
+Key34=65112:176
+Key35=65108:175
Key36=65293:13
Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=43:43
-Key48=42:42
-Key49=65322:0
+Key38=230:230
+Key39=167:167
+Key40=240:240
+Key41=170:170
+Key42=959:331
+Key43=689:295
+Key44=65122:0
+Key45=38:38
+Key46=435:322
+Key47=65113:733
+Key48=65114:711
+Key49=124:124
Key50=65505:0
-Key51=125:125
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
+Key51=65109:728
+Key52=60:60
+Key53=62:62
+Key54=169:169
+Key55=2768:8216
+Key56=2769:8217
Key57=110:110
-Key58=109:109
-Key59=60:60
-Key60=62:62
-Key61=63:63
+Key58=186:186
+Key59=215:215
+Key60=247:247
+Key61=65110:729
Key62=65506:0
Key63=65450:42
Key64=65511:0
@@ -1028,7 +1028,7 @@ Key109=65508:0
Key110=65299:0
Key111=65377:0
Key112=65455:47
-Key113=65512:0
+Key113=65312:0
Key114=269025049:0
Key115=65515:0
Key116=65516:0
@@ -1048,7 +1048,7 @@ Key129=0:0
Key130=0:0
Key131=0:0
Key132=0:0
-Key133=124:124
+Key133=0:0
Key134=0:0
Key135=0:0
Key136=0:0
diff --git a/instfiles/km-080c.ini b/instfiles/km-0000080c.ini
index 3b160b37..3b160b37 100644
--- a/instfiles/km-080c.ini
+++ b/instfiles/km-0000080c.ini
diff --git a/instfiles/km-0813.ini b/instfiles/km-00000813.ini
index 3b160b37..3b160b37 100644
--- a/instfiles/km-0813.ini
+++ b/instfiles/km-00000813.ini
diff --git a/instfiles/km-0816.ini b/instfiles/km-00000816.ini
index 3a5801b2..3a5801b2 100644
--- a/instfiles/km-0816.ini
+++ b/instfiles/km-00000816.ini
diff --git a/instfiles/km-0000100c.ini b/instfiles/km-0000100c.ini
new file mode 100644
index 00000000..fd963fc0
--- /dev/null
+++ b/instfiles/km-0000100c.ini
@@ -0,0 +1,659 @@
+[noshift]
+Key8=0:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=39:39
+Key21=65106:94
+Key22=65288:8
+Key23=65289:9
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=122:122
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=232:232
+Key35=65111:168
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=233:233
+Key48=224:224
+Key49=167:167
+Key50=65505:0
+Key51=36:36
+Key52=121:121
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=44:44
+Key60=46:46
+Key61=45:45
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=65406:0
+Key94=60:60
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65027:0
+Key114=0:0
+Key115=0:0
+Key116=0:0
+Key117=0:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shift]
+Key8=0:0
+Key9=65307:27
+Key10=43:43
+Key11=34:34
+Key12=42:42
+Key13=231:231
+Key14=37:37
+Key15=38:38
+Key16=47:47
+Key17=40:40
+Key18=41:41
+Key19=61:61
+Key20=63:63
+Key21=65104:96
+Key22=65288:8
+Key23=65056:0
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=90:90
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=252:252
+Key35=33:33
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=246:246
+Key48=228:228
+Key49=176:176
+Key50=65505:0
+Key51=163:163
+Key52=89:89
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=59:59
+Key60=58:58
+Key61=95:95
+Key62=65506:0
+Key63=65450:42
+Key64=65511:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65273:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65454:46
+Key92=0:0
+Key93=65406:0
+Key94=62:62
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65312:0
+Key114=0:0
+Key115=0:0
+Key116=0:0
+Key117=0:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[altgr]
+Key8=0:0
+Key9=65307:27
+Key10=124:124
+Key11=64:64
+Key12=35:35
+Key13=188:188
+Key14=189:189
+Key15=172:172
+Key16=166:166
+Key17=162:162
+Key18=93:93
+Key19=125:125
+Key20=65105:180
+Key21=65107:126
+Key22=65288:8
+Key23=65289:9
+Key24=64:64
+Key25=435:322
+Key26=8364:8364
+Key27=182:182
+Key28=956:359
+Key29=2299:8592
+Key30=2302:8595
+Key31=2301:8594
+Key32=248:248
+Key33=254:254
+Key34=91:91
+Key35=93:93
+Key36=65293:13
+Key37=65507:0
+Key38=230:230
+Key39=223:223
+Key40=240:240
+Key41=496:273
+Key42=959:331
+Key43=689:295
+Key44=106:106
+Key45=930:312
+Key46=435:322
+Key47=65105:180
+Key48=123:123
+Key49=172:172
+Key50=65505:0
+Key51=125:125
+Key52=171:171
+Key53=187:187
+Key54=162:162
+Key55=2770:8220
+Key56=2771:8221
+Key57=110:110
+Key58=181:181
+Key59=2211:0
+Key60=183:183
+Key61=65120:0
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=65406:0
+Key94=92:92
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=0:0
+Key112=65455:47
+Key113=65027:0
+Key114=0:0
+Key115=0:0
+Key116=0:0
+Key117=0:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[capslock]
+Key8=0:0
+Key9=65307:27
+Key10=49:49
+Key11=50:50
+Key12=51:51
+Key13=52:52
+Key14=53:53
+Key15=54:54
+Key16=55:55
+Key17=56:56
+Key18=57:57
+Key19=48:48
+Key20=39:39
+Key21=65106:94
+Key22=65288:8
+Key23=65289:9
+Key24=81:81
+Key25=87:87
+Key26=69:69
+Key27=82:82
+Key28=84:84
+Key29=90:90
+Key30=85:85
+Key31=73:73
+Key32=79:79
+Key33=80:80
+Key34=200:200
+Key35=65111:168
+Key36=65293:13
+Key37=65507:0
+Key38=65:65
+Key39=83:83
+Key40=68:68
+Key41=70:70
+Key42=71:71
+Key43=72:72
+Key44=74:74
+Key45=75:75
+Key46=76:76
+Key47=201:201
+Key48=192:192
+Key49=167:167
+Key50=65505:0
+Key51=36:36
+Key52=89:89
+Key53=88:88
+Key54=67:67
+Key55=86:86
+Key56=66:66
+Key57=78:78
+Key58=77:77
+Key59=44:44
+Key60=46:46
+Key61=45:45
+Key62=65506:0
+Key63=65450:42
+Key64=65513:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65407:0
+Key78=65300:0
+Key79=65429:0
+Key80=65431:0
+Key81=65434:0
+Key82=65453:45
+Key83=65430:0
+Key84=65437:0
+Key85=65432:0
+Key86=65451:43
+Key87=65436:0
+Key88=65433:0
+Key89=65435:0
+Key90=65438:0
+Key91=65439:0
+Key92=0:0
+Key93=65406:0
+Key94=60:60
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65027:0
+Key114=0:0
+Key115=0:0
+Key116=0:0
+Key117=0:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=0:0
+Key126=65469:61
+Key127=0:0
+Key128=0:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
+
+[shiftcapslock]
+Key8=0:0
+Key9=65307:27
+Key10=43:43
+Key11=34:34
+Key12=42:42
+Key13=199:199
+Key14=37:37
+Key15=38:38
+Key16=47:47
+Key17=40:40
+Key18=41:41
+Key19=61:61
+Key20=63:63
+Key21=65104:96
+Key22=65288:8
+Key23=65056:0
+Key24=113:113
+Key25=119:119
+Key26=101:101
+Key27=114:114
+Key28=116:116
+Key29=122:122
+Key30=117:117
+Key31=105:105
+Key32=111:111
+Key33=112:112
+Key34=220:220
+Key35=33:33
+Key36=65293:13
+Key37=65507:0
+Key38=97:97
+Key39=115:115
+Key40=100:100
+Key41=102:102
+Key42=103:103
+Key43=104:104
+Key44=106:106
+Key45=107:107
+Key46=108:108
+Key47=214:214
+Key48=196:196
+Key49=176:176
+Key50=65505:0
+Key51=163:163
+Key52=121:121
+Key53=120:120
+Key54=99:99
+Key55=118:118
+Key56=98:98
+Key57=110:110
+Key58=109:109
+Key59=59:59
+Key60=58:58
+Key61=95:95
+Key62=65506:0
+Key63=65450:42
+Key64=65511:0
+Key65=32:32
+Key66=65509:0
+Key67=65470:0
+Key68=65471:0
+Key69=65472:0
+Key70=65473:0
+Key71=65474:0
+Key72=65475:0
+Key73=65476:0
+Key74=65477:0
+Key75=65478:0
+Key76=65479:0
+Key77=65273:0
+Key78=65300:0
+Key79=65463:55
+Key80=65464:56
+Key81=65465:57
+Key82=65453:45
+Key83=65460:52
+Key84=65461:53
+Key85=65462:54
+Key86=65451:43
+Key87=65457:49
+Key88=65458:50
+Key89=65459:51
+Key90=65456:48
+Key91=65454:46
+Key92=0:0
+Key93=65406:0
+Key94=62:62
+Key95=65480:0
+Key96=65481:0
+Key97=65360:0
+Key98=65362:0
+Key99=65365:0
+Key100=65361:0
+Key101=0:0
+Key102=65363:0
+Key103=65367:0
+Key104=65364:0
+Key105=65366:0
+Key106=65379:0
+Key107=65535:127
+Key108=65421:13
+Key109=65508:0
+Key110=65299:0
+Key111=65377:0
+Key112=65455:47
+Key113=65312:0
+Key114=0:0
+Key115=0:0
+Key116=0:0
+Key117=0:0
+Key118=0:0
+Key119=0:0
+Key120=0:0
+Key121=0:0
+Key122=0:0
+Key123=0:0
+Key124=65027:0
+Key125=65513:0
+Key126=65469:61
+Key127=65515:0
+Key128=65517:0
+Key129=0:0
+Key130=0:0
+Key131=0:0
+Key132=0:0
+Key133=0:0
+Key134=0:0
+Key135=0:0
+Key136=0:0
+Key137=0:0
diff --git a/instfiles/km-e0210411.ini b/instfiles/km-e0210411.ini
deleted file mode 100644
index 50ba669f..00000000
--- a/instfiles/km-e0210411.ini
+++ /dev/null
@@ -1,1055 +0,0 @@
-[noshift]
-Key8=65406:0
-Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
-Key22=65288:8
-Key23=65289:9
-Key24=113:113
-Key25=119:119
-Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=64:64
-Key35=91:91
-Key36=65293:13
-Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=59:59
-Key48=58:58
-Key49=65322:0
-Key50=65505:0
-Key51=93:93
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
-Key57=110:110
-Key58=109:109
-Key59=44:44
-Key60=46:46
-Key61=47:47
-Key62=65506:0
-Key63=65450:42
-Key64=65513:0
-Key65=32:32
-Key66=65328:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65429:0
-Key80=65431:0
-Key81=65434:0
-Key82=65453:45
-Key83=65430:0
-Key84=65437:0
-Key85=65432:0
-Key86=65451:43
-Key87=65436:0
-Key88=65433:0
-Key89=65435:0
-Key90=65438:0
-Key91=65439:0
-Key92=65377:0
-Key93=0:0
-Key94=60:60
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65514:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=92:92
-Key124=65027:0
-Key125=0:0
-Key126=65469:61
-Key127=0:0
-Key128=0:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=165:165
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[shift]
-Key8=65406:0
-Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
-Key22=65288:8
-Key23=65056:0
-Key24=81:81
-Key25=87:87
-Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=96:96
-Key35=123:123
-Key36=65293:13
-Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=43:43
-Key48=42:42
-Key49=65322:0
-Key50=65505:0
-Key51=125:125
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
-Key57=78:78
-Key58=77:77
-Key59=60:60
-Key60=62:62
-Key61=63:63
-Key62=65506:0
-Key63=65450:42
-Key64=65511:0
-Key65=32:32
-Key66=65509:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65463:55
-Key80=65464:56
-Key81=65465:57
-Key82=65453:45
-Key83=65460:52
-Key84=65461:53
-Key85=65462:54
-Key86=65451:43
-Key87=65457:49
-Key88=65458:50
-Key89=65459:51
-Key90=65456:48
-Key91=65454:46
-Key92=65377:0
-Key93=0:0
-Key94=62:62
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65512:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=95:95
-Key124=65027:0
-Key125=65513:0
-Key126=65469:61
-Key127=65515:0
-Key128=65517:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=124:124
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[altgr]
-Key8=65406:0
-Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
-Key22=65288:8
-Key23=65289:9
-Key24=113:113
-Key25=119:119
-Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=64:64
-Key35=91:91
-Key36=65293:13
-Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=59:59
-Key48=58:58
-Key49=65322:0
-Key50=65505:0
-Key51=93:93
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
-Key57=110:110
-Key58=109:109
-Key59=44:44
-Key60=46:46
-Key61=47:47
-Key62=65506:0
-Key63=65450:42
-Key64=65513:0
-Key65=32:32
-Key66=65328:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65429:0
-Key80=65431:0
-Key81=65434:0
-Key82=65453:45
-Key83=65430:0
-Key84=65437:0
-Key85=65432:0
-Key86=65451:43
-Key87=65436:0
-Key88=65433:0
-Key89=65435:0
-Key90=65438:0
-Key91=65439:0
-Key92=65377:0
-Key93=0:0
-Key94=124:124
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65514:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=0:0
-Key126=65469:61
-Key127=0:0
-Key128=0:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=165:165
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[shiftaltgr]
-Key8=65406:0
-Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
-Key22=65288:8
-Key23=65056:0
-Key24=81:81
-Key25=87:87
-Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=96:96
-Key35=123:123
-Key36=65293:13
-Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=43:43
-Key48=42:42
-Key49=65322:0
-Key50=65505:0
-Key51=125:125
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
-Key57=78:78
-Key58=77:77
-Key59=60:60
-Key60=62:62
-Key61=63:63
-Key62=65506:0
-Key63=65450:42
-Key64=65511:0
-Key65=32:32
-Key66=65509:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65463:55
-Key80=65464:56
-Key81=65465:57
-Key82=65453:45
-Key83=65460:52
-Key84=65461:53
-Key85=65462:54
-Key86=65451:43
-Key87=65457:49
-Key88=65458:50
-Key89=65459:51
-Key90=65456:48
-Key91=65454:46
-Key92=65377:0
-Key93=0:0
-Key94=166:166
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65512:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=65513:0
-Key126=65469:61
-Key127=65515:0
-Key128=65517:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=124:124
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[capslock]
-Key8=65406:0
-Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
-Key22=65288:8
-Key23=65289:9
-Key24=81:81
-Key25=87:87
-Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=64:64
-Key35=91:91
-Key36=65293:13
-Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=59:59
-Key48=58:58
-Key49=65322:0
-Key50=65505:0
-Key51=93:93
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
-Key57=78:78
-Key58=77:77
-Key59=44:44
-Key60=46:46
-Key61=47:47
-Key62=65506:0
-Key63=65450:42
-Key64=65513:0
-Key65=32:32
-Key66=65328:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65429:0
-Key80=65431:0
-Key81=65434:0
-Key82=65453:45
-Key83=65430:0
-Key84=65437:0
-Key85=65432:0
-Key86=65451:43
-Key87=65436:0
-Key88=65433:0
-Key89=65435:0
-Key90=65438:0
-Key91=65439:0
-Key92=65377:0
-Key93=0:0
-Key94=60:60
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65514:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=0:0
-Key126=65469:61
-Key127=0:0
-Key128=0:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=165:165
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[capslockaltgr]
-Key8=65406:0
-Key9=65307:27
-Key10=49:49
-Key11=50:50
-Key12=51:51
-Key13=52:52
-Key14=53:53
-Key15=54:54
-Key16=55:55
-Key17=56:56
-Key18=57:57
-Key19=48:48
-Key20=45:45
-Key21=94:94
-Key22=65288:8
-Key23=65289:9
-Key24=81:81
-Key25=87:87
-Key26=69:69
-Key27=82:82
-Key28=84:84
-Key29=89:89
-Key30=85:85
-Key31=73:73
-Key32=79:79
-Key33=80:80
-Key34=64:64
-Key35=91:91
-Key36=65293:13
-Key37=65507:0
-Key38=65:65
-Key39=83:83
-Key40=68:68
-Key41=70:70
-Key42=71:71
-Key43=72:72
-Key44=74:74
-Key45=75:75
-Key46=76:76
-Key47=59:59
-Key48=58:58
-Key49=65322:0
-Key50=65505:0
-Key51=93:93
-Key52=90:90
-Key53=88:88
-Key54=67:67
-Key55=86:86
-Key56=66:66
-Key57=78:78
-Key58=77:77
-Key59=44:44
-Key60=46:46
-Key61=47:47
-Key62=65506:0
-Key63=65450:42
-Key64=65513:0
-Key65=32:32
-Key66=65328:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65429:0
-Key80=65431:0
-Key81=65434:0
-Key82=65453:45
-Key83=65430:0
-Key84=65437:0
-Key85=65432:0
-Key86=65451:43
-Key87=65436:0
-Key88=65433:0
-Key89=65435:0
-Key90=65438:0
-Key91=65439:0
-Key92=65377:0
-Key93=0:0
-Key94=124:124
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65514:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=0:0
-Key126=65469:61
-Key127=0:0
-Key128=0:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=165:165
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[shiftcapslock]
-Key8=65406:0
-Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
-Key22=65288:8
-Key23=65056:0
-Key24=113:113
-Key25=119:119
-Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=96:96
-Key35=123:123
-Key36=65293:13
-Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=43:43
-Key48=42:42
-Key49=65322:0
-Key50=65505:0
-Key51=125:125
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
-Key57=110:110
-Key58=109:109
-Key59=60:60
-Key60=62:62
-Key61=63:63
-Key62=65506:0
-Key63=65450:42
-Key64=65511:0
-Key65=32:32
-Key66=65509:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65463:55
-Key80=65464:56
-Key81=65465:57
-Key82=65453:45
-Key83=65460:52
-Key84=65461:53
-Key85=65462:54
-Key86=65451:43
-Key87=65457:49
-Key88=65458:50
-Key89=65459:51
-Key90=65456:48
-Key91=65454:46
-Key92=65377:0
-Key93=0:0
-Key94=62:62
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65512:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=65513:0
-Key126=65469:61
-Key127=65515:0
-Key128=65517:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=124:124
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
-
-[shiftcapslockaltgr]
-Key8=65406:0
-Key9=65307:27
-Key10=33:33
-Key11=34:34
-Key12=35:35
-Key13=36:36
-Key14=37:37
-Key15=38:38
-Key16=39:39
-Key17=40:40
-Key18=41:41
-Key19=48:48
-Key20=61:61
-Key21=126:126
-Key22=65288:8
-Key23=65056:0
-Key24=113:113
-Key25=119:119
-Key26=101:101
-Key27=114:114
-Key28=116:116
-Key29=121:121
-Key30=117:117
-Key31=105:105
-Key32=111:111
-Key33=112:112
-Key34=96:96
-Key35=123:123
-Key36=65293:13
-Key37=65507:0
-Key38=97:97
-Key39=115:115
-Key40=100:100
-Key41=102:102
-Key42=103:103
-Key43=104:104
-Key44=106:106
-Key45=107:107
-Key46=108:108
-Key47=43:43
-Key48=42:42
-Key49=65322:0
-Key50=65505:0
-Key51=125:125
-Key52=122:122
-Key53=120:120
-Key54=99:99
-Key55=118:118
-Key56=98:98
-Key57=110:110
-Key58=109:109
-Key59=60:60
-Key60=62:62
-Key61=63:63
-Key62=65506:0
-Key63=65450:42
-Key64=65511:0
-Key65=32:32
-Key66=65509:0
-Key67=65470:0
-Key68=65471:0
-Key69=65472:0
-Key70=65473:0
-Key71=65474:0
-Key72=65475:0
-Key73=65476:0
-Key74=65477:0
-Key75=65478:0
-Key76=65479:0
-Key77=65407:0
-Key78=65300:0
-Key79=65463:55
-Key80=65464:56
-Key81=65465:57
-Key82=65453:45
-Key83=65460:52
-Key84=65461:53
-Key85=65462:54
-Key86=65451:43
-Key87=65457:49
-Key88=65458:50
-Key89=65459:51
-Key90=65456:48
-Key91=65454:46
-Key92=65377:0
-Key93=0:0
-Key94=166:166
-Key95=65480:0
-Key96=65481:0
-Key97=65360:0
-Key98=65362:0
-Key99=65365:0
-Key100=65361:0
-Key101=0:0
-Key102=65363:0
-Key103=65367:0
-Key104=65364:0
-Key105=65366:0
-Key106=65379:0
-Key107=65535:127
-Key108=65421:13
-Key109=65508:0
-Key110=65299:0
-Key111=65377:0
-Key112=65455:47
-Key113=65512:0
-Key114=269025049:0
-Key115=65515:0
-Key116=65516:0
-Key117=0:0
-Key118=269025153:0
-Key119=269025093:0
-Key120=269025094:0
-Key121=269025095:0
-Key122=269025096:0
-Key123=0:0
-Key124=65027:0
-Key125=65513:0
-Key126=65469:61
-Key127=65515:0
-Key128=65517:0
-Key129=0:0
-Key130=0:0
-Key131=0:0
-Key132=0:0
-Key133=124:124
-Key134=0:0
-Key135=0:0
-Key136=0:0
-Key137=0:0
diff --git a/instfiles/pam.d/Makefile.am b/instfiles/pam.d/Makefile.am
index d51d5c20..3e09802b 100644
--- a/instfiles/pam.d/Makefile.am
+++ b/instfiles/pam.d/Makefile.am
@@ -1,4 +1,9 @@
-EXTRA_DIST = xrdp-sesman
+EXTRA_DIST = \
+ xrdp-sesman.common \
+ xrdp-sesman.other \
+ xrdp-sesman.password-auth
+
+CLEANFILES = xrdp-sesman
if SESMAN_NOPAM
PAMFILE =
@@ -14,7 +19,19 @@ endif
endif
endif
-pamddir=$(sysconfdir)/pam.d
+pamddir = $(sysconfdir)/pam.d
pamd_DATA = \
$(PAMFILE)
+
+xrdp-sesman:
+ if test -e /etc/pam.d/password-auth; then \
+ pamrules=xrdp-sesman.password-auth; \
+ else \
+ if test -e /etc/pam.d/common-auth; then \
+ pamrules=xrdp-sesman.common; \
+ else \
+ pamrules=xrdp-sesman.other; \
+ fi; \
+ fi; \
+ $(LN_S) $(srcdir)/$$pamrules $@
diff --git a/instfiles/pam.d/xrdp-sesman b/instfiles/pam.d/xrdp-sesman.common
index 789ce8f7..b2089987 100644
--- a/instfiles/pam.d/xrdp-sesman
+++ b/instfiles/pam.d/xrdp-sesman.common
@@ -2,4 +2,3 @@
@include common-auth
@include common-account
@include common-session
-@include common-password
diff --git a/instfiles/pam.d/xrdp-sesman.password-auth b/instfiles/pam.d/xrdp-sesman.password-auth
new file mode 100644
index 00000000..b17187c8
--- /dev/null
+++ b/instfiles/pam.d/xrdp-sesman.password-auth
@@ -0,0 +1,4 @@
+#%PAM-1.0
+auth include password-auth
+account include password-auth
+session include password-auth
diff --git a/instfiles/pulse/Makefile.am b/instfiles/pulse/Makefile.am
index fcd9ee4b..72b80d10 100644
--- a/instfiles/pulse/Makefile.am
+++ b/instfiles/pulse/Makefile.am
@@ -1,3 +1,2 @@
-EXTRA_DIST = default.pa
-pulsedir=$(sysconfdir)/xrdp/pulse
-pulse_DATA = default.pa
+pulsedir = $(sysconfdir)/xrdp/pulse
+dist_pulse_DATA = default.pa
diff --git a/instfiles/rc.d/Makefile.am b/instfiles/rc.d/Makefile.am
new file mode 100644
index 00000000..17993232
--- /dev/null
+++ b/instfiles/rc.d/Makefile.am
@@ -0,0 +1,2 @@
+startscriptdir = $(sysconfdir)/rc.d
+dist_startscript_SCRIPTS = xrdp
diff --git a/instfiles/rc.d/xrdp b/instfiles/rc.d/xrdp
new file mode 100644
index 00000000..9dec649e
--- /dev/null
+++ b/instfiles/rc.d/xrdp
@@ -0,0 +1,80 @@
+#!/bin/sh
+#
+# Copyright (c) 1992-2015 The FreeBSD 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:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. 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 AUTHOR 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 AUTHOR 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.
+#
+# $FreeBSD$
+#
+# REQUIRE: DAEMON
+# PROVIDE: xrdp xrdp_sesman
+#
+
+. /etc/rc.subr
+
+name="xrdp"
+rcvar=xrdp_enable
+xrdp_daemons="xrdp"
+
+# Read settings and set default values.
+load_rc_config "$name"
+: ${xrdp_enable="NO"}
+
+# Enable/disable dependent daemon.
+if [ -n "${rcvar}" ] && checkyesno "xrdp_sesman_enable"; then
+ xrdp_daemons="xrdp xrdp_sesman"
+fi
+
+# Commands.
+extra_commands="reload status"
+start_cmd="xrdp_cmd"
+stop_cmd="xrdp_cmd"
+status_cmd="xrdp_cmd"
+reload_cmd="xrdp_cmd"
+rcvar_cmd="xrdp_cmd"
+
+# Command wrapper to call each of them per daemon.
+xrdp_cmd() {
+ local name rcvar command pidfile xrdp_daemons
+ # Prevent recursive calling.
+ unset "${rc_arg}_cmd"
+ # Stop processes in the reverse to order.
+ if [ "${rc_arg}" = "stop" ] ; then
+ xrdp_daemons=$(reverse_list ${xrdp_daemons})
+ fi
+
+ # Apply to all the daemons.
+ for name in ${xrdp_daemons}; do
+ rcvar=${name}_enable
+ if [ "${name}" = "xrdp_sesman" ]; then
+ command="%%PREFIX%%/sbin/xrdp-sesman"
+ pidfile="/var/run/xrdp-sesman.pid"
+ else
+ command="%%PREFIX%%/sbin/${name}"
+ pidfile="/var/run/${name}.pid"
+ fi
+
+ run_rc_command "${_rc_prefix}${rc_arg}" ${rc_extra_args}
+ done
+}
+
+run_rc_command "$1"
diff --git a/instfiles/xrdp-sesman.service b/instfiles/xrdp-sesman.service
index d40150cd..0ce9a4e5 100644
--- a/instfiles/xrdp-sesman.service
+++ b/instfiles/xrdp-sesman.service
@@ -2,11 +2,13 @@
Description=xrdp session manager
After=syslog.target network.target
StopWhenUnneeded=true
+BindTo=xrdp.service
[Service]
Type=forking
PIDFile=/var/run/xrdp-sesman.pid
-EnvironmentFile=/etc/sysconfig/xrdp
+EnvironmentFile=-/etc/sysconfig/xrdp
+EnvironmentFile=-/etc/default/xrdp
ExecStart=/usr/sbin/xrdp-sesman $SESMAN_OPTIONS
ExecStop=/usr/sbin/xrdp-sesman $SESMAN_OPTIONS --kill
diff --git a/instfiles/xrdp.service b/instfiles/xrdp.service
index 7bb076d1..fca4bd66 100644
--- a/instfiles/xrdp.service
+++ b/instfiles/xrdp.service
@@ -6,7 +6,8 @@ After=syslog.target network.target xrdp-sesman.service
[Service]
Type=forking
PIDFile=/var/run/xrdp.pid
-EnvironmentFile=/etc/sysconfig/xrdp
+EnvironmentFile=-/etc/sysconfig/xrdp
+EnvironmentFile=-/etc/default/xrdp
ExecStart=/usr/sbin/xrdp $XRDP_OPTIONS
ExecStop=/usr/sbin/xrdp $XRDP_OPTIONS --kill
diff --git a/keygen/Makefile.am b/keygen/Makefile.am
index c28c063d..014e8df9 100644
--- a/keygen/Makefile.am
+++ b/keygen/Makefile.am
@@ -1,11 +1,10 @@
+EXTRA_DIST = openssl.conf
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
-
-INCLUDES = \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-I$(top_srcdir)/common
bin_PROGRAMS = \
@@ -15,3 +14,23 @@ xrdp_keygen_SOURCES = keygen.c
xrdp_keygen_LDADD = \
$(top_builddir)/common/libcommon.la
+
+xrdpsysconfdir = $(sysconfdir)/xrdp
+
+install-data-hook:
+ umask 077 && \
+ if [ ! -f $(DESTDIR)$(xrdpsysconfdir)/rsakeys.ini ]; then \
+ ./xrdp-keygen xrdp $(DESTDIR)$(xrdpsysconfdir)/rsakeys.ini; \
+ fi && \
+ if [ ! -f $(DESTDIR)$(xrdpsysconfdir)/cert.pem ]; then \
+ openssl req -x509 -newkey rsa:2048 -sha256 -nodes \
+ -keyout $(DESTDIR)$(xrdpsysconfdir)/key.pem -out \
+ $(DESTDIR)$(xrdpsysconfdir)/cert.pem -days 365 \
+ -subj /C=US/ST=CA/L=Sunnyvale/O=xrdp/CN=www.xrdp.org \
+ -config $(srcdir)/openssl.conf; \
+ fi
+
+uninstall-hook:
+ rm -f $(DESTDIR)$(xrdpsysconfdir)/rsakeys.ini
+ rm -f $(DESTDIR)$(xrdpsysconfdir)/cert.pem
+ rm -f $(DESTDIR)$(xrdpsysconfdir)/key.pem
diff --git a/keygen/keygen.c b/keygen/keygen.c
index 8b40071f..12970100 100644
--- a/keygen/keygen.c
+++ b/keygen/keygen.c
@@ -34,8 +34,8 @@
/* this is the signature size in bytes */
#define TSSK_KEY_LENGTH 64
-/* default to 512 bit key size, can set changed, set */
-static int g_key_size_bits = 512;
+/* default to 2048 bit key size, can set changed, set */
+static int g_key_size_bits = 2048;
static tui8 g_exponent[4] =
{
@@ -195,11 +195,11 @@ static tui8 g_testkey2048[376] = /* 2048 bit test key */
static int APP_CC
out_params(void)
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("xrdp rsa key gen utility examples");
g_writeln(" xrdp-keygen xrdp ['path and file name' | auto] [512 or 2048]");
g_writeln(" xrdp-keygen test");
- g_writeln("");
+ g_writeln("%s", "");
return 0;
}
@@ -282,7 +282,7 @@ sign_key(char *e_data, int e_len, char *n_data, int n_len,
/*****************************************************************************/
static int APP_CC
-write_out_line(int fd, char *name, char *data, int len)
+write_out_line(int fd, const char *name, char *data, int len)
{
int max;
int error;
@@ -351,7 +351,7 @@ save_all(char *e_data, int e_len, char *n_data, int n_len,
}
g_writeln("saving to %s", filename);
- g_writeln("");
+ g_writeln("%s", "");
if (g_file_exist(filename))
{
@@ -411,15 +411,14 @@ key_gen(const char *path_and_file_name)
d_len = n_len;
sign_len = 64;
error = 0;
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("Generating %d bit rsa key...", g_key_size_bits);
- g_writeln("");
+ g_writeln("%s", "");
if (error == 0)
{
error = ssl_gen_key_xrdp1(g_key_size_bits, e_data, e_len, n_data, n_len,
d_data, d_len);
-
if (error != 0)
{
g_writeln("error %d in key_gen, ssl_gen_key_xrdp1", error);
@@ -429,7 +428,7 @@ key_gen(const char *path_and_file_name)
if (error == 0)
{
g_writeln("ssl_gen_key_xrdp1 ok");
- g_writeln("");
+ g_writeln("%s", "");
error = sign_key(e_data, e_len, n_data, n_len, sign_data, sign_len);
if (error != 0)
@@ -589,10 +588,10 @@ main(int argc, char **argv)
}
else if (g_strcasecmp(argv[1], "test") == 0)
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("testing 512 bit key");
key_test512();
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("testing 2048 bit key");
key_test2048();
return 0;
diff --git a/keygen/openssl.conf b/keygen/openssl.conf
new file mode 100644
index 00000000..79b1dfb4
--- /dev/null
+++ b/keygen/openssl.conf
@@ -0,0 +1,4 @@
+[req]
+distinguished_name = req_distinguished_name
+
+[req_distinguished_name]
diff --git a/libpainter b/libpainter
new file mode 160000
+Subproject 71561310ccb2cf9c086e1ca533cd3b846283c3e
diff --git a/librfxcodec b/librfxcodec
-Subproject 61f6e92ecdfd057215da7932b6afefcbfa92844
+Subproject 03a36890da75d6c27a31bcd1caae4bb9c839c6f
diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am
index bd37cad4..0452c1da 100644
--- a/libxrdp/Makefile.am
+++ b/libxrdp/Makefile.am
@@ -1,71 +1,65 @@
-EXTRA_DIST = libxrdp.h libxrdpinc.h
+EXTRA_DIST = \
+ xrdp_surface.c
-EXTRA_DEFINES =
-EXTRA_INCLUDES =
-EXTRA_LIBS =
-EXTRA_FLAGS =
+AM_CPPFLAGS = \
+ -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
+ -DXRDP_SBIN_PATH=\"${sbindir}\" \
+ -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
+ -I$(top_srcdir)/common
+
+AM_LDFLAGS =
+
+LIBXRDP_EXTRA_LIBS =
if XRDP_DEBUG
-EXTRA_DEFINES += -DXRDP_DEBUG
+AM_CPPFLAGS += -DXRDP_DEBUG
else
-EXTRA_DEFINES += -DXRDP_NODEBUG
+AM_CPPFLAGS += -DXRDP_NODEBUG
endif
if XRDP_NEUTRINORDP
-EXTRA_DEFINES += -DXRDP_NEUTRINORDP
-EXTRA_LIBS += $(FREERDP_LIBS)
+AM_CPPFLAGS += -DXRDP_NEUTRINORDP
+LIBXRDP_EXTRA_LIBS += $(FREERDP_LIBS)
+endif
+
+if XRDP_RFXCODEC
+AM_CPPFLAGS += -DXRDP_RFXCODEC
endif
if XRDP_TJPEG
-EXTRA_DEFINES += -DXRDP_JPEG -DXRDP_TJPEG
-EXTRA_INCLUDES += @TurboJpegIncDir@
-EXTRA_FLAGS += @TurboJpegLibDir@
-EXTRA_LIBS += -lturbojpeg
+AM_CPPFLAGS += -DXRDP_JPEG -DXRDP_TJPEG @TurboJpegIncDir@
+AM_LDFLAGS += @TurboJpegLibDir@
+LIBXRDP_EXTRA_LIBS += -lturbojpeg
else
if XRDP_JPEG
-EXTRA_DEFINES += -DXRDP_JPEG
-EXTRA_LIBS += -ljpeg
+AM_CPPFLAGS += -DXRDP_JPEG
+LIBXRDP_EXTRA_LIBS += -ljpeg
endif
endif
-if GOT_PREFIX
-EXTRA_INCLUDES += -I$(prefix)/include
-EXTRA_FLAGS += -L$(prefix)/lib -Wl,-rpath -Wl,$(prefix)/lib
-endif
-
-AM_CFLAGS = \
- -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
- -DXRDP_SBIN_PATH=\"${sbindir}\" \
- -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\" \
- $(EXTRA_DEFINES)
-
-INCLUDES = \
- -I$(top_srcdir)/common \
- $(EXTRA_INCLUDES)
-
-lib_LTLIBRARIES = \
+module_LTLIBRARIES = \
libxrdp.la
libxrdp_la_SOURCES = \
libxrdp.c \
+ libxrdp.h \
+ libxrdpinc.h \
+ xrdp_bitmap32_compress.c \
+ xrdp_bitmap_compress.c \
+ xrdp_caps.c \
xrdp_channel.c \
+ xrdp_fastpath.c \
xrdp_iso.c \
+ xrdp_jpeg_compress.c \
xrdp_mcs.c \
+ xrdp_mppc_enc.c \
xrdp_orders.c \
- xrdp_rdp.c \
- xrdp_sec.c \
- xrdp_bitmap_compress.c \
- xrdp_bitmap32_compress.c \
- xrdp_jpeg_compress.c \
xrdp_orders_rail.c \
- xrdp_mppc_enc.c \
- xrdp_fastpath.c \
- xrdp_caps.c
-
-libxrdp_la_LDFLAGS = \
- $(EXTRA_FLAGS)
+ xrdp_orders_rail.h \
+ xrdp_rdp.c \
+ xrdp_sec.c
libxrdp_la_LIBADD = \
$(top_builddir)/common/libcommon.la \
- $(EXTRA_LIBS)
+ $(LIBXRDP_EXTRA_LIBS)
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 594fcc73..c52829f8 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -27,6 +27,8 @@
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
+#define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */
+
/******************************************************************************/
struct xrdp_session *EXPORT_CC
libxrdp_init(tbus id, struct trans *trans)
@@ -66,7 +68,7 @@ libxrdp_disconnect(struct xrdp_session *session)
/******************************************************************************/
int EXPORT_CC
-libxrdp_process_incomming(struct xrdp_session *session)
+libxrdp_process_incoming(struct xrdp_session *session)
{
int rv;
@@ -105,7 +107,7 @@ libxrdp_get_pdu_bytes(const char *aheader)
}
/******************************************************************************/
-/* only used durring connection */
+/* only used during connection */
struct stream * APP_CC
libxrdp_force_read(struct trans* trans)
{
@@ -253,8 +255,8 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
{
/*This situation can happen and this is a workaround*/
cont = 0;
- g_writeln("Serious programming error we were locked in a deadly loop") ;
- g_writeln("remaining :%d", s->end - s->next_packet);
+ g_writeln("Serious programming error: we were locked in a deadly loop");
+ g_writeln("Remaining: %d", (int) (s->end - s->next_packet));
s->next_packet = 0;
}
@@ -373,15 +375,15 @@ libxrdp_send_bell(struct xrdp_session *session)
return 0;
}
-
/*****************************************************************************/
int EXPORT_CC
libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
int bpp, char *data, int x, int y, int cx, int cy)
{
- int line_size = 0;
+ int line_bytes = 0;
int i = 0;
int j = 0;
+ int k;
int total_lines = 0;
int lines_sending = 0;
int Bpp = 0;
@@ -389,27 +391,43 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
int bufsize = 0;
int total_bufsize = 0;
int num_updates = 0;
+ int line_pad_bytes;
+ int server_line_bytes;
char *p_num_updates = (char *)NULL;
char *p = (char *)NULL;
char *q = (char *)NULL;
struct stream *s = (struct stream *)NULL;
struct stream *temp_s = (struct stream *)NULL;
+ tui32 pixel;
- DEBUG(("libxrdp_send_bitmap sending bitmap"));
+ LLOGLN(10, ("libxrdp_send_bitmap: sending bitmap"));
Bpp = (bpp + 7) / 8;
- e = width % 4;
-
- if (e != 0)
+ e = (4 - width) & 3;
+ switch (bpp)
{
- e = 4 - e;
+ case 15:
+ case 16:
+ server_line_bytes = width * 2;
+ break;
+ case 24:
+ case 32:
+ server_line_bytes = width * 4;
+ break;
+ default: /* 8 bpp */
+ server_line_bytes = width;
+ break;
}
+ line_bytes = width * Bpp;
+ line_pad_bytes = line_bytes + e * Bpp;
- line_size = width * Bpp;
+ LLOGLN(10, ("libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d "
+ "server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes));
make_stream(s);
- init_stream(s, 8192);
+ init_stream(s, MAX_BITMAP_BUF_SIZE);
if (session->client_info->use_bitmap_comp)
{
+ LLOGLN(10, ("libxrdp_send_bitmap: compression"));
make_stream(temp_s);
init_stream(temp_s, 65536);
i = 0;
@@ -421,6 +439,8 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
while (i > 0)
{
+ LLOGLN(10, ("libxrdp_send_bitmap: i %d", i));
+
total_bufsize = 0;
num_updates = 0;
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
@@ -440,10 +460,26 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
}
p = s->p;
- lines_sending = xrdp_bitmap_compress(data, width, height,
- s, bpp,
- 4096 - total_bufsize,
- i - 1, temp_s, e);
+
+ if (bpp > 24)
+ {
+ LLOGLN(10, ("libxrdp_send_bitmap: 32 bpp"));
+ lines_sending = xrdp_bitmap32_compress(data, width, height,
+ s, 32,
+ (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
+ i - 1, temp_s, e, 0x10);
+ LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
+ i, lines_sending));
+ }
+ else
+ {
+ lines_sending = xrdp_bitmap_compress(data, width, height,
+ s, bpp,
+ (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
+ i - 1, temp_s, e);
+ LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
+ i, lines_sending));
+ }
if (lines_sending == 0)
{
@@ -470,6 +506,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
out_uint16_le(s, bufsize); /* compressed size */
j = (width + e) * Bpp;
j = j * lines_sending;
+ total_bufsize += 18; /* bytes since pop layer */
}
else
{
@@ -481,31 +518,42 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
out_uint16_le(s, j); /* line size */
j = j * lines_sending;
out_uint16_le(s, j); /* final size */
+ total_bufsize += 26; /* bytes since pop layer */
}
- if (j > 32768)
+ LLOGLN(10, ("libxrdp_send_bitmap: decompressed pixels %d "
+ "decompressed bytes %d compressed bytes %d",
+ lines_sending * (width + e),
+ line_pad_bytes * lines_sending, bufsize));
+
+ if (j > MAX_BITMAP_BUF_SIZE)
{
- g_writeln("error, decompressed size too big, its %d", j);
+ LLOGLN(0, ("libxrdp_send_bitmap: error, decompressed "
+ "size too big: %d bytes", j));
}
- if (bufsize > 8192)
+ if (bufsize > MAX_BITMAP_BUF_SIZE)
{
- g_writeln("error, compressed size too big, its %d", bufsize);
+ LLOGLN(0, ("libxrdp_send_bitmap: error, compressed size "
+ "too big: %d bytes", bufsize));
}
s->p = s->end;
}
- while (total_bufsize < 4096 && i > 0);
+ while (total_bufsize < MAX_BITMAP_BUF_SIZE && i > 0);
+
+ LLOGLN(10, ("libxrdp_send_bitmap: num_updates %d total_bufsize %d",
+ num_updates, total_bufsize));
p_num_updates[0] = num_updates;
p_num_updates[1] = num_updates >> 8;
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_UPDATE);
- if (total_bufsize > 8192)
+ if (total_bufsize > MAX_BITMAP_BUF_SIZE)
{
- g_writeln("error, total compressed size too big, its %d",
- total_bufsize);
+ LLOGLN(0, ("libxrdp_send_bitmap: error, total compressed "
+ "size too big: %d bytes", total_bufsize));
}
}
@@ -513,22 +561,30 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
}
else
{
+ LLOGLN(10, ("libxrdp_send_bitmap: no compression"));
total_lines = height;
i = 0;
p = data;
- if (line_size > 0 && total_lines > 0)
+ if (line_bytes > 0 && total_lines > 0)
{
while (i < total_lines)
{
- lines_sending = 4096 / (line_size + e * Bpp);
+
+ lines_sending = (MAX_BITMAP_BUF_SIZE - 100) / line_pad_bytes;
if (i + lines_sending > total_lines)
{
lines_sending = total_lines - i;
}
- p = p + line_size * lines_sending;
+ if (lines_sending == 0)
+ {
+ LLOGLN(0, ("libxrdp_send_bitmap: error, lines_sending == zero"));
+ break;
+ }
+
+ p += server_line_bytes * lines_sending;
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
out_uint16_le(s, RDP_UPDATE_BITMAP);
out_uint16_le(s, 1); /* num updates */
@@ -540,14 +596,58 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
out_uint16_le(s, lines_sending);
out_uint16_le(s, bpp); /* bpp */
out_uint16_le(s, 0); /* compress */
- out_uint16_le(s, (line_size + e * Bpp) * lines_sending); /* bufsize */
+ out_uint16_le(s, line_pad_bytes * lines_sending); /* bufsize */
q = p;
- for (j = 0; j < lines_sending; j++)
+ switch (bpp)
{
- q = q - line_size;
- out_uint8a(s, q, line_size); /* B_ENDIAN doesn't work here, todo */
- out_uint8s(s, e * Bpp);
+ case 8:
+ for (j = 0; j < lines_sending; j++)
+ {
+ q = q - line_bytes;
+ out_uint8a(s, q, line_bytes);
+ out_uint8s(s, e);
+ }
+ break;
+ case 15:
+ case 16:
+ for (j = 0; j < lines_sending; j++)
+ {
+ q = q - server_line_bytes;
+ for (k = 0; k < width; k++)
+ {
+ pixel = *((tui16*)(q + k * 2));
+ out_uint16_le(s, pixel);
+ }
+ out_uint8s(s, e * 2);
+ }
+ break;
+ case 24:
+ for (j = 0; j < lines_sending; j++)
+ {
+ q = q - server_line_bytes;
+ for (k = 0; k < width; k++)
+ {
+ pixel = *((tui32*)(q + k * 4));
+ out_uint8(s, pixel);
+ out_uint8(s, pixel >> 8);
+ out_uint8(s, pixel >> 16);
+ }
+ out_uint8s(s, e * 3);
+ }
+ break;
+ case 32:
+ for (j = 0; j < lines_sending; j++)
+ {
+ q = q - server_line_bytes;
+ for (k = 0; k < width; k++)
+ {
+ pixel = *((int*)(q + k * 4));
+ out_uint32_le(s, pixel);
+ }
+ out_uint8s(s, e * 4);
+ }
+ break;
}
s_mark_end(s);
@@ -971,7 +1071,7 @@ libxrdp_reset(struct xrdp_session *session,
}
/* shut down the rdp client */
- if (xrdp_rdp_send_deactive((struct xrdp_rdp *)session->rdp) != 0)
+ if (xrdp_rdp_send_deactivate((struct xrdp_rdp *)session->rdp) != 0)
{
return 1;
}
@@ -982,14 +1082,6 @@ libxrdp_reset(struct xrdp_session *session,
return 1;
}
- /* process till up and running */
- session->up_and_running = 0;
-
- if (libxrdp_process_data(session, 0) != 0)
- {
- g_writeln("non handled error from libxrdp_process_data");
- }
-
return 0;
}
@@ -1082,10 +1174,10 @@ libxrdp_query_channel(struct xrdp_session *session, int index,
}
/*****************************************************************************/
-/* returns a zero based index of the channel, -1 if error or it dosen't
+/* returns a zero based index of the channel, -1 if error or it doesn't
exist */
int EXPORT_CC
-libxrdp_get_channel_id(struct xrdp_session *session, char *name)
+libxrdp_get_channel_id(struct xrdp_session *session, const char *name)
{
int index = 0;
int count = 0;
@@ -1306,13 +1398,12 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
struct stream ls;
struct stream *s;
struct xrdp_rdp *rdp;
- int rv;
int sec_bytes;
int rdp_bytes;
int max_bytes;
int cmd_bytes;
- LLOGLN(10, ("libxrdp_fastpath_init:"));
+ LLOGLN(10, ("libxrdp_fastpath_send_surface:"));
if ((session->client_info->use_fast_path & 1) == 0)
{
return 1;
@@ -1341,13 +1432,13 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
s->rdp_hdr = s->sec_hdr + sec_bytes;
s->end = data_pad + pad_bytes + data_bytes;
s->p = s->data + (rdp_bytes + sec_bytes);
- /* TS_SURFCMD_SET_SURF_BITS */
- out_uint16_le(s, 0x0001); /* CMDTYPE_SET_SURFACE_BITS */
+ /* TS_SURFCMD_STREAM_SURF_BITS */
+ out_uint16_le(s, CMDTYPE_STREAM_SURFACE_BITS);
out_uint16_le(s, destLeft);
out_uint16_le(s, destTop);
out_uint16_le(s, destRight);
out_uint16_le(s, destBottom);
- /* TS_ BITMAP_DATA_EX */
+ /* TS_BITMAP_DATA_EX */
out_uint8(s, bpp);
out_uint8(s, 0);
out_uint8(s, 0);
@@ -1362,3 +1453,40 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
}
return 0;
}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_fastpath_send_frame_marker(struct xrdp_session *session,
+ int frame_action, int frame_id)
+{
+ struct stream *s;
+ struct xrdp_rdp *rdp;
+
+ LLOGLN(10, ("libxrdp_fastpath_send_frame_marker:"));
+ if ((session->client_info->use_fast_path & 1) == 0)
+ {
+ return 1;
+ }
+ if (session->client_info->use_frame_acks == 0)
+ {
+ return 1;
+ }
+ rdp = (struct xrdp_rdp *) (session->rdp);
+ make_stream(s);
+ init_stream(s, 8192);
+ xrdp_rdp_init_fastpath(rdp, s);
+ out_uint16_le(s, 0x0004); /* CMDTYPE_FRAME_MARKER */
+ out_uint16_le(s, frame_action);
+ out_uint32_le(s, frame_id);
+ s_mark_end(s);
+ /* 4 = FASTPATH_UPDATETYPE_SURFCMDS */
+ if (xrdp_rdp_send_fastpath(rdp, s, 4) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ free_stream(s);
+ return 0;
+
+}
+
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index 5f60183d..857abc99 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -281,7 +281,7 @@ struct xrdp_mppc_enc
char *outputBuffer; /* contains compressed data */
char *outputBufferPlus;
int historyOffset; /* next free slot in historyBuffer */
- int buf_len; /* length of historyBuffer, protocol dependant */
+ int buf_len; /* length of historyBuffer, protocol dependent */
int bytes_in_opb; /* compressed bytes available in outputBuffer */
int flags; /* PACKET_COMPRESSED, PACKET_AT_FRONT, PACKET_FLUSHED etc */
int flagsHold;
@@ -401,7 +401,7 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s);
int APP_CC
xrdp_rdp_disconnect(struct xrdp_rdp *self);
int APP_CC
-xrdp_rdp_send_deactive(struct xrdp_rdp *self);
+xrdp_rdp_send_deactivate(struct xrdp_rdp *self);
/* xrdp_orders.c */
struct xrdp_orders * APP_CC
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index 2262f66f..275b674a 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -27,8 +27,8 @@
struct xrdp_brush
{
- int x_orgin;
- int y_orgin;
+ int x_origin;
+ int y_origin;
int style;
char pattern[8];
};
@@ -72,6 +72,8 @@ struct xrdp_session
int up_and_running;
int (*is_term)(void);
int in_process_data; /* inc / dec libxrdp_process_data calls */
+
+ struct source_info si;
};
struct xrdp_session * DEFAULT_CC
@@ -81,7 +83,7 @@ libxrdp_exit(struct xrdp_session *session);
int DEFAULT_CC
libxrdp_disconnect(struct xrdp_session *session);
int DEFAULT_CC
-libxrdp_process_incomming(struct xrdp_session *session);
+libxrdp_process_incoming(struct xrdp_session *session);
int EXPORT_CC
libxrdp_get_pdu_bytes(const char *aheader);
struct stream * APP_CC
@@ -187,7 +189,7 @@ int DEFAULT_CC
libxrdp_query_channel(struct xrdp_session *session, int index,
char *channel_name, int *channel_flags);
int DEFAULT_CC
-libxrdp_get_channel_id(struct xrdp_session *session, char *name);
+libxrdp_get_channel_id(struct xrdp_session *session, const char *name);
int DEFAULT_CC
libxrdp_send_to_channel(struct xrdp_session *session, int channel_id,
char *data, int data_len,
@@ -242,5 +244,8 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
int destLeft, int dst_Top,
int destRight, int destBottom, int bpp,
int codecID, int width, int height);
+int EXPORT_CC
+libxrdp_fastpath_send_frame_marker(struct xrdp_session *session,
+ int frame_action, int frame_id);
#endif
diff --git a/libxrdp/xrdp_bitmap32_compress.c b/libxrdp/xrdp_bitmap32_compress.c
index 083c4409..daec9f28 100644
--- a/libxrdp/xrdp_bitmap32_compress.c
+++ b/libxrdp/xrdp_bitmap32_compress.c
@@ -107,7 +107,7 @@ fsplit3(char *in_data, int start_line, int width, int e,
}
start_line--;
cy++;
- if (out_index > 64 * 64)
+ if (out_index + width + e > 64 * 64)
{
break;
}
@@ -195,7 +195,7 @@ fsplit4(char *in_data, int start_line, int width, int e,
}
start_line--;
cy++;
- if (out_index > 64 * 64)
+ if (out_index + width + e > 64 * 64)
{
break;
}
@@ -422,6 +422,7 @@ xrdp_bitmap32_compress(char *in_data, int width, int height,
char *sr_data;
char *sg_data;
char *sb_data;
+ char *hold_p;
int a_bytes;
int r_bytes;
int g_bytes;
@@ -449,6 +450,7 @@ xrdp_bitmap32_compress(char *in_data, int width, int height,
r_data = a_data + max_bytes;
g_data = r_data + max_bytes;
b_data = g_data + max_bytes;
+ hold_p = s->p;
if (header & FLAGS_NOALPHA)
{
@@ -459,35 +461,44 @@ xrdp_bitmap32_compress(char *in_data, int width, int height,
fdelta(sr_data, r_data, cx, cy);
fdelta(sg_data, g_data, cx, cy);
fdelta(sb_data, b_data, cx, cy);
- out_uint8(s, header);
- r_bytes = fpack(r_data, cx, cy, s);
- g_bytes = fpack(g_data, cx, cy, s);
- b_bytes = fpack(b_data, cx, cy, s);
- total_bytes = r_bytes + g_bytes + b_bytes;
- if (1 + total_bytes > byte_limit)
+ while (cy > 0)
{
- /* failed */
- LLOGLN(0, ("xrdp_bitmap32_compress: too big, rgb "
- "bytes %d %d %d total_bytes %d cx %d cy %d "
- "byte_limit %d", r_bytes, g_bytes, b_bytes,
- total_bytes, cx, cy, byte_limit));
- return 0;
- }
- max_bytes = cx * cy * 3;
- if (total_bytes > max_bytes)
- {
- /* raw is better */
- LLOGLN(10, ("xrdp_bitmap32_compress: too big, rgb "
- "bytes %d %d %d total_bytes %d cx %d cy %d "
- "max_bytes %d", r_bytes, g_bytes, b_bytes,
- total_bytes, cx, cy, max_bytes));
- init_stream(s, 0);
- foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
+ s->p = hold_p;
+ out_uint8(s, header);
+ r_bytes = fpack(r_data, cx, cy, s);
+ g_bytes = fpack(g_data, cx, cy, s);
+ b_bytes = fpack(b_data, cx, cy, s);
+ max_bytes = cx * cy * 3;
+ total_bytes = r_bytes + g_bytes + b_bytes;
+ if (total_bytes > max_bytes)
+ {
+ if (2 + max_bytes <= byte_limit)
+ {
+ s->p = hold_p;
+ foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
+ break;
+ }
+ }
+ if (1 + total_bytes <= byte_limit)
+ {
+ break;
+ }
+ cy--;
}
}
else
{
- foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
+ while (cy > 0)
+ {
+ max_bytes = cx * cy * 3;
+ if (2 + max_bytes <= byte_limit)
+ {
+ s->p = hold_p;
+ foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
+ break;
+ }
+ cy--;
+ }
}
}
else
@@ -500,36 +511,45 @@ xrdp_bitmap32_compress(char *in_data, int width, int height,
fdelta(sr_data, r_data, cx, cy);
fdelta(sg_data, g_data, cx, cy);
fdelta(sb_data, b_data, cx, cy);
- out_uint8(s, header);
- a_bytes = fpack(a_data, cx, cy, s);
- r_bytes = fpack(r_data, cx, cy, s);
- g_bytes = fpack(g_data, cx, cy, s);
- b_bytes = fpack(b_data, cx, cy, s);
- max_bytes = cx * cy * 4;
- total_bytes = a_bytes + r_bytes + g_bytes + b_bytes;
- if (1 + total_bytes > byte_limit)
+ while (cy > 0)
{
- /* failed */
- LLOGLN(0, ("xrdp_bitmap32_compress: too big, argb "
- "bytes %d %d %d %d total_bytes %d cx %d cy %d "
- "byte_limit %d", a_bytes, r_bytes, g_bytes, b_bytes,
- total_bytes, cx, cy, byte_limit));
- return 0;
- }
- if (total_bytes > max_bytes)
- {
- /* raw is better */
- LLOGLN(10, ("xrdp_bitmap32_compress: too big, argb "
- "bytes %d %d %d %d total_bytes %d cx %d cy %d "
- "max_bytes %d", a_bytes, r_bytes, g_bytes, b_bytes,
- total_bytes, cx, cy, max_bytes));
- init_stream(s, 0);
- foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
+ s->p = hold_p;
+ out_uint8(s, header);
+ a_bytes = fpack(a_data, cx, cy, s);
+ r_bytes = fpack(r_data, cx, cy, s);
+ g_bytes = fpack(g_data, cx, cy, s);
+ b_bytes = fpack(b_data, cx, cy, s);
+ max_bytes = cx * cy * 4;
+ total_bytes = a_bytes + r_bytes + g_bytes + b_bytes;
+ if (total_bytes > max_bytes)
+ {
+ if (2 + max_bytes <= byte_limit)
+ {
+ s->p = hold_p;
+ foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
+ break;
+ }
+ }
+ if (1 + total_bytes <= byte_limit)
+ {
+ break;
+ }
+ cy--;
}
}
else
{
- foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
+ while (cy > 0)
+ {
+ max_bytes = cx * cy * 4;
+ if (2 + max_bytes <= byte_limit)
+ {
+ s->p = hold_p;
+ foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
+ break;
+ }
+ cy--;
+ }
}
}
return cy;
diff --git a/libxrdp/xrdp_bitmap_compress.c b/libxrdp/xrdp_bitmap_compress.c
index 03c56f10..56898776 100644
--- a/libxrdp/xrdp_bitmap_compress.c
+++ b/libxrdp/xrdp_bitmap_compress.c
@@ -22,6 +22,8 @@
#include "libxrdp.h"
+#define BC_MAX_BYTES (16 * 1024)
+
/*****************************************************************************/
#define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
do { \
@@ -695,7 +697,7 @@ xrdp_bitmap_compress(char *in_data, int width, int height,
out_count = end;
line = in_data + width * start_line;
- while (start_line >= 0 && out_count < 32768)
+ while (start_line >= 0 && out_count <= BC_MAX_BYTES)
{
i = (s->p - s->data) + count;
@@ -987,7 +989,7 @@ xrdp_bitmap_compress(char *in_data, int width, int height,
out_count = end * 2;
line = in_data + width * start_line * 2;
- while (start_line >= 0 && out_count < 32768)
+ while (start_line >= 0 && out_count <= BC_MAX_BYTES)
{
i = (s->p - s->data) + count * 2;
@@ -1279,7 +1281,7 @@ xrdp_bitmap_compress(char *in_data, int width, int height,
out_count = end * 3;
line = in_data + width * start_line * 4;
- while (start_line >= 0 && out_count < 32768)
+ while (start_line >= 0 && out_count <= BC_MAX_BYTES)
{
i = (s->p - s->data) + count * 3;
diff --git a/libxrdp/xrdp_caps.c b/libxrdp/xrdp_caps.c
index a5883a01..ec971648 100644
--- a/libxrdp/xrdp_caps.c
+++ b/libxrdp/xrdp_caps.c
@@ -74,8 +74,13 @@ xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s,
g_writeln("xrdp_caps_process_general: error");
return 1;
}
- in_uint8s(s, 10);
- in_uint16_le(s, extraFlags);
+
+ in_uint16_le(s, self->client_info.client_os_major); /* osMajorType (2 bytes) */
+ in_uint16_le(s, self->client_info.client_os_minor); /* osMinorType (2 bytes) */
+ in_uint8s(s, 6);
+ in_uint16_le(s, extraFlags); /* extraFlags (2 bytes) */
+
+ self->client_info.op1 = extraFlags & NO_BITMAP_COMPRESSION_HDR;
/* use_compact_packets is pretty much 'use rdp5' */
self->client_info.use_compact_packets = (extraFlags != 0);
/* op2 is a boolean to use compact bitmap headers in bitmap cache */
@@ -155,6 +160,15 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
DEBUG(("desktop cache size %d", i));
in_uint8s(s, 4); /* Unknown */
in_uint8s(s, 4); /* Unknown */
+
+ /* check if libpainter should be used for drawing, instead of orders */
+ if (!(order_caps[TS_NEG_DSTBLT_INDEX] && order_caps[TS_NEG_PATBLT_INDEX] &&
+ order_caps[TS_NEG_SCRBLT_INDEX] && order_caps[TS_NEG_MEMBLT_INDEX]))
+ {
+ g_writeln("xrdp_caps_process_order: not enough orders supported by client, using painter.");
+ self->client_info.no_orders_supported = 1;
+ }
+
return 0;
}
@@ -185,7 +199,7 @@ xrdp_caps_process_bmpcache(struct xrdp_rdp *self, struct stream *s,
i = MAX(i, 0);
self->client_info.cache2_entries = i;
in_uint16_le(s, self->client_info.cache2_size);
- /* caceh 3 */
+ /* cache 3 */
in_uint16_le(s, i);
i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
i = MAX(i, 0);
@@ -453,7 +467,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0)
{
- g_writeln("xrdp_caps_process_codecs: nscodec codec id %d prop len %d",
+ g_writeln("xrdp_caps_process_codecs: nscodec, codec id %d, properties len %d",
codec_id, codec_properties_length);
self->client_info.ns_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
@@ -462,7 +476,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
}
else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0)
{
- g_writeln("xrdp_caps_process_codecs: rfx codec id %d prop len %d",
+ g_writeln("xrdp_caps_process_codecs: RemoteFX, codec id %d, properties len %d",
codec_id, codec_properties_length);
self->client_info.rfx_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
@@ -471,7 +485,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
}
else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0)
{
- g_writeln("xrdp_caps_process_codecs: jpeg codec id %d prop len %d",
+ g_writeln("xrdp_caps_process_codecs: jpeg, codec id %d, properties len %d",
codec_id, codec_properties_length);
self->client_info.jpeg_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
@@ -486,6 +500,15 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
}
g_writeln(" jpeg quality set to %d", self->client_info.jpeg_prop[0]);
}
+ else if (g_memcmp(codec_guid, XR_CODEC_GUID_H264, 16) == 0)
+ {
+ g_writeln("xrdp_caps_process_codecs: h264, codec id %d, properties len %d",
+ codec_id, codec_properties_length);
+ self->client_info.h264_codec_id = codec_id;
+ i1 = MIN(64, codec_properties_length);
+ g_memcpy(self->client_info.h264_prop, s->p, i1);
+ self->client_info.h264_prop_len = i1;
+ }
else
{
g_writeln("xrdp_caps_process_codecs: unknown codec id %d", codec_id);
@@ -499,8 +522,8 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
/*****************************************************************************/
static int APP_CC
-xrdp_caps_process_multifragmetupdate(struct xrdp_rdp *self, struct stream *s,
- int len)
+xrdp_caps_process_multifragmentupdate(struct xrdp_rdp *self, struct stream *s,
+ int len)
{
int MaxRequestSize;
@@ -509,6 +532,29 @@ xrdp_caps_process_multifragmetupdate(struct xrdp_rdp *self, struct stream *s,
return 0;
}
+ /*****************************************************************************/
+static int APP_CC
+xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len)
+{
+ g_writeln("xrdp_caps_process_frame_ack:");
+ self->client_info.use_frame_acks = 1;
+ in_uint32_le(s, self->client_info.max_unacknowledged_frame_count);
+ g_writeln(" max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+xrdp_caps_process_surface_cmds(struct xrdp_rdp *self, struct stream *s, int len)
+{
+ int cmdFlags;
+ g_writeln("xrdp_caps_process_surface_cmds:");
+ in_uint32_le(s, cmdFlags);
+ in_uint8s(s, 4); /* reserved */
+ g_writeln(" cmdFlags 0x%08x", cmdFlags);
+ return 0;
+}
+
/*****************************************************************************/
int APP_CC
xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
@@ -530,6 +576,11 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
in_uint16_le(s, num_caps);
in_uint8s(s, 2); /* pad */
+ if ((cap_len < 0) || (cap_len > 1024 * 1024))
+ {
+ return 1;
+ }
+
for (index = 0; index < num_caps; index++)
{
p = s->p;
@@ -542,7 +593,8 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
in_uint16_le(s, len);
if ((len < 4) || !s_check_rem(s, len - 4))
{
- g_writeln("xrdp_caps_process_confirm_active: error len %d", len, s->end - s->p);
+ g_writeln("xrdp_caps_process_confirm_active: error: len %d, "
+ "remaining %d", len, (int) (s->end - s->p));
return 1;
}
len -= 4;
@@ -621,11 +673,17 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
xrdp_caps_process_window(self, s, len);
break;
case 0x001A: /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */
- xrdp_caps_process_multifragmetupdate(self, s, len);
+ xrdp_caps_process_multifragmentupdate(self, s, len);
break;
case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */
xrdp_caps_process_codecs(self, s, len);
break;
+ case 0x001E: /* CAPSSETTYPE_FRAME_ACKNOWLEDGE */
+ xrdp_caps_process_frame_ack(self, s, len);
+ break;
+ case RDP_CAPSET_SURFCMDS: /* CAPSETTYPE_SURFACE_COMMANDS */
+ xrdp_caps_process_surface_cmds(self, s, len);
+ break;
default:
g_writeln("unknown in xrdp_caps_process_confirm_active %d", type);
break;
@@ -634,6 +692,17 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
s->p = p + len + 4;
}
+ if (self->client_info.no_orders_supported &&
+ (self->client_info.offscreen_support_level != 0))
+ {
+ g_writeln("xrdp_caps_process_confirm_active: not enough orders "
+ "supported by client, client wants off screen bitmap but "
+ "offscreen bitmaps disabled");
+ self->client_info.offscreen_support_level = 0;
+ self->client_info.offscreen_cache_size = 0;
+ self->client_info.offscreen_cache_entries = 0;
+ }
+
DEBUG(("out xrdp_caps_process_confirm_active"));
return 0;
}
@@ -794,22 +863,30 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16);
out_uint8(s, 1); /* codec id, must be 1 */
- out_uint16_le(s, 3);
+ out_uint16_le(s, 3); /* codecPropertiesLength */
out_uint8(s, 0x01); /* fAllowDynamicFidelity */
out_uint8(s, 0x01); /* fAllowSubsampling */
out_uint8(s, 0x03); /* colorLossLevel */
+#if defined(XRDP_RFXCODEC) || defined(XRDP_NEUTRINORDP)
/* remotefx */
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16);
out_uint8(s, 0); /* codec id, client sets */
- out_uint16_le(s, 256);
- out_uint8s(s, 256);
+ out_uint16_le(s, 4); /* codecPropertiesLength */
+ out_uint32_le(s, 0); /* reserved */
+ /* image remotefx */
+ codec_caps_count++;
+ out_uint8a(s, XR_CODEC_GUID_IMAGE_REMOTEFX, 16);
+ out_uint8(s, 0); /* codec id, client sets */
+ out_uint16_le(s, 4); /* codecPropertiesLength */
+ out_uint32_le(s, 0); /* reserved */
+#endif
/* jpeg */
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_JPEG, 16);
out_uint8(s, 0); /* codec id, client sets */
- out_uint16_le(s, 1); /* ext length */
- out_uint8(s, 75);
+ out_uint16_le(s, 1); /* codecPropertiesLength */
+ out_uint8(s, 75); /* jpeg compression ratio */
/* calculate and set size and count */
codec_caps_size = (int)(s->p - codec_caps_size_ptr);
codec_caps_size += 2; /* 2 bytes for RDP_CAPSET_BMPCODECS above */
@@ -837,16 +914,10 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, RDP_CAPSET_INPUT); /* 13(0xd) */
out_uint16_le(s, RDP_CAPLEN_INPUT); /* 88(0x58) */
- /* INPUT_FLAG_SCANCODES 0x0001
- INPUT_FLAG_MOUSEX 0x0004
- INPUT_FLAG_FASTPATH_INPUT 0x0008
- INPUT_FLAG_FASTPATH_INPUT2 0x0020 */
- flags = 0x0001 | 0x0004;
+ flags = INPUT_FLAG_SCANCODES | INPUT_FLAG_MOUSEX | INPUT_FLAG_UNICODE;
if (self->client_info.use_fast_path & 2)
{
- /* 0x0008 INPUT_FLAG_FASTPATH_INPUT */
- /* 0x0020 INPUT_FLAG_FASTPATH_INPUT2 */
- flags |= 0x0008 | 0x0020;
+ flags |= INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2;
}
out_uint16_le(s, flags);
out_uint8s(s, 82);
@@ -872,12 +943,28 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, 5);
out_uint8(s, 0); /* client sets */
- if (self->client_info.use_fast_path & 1) /* fastpath output on */
+ if (self->client_info.use_fast_path & FASTPATH_OUTPUT_SUPPORTED) /* fastpath output on */
{
+ /* multifragment update */
caps_count++;
- out_uint16_le(s, 0x001A); /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */
- out_uint16_le(s, 8);
+ out_uint16_le(s, RDP_CAPSET_MULTIFRAGMENT); /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */
+ out_uint16_le(s, RDP_CAPLEN_MULTIFRAGMENT);
out_uint32_le(s, 3 * 1024 * 1024); /* 3MB */
+
+ /* frame acks */
+ caps_count++;
+ out_uint16_le(s, RDP_CAPSET_FRAME_ACKNOWLEDGE); /* CAPSETTYPE_FRAME_ACKNOWLEDGE */
+ out_uint16_le(s, RDP_CAPLEN_FRAME_ACKNOWLEDGE);
+ out_uint32_le(s, 2); /* 2 frames in flight */
+
+ /* surface commands */
+ caps_count++;
+ out_uint16_le(s, RDP_CAPSET_SURFCMDS); /* CAPSETTYPE_SURFACE_COMMANDS */
+ out_uint16_le(s, RDP_CAPLEN_SURFCMDS); /* lengthCapability */
+ out_uint32_le(s, (SURFCMDS_SETSURFACEBITS |
+ SURFCMDS_FRAMEMARKER |
+ SURFCMDS_STREAMSUFRACEBITS)); /* cmdFlags */
+ out_uint32_le(s, 0); /* reserved */
}
out_uint8s(s, 4); /* pad */
diff --git a/libxrdp/xrdp_channel.c b/libxrdp/xrdp_channel.c
index 7d3909d5..2da0ecdb 100644
--- a/libxrdp/xrdp_channel.c
+++ b/libxrdp/xrdp_channel.c
@@ -173,7 +173,7 @@ xrdp_channel_call_callback(struct xrdp_channel *self, struct stream *s,
/*****************************************************************************/
/* returns error */
-/* This is called from the secure layer to process an incomming non global
+/* This is called from the secure layer to process an incoming non global
channel packet.
'chanid' passed in here is the mcs channel id so it MCS_GLOBAL_CHANNEL
plus something. */
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
index 6a4eb78e..33e9c9d0 100644
--- a/libxrdp/xrdp_fastpath.c
+++ b/libxrdp/xrdp_fastpath.c
@@ -97,7 +97,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
}
/*****************************************************************************/
-/* no fragmenation */
+/* no fragmentation */
int APP_CC
xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s)
{
@@ -113,18 +113,6 @@ xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s)
}
/*****************************************************************************/
-/* no fragmenation */
-int APP_CC
-xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
-{
- if (trans_force_write_s(self->trans, s) != 0)
- {
- return 1;
- }
- return 0;
-}
-
-/*****************************************************************************/
static int APP_CC
xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg,
long param1, long param2,
@@ -145,6 +133,19 @@ xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg,
}
/*****************************************************************************/
+/* no fragmentation */
+int APP_CC
+xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
+{
+ if (trans_write_copy_s(self->trans, s) != 0)
+ {
+ return 1;
+ }
+ xrdp_fastpath_session_callback(self, 0x5556, 0, 0, 0, 0);
+ return 0;
+}
+
+/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SCANCODE */
static int APP_CC
xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self,
@@ -264,12 +265,30 @@ static int APP_CC
xrdp_fastpath_process_EVENT_UNICODE(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
- if (!s_check_rem(s, 2))
- {
- return 1;
- }
- in_uint8s(s, 2);
- return 0;
+ int flags;
+ int code;
+
+ flags = 0;
+ if (!s_check_rem(s, 2))
+ {
+ return 1;
+ }
+ in_uint16_le(s, code); /* unicode (2 byte) */
+ if (eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)
+ {
+ flags |= KBD_FLAG_UP;
+ }
+ else
+ {
+ flags |= KBD_FLAG_DOWN;
+ }
+ if (eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)
+ {
+ flags |= KBD_FLAG_EXT;
+ }
+ xrdp_fastpath_session_callback(self, RDP_INPUT_UNICODE,
+ code, 0, flags, 0);
+ return 0;
}
/*****************************************************************************/
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index 3c012b8f..b89e1616 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -20,6 +20,16 @@
*/
#include "libxrdp.h"
+#include "log.h"
+
+#define LOG_LEVEL 1
+#define LLOG(_level, _args) \
+ do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
+#define LHEXDUMP(_level, _args) \
+ do { if (_level < LOG_LEVEL) { g_hexdump _args ; } } while (0)
+
/*****************************************************************************/
struct xrdp_iso *
@@ -28,11 +38,11 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
{
struct xrdp_iso *self;
- DEBUG((" in xrdp_iso_create"));
+ LLOGLN(10, (" in xrdp_iso_create"));
self = (struct xrdp_iso *) g_malloc(sizeof(struct xrdp_iso), 1);
self->mcs_layer = owner;
self->trans = trans;
- DEBUG((" out xrdp_iso_create"));
+ LLOGLN(10, (" out xrdp_iso_create"));
return self;
}
@@ -54,19 +64,30 @@ static int APP_CC
xrdp_iso_negotiate_security(struct xrdp_iso *self)
{
int rv = 0;
- int server_security_layer = self->mcs_layer->sec_layer->rdp_layer->client_info.security_layer;
+ struct xrdp_client_info *client_info = &(self->mcs_layer->sec_layer->rdp_layer->client_info);
- self->selectedProtocol = server_security_layer;
+ self->selectedProtocol = client_info->security_layer;
- switch (server_security_layer)
+ switch (client_info->security_layer)
{
case PROTOCOL_RDP:
- self->rdpNegData = 0; /* no need to send rdp_neg_data back to client */
break;
case PROTOCOL_SSL:
if (self->requestedProtocol & PROTOCOL_SSL)
{
- self->selectedProtocol = PROTOCOL_SSL;
+
+ if(!g_file_exist(client_info->certificate) ||
+ !g_file_exist(client_info->key_file))
+ {
+ /* certificate file doesn't exist */
+ LLOGLN(0, ("xrdp_iso_negotiate_security: TLS certificate not found on server"));
+ self->failureCode = SSL_CERT_NOT_ON_SERVER;
+ rv = 1; /* error */
+ }
+ else
+ {
+ self->selectedProtocol = PROTOCOL_SSL;
+ }
}
else
{
@@ -77,9 +98,11 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
case PROTOCOL_HYBRID:
case PROTOCOL_HYBRID_EX:
default:
- if (self->requestedProtocol & PROTOCOL_SSL)
+ if ((self->requestedProtocol & PROTOCOL_SSL) &&
+ g_file_exist(client_info->certificate) &&
+ g_file_exist(client_info->key_file))
{
- /* thats a patch since we don't support CredSSP for now */
+ /* that's a patch since we don't support CredSSP for now */
self->selectedProtocol = PROTOCOL_SSL;
}
else
@@ -89,8 +112,8 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
break;
}
- DEBUG(("xrdp_iso_negotiate_security: server security layer %d , client security layer %d",
- self->selectedProtocol, self->requestedProtocol));
+ log_message(LOG_LEVEL_DEBUG, "Security layer: requested %d, selected %d",
+ self->requestedProtocol, self->selectedProtocol);
return rv;
}
@@ -105,22 +128,22 @@ xrdp_iso_process_rdp_neg_req(struct xrdp_iso *self, struct stream *s)
in_uint8(s, flags);
if (flags != 0x0 && flags != 0x8 && flags != 0x1)
{
- DEBUG(("xrdp_iso_process_rdpNegReq: error, flags: %x",flags));
+ LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, flags: %x",flags));
return 1;
}
in_uint16_le(s, len);
if (len != 8)
{
- DEBUG(("xrdp_iso_process_rdpNegReq: error, length: %x",len));
+ LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, length: %x",len));
return 1;
}
in_uint32_le(s, self->requestedProtocol);
if (self->requestedProtocol > 0xb)
{
- DEBUG(("xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x",
- self->requestedProtocol));
+ LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x",
+ self->requestedProtocol));
return 1;
}
@@ -139,15 +162,15 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
if (s != self->trans->in_s)
{
- g_writeln("xrdp_iso_recv_msg error logic");
+ LLOGLN(10, ("xrdp_iso_recv_msg error logic"));
}
in_uint8(s, ver);
if (ver != 3)
{
- g_writeln("xrdp_iso_recv_msg: bad ver");
- g_hexdump(s->data, 4);
+ LLOGLN(10, ("xrdp_iso_recv_msg: bad ver"));
+ LHEXDUMP(10, (s->data, 4));
return 1;
}
@@ -195,21 +218,21 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
int code;
int len;
- DEBUG((" in xrdp_iso_recv"));
+ LLOGLN(10, (" in xrdp_iso_recv"));
if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
{
- DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero"));
+ LLOGLN(10, (" out xrdp_iso_recv xrdp_iso_recv_msg return non zero"));
return 1;
}
if (code != ISO_PDU_DT || len != 2)
{
- DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2"));
+ LLOGLN(10, (" out xrdp_iso_recv code != ISO_PDU_DT or length != 2"));
return 1;
}
- DEBUG((" out xrdp_iso_recv"));
+ LLOGLN(10, (" out xrdp_iso_recv"));
return 0;
}
/*****************************************************************************/
@@ -266,7 +289,7 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
len_ptr[1] = len;
len_indicator_ptr[0] = len_indicator;
- if (trans_force_write_s(self->trans, s) != 0)
+ if (trans_write_copy_s(self->trans, s) != 0)
{
free_stream(s);
return 1;
@@ -289,7 +312,7 @@ xrdp_iso_incoming(struct xrdp_iso *self)
char *pend;
struct stream *s;
- DEBUG((" in xrdp_iso_incoming"));
+ LLOGLN(10, (" in xrdp_iso_incoming"));
s = libxrdp_force_read(self->trans);
if (s == 0)
@@ -299,7 +322,7 @@ xrdp_iso_incoming(struct xrdp_iso *self)
if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
{
- g_writeln("xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero");
+ LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero"));
return 1;
}
@@ -322,7 +345,7 @@ xrdp_iso_incoming(struct xrdp_iso *self)
self->rdpNegData = 1;
if (xrdp_iso_process_rdp_neg_req(self, s) != 0)
{
- g_writeln("xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero");
+ LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero"));
return 1;
}
break;
@@ -335,11 +358,18 @@ xrdp_iso_incoming(struct xrdp_iso *self)
{
text[cookie_index] = cc_type;
cookie_index++;
+ if (cookie_index > 255)
+ {
+ cookie_index = 255;
+ }
if ((s->p[0] == 0x0D) && (s->p[1] == 0x0A))
{
in_uint8s(s, 2);
text[cookie_index] = 0;
cookie_index = 0;
+ if (g_strlen(text) > 0)
+ {
+ }
break;
}
in_uint8(s, cc_type);
@@ -354,11 +384,11 @@ xrdp_iso_incoming(struct xrdp_iso *self)
/* send connection confirm back to client */
if (xrdp_iso_send_cc(self) != 0)
{
- g_writeln("xrdp_iso_incoming: xrdp_iso_send_cc returned non zero");
+ LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_send_cc returned non zero"));
return 1;
}
- DEBUG((" out xrdp_iso_incoming"));
+ LLOGLN(10, (" out xrdp_iso_incoming"));
return rv;
}
@@ -379,7 +409,7 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
{
int len;
- DEBUG((" in xrdp_iso_send"));
+ LLOGLN(10, (" in xrdp_iso_send"));
s_pop_layer(s, iso_hdr);
len = (int) (s->end - s->p);
out_uint8(s, 3);
@@ -389,11 +419,11 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
out_uint8(s, ISO_PDU_DT);
out_uint8(s, 0x80);
- if (trans_force_write_s(self->trans, s) != 0)
+ if (trans_write_copy_s(self->trans, s) != 0)
{
return 1;
}
- DEBUG((" out xrdp_iso_send"));
+ LLOGLN(10, (" out xrdp_iso_send"));
return 0;
}
diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c
index e4ce64fe..755c20bd 100644
--- a/libxrdp/xrdp_jpeg_compress.c
+++ b/libxrdp/xrdp_jpeg_compress.c
@@ -160,12 +160,12 @@ xrdp_codec_jpeg_compress(void *handle,
* TJPF_ARGB no works, zero bytes */
error = tjCompress(tj_han, /* opaque handle */
- src_ptr, /* source buf */
+ (unsigned char *) src_ptr, /* source buf */
cx, /* width of area to compress */
stride, /* pitch */
cy, /* height of area to compress */
TJPF_XBGR, /* pixel size */
- out_data, /* dest buf */
+ (unsigned char *) out_data, /* dest buf */
&lio_len, /* inner_buf length & compressed_size */
TJSAMP_420, /* jpeg sub sample */
quality, /* jpeg quality */
@@ -213,14 +213,14 @@ xrdp_jpeg_deinit(void *handle)
struct mydata_comp
{
- char *cb;
+ JOCTET *cb;
int cb_bytes;
int total_done;
int overwrite;
};
/*****************************************************************************/
-/* called at begining */
+/* called at beginning */
static void DEFAULT_CC
my_init_destination(j_compress_ptr cinfo)
{
@@ -265,8 +265,8 @@ my_term_destination(j_compress_ptr cinfo)
/*****************************************************************************/
static int APP_CC
-jp_do_compress(char *data, int width, int height, int bpp, int quality,
- char *comp_data, int *comp_data_bytes)
+jp_do_compress(JOCTET *data, int width, int height, int bpp, int quality,
+ JOCTET *comp_data, int *comp_data_bytes)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
@@ -336,9 +336,8 @@ jpeg_compress(char *in_data, int width, int height,
struct stream *s, struct stream *temp_s, int bpp,
int byte_limit, int e, int quality)
{
- char *data;
+ JOCTET *data;
tui32 *src32;
- tui16 *src16;
tui8 *dst8;
tui32 pixel;
int red;
@@ -348,7 +347,7 @@ jpeg_compress(char *in_data, int width, int height,
int i;
int cdata_bytes;
- data = temp_s->data;
+ data = (JOCTET *) temp_s->data;
dst8 = data;
if (bpp == 24)
@@ -366,11 +365,14 @@ jpeg_compress(char *in_data, int width, int height,
*(dst8++) = red;
}
- for (i = 0; i < e; i++)
+ if (width > 0)
{
- *(dst8++) = blue;
- *(dst8++) = green;
- *(dst8++) = red;
+ for (i = 0; i < e; i++)
+ {
+ *(dst8++) = blue;
+ *(dst8++) = green;
+ *(dst8++) = red;
+ }
}
}
}
@@ -380,7 +382,8 @@ jpeg_compress(char *in_data, int width, int height,
}
cdata_bytes = byte_limit;
- jp_do_compress(data, width + e, height, 24, quality, s->p, &cdata_bytes);
+ jp_do_compress(data, width + e, height, 24, quality, (JOCTET *) s->p,
+ &cdata_bytes);
s->p += cdata_bytes;
return cdata_bytes;
}
diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c
index 0ff57b0c..8ed821e9 100644
--- a/libxrdp/xrdp_mcs.c
+++ b/libxrdp/xrdp_mcs.c
@@ -183,7 +183,7 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
}
else
{
- log_message(LOG_LEVEL_DEBUG,"Recieved an unhandled appid:%d",appid);
+ log_message(LOG_LEVEL_DEBUG,"Received an unhandled appid:%d",appid);
}
break;
@@ -761,7 +761,7 @@ xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
out_uint8(s, 0);
if (self->mcs_layer->iso_layer->rdpNegData)
{
- /* ReqeustedProtocol */
+ /* RequestedProtocol */
out_uint32_le(s, self->mcs_layer->iso_layer->requestedProtocol);
}
out_uint16_le(s, SEC_TAG_SRV_CHANNELS);
@@ -1023,7 +1023,7 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
if (len > 8192 * 2)
{
- g_writeln("error in xrdp_mcs_send, size too big, its %d", len);
+ g_writeln("error in xrdp_mcs_send, size too big: %d bytes", len);
}
//if (len > max_len)
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 7d969514..b0c28ed8 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -236,7 +236,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
size = (int)(self->out_s->p - self->order_count_ptr);
if (size < 0)
{
- g_writeln("error in xrdp_orders_check, size too small, its %d", size);
+ g_writeln("error in xrdp_orders_check, size too small: %d bytes", size);
return 1;
}
if (size > max_packet_size)
@@ -244,7 +244,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
/* this suggests someone calls this function without passing the
correct max_size so we end up putting more into the buffer
than we indicate we can */
- g_writeln("error in xrdp_orders_check, size too big, its %d", size);
+ g_writeln("error in xrdp_orders_check, size too big: %d bytes", size);
/* We where getting called with size already greater than
max_packet_size
Which I suspect was because the sending of text did not include
@@ -286,7 +286,7 @@ xrdp_orders_last_bounds(struct xrdp_orders *self, struct xrdp_rect *rect)
}
/*****************************************************************************/
-/* check if all coords are withing 256 bytes */
+/* check if all coords are within 256 bytes */
/* returns boolean */
static int APP_CC
xrdp_orders_send_delta(struct xrdp_orders *self, int *vals, int count)
@@ -507,7 +507,7 @@ xrdp_orders_rect(struct xrdp_orders *self, int x, int y, int cx, int cy,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -678,7 +678,7 @@ xrdp_orders_screen_blt(struct xrdp_orders *self, int x, int y,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -870,7 +870,7 @@ xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -1014,18 +1014,18 @@ xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y,
brush = &blank_brush;
}
- if (brush->x_orgin != self->orders_state.pat_blt_brush.x_orgin)
+ if (brush->x_origin != self->orders_state.pat_blt_brush.x_origin)
{
present |= 0x0080;
- out_uint8(self->out_s, brush->x_orgin);
- self->orders_state.pat_blt_brush.x_orgin = brush->x_orgin;
+ out_uint8(self->out_s, brush->x_origin);
+ self->orders_state.pat_blt_brush.x_origin = brush->x_origin;
}
- if (brush->y_orgin != self->orders_state.pat_blt_brush.y_orgin)
+ if (brush->y_origin != self->orders_state.pat_blt_brush.y_origin)
{
present |= 0x0100;
- out_uint8(self->out_s, brush->y_orgin);
- self->orders_state.pat_blt_brush.y_orgin = brush->y_orgin;
+ out_uint8(self->out_s, brush->y_origin);
+ self->orders_state.pat_blt_brush.y_origin = brush->y_origin;
}
if (brush->style != self->orders_state.pat_blt_brush.style)
@@ -1087,7 +1087,7 @@ xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -1258,7 +1258,7 @@ xrdp_orders_line(struct xrdp_orders *self, int mix_mode,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (MIN(endx, startx) < rect->left ||
MIN(endy, starty) < rect->top ||
MAX(endx, startx) >= rect->right ||
@@ -1460,7 +1460,7 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -1667,7 +1667,7 @@ xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat,
self->orders_state.last_order = RDP_ORDER_COMPOSITE;
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (dstx < rect->left || dsty < rect->top ||
dstx + width > rect->right || dsty + height > rect->bottom)
{
@@ -1999,7 +1999,7 @@ xrdp_orders_text(struct xrdp_orders *self,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if ((box_right - box_left > 1 &&
(box_left < rect->left ||
box_top < rect->top ||
@@ -2235,6 +2235,11 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders *self,
Bpp = (bpp + 7) / 8;
bufsize = (width + e) * height * Bpp;
+ while (bufsize + 16 > MAX_ORDERS_SIZE)
+ {
+ height--;
+ bufsize = (width + e) * height * Bpp;
+ }
if (xrdp_orders_check(self, bufsize + 16) != 0)
{
return 1;
@@ -2254,33 +2259,58 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders *self,
out_uint16_le(self->out_s, bufsize);
out_uint16_le(self->out_s, cache_idx);
- for (i = height - 1; i >= 0; i--)
+ if (Bpp == 4)
{
- for (j = 0; j < width; j++)
+ for (i = height - 1; i >= 0; i--)
{
- if (Bpp == 3)
+ for (j = 0; j < width; j++)
{
pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
+ out_uint8(self->out_s, pixel >> 24);
}
- else if (Bpp == 2)
+ out_uint8s(self->out_s, Bpp * e);
+ }
+ }
+ else if (Bpp == 3)
+ {
+ for (i = height - 1; i >= 0; i--)
+ {
+ for (j = 0; j < width; j++)
{
- pixel = GETPIXEL16(data, j, i, width);
+ pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
+ out_uint8(self->out_s, pixel >> 16);
}
- else if (Bpp == 1)
+ out_uint8s(self->out_s, Bpp * e);
+ }
+ }
+ else if (Bpp == 2)
+ {
+ for (i = height - 1; i >= 0; i--)
+ {
+ for (j = 0; j < width; j++)
{
- pixel = GETPIXEL8(data, j, i, width);
+ pixel = GETPIXEL16(data, j, i, width);
out_uint8(self->out_s, pixel);
+ out_uint8(self->out_s, pixel >> 8);
}
+ out_uint8s(self->out_s, Bpp * e);
}
-
- for (j = 0; j < e; j++)
+ }
+ else if (Bpp == 1)
+ {
+ for (i = height - 1; i >= 0; i--)
{
- out_uint8s(self->out_s, Bpp);
+ for (j = 0; j < width; j++)
+ {
+ pixel = GETPIXEL8(data, j, i, width);
+ out_uint8(self->out_s, pixel);
+ }
+ out_uint8s(self->out_s, Bpp * e);
}
}
@@ -2334,20 +2364,19 @@ xrdp_orders_send_bitmap(struct xrdp_orders *self,
if (bpp > 24)
{
lines_sending = xrdp_bitmap32_compress(data, width, height, s,
- bpp, 16384,
+ bpp, MAX_ORDERS_SIZE,
i - 1, temp_s, e, 0x10);
}
else
{
- lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
+ lines_sending = xrdp_bitmap_compress(data, width, height, s,
+ bpp, MAX_ORDERS_SIZE,
i - 1, temp_s, e);
}
if (lines_sending != height)
{
- g_writeln("error in xrdp_orders_send_bitmap, lines_sending(%d) != \
-height(%d)", lines_sending, height);
- return 1;
+ height = lines_sending;
}
bufsize = (int)(s->p - p);
@@ -2458,6 +2487,7 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
int pixel = 0;
int e = 0;
+ g_writeln("xrdp_orders_send_raw_bitmap2:");
if (width > 64)
{
g_writeln("error, width > 64");
@@ -2479,6 +2509,11 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
Bpp = (bpp + 7) / 8;
bufsize = (width + e) * height * Bpp;
+ while (bufsize + 14 > MAX_ORDERS_SIZE)
+ {
+ height--;
+ bufsize = (width + e) * height * Bpp;
+ }
if (xrdp_orders_check(self, bufsize + 14) != 0)
{
return 1;
@@ -2499,7 +2534,7 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
i = cache_idx & 0xff;
out_uint8(self->out_s, i);
- if (1 && Bpp == 3)
+ if (Bpp == 4)
{
for (i = height - 1; i >= 0; i--)
{
@@ -2509,45 +2544,50 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
+ out_uint8(self->out_s, pixel >> 24);
}
- for (j = 0; j < e; j++)
- {
- out_uint8s(self->out_s, Bpp);
- }
+ out_uint8s(self->out_s, Bpp * e);
}
}
- else
- {
- for (i = height - 1; i >= 0; i--)
+ else if (Bpp == 3)
{
- for (j = 0; j < width; j++)
+ for (i = height - 1; i >= 0; i--)
{
- if (Bpp == 3)
+ for (j = 0; j < width; j++)
{
pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
}
- else if (Bpp == 2)
+ out_uint8s(self->out_s, Bpp * e);
+ }
+ }
+ else if (Bpp == 2)
+ {
+ for (i = height - 1; i >= 0; i--)
+ {
+ for (j = 0; j < width; j++)
{
pixel = GETPIXEL16(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
}
- else if (Bpp == 1)
+ out_uint8s(self->out_s, Bpp * e);
+ }
+ }
+ else if (Bpp == 1)
+ {
+ for (i = height - 1; i >= 0; i--)
+ {
+ for (j = 0; j < width; j++)
{
pixel = GETPIXEL8(data, j, i, width);
out_uint8(self->out_s, pixel);
}
- }
-
- for (j = 0; j < e; j++)
- {
- out_uint8s(self->out_s, Bpp);
+ out_uint8s(self->out_s, Bpp * e);
}
}
- }
return 0;
}
@@ -2599,20 +2639,19 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
if (bpp > 24)
{
lines_sending = xrdp_bitmap32_compress(data, width, height, s,
- bpp, 16384,
+ bpp, MAX_ORDERS_SIZE,
i - 1, temp_s, e, 0x10);
}
else
{
- lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
+ lines_sending = xrdp_bitmap_compress(data, width, height, s,
+ bpp, MAX_ORDERS_SIZE,
i - 1, temp_s, e);
}
if (lines_sending != height)
{
- g_writeln("error in xrdp_orders_send_bitmap2, lines_sending(%d) != \
-height(%d)", lines_sending, height);
- return 1;
+ height = lines_sending;
}
bufsize = (int)(s->p - p);
@@ -2641,6 +2680,7 @@ height(%d)", lines_sending, height);
return 0;
}
+#if defined(XRDP_JPEG)
/*****************************************************************************/
static int
xrdp_orders_send_as_jpeg(struct xrdp_orders *self,
@@ -2663,6 +2703,7 @@ xrdp_orders_send_as_jpeg(struct xrdp_orders *self,
return 1;
}
+#endif
#if defined(XRDP_NEUTRINORDP)
/*****************************************************************************/
@@ -2693,6 +2734,7 @@ xrdp_orders_send_as_rfx(struct xrdp_orders *self,
}
#endif
+#if defined(XRDP_JPEG) || defined(XRDP_NEUTRINORDP)
/*****************************************************************************/
static int APP_CC
xrdp_orders_out_v3(struct xrdp_orders *self, int cache_id, int cache_idx,
@@ -2719,7 +2761,7 @@ xrdp_orders_out_v3(struct xrdp_orders *self, int cache_id, int cache_idx,
out_uint8(self->out_s, RDP_ORDER_BMPCACHE3); /* type */
/* cache index */
out_uint16_le(self->out_s, cache_idx);
- /* persistant cache key 1/2 */
+ /* persistent cache key 1/2 */
out_uint32_le(self->out_s, 0);
out_uint32_le(self->out_s, 0);
/* bitmap data */
@@ -2733,6 +2775,7 @@ xrdp_orders_out_v3(struct xrdp_orders *self, int cache_id, int cache_idx,
out_uint8a(self->out_s, buf, bufsize);
return 0;
}
+#endif
/*****************************************************************************/
/* secondary drawing order (bitmap v3) using remotefx compression */
@@ -2741,12 +2784,16 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx, int hints)
{
- int e;
+ struct xrdp_client_info *ci;
+#if defined(XRDP_JPEG) || defined(XRDP_NEUTRINORDP)
int bufsize;
- int quality;
struct stream *xr_s; /* xrdp stream */
+#endif
+#if defined(XRDP_JPEG)
+ int e;
+ int quality;
struct stream *temp_s; /* xrdp stream */
- struct xrdp_client_info *ci;
+#endif
#if defined(XRDP_NEUTRINORDP)
STREAM *fr_s; /* FreeRDP stream */
RFX_CONTEXT *context;
diff --git a/libxrdp/xrdp_orders_rail.c b/libxrdp/xrdp_orders_rail.c
index 91d4b607..3c5d5b63 100644
--- a/libxrdp/xrdp_orders_rail.c
+++ b/libxrdp/xrdp_orders_rail.c
@@ -333,6 +333,12 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
order_size += 8 * window_state->num_visibility_rects;
}
+ if (order_size < 12)
+ {
+ /* no flags set */
+ return 0;
+ }
+
if (xrdp_orders_check(self, order_size) != 0)
{
return 1;
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 34842533..dd6e6d38 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -98,8 +98,8 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
}
else
{
- log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is"
- "undefined 'high' will be used");
+ log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is "
+ "undefined, 'high' will be used");
client_info->crypt_level = 3;
}
}
@@ -160,6 +160,14 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
client_info->use_fast_path = 0;
}
}
+ else if (g_strcasecmp(item, "disableSSLv3") == 0)
+ {
+ client_info->disableSSLv3 = g_text2bool(value);
+ }
+ else if (g_strcasecmp(item, "tls_ciphers") == 0)
+ {
+ g_strcpy(client_info->tls_ciphers, value);
+ }
else if (g_strcasecmp(item, "security_layer") == 0)
{
if (g_strcasecmp(value, "rdp") == 0)
@@ -174,22 +182,37 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
{
client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID;
}
+ else if (g_strcasecmp(value, "negotiate") == 0)
+ {
+ client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX;
+ }
else
{
- log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured security layer is "
- "undefined, xrdp will negotiate client compatible");
+ log_message(LOG_LEVEL_ERROR, "security_layer=%s is not "
+ "recognized, will use security_layer=negotiate",
+ value);
client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX;
}
}
else if (g_strcasecmp(item, "certificate") == 0)
{
g_memset(client_info->certificate, 0, sizeof(char) * 1024);
- if (value[0] != '/')
+ if (g_strlen(value) == 0)
{
/* default certificate path */
g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH);
- log_message(LOG_LEVEL_ALWAYS,"WARNING: Invalid x.509 certificate path defined, "
- "default path will be used: %s", client_info->certificate);
+ log_message(LOG_LEVEL_INFO,
+ "Using default X.509 certificate: %s",
+ client_info->certificate);
+
+ }
+ else if (value[0] != '/')
+ {
+ /* default certificate path */
+ g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH);
+ log_message(LOG_LEVEL_WARNING,
+ "X.509 certificate should use absolute path, using "
+ "default instead: %s", client_info->certificate);
}
else
{
@@ -200,12 +223,20 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
else if (g_strcasecmp(item, "key_file") == 0)
{
g_memset(client_info->key_file, 0, sizeof(char) * 1024);
- if (value[0] != '/')
+ if (g_strlen(value) == 0)
+ {
+ /* default key_file path */
+ g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH);
+ log_message(LOG_LEVEL_INFO, "Using default X.509 key file: %s",
+ client_info->key_file);
+ }
+ else if (value[0] != '/')
{
/* default key_file path */
g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH);
- log_message(LOG_LEVEL_ALWAYS,"WARNING: Invalid x.509 certificate path defined, "
- "default path will be used: %s", client_info->key_file);
+ log_message(LOG_LEVEL_WARNING,
+ "X.509 key file should use absolute path, using "
+ "default instead: %s", client_info->key_file);
}
else
{
@@ -962,7 +993,6 @@ xrdp_rdp_process_data_sync(struct xrdp_rdp *self)
static int APP_CC
xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
{
- int op;
int left;
int top;
int right;
@@ -970,7 +1000,7 @@ xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
int cx;
int cy;
- in_uint32_le(s, op);
+ in_uint8s(s, 4); /* op */
in_uint16_le(s, left);
in_uint16_le(s, top);
in_uint16_le(s, right);
@@ -1107,20 +1137,35 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason)
#endif
/*****************************************************************************/
+static int APP_CC
+xrdp_rdp_process_frame_ack(struct xrdp_rdp *self, struct stream *s)
+{
+ int frame_id;
+
+ //g_writeln("xrdp_rdp_process_frame_ack:");
+ in_uint32_le(s, frame_id);
+ //g_writeln(" frame_id %d", frame_id);
+ if (self->session->callback != 0)
+ {
+ /* call to xrdp_wm.c : callback */
+ self->session->callback(self->session->id, 0x5557, frame_id, 0,
+ 0, 0);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
/* RDP_PDU_DATA */
int APP_CC
xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
{
- int len;
int data_type;
- int ctype;
- int clen;
in_uint8s(s, 6);
- in_uint16_le(s, len);
+ in_uint8s(s, 2); /* len */
in_uint8(s, data_type);
- in_uint8(s, ctype);
- in_uint16_le(s, clen);
+ in_uint8s(s, 1); /* ctype */
+ in_uint8s(s, 2); /* clen */
DEBUG(("xrdp_rdp_process_data code %d", data_type));
switch (data_type)
@@ -1141,7 +1186,7 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
xrdp_rdp_process_screen_update(self, s);
break;
case 35: /* 35(0x23) */
- /* 35 ?? this comes when minimuzing a full screen mstsc.exe 2600 */
+ /* 35 ?? this comes when minimizing a full screen mstsc.exe 2600 */
/* I think this is saying the client no longer wants screen */
/* updates and it will issue a 33 above to catch up */
/* so minimized apps don't take bandwidth */
@@ -1155,6 +1200,9 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
case RDP_DATA_PDU_FONT2: /* 39(0x27) */
xrdp_rdp_process_data_font(self, s);
break;
+ case 56: /* PDUTYPE2_FRAME_ACKNOWLEDGE 0x38 */
+ xrdp_rdp_process_frame_ack(self, s);
+ break;
default:
g_writeln("unknown in xrdp_rdp_process_data %d", data_type);
break;
@@ -1176,18 +1224,18 @@ xrdp_rdp_disconnect(struct xrdp_rdp *self)
/*****************************************************************************/
int APP_CC
-xrdp_rdp_send_deactive(struct xrdp_rdp *self)
+xrdp_rdp_send_deactivate(struct xrdp_rdp *self)
{
struct stream *s;
- DEBUG(("in xrdp_rdp_send_deactive"));
+ DEBUG(("in xrdp_rdp_send_deactivate"));
make_stream(s);
init_stream(s, 8192);
if (xrdp_rdp_init(self, s) != 0)
{
free_stream(s);
- DEBUG(("out xrdp_rdp_send_deactive error"));
+ DEBUG(("out xrdp_rdp_send_deactivate error"));
return 1;
}
@@ -1196,11 +1244,11 @@ xrdp_rdp_send_deactive(struct xrdp_rdp *self)
if (xrdp_rdp_send(self, s, RDP_PDU_DEACTIVATE) != 0)
{
free_stream(s);
- DEBUG(("out xrdp_rdp_send_deactive error"));
+ DEBUG(("out xrdp_rdp_send_deactivate error"));
return 1;
}
free_stream(s);
- DEBUG(("out xrdp_rdp_send_deactive"));
+ DEBUG(("out xrdp_rdp_send_deactivate"));
return 0;
}
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index 1d3b0061..06813d25 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -236,7 +236,9 @@ xrdp_load_keyboard_layout(struct xrdp_client_info *client_info)
char keyboard_cfg_file[256] = { 0 };
char rdp_layout[256] = { 0 };
- LLOGLN(0, ("xrdp_load_keyboard_layout:"));
+ LLOGLN(0, ("xrdp_load_keyboard_layout: keyboard_type [%d] keyboard_subtype [%d]",
+ client_info->keyboard_type, client_info->keyboard_subtype));
+
/* infer model/variant */
/* TODO specify different X11 keyboard models/variants */
g_memset(client_info->model, 0, sizeof(client_info->model));
@@ -338,6 +340,15 @@ xrdp_load_keyboard_layout(struct xrdp_client_info *client_info)
g_strncpy(client_info->variant, value, bytes - 1);
}
}
+ else if (g_strcasecmp(item, "options") == 0)
+ {
+ if (section_found != -1 && section_found == index)
+ {
+ bytes = sizeof(client_info->options);
+ g_memset(client_info->options, 0, bytes);
+ g_strncpy(client_info->options, value, bytes - 1);
+ }
+ }
else
{
/*
@@ -413,13 +424,13 @@ xrdp_load_keyboard_layout(struct xrdp_client_info *client_info)
list_delete(values);
LLOGLN(0, ("xrdp_load_keyboard_layout: model [%s] variant [%s] "
- "layout [%s]", client_info->model, client_info->variant,
- client_info->layout));
+ "layout [%s] options [%s]", client_info->model,
+ client_info->variant, client_info->layout, client_info->options));
g_file_close(fd);
}
else
{
- LLOGLN(0, ("xrdp_load_keyboard_layout: error opening %d",
+ LLOGLN(0, ("xrdp_load_keyboard_layout: error opening %s",
keyboard_cfg_file));
}
}
@@ -648,7 +659,6 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
int len_directory = 0;
int len_ip = 0;
int len_dll = 0;
- int tzone = 0;
char tmpdata[256];
/* initialize (zero out) local variables */
@@ -837,7 +847,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
{
return 1;
}
- in_uint32_le(s, tzone); /* len of timezone */
+ in_uint8s(s, 4); /* len of timezone */
in_uint8s(s, 62); /* skip */
in_uint8s(s, 22); /* skip misc. */
in_uint8s(s, 62); /* skip */
@@ -1814,7 +1824,6 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
{
int num_channels;
int index;
- struct mcs_channel_item *channel_item;
struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL;
client_info = &(self->rdp_layer->client_info);
@@ -1871,15 +1880,20 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
int index;
int monitorCount;
int flags;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+ int got_primary;
struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL;
client_info = &(self->rdp_layer->client_info);
- DEBUG(("processing monitors data, allow_multimon is %d", client_info->multimon));
+ LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon));
/* this is an option set in xrdp.ini */
if (client_info->multimon != 1) /* are multi-monitors allowed ? */
{
- DEBUG(("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
+ LLOGLN(0, ("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
"allowed, skipping"));
return 0;
}
@@ -1887,7 +1901,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
//verify flags - must be 0x0
if (flags != 0)
{
- DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
+ LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
"zero, detected: %d", flags));
return 1;
}
@@ -1895,15 +1909,20 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
//verify monitorCount - max 16
if (monitorCount > 16)
{
- DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
+ LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
"monitors is 16, detected: %d", monitorCount));
return 1;
}
- g_writeln("monitorCount= %d", monitorCount); // for debugging only
+ LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount));
client_info->monitorCount = monitorCount;
+ x1 = 0;
+ y1 = 0;
+ x2 = 0;
+ y2 = 0;
+ got_primary = 0;
/* Add client_monitor_data to client_info struct, will later pass to X11rdp */
for (index = 0; index < monitorCount; index++)
{
@@ -1912,10 +1931,73 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
in_uint32_le(s, client_info->minfo[index].right);
in_uint32_le(s, client_info->minfo[index].bottom);
in_uint32_le(s, client_info->minfo[index].is_primary);
+ if (index == 0)
+ {
+ x1 = client_info->minfo[index].left;
+ y1 = client_info->minfo[index].top;
+ x2 = client_info->minfo[index].right;
+ y2 = client_info->minfo[index].bottom;
+ }
+ else
+ {
+ x1 = MIN(x1, client_info->minfo[index].left);
+ y1 = MIN(y1, client_info->minfo[index].top);
+ x2 = MAX(x2, client_info->minfo[index].right);
+ y2 = MAX(y2, client_info->minfo[index].bottom);
+ }
+
+ if (client_info->minfo[index].is_primary)
+ {
+ got_primary = 1;
+ }
+
+ LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: got a monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d",
+ index,
+ client_info->minfo[index].left,
+ client_info->minfo[index].top,
+ client_info->minfo[index].right,
+ client_info->minfo[index].bottom,
+ client_info->minfo[index].is_primary));
+ }
+
+ if (!got_primary)
+ {
+ /* no primary monitor was set, choose the leftmost monitor as primary */
+ for (index = 0; index < monitorCount; index++)
+ {
+ if (client_info->minfo[index].left == x1 &&
+ client_info->minfo[index].top == y1)
+ {
+ client_info->minfo[index].is_primary = 1;
+ break;
+ }
+ }
+ }
+
+ /* set wm geometry */
+ if ((x2 > x1) && (y2 > y1))
+ {
+ client_info->width = (x2 - x1) + 1;
+ client_info->height = (y2 - y1) + 1;
+ }
+ /* make sure virtual desktop size is ok */
+ if (client_info->width > 0x7FFE || client_info->width < 0xC8 ||
+ client_info->height > 0x7FFE || client_info->height < 0xC8)
+ {
+ LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: error, virtual desktop width / height is too large"));
+ return 1; /* error */
+ }
- g_writeln("got a monitor: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d", client_info->minfo[index].left,
- client_info->minfo[index].top, client_info->minfo[index].right, client_info->minfo[index].bottom, client_info->minfo[index].is_primary);
+ /* keep a copy of non negative monitor info values for xrdp_wm usage */
+ for (index = 0; index < monitorCount; index++)
+ {
+ client_info->minfo_wm[index].left = client_info->minfo[index].left - x1;
+ client_info->minfo_wm[index].top = client_info->minfo[index].top - y1;
+ client_info->minfo_wm[index].right = client_info->minfo[index].right - x1;
+ client_info->minfo_wm[index].bottom = client_info->minfo[index].bottom - y1;
+ client_info->minfo_wm[index].is_primary = client_info->minfo[index].is_primary;
}
+
return 0;
}
@@ -2030,7 +2112,7 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
client_info = &(self->rdp_layer->client_info);
s = &(self->client_mcs_data);
- /* get hostname, its unicode */
+ /* get hostname, it's unicode */
s->p = s->data;
if (!s_check_rem(s, 47))
{
@@ -2165,7 +2247,9 @@ xrdp_sec_incoming(struct xrdp_sec *self)
if (trans_set_tls_mode(self->mcs_layer->iso_layer->trans,
self->rdp_layer->client_info.key_file,
- self->rdp_layer->client_info.certificate) != 0)
+ self->rdp_layer->client_info.certificate,
+ self->rdp_layer->client_info.disableSSLv3,
+ self->rdp_layer->client_info.tls_ciphers) != 0)
{
g_writeln("xrdp_sec_incoming: trans_set_tls_mode failed");
return 1;
@@ -2231,6 +2315,15 @@ xrdp_sec_incoming(struct xrdp_sec *self)
hex_str_to_bin(value, self->pri_exp, self->rsa_key_bytes);
}
}
+
+ if (self->rsa_key_bytes <= 64)
+ {
+ g_writeln("warning, RSA key len 512 "
+ "bits or less, consider creating a 2048 bit key");
+ log_message(LOG_LEVEL_WARNING, "warning, RSA key len 512 "
+ "bits or less, consider creating a 2048 bit key");
+ }
+
list_delete(items);
list_delete(values);
}
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644
index 00000000..94f2b516
--- /dev/null
+++ b/m4/.gitignore
@@ -0,0 +1,2 @@
+libtool.m4
+lt*.m4
diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4
new file mode 100644
index 00000000..2bb27ef2
--- /dev/null
+++ b/m4/ax_append_compile_flags.m4
@@ -0,0 +1,67 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+# For every FLAG1, FLAG2 it is checked whether the compiler works with the
+# flag. If it does, the flag is added FLAGS-VARIABLE
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. During the check the flag is always added to the
+# current language's flags.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+# NOTE: This macro depends on the AX_APPEND_FLAG and
+# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with
+# AX_APPEND_LINK_FLAGS.
+#
+# LICENSE
+#
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 5
+
+AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
+[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG])
+AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
+for flag in $1; do
+ AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4])
+done
+])dnl AX_APPEND_COMPILE_FLAGS
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
new file mode 100644
index 00000000..08f2e07e
--- /dev/null
+++ b/m4/ax_append_flag.m4
@@ -0,0 +1,71 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+# added in between.
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
+# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+# FLAG.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 6
+
+AC_DEFUN([AX_APPEND_FLAG],
+[dnl
+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
+AS_VAR_SET_IF(FLAGS,[
+ AS_CASE([" AS_VAR_GET(FLAGS) "],
+ [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
+ [
+ AS_VAR_APPEND(FLAGS,[" $1"])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+ ],
+ [
+ AS_VAR_SET(FLAGS,[$1])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4
new file mode 100644
index 00000000..1f077992
--- /dev/null
+++ b/m4/ax_cflags_warn_all.m4
@@ -0,0 +1,122 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+#
+# DESCRIPTION
+#
+# Try to find a compiler option that enables most reasonable warnings.
+#
+# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
+# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
+#
+# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
+# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
+# Intel compilers. For a given compiler, the Fortran flags are much more
+# experimental than their C equivalents.
+#
+# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
+# - $2 add-value-if-not-found : nothing
+# - $3 action-if-found : add value to shellvariable
+# - $4 action-if-not-found : nothing
+#
+# NOTE: These macros depend on AX_APPEND_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 15
+
+AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
+AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
+AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
+AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
+VAR,[VAR="no, unknown"
+ac_save_[]FLAGS="$[]FLAGS"
+for ac_arg dnl
+in "-warn all % -warn all" dnl Intel
+ "-pedantic % -Wall" dnl GCC
+ "-xstrconst % -v" dnl Solaris C
+ "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
+ "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
+ "-ansi -ansiE % -fullwarn" dnl IRIX
+ "+ESlit % +w1" dnl HP-UX C
+ "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
+ "-h conform % -h msglevel 2" dnl Cray C (Unicos)
+ #
+do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
+done
+FLAGS="$ac_save_[]FLAGS"
+])
+AS_VAR_POPDEF([FLAGS])dnl
+AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
+case ".$VAR" in
+ .ok|.ok,*) m4_ifvaln($3,$3) ;;
+ .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
+ *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
+esac
+AS_VAR_POPDEF([VAR])dnl
+])dnl AX_FLAGS_WARN_ALL
+dnl implementation tactics:
+dnl the for-argument contains a list of options. The first part of
+dnl these does only exist to detect the compiler - usually it is
+dnl a global option to enable -ansi or -extrawarnings. All other
+dnl compilers will fail about it. That was needed since a lot of
+dnl compilers will give false positives for some option-syntax
+dnl like -Woption or -Xoption as they think of it is a pass-through
+dnl to later compile stages or something. The "%" is used as a
+dnl delimiter. A non-option comment can be given after "%%" marks
+dnl which will be shown but not added to the respective C/CXXFLAGS.
+
+AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C])
+])
+
+AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C++])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C++])
+])
+
+AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([Fortran])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([Fortran])
+])
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 00000000..ca363971
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,74 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's compiler
+# or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 4
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+ AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_VAR_IF(CACHEVAR,yes,
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/m4/ax_gcc_func_attribute.m4 b/m4/ax_gcc_func_attribute.m4
new file mode 100644
index 00000000..c788ca9b
--- /dev/null
+++ b/m4/ax_gcc_func_attribute.m4
@@ -0,0 +1,223 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
+#
+# DESCRIPTION
+#
+# This macro checks if the compiler supports one of GCC's function
+# attributes; many other compilers also provide function attributes with
+# the same syntax. Compiler warnings are used to detect supported
+# attributes as unsupported ones are ignored by default so quieting
+# warnings when using this macro will yield false positives.
+#
+# The ATTRIBUTE parameter holds the name of the attribute to be checked.
+#
+# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
+#
+# The macro caches its result in the ax_cv_have_func_attribute_<attribute>
+# variable.
+#
+# The macro currently supports the following function attributes:
+#
+# alias
+# aligned
+# alloc_size
+# always_inline
+# artificial
+# cold
+# const
+# constructor
+# constructor_priority for constructor attribute with priority
+# deprecated
+# destructor
+# dllexport
+# dllimport
+# error
+# externally_visible
+# flatten
+# format
+# format_arg
+# gnu_inline
+# hot
+# ifunc
+# leaf
+# malloc
+# noclone
+# noinline
+# nonnull
+# noreturn
+# nothrow
+# optimize
+# pure
+# unused
+# used
+# visibility
+# warning
+# warn_unused_result
+# weak
+# weakref
+#
+# Unsuppored function attributes will be tested with a prototype returning
+# an int and not accepting any arguments and the result of the check might
+# be wrong or meaningless so use with care.
+#
+# LICENSE
+#
+# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 3
+
+AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
+ AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
+
+ AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([
+ m4_case([$1],
+ [alias], [
+ int foo( void ) { return 0; }
+ int bar( void ) __attribute__(($1("foo")));
+ ],
+ [aligned], [
+ int foo( void ) __attribute__(($1(32)));
+ ],
+ [alloc_size], [
+ void *foo(int a) __attribute__(($1(1)));
+ ],
+ [always_inline], [
+ inline __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [artificial], [
+ inline __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [cold], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [const], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [constructor_priority], [
+ int foo( void ) __attribute__((__constructor__(65535/2)));
+ ],
+ [constructor], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [deprecated], [
+ int foo( void ) __attribute__(($1("")));
+ ],
+ [destructor], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [dllexport], [
+ __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [dllimport], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [error], [
+ int foo( void ) __attribute__(($1("")));
+ ],
+ [externally_visible], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [flatten], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [format], [
+ int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
+ ],
+ [format_arg], [
+ char *foo(const char *p) __attribute__(($1(1)));
+ ],
+ [gnu_inline], [
+ inline __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [hot], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [ifunc], [
+ int my_foo( void ) { return 0; }
+ static int (*resolve_foo(void))(void) { return my_foo; }
+ int foo( void ) __attribute__(($1("resolve_foo")));
+ ],
+ [leaf], [
+ __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [malloc], [
+ void *foo( void ) __attribute__(($1));
+ ],
+ [noclone], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [noinline], [
+ __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [nonnull], [
+ int foo(char *p) __attribute__(($1(1)));
+ ],
+ [noreturn], [
+ void foo( void ) __attribute__(($1));
+ ],
+ [nothrow], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [optimize], [
+ __attribute__(($1(3))) int foo( void ) { return 0; }
+ ],
+ [pure], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [unused], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [used], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [visibility], [
+ int foo_def( void ) __attribute__(($1("default")));
+ int foo_hid( void ) __attribute__(($1("hidden")));
+ int foo_int( void ) __attribute__(($1("internal")));
+ int foo_pro( void ) __attribute__(($1("protected")));
+ ],
+ [warning], [
+ int foo( void ) __attribute__(($1("")));
+ ],
+ [warn_unused_result], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [weak], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [weakref], [
+ static int foo( void ) { return 0; }
+ static int bar( void ) __attribute__(($1("foo")));
+ ],
+ [
+ m4_warn([syntax], [Unsupported attribute $1, the test may fail])
+ int foo( void ) __attribute__(($1));
+ ]
+ )], [])
+ ],
+ dnl GCC doesn't exit with an error if an unknown attribute is
+ dnl provided but only outputs a warning, so accept the attribute
+ dnl only if no warning were issued.
+ [AS_IF([test -s conftest.err],
+ [AS_VAR_SET([ac_var], [no])],
+ [AS_VAR_SET([ac_var], [yes])])],
+ [AS_VAR_SET([ac_var], [no])])
+ ])
+
+ AS_IF([test yes = AS_VAR_GET([ac_var])],
+ [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
+ [Define to 1 if the system has the `$1' function attribute])], [])
+
+ AS_VAR_POPDEF([ac_var])
+])
diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4
new file mode 100644
index 00000000..cae11112
--- /dev/null
+++ b/m4/ax_require_defined.m4
@@ -0,0 +1,37 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_REQUIRE_DEFINED(MACRO)
+#
+# DESCRIPTION
+#
+# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
+# been defined and thus are available for use. This avoids random issues
+# where a macro isn't expanded. Instead the configure script emits a
+# non-fatal:
+#
+# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
+#
+# It's like AC_REQUIRE except it doesn't expand the required macro.
+#
+# Here's an example:
+#
+# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
+#
+# LICENSE
+#
+# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 1
+
+AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
+ m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
+])dnl AX_REQUIRE_DEFINED
diff --git a/m4/ax_type_socklen_t.m4 b/m4/ax_type_socklen_t.m4
new file mode 100644
index 00000000..834c4cfa
--- /dev/null
+++ b/m4/ax_type_socklen_t.m4
@@ -0,0 +1,61 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_type_socklen_t.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_TYPE_SOCKLEN_T
+#
+# DESCRIPTION
+#
+# Check whether sys/socket.h defines type socklen_t. Please note that some
+# systems require sys/types.h to be included before sys/socket.h can be
+# compiled.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Lars Brinkhoff <lars@nocrew.org>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 5
+
+AU_ALIAS([TYPE_SOCKLEN_T], [AX_TYPE_SOCKLEN_T])
+AC_DEFUN([AX_TYPE_SOCKLEN_T],
+[AC_CACHE_CHECK([for socklen_t], ac_cv_ax_type_socklen_t,
+[
+ AC_TRY_COMPILE(
+ [#include <sys/types.h>
+ #include <sys/socket.h>],
+ [socklen_t len = 42; return 0;],
+ ac_cv_ax_type_socklen_t=yes,
+ ac_cv_ax_type_socklen_t=no)
+])
+ if test $ac_cv_ax_type_socklen_t != yes; then
+ AC_DEFINE(socklen_t, int, [Substitute for socklen_t])
+ fi
+])
diff --git a/m4/pkg.m4 b/m4/pkg.m4
new file mode 100644
index 00000000..82bea96e
--- /dev/null
+++ b/m4/pkg.m4
@@ -0,0 +1,275 @@
+dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+dnl serial 11 (pkg-config-0.29.1)
+dnl
+dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29.1])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])dnl PKG_PROG_PKG_CONFIG
+
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl have to call PKG_CHECK_EXISTS manually
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes ],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])dnl _PKG_CONFIG
+
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
+
+
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
+
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_INSTALLDIR
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_NOARCH_INSTALLDIR
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])dnl PKG_CHECK_VAR
diff --git a/mc/Makefile.am b/mc/Makefile.am
index eb000085..e705ff0d 100644
--- a/mc/Makefile.am
+++ b/mc/Makefile.am
@@ -1,18 +1,16 @@
-EXTRA_DIST = mc.h
-
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
-
-INCLUDES = \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-I$(top_srcdir)/common
-lib_LTLIBRARIES = \
+module_LTLIBRARIES = \
libmc.la
-libmc_la_SOURCES = mc.c
+libmc_la_SOURCES = \
+ mc.c \
+ mc.h
libmc_la_LIBADD = \
$(top_builddir)/common/libcommon.la
diff --git a/mc/mc.c b/mc/mc.c
index c1ec958c..3e0909d4 100644
--- a/mc/mc.c
+++ b/mc/mc.c
@@ -75,13 +75,13 @@ lib_mod_end(struct mod *mod)
/******************************************************************************/
/* return error */
int DEFAULT_CC
-lib_mod_set_param(struct mod *mod, char *name, char *value)
+lib_mod_set_param(struct mod *mod, const char *name, char *value)
{
return 0;
}
/******************************************************************************/
-struct mod *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct mod *mod;
@@ -89,20 +89,22 @@ mod_init(void)
mod = (struct mod *)g_malloc(sizeof(struct mod), 1);
mod->size = sizeof(struct mod);
mod->version = CURRENT_MOD_VER;
- mod->handle = (long)mod;
+ mod->handle = (tintptr) mod;
mod->mod_connect = lib_mod_connect;
mod->mod_start = lib_mod_start;
mod->mod_event = lib_mod_event;
mod->mod_signal = lib_mod_signal;
mod->mod_end = lib_mod_end;
mod->mod_set_param = lib_mod_set_param;
- return mod;
+ return (tintptr) mod;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct mod *mod)
+mod_exit(tintptr handle)
{
+ struct mod *mod = (struct mod *) handle;
+
if (mod == 0)
{
return 0;
diff --git a/mc/mc.h b/mc/mc.h
index 684219c7..65297942 100644
--- a/mc/mc.h
+++ b/mc/mc.h
@@ -24,7 +24,7 @@
#include "os_calls.h"
#include "defines.h"
-#define CURRENT_MOD_VER 2
+#define CURRENT_MOD_VER 3
struct mod
{
@@ -37,13 +37,13 @@ struct mod
long param3, long param4);
int (*mod_signal)(struct mod* v);
int (*mod_end)(struct mod* v);
- int (*mod_set_param)(struct mod* v, char* name, char* value);
+ int (*mod_set_param)(struct mod* v, const char *name, char* value);
int (*mod_session_change)(struct mod* v, int, int);
int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct mod* v);
- long mod_dumby[100 - 9]; /* align, 100 minus the number of mod
- functions above */
+ tintptr mod_dumby[100 - 9]; /* align, 100 minus the number of mod
+ functions above */
/* server functions */
int (*server_begin_update)(struct mod* v);
int (*server_end_update)(struct mod* v);
@@ -62,12 +62,12 @@ struct mod
int (*server_set_bgcolor)(struct mod* v, int bgcolor);
int (*server_set_opcode)(struct mod* v, int opcode);
int (*server_set_mixmode)(struct mod* v, int mixmode);
- int (*server_set_brush)(struct mod* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct mod* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct mod* v, int style,
int width);
int (*server_draw_line)(struct mod* v, int x1, int y1, int x2, int y2);
- int (*server_add_char)(struct mod* v, int font, int charactor,
+ int (*server_add_char)(struct mod* v, int font, int character,
int offset, int baseline,
int width, int height, char* data);
int (*server_draw_text)(struct mod* v, int font,
@@ -80,19 +80,20 @@ struct mod
int (*server_query_channel)(struct mod* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct mod* v, char* name);
+ int (*server_get_channel_id)(struct mod* v, const char *name);
int (*server_send_to_channel)(struct mod* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
int (*server_bell_trigger)(struct mod* v);
- long server_dumby[100 - 25]; /* align, 100 minus the number of server
- functions above */
+ tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server
+ functions above */
/* common */
- long handle; /* pointer to self as long */
- long wm;
- long painter;
- int sck;
+ tintptr handle; /* pointer to self as long */
+ tintptr wm;
+ tintptr painter;
+ tintptr si;
/* mod data */
+ int sck;
int width;
int height;
int bpp;
diff --git a/neutrinordp/Makefile.am b/neutrinordp/Makefile.am
index 93e1196a..fb5bf030 100644
--- a/neutrinordp/Makefile.am
+++ b/neutrinordp/Makefile.am
@@ -1,27 +1,25 @@
-EXTRA_DIST = xrdp-neutrinordp.h
-EXTRA_DEFINES =
-
-if XRDP_DEBUG
-EXTRA_DEFINES += -DXRDP_DEBUG
-else
-EXTRA_DEFINES += -DXRDP_NODEBUG
-endif
-
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
- $(EXTRA_DEFINES)
-
-INCLUDES = \
-I$(top_srcdir)/common \
$(FREERDP_CFLAGS)
-lib_LTLIBRARIES = \
+if XRDP_DEBUG
+AM_CPPFLAGS += -DXRDP_DEBUG
+else
+AM_CPPFLAGS += -DXRDP_NODEBUG
+endif
+
+module_LTLIBRARIES = \
libxrdpneutrinordp.la
-libxrdpneutrinordp_la_SOURCES = xrdp-neutrinordp.c xrdp-color.c
+libxrdpneutrinordp_la_SOURCES = \
+ xrdp-color.c \
+ xrdp-color.h \
+ xrdp-neutrinordp.c \
+ xrdp-neutrinordp.h
libxrdpneutrinordp_la_LIBADD = \
$(top_builddir)/common/libcommon.la \
diff --git a/neutrinordp/xrdp-color.c b/neutrinordp/xrdp-color.c
index 8201e918..80fac32b 100644
--- a/neutrinordp/xrdp-color.c
+++ b/neutrinordp/xrdp-color.c
@@ -213,6 +213,28 @@ convert_bitmap(int in_bpp, int out_bpp, char *bmpdata,
return bmpdata;
}
+ if ((in_bpp == 16) && (out_bpp == 32))
+ {
+ out = (char *)g_malloc(width * height * 4, 0);
+ src = bmpdata;
+ dst = out;
+
+ for (i = 0; i < height; i++)
+ {
+ for (j = 0; j < width; j++)
+ {
+ pixel = *((tui16 *)src);
+ SPLITCOLOR16(red, green, blue, pixel);
+ pixel = COLOR24RGB(red, green, blue);
+ *((tui32 *)dst) = pixel;
+ src += 2;
+ dst += 4;
+ }
+ }
+
+ return out;
+ }
+
g_writeln("convert_bitmap: error unknown conversion from %d to %d",
in_bpp, out_bpp);
return 0;
@@ -292,6 +314,14 @@ convert_color(int in_bpp, int out_bpp, int in_color, int *palette)
return pixel;
}
+ if ((in_bpp == 16) && (out_bpp == 32))
+ {
+ pixel = in_color;
+ SPLITCOLOR16(red, green, blue, pixel);
+ pixel = COLOR24BGR(red, green, blue);
+ return pixel;
+ }
+
if ((in_bpp == 24) && (out_bpp == 24))
{
return in_color;
diff --git a/neutrinordp/xrdp-color.h b/neutrinordp/xrdp-color.h
index 6a3f7362..acf63780 100644
--- a/neutrinordp/xrdp-color.h
+++ b/neutrinordp/xrdp-color.h
@@ -20,10 +20,10 @@
#ifndef __XRDP_COLOR_H
#define __XRDP_COLOR_H
-char* APP_CC
-convert_bitmap(int in_bpp, int out_bpp, char* bmpdata,
- int width, int height, int* palette);
+char *APP_CC
+convert_bitmap(int in_bpp, int out_bpp, char *bmpdata,
+ int width, int height, int *palette);
int APP_CC
-convert_color(int in_bpp, int out_bpp, int in_color, int* palette);
+convert_color(int in_bpp, int out_bpp, int in_color, int *palette);
#endif
diff --git a/neutrinordp/xrdp-neutrinordp.c b/neutrinordp/xrdp-neutrinordp.c
index 0b90767d..34ed9c2c 100644
--- a/neutrinordp/xrdp-neutrinordp.c
+++ b/neutrinordp/xrdp-neutrinordp.c
@@ -22,7 +22,6 @@
#include "xrdp_rail.h"
#include "log.h"
#include <freerdp/settings.h>
-#include <X11/Xlib.h>
#ifdef XRDP_DEBUG
#define LOG_LEVEL 99
@@ -48,13 +47,14 @@ verifyColorMap(struct mod *mod)
{
int i;
- for(i = 0; i < 255; i++)
+ for (i = 0; i < 255; i++)
{
if (mod->colormap[i] != 0)
{
return ;
}
}
+
LLOGLN(0, ("The colormap is all NULL"));
}
@@ -114,44 +114,58 @@ lxrdp_connect(struct mod *mod)
{
case PREECONNECTERROR:
g_snprintf(buf, 128, "The error code from connect is "
- "PREECONNECTERROR");
+ "PREECONNECTERROR");
break;
+
case UNDEFINEDCONNECTERROR:
g_snprintf(buf, 128, "The error code from connect is "
- "UNDEFINEDCONNECTERROR");
+ "UNDEFINEDCONNECTERROR");
break;
+
case POSTCONNECTERROR:
g_snprintf(buf, 128, "The error code from connect is "
- "POSTCONNECTERROR");
+ "POSTCONNECTERROR");
break;
+
case DNSERROR:
g_snprintf(buf, 128, "The DNS system generated an error");
break;
+
case DNSNAMENOTFOUND:
g_snprintf(buf, 128, "The DNS system could not find the "
- "specified name");
+ "specified name");
break;
+
case CONNECTERROR:
g_snprintf(buf, 128, "A general connect error was returned");
break;
+
case MCSCONNECTINITIALERROR:
g_snprintf(buf, 128, "The error code from connect is "
- "MCSCONNECTINITIALERROR");
+ "MCSCONNECTINITIALERROR");
break;
+
case TLSCONNECTERROR:
g_snprintf(buf, 128, "Error in TLS handshake");
break;
+
case AUTHENTICATIONERROR:
g_snprintf(buf, 128, "Authentication error check your password "
- "and username");
+ "and username");
+ break;
+
+ case INSUFFICIENTPRIVILEGESERROR:
+ g_snprintf(buf, 128, "Insufficent privileges on target server");
break;
+
default:
g_snprintf(buf, 128, "Unhandled Errorcode from connect : %d",
- connectErrorCode);
+ connectErrorCode);
break;
}
}
- log_message(LOG_LEVEL_INFO,buf);
+
+ log_message(LOG_LEVEL_INFO, buf);
mod->server_msg(mod, buf, 0);
}
@@ -195,6 +209,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
switch (msg)
{
case 15: /* key down */
+
/* Before we handle the first character we synchronize
capslock and numlock. */
/* We collect the state during the first synchronize
@@ -205,85 +220,102 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
mod->inst->input->SynchronizeEvent(mod->inst->input, mod->keyBoardLockInfo);
mod->bool_keyBoardSynced = 1;
}
+
mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3);
break;
+
case 16: /* key up */
mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3);
break;
+
case 17: /* Synchronize */
- LLOGLN(11, ("Synchronized event handled : %d",param1));
+ LLOGLN(11, ("Synchronized event handled : %ld", param1));
/* In some situations the Synchronize event come to early.
Therefore we store this information and use it when we
receive the first keyboard event
Without this fix numlock and capslock can come
out of sync. */
mod->inst->input->SynchronizeEvent(mod->inst->input, param1);
+
if (!mod->bool_keyBoardSynced)
{
mod->keyBoardLockInfo = param1;
}
+
break;
+
case 100: /* mouse move */
- LLOGLN(12, ("mouse move %d %d", param1, param2));
+ LLOGLN(12, ("mouse move %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_MOVE;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 101: /* left button up */
- LLOGLN(12, ("left button up %d %d", param1, param2));
+ LLOGLN(12, ("left button up %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON1;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 102: /* left button down */
- LLOGLN(12, ("left button down %d %d", param1, param2));
+ LLOGLN(12, ("left button down %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON1 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 103: /* right button up */
- LLOGLN(12, ("right button up %d %d", param1, param2));
+ LLOGLN(12, ("right button up %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON2;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 104: /* right button down */
- LLOGLN(12, ("right button down %d %d", param1, param2));
+ LLOGLN(12, ("right button down %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON2 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 105: /* middle button up */
- LLOGLN(12, ("middle button up %d %d", param1, param2));
+ LLOGLN(12, ("middle button up %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON3;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 106: /* middle button down */
- LLOGLN(12, ("middle button down %d %d", param1, param2));
+ LLOGLN(12, ("middle button down %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON3 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 107: /* wheel up */
flags = PTR_FLAGS_WHEEL | 0x0078;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
break;
+
case 108:
break;
+
case 109: /* wheel down */
flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
break;
+
case 110:
break;
+
case 200:
LLOGLN(10, ("Invalidate request sent from client"));
x = (param1 >> 16) & 0xffff;
@@ -292,6 +324,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
cy = (param2 >> 0) & 0xffff;
mod->inst->SendInvalidate(mod->inst, -1, x, y, cx, cy);
break;
+
case 0x5555:
chanid = LOWORD(param1);
flags = HIWORD(param1);
@@ -300,6 +333,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
total_size = (int)param4;
LLOGLN(12, ("lxrdp_event: client to server ,chanid= %d flags= %d", chanid, flags));
+
if ((chanid < 0) || (chanid >= mod->inst->settings->num_channels))
{
LLOGLN(0, ("lxrdp_event: error chanid %d", chanid));
@@ -313,6 +347,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
case 3:
mod->inst->SendChannelData(mod->inst, lchid, (tui8 *)data, total_size);
break;
+
case 2:
/* end */
g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
@@ -324,6 +359,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
mod->chan_buf_bytes = 0;
mod->chan_buf_valid = 0;
break;
+
case 1:
/* start */
g_free(mod->chan_buf);
@@ -333,6 +369,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
mod->chan_buf_valid += size;
break;
+
default:
/* middle */
g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
@@ -341,6 +378,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
}
break;
+
default:
LLOGLN(0, ("Unhandled message type in eventhandler %d", msg));
break;
@@ -389,7 +427,7 @@ lxrdp_end(struct mod *mod)
/******************************************************************************/
/* return error */
static int DEFAULT_CC
-lxrdp_set_param(struct mod *mod, char *name, char *value)
+lxrdp_set_param(struct mod *mod, const char *name, char *value)
{
rdpSettings *settings;
@@ -420,6 +458,10 @@ lxrdp_set_param(struct mod *mod, char *name, char *value)
{
g_strncpy(mod->username, value, 255);
}
+ else if (g_strcmp(name, "domain") == 0)
+ {
+ g_strncpy(mod->domain, value, 255);
+ }
else if (g_strcmp(name, "password") == 0)
{
g_strncpy(mod->password, value, 255);
@@ -430,6 +472,14 @@ lxrdp_set_param(struct mod *mod, char *name, char *value)
/* This is a Struct and cannot be printed in next else*/
LLOGLN(10, ("Client_info struct ignored"));
}
+ else if (g_strcmp(name, "program") == 0)
+ {
+ settings->shell = g_strdup(value);
+ }
+ else if (g_strcmp(name, "nla") == 0)
+ {
+ settings->nla_security = g_text2bool(value);
+ }
else
{
LLOGLN(0, ("lxrdp_set_param: unknown name [%s] value [%s]", name, value));
@@ -572,16 +622,18 @@ lfreerdp_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap)
if (bd->compressed)
{
- LLOGLN(20,("decompress size : %d",bd->bitmapLength));
- if(!bitmap_decompress(bd->bitmapDataStream, (tui8 *)dst_data, bd->width,
- bd->height, bd->bitmapLength, server_bpp, server_bpp)){
- LLOGLN(0,("Failure to decompress the bitmap"));
+ LLOGLN(20, ("decompress size : %d", bd->bitmapLength));
+
+ if (!bitmap_decompress(bd->bitmapDataStream, (tui8 *)dst_data, bd->width,
+ bd->height, bd->bitmapLength, server_bpp, server_bpp))
+ {
+ LLOGLN(0, ("Failure to decompress the bitmap"));
}
}
else
{
/* bitmap is upside down */
- LLOGLN(10,("bitmap upside down"));
+ LLOGLN(10, ("bitmap upside down"));
src = (char *)(bd->bitmapDataStream);
dst = dst_data + bd->height * line_bytes;
@@ -646,14 +698,15 @@ lfreerdp_pat_blt(rdpContext *context, PATBLT_ORDER *patblt)
patblt->backColor, mod->colormap);
LLOGLN(10, ("lfreerdp_pat_blt: nLeftRect %d nTopRect %d "
- "nWidth %d nHeight %d fgcolor 0x%8.8x bgcolor 0x%8.8x",
- patblt->nLeftRect, patblt->nTopRect,
- patblt->nWidth, patblt->nHeight, fgcolor, bgcolor));
+ "nWidth %d nHeight %d fgcolor 0x%8.8x bgcolor 0x%8.8x",
+ patblt->nLeftRect, patblt->nTopRect,
+ patblt->nWidth, patblt->nHeight, fgcolor, bgcolor));
if (fgcolor == bgcolor)
{
LLOGLN(0, ("Warning same color on both bg and fg"));
}
+
mod->server_set_mixmode(mod, 1);
mod->server_set_opcode(mod, patblt->bRop);
mod->server_set_fgcolor(mod, fgcolor);
@@ -718,9 +771,9 @@ lfreerdp_opaque_rect(rdpContext *context, OPAQUE_RECT_ORDER *opaque_rect)
fgcolor = convert_color(server_bpp, client_bpp,
opaque_rect->color, mod->colormap);
LLOGLN(10, ("lfreerdp_opaque_rect: nLeftRect %d nTopRect %d "
- "nWidth %d nHeight %d fgcolor 0x%8.8x",
- opaque_rect->nLeftRect, opaque_rect->nTopRect,
- opaque_rect->nWidth, opaque_rect->nHeight, fgcolor));
+ "nWidth %d nHeight %d fgcolor 0x%8.8x",
+ opaque_rect->nLeftRect, opaque_rect->nTopRect,
+ opaque_rect->nWidth, opaque_rect->nHeight, fgcolor));
mod->server_set_fgcolor(mod, fgcolor);
mod->server_fill_rect(mod, opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight);
@@ -793,16 +846,16 @@ lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
bgcolor = convert_color(server_bpp, client_bpp,
glyph_index->backColor, mod->colormap);
LLOGLN(10, ("lfreerdp_glyph_index: "
- "bkLeft %d bkTop %d width %d height %d "
- "opLeft %d opTop %d width %d height %d "
- "cbData %d fgcolor 0x%8.8x bgcolor 0x%8.8x fOpRedundant %d",
- glyph_index->bkLeft, glyph_index->bkTop,
- glyph_index->bkRight - glyph_index->bkLeft,
- glyph_index->bkBottom - glyph_index->bkTop,
- glyph_index->opLeft, glyph_index->opTop,
- glyph_index->opRight - glyph_index->opLeft,
- glyph_index->opBottom - glyph_index->opTop,
- glyph_index->cbData, fgcolor, bgcolor, glyph_index->fOpRedundant));
+ "bkLeft %d bkTop %d width %d height %d "
+ "opLeft %d opTop %d width %d height %d "
+ "cbData %d fgcolor 0x%8.8x bgcolor 0x%8.8x fOpRedundant %d",
+ glyph_index->bkLeft, glyph_index->bkTop,
+ glyph_index->bkRight - glyph_index->bkLeft,
+ glyph_index->bkBottom - glyph_index->bkTop,
+ glyph_index->opLeft, glyph_index->opTop,
+ glyph_index->opRight - glyph_index->opLeft,
+ glyph_index->opBottom - glyph_index->opTop,
+ glyph_index->cbData, fgcolor, bgcolor, glyph_index->fOpRedundant));
mod->server_set_bgcolor(mod, fgcolor);
mod->server_set_fgcolor(mod, bgcolor);
opLeft = glyph_index->opLeft;
@@ -810,6 +863,7 @@ lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
opRight = glyph_index->opRight;
opBottom = glyph_index->opBottom;
#if 1
+
/* workarounds for freerdp not using fOpRedundant in
glyph.c::update_gdi_glyph_index */
if (glyph_index->fOpRedundant)
@@ -817,8 +871,9 @@ lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
opLeft = glyph_index->bkLeft;
opTop = glyph_index->bkTop;
opRight = glyph_index->bkRight;
- opBottom =glyph_index->bkBottom;
+ opBottom = glyph_index->bkBottom;
}
+
#endif
mod->server_draw_text(mod, glyph_index->cacheId, glyph_index->flAccel,
glyph_index->fOpRedundant,
@@ -866,7 +921,7 @@ lfreerdp_cache_bitmap(rdpContext *context, CACHE_BITMAP_ORDER *cache_bitmap_orde
/******************************************************************************/
/* Turn the bitmap upside down*/
static void DEFAULT_CC
-lfreerdp_upsidedown(uint8* destination, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, int server_Bpp)
+lfreerdp_upsidedown(uint8 *destination, CACHE_BITMAP_V2_ORDER *cache_bitmap_v2_order, int server_Bpp)
{
tui8 *src;
tui8 *dst;
@@ -1079,7 +1134,7 @@ static void DEFAULT_CC
lfreerdp_pointer_system(rdpContext *context,
POINTER_SYSTEM_UPDATE *pointer_system)
{
- LLOGLN(0, ("lfreerdp_pointer_system: - no code here type value = %d",pointer_system->type));
+ LLOGLN(0, ("lfreerdp_pointer_system: - no code here type value = %d", pointer_system->type));
}
/******************************************************************************/
@@ -1112,7 +1167,7 @@ lfreerdp_get_pixel(void *bits, int width, int height, int bpp,
{
src8 = (tui8 *)bits;
src8 += y * delta + x * 4;
- pixel = ((int*)(src8))[0];
+ pixel = ((int *)(src8))[0];
return pixel;
}
else
@@ -1159,7 +1214,7 @@ lfreerdp_set_pixel(int pixel, void *bits, int width, int height, int bpp,
{
dst8 = (tui8 *)bits;
dst8 += y * delta + x * 4;
- ((int*)(dst8))[0] = pixel;
+ ((int *)(dst8))[0] = pixel;
}
else
{
@@ -1210,21 +1265,23 @@ lfreerdp_pointer_new(rdpContext *context,
LLOGLN(20, ("lfreerdp_pointer_new:"));
LLOGLN(20, (" bpp %d", pointer_new->xorBpp));
LLOGLN(20, (" width %d height %d", pointer_new->colorPtrAttr.width,
- pointer_new->colorPtrAttr.height));
+ pointer_new->colorPtrAttr.height));
LLOGLN(20, (" lengthXorMask %d lengthAndMask %d",
- pointer_new->colorPtrAttr.lengthXorMask,
- pointer_new->colorPtrAttr.lengthAndMask));
+ pointer_new->colorPtrAttr.lengthXorMask,
+ pointer_new->colorPtrAttr.lengthAndMask));
index = pointer_new->colorPtrAttr.cacheIndex;
+
if (index >= 32)
{
LLOGLN(0, ("lfreerdp_pointer_new: pointer index too big"));
return ;
}
+
if (pointer_new->xorBpp == 1 &&
- pointer_new->colorPtrAttr.width == 32 &&
- pointer_new->colorPtrAttr.height == 32)
+ pointer_new->colorPtrAttr.width == 32 &&
+ pointer_new->colorPtrAttr.height == 32)
{
LLOGLN(10, ("lfreerdp_pointer_new:"));
mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
@@ -1241,14 +1298,14 @@ lfreerdp_pointer_new(rdpContext *context,
lfreerdp_convert_color_image(dst, 32, 32, 1, 32 / -8,
src, 32, 32, 1, 32 / 8);
}
- else if(pointer_new->xorBpp >= 8 &&
- pointer_new->colorPtrAttr.width == 32 &&
- pointer_new->colorPtrAttr.height == 32)
+ else if (pointer_new->xorBpp >= 8 &&
+ pointer_new->colorPtrAttr.width == 32 &&
+ pointer_new->colorPtrAttr.height == 32)
{
bytes_per_pixel = (pointer_new->xorBpp + 7) / 8;
bits_per_pixel = pointer_new->xorBpp;
LLOGLN(10, ("lfreerdp_pointer_new: bpp %d Bpp %d", bits_per_pixel,
- bytes_per_pixel));
+ bytes_per_pixel));
mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
mod->pointer_cache[index].bpp = bits_per_pixel;
@@ -1263,7 +1320,7 @@ lfreerdp_pointer_new(rdpContext *context,
{
LLOGLN(0, ("lfreerdp_pointer_new: error bpp %d width %d height %d index: %d",
pointer_new->xorBpp, pointer_new->colorPtrAttr.width,
- pointer_new->colorPtrAttr.height,index));
+ pointer_new->colorPtrAttr.height, index));
}
mod->server_set_pointer_ex(mod, mod->pointer_cache[index].hotx,
@@ -1299,28 +1356,31 @@ lfreerdp_pointer_cached(rdpContext *context,
/******************************************************************************/
static void DEFAULT_CC
-lfreerdp_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
+lfreerdp_polygon_cb(rdpContext *context, POLYGON_CB_ORDER *polygon_cb)
{
LLOGLN(0, ("lfreerdp_polygon_sc called:- not supported!!!!!!!!!!!!!!!!!!!!"));
}
/******************************************************************************/
static void DEFAULT_CC
-lfreerdp_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
+lfreerdp_polygon_sc(rdpContext *context, POLYGON_SC_ORDER *polygon_sc)
{
struct mod *mod;
int i, npoints;
- XPoint points[4];
+ struct {
+ short x, y;
+ } points[4];
int fgcolor;
int server_bpp, client_bpp;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_polygon_sc :%d(points) %d(color) %d(fillmode) "
- "%d(bRop) %d(cbData) %d(x) %d(y)",
- polygon_sc->nDeltaEntries, polygon_sc->brushColor,
- polygon_sc->fillMode, polygon_sc->bRop2,
- polygon_sc->cbData, polygon_sc->xStart,
- polygon_sc->yStart));
+ "%d(bRop) %d(cbData) %d(x) %d(y)",
+ polygon_sc->nDeltaEntries, polygon_sc->brushColor,
+ polygon_sc->fillMode, polygon_sc->bRop2,
+ polygon_sc->cbData, polygon_sc->xStart,
+ polygon_sc->yStart));
+
if (polygon_sc->nDeltaEntries == 3)
{
server_bpp = mod->inst->settings->color_depth;
@@ -1334,6 +1394,7 @@ lfreerdp_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
points[i + 1].x = 0; // polygon_sc->points[i].x;
points[i + 1].y = 0; // polygon_sc->points[i].y;
}
+
fgcolor = convert_color(server_bpp, client_bpp,
polygon_sc->brushColor, mod->colormap);
@@ -1343,10 +1404,10 @@ lfreerdp_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
mod->server_set_pen(mod, 1, 1); // style, width
// TODO replace with correct brush; this is a workaround
// This workaround handles the text cursor in microsoft word.
- mod->server_draw_line(mod,polygon_sc->xStart,polygon_sc->yStart,polygon_sc->xStart,polygon_sc->yStart+points[2].y);
-// mod->server_fill_rect(mod, points[0].x, points[0].y,
-// points[0].x-points[3].x, points[0].y-points[2].y);
-// mod->server_set_brush(mod,); // howto use this on our indata??
+ mod->server_draw_line(mod, polygon_sc->xStart, polygon_sc->yStart, polygon_sc->xStart, polygon_sc->yStart + points[2].y);
+ // mod->server_fill_rect(mod, points[0].x, points[0].y,
+ // points[0].x-points[3].x, points[0].y-points[2].y);
+ // mod->server_set_brush(mod,); // howto use this on our indata??
mod->server_set_opcode(mod, 0xcc);
}
else
@@ -1357,7 +1418,7 @@ lfreerdp_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
/******************************************************************************/
static void DEFAULT_CC
-lfreerdp_syncronize(rdpContext* context)
+lfreerdp_synchronize(rdpContext *context)
{
struct mod *mod;
mod = ((struct mod_context *)context)->modi;
@@ -1455,6 +1516,7 @@ lfreerdp_pre_connect(freerdp *instance)
instance->settings->username = g_strdup(mod->username);
instance->settings->password = g_strdup(mod->password);
+ instance->settings->domain = g_strdup(mod->domain);
if (mod->client_info.rail_support_level > 0)
{
@@ -1472,29 +1534,31 @@ lfreerdp_pre_connect(freerdp *instance)
{
LLOGLN(10, ("Special PerformanceFlags changed"));
instance->settings->performance_flags = PERF_DISABLE_WALLPAPER |
- PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
- PERF_DISABLE_THEMING;
- // | PERF_DISABLE_CURSOR_SHADOW | PERF_DISABLE_CURSORSETTINGS;
+ PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
+ PERF_DISABLE_THEMING;
+ // | PERF_DISABLE_CURSOR_SHADOW | PERF_DISABLE_CURSORSETTINGS;
}
+
instance->settings->compression = 0;
instance->settings->ignore_certificate = 1;
// Multi Monitor Settings
instance->settings->num_monitors = mod->client_info.monitorCount;
+
for (index = 0; index < mod->client_info.monitorCount; index++)
{
- instance->settings->monitors[index].x = mod->client_info.minfo[index].left;
- instance->settings->monitors[index].y = mod->client_info.minfo[index].top;
- instance->settings->monitors[index].width = mod->client_info.minfo[index].right;
- instance->settings->monitors[index].height = mod->client_info.minfo[index].bottom;
- instance->settings->monitors[index].is_primary = mod->client_info.minfo[index].is_primary;
+ instance->settings->monitors[index].x = mod->client_info.minfo[index].left;
+ instance->settings->monitors[index].y = mod->client_info.minfo[index].top;
+ instance->settings->monitors[index].width = mod->client_info.minfo[index].right;
+ instance->settings->monitors[index].height = mod->client_info.minfo[index].bottom;
+ instance->settings->monitors[index].is_primary = mod->client_info.minfo[index].is_primary;
}
instance->update->BeginPaint = lfreerdp_begin_paint;
instance->update->EndPaint = lfreerdp_end_paint;
instance->update->SetBounds = lfreerdp_set_bounds;
instance->update->BitmapUpdate = lfreerdp_bitmap_update;
- instance->update->Synchronize = lfreerdp_syncronize ;
+ instance->update->Synchronize = lfreerdp_synchronize;
instance->update->primary->DstBlt = lfreerdp_dst_blt;
instance->update->primary->PatBlt = lfreerdp_pat_blt;
instance->update->primary->ScrBlt = lfreerdp_scr_blt;
@@ -1536,9 +1600,9 @@ lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
int index;
struct mod *mod;
struct rail_window_state_order wso;
- UNICONV* uniconv;
+ UNICONV *uniconv;
- LLOGLN(0, ("llrail_WindowCreate:"));
+ LLOGLN(10, ("lrail_WindowCreate:"));
uniconv = freerdp_uniconv_new();
mod = ((struct mod_context *)context)->modi;
memset(&wso, 0, sizeof(wso));
@@ -1551,10 +1615,10 @@ lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
{
wso.title_info = freerdp_uniconv_in(uniconv,
- window_state->titleInfo.string, window_state->titleInfo.length);
+ window_state->titleInfo.string, window_state->titleInfo.length);
}
- LLOGLN(0, ("lrail_WindowCreate: %s", wso.title_info));
+ LLOGLN(10, ("lrail_WindowCreate: %s", wso.title_info));
wso.client_offset_x = window_state->clientOffsetX;
wso.client_offset_y = window_state->clientOffsetY;
wso.client_area_width = window_state->clientAreaWidth;
@@ -1614,7 +1678,7 @@ void DEFAULT_CC
lrail_WindowUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
WINDOW_STATE_ORDER *window_state)
{
- LLOGLN(0, ("lrail_WindowUpdate:"));
+ LLOGLN(10, ("lrail_WindowUpdate:"));
lrail_WindowCreate(context, orderInfo, window_state);
}
@@ -1624,7 +1688,7 @@ lrail_WindowDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
{
struct mod *mod;
- LLOGLN(0, ("lrail_WindowDelete:"));
+ LLOGLN(10, ("lrail_WindowDelete:"));
mod = ((struct mod_context *)context)->modi;
mod->server_window_delete(mod, orderInfo->windowId);
}
@@ -1637,7 +1701,7 @@ lrail_WindowIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
struct mod *mod;
struct rail_icon_info rii;
- LLOGLN(0, ("lrail_WindowIcon:"));
+ LLOGLN(10, ("lrail_WindowIcon:"));
mod = ((struct mod_context *)context)->modi;
memset(&rii, 0, sizeof(rii));
rii.bpp = window_icon->iconInfo->bpp;
@@ -1662,7 +1726,7 @@ lrail_WindowCachedIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
{
struct mod *mod;
- LLOGLN(0, ("lrail_WindowCachedIcon:"));
+ LLOGLN(10, ("lrail_WindowCachedIcon:"));
mod = ((struct mod_context *)context)->modi;
mod->server_window_cached_icon(mod, orderInfo->windowId,
window_cached_icon->cachedIcon.cacheEntry,
@@ -1677,9 +1741,9 @@ lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
{
struct mod *mod;
struct rail_notify_state_order rnso;
- UNICONV* uniconv;
+ UNICONV *uniconv;
- LLOGLN(0, ("lrail_NotifyIconCreate:"));
+ LLOGLN(10, ("lrail_NotifyIconCreate:"));
uniconv = freerdp_uniconv_new();
mod = ((struct mod_context *)context)->modi;
@@ -1688,19 +1752,20 @@ lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
{
- rnso.tool_tip = freerdp_uniconv_in(uniconv,
- notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
+ rnso.tool_tip = freerdp_uniconv_in(uniconv,
+ notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
}
+
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
{
- rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
- rnso.infotip.flags = notify_icon_state->infoTip.flags;
- rnso.infotip.text = freerdp_uniconv_in(uniconv,
- notify_icon_state->infoTip.text.string,
- notify_icon_state->infoTip.text.length);
- rnso.infotip.title = freerdp_uniconv_in(uniconv,
- notify_icon_state->infoTip.title.string,
- notify_icon_state->infoTip.title.length);
+ rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
+ rnso.infotip.flags = notify_icon_state->infoTip.flags;
+ rnso.infotip.text = freerdp_uniconv_in(uniconv,
+ notify_icon_state->infoTip.text.string,
+ notify_icon_state->infoTip.text.length);
+ rnso.infotip.title = freerdp_uniconv_in(uniconv,
+ notify_icon_state->infoTip.title.string,
+ notify_icon_state->infoTip.title.length);
}
rnso.state = notify_icon_state->state;
@@ -1731,7 +1796,7 @@ void DEFAULT_CC
lrail_NotifyIconUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
NOTIFY_ICON_STATE_ORDER *notify_icon_state)
{
- LLOGLN(0, ("lrail_NotifyIconUpdate:"));
+ LLOGLN(10, ("lrail_NotifyIconUpdate:"));
lrail_NotifyIconCreate(context, orderInfo, notify_icon_state);
}
@@ -1741,7 +1806,7 @@ lrail_NotifyIconDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
{
struct mod *mod;
- LLOGLN(0, ("lrail_NotifyIconDelete:"));
+ LLOGLN(10, ("lrail_NotifyIconDelete:"));
mod = ((struct mod_context *)context)->modi;
mod->server_notify_delete(mod, orderInfo->windowId,
orderInfo->notifyIconId);
@@ -1756,7 +1821,7 @@ lrail_MonitoredDesktop(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
struct mod *mod;
struct rail_monitored_desktop_order rmdo;
- LLOGLN(0, ("lrail_MonitoredDesktop:"));
+ LLOGLN(10, ("lrail_MonitoredDesktop:"));
mod = ((struct mod_context *)context)->modi;
memset(&rmdo, 0, sizeof(rmdo));
rmdo.active_window_id = monitored_desktop->activeWindowId;
@@ -1786,7 +1851,7 @@ lrail_NonMonitoredDesktop(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
struct mod *mod;
struct rail_monitored_desktop_order rmdo;
- LLOGLN(0, ("lrail_NonMonitoredDesktop:"));
+ LLOGLN(10, ("lrail_NonMonitoredDesktop:"));
mod = ((struct mod_context *)context)->modi;
memset(&rmdo, 0, sizeof(rmdo));
mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags);
@@ -1798,7 +1863,7 @@ lfreerdp_post_connect(freerdp *instance)
{
struct mod *mod;
- LLOGLN(0, ("lfreerdp_post_connect:"));
+ LLOGLN(10, ("lfreerdp_post_connect:"));
mod = ((struct mod_context *)(instance->context))->modi;
g_memset(mod->password, 0, sizeof(mod->password));
@@ -1890,7 +1955,7 @@ lfreerdp_verify_certificate(freerdp *instance, char *subject, char *issuer,
}
/******************************************************************************/
-struct mod *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct mod *mod;
@@ -1903,7 +1968,7 @@ mod_init(void)
mod->vmaj, mod->vmin, mod->vrev));
mod->size = sizeof(struct mod);
mod->version = CURRENT_MOD_VER;
- mod->handle = (tbus)mod;
+ mod->handle = (tintptr) mod;
mod->mod_connect = lxrdp_connect;
mod->mod_start = lxrdp_start;
mod->mod_event = lxrdp_event;
@@ -1930,13 +1995,15 @@ mod_init(void)
lcon->modi = mod;
LLOGLN(10, ("mod_init: mod %p", mod));
- return mod;
+ return (tintptr) mod;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct mod *mod)
+mod_exit(tintptr handle)
{
+ struct mod *mod = (struct mod *) handle;
+
LLOGLN(0, ("mod_exit:"));
if (mod == 0)
diff --git a/neutrinordp/xrdp-neutrinordp.h b/neutrinordp/xrdp-neutrinordp.h
index aaff6d5a..79bb460d 100644
--- a/neutrinordp/xrdp-neutrinordp.h
+++ b/neutrinordp/xrdp-neutrinordp.h
@@ -35,151 +35,154 @@
struct bitmap_item
{
- int width;
- int height;
- char* data;
+ int width;
+ int height;
+ char *data;
};
struct brush_item
{
- int bpp;
- int width;
- int height;
- char* data;
- char b8x8[8];
+ int bpp;
+ int width;
+ int height;
+ char *data;
+ char b8x8[8];
};
struct pointer_item
{
- int hotx;
- int hoty;
- char data[32 * 32 * 4];
- char mask[32 * 32 / 8];
- int bpp;
+ int hotx;
+ int hoty;
+ char data[32 * 32 * 4];
+ char mask[32 * 32 / 8];
+ int bpp;
};
-#define CURRENT_MOD_VER 2
+#define CURRENT_MOD_VER 3
struct mod
{
- int size; /* size of this struct */
- int version; /* internal version */
- /* client functions */
- int (*mod_start)(struct mod* v, int w, int h, int bpp);
- int (*mod_connect)(struct mod* v);
- int (*mod_event)(struct mod* v, int msg, long param1, long param2,
- long param3, long param4);
- int (*mod_signal)(struct mod* v);
- int (*mod_end)(struct mod* v);
- int (*mod_set_param)(struct mod* v, char* name, char* value);
- int (*mod_session_change)(struct mod* v, int, int);
- int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount,
- tbus* write_objs, int* wcount, int* timeout);
- int (*mod_check_wait_objs)(struct mod* v);
- long mod_dumby[100 - 9]; /* align, 100 minus the number of mod
- functions above */
- /* server functions */
- int (*server_begin_update)(struct mod* v);
- int (*server_end_update)(struct mod* v);
- int (*server_fill_rect)(struct mod* v, int x, int y, int cx, int cy);
- int (*server_screen_blt)(struct mod* v, int x, int y, int cx, int cy,
- int srcx, int srcy);
- int (*server_paint_rect)(struct mod* v, int x, int y, int cx, int cy,
- char* data, int width, int height, int srcx, int srcy);
- int (*server_set_pointer)(struct mod* v, int x, int y, char* data, char* mask);
- int (*server_palette)(struct mod* v, int* palette);
- int (*server_msg)(struct mod* v, char* msg, int code);
- int (*server_is_term)(struct mod* v);
- int (*server_set_clip)(struct mod* v, int x, int y, int cx, int cy);
- int (*server_reset_clip)(struct mod* v);
- int (*server_set_fgcolor)(struct mod* v, int fgcolor);
- int (*server_set_bgcolor)(struct mod* v, int bgcolor);
- int (*server_set_opcode)(struct mod* v, int opcode);
- int (*server_set_mixmode)(struct mod* v, int mixmode);
- int (*server_set_brush)(struct mod* v, int x_orgin, int y_orgin,
- int style, char* pattern);
- int (*server_set_pen)(struct mod* v, int style,
- int width);
- int (*server_draw_line)(struct mod* v, int x1, int y1, int x2, int y2);
- int (*server_add_char)(struct mod* v, int font, int charactor,
- int offset, int baseline,
- int width, int height, char* data);
- int (*server_draw_text)(struct mod* v, int font,
- int flags, int mixmode, int clip_left, int clip_top,
- int clip_right, int clip_bottom,
- int box_left, int box_top,
- int box_right, int box_bottom,
- int x, int y, char* data, int data_len);
- int (*server_reset)(struct mod* v, int width, int height, int bpp);
- int (*server_query_channel)(struct mod* v, int index,
- char* channel_name,
- int* channel_flags);
- int (*server_get_channel_id)(struct mod* v, char* name);
- int (*server_send_to_channel)(struct mod* v, int channel_id,
- char* data, int data_len,
- int total_data_len, int flags);
- int (*server_bell_trigger)(struct mod* v);
- /* off screen bitmaps */
- int (*server_create_os_surface)(struct mod* v, int rdpindex,
- int width, int height);
- int (*server_switch_os_surface)(struct mod* v, int rdpindex);
- int (*server_delete_os_surface)(struct mod* v, int rdpindex);
- int (*server_paint_rect_os)(struct mod* mod, int x, int y,
- int cx, int cy,
- int rdpindex, int srcx, int srcy);
- int (*server_set_hints)(struct mod* mod, int hints, int mask);
- /* rail */
- int (*server_window_new_update)(struct mod* mod, int window_id,
- struct rail_window_state_order* window_state,
- int flags);
- int (*server_window_delete)(struct mod* mod, int window_id);
- int (*server_window_icon)(struct mod* mod,
- int window_id, int cache_entry, int cache_id,
- struct rail_icon_info* icon_info,
- int flags);
- int (*server_window_cached_icon)(struct mod* mod,
- int window_id, int cache_entry,
- int cache_id, int flags);
- int (*server_notify_new_update)(struct mod* mod,
- int window_id, int notify_id,
- struct rail_notify_state_order* notify_state,
- int flags);
- int (*server_notify_delete)(struct mod* mod, int window_id,
- int notify_id);
- int (*server_monitored_desktop)(struct mod* mod,
- struct rail_monitored_desktop_order* mdo,
- int flags);
- int (*server_set_pointer_ex)(struct mod* mod, int x, int y, char* data,
- char* mask, int bpp);
+ int size; /* size of this struct */
+ int version; /* internal version */
+ /* client functions */
+ int (*mod_start)(struct mod *v, int w, int h, int bpp);
+ int (*mod_connect)(struct mod *v);
+ int (*mod_event)(struct mod *v, int msg, long param1, long param2,
+ long param3, long param4);
+ int (*mod_signal)(struct mod *v);
+ int (*mod_end)(struct mod *v);
+ int (*mod_set_param)(struct mod *v, const char *name, char *value);
+ int (*mod_session_change)(struct mod *v, int, int);
+ int (*mod_get_wait_objs)(struct mod *v, tbus *read_objs, int *rcount,
+ tbus *write_objs, int *wcount, int *timeout);
+ int (*mod_check_wait_objs)(struct mod *v);
+ tintptr mod_dumby[100 - 9]; /* align, 100 minus the number of mod
+ functions above */
+ /* server functions */
+ int (*server_begin_update)(struct mod *v);
+ int (*server_end_update)(struct mod *v);
+ int (*server_fill_rect)(struct mod *v, int x, int y, int cx, int cy);
+ int (*server_screen_blt)(struct mod *v, int x, int y, int cx, int cy,
+ int srcx, int srcy);
+ int (*server_paint_rect)(struct mod *v, int x, int y, int cx, int cy,
+ char *data, int width, int height, int srcx, int srcy);
+ int (*server_set_pointer)(struct mod *v, int x, int y, char *data, char *mask);
+ int (*server_palette)(struct mod *v, int *palette);
+ int (*server_msg)(struct mod *v, char *msg, int code);
+ int (*server_is_term)(struct mod *v);
+ int (*server_set_clip)(struct mod *v, int x, int y, int cx, int cy);
+ int (*server_reset_clip)(struct mod *v);
+ int (*server_set_fgcolor)(struct mod *v, int fgcolor);
+ int (*server_set_bgcolor)(struct mod *v, int bgcolor);
+ int (*server_set_opcode)(struct mod *v, int opcode);
+ int (*server_set_mixmode)(struct mod *v, int mixmode);
+ int (*server_set_brush)(struct mod *v, int x_origin, int y_origin,
+ int style, char *pattern);
+ int (*server_set_pen)(struct mod *v, int style,
+ int width);
+ int (*server_draw_line)(struct mod *v, int x1, int y1, int x2, int y2);
+ int (*server_add_char)(struct mod *v, int font, int character,
+ int offset, int baseline,
+ int width, int height, char *data);
+ int (*server_draw_text)(struct mod *v, int font,
+ int flags, int mixmode, int clip_left, int clip_top,
+ int clip_right, int clip_bottom,
+ int box_left, int box_top,
+ int box_right, int box_bottom,
+ int x, int y, char *data, int data_len);
+ int (*server_reset)(struct mod *v, int width, int height, int bpp);
+ int (*server_query_channel)(struct mod *v, int index,
+ char *channel_name,
+ int *channel_flags);
+ int (*server_get_channel_id)(struct mod *v, const char *name);
+ int (*server_send_to_channel)(struct mod *v, int channel_id,
+ char *data, int data_len,
+ int total_data_len, int flags);
+ int (*server_bell_trigger)(struct mod *v);
+ /* off screen bitmaps */
+ int (*server_create_os_surface)(struct mod *v, int rdpindex,
+ int width, int height);
+ int (*server_switch_os_surface)(struct mod *v, int rdpindex);
+ int (*server_delete_os_surface)(struct mod *v, int rdpindex);
+ int (*server_paint_rect_os)(struct mod *mod, int x, int y,
+ int cx, int cy,
+ int rdpindex, int srcx, int srcy);
+ int (*server_set_hints)(struct mod *mod, int hints, int mask);
+ /* rail */
+ int (*server_window_new_update)(struct mod *mod, int window_id,
+ struct rail_window_state_order *window_state,
+ int flags);
+ int (*server_window_delete)(struct mod *mod, int window_id);
+ int (*server_window_icon)(struct mod *mod,
+ int window_id, int cache_entry, int cache_id,
+ struct rail_icon_info *icon_info,
+ int flags);
+ int (*server_window_cached_icon)(struct mod *mod,
+ int window_id, int cache_entry,
+ int cache_id, int flags);
+ int (*server_notify_new_update)(struct mod *mod,
+ int window_id, int notify_id,
+ struct rail_notify_state_order *notify_state,
+ int flags);
+ int (*server_notify_delete)(struct mod *mod, int window_id,
+ int notify_id);
+ int (*server_monitored_desktop)(struct mod *mod,
+ struct rail_monitored_desktop_order *mdo,
+ int flags);
+ int (*server_set_pointer_ex)(struct mod *mod, int x, int y, char *data,
+ char *mask, int bpp);
- long server_dumby[100 - 37]; /* align, 100 minus the number of server
- functions above */
- /* common */
- tbus handle; /* pointer to self as long */
- tbus wm;
- tbus painter;
- int sck;
- /* mod data */
- int width;
- int height;
- int bpp;
- int colormap[256];
- char* chan_buf;
- int chan_buf_valid;
- int chan_buf_bytes;
- int vmaj;
- int vmin;
- int vrev;
- char username[256];
- char password[256];
- int bool_keyBoardSynced ; /* Numlock can be out of sync, we hold state here to resolve */
- int keyBoardLockInfo ; /* Holds initial numlock capslock state */
+ tintptr server_dumby[100 - 37]; /* align, 100 minus the number of server
+ functions above */
+ /* common */
+ tintptr handle; /* pointer to self as long */
+ tintptr wm;
+ tintptr painter;
+ tintptr si;
- struct xrdp_client_info client_info;
+ /* mod data */
+ int sck;
+ int width;
+ int height;
+ int bpp;
+ int colormap[256];
+ char *chan_buf;
+ int chan_buf_valid;
+ int chan_buf_bytes;
+ int vmaj;
+ int vmin;
+ int vrev;
+ char username[256];
+ char password[256];
+ char domain[256];
+ int bool_keyBoardSynced ; /* Numlock can be out of sync, we hold state here to resolve */
+ int keyBoardLockInfo ; /* Holds initial numlock capslock state */
- struct rdp_freerdp* inst;
- struct bitmap_item bitmap_cache[4][4096];
- struct brush_item brush_cache[64];
- struct pointer_item pointer_cache[32];
+ struct xrdp_client_info client_info;
+
+ struct rdp_freerdp *inst;
+ struct bitmap_item bitmap_cache[4][4096];
+ struct brush_item brush_cache[64];
+ struct pointer_item pointer_cache[32];
};
diff --git a/pkgconfig/.gitignore b/pkgconfig/.gitignore
new file mode 100644
index 00000000..905f6549
--- /dev/null
+++ b/pkgconfig/.gitignore
@@ -0,0 +1,2 @@
+xrdp.pc
+xrdp-uninstalled.pc
diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am
new file mode 100644
index 00000000..4fa572f9
--- /dev/null
+++ b/pkgconfig/Makefile.am
@@ -0,0 +1,2 @@
+pkgconfigdir = @pkgconfigdir@
+pkgconfig_DATA = xrdp.pc
diff --git a/pkgconfig/xrdp-uninstalled.pc.in b/pkgconfig/xrdp-uninstalled.pc.in
new file mode 100644
index 00000000..aa130fd3
--- /dev/null
+++ b/pkgconfig/xrdp-uninstalled.pc.in
@@ -0,0 +1,7 @@
+abs_top_srcdir=@abs_top_srcdir@
+includedir=${abs_top_srcdir}/common
+
+Name: xrdp
+Description: An open source Remote Desktop Protocol (RDP) server
+Version: @VERSION@
+Cflags: -I${includedir}
diff --git a/pkgconfig/xrdp.pc.in b/pkgconfig/xrdp.pc.in
new file mode 100644
index 00000000..d5aa33ee
--- /dev/null
+++ b/pkgconfig/xrdp.pc.in
@@ -0,0 +1,9 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: xrdp
+Description: An open source Remote Desktop Protocol (RDP) server
+Version: @VERSION@
+Cflags: -I${includedir}
diff --git a/prog_std.txt b/prog_std.txt
deleted file mode 100644
index c358a470..00000000
--- a/prog_std.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-
-This is an atempt to explain my odd programming standard used for this project.
-Not to defend any of these but its my default standard and make it easy
-for me to read.
-Some files break these rules, they will be updated eventually.
-
-try to make any file compile with c++ compilers
-
-always put one var on a line by itself
- char* pvar;
- char text[256];
-not
- char *pvar, text[256];
-
-function calls look like this
- foo(a, b, c);
-not
- foo ( a, b, c );
-
-while, if, and case statements look like
- while (i != 0)
-not
- while(i != 0)
-
-for comments, always use /* */, not //
-
-defines should always be uppercase
-
-don't use tabs, use spaces
-
-no line should exceed 80 chars
-
-always use {} in if and while, even if its only one line
- while (p != 0)
- {
- p = p->next;
- }
-not
- while (p != 0)
- p = p->next;
diff --git a/rdp/Makefile.am b/rdp/Makefile.am
index 9b519d7c..30368156 100644
--- a/rdp/Makefile.am
+++ b/rdp/Makefile.am
@@ -1,27 +1,22 @@
-EXTRA_DIST = rdp.h
-EXTRA_DEFINES =
-
-if XRDP_DEBUG
-EXTRA_DEFINES += -DXRDP_DEBUG
-else
-EXTRA_DEFINES += -DXRDP_NODEBUG
-endif
-
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
- $(EXTRA_DEFINES)
-
-INCLUDES = \
-I$(top_srcdir)/common
-lib_LTLIBRARIES = \
+if XRDP_DEBUG
+AM_CPPFLAGS += -DXRDP_DEBUG
+else
+AM_CPPFLAGS += -DXRDP_NODEBUG
+endif
+
+module_LTLIBRARIES = \
librdp.la
librdp_la_SOURCES = \
rdp.c \
+ rdp.h \
rdp_bitmap.c \
rdp_iso.c \
rdp_lic.c \
diff --git a/rdp/rdp.c b/rdp/rdp.c
index abbbab73..5dc13363 100644
--- a/rdp/rdp.c
+++ b/rdp/rdp.c
@@ -242,7 +242,7 @@ lib_mod_end(struct mod *mod)
/******************************************************************************/
/* return error */
int DEFAULT_CC
-lib_mod_set_param(struct mod *mod, char *name, char *value)
+lib_mod_set_param(struct mod *mod, const char *name, char *value)
{
if (g_strncasecmp(name, "ip", 255) == 0)
{
@@ -318,7 +318,7 @@ lib_mod_check_wait_objs(struct mod *mod)
}
/******************************************************************************/
-struct mod *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct mod *mod;
@@ -327,7 +327,7 @@ mod_init(void)
mod = (struct mod *)g_malloc(sizeof(struct mod), 1);
mod->size = sizeof(struct mod);
mod->version = CURRENT_MOD_VER;
- mod->handle = (long)mod;
+ mod->handle = (tintptr) mod;
mod->mod_connect = lib_mod_connect;
mod->mod_start = lib_mod_start;
mod->mod_event = lib_mod_event;
@@ -338,13 +338,15 @@ mod_init(void)
mod->mod_check_wait_objs = lib_mod_check_wait_objs;
mod->rdp_layer = rdp_rdp_create(mod);
DEBUG(("out mod_init"));
- return mod;
+ return (tintptr) mod;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct mod *mod)
+mod_exit(tintptr handle)
{
+ struct mod *mod = (struct mod *) handle;
+
DEBUG(("in mod_exit"));
g_free(mod);
DEBUG(("out mod_exit"));
diff --git a/rdp/rdp.h b/rdp/rdp.h
index 9a755a38..ff04fafa 100644
--- a/rdp/rdp.h
+++ b/rdp/rdp.h
@@ -262,7 +262,7 @@ struct mod
long param3, long param4);
int (*mod_signal)(struct mod* v);
int (*mod_end)(struct mod* v);
- int (*mod_set_param)(struct mod* v, char* name, char* value);
+ int (*mod_set_param)(struct mod* v, const char *name, char* value);
int (*mod_session_change)(struct mod* v, int, int);
int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
@@ -287,12 +287,12 @@ struct mod
int (*server_set_bgcolor)(struct mod* v, int bgcolor);
int (*server_set_opcode)(struct mod* v, int opcode);
int (*server_set_mixmode)(struct mod* v, int mixmode);
- int (*server_set_brush)(struct mod* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct mod* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct mod* v, int style,
int width);
int (*server_draw_line)(struct mod* v, int x1, int y1, int x2, int y2);
- int (*server_add_char)(struct mod* v, int font, int charactor,
+ int (*server_add_char)(struct mod* v, int font, int character,
int offset, int baseline,
int width, int height, char* data);
int (*server_draw_text)(struct mod* v, int font,
@@ -305,7 +305,7 @@ struct mod
int (*server_query_channel)(struct mod* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct mod* v, char* name);
+ int (*server_get_channel_id)(struct mod* v, const char *name);
int (*server_send_to_channel)(struct mod* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
diff --git a/rdp/rdp_lic.c b/rdp/rdp_lic.c
index 2441bc7f..799c14b7 100644
--- a/rdp/rdp_lic.c
+++ b/rdp/rdp_lic.c
@@ -73,6 +73,7 @@ rdp_lic_generate_hwid(struct rdp_lic *self, char *hwid)
LICENCE_HWID_SIZE - 4);
}
+#if 0
/*****************************************************************************/
/* Present an existing licence to the server */
static void APP_CC
@@ -112,6 +113,7 @@ rdp_lic_present(struct rdp_lic *self, char *client_random, char *rsa_data,
rdp_sec_send(self->sec_layer, s, sec_flags);
free_stream(s);
}
+#endif
/*****************************************************************************/
/* Send a licence request packet */
@@ -161,13 +163,7 @@ rdp_lic_process_demand(struct rdp_lic *self, struct stream *s)
{
char null_data[SEC_MODULUS_SIZE];
char *server_random;
- char signature[LICENCE_SIGNATURE_SIZE];
- char hwid[LICENCE_HWID_SIZE];
- char *licence_data;
- int licence_size;
- void *crypt_key;
- licence_data = 0;
/* Retrieve the server random from the incoming packet */
in_uint8p(s, server_random, SEC_RANDOM_SIZE);
/* We currently use null client keys. This is a bit naughty but, hey,
@@ -176,10 +172,17 @@ rdp_lic_process_demand(struct rdp_lic *self, struct stream *s)
rdp_lic_generate_keys(self, null_data, server_random, null_data);
#if 0
+ int licence_size;
+ char *licence_data;
+
licence_size = 0; /* todo load_licence(&licence_data); */
if (licence_size > 0)
{
+ void *crypt_key;
+ char hwid[LICENCE_HWID_SIZE];
+ char signature[LICENCE_SIGNATURE_SIZE];
+
/* Generate a signature for the HWID buffer */
rdp_lic_generate_hwid(self, hwid);
rdp_sec_sign(signature, 16, self->licence_sign_key, 16,
diff --git a/rdp/rdp_mcs.c b/rdp/rdp_mcs.c
index 18c33ac4..536ba7d1 100644
--- a/rdp/rdp_mcs.c
+++ b/rdp/rdp_mcs.c
@@ -19,7 +19,7 @@
*/
#include "rdp.h"
-#include "common/log.h"
+#include "log.h"
/*****************************************************************************/
struct rdp_mcs *APP_CC
diff --git a/rdp/rdp_orders.c b/rdp/rdp_orders.c
index 0e4d42ad..1cad819d 100644
--- a/rdp/rdp_orders.c
+++ b/rdp/rdp_orders.c
@@ -225,7 +225,6 @@ rdp_orders_process_raw_bmpcache(struct rdp_orders *self, struct stream *s,
int flags)
{
int cache_idx = 0;
- int bufsize = 0;
int cache_id = 0;
int width = 0;
int height = 0;
@@ -244,7 +243,7 @@ rdp_orders_process_raw_bmpcache(struct rdp_orders *self, struct stream *s,
in_uint8(s, height);
in_uint8(s, bpp);
Bpp = (bpp + 7) / 8;
- in_uint16_le(s, bufsize);
+ in_uint8s(s, 2); /* bufsize */
in_uint16_le(s, cache_idx);
inverted = (char *)g_malloc(width * height * Bpp, 0);
@@ -326,15 +325,11 @@ rdp_orders_process_bmpcache(struct rdp_orders *self, struct stream *s,
int bpp = 0;
int Bpp = 0;
int bufsize = 0;
- int pad1 = 0;
- int pad2 = 0;
- int row_size = 0;
- int final_size = 0;
struct rdp_bitmap *bitmap = (struct rdp_bitmap *)NULL;
struct stream *rec_s = (struct stream *)NULL;
in_uint8(s, cache_id);
- in_uint8(s, pad1);
+ in_uint8s(s, 1); /* pad */
in_uint8(s, width);
in_uint8(s, height);
in_uint8(s, bpp);
@@ -348,10 +343,10 @@ rdp_orders_process_bmpcache(struct rdp_orders *self, struct stream *s,
}
else
{
- in_uint16_le(s, pad2);
+ in_uint8s(s, 2); /* pad */
in_uint16_le(s, size);
- in_uint16_le(s, row_size);
- in_uint16_le(s, final_size);
+ in_uint8s(s, 2); /* row_size */
+ in_uint8s(s, 2); /* final_size */
}
in_uint8p(s, data, size);
@@ -1115,8 +1110,8 @@ static void APP_CC
rdp_orders_process_desksave(struct rdp_orders *self, struct stream *s,
int present, int delta)
{
- int width = 0;
- int height = 0;
+ //int width = 0;
+ //int height = 0;
if (present & 0x01)
{
@@ -1435,7 +1430,7 @@ rdp_orders_process_orders(struct rdp_orders *self, struct stream *s,
}
/*****************************************************************************/
-/* returns pointer, it might return bmpdata if the data dosen't need to
+/* returns pointer, it might return bmpdata if the data doesn't need to
be converted, else it mallocs it. The calling function must free
it if needed */
char *APP_CC
diff --git a/rdp/rdp_rdp.c b/rdp/rdp_rdp.c
index 9ce63664..1e7952c5 100644
--- a/rdp/rdp_rdp.c
+++ b/rdp/rdp_rdp.c
@@ -312,7 +312,7 @@ rdp_rdp_out_colcache_caps(struct rdp_rdp *self, struct stream *s)
return 0;
}
-static char caps_0x0d[] =
+static const unsigned char caps_0x0d[] =
{
0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -327,11 +327,11 @@ static char caps_0x0d[] =
0x00, 0x00, 0x00, 0x00
};
-static char caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
+static const unsigned char caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
-static char caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
+static const unsigned char caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
-static char caps_0x10[] =
+static const unsigned char caps_0x10[] =
{
0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
@@ -345,7 +345,7 @@ static char caps_0x10[] =
/* Output unknown capability sets */
static int APP_CC
rdp_rdp_out_unknown_caps(struct rdp_rdp *self, struct stream *s, int id,
- int length, char *caps)
+ int length, const unsigned char *caps)
{
out_uint16_le(s, id);
out_uint16_le(s, length);
@@ -415,9 +415,9 @@ rdp_rdp_send_confirm_active(struct rdp_rdp *self, struct stream *s)
static int APP_CC
rdp_rdp_process_color_pointer_pdu(struct rdp_rdp *self, struct stream *s)
{
- int cache_idx;
- int dlen;
- int mlen;
+ unsigned int cache_idx;
+ unsigned int dlen;
+ unsigned int mlen;
struct rdp_cursor *cursor;
in_uint16_le(s, cache_idx);
@@ -506,8 +506,6 @@ static int APP_CC
rdp_rdp_process_pointer_pdu(struct rdp_rdp *self, struct stream *s)
{
int message_type;
- int x;
- int y;
int rv;
rv = 0;
@@ -517,8 +515,8 @@ rdp_rdp_process_pointer_pdu(struct rdp_rdp *self, struct stream *s)
switch (message_type)
{
case RDP_POINTER_MOVE:
- in_uint16_le(s, x);
- in_uint16_le(s, y);
+ in_uint8s(s, 2); /* x */
+ in_uint8s(s, 2); /* y */
break;
case RDP_POINTER_COLOR:
rv = rdp_rdp_process_color_pointer_pdu(self, s);
@@ -934,15 +932,13 @@ int APP_CC
rdp_rdp_process_data_pdu(struct rdp_rdp *self, struct stream *s)
{
int data_pdu_type;
- int ctype;
- int len;
int rv;
rv = 0;
in_uint8s(s, 6); /* shareid, pad, streamid */
- in_uint16_le(s, len);
+ in_uint8s(s, 2); /* len */
in_uint8(s, data_pdu_type);
- in_uint8(s, ctype);
+ in_uint8s(s, 1); /* ctype */
in_uint8s(s, 2); /* clen */
switch (data_pdu_type)
@@ -983,14 +979,12 @@ rdp_rdp_process_general_caps(struct rdp_rdp *self, struct stream *s)
static void APP_CC
rdp_rdp_process_bitmap_caps(struct rdp_rdp *self, struct stream *s)
{
- int width = 0;
- int height = 0;
int bpp = 0;
in_uint16_le(s, bpp);
in_uint8s(s, 6);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
+ in_uint8s(s, 2); /* width */
+ in_uint8s(s, 2); /* height */
self->mod->rdp_bpp = bpp;
/* todo, call reset if needed and use width and height */
}
diff --git a/rdp/rdp_tcp.c b/rdp/rdp_tcp.c
index f0a76d7d..60807806 100644
--- a/rdp/rdp_tcp.c
+++ b/rdp/rdp_tcp.c
@@ -55,7 +55,7 @@ rdp_tcp_recv(struct rdp_tcp *self, struct stream *s, int len)
{
int rcvd;
- DEBUG((" in rdp_tcp_recv gota get %d bytes on sck %d",
+ DEBUG((" in rdp_tcp_recv will get %d bytes on sck %d",
len, self->sck));
if (self->sck_closed)
@@ -74,7 +74,7 @@ rdp_tcp_recv(struct rdp_tcp *self, struct stream *s, int len)
{
if (g_tcp_last_error_would_block(self->sck))
{
- g_tcp_can_recv(self->sck, 10);
+ g_sck_can_recv(self->sck, 10);
}
else
{
@@ -115,7 +115,7 @@ rdp_tcp_send(struct rdp_tcp *self, struct stream *s)
}
len = s->end - s->data;
- DEBUG((" in rdp_tcp_send gota send %d bytes on sck %d", len,
+ DEBUG((" in rdp_tcp_send will send %d bytes on sck %d", len,
self->sck));
total = 0;
diff --git a/readme.txt b/readme.txt
index aa2b2742..b4a79af8 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,39 +1,3 @@
+xrdp 0.9.1
-xrdp 0.9.0
-
-Credits
- This project is very much dependent on NeutrinoRDP, FreeRDP, rdesktop, and
- the work of Matt Chapman and the NeutrinoRDP team members, of which I'm a
- member.
-
- Mark from up 19.9 was the first to work with rdp server code.
-
-Tested with linux on i386, x64, sparc, and ppc.
-I've got it compiling and working in windows with borland free tools.
-Non of the sesman or Xserver stuff works in windows of course.
-
-xrdp directory is the main server code
-vnc directory is a simple vnc client module for xrdp
-sesman directory is a session manager for xrdp that uses Xvnc for the Xserver
-libxrdp directory is a static library needed by xrdp
-rdp is an rdp client module for connecting to another rdp server
-xup is a module used to connect to an rdp specific X11 server
-Xserver is the files needed to build an rdp specific X11 server
-COPYING is the licence file
-design.txt is an attempt to expain the project design
-prog_std.txt is an attemp to explain the programming standard used
-
-since version 0.5.0 we switch to autotool to build xrdp
-
-to build and install
-
-change to the xrdp directory and run
-./bootstrap
-./configure
-make
-then as root
-make install
-
-see file-loc.txt to see what files are installed where
-
-Jay Sorg
+The contents of this file has been moved to README.md
diff --git a/sesman/Makefile.am b/sesman/Makefile.am
index 516639f4..89b99f54 100644
--- a/sesman/Makefile.am
+++ b/sesman/Makefile.am
@@ -1,12 +1,11 @@
-EXTRA_DIST = sesman.ini startwm.sh sesman.h access.h auth.h config.h env.h lock.h scp.h scp_v0.h scp_v1.h scp_v1_mng.h session.h sig.h thread.h
+EXTRA_DIST = \
+ Doxyfile
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
-
-INCLUDES = \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-I$(top_srcdir)/common \
-I$(top_srcdir)/sesman/libscp
@@ -37,18 +36,29 @@ sbin_PROGRAMS = \
xrdp-sesman
xrdp_sesman_SOURCES = \
+ access.c \
+ access.h \
+ auth.h \
+ config.c \
+ config.h \
+ env.c \
+ env.h \
scp.c \
+ scp.h \
scp_v0.c \
+ scp_v0.h \
scp_v1.c \
+ scp_v1.h \
scp_v1_mng.c \
+ scp_v1_mng.h \
sesman.c \
+ sesman.h \
session.c \
+ session.h \
sig.c \
- thread.c \
- lock.c \
- access.c \
- config.c \
- env.c \
+ sig.h \
+ xauth.c \
+ xauth.h \
$(AUTH_C)
xrdp_sesman_LDADD = \
@@ -59,8 +69,10 @@ xrdp_sesman_LDADD = \
sesmansysconfdir=$(sysconfdir)/xrdp
-sesmansysconf_DATA = \
- sesman.ini \
+dist_sesmansysconf_DATA = \
+ sesman.ini
+
+dist_sesmansysconf_SCRIPTS = \
startwm.sh
SUBDIRS = \
@@ -68,7 +80,3 @@ SUBDIRS = \
tools \
sessvc \
chansrv
-
-# must be tab below
-install-data-hook:
- chmod 755 $(DESTDIR)$(sysconfdir)/xrdp/startwm.sh
diff --git a/sesman/access.c b/sesman/access.c
index 1ba22df4..071c0ec3 100644
--- a/sesman/access.c
+++ b/sesman/access.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ extern struct config_sesman *g_cfg; /* in sesman.c */
/******************************************************************************/
int DEFAULT_CC
-access_login_allowed(char *user)
+access_login_allowed(const char *user)
{
int gid;
int ok;
@@ -79,7 +79,7 @@ access_login_allowed(char *user)
/******************************************************************************/
int DEFAULT_CC
-access_login_mng_allowed(char *user)
+access_login_mng_allowed(const char *user)
{
int gid;
int ok;
@@ -93,7 +93,7 @@ access_login_mng_allowed(char *user)
if (0 == g_cfg->sec.ts_admins_enable)
{
- LOG_DBG("[MNG] Terminal Server Admin group is disabled,"
+ LOG_DBG("[MNG] Terminal Server Admin group is disabled, "
"allowing authentication", 1);
return 1;
}
diff --git a/sesman/access.h b/sesman/access.h
index 2da6bb88..7705f8bb 100644
--- a/sesman/access.h
+++ b/sesman/access.h
@@ -35,7 +35,7 @@
*
*/
int DEFAULT_CC
-access_login_allowed(char* user);
+access_login_allowed(const char *user);
/**
*
@@ -45,6 +45,6 @@ access_login_allowed(char* user);
*
*/
int DEFAULT_CC
-access_login_mng_allowed(char* user);
+access_login_mng_allowed(const char *user);
#endif
diff --git a/sesman/auth.h b/sesman/auth.h
index e06b9eb3..68e677ef 100644
--- a/sesman/auth.h
+++ b/sesman/auth.h
@@ -32,11 +32,11 @@
* @brief Validates user's password
* @param user user's login name
* @param pass user's password
- * @return 0 on success, 1 on failure
+ * @return non-zero handle on success, 0 on failure
*
*/
long DEFAULT_CC
-auth_userpass(char* user, char* pass, int *errorcode);
+auth_userpass(const char *user, const char *pass, int *errorcode);
/**
*
@@ -94,7 +94,7 @@ auth_set_env(long in_val);
*
*/
int DEFAULT_CC
-auth_check_pwd_chg(char* user);
+auth_check_pwd_chg(const char *user);
/**
*
@@ -104,6 +104,6 @@ auth_check_pwd_chg(char* user);
*
*/
int DEFAULT_CC
-auth_change_pwd(char* user, char* newpwd);
+auth_change_pwd(const char *user, const char *newpwd);
#endif
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 7a97c136..7a2672a8 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -1,62 +1,74 @@
EXTRA_DIST = \
- chansrv.h \
- chansrv_fuse.h \
- clipboard.h \
- clipboard_common.h \
- clipboard_file.h \
- devredir.h \
- drdynvc.h \
- rail.h \
- sound.h \
- xcommon.h \
- mlog.h \
- chansrv_common.h
-
-EXTRA_DEFINES =
-EXTRA_INCLUDES =
-EXTRA_LIBS =
-EXTRA_FLAGS =
+ clipboard-notes.txt \
+ pcsc \
+ pulse \
+ wave-format-server.txt
-if XRDP_FUSE
-EXTRA_DEFINES += -DXRDP_FUSE
-EXTRA_LIBS += -lfuse
-endif
-
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
- $(EXTRA_DEFINES)
+ -I$(top_srcdir)/common
+
+CHANSRV_EXTRA_LIBS =
+
+if XRDP_FUSE
+AM_CPPFLAGS += -DXRDP_FUSE $(FUSE_CFLAGS)
+CHANSRV_EXTRA_LIBS += $(FUSE_LIBS)
+endif
+
+if XRDP_OPUS
+AM_CPPFLAGS += -DXRDP_OPUS
+CHANSRV_EXTRA_LIBS += -lopus
+endif
+
+if XRDP_MP3LAME
+AM_CPPFLAGS += -DXRDP_MP3LAME
+CHANSRV_EXTRA_LIBS += -lmp3lame
+endif
-INCLUDES = \
- -I$(top_srcdir)/common \
- $(EXTRA_INCLUDES)
+AM_CFLAGS = $(X_CFLAGS)
sbin_PROGRAMS = \
xrdp-chansrv
xrdp_chansrv_SOURCES = \
chansrv.c \
- sound.c \
+ chansrv.h \
+ chansrv_common.c \
+ chansrv_common.h \
+ chansrv_fuse.c \
+ chansrv_fuse.h \
clipboard.c \
+ clipboard.h \
+ clipboard_common.h \
clipboard_file.c \
+ clipboard_file.h \
devredir.c \
+ devredir.h \
+ drdynvc.c \
+ drdynvc.h \
+ fifo.c \
+ fifo.h \
+ irp.c \
+ irp.h \
+ mlog.h \
+ rail.c \
+ rail.h \
smartcard.c \
+ smartcard.h \
smartcard_pcsc.c \
- rail.c \
+ smartcard_pcsc.h \
+ sound.c \
+ sound.h \
xcommon.c \
- drdynvc.c \
- chansrv_fuse.c \
- irp.c \
- fifo.c \
- chansrv_common.c
+ xcommon.h
xrdp_chansrv_LDFLAGS = \
- $(EXTRA_FLAGS)
+ $(X_LIBS)
xrdp_chansrv_LDADD = \
- -L/usr/X11R6/lib \
$(top_builddir)/common/libcommon.la \
- -lX11 -lXfixes -lXrandr \
- $(EXTRA_LIBS)
+ $(X_PRE_LIBS) -lXfixes -lXrandr -lX11 $(X_EXTRA_LIBS) \
+ $(CHANSRV_EXTRA_LIBS)
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index af2f6957..25133fec 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -55,7 +55,7 @@ static tbus g_thread_done_event = 0;
static int g_use_unix_socket = 0;
-static char g_xrdpapi_magic[12] =
+static const unsigned char g_xrdpapi_magic[12] =
{ 0x78, 0x32, 0x10, 0x67, 0x00, 0x92, 0x30, 0x56, 0xff, 0xd8, 0xa9, 0x1f };
int g_display_num = 0;
@@ -97,7 +97,7 @@ add_timeout(int msoffset, void (*callback)(void *data), void *data)
LOG(10, ("add_timeout:"));
now = g_time3();
- tobj = g_malloc(sizeof(struct timeout_obj), 1);
+ tobj = g_new0(struct timeout_obj, 1);
tobj->mstime = now + msoffset;
tobj->callback = callback;
tobj->data = data;
@@ -734,8 +734,7 @@ process_message(void)
rv = process_message_channel_data_response(s);
break;
default:
- LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ",
- "unknown msg %d", id));
+ LOGM((LOG_LEVEL_ERROR, "process_message: unknown msg %d", id));
break;
}
@@ -756,7 +755,6 @@ int DEFAULT_CC
my_trans_data_in(struct trans *trans)
{
struct stream *s = (struct stream *)NULL;
- int id = 0;
int size = 0;
int error = 0;
@@ -772,7 +770,7 @@ my_trans_data_in(struct trans *trans)
LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:"));
s = trans_get_in_s(trans);
- in_uint32_le(s, id);
+ in_uint8s(s, 4); /* id */
in_uint32_le(s, size);
error = trans_force_read(trans, size - 8);
@@ -1184,7 +1182,7 @@ channel_thread_loop(void *in_val)
num_objs++;
trans_get_wait_objs(g_lis_trans, objs, &num_objs);
trans_get_wait_objs_rw(g_con_trans, objs, &num_objs,
- wobjs, &num_wobjs);
+ wobjs, &num_wobjs, &timeout);
trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
if (g_api_con_trans_list != 0)
@@ -1389,22 +1387,60 @@ read_ini(void)
}
/*****************************************************************************/
-static char* APP_CC
-get_log_path()
+static int APP_CC
+get_log_path(char *path, int bytes)
{
- char* log_path = 0;
+ char* log_path;
+ int rv;
+ rv = 1;
log_path = g_getenv("CHANSRV_LOG_PATH");
if (log_path == 0)
{
+ log_path = g_getenv("XDG_DATA_HOME");
+ if (log_path != 0)
+ {
+ g_snprintf(path, bytes, "%s%s", log_path, "/xrdp");
+ if (g_directory_exist(path) || (g_mkdir(path) == 0))
+ {
+ rv = 0;
+ }
+ }
+ }
+ else
+ {
+ g_snprintf(path, bytes, "%s", log_path);
+ if (g_directory_exist(path) || (g_mkdir(path) == 0))
+ {
+ rv = 0;
+ }
+ }
+ if (rv != 0)
+ {
log_path = g_getenv("HOME");
+ if (log_path != 0)
+ {
+ g_snprintf(path, bytes, "%s%s", log_path, "/.local");
+ if (g_directory_exist(path) || (g_mkdir(path) == 0))
+ {
+ g_snprintf(path, bytes, "%s%s", log_path, "/.local/share");
+ if (g_directory_exist(path) || (g_mkdir(path) == 0))
+ {
+ g_snprintf(path, bytes, "%s%s", log_path, "/.local/share/xrdp");
+ if (g_directory_exist(path) || (g_mkdir(path) == 0))
+ {
+ rv = 0;
+ }
+ }
+ }
+ }
}
- return log_path;
+ return rv;
}
/*****************************************************************************/
-static unsigned int APP_CC
-get_log_level(const char* level_str, unsigned int default_level)
+static enum logLevels APP_CC
+get_log_level(const char* level_str, enum logLevels default_level)
{
static const char* levels[] = {
"LOG_LEVEL_ALWAYS",
@@ -1423,7 +1459,7 @@ get_log_level(const char* level_str, unsigned int default_level)
{
if (g_strcasecmp(levels[i], level_str) == 0)
{
- return i;
+ return (enum logLevels) i;
}
}
return default_level;
@@ -1463,17 +1499,17 @@ main(int argc, char **argv)
tbus waiters[4];
int pid = 0;
char text[256];
- char* log_path;
+ char log_path[256];
char *display_text;
char log_file[256];
enum logReturns error;
struct log_config logconfig;
- unsigned int log_level;
+ enum logLevels log_level;
g_init("xrdp-chansrv"); /* os_calls */
- log_path = get_log_path();
- if (log_path == 0)
+ log_path[255] = 0;
+ if (get_log_path(log_path, 255) != 0)
{
g_writeln("error reading CHANSRV_LOG_PATH and HOME environment variable");
g_deinit();
@@ -1487,7 +1523,7 @@ main(int argc, char **argv)
/* starting logging subsystem */
g_memset(&logconfig, 0, sizeof(struct log_config));
- logconfig.program_name = "XRDP-Chansrv";
+ logconfig.program_name = "xrdp-chansrv";
g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", log_path);
g_writeln("chansrv::main: using log file [%s]", log_file);
@@ -1500,7 +1536,7 @@ main(int argc, char **argv)
logconfig.fd = -1;
logconfig.log_level = log_level;
logconfig.enable_syslog = 0;
- logconfig.syslog_level = 0;
+ logconfig.syslog_level = LOG_LEVEL_ALWAYS;
error = log_start_from_param(&logconfig);
if (error != LOG_STARTUP_OK)
@@ -1525,7 +1561,6 @@ main(int argc, char **argv)
LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid));
/* set up signal handler */
- g_signal_kill(term_signal_handler); /* SIGKILL */
g_signal_terminate(term_signal_handler); /* SIGTERM */
g_signal_user_interrupt(term_signal_handler); /* SIGINT */
g_signal_pipe(nil_signal_handler); /* SIGPIPE */
@@ -1534,7 +1569,9 @@ main(int argc, char **argv)
display_text = g_getenv("DISPLAY");
LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text));
- get_display_num_from_display(display_text);
+
+ if (display_text)
+ get_display_num_from_display(display_text);
if (g_display_num == 0)
{
@@ -1629,7 +1666,8 @@ struct_from_dvc_chan_id(tui32 dvc_chan_id)
for (i = 0; i < MAX_DVC_CHANNELS; i++)
{
- if (g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)
+ if (g_dvc_channels[i]->dvc_chan_id >= 0 &&
+ (tui32) g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)
{
return g_dvc_channels[i];
}
@@ -1645,7 +1683,8 @@ remove_struct_with_chan_id(tui32 dvc_chan_id)
for (i = 0; i < MAX_DVC_CHANNELS; i++)
{
- if (g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)
+ if (g_dvc_channels[i]->dvc_chan_id >= 0 &&
+ (tui32) g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)
{
g_dvc_channels[i] = NULL;
return 0;
diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c
index c4532ead..16fda322 100644
--- a/sesman/chansrv/chansrv_fuse.c
+++ b/sesman/chansrv/chansrv_fuse.c
@@ -19,7 +19,7 @@
/*
* TODO
* o when creating dir/file, ensure it does not already exist
- * o do not allow dirs to be created in ino==1 except for .clipbard and share mounts
+ * o do not allow dirs to be created in ino==1 except for .clipboard and share mounts
* o fix the HACK where I have to use my own buf instead of g_buffer
* this is in func xfuse_check_wait_objs()
* o if fuse mount point is already mounted, I get segfault
@@ -39,8 +39,6 @@
//#define USE_SYNC_FLAG
-static char g_fuse_mount_name[256] = "xrdp_client";
-
/* FUSE mount point */
char g_fuse_root_path[256] = "";
char g_fuse_clipboard_path[256] = ""; /* for clipboard use */
@@ -56,13 +54,14 @@ char g_fuse_clipboard_path[256] = ""; /* for clipboard use */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "arch.h"
#include "chansrv_fuse.h"
/* dummy calls when XRDP_FUSE is not defined */
-int xfuse_init() { return 0; }
-int xfuse_deinit() { return 0; }
+int xfuse_init(void) { return 0; }
+int xfuse_deinit(void) { return 0; }
int xfuse_check_wait_objs(void) { return 0; }
int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout) { return 0; }
int xfuse_clear_clip_dir(void) { return 0; }
@@ -73,7 +72,7 @@ int xfuse_create_share(tui32 device_id, char *dirname) { r
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId) {}
void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length) {}
void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length) {}
-int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) {}
+int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) { return 0; }
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) {}
void xfuse_devredir_cb_rmdir_or_file(void *vp, tui32 IoStatus) {}
void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus) {}
@@ -88,9 +87,8 @@ void xfuse_devredir_cb_file_close(void *vp) {}
******************************************************************************/
#define FUSE_USE_VERSION 26
-#define _FILE_OFFSET_BITS 64
-#include <fuse/fuse_lowlevel.h>
+#include <fuse_lowlevel.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -102,9 +100,16 @@ void xfuse_devredir_cb_file_close(void *vp) {}
#include "arch.h"
#include "os_calls.h"
+#include "clipboard_file.h"
#include "chansrv_fuse.h"
+#include "devredir.h"
#include "list.h"
#include "fifo.h"
+#include "file.h"
+
+#ifndef EREMOTEIO
+#define EREMOTEIO EIO
+#endif
#define min(x, y) ((x) < (y) ? (x) : (y))
@@ -234,6 +239,8 @@ struct opendir_req
struct fuse_file_info *fi;
};
+static char g_fuse_mount_name[256] = "xrdp_client";
+
FIFO g_fifo_opendir;
static struct list *g_req_list = 0;
@@ -248,10 +255,10 @@ static int g_fd = 0;
static tintptr g_bufsize = 0;
/* forward declarations for internal access */
-static int xfuse_init_xrdp_fs();
-static int xfuse_deinit_xrdp_fs();
+static int xfuse_init_xrdp_fs(void);
+static int xfuse_deinit_xrdp_fs(void);
static int xfuse_init_lib(struct fuse_args *args);
-static int xfuse_is_inode_valid(int ino);
+static int xfuse_is_inode_valid(fuse_ino_t ino);
// LK_TODO
#if 0
@@ -259,40 +266,27 @@ static void xfuse_create_file(fuse_req_t req, fuse_ino_t parent,
const char *name, mode_t mode, int type);
#endif
-static void xfuse_dump_fs();
-static void xfuse_dump_xrdp_inode(struct xrdp_inode *xino);
-static tui32 xfuse_get_device_id_for_inode(tui32 ino, char *full_path);
+static void xfuse_dump_fs(void);
+static tui32 xfuse_get_device_id_for_inode(fuse_ino_t ino, char *full_path);
static void fuse_reverse_pathname(char *full_path, char *reverse_path);
-static struct xrdp_inode * xfuse_get_inode_from_pinode_name(tui32 pinode,
+static struct xrdp_inode * xfuse_get_inode_from_pinode_name(fuse_ino_t pinode,
const char *name);
static struct xrdp_inode * xfuse_create_file_in_xrdp_fs(tui32 device_id,
int pinode, char *name,
int type);
-static int xfuse_does_file_exist(int parent, char *name);
-static int xfuse_delete_file(int parent, char *name);
+static int xfuse_does_file_exist(fuse_ino_t parent, char *name);
static int xfuse_delete_file_with_xinode(XRDP_INODE *xinode);
static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode);
static int xfuse_recursive_delete_dir_with_xinode(XRDP_INODE *xinode);
-static void xfuse_update_xrdpfs_size();
+static void xfuse_update_xrdpfs_size(void);
+
+#ifdef USE_SYNC_FLAG
static void xfuse_enum_dir(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t off, struct fuse_file_info *fi);
-
-/* forward declarations for calls we make into devredir */
-int dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path);
-
-int dev_redir_file_open(void *fusep, tui32 device_id, char *path,
- int mode, int type, char *gen_buf);
-
-int devredir_file_read(void *fusep, tui32 device_id, tui32 FileId,
- tui32 Length, tui64 Offset);
-
-int dev_redir_file_write(void *fusep, tui32 device_id, tui32 FileId,
- const char *buf, tui32 Length, tui64 Offset);
-
-int devredir_file_close(void *fusep, tui32 device_id, tui32 FileId);
+#endif
/* forward declarations for FUSE callbacks */
static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent,
@@ -301,10 +295,7 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent,
static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);
-/* this is not a callback, but its's used by xfuse_cb_readdir() */
-static void xfuse_dirbuf_add(fuse_req_t req, struct dirbuf *b,
- const char *name, fuse_ino_t ino);
-
+/* this is not a callback, but it's used by xfuse_cb_readdir() */
static int xfuse_dirbuf_add1(fuse_req_t req, struct dirbuf1 *b,
const char *name, fuse_ino_t ino);
@@ -348,8 +339,10 @@ static void xfuse_cb_create(fuse_req_t req, fuse_ino_t parent,
const char *name, mode_t mode,
struct fuse_file_info *fi);
+#if 0
static void xfuse_cb_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
struct fuse_file_info *fi);
+#endif
static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set, struct fuse_file_info *fi);
@@ -363,13 +356,9 @@ static int xfuse_proc_opendir_req(fuse_req_t req, fuse_ino_t ino,
static void xfuse_cb_releasedir(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);
-/* clipboard calls */
-int clipboard_request_file_data(int stream_id, int lindex, int offset,
- int request_bytes);
-
/* misc calls */
-static void xfuse_mark_as_stale(int pinode);
-static void xfuse_delete_stale_entries(int pinode);
+static void xfuse_mark_as_stale(fuse_ino_t pinode);
+static void xfuse_delete_stale_entries(fuse_ino_t pinode);
/*****************************************************************************/
int APP_CC
@@ -618,9 +607,10 @@ int xfuse_create_share(tui32 device_id, char *dirname)
if (dirname == NULL || strlen(dirname) == 0)
return -1;
- if ((xinode = calloc(1, sizeof(struct xrdp_inode))) == NULL)
+ xinode = g_new0(struct xrdp_inode, 1);
+ if (xinode == NULL)
{
- log_debug("calloc() failed");
+ log_debug("g_new0() failed");
return -1;
}
@@ -644,7 +634,7 @@ int xfuse_create_share(tui32 device_id, char *dirname)
/* insert it in xrdp fs */
g_xrdp_fs.inode_table[xinode->inode] = xinode;
log_debug("created new share named %s at inode_table[%d]",
- dirname, (int) xinode->inode);
+ dirname, xinode->inode);
/* update nentries in parent inode */
xinode = g_xrdp_fs.inode_table[1];
@@ -653,7 +643,8 @@ int xfuse_create_share(tui32 device_id, char *dirname)
xinode->nentries++;
#if 0
- if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
+ fip = g_new0(XFUSE_INFO, 1);
+ if (fip == NULL)
{
log_error("system out of memory");
return -1;
@@ -682,12 +673,17 @@ int xfuse_create_share(tui32 device_id, char *dirname)
int xfuse_clear_clip_dir(void)
{
- int i;
+ fuse_ino_t i;
XRDP_INODE *xinode;
XRDP_INODE *xip;
log_debug("entered");
+ if (g_xrdp_fs.inode_table == NULL)
+ {
+ return 0;
+ }
+
/* xinode for .clipboard */
xip = g_xrdp_fs.inode_table[2];
@@ -770,6 +766,11 @@ int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex)
2, /* parent inode */
filename,
S_IFREG);
+ if (xinode == NULL)
+ {
+ log_debug("failed to create file in xrdp filesystem");
+ return -1;
+ }
xinode->size = size;
xinode->lindex = lindex;
xinode->is_loc_resource = 1;
@@ -831,7 +832,7 @@ static int xfuse_init_lib(struct fuse_args *args)
fuse_session_add_chan(g_se, g_ch);
g_bufsize = fuse_chan_bufsize(g_ch);
- g_buffer = calloc(g_bufsize, 1);
+ g_buffer = g_new0(char, g_bufsize);
g_fd = fuse_chan_fd(g_ch);
g_req_list = list_create();
@@ -851,7 +852,7 @@ static int xfuse_init_xrdp_fs()
{
struct xrdp_inode *xino;
- g_xrdp_fs.inode_table = calloc(4096, sizeof(struct xrdp_inode *));
+ g_xrdp_fs.inode_table = g_new0(struct xrdp_inode *, 4096);
if (g_xrdp_fs.inode_table == NULL)
{
log_error("system out of memory");
@@ -862,7 +863,8 @@ static int xfuse_init_xrdp_fs()
* index 0 is our .. dir
*/
- if ((xino = calloc(1, sizeof(struct xrdp_inode))) == NULL)
+ xino = g_new0(struct xrdp_inode, 1);
+ if (xino == NULL)
{
log_error("system out of memory");
free(g_xrdp_fs.inode_table);
@@ -885,7 +887,8 @@ static int xfuse_init_xrdp_fs()
* index 1 is our . dir
*/
- if ((xino = calloc(1, sizeof(struct xrdp_inode))) == NULL)
+ xino = g_new0(struct xrdp_inode, 1);
+ if (xino == NULL)
{
log_error("system out of memory");
free(g_xrdp_fs.inode_table[0]);
@@ -909,7 +912,8 @@ static int xfuse_init_xrdp_fs()
* index 2 is for clipboard use
*/
- if ((xino = calloc(1, sizeof(struct xrdp_inode))) == NULL)
+ xino = g_new0(struct xrdp_inode, 1);
+ if (xino == NULL)
{
log_error("system out of memory");
free(g_xrdp_fs.inode_table[0]);
@@ -956,7 +960,7 @@ static int xfuse_deinit_xrdp_fs()
* @return 1 if it does, 0 otherwise
*****************************************************************************/
-static int xfuse_is_inode_valid(int ino)
+static int xfuse_is_inode_valid(fuse_ino_t ino)
{
/* is ino present in our table? */
if ((ino < FIRST_INODE) || (ino >= g_xrdp_fs.next_node))
@@ -980,18 +984,19 @@ static void xfuse_create_file(fuse_req_t req, fuse_ino_t parent,
struct xrdp_inode *xinode;
struct fuse_entry_param e;
- log_debug("parent=%d name=%s", (int) parent, name);
+ log_debug("parent=%ld name=%s", parent, name);
/* do we have a valid parent inode? */
if (!xfuse_is_inode_valid(parent))
{
- log_error("inode %d is not valid", parent);
+ log_error("inode %ld is not valid", parent);
fuse_reply_err(req, EBADF);
}
- if ((xinode = calloc(1, sizeof(struct xrdp_inode))) == NULL)
+ xinode = g_new0(struct xrdp_inode, 1);
+ if (xinode == NULL)
{
- log_error("calloc() failed");
+ log_error("g_new0() failed");
fuse_reply_err(req, ENOMEM);
}
@@ -1012,11 +1017,11 @@ static void xfuse_create_file(fuse_req_t req, fuse_ino_t parent,
/* insert it in xrdp fs */
g_xrdp_fs.inode_table[xinode->inode] = xinode;
xfuse_update_xrdpfs_size();
- log_debug("inserted new dir at inode_table[%d]", (int) xinode->inode);
+ log_debug("inserted new dir at inode_table[%d]", xinode->inode);
xfuse_dump_fs();
- log_debug("new inode=%d", (int) xinode->inode);
+ log_debug("new inode=%d", xinode->inode);
/* setup return value */
memset(&e, 0, sizeof(e));
@@ -1040,7 +1045,7 @@ static void xfuse_create_file(fuse_req_t req, fuse_ino_t parent,
static void xfuse_dump_fs()
{
- int i;
+ fuse_ino_t i;
struct xrdp_inode *xinode;
log_debug("found %d entries", g_xrdp_fs.num_entries - FIRST_INODE);
@@ -1056,11 +1061,11 @@ static void xfuse_dump_fs()
continue;
log_debug("pinode=%d inode=%d nentries=%d nopen=%d is_synced=%d name=%s",
- (int) xinode->parent_inode, (int) xinode->inode,
+ xinode->parent_inode, xinode->inode,
xinode->nentries, xinode->nopen, xinode->is_synced,
xinode->name);
}
- log_debug("");
+ log_debug("%s", "");
}
/**
@@ -1069,20 +1074,22 @@ static void xfuse_dump_fs()
* @param xino xinode structure to dump
*****************************************************************************/
+#if 0
static void xfuse_dump_xrdp_inode(struct xrdp_inode *xino)
{
log_debug("--- dumping struct xinode ---");
log_debug("name: %s", xino->name);
- log_debug("parent_inode: %ld", xino->parent_inode);
- log_debug("inode: %ld", xino->inode);
+ log_debug("parent_inode: %d", xino->parent_inode);
+ log_debug("inode: %d", xino->inode);
log_debug("mode: %o", xino->mode);
log_debug("nlink: %d", xino->nlink);
log_debug("uid: %d", xino->uid);
log_debug("gid: %d", xino->gid);
- log_debug("size: %ld", xino->size);
+ log_debug("size: %zd", xino->size);
log_debug("device_id: %d", xino->device_id);
- log_debug("");
+ log_debug("%s", "");
}
+#endif
/**
* Return the device_id associated with specified inode and copy the
@@ -1094,10 +1101,10 @@ static void xfuse_dump_xrdp_inode(struct xrdp_inode *xino)
* @return the device_id of specified inode
*****************************************************************************/
-static tui32 xfuse_get_device_id_for_inode(tui32 ino, char *full_path)
+static tui32 xfuse_get_device_id_for_inode(fuse_ino_t ino, char *full_path)
{
- tui32 parent_inode = 0;
- tui32 child_inode = ino;
+ fuse_ino_t parent_inode = 0;
+ fuse_ino_t child_inode = ino;
char reverse_path[4096];
/* ino == 1 is a special case; we already know that it is not */
@@ -1105,7 +1112,7 @@ static tui32 xfuse_get_device_id_for_inode(tui32 ino, char *full_path)
if (ino == 1)
{
/* just return the device_id for the file in full_path */
- log_debug("looking for file with pinode=%d name=%s", ino, full_path);
+ log_debug("looking for file with pinode=%ld name=%s", ino, full_path);
xfuse_dump_fs();
XRDP_INODE *xinode = xfuse_get_inode_from_pinode_name(ino, full_path);
@@ -1164,10 +1171,10 @@ static void fuse_reverse_pathname(char *full_path, char *reverse_path)
* Return the inode that matches the name and parent inode
*****************************************************************************/
-static struct xrdp_inode * xfuse_get_inode_from_pinode_name(tui32 pinode,
+static struct xrdp_inode * xfuse_get_inode_from_pinode_name(fuse_ino_t pinode,
const char *name)
{
- int i;
+ fuse_ino_t i;
struct xrdp_inode * xinode;
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
@@ -1207,7 +1214,8 @@ static struct xrdp_inode * xfuse_create_file_in_xrdp_fs(tui32 device_id,
if ((name == NULL) || (strlen(name) == 0))
return NULL;
- if ((xinode = calloc(1, sizeof(XRDP_INODE))) == NULL)
+ xinode = g_new0(XRDP_INODE, 1);
+ if (xinode == NULL)
{
log_error("system out of memory");
return NULL;
@@ -1254,14 +1262,14 @@ static struct xrdp_inode * xfuse_create_file_in_xrdp_fs(tui32 device_id,
* Check if specified file exists
*
* @param parent parent inode of file
- * @param name flilename or dirname
+ * @param name filename or dirname
*
* @return 1 if specified file exists, 0 otherwise
*****************************************************************************/
-static int xfuse_does_file_exist(int parent, char *name)
+static int xfuse_does_file_exist(fuse_ino_t parent, char *name)
{
- int i;
+ fuse_ino_t i;
XRDP_INODE *xinode;
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
@@ -1279,11 +1287,6 @@ static int xfuse_does_file_exist(int parent, char *name)
return 0;
}
-static int xfuse_delete_file(int parent, char *name)
-{
- return -1;
-}
-
static int xfuse_delete_file_with_xinode(XRDP_INODE *xinode)
{
/* make sure it is not a dir */
@@ -1303,7 +1306,7 @@ static int xfuse_delete_file_with_xinode(XRDP_INODE *xinode)
static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode)
{
XRDP_INODE *xip;
- int i;
+ fuse_ino_t i;
/* make sure it is not a file */
if ((xinode == NULL) || (xinode->mode & S_IFREG))
@@ -1339,7 +1342,7 @@ static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode)
static int xfuse_recursive_delete_dir_with_xinode(XRDP_INODE *xinode)
{
XRDP_INODE *xip;
- int i;
+ fuse_ino_t i;
/* make sure it is not a file */
if ((xinode == NULL) || (xinode->mode & S_IFREG))
@@ -1404,12 +1407,12 @@ static void xfuse_update_xrdpfs_size()
}
/* zero newly added memory */
- memset(vp + g_xrdp_fs.max_entries * sizeof(struct xrdp_inode *),
+ memset((char *) vp + g_xrdp_fs.max_entries * sizeof(struct xrdp_inode *),
0,
100 * sizeof(struct xrdp_inode *));
g_xrdp_fs.max_entries += 100;
- g_xrdp_fs.inode_table = vp;
+ g_xrdp_fs.inode_table = (struct xrdp_inode **) vp;
}
/******************************************************************************
@@ -1435,12 +1438,12 @@ int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
if (!xfuse_is_inode_valid(fip->inode))
{
- log_error("inode %d is not valid", fip->inode);
+ log_error("inode %ld is not valid", fip->inode);
g_free(xinode);
return -1;
}
- log_debug("parent_inode=%d name=%s", fip->inode, xinode->name);
+ log_debug("parent_inode=%ld name=%s", fip->inode, xinode->name);
/* if filename is . or .. don't add it */
if ((strcmp(xinode->name, ".") == 0) || (strcmp(xinode->name, "..") == 0))
@@ -1453,7 +1456,7 @@ int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
if ((xip = xfuse_get_inode_from_pinode_name(fip->inode, xinode->name)) != NULL)
{
- log_debug("inode=%d name=%s already exists in xrdp_fs; not adding it",
+ log_debug("inode=%ld name=%s already exists in xrdp_fs; not adding it",
fip->inode, xinode->name);
g_free(xinode);
xip->stale = 0;
@@ -1506,7 +1509,7 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
/* do we have a valid inode? */
if (!xfuse_is_inode_valid(fip->inode))
{
- log_error("inode %d is not valid", fip->inode);
+ log_error("inode %ld is not valid", fip->inode);
if (fip->invoke_fuse)
fuse_reply_err(fip->req, EBADF);
goto done;
@@ -1515,9 +1518,9 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
xfuse_delete_stale_entries(fip->inode);
/* this will be used by xfuse_cb_readdir() */
- di = calloc(1, sizeof(struct dir_info));
+ di = g_new0(struct dir_info, 1);
di->index = FIRST_INODE;
- fip->fi->fh = (long) di;
+ fip->fi->fh = (tintptr) di;
fuse_reply_open(fip->req, fip->fi);
@@ -1532,7 +1535,7 @@ done:
while (1)
{
/* process next request */
- odreq = fifo_peek(&g_fifo_opendir);
+ odreq = (struct opendir_req *) fifo_peek(&g_fifo_opendir);
if (!odreq)
return;
@@ -1585,7 +1588,8 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId,
if (fip->fi != NULL)
{
- if ((fh = calloc(1, sizeof(XFUSE_HANDLE))) == NULL)
+ fh = g_new0(XFUSE_HANDLE, 1);
+ if (fh == NULL)
{
log_error("system out of memory");
if (fip->invoke_fuse)
@@ -1599,9 +1603,9 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId,
fh->DeviceId = DeviceId;
fh->FileId = FileId;
- fip->fi->fh = (uint64_t) ((long) fh);
- log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
- fip, fip->fi, fip->fi->fh);
+ fip->fi->fh = (tintptr) fh;
+ log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=0x%llx",
+ fip, fip->fi, (long long) fip->fi->fh);
}
if (fip->invoke_fuse)
@@ -1626,7 +1630,7 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId,
#if 0
if ((xinode = g_xrdp_fs.inode_table[fip->inode]) == NULL)
{
- log_error("inode at inode_table[%d] is NULL", fip->inode);
+ log_error("inode at inode_table[%ld] is NULL", fip->inode);
fuse_reply_err(fip->req, EBADF);
goto done;
}
@@ -1704,8 +1708,8 @@ void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length)
return;
}
- log_debug("+++ XFUSE_INFO=%p, XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
- fip, fip->fi, fip->fi->fh);
+ log_debug("+++ XFUSE_INFO=%p, XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=0x%llx",
+ fip, fip->fi, (long long) fip->fi->fh);
fuse_reply_write(fip->req, length);
@@ -1713,7 +1717,7 @@ void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length)
if ((xinode = g_xrdp_fs.inode_table[fip->inode]) != NULL)
xinode->size += length;
else
- log_error("inode at inode_table[%d] is NULL", fip->inode);
+ log_error("inode at inode_table[%ld] is NULL", fip->inode);
free(fip);
}
@@ -1834,12 +1838,12 @@ void xfuse_devredir_cb_file_close(void *vp)
return;
}
- log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
- fip, fip->fi, fip->fi->fh);
+ log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=0x%llx",
+ fip, fip->fi, (long long) fip->fi->fh);
if ((xinode = g_xrdp_fs.inode_table[fip->inode]) == NULL)
{
- log_debug("inode_table[%d] is NULL", fip->inode);
+ log_debug("inode_table[%ld] is NULL", fip->inode);
fuse_reply_err(fip->req, EBADF);
return;
}
@@ -1853,11 +1857,11 @@ void xfuse_devredir_cb_file_close(void *vp)
#if 0
if ((xinode->nopen == 0) && fip->fi && fip->fi->fh)
{
- printf("LK_TODO: ################################ fi=%p fi->fh=%p\n",
- fip->fi, fip->fi->fh);
+ printf("LK_TODO: ################################ fi=%p fi->fh=0x%llx\n",
+ fip->fi, (long long) fip->fi->fh);
free((char *) (tintptr) (fip->fi->fh));
- fip->fi->fh = NULL;
+ fip->fi->fh = 0;
}
#endif
@@ -1880,12 +1884,12 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
XRDP_INODE *xinode;
struct fuse_entry_param e;
- log_debug("looking for parent=%d name=%s", (int) parent, name);
+ log_debug("looking for parent=%ld name=%s", parent, name);
xfuse_dump_fs();
if (!xfuse_is_inode_valid(parent))
{
- log_error("inode %d is not valid", parent);
+ log_error("inode %ld is not valid", parent);
fuse_reply_err(req, EBADF);
return;
}
@@ -1893,7 +1897,7 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
xinode = xfuse_get_inode_from_pinode_name(parent, name);
if (xinode == NULL)
{
- log_debug("did not find entry for parent=%d name=%s", parent, name);
+ log_debug("did not find entry for parent=%ld name=%s", parent, name);
fuse_reply_err(req, ENOENT);
return;
}
@@ -1914,7 +1918,7 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
e.generation = 1;
fuse_reply_entry(req, &e);
- log_debug("found entry for parent=%d name=%s uid=%d gid=%d",
+ log_debug("found entry for parent=%ld name=%s uid=%d gid=%d",
parent, name, xinode->uid, xinode->gid);
return;
}
@@ -1931,12 +1935,12 @@ static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
(void) fi;
- log_debug("req=%p ino=%d", req, (int) ino);
+ log_debug("req=%p ino=%ld", req, ino);
/* if ino is not valid, just return */
if (!xfuse_is_inode_valid(ino))
{
- log_error("inode %d is not valid", ino);
+ log_error("inode %ld is not valid", ino);
fuse_reply_err(req, EBADF);
return;
}
@@ -1944,7 +1948,7 @@ static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
xino = g_xrdp_fs.inode_table[ino];
if (!xino)
{
- log_debug("****** invalid ino=%d", (int) ino);
+ log_debug("****** invalid ino=%ld", ino);
fuse_reply_err(req, EBADF);
return;
}
@@ -1961,13 +1965,14 @@ static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
*
*****************************************************************************/
+#if 0
static void xfuse_dirbuf_add(fuse_req_t req, struct dirbuf *b,
const char *name, fuse_ino_t ino)
{
struct stat stbuf;
size_t oldsize = b->size;
- log_debug("adding ino=%d name=%s", (int) ino, name);
+ log_debug("adding ino=%ld name=%s", ino, name);
b->size += fuse_add_direntry(req, NULL, 0, name, NULL, 0);
b->p = (char *) realloc(b->p, b->size);
@@ -1977,6 +1982,7 @@ static void xfuse_dirbuf_add(fuse_req_t req, struct dirbuf *b,
fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf,
b->size);
}
+#endif
static int xfuse_dirbuf_add1(fuse_req_t req, struct dirbuf1 *b,
const char *name, fuse_ino_t ino)
@@ -2017,15 +2023,15 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
XRDP_INODE *ti;
struct dir_info *di;
struct dirbuf1 b;
- int i;
+ fuse_ino_t i;
int first_time;
- log_debug("req=%p inode=%d size=%d offset=%d", req, ino, size, off);
+ log_debug("req=%p inode=%ld size=%zd offset=%lld", req, ino, size, (long long) off);
/* do we have a valid inode? */
if (!xfuse_is_inode_valid(ino))
{
- log_error("inode %d is not valid", ino);
+ log_error("inode %ld is not valid", ino);
fuse_reply_err(req, EBADF);
return;
}
@@ -2058,7 +2064,7 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
ti = g_xrdp_fs.inode_table[ino];
if (!ti)
{
- log_debug("****** g_xrdp_fs.inode_table[%d] is NULL", ino);
+ log_debug("****** g_xrdp_fs.inode_table[%ld] is NULL", ino);
fuse_reply_buf(req, NULL, 0);
return;
}
@@ -2086,7 +2092,7 @@ static void xfuse_cb_mkdir(fuse_req_t req, fuse_ino_t parent,
XRDP_INODE *xinode;
struct fuse_entry_param e;
- log_debug("entered: parent_inode=%d name=%s", (int) parent, name);
+ log_debug("entered: parent_inode=%ld name=%s", parent, name);
if ((xinode = xfuse_get_inode_from_pinode_name(parent, name)) != NULL)
{
@@ -2146,19 +2152,19 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent,
char full_path[4096];
tui32 device_id;
- log_debug("entered: parent=%d name=%s", parent, name);
+ log_debug("entered: parent=%ld name=%s", parent, name);
/* is parent inode valid? */
if (!xfuse_is_inode_valid(parent))
{
- log_error("inode %d is not valid", parent);
+ log_error("inode %ld is not valid", parent);
fuse_reply_err(req, EBADF);
return;
}
if ((xinode = xfuse_get_inode_from_pinode_name(parent, name)) == NULL)
{
- log_error("did not find file with pinode=%d name=%s", parent, name);
+ log_error("did not find file with pinode=%ld name=%s", parent, name);
fuse_reply_err(req, EBADF);
return;
}
@@ -2185,7 +2191,7 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent,
}
strcat(full_path, "/");
- strncat(full_path, name, sizeof(full_path) - strlen(full_path));
+ strncat(full_path, name, sizeof(full_path) - strlen(full_path) - 1);
if (xinode->is_loc_resource)
{
@@ -2199,7 +2205,8 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent,
/* specified file resides on redirected share */
- if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
+ fip = g_new0(XFUSE_INFO, 1);
+ if (fip == NULL)
{
log_error("system out of memory");
fuse_reply_err(req, ENOMEM);
@@ -2248,18 +2255,18 @@ static void xfuse_cb_rename(fuse_req_t req,
char *cptr;
char old_full_path[1024];
char new_full_path[1024];
- char *cp;
+ const char *cp;
tui32 device_id;
- log_debug("entered: old_parent=%d old_name=%s new_parent=%d new_name=%s",
+ log_debug("entered: old_parent=%ld old_name=%s new_parent=%ld new_name=%s",
old_parent, old_name, new_parent, new_name);
xfuse_dump_fs();
/* is old_parent inode valid? */
if (!xfuse_is_inode_valid(old_parent))
{
- log_error("inode %d is not valid", old_parent);
+ log_error("inode %ld is not valid", old_parent);
fuse_reply_err(req, EINVAL);
return;
}
@@ -2267,7 +2274,7 @@ static void xfuse_cb_rename(fuse_req_t req,
/* is new_parent inode valid? */
if (!xfuse_is_inode_valid(new_parent))
{
- log_error("inode %d is not valid", new_parent);
+ log_error("inode %ld is not valid", new_parent);
fuse_reply_err(req, EINVAL);
return;
}
@@ -2287,7 +2294,7 @@ static void xfuse_cb_rename(fuse_req_t req,
old_xinode = xfuse_get_inode_from_pinode_name(old_parent, old_name);
if (old_xinode == NULL)
{
- log_error("did not find file with pinode=%d name=%s",
+ log_error("did not find file with pinode=%ld name=%s",
old_parent, old_name);
fuse_reply_err(req, EBADF);
return;
@@ -2328,7 +2335,8 @@ static void xfuse_cb_rename(fuse_req_t req,
strcat(old_full_path, "/");
strcat(old_full_path, old_name);
- if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
+ fip = g_new0(XFUSE_INFO, 1);
+ if (fip == NULL)
{
log_error("system out of memory");
fuse_reply_err(req, ENOMEM);
@@ -2396,8 +2404,8 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent,
full_path[0] = 0;
- log_debug("entered: parent_ino=%d name=%s type=%s",
- (int) parent, name, (type == S_IFDIR) ? "dir" : "file");
+ log_debug("entered: parent_ino=%ld name=%s type=%s",
+ parent, name, (type == S_IFDIR) ? "dir" : "file");
/* name must be valid */
if ((name == NULL) || (strlen(name) == 0))
@@ -2410,7 +2418,7 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent,
/* is parent inode valid? */
if ((parent == 1) || (!xfuse_is_inode_valid(parent)))
{
- log_error("inode %d is not valid", parent);
+ log_error("inode %ld is not valid", parent);
fuse_reply_err(req, EBADF);
return;
}
@@ -2432,7 +2440,8 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent,
/* specified file resides on redirected share */
- if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
+ fip = g_new0(XFUSE_INFO, 1);
+ if (fip == NULL)
{
log_error("system out of memory");
fuse_reply_err(req, ENOMEM);
@@ -2488,11 +2497,11 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
char full_path[4096];
tui32 device_id;
- log_debug("entered: ino=%d", (int) ino);
+ log_debug("entered: ino=%ld", ino);
if (!xfuse_is_inode_valid(ino))
{
- log_error("inode %d is not valid", ino);
+ log_error("inode %ld is not valid", ino);
fuse_reply_err(req, EBADF);
return;
}
@@ -2501,7 +2510,7 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
xinode = g_xrdp_fs.inode_table[ino];
if (!xinode)
{
- log_debug("****** g_xrdp_fs.inode_table[%d] is NULL", ino);
+ log_debug("****** g_xrdp_fs.inode_table[%ld] is NULL", ino);
fuse_reply_err(req, EBADF);
return;
}
@@ -2512,21 +2521,22 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
return;
}
- device_id = xfuse_get_device_id_for_inode((tui32) ino, full_path);
+ device_id = xfuse_get_device_id_for_inode(ino, full_path);
if (xinode->is_loc_resource)
{
/* specified file is a local resource */
- XFUSE_HANDLE *fh = calloc(1, sizeof(XFUSE_HANDLE));
+ XFUSE_HANDLE *fh = g_new0(XFUSE_HANDLE, 1);
fh->is_loc_resource = 1;
- fi->fh = (uint64_t) ((long) fh);
+ fi->fh = (tintptr) fh;
fuse_reply_open(req, fi);
return;
}
/* specified file resides on redirected share */
- if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
+ fip = g_new0(XFUSE_INFO, 1);
+ if (fip == NULL)
{
log_error("system out of memory");
fuse_reply_err(req, ENOMEM);
@@ -2572,13 +2582,13 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
{
XFUSE_INFO *fip = NULL;
XFUSE_HANDLE *handle = (XFUSE_HANDLE *) (tintptr) (fi->fh);
- tui32 FileId;
- log_debug("entered: ino=%d fi=%p fi->fh=%p", (int) ino, fi, fi->fh);
+ log_debug("entered: ino=%ld fi=%p fi->fh=0x%llx", ino, fi,
+ (long long) fi->fh);
if (!xfuse_is_inode_valid(ino))
{
- log_error("inode %d is not valid", ino);
+ log_error("inode %ld is not valid", ino);
fuse_reply_err(req, EBADF);
return;
}
@@ -2586,7 +2596,7 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
XRDP_INODE *xinode = g_xrdp_fs.inode_table[ino];
if (!xinode)
{
- log_debug("****** g_xrdp_fs.inode_table[%d] is NULL", ino);
+ log_debug("****** g_xrdp_fs.inode_table[%ld] is NULL", ino);
fuse_reply_err(req, 0);
return;
}
@@ -2609,7 +2619,8 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
return;
}
- if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
+ fip = g_new0(XFUSE_INFO, 1);
+ if (fip == NULL)
{
log_error("system out of memory");
fuse_reply_err(req, ENOMEM);
@@ -2622,10 +2633,9 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
fip->device_id = handle->DeviceId;
fip->fi = fi;
- log_debug(" +++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
- fip, fip->fi, fip->fi->fh);
+ log_debug(" +++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=0x%llx",
+ fip, fip->fi, (long long) fip->fi->fh);
- FileId = handle->FileId;
fip->fi->fh = 0;
xinode->close_in_progress = 1;
@@ -2650,7 +2660,7 @@ static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size,
struct req_list_item *rli;
long handle;
- log_debug("want_bytes %ld bytes at off %ld", size, off);
+ log_debug("want_bytes %zd bytes at off %lld", size, (long long) off);
if (fi->fh == 0)
{
@@ -2674,8 +2684,7 @@ static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size,
return;
}
- rli = (struct req_list_item *)
- g_malloc(sizeof(struct req_list_item), 1);
+ rli = g_new0(struct req_list_item, 1);
rli->stream_id = 0;
rli->req = req;
@@ -2686,8 +2695,8 @@ static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size,
if (g_req_list->count == 1)
{
- log_debug("requesting clipboard file data lindex = %d off = %d size = %d",
- rli->lindex, (int) off, (int) size);
+ log_debug("requesting clipboard file data lindex = %d off = %lld size = %zd",
+ rli->lindex, (long long) off, size);
clipboard_request_file_data(rli->stream_id, rli->lindex,
(int) off, (int) size);
@@ -2698,7 +2707,8 @@ static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size,
/* target file is on a remote device */
- if ((fusep = calloc(1, sizeof(XFUSE_INFO))) == NULL)
+ fusep = g_new0(XFUSE_INFO, 1);
+ if (fusep == NULL)
{
log_error("system out of memory");
fuse_reply_err(req, ENOMEM);
@@ -2723,8 +2733,8 @@ static void xfuse_cb_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
XFUSE_INFO *fusep;
long handle;
- log_debug("write %d bytes at off %d to inode=%d",
- (int) size, (int) off, (int) ino);
+ log_debug("write %zd bytes at off %lld to inode=%ld",
+ size, (long long) off, ino);
if (fi->fh == 0)
{
@@ -2745,7 +2755,8 @@ static void xfuse_cb_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
/* target file is on a remote device */
- if ((fusep = calloc(1, sizeof(XFUSE_INFO))) == NULL)
+ fusep = g_new0(XFUSE_INFO, 1);
+ if (fusep == NULL)
{
log_error("system out of memory");
fuse_reply_err(req, ENOMEM);
@@ -2758,8 +2769,8 @@ static void xfuse_cb_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
fusep->device_id = fh->DeviceId;
fusep->fi = fi;
- log_debug("+++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p",
- fusep, fusep->fi, fusep->fi->fh);
+ log_debug("+++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=0x%llx",
+ fusep, fusep->fi, (long long) fusep->fi->fh);
dev_redir_file_write(fusep, fh->DeviceId, fh->FileId, buf, size, off);
log_debug("exiting");
@@ -2772,8 +2783,8 @@ static void xfuse_cb_create(fuse_req_t req, fuse_ino_t parent,
const char *name, mode_t mode,
struct fuse_file_info *fi)
{
- log_debug("entered: parent_inode=%d, name=%s fi=%p",
- (int) parent, name, fi);
+ log_debug("entered: parent_inode=%ld, name=%s fi=%p",
+ parent, name, fi);
xfuse_create_dir_or_file(req, parent, name, mode, fi, S_IFREG);
}
@@ -2781,13 +2792,15 @@ static void xfuse_cb_create(fuse_req_t req, fuse_ino_t parent,
/**
*****************************************************************************/
+#if 0
static void xfuse_cb_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
struct fuse_file_info *fi)
{
- log_debug("#################### entered: ino=%d datasync=%d", (int) ino, datasync);
+ log_debug("#################### entered: ino=%ld datasync=%d", ino, datasync);
log_debug("function not required");
fuse_reply_err(req, EINVAL);
}
+#endif
/**
*****************************************************************************/
@@ -2802,14 +2815,14 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if (!xfuse_is_inode_valid(ino))
{
- log_error("inode %d is not valid", ino);
+ log_error("inode %ld is not valid", ino);
fuse_reply_err(req, EBADF);
return;
}
if ((xinode = g_xrdp_fs.inode_table[ino]) == NULL)
{
- log_debug("g_xrdp_fs.inode_table[%d] is NULL", ino);
+ log_debug("g_xrdp_fs.inode_table[%ld] is NULL", ino);
fuse_reply_err(req, EBADF);
return;
}
@@ -2835,9 +2848,9 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if (to_set & FUSE_SET_ATTR_SIZE)
{
- log_debug("previous file size: %d", attr->st_size);
+ log_debug("previous file size: %lld", (long long) attr->st_size);
xinode->size = attr->st_size;
- log_debug("returning file size: %d", xinode->size);
+ log_debug("returning file size: %zd", xinode->size);
}
if (to_set & FUSE_SET_ATTR_ATIME)
@@ -2886,7 +2899,7 @@ static void xfuse_cb_opendir(fuse_req_t req, fuse_ino_t ino,
struct opendir_req *odreq;
/* save request */
- odreq = malloc(sizeof(struct opendir_req));
+ odreq = g_new(struct opendir_req, 1);
odreq->req = req;
odreq->ino = ino;
odreq->fi = fi;
@@ -2918,11 +2931,11 @@ static int xfuse_proc_opendir_req(fuse_req_t req, fuse_ino_t ino,
char full_path[4096];
char *cptr;
- log_debug("inode=%d", ino);
+ log_debug("inode=%ld", ino);
if (!xfuse_is_inode_valid(ino))
{
- log_error("inode %d is not valid", ino);
+ log_error("inode %ld is not valid", ino);
fuse_reply_err(req, EBADF);
g_free(fifo_remove(&g_fifo_opendir));
return -1;
@@ -2933,7 +2946,7 @@ static int xfuse_proc_opendir_req(fuse_req_t req, fuse_ino_t ino,
if ((xinode = g_xrdp_fs.inode_table[ino]) == NULL)
{
- log_debug("g_xrdp_fs.inode_table[%d] is NULL", ino);
+ log_debug("g_xrdp_fs.inode_table[%ld] is NULL", ino);
fuse_reply_err(req, EBADF);
g_free(fifo_remove(&g_fifo_opendir));
return -1;
@@ -2955,18 +2968,19 @@ static int xfuse_proc_opendir_req(fuse_req_t req, fuse_ino_t ino,
{
goto do_remote_lookup;
}
-#endif
do_remote_lookup:
+#endif
- xfuse_mark_as_stale((int) ino);
+ xfuse_mark_as_stale(ino);
log_debug("did not find entry; redirecting call to dev_redir");
- device_id = xfuse_get_device_id_for_inode((tui32) ino, full_path);
+ device_id = xfuse_get_device_id_for_inode(ino, full_path);
- log_debug("dev_id=%d ino=%d full_path=%s", device_id, ino, full_path);
+ log_debug("dev_id=%d ino=%ld full_path=%s", device_id, ino, full_path);
- if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
+ fip = g_new0(XFUSE_INFO, 1);
+ if (fip == NULL)
{
log_error("system out of memory");
fuse_reply_err(req, ENOMEM);
@@ -3008,9 +3022,9 @@ do_remote_lookup:
done:
- di = calloc(1, sizeof(struct dir_info));
+ di = g_new0(struct dir_info, 1);
di->index = FIRST_INODE;
- fi->fh = (long) di;
+ fi->fh = (tintptr) di;
fuse_reply_open(req, fi);
g_free(fifo_remove(&g_fifo_opendir));
return -1;
@@ -3042,9 +3056,9 @@ static void xfuse_cb_releasedir(fuse_req_t req, fuse_ino_t ino,
*****************************************************************************/
static void
-xfuse_mark_as_stale(int pinode)
+xfuse_mark_as_stale(fuse_ino_t pinode)
{
- int i;
+ fuse_ino_t i;
XRDP_INODE *xinode;
if ((pinode < FIRST_INODE) || (pinode >= g_xrdp_fs.num_entries))
@@ -3071,9 +3085,9 @@ xfuse_mark_as_stale(int pinode)
*****************************************************************************/
static void
-xfuse_delete_stale_entries(int pinode)
+xfuse_delete_stale_entries(fuse_ino_t pinode)
{
- int i;
+ fuse_ino_t i;
XRDP_INODE *xinode;
if ((pinode < FIRST_INODE) || (pinode >= g_xrdp_fs.num_entries))
diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c
index 310e2093..7a9795d6 100644
--- a/sesman/chansrv/clipboard.c
+++ b/sesman/chansrv/clipboard.c
@@ -176,6 +176,8 @@ x-special/gnome-copied-files
#define LOG_ERROR 0
#define LOG_INFO 1
#define LOG_DEBUG 2
+
+#undef LOG_LEVEL
#define LOG_LEVEL LOG_ERROR
#define log_error(_params...) \
@@ -271,7 +273,7 @@ static int g_cliprdr_flags = CB_USE_LONG_FORMAT_NAMES |
CB_FILECLIP_NO_FILE_PATHS;
/* from client to server */
-/* last recieved CLIPRDR_FORMAT_LIST(CLIPRDR_FORMAT_ANNOUNCE) */
+/* last received CLIPRDR_FORMAT_LIST(CLIPRDR_FORMAT_ANNOUNCE) */
static int g_formatIds[16];
static int g_num_formatIds = 0;
@@ -580,7 +582,7 @@ clipboard_send_format_ack(void)
/*****************************************************************************/
/* returns number of bytes written */
int APP_CC
-clipboard_out_unicode(struct stream *s, char *text, int num_chars)
+clipboard_out_unicode(struct stream *s, const char *text, int num_chars)
{
int index;
int lnum_chars;
@@ -1084,11 +1086,11 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
/* response to CB_FORMAT_LIST; used to indicate whether
processing of the Format List PDU was successful */
static int APP_CC
-clipboard_prcoess_format_ack(struct stream *s, int clip_msg_status,
+clipboard_process_format_ack(struct stream *s, int clip_msg_status,
int clip_msg_len)
{
- log_debug("clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK");
- log_debug("clipboard_prcoess_format_ack:");
+ log_debug("clipboard_process_format_ack: CLIPRDR_FORMAT_ACK");
+ log_debug("clipboard_process_format_ack:");
return 0;
}
@@ -1547,7 +1549,7 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
{
log_error("aborting clipboard_data_in - clipboard has not "
"been initialized");
- /* we return 0 here to indicate no protocol problem occured */
+ /* we return 0 here to indicate no protocol problem occurred */
return 0;
}
@@ -1632,7 +1634,7 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
/* response to CB_FORMAT_LIST; used to indicate whether */
/* processing of the Format List PDU was successful */
case CB_FORMAT_LIST_RESPONSE: /* 3 CLIPRDR_FORMAT_ACK */
- rv = clipboard_prcoess_format_ack(ls, clip_msg_status,
+ rv = clipboard_process_format_ack(ls, clip_msg_status,
clip_msg_len);
break;
/* sent by recipient of CB_FORMAT_LIST; used to request data for one */
@@ -1695,16 +1697,16 @@ clipboard_event_selection_owner_notify(XEvent *xevent)
XFixesSelectionNotifyEvent *lxevent;
lxevent = (XFixesSelectionNotifyEvent *)xevent;
- log_debug("clipboard_event_selection_owner_notify: %p", lxevent->owner);
+ log_debug("clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner);
log_debug("clipboard_event_selection_owner_notify: "
- "window %d subtype %d owner %d g_wnd %d",
+ "window %ld subtype %d owner %ld g_wnd %ld",
lxevent->window, lxevent->subtype, lxevent->owner, g_wnd);
if (lxevent->owner == g_wnd)
{
log_debug("clipboard_event_selection_owner_notify: matches g_wnd");
log_debug("clipboard_event_selection_owner_notify: skipping, "
- "onwer == g_wnd");
+ "owner == g_wnd");
g_got_selection = 1;
return 0;
}
@@ -1733,7 +1735,7 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom *type, int *fmt,
Atom ltype;
log_debug("clipboard_get_window_property:");
- log_debug(" prop %d name %s", prop, get_atom_text(prop));
+ log_debug(" prop %ld name %s", prop, get_atom_text(prop));
lxdata = 0;
ltype = 0;
XGetWindowProperty(g_display, wnd, prop, 0, 0, 0,
@@ -1871,7 +1873,7 @@ clipboard_event_selection_notify(XEvent *xevent)
if (rv == 0)
{
- log_debug("clipboard_event_selection_notify: wnd %p prop %s",
+ log_debug("clipboard_event_selection_notify: wnd 0x%lx prop %s",
lxevent->requestor,
get_atom_text(lxevent->property));
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
@@ -1887,7 +1889,7 @@ clipboard_event_selection_notify(XEvent *xevent)
XDeleteProperty(g_display, lxevent->requestor, lxevent->property);
if (type == g_incr_atom)
{
- /* nothing more to do here, the data is comming in through
+ /* nothing more to do here, the data is coming in through
PropertyNotify */
log_debug("clipboard_event_selection_notify: type is INCR "
"data_size %d property name %s type %s", data_size,
@@ -1918,9 +1920,10 @@ clipboard_event_selection_notify(XEvent *xevent)
for (index = 0; index < n_items; index++)
{
atom = atoms[index];
- LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d",
+ LOGM((LOG_LEVEL_DEBUG,
+ "clipboard_event_selection_notify: 0x%lx %s 0x%lx",
atom, get_atom_text(atom), XA_STRING));
- log_debug("clipboard_event_selection_notify: 0x%x %s",
+ log_debug("clipboard_event_selection_notify: 0x%lx %s",
atom, get_atom_text(atom));
if (atom == g_utf8_atom)
{
@@ -1941,15 +1944,15 @@ clipboard_event_selection_notify(XEvent *xevent)
}
else
{
- log_error("clipboard_event_selection_notify: unknown atom 0x%x", atom);
+ log_error("clipboard_event_selection_notify: unknown atom 0x%lx", atom);
}
}
}
else
{
log_error("clipboard_event_selection_notify: error, "
- "target is 'TARGETS' and type[%d] or fmt[%d] not right, "
- "should be type[%d], fmt[%d]", type, fmt, XA_ATOM, 32);
+ "target is 'TARGETS' and type[%ld] or fmt[%d] not right, "
+ "should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32);
}
}
else if (lxevent->target == g_utf8_atom)
@@ -2136,9 +2139,9 @@ clipboard_event_selection_request(XEvent *xevent)
char *xdata;
lxev = (XSelectionRequestEvent *)xevent;
- log_debug("clipboard_event_selection_request: %p", lxev->property);
- log_debug("clipboard_event_selection_request: g_wnd %d, "
- ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
+ log_debug("clipboard_event_selection_request: 0x%lx", lxev->property);
+ log_debug("clipboard_event_selection_request: g_wnd %ld, "
+ ".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld",
g_wnd, lxev->requestor, lxev->owner, lxev->selection,
get_atom_text(lxev->selection),
lxev->target, lxev->property);
@@ -2324,8 +2327,8 @@ clipboard_event_property_notify(XEvent *xevent)
char *cptr;
log_debug("clipboard_event_property_notify:");
- log_debug("clipboard_event_property_notify: PropertyNotify .window %d "
- ".state %d .atom %d %s", xevent->xproperty.window,
+ log_debug("clipboard_event_property_notify: PropertyNotify .window %ld "
+ ".state %d .atom %ld %s", xevent->xproperty.window,
xevent->xproperty.state, xevent->xproperty.atom,
get_atom_text(xevent->xproperty.atom));
@@ -2380,6 +2383,11 @@ clipboard_event_property_notify(XEvent *xevent)
AnyPropertyType, &actual_type_return, &actual_format_return,
&nitems_returned, &bytes_left, &data);
+ if (rv != Success)
+ {
+ return 1;
+ }
+
if (data != 0)
{
XFree(data);
@@ -2410,7 +2418,7 @@ clipboard_event_property_notify(XEvent *xevent)
}
else
{
- log_error("clipboard_event_property_notify: error unknown type %d",
+ log_error("clipboard_event_property_notify: error unknown type %ld",
g_clip_s2c.type);
clipboard_send_data_response_failed();
}
@@ -2423,6 +2431,11 @@ clipboard_event_property_notify(XEvent *xevent)
AnyPropertyType, &actual_type_return, &actual_format_return,
&nitems_returned, &bytes_left, &data);
+ if (rv != Success)
+ {
+ return 1;
+ }
+
format_in_bytes = FORMAT_TO_BYTES(actual_format_return);
new_data_len = nitems_returned * format_in_bytes;
cptr = (char *) g_malloc(g_clip_s2c.total_bytes + new_data_len, 0);
diff --git a/sesman/chansrv/clipboard_common.h b/sesman/chansrv/clipboard_common.h
index 5a74de66..1944b760 100644
--- a/sesman/chansrv/clipboard_common.h
+++ b/sesman/chansrv/clipboard_common.h
@@ -127,7 +127,8 @@ struct clip_file_desc /* CLIPRDR_FILEDESCRIPTOR */
char cFileName[256];
};
-int APP_CC clipboard_out_unicode(struct stream *s, char *text, int num_chars);
+int APP_CC clipboard_out_unicode(struct stream *s, const char *text,
+ int num_chars);
int APP_CC clipboard_in_unicode(struct stream *s, char *text, int *num_chars);
#endif
diff --git a/sesman/chansrv/clipboard_file.c b/sesman/chansrv/clipboard_file.c
index ff95b0a0..5724829f 100644
--- a/sesman/chansrv/clipboard_file.c
+++ b/sesman/chansrv/clipboard_file.c
@@ -22,6 +22,7 @@
* CLIPRDR_FILEDESCRIPTOR
* http://msdn.microsoft.com/en-us/library/ff362447%28prot.20%29.aspx */
+#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xfixes.h>
@@ -101,6 +102,7 @@ static int g_file_request_sent_type = 0;
#define CB_EPOCH_DIFF 11644473600LL
/*****************************************************************************/
+#if 0
static tui64 APP_CC
timeval2wintime(struct timeval *tv)
{
@@ -112,6 +114,7 @@ timeval2wintime(struct timeval *tv)
result += tv->tv_usec * 10;
return result;
}
+#endif
/*****************************************************************************/
/* this will replace %20 or any hex with the space or correct char
@@ -197,6 +200,7 @@ clipboard_get_file(char* file, int bytes)
}
g_memcpy(filename, file + pindex + 1, (bytes - 1) - pindex);
/* this should replace %20 with space */
+ clipboard_check_file(pathname);
clipboard_check_file(filename);
g_snprintf(full_fn, 255, "%s/%s", pathname, filename);
if (g_directory_exist(full_fn))
@@ -449,7 +453,7 @@ clipboard_send_file_data(int streamId, int lindex,
if (g_file_seek(fd, nPositionLow) < 0)
{
log_message(LOG_LEVEL_ERROR, "clipboard_send_file_data: seek error "
- "in file: %s\n", full_fn);
+ "in file: %s", full_fn);
g_file_close(fd);
return 1;
}
@@ -528,7 +532,6 @@ clipboard_process_file_request(struct stream *s, int clip_msg_status,
int lindex;
int dwFlags;
int nPositionLow;
- int nPositionHigh;
int cbRequested;
//int clipDataId;
@@ -538,7 +541,7 @@ clipboard_process_file_request(struct stream *s, int clip_msg_status,
in_uint32_le(s, lindex);
in_uint32_le(s, dwFlags);
in_uint32_le(s, nPositionLow);
- in_uint32_le(s, nPositionHigh);
+ in_uint8s(s, 4); /* nPositionHigh */
in_uint32_le(s, cbRequested);
//in_uint32_le(s, clipDataId); /* options, used when locking */
if (dwFlags & CB_FILECONTENTS_SIZE)
@@ -553,7 +556,7 @@ clipboard_process_file_request(struct stream *s, int clip_msg_status,
}
/*****************************************************************************/
-/* server requested info about the file and this is the responce
+/* server requested info about the file and this is the response
it's either the file size or file data */
int APP_CC
clipboard_process_file_response(struct stream *s, int clip_msg_status,
@@ -626,6 +629,7 @@ clipboard_c2s_in_files(struct stream *s, char *file_list)
int cItems;
int lindex;
int str_len;
+ int file_count;
struct clip_file_desc *cfd;
char *ptr;
@@ -644,6 +648,7 @@ clipboard_c2s_in_files(struct stream *s, char *file_list)
log_debug("clipboard_c2s_in_files: cItems %d", cItems);
cfd = (struct clip_file_desc *)
g_malloc(sizeof(struct clip_file_desc), 0);
+ file_count = 0;
ptr = file_list;
for (lindex = 0; lindex < cItems; lindex++)
{
@@ -656,7 +661,18 @@ clipboard_c2s_in_files(struct stream *s, char *file_list)
"supported [%s]", cfd->cFileName);
continue;
}
- xfuse_add_clip_dir_item(cfd->cFileName, 0, cfd->fileSizeLow, lindex);
+ if (xfuse_add_clip_dir_item(cfd->cFileName, 0, cfd->fileSizeLow, lindex) == -1)
+ {
+ log_error("clipboard_c2s_in_files: failed to add clip dir item");
+ continue;
+ }
+
+ if (file_count > 0)
+ {
+ *ptr = '\n';
+ ptr++;
+ }
+ file_count++;
g_strcpy(ptr, "file://");
ptr += 7;
@@ -671,9 +687,6 @@ clipboard_c2s_in_files(struct stream *s, char *file_list)
str_len = g_strlen(cfd->cFileName);
g_strcpy(ptr, cfd->cFileName);
ptr += str_len;
-
- *ptr = '\n';
- ptr++;
}
*ptr = 0;
g_free(cfd);
diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c
index cea42c81..111ac465 100644
--- a/sesman/chansrv/devredir.c
+++ b/sesman/chansrv/devredir.c
@@ -242,11 +242,11 @@ dev_redir_data_in(struct stream *s, int chan_id, int chan_flags, int length,
case PAKID_CORE_CLIENT_NAME:
/* client is telling us its computer name; do we even care? */
- /* let client know loggin was successful */
+ /* let client know login was successful */
dev_redir_send_server_user_logged_on();
usleep(1000 * 100);
- /* let client know our capabilites */
+ /* let client know our capabilities */
dev_redir_send_server_core_cap_req();
/* send confirm clientID */
@@ -430,7 +430,8 @@ void devredir_send_server_device_announce_resp(tui32 device_id)
* @return 0 on success, -1 on failure
*****************************************************************************/
-int dev_redir_send_drive_create_request(tui32 device_id, char *path,
+int dev_redir_send_drive_create_request(tui32 device_id,
+ const char *path,
tui32 DesiredAccess,
tui32 CreateOptions,
tui32 CreateDisposition,
@@ -576,7 +577,7 @@ void dev_redir_send_drive_dir_request(IRP *irp, tui32 device_id,
******************************************************************************/
/**
- * @brief process client's repsonse to our core_capability_req() msg
+ * @brief process client's response to our core_capability_req() msg
*
* @param s stream containing client's response
*****************************************************************************/
@@ -636,7 +637,7 @@ void dev_redir_proc_client_core_cap_resp(struct stream *s)
void devredir_proc_client_devlist_announce_req(struct stream *s)
{
- int i;
+ unsigned int i;
int j;
tui32 device_count;
tui32 device_type;
@@ -890,24 +891,16 @@ dev_redir_proc_query_dir_response(IRP *irp,
XRDP_INODE *xinode;
tui32 Length;
- tui32 NextEntryOffset;
tui64 CreationTime;
tui64 LastAccessTime;
tui64 LastWriteTime;
- tui64 ChangeTime;
tui64 EndOfFile;
tui32 FileAttributes;
tui32 FileNameLength;
tui32 status;
-#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
- tui32 EaSize;
- tui8 ShortNameLength;
- tui8 Reserved;
-#endif
-
char filename[256];
- int i = 0;
+ unsigned int i = 0;
xstream_rd_u32_le(s_in, Length);
@@ -935,21 +928,21 @@ dev_redir_proc_query_dir_response(IRP *irp,
{
log_debug("processing FILE_DIRECTORY_INFORMATION structs");
- xstream_rd_u32_le(s_in, NextEntryOffset);
+ xstream_seek(s_in, 4); /* NextEntryOffset */
xstream_seek(s_in, 4); /* FileIndex */
xstream_rd_u64_le(s_in, CreationTime);
xstream_rd_u64_le(s_in, LastAccessTime);
xstream_rd_u64_le(s_in, LastWriteTime);
- xstream_rd_u64_le(s_in, ChangeTime);
+ xstream_seek(s_in, 8); /* ChangeTime */
xstream_rd_u64_le(s_in, EndOfFile);
xstream_seek(s_in, 8); /* AllocationSize */
xstream_rd_u32_le(s_in, FileAttributes);
xstream_rd_u32_le(s_in, FileNameLength);
#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
- xstream_rd_u32_le(s_in, EaSize);
- xstream_rd_u8(s_in, ShortNameLength);
- xstream_rd_u8(s_in, Reserved);
+ xstream_seek(s_in, 4); /* EaSize */
+ xstream_seek(s_in, 1); /* ShortNameLength */
+ xstream_seek(s_in, 1); /* Reserved */
xstream_seek(s_in, 23); /* ShortName in Unicode */
#endif
devredir_cvt_from_unicode_len(filename, s_in->p, FileNameLength);
@@ -959,11 +952,9 @@ dev_redir_proc_query_dir_response(IRP *irp,
#else
i += 64 + FileNameLength;
#endif
- //log_debug("NextEntryOffset: 0x%x", NextEntryOffset);
//log_debug("CreationTime: 0x%llx", CreationTime);
//log_debug("LastAccessTime: 0x%llx", LastAccessTime);
//log_debug("LastWriteTime: 0x%llx", LastWriteTime);
- //log_debug("ChangeTime: 0x%llx", ChangeTime);
//log_debug("EndOfFile: %lld", EndOfFile);
//log_debug("FileAttributes: 0x%x", FileAttributes);
#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
@@ -972,7 +963,8 @@ dev_redir_proc_query_dir_response(IRP *irp,
//log_debug("FileNameLength: %d", FileNameLength);
log_debug("FileName: %s", filename);
- if ((xinode = calloc(1, sizeof(struct xrdp_inode))) == NULL)
+ xinode = g_new0(struct xrdp_inode, 1);
+ if (xinode == NULL)
{
log_error("system out of memory");
fuse_data = devredir_fuse_data_peek(irp);
@@ -1006,7 +998,7 @@ dev_redir_proc_query_dir_response(IRP *irp,
*****************************************************************************/
int APP_CC
-dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path)
+dev_redir_get_dir_listing(void *fusep, tui32 device_id, const char *path)
{
tui32 DesiredAccess;
tui32 CreateOptions;
@@ -1019,28 +1011,29 @@ dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path)
if ((irp = devredir_irp_new()) == NULL)
return -1;
- /* cvt / to windows compatible \ */
- devredir_cvt_slash(path);
+ strncpy(irp->pathname, path, 255);
+
+ /* convert / to windows compatible \ */
+ devredir_cvt_slash(irp->pathname);
irp->CompletionId = g_completion_id++;
irp->completion_type = CID_CREATE_DIR_REQ;
irp->DeviceId = device_id;
- strncpy(irp->pathname, path, 255);
devredir_fuse_data_enqueue(irp, fusep);
DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE;
CreateOptions = CO_FILE_DIRECTORY_FILE | CO_FILE_SYNCHRONOUS_IO_NONALERT;
CreateDisposition = CD_FILE_OPEN;
- rval = dev_redir_send_drive_create_request(device_id, path,
+ rval = dev_redir_send_drive_create_request(device_id, irp->pathname,
DesiredAccess, CreateOptions,
CreateDisposition,
irp->CompletionId);
- log_debug("looking for device_id=%d path=%s", device_id, path);
+ log_debug("looking for device_id=%d path=%s", device_id, irp->pathname);
- /* when we get a respone to dev_redir_send_drive_create_request(), we */
+ /* when we get a response to dev_redir_send_drive_create_request(), we */
/* call dev_redir_send_drive_dir_request(), which needs the following */
/* at the end of the path argument */
if (dev_redir_string_ends_with(irp->pathname, '\\'))
@@ -1052,8 +1045,8 @@ dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path)
}
int APP_CC
-dev_redir_file_open(void *fusep, tui32 device_id, char *path,
- int mode, int type, char *gen_buf)
+dev_redir_file_open(void *fusep, tui32 device_id, const char *path,
+ int mode, int type, const char *gen_buf)
{
tui32 DesiredAccess;
tui32 CreateOptions;
@@ -1170,7 +1163,7 @@ int devredir_file_close(void *fusep, tui32 device_id, tui32 FileId)
*****************************************************************************/
int APP_CC
-devredir_rmdir_or_file(void *fusep, tui32 device_id, char *path, int mode)
+devredir_rmdir_or_file(void *fusep, tui32 device_id, const char *path, int mode)
{
tui32 DesiredAccess;
tui32 CreateOptions;
@@ -1265,7 +1258,7 @@ devredir_file_read(void *fusep, tui32 DeviceId, tui32 FileId,
int APP_CC
dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
- const char *buf, tui32 Length, tui64 Offset)
+ const char *buf, int Length, tui64 Offset)
{
struct stream *s;
IRP *irp;
@@ -1330,7 +1323,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
* @return FUSE_DATA on success, or NULL on failure
*****************************************************************************/
-void * APP_CC
+FUSE_DATA *APP_CC
devredir_fuse_data_peek(IRP *irp)
{
log_debug("returning %p", irp->fd_head);
@@ -1343,7 +1336,7 @@ devredir_fuse_data_peek(IRP *irp)
* @return FUSE_DATA on success, NULL on failure
*****************************************************************************/
-void * APP_CC
+FUSE_DATA *APP_CC
devredir_fuse_data_dequeue(IRP *irp)
{
FUSE_DATA *head;
@@ -1388,7 +1381,8 @@ devredir_fuse_data_enqueue(IRP *irp, void *vp)
if (irp == NULL)
return -1;
- if ((fd = calloc(1, sizeof(FUSE_DATA))) == NULL)
+ fd = g_new0(FUSE_DATA, 1);
+ if (fd == NULL)
return -1;
fd->data_ptr = vp;
@@ -1453,7 +1447,7 @@ devredir_cvt_slash(char *path)
}
void APP_CC
-devredir_cvt_to_unicode(char *unicode, char *path)
+devredir_cvt_to_unicode(char *unicode, const char *path)
{
char *dest;
char *src;
@@ -1484,7 +1478,6 @@ devredir_cvt_from_unicode_len(char *path, char *unicode, int len)
char *dest;
char *dest_saved;
char *src;
- int rv;
int i;
int bytes_to_alloc;
int max_bytes;
@@ -1492,7 +1485,7 @@ devredir_cvt_from_unicode_len(char *path, char *unicode, int len)
bytes_to_alloc = (((len / 2) * sizeof(twchar)) + sizeof(twchar));
src = unicode;
- dest = g_malloc(bytes_to_alloc, 1);
+ dest = g_new0(char, bytes_to_alloc);
dest_saved = dest;
for (i = 0; i < len; i += 2)
@@ -1509,7 +1502,7 @@ devredir_cvt_from_unicode_len(char *path, char *unicode, int len)
max_bytes = wcstombs(NULL, (wchar_t *) dest_saved, 0);
if (max_bytes > 0)
{
- rv = wcstombs(path, (wchar_t *) dest_saved, max_bytes);
+ wcstombs(path, (wchar_t *) dest_saved, max_bytes);
path[max_bytes] = 0;
}
diff --git a/sesman/chansrv/devredir.h b/sesman/chansrv/devredir.h
index 5a402c9c..6479c6f6 100644
--- a/sesman/chansrv/devredir.h
+++ b/sesman/chansrv/devredir.h
@@ -27,8 +27,8 @@
#define USE_SHORT_NAMES_IN_DIR_LISTING
-void *devredir_fuse_data_peek(IRP *irp);
-void *devredir_fuse_data_dequeue(IRP *irp);
+FUSE_DATA *devredir_fuse_data_peek(IRP *irp);
+FUSE_DATA *devredir_fuse_data_dequeue(IRP *irp);
int devredir_fuse_data_enqueue(IRP *irp, void *vp);
int APP_CC dev_redir_init(void);
@@ -48,7 +48,8 @@ void devredir_send_server_device_announce_resp(tui32 device_id);
void dev_redir_send_drive_dir_request(IRP *irp, tui32 device_id,
tui32 InitialQuery, char *Path);
-int dev_redir_send_drive_create_request(tui32 device_id, char *path,
+int dev_redir_send_drive_create_request(tui32 device_id,
+ const char *path,
tui32 DesiredAccess,
tui32 CreateOptions,
tui32 CreateDisposition,
@@ -81,7 +82,7 @@ void devredir_insert_DeviceIoRequest(struct stream *s,
tui32 MinorFunction);
void devredir_cvt_slash(char *path);
-void devredir_cvt_to_unicode(char *unicode, char *path);
+void devredir_cvt_to_unicode(char *unicode, const char *path);
void devredir_cvt_from_unicode_len(char *path, char *unicode, int len);
int dev_redir_string_ends_with(char *string, char c);
@@ -94,16 +95,23 @@ void devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus);
void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus);
/* called from FUSE module */
-int dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path);
+int dev_redir_get_dir_listing(void *fusep, tui32 device_id, const char *path);
-int dev_redir_file_open(void *fusep, tui32 device_id, char *path,
- int mode, int type, char *gen_buf);
+int dev_redir_file_open(void *fusep, tui32 device_id, const char *path,
+ int mode, int type, const char *gen_buf);
int devredir_file_close(void *fusep, tui32 device_id, tui32 file_id);
int devredir_file_read(void *fusep, tui32 device_id, tui32 FileId,
tui32 Length, tui64 Offset);
+int APP_CC
+dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
+ const char *buf, int Length, tui64 Offset);
+
+int APP_CC
+devredir_rmdir_or_file(void *fusep, tui32 device_id, const char *path, int mode);
+
int send_channel_data(int chan_id, char *data, int size);
/*
@@ -329,7 +337,7 @@ enum FS_INFORMATION_CLASS
(((_a) & W_FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR | 0100 : S_IFREG) |\
(((_a) & W_FILE_ATTRIBUTE_READONLY) ? 0444 : 0644)
-/* winodws time starts on Jan 1, 1601 */
+/* Windows time starts on Jan 1, 1601 */
/* Linux time starts on Jan 1, 1970 */
#define EPOCH_DIFF 11644473600LL
#define WINDOWS_TO_LINUX_TIME(_t) ((_t) / 10000000) - EPOCH_DIFF;
diff --git a/sesman/chansrv/drdynvc.c b/sesman/chansrv/drdynvc.c
index 70b08d97..dfd8a878 100644
--- a/sesman/chansrv/drdynvc.c
+++ b/sesman/chansrv/drdynvc.c
@@ -18,7 +18,7 @@
#include "drdynvc.h"
-int g_drdynvc_chan_id;
+extern int g_drdynvc_chan_id; /* in chansrv.c */
int g_drdynvc_inited = 0;
static int APP_CC drdynvc_send_capability_request(uint16_t version);
@@ -342,24 +342,24 @@ drdynvc_process_data_first(struct stream *s, unsigned char cmd)
uint32_t chan_id;
int bytes_in_stream;
- int data_len;
int Len;
drdynvc_get_chan_id(s, cmd, &chan_id);
Len = (cmd >> 2) & 0x03;
+ /* skip data_len */
if (Len == 0)
{
- in_uint8(s, data_len);
+ in_uint8s(s, 1);
}
else if (Len == 1)
{
- in_uint16_le(s, data_len);
+ in_uint8s(s, 2);
}
else
{
- in_uint32_le(s, data_len);
+ in_uint8s(s, 4);
}
bytes_in_stream = stream_length_after_p(s);
@@ -414,7 +414,7 @@ drdynvc_process_data(struct stream *s, unsigned char cmd)
* process incoming data on a dynamic virtual channel
*
* @pram s stream containing the incoming data
- * @pram chand_id LK_TODO
+ * @pram chan_id LK_TODO
* @pram chan_flags LK_TODO
* @pram length LK_TODO
* @pram total_length LK_TODO
diff --git a/sesman/chansrv/fifo.c b/sesman/chansrv/fifo.c
index b212736a..595dbb29 100644
--- a/sesman/chansrv/fifo.c
+++ b/sesman/chansrv/fifo.c
@@ -235,21 +235,21 @@ fifo_remove(FIFO* fp)
void*
fifo_peek(FIFO* fp)
{
- log_debug_high("entered\n");
+ log_debug_high("entered");
if (!fp)
{
- log_debug_high("FIFO is null\n");
+ log_debug_high("FIFO is null");
return 0;
}
if (fp->rd_ptr == fp->wr_ptr)
{
- log_debug_high("FIFO is empty\n");
+ log_debug_high("FIFO is empty");
return 0;
}
- log_debug_low("peeking data at index %d\n", fp->rd_ptr);
+ log_debug_low("peeking data at index %d", fp->rd_ptr);
return (void *) fp->user_data[fp->rd_ptr];
}
diff --git a/sesman/chansrv/irp.c b/sesman/chansrv/irp.c
index 2a5209d8..ad318cb1 100644
--- a/sesman/chansrv/irp.c
+++ b/sesman/chansrv/irp.c
@@ -77,7 +77,8 @@ IRP * devredir_irp_new()
log_debug("entered");
/* create new IRP */
- if ((irp = g_malloc(sizeof(IRP), 1)) == NULL)
+ irp = g_new0(IRP, 1);
+ if (irp == NULL)
{
log_error("system out of memory!");
return NULL;
diff --git a/sesman/chansrv/pcsc/.gitignore b/sesman/chansrv/pcsc/.gitignore
new file mode 100644
index 00000000..24600083
--- /dev/null
+++ b/sesman/chansrv/pcsc/.gitignore
@@ -0,0 +1 @@
+!Makefile
diff --git a/sesman/chansrv/pcsc/wrapper/winscard-funcs.h b/sesman/chansrv/pcsc/wrapper/winscard-funcs.h
index 0a4198a3..d28e1445 100755
--- a/sesman/chansrv/pcsc/wrapper/winscard-funcs.h
+++ b/sesman/chansrv/pcsc/wrapper/winscard-funcs.h
@@ -107,7 +107,7 @@ typedef LONG WINAPI
(*tSCardFreeMemory)(SCARDCONTEXT hContext, LPCVOID pvMem);
typedef LONG WINAPI
(*tSCardLocateCardsA)(SCARDCONTEXT hContext, LPCSTR mszCards,
- LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders);
+ LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders);
typedef LONG WINAPI
(*tSCardLocateCardsW)(SCARDCONTEXT hContext, LPCWSTR mszCards,
LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders);
@@ -160,7 +160,7 @@ typedef LONG WINAPI
typedef LONG WINAPI
(*tSCardControl)(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer,
- DWORD nOutBufferSize, LPDWORD lpBytesReturned);
+ DWORD nOutBufferSize, LPDWORD lpBytesReturned);
typedef LONG WINAPI
(*tSCardGetAttrib)(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
LPDWORD pcbAttrLen);
diff --git a/sesman/chansrv/pcsc/wrapper/winscard.c b/sesman/chansrv/pcsc/wrapper/winscard.c
index 34157f7c..f00ddf84 100755
--- a/sesman/chansrv/pcsc/wrapper/winscard.c
+++ b/sesman/chansrv/pcsc/wrapper/winscard.c
@@ -98,7 +98,7 @@ static int g_funcs_loaded = 0;
/*****************************************************************************/
static int __fastcall
-load_funsc(void)
+load_funcs(void)
{
HMODULE lib;
@@ -108,7 +108,7 @@ load_funsc(void)
}
g_funcs_loaded = 1;
lib = LoadLibrary("winscard-org.dll");
- LLOGLN(0, ("load_funsc: lib %p", lib));
+ LLOGLN(0, ("load_funcs: lib %p", lib));
LLOAD(aSCardEstablishContext, tSCardEstablishContext, "SCardEstablishContext");
LLOAD(aSCardReleaseContext, tSCardReleaseContext, "SCardReleaseContext");
LLOAD(aSCardIsValidContext, tSCardIsValidContext, "SCardIsValidContext");
@@ -180,7 +180,7 @@ DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
case DLL_PROCESS_ATTACH:
LLOGLN(0, ("DllEntryPoint: DLL_PROCESS_ATTACH"));
- load_funsc();
+ load_funcs();
rv = TRUE;
break;
case DLL_THREAD_ATTACH:
diff --git a/sesman/chansrv/pulse/.gitignore b/sesman/chansrv/pulse/.gitignore
new file mode 100644
index 00000000..24600083
--- /dev/null
+++ b/sesman/chansrv/pulse/.gitignore
@@ -0,0 +1 @@
+!Makefile
diff --git a/sesman/chansrv/pulse/module-xrdp-sink-symdef.h b/sesman/chansrv/pulse/module-xrdp-sink-symdef.h
index 14443d31..7001ba51 100644
--- a/sesman/chansrv/pulse/module-xrdp-sink-symdef.h
+++ b/sesman/chansrv/pulse/module-xrdp-sink-symdef.h
@@ -1,5 +1,5 @@
-#ifndef foomodulexrdpsinksymdeffoo
-#define foomodulexrdpsinksymdeffoo
+#ifndef MODULE_XRDP_SINK_SYMDEF_H
+#define MODULE_XRDP_SINK_SYMDEF_H
#include <pulsecore/core.h>
#include <pulsecore/module.h>
diff --git a/sesman/chansrv/pulse/module-xrdp-sink.c b/sesman/chansrv/pulse/module-xrdp-sink.c
index 8606f412..79cd7b27 100644
--- a/sesman/chansrv/pulse/module-xrdp-sink.c
+++ b/sesman/chansrv/pulse/module-xrdp-sink.c
@@ -77,7 +77,7 @@ PA_MODULE_USAGE(
"sink_name=<name for the sink> "
"sink_properties=<properties for the sink> "
"format=<sample format> "
- "rate=<sample rate>"
+ "rate=<sample rate> "
"channels=<number of channels> "
"channel_map=<channel map>");
@@ -309,7 +309,7 @@ static int data_send(struct userdata *u, pa_memchunk *chunk) {
s.sun_family = AF_UNIX;
bytes = sizeof(s.sun_path) - 1;
snprintf(s.sun_path, bytes, CHANSRV_PORT_STR, u->display_num);
- pa_log_debug("trying to conenct to %s", s.sun_path);
+ pa_log_debug("trying to connect to %s", s.sun_path);
if (connect(fd, (struct sockaddr *)&s,
sizeof(struct sockaddr_un)) != 0) {
u->failed_connect_time = pa_rtclock_now();
@@ -440,7 +440,11 @@ static void thread_func(void *userdata) {
pa_rtpoll_set_timer_disabled(u->rtpoll);
}
+#if defined(PA_CHECK_VERSION) && PA_CHECK_VERSION(6, 0, 0)
+ if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) {
+#else
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) {
+#endif
goto fail;
}
diff --git a/sesman/chansrv/pulse/module-xrdp-source-symdef.h b/sesman/chansrv/pulse/module-xrdp-source-symdef.h
index e0467648..41e364ce 100644
--- a/sesman/chansrv/pulse/module-xrdp-source-symdef.h
+++ b/sesman/chansrv/pulse/module-xrdp-source-symdef.h
@@ -1,5 +1,5 @@
-#ifndef foomodulenullsourcesymdeffoo
-#define foomodulenullsourcesymdeffoo
+#ifndef MODULE_XRDP_SOURCE_SYMDEF_H
+#define MODULE_XRDP_SOURCE_SYMDEF_H
#include <pulsecore/core.h>
#include <pulsecore/module.h>
diff --git a/sesman/chansrv/pulse/module-xrdp-source.c b/sesman/chansrv/pulse/module-xrdp-source.c
index 37c0bb4e..78124f9d 100644
--- a/sesman/chansrv/pulse/module-xrdp-source.c
+++ b/sesman/chansrv/pulse/module-xrdp-source.c
@@ -313,7 +313,7 @@ static void thread_func(void *userdata) {
} else {
if (u->want_src_data)
{
- /* we dont want source data anymore */
+ /* we don't want source data anymore */
char buf[12];
buf[0] = 0;
@@ -339,8 +339,13 @@ static void thread_func(void *userdata) {
}
/* Hmm, nothing to do. Let's sleep */
- if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
+#if defined(PA_CHECK_VERSION) && PA_CHECK_VERSION(6, 0, 0)
+ if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) {
+#else
+ if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) {
+#endif
goto fail;
+ }
if (ret == 0)
goto finish;
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
index f3777970..3470cece 100644
--- a/sesman/chansrv/rail.c
+++ b/sesman/chansrv/rail.c
@@ -184,7 +184,7 @@ rail_send_key_esc(int window_id)
static struct rail_window_data* APP_CC
rail_get_window_data(Window window)
{
- int bytes;
+ unsigned int bytes;
Atom actual_type_return;
int actual_format_return;
unsigned long nitems_return;
@@ -238,7 +238,7 @@ rail_get_window_data_safe(Window window)
{
return rv;
}
- rv = g_malloc(sizeof(struct rail_window_data), 1);
+ rv = g_new0(struct rail_window_data, 1);
rail_set_window_data(window, rv);
g_free(rv);
return rail_get_window_data(window);
@@ -383,7 +383,7 @@ rail_startup()
if (g_xrr_event_base > 0)
{
- LOG(0, ("rail_init: found RandR entension"));
+ LOG(0, ("rail_init: found RandR extension"));
st = XRRQueryVersion(g_display, &ver_maj, &ver_min);
if (st)
{
@@ -508,7 +508,7 @@ rail_win_popdown(void)
window_attributes.map_state == IsViewable &&
list_index_of(g_window_list, children[i]) >= 0)
{
- LOG(10, (" dismiss pop up 0x%8.8x", children[i]));
+ LOG(10, (" dismiss pop up 0x%8.8lx", children[i]));
rail_send_key_esc(children[i]);
rv = 1;
}
@@ -543,12 +543,12 @@ rail_close_window(int window_id)
/*****************************************************************************/
void DEFAULT_CC
-my_timoeut(void* data)
+my_timeout(void* data)
{
- LOG(10, ("my_timoeut: g_got_focus %d", g_got_focus));
+ LOG(10, ("my_timeout: g_got_focus %d", g_got_focus));
if (g_focus_counter == (int)(long)data)
{
- LOG(10, ("my_timoeut: g_focus_counter %d", g_focus_counter));
+ LOG(10, ("my_timeout: g_focus_counter %d", g_focus_counter));
rail_win_popdown();
}
}
@@ -557,7 +557,7 @@ my_timoeut(void* data)
static int APP_CC
rail_process_activate(struct stream *s, int size)
{
- int window_id;
+ unsigned int window_id;
int enabled;
int index;
XWindowAttributes window_attributes;
@@ -617,7 +617,7 @@ rail_process_activate(struct stream *s, int size)
LOG(10, (" window attributes: override_redirect %d",
window_attributes.override_redirect));
- add_timeout(200, my_timoeut, (void*)(long)g_focus_counter);
+ add_timeout(200, my_timeout, (void*)(long)g_focus_counter);
}
return 0;
}
@@ -756,7 +756,7 @@ rail_win_set_state(Window win, unsigned long state)
int old_state;
unsigned long data[2] = { state, None };
- LOG(10, (" rail_win_set_state: %d", state));
+ LOG(10, (" rail_win_set_state: %ld", state));
/* check whether WM_STATE exists */
old_state = rail_win_get_state(win);
if (old_state == -1)
@@ -1148,8 +1148,8 @@ rail_data_in(struct stream *s, int chan_id, int chan_flags, int length,
return 0;
}
-static int g_crc_seed = 0xffffffff;
-static int g_crc_table[256] =
+static const unsigned int g_crc_seed = 0xffffffff;
+static const unsigned int g_crc_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@@ -1259,7 +1259,7 @@ rail_win_send_text(Window win)
}
if (data && len > 0)
{
- LOG(10, ("chansrv::rail_win_send_text: 0x%8.8x text %s length %d",
+ LOG(10, ("chansrv::rail_win_send_text: 0x%8.8lx text %s length %d",
win, data, len));
make_stream(s);
init_stream(s, len + 1024);
@@ -1289,7 +1289,7 @@ rail_destroy_window(Window window_id)
{
struct stream *s;
- LOG(10, ("chansrv::rail_destroy_window 0x%8.8x", window_id));
+ LOG(10, ("chansrv::rail_destroy_window 0x%8.8lx", window_id));
make_stream(s);
init_stream(s, 1024);
@@ -1309,7 +1309,7 @@ rail_show_window(Window window_id, int show_state)
int flags;
struct stream* s;
- LOG(10, ("chansrv::rail_show_window 0x%8.8x 0x%x", window_id, show_state));
+ LOG(10, ("chansrv::rail_show_window 0x%8.8lx 0x%x", window_id, show_state));
make_stream(s);
init_stream(s, 1024);
@@ -1351,7 +1351,7 @@ rail_create_window(Window window_id, Window owner_id)
struct rail_window_data* rwd;
struct stream* s;
- LOG(10, ("chansrv::rail_create_window 0x%8.8x", window_id));
+ LOG(10, ("chansrv::rail_create_window 0x%8.8lx", window_id));
rwd = rail_get_window_data_safe(window_id);
if (rwd == 0)
@@ -1507,7 +1507,7 @@ rail_configure_request_window(XConfigureRequestEvent* config)
if (mask & CWStackMode)
{
LOG(10, ("chansrv::rail_configure_request_window: CWStackMode "
- "detail 0x%8.8x above 0x%8.8x", config->detail, config->above));
+ "detail 0x%8.8x above 0x%8.8lx", config->detail, config->above));
if (config->detail == Above)
{
LOG(10, ("chansrv::rail_configure_request_window: bring to front "
@@ -1775,7 +1775,7 @@ rail_configure_window(XConfigureEvent *config)
/*****************************************************************************/
static int
-rail_desktop_resize(lxevent)
+rail_desktop_resize(XEvent *lxevent)
{
LOG(0, ("rail_desktop_resize:"));
return 0;
@@ -1808,7 +1808,7 @@ rail_xevent(void *xevent)
{
case PropertyNotify:
prop_name = XGetAtomName(g_display, lxevent->xproperty.atom);
- LOG(10, (" got PropertyNotify window_id 0x%8.8x %s state new %d",
+ LOG(10, (" got PropertyNotify window_id 0x%8.8lx %s state new %d",
lxevent->xproperty.window, prop_name,
lxevent->xproperty.state == PropertyNewValue));
@@ -1831,7 +1831,7 @@ rail_xevent(void *xevent)
break;
case ConfigureRequest:
- LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window));
+ LOG(10, (" got ConfigureRequest window_id 0x%8.8lx", lxevent->xconfigurerequest.window));
g_memset(&xwc, 0, sizeof(xwc));
xwc.x = lxevent->xconfigurerequest.x;
xwc.y = lxevent->xconfigurerequest.y;
@@ -1849,13 +1849,13 @@ rail_xevent(void *xevent)
break;
case CreateNotify:
- LOG(10, (" got CreateNotify window 0x%8.8x parent 0x%8.8x",
+ LOG(10, (" got CreateNotify window 0x%8.8lx parent 0x%8.8lx",
lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent));
rail_select_input(lxevent->xcreatewindow.window);
break;
case DestroyNotify:
- LOG(10, (" got DestroyNotify window 0x%8.8x event 0x%8.8x",
+ LOG(10, (" got DestroyNotify window 0x%8.8lx event 0x%8.8lx",
lxevent->xdestroywindow.window, lxevent->xdestroywindow.event));
if (lxevent->xdestroywindow.window != lxevent->xdestroywindow.event)
{
@@ -1871,12 +1871,12 @@ rail_xevent(void *xevent)
break;
case MapRequest:
- LOG(10, (" got MapRequest window 0x%8.8x", lxevent->xmaprequest.window));
+ LOG(10, (" got MapRequest window 0x%8.8lx", lxevent->xmaprequest.window));
XMapWindow(g_display, lxevent->xmaprequest.window);
break;
case MapNotify:
- LOG(10, (" got MapNotify window 0x%8.8x event 0x%8.8x",
+ LOG(10, (" got MapNotify window 0x%8.8lx event 0x%8.8lx",
lxevent->xmap.window, lxevent->xmap.event));
if (lxevent->xmap.window != lxevent->xmap.event)
{
@@ -1902,7 +1902,7 @@ rail_xevent(void *xevent)
break;
case UnmapNotify:
- LOG(10, (" got UnmapNotify 0x%8.8x", lxevent->xunmap.event));
+ LOG(10, (" got UnmapNotify 0x%8.8lx", lxevent->xunmap.event));
if (lxevent->xunmap.window != lxevent->xunmap.event)
{
break;
@@ -1910,7 +1910,7 @@ rail_xevent(void *xevent)
if (is_window_valid_child_of_root(lxevent->xunmap.window))
{
index = list_index_of(g_window_list, lxevent->xunmap.window);
- LOG(10, (" window 0x%8.8x is unmapped", lxevent->xunmap.window));
+ LOG(10, (" window 0x%8.8lx is unmapped", lxevent->xunmap.window));
if (index >= 0)
{
XGetWindowAttributes(g_display, lxevent->xunmap.window, &wnd_attributes);
@@ -1929,7 +1929,7 @@ rail_xevent(void *xevent)
break;
case ConfigureNotify:
- LOG(10, (" got ConfigureNotify 0x%8.8x event 0x%8.8x", lxevent->xconfigure.window,
+ LOG(10, (" got ConfigureNotify 0x%8.8lx event 0x%8.8lx", lxevent->xconfigure.window,
lxevent->xconfigure.event));
rv = 0;
if (lxevent->xconfigure.event != lxevent->xconfigure.window ||
@@ -1975,8 +1975,8 @@ rail_xevent(void *xevent)
break;
case ReparentNotify:
- LOG(10, (" got ReparentNotify window 0x%8.8x parent 0x%8.8x "
- "event 0x%8.8x x %d y %d overrider redirect %d",
+ LOG(10, (" got ReparentNotify window 0x%8.8lx parent 0x%8.8lx "
+ "event 0x%8.8lx x %d y %d override redirect %d",
lxevent->xreparent.window, lxevent->xreparent.parent,
lxevent->xreparent.event, lxevent->xreparent.x,
lxevent->xreparent.y, lxevent->xreparent.override_redirect));
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index a07e36eb..41fe66a4 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -900,7 +900,8 @@ scard_add_new_device(tui32 device_id)
return -1;
}
- if ((sc = g_malloc(sizeof(SMARTCARD), 1)) == NULL)
+ sc = g_new0(SMARTCARD, 1);
+ if (sc == NULL)
{
log_error("system out of memory");
return -1;
@@ -1255,7 +1256,7 @@ scard_send_GetStatusChange(IRP* irp, char *context, int context_bytes,
struct stream *s;
tui32 ioctl;
int bytes;
- int i;
+ unsigned int i;
int num_chars;
int index;
twchar w_reader_name[100];
@@ -1854,8 +1855,8 @@ scard_send_Transmit(IRP *irp, char *context, int context_bytes,
}
log_debug("send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d "
- "extra_bytes %d recv dwProtocol %d cbPciLength %d", send_bytes,
- recv_bytes, send_ior->dwProtocol, send_ior->cbPciLength,
+ "extra_bytes %d recv dwProtocol %d cbPciLength %d extra_bytes %d",
+ send_bytes, recv_bytes, send_ior->dwProtocol, send_ior->cbPciLength,
send_ior->extra_bytes, recv_ior->dwProtocol, recv_ior->cbPciLength,
recv_ior->extra_bytes);
@@ -1873,7 +1874,7 @@ scard_send_Transmit(IRP *irp, char *context, int context_bytes,
* u32 4 bytes dwProtocol
* u32 4 bytes cbPciLength
* u32 4 bytes map2
- * u32 4 byts cbSendLength
+ * u32 4 bytes cbSendLength
* u32 4 bytes map3
* u32 4 bytes map4
* u32 4 bytes map5
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index 9824432e..29bd5a23 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -97,7 +97,7 @@ create_uds_client(struct trans *con)
{
return 0;
}
- uds_client = g_malloc(sizeof(struct pcsc_uds_client), 1);
+ uds_client = g_new0(struct pcsc_uds_client, 1);
if (uds_client == 0)
{
return 0;
@@ -145,7 +145,7 @@ get_uds_client_by_id(int uds_client_id)
/*****************************************************************************/
struct pcsc_context *
get_pcsc_context_by_app_context(struct pcsc_uds_client *uds_client,
- int app_context)
+ tui32 app_context)
{
struct pcsc_context *rv;
int index;
@@ -173,7 +173,7 @@ get_pcsc_context_by_app_context(struct pcsc_uds_client *uds_client,
/*****************************************************************************/
struct pcsc_card *
get_pcsc_card_by_app_card(struct pcsc_uds_client *uds_client,
- int app_card, struct pcsc_context **acontext)
+ tui32 app_card, struct pcsc_context **acontext)
{
struct pcsc_card *lcard;
struct pcsc_context *lcontext;
@@ -259,7 +259,7 @@ free_uds_client(struct pcsc_uds_client *uds_client)
}
list_delete(context->cards);
}
- LLOGLN(10, (" left over context 0x%8.8x", context->context));
+ LLOGLN(10, (" left over context %p", context->context));
scard_send_cancel(0, context->context, context->context_bytes);
scard_send_release_context(0, context->context,
context->context_bytes);
@@ -606,7 +606,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
g_free(groups);
return 1;
}
- pcscListReaders = g_malloc(sizeof(struct pcsc_list_readers), 1);
+ pcscListReaders = g_new0(struct pcsc_list_readers, 1);
pcscListReaders->uds_client_id = uds_client->uds_client_id;
pcscListReaders->cchReaders = cchReaders;
scard_send_list_readers(pcscListReaders, lcontext->context,
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index e0628a87..e2b6f53b 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -30,6 +30,16 @@
#include "file_loc.h"
#include "chansrv_common.h"
+#if defined(XRDP_OPUS)
+#include <opus/opus.h>
+static OpusEncoder *g_opus_encoder = 0;
+#endif
+
+#if defined(XRDP_MP3LAME)
+#include <lame/lame.h>
+static lame_global_flags *g_lame_encoder = 0;
+#endif
+
extern int g_rdpsnd_chan_id; /* in chansrv.c */
extern int g_display_num; /* in chansrv.c */
@@ -50,11 +60,13 @@ static int g_bytes_in_fifo = 0;
static struct stream *g_stream_inp = NULL;
static struct stream *g_stream_incoming_packet = NULL;
-#define BBUF_SIZE (1024 * 8)
-char g_buffer[BBUF_SIZE];
-int g_buf_index = 0;
-int g_sent_time[256];
-int g_sent_flag[256];
+#define MAX_BBUF_SIZE (1024 * 16)
+static char g_buffer[MAX_BBUF_SIZE];
+static int g_buf_index = 0;
+static int g_sent_time[256];
+static int g_sent_flag[256];
+
+static int g_bbuf_size = 1024 * 8; /* may change later */
struct xr_wave_format_ex
{
@@ -65,12 +77,12 @@ struct xr_wave_format_ex
int nBlockAlign;
int wBitsPerSample;
int cbSize;
- char *data;
+ tui8 *data;
};
/* output formats */
-static char g_pcm_22050_data[] = { 0 };
+static tui8 g_pcm_22050_data[] = { 0 };
static struct xr_wave_format_ex g_pcm_22050 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
@@ -83,7 +95,7 @@ static struct xr_wave_format_ex g_pcm_22050 =
g_pcm_22050_data /* data */
};
-static char g_pcm_44100_data[] = { 0 };
+static tui8 g_pcm_44100_data[] = { 0 };
static struct xr_wave_format_ex g_pcm_44100 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
@@ -96,13 +108,55 @@ static struct xr_wave_format_ex g_pcm_44100 =
g_pcm_44100_data /* data */
};
-#define SND_NUM_OUTP_FORMATS 2
-static struct xr_wave_format_ex *g_wave_outp_formats[SND_NUM_OUTP_FORMATS] =
+#if defined(XRDP_OPUS)
+static tui8 g_opus_44100_data[] = { 0 };
+static struct xr_wave_format_ex g_opus_44100 =
+{
+ 0x0069, /* wFormatTag - WAVE_FORMAT_OPUS */
+ 2, /* num of channels */
+ 44100, /* samples per sec */
+ 176400, /* avg bytes per sec */
+ 4, /* block align */
+ 16, /* bits per sample */
+ 0, /* data size */
+ g_opus_44100_data /* data */
+};
+#endif
+
+#if defined(XRDP_MP3LAME)
+static tui8 g_mp3lame_44100_data[] = { 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x71, 0x05 };
+static struct xr_wave_format_ex g_mp3lame_44100 =
+{
+ 0x0055, /* wFormatTag - WAVE_FORMAT_MPEGLAYER3 */
+ 2, /* num of channels */
+ 44100, /* samples per sec */
+ 176400, /* avg bytes per sec */
+ 4, /* block align */
+ 0, /* bits per sample */
+ 12, /* data size */
+ g_mp3lame_44100_data /* data */
+};
+#endif
+
+static struct xr_wave_format_ex *g_wave_outp_formats[] =
{
&g_pcm_44100,
- &g_pcm_22050
+ &g_pcm_22050,
+#if defined(XRDP_OPUS)
+ &g_opus_44100,
+#endif
+#if defined(XRDP_MP3LAME)
+ &g_mp3lame_44100,
+#endif
+ 0
};
+static int g_client_does_opus = 0;
+static int g_client_opus_index = 0;
+
+static int g_client_does_mp3lame = 0;
+static int g_client_mp3lame_index = 0;
+
/* index into list from client */
static int g_current_client_format_index = 0;
@@ -111,7 +165,7 @@ static int g_current_server_format_index = 0;
/* input formats */
-static char g_pcm_inp_22050_data[] = { 0 };
+static tui8 g_pcm_inp_22050_data[] = { 0 };
static struct xr_wave_format_ex g_pcm_inp_22050 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
@@ -124,7 +178,7 @@ static struct xr_wave_format_ex g_pcm_inp_22050 =
g_pcm_inp_22050_data /* data */
};
-static char g_pcm_inp_44100_data[] = { 0 };
+static tui8 g_pcm_inp_44100_data[] = { 0 };
static struct xr_wave_format_ex g_pcm_inp_44100 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
@@ -137,11 +191,11 @@ static struct xr_wave_format_ex g_pcm_inp_44100 =
g_pcm_inp_44100_data /* data */
};
-#define SND_NUM_INP_FORMATS 2
-static struct xr_wave_format_ex *g_wave_inp_formats[SND_NUM_INP_FORMATS] =
+static struct xr_wave_format_ex *g_wave_inp_formats[] =
{
&g_pcm_inp_44100,
- &g_pcm_inp_22050
+ &g_pcm_inp_22050,
+ 0
};
static int g_client_input_format_index = 0;
@@ -168,8 +222,13 @@ sound_send_server_output_formats(void)
struct stream *s;
int bytes;
int index;
+ int num_formats;
char *size_ptr;
+ num_formats = sizeof(g_wave_outp_formats) /
+ sizeof(g_wave_outp_formats[0]) - 1;
+ LOG(10, ("sound_send_server_output_formats: num_formats %d", num_formats));
+
make_stream(s);
init_stream(s, 8182);
out_uint16_le(s, SNDC_FORMATS);
@@ -179,9 +238,9 @@ sound_send_server_output_formats(void)
out_uint32_le(s, 0); /* dwVolume */
out_uint32_le(s, 0); /* dwPitch */
out_uint16_le(s, 0); /* wDGramPort */
- out_uint16_le(s, SND_NUM_OUTP_FORMATS); /* wNumberOfFormats */
+ out_uint16_le(s, num_formats); /* wNumberOfFormats */
out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */
- out_uint16_le(s, 2); /* wVersion */
+ out_uint16_le(s, 5); /* wVersion */
out_uint8(s, 0); /* bPad */
/* sndFormats */
@@ -203,7 +262,7 @@ sound_send_server_output_formats(void)
00 00
*/
- for (index = 0; index < SND_NUM_OUTP_FORMATS; index++)
+ for (index = 0; index < num_formats; index++)
{
out_uint16_le(s, g_wave_outp_formats[index]->wFormatTag);
out_uint16_le(s, g_wave_outp_formats[index]->nChannels);
@@ -302,6 +361,22 @@ sound_process_output_format(int aindex, int wFormatTag, int nChannels,
}
}
#endif
+
+ if (wFormatTag == 0x0069)
+ {
+ LOG(0, ("wFormatTag, opus"));
+ g_client_does_opus = 1;
+ g_client_opus_index = aindex;
+ g_bbuf_size = 11520;
+ }
+ else if (wFormatTag == 0x0055)
+ {
+ LOG(0, ("wFormatTag, mp3"));
+ g_client_does_mp3lame = 1;
+ g_client_mp3lame_index = aindex;
+ g_bbuf_size = 11520;
+ }
+
return 0;
}
@@ -355,6 +430,182 @@ sound_process_output_formats(struct stream *s, int size)
return 0;
}
+#if defined(XRDP_OPUS)
+
+/*****************************************************************************/
+static int
+sound_wave_compress_opus(char *data, int data_bytes, int *format_index)
+{
+ unsigned char *cdata;
+ int cdata_bytes;
+ int rv;
+ int error;
+ int data_bytes_org;
+ opus_int16 *os16;
+
+ if (g_client_does_opus == 0)
+ {
+ return data_bytes;
+ }
+ if (g_opus_encoder == 0)
+ {
+ /* NB (narrowband) 8 kHz
+ MB (medium-band) 12 kHz
+ WB (wideband) 16 kHz
+ SWB (super-wideband) 24 kHz
+ FB (fullband) 48 kHz */
+ g_opus_encoder = opus_encoder_create(48000, 2,
+ OPUS_APPLICATION_AUDIO,
+ &error);
+ if (g_opus_encoder == 0)
+ {
+ LOG(0, ("sound_wave_compress_opus: opus_encoder_create failed"));
+ return data_bytes;
+ }
+ }
+ data_bytes_org = data_bytes;
+ rv = data_bytes;
+ cdata_bytes = data_bytes;
+ cdata = (unsigned char *) g_malloc(cdata_bytes, 0);
+ os16 = (opus_int16 *) data;
+ /* at 48000 we have
+ 2.5 ms 480
+ 5 ms 960
+ 10 ms 1920
+ 20 ms 3840
+ 40 ms 7680
+ 60 ms 11520 */
+ if (data_bytes < g_bbuf_size)
+ {
+ g_memset(data + data_bytes, 0, g_bbuf_size - data_bytes);
+ data_bytes = g_bbuf_size;
+ }
+ cdata_bytes = opus_encode(g_opus_encoder, os16, data_bytes / 4,
+ cdata, cdata_bytes);
+ if ((cdata_bytes > 0) && (cdata_bytes < data_bytes_org))
+ {
+ *format_index = g_client_opus_index;
+ g_memcpy(data, cdata, cdata_bytes);
+ rv = cdata_bytes;
+ }
+ g_free(cdata);
+ return rv;
+}
+
+#else
+
+/*****************************************************************************/
+static int
+sound_wave_compress_opus(char *data, int data_bytes, int *format_index)
+{
+ return data_bytes;
+}
+
+#endif
+
+#if defined(XRDP_MP3LAME)
+
+/*****************************************************************************/
+static int
+sound_wave_compress_mp3lame(char *data, int data_bytes, int *format_index)
+{
+ int rv;
+ int cdata_bytes;
+ int odata_bytes;
+ unsigned char *cdata;
+
+ cdata = NULL;
+ rv = data_bytes;
+
+ if (g_client_does_mp3lame == 0)
+ {
+ return rv;
+ }
+
+ if (g_lame_encoder == 0)
+ {
+ /* init mp3 lame encoder */
+ LOG(0, ("sound_wave_compress_mp3lame: using mp3lame"));
+
+ g_lame_encoder = lame_init();
+ if (g_lame_encoder == 0)
+ {
+ LOG(0, ("sound_wave_compress_mp3lame: lame_init() failed"));
+ return rv;
+ }
+ lame_set_num_channels(g_lame_encoder, g_mp3lame_44100.nChannels);
+ lame_set_in_samplerate(g_lame_encoder, g_mp3lame_44100.nSamplesPerSec);
+ if (lame_init_params(g_lame_encoder) == -1)
+ {
+ LOG(0, ("sound_wave_compress_mp3lame: lame_init_params() failed"));
+ return rv;
+ }
+
+ LOG(0, ("sound_wave_compress_mp3lame: lame config:"));
+ LOG(0, (" brate : %d", lame_get_brate(g_lame_encoder)));
+ LOG(0, (" compression ratio: %f", lame_get_compression_ratio(g_lame_encoder)));
+ LOG(0, (" encoder delay : %d", lame_get_encoder_delay(g_lame_encoder)));
+ LOG(0, (" frame size : %d", lame_get_framesize(g_lame_encoder)));
+ LOG(0, (" encoder padding : %d", lame_get_encoder_padding(g_lame_encoder)));
+ LOG(0, (" mode : %d", lame_get_mode(g_lame_encoder)));
+ }
+
+ odata_bytes = data_bytes;
+ cdata_bytes = data_bytes;
+ cdata = (unsigned char *) g_malloc(cdata_bytes, 0);
+ if (data_bytes < g_bbuf_size)
+ {
+ g_memset(data + data_bytes, 0, g_bbuf_size - data_bytes);
+ data_bytes = g_bbuf_size;
+ }
+ cdata_bytes = lame_encode_buffer_interleaved(g_lame_encoder,
+ (short int *) data,
+ data_bytes / 4,
+ cdata,
+ cdata_bytes);
+ if (cdata_bytes < 0)
+ {
+ LOG(0, ("sound_wave_compress: lame_encode_buffer_interleaved() "
+ "failed, error %d", cdata_bytes));
+ return rv;
+ }
+ if ((cdata_bytes > 0) && (cdata_bytes < odata_bytes))
+ {
+ *format_index = g_client_mp3lame_index;
+ g_memcpy(data, cdata, cdata_bytes);
+ rv = cdata_bytes;
+ }
+
+ g_free(cdata);
+ return rv;
+}
+
+#else
+
+/*****************************************************************************/
+static int
+sound_wave_compress_mp3lame(char *data, int data_bytes, int *format_index)
+{
+ return data_bytes;
+}
+
+#endif
+
+/*****************************************************************************/
+static int
+sound_wave_compress(char *data, int data_bytes, int *format_index)
+{
+ if (g_client_does_opus)
+ {
+ return sound_wave_compress_opus(data, data_bytes, format_index);
+ }
+ else if (g_client_does_mp3lame)
+ {
+ return sound_wave_compress_mp3lame(data, data_bytes, format_index);
+ }
+ return data_bytes;
+}
+
/*****************************************************************************/
/* send wave message to client */
static int
@@ -363,6 +614,7 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
struct stream *s;
int bytes;
int time;
+ int format_index;
char *size_ptr;
LOG(10, ("sound_send_wave_data_chunk: data_bytes %d", data_bytes));
@@ -385,6 +637,10 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
LOG(10, ("sound_send_wave_data_chunk: got room"));
}
+ /* compress, if available */
+ format_index = g_current_client_format_index;
+ data_bytes = sound_wave_compress(data, data_bytes, &format_index);
+
/* part one of 2 PDU wave info */
LOG(10, ("sound_send_wave_data_chunk: sending %d bytes", data_bytes));
@@ -396,7 +652,7 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
out_uint16_le(s, 0); /* size, set later */
time = g_time2();
out_uint16_le(s, time);
- out_uint16_le(s, g_current_client_format_index); /* wFormatNo */
+ out_uint16_le(s, format_index); /* wFormatNo */
g_cBlockNo++;
out_uint8(s, g_cBlockNo);
g_sent_time[g_cBlockNo & 0xff] = time;
@@ -445,7 +701,7 @@ sound_send_wave_data(char *data, int data_bytes)
error = 0;
while (data_bytes > 0)
{
- space_left = BBUF_SIZE - g_buf_index;
+ space_left = g_bbuf_size - g_buf_index;
chunk_bytes = MIN(space_left, data_bytes);
if (chunk_bytes < 1)
{
@@ -455,10 +711,10 @@ sound_send_wave_data(char *data, int data_bytes)
}
g_memcpy(g_buffer + g_buf_index, data + data_index, chunk_bytes);
g_buf_index += chunk_bytes;
- if (g_buf_index >= BBUF_SIZE)
+ if (g_buf_index >= g_bbuf_size)
{
g_buf_index = 0;
- res = sound_send_wave_data_chunk(g_buffer, BBUF_SIZE);
+ res = sound_send_wave_data_chunk(g_buffer, g_bbuf_size);
if (res == 2)
{
/* don't need to error on this */
@@ -695,6 +951,12 @@ sound_init(void)
/* save data from sound_server_source */
fifo_init(&g_in_fifo, 100);
+ g_client_does_opus = 0;
+ g_client_opus_index = 0;
+
+ g_client_does_mp3lame = 0;
+ g_client_mp3lame_index = 0;
+
return 0;
}
@@ -727,6 +989,15 @@ sound_deinit(void)
g_audio_c_trans_in = 0;
}
+#if defined(XRDP_MP3LAME)
+ if (g_lame_encoder)
+ {
+ lame_close(g_lame_encoder);
+ g_lame_encoder = 0;
+ g_client_does_mp3lame = 0;
+ }
+#endif
+
fifo_deinit(&g_in_fifo);
return 0;
@@ -878,7 +1149,7 @@ sound_check_wait_objs(void)
/******************************************************************************
** **
- ** Microphone releated code **
+ ** Microphone related code **
** **
******************************************************************************/
@@ -889,10 +1160,15 @@ sound_check_wait_objs(void)
static int APP_CC
sound_send_server_input_formats(void)
{
- struct stream* s;
- int bytes;
- int index;
- char* size_ptr;
+ struct stream *s;
+ int bytes;
+ int index;
+ int num_formats;
+ char *size_ptr;
+
+ num_formats = sizeof(g_wave_inp_formats) /
+ sizeof(g_wave_inp_formats[0]) - 1;
+ LOG(10, ("sound_send_server_input_formats: num_formats %d", num_formats));
make_stream(s);
init_stream(s, 8182);
@@ -901,8 +1177,8 @@ sound_send_server_input_formats(void)
out_uint16_le(s, 0); /* size, set later */
out_uint32_le(s, 0); /* unused */
out_uint32_le(s, 0); /* unused */
- out_uint16_le(s, SND_NUM_INP_FORMATS); /* wNumberOfFormats */
- out_uint16_le(s, 2); /* wVersion */
+ out_uint16_le(s, num_formats); /* wNumberOfFormats */
+ out_uint16_le(s, 5); /* wVersion */
/*
wFormatTag 2 byte offset 0
@@ -915,7 +1191,7 @@ sound_send_server_input_formats(void)
data variable offset 18
*/
- for (index = 0; index < SND_NUM_INP_FORMATS; index++)
+ for (index = 0; index < num_formats; index++)
{
out_uint16_le(s, g_wave_inp_formats[index]->wFormatTag);
out_uint16_le(s, g_wave_inp_formats[index]->nChannels);
diff --git a/sesman/chansrv/wave-format-server.txt b/sesman/chansrv/wave-format-server.txt
index 1d0bb91e..3a197a71 100644
--- a/sesman/chansrv/wave-format-server.txt
+++ b/sesman/chansrv/wave-format-server.txt
@@ -464,3 +464,470 @@ wFormatTag=353 nChannels=1 nSamplesPerSec=8000 nAvgBytesPerSec=750 nBlockAlign=4
?
wFormatTag=66 nChannels=1 nSamplesPerSec=8000 nAvgBytesPerSec=666 nBlockAlign=20 wBitsPerSample=0 cbSize=10
0000 03 00 ce 9a 32 f7 a2 ae de ac ....2.....
+
+
+
+//***************************************************************
+// Windows 7 SP1 x64 Server Formats
+WAVE_FORMAT_PCM:
+wFormatTag: 0x0001 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 176400 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44359 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44251 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22311 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22201 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22179 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22125 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11289 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11177 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11155 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11100 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 8957 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8192 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8110 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5644 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5588 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4478 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4096 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4055 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2239 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1625 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+
+//***************************************************************
+// Windows 10 10586 x64 Server Formats
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 24000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 20000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 16000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 12000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_PCM:
+wFormatTag: 0x0001 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 176400 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44359 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44251 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22311 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22201 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22179 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22125 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11289 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11177 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11155 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11100 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 8957 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8192 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8110 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5644 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5588 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4478 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4096 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4055 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2239 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1625 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+
+//***************************************************************
+// Windows Server 2016 TP4 x64 Server Formats
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 24000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 20000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 16000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 12000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_PCM:
+wFormatTag: 0x0001 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 176400 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44359 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44251 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22311 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22201 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22179 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22125 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11289 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11177 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11155 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11100 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 8957 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8192 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8110 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5644 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5588 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4478 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4096 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4055 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2239 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1625 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+
+
+
+
+//***************************************************************
+// Windows XP SP3 x86 Server Formats
+WAVE_FORMAT_PCM:
+wFormatTag: 0x0001 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 88200 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22311 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22201 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 22050 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 22050 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 22050 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 22050 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 16000 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 16000 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11289 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11177 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11155 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11100 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 11025 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 11025 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8192 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8110 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 8000 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 8000 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 7000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 16000 nAvgBytesPerSec: 7000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 6000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 16000 nAvgBytesPerSec: 6000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5644 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5588 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 5000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 16000 nAvgBytesPerSec: 5000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4478 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4096 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4055 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 4005 nBlockAlign: 186 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 16000 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 12000 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 12000 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 2519 nBlockAlign: 117 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 2519 nBlockAlign: 117 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 12000 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 12000 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 12000 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 12000 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2239 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 2000 nBlockAlign: 64 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 2000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 12000 nAvgBytesPerSec: 2000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 2000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1625 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 1500 nBlockAlign: 96 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 1249 nBlockAlign: 58 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_DSPGROUP_TRUESPEECH :
+wFormatTag: 0x0022 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1067 nBlockAlign: 32 wBitsPerSample: 1 cbSize: 32
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 1012 nBlockAlign: 47 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1000 nBlockAlign: 64 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 12000 nAvgBytesPerSec: 1000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 1000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MSG723:
+wFormatTag: 0x0042 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 800 nBlockAlign: 24 wBitsPerSample: 0 cbSize: 10
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 750 nBlockAlign: 48 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MSG723:
+wFormatTag: 0x0042 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 666 nBlockAlign: 20 wBitsPerSample: 0 cbSize: 10
+
diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c
index 919bc41b..9aae4a06 100644
--- a/sesman/chansrv/xcommon.c
+++ b/sesman/chansrv/xcommon.c
@@ -63,15 +63,17 @@ xcommon_error_handler(Display *dis, XErrorEvent *xer)
/* The X server had an internal error. This is the last function called.
Do any cleanup that needs to be done on exit, like removing temporary files.
Don't worry about memory leaks */
+#if 0
static int DEFAULT_CC
xcommon_fatal_handler(Display *dis)
{
return 0;
}
+#endif
/*****************************************************************************/
-/* returns time in miliseconds
- this is like g_time2 in os_calls, but not miliseconds since machine was
+/* returns time in milliseconds
+ this is like g_time2 in os_calls, but not milliseconds since machine was
up, something else
this is a time value similar to what the xserver uses */
int APP_CC
diff --git a/sesman/config.c b/sesman/config.c
index 5a904fc3..0c169938 100644
--- a/sesman/config.c
+++ b/sesman/config.c
@@ -182,61 +182,6 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
return 0;
}
-/******************************************************************************
-int DEFAULT_CC
-config_read_logging(int file, struct log_config* lc, struct list* param_n,
- struct list* param_v)
-{
- int i;
- char* buf;
-
- list_clear(param_v);
- list_clear(param_n);
-
- // setting defaults
- lc->program_name = g_strdup("sesman");
- lc->log_file = 0;
- lc->fd = 0;
- lc->log_level = LOG_LEVEL_DEBUG;
- lc->enable_syslog = 0;
- lc->syslog_level = LOG_LEVEL_DEBUG;
-
- file_read_section(file, SESMAN_CFG_LOGGING, param_n, param_v);
- for (i = 0; i < param_n->count; i++)
- {
- buf = (char*)list_get_item(param_n, i);
- if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_FILE))
- {
- lc->log_file = g_strdup((char*)list_get_item(param_v, i));
- }
- if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_LEVEL))
- {
- lc->log_level = log_text2level((char*)list_get_item(param_v, i));
- }
- if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_SYSLOG))
- {
- lc->enable_syslog = g_text2bool((char*)list_get_item(param_v, i));
- }
- if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_SYSLOG_LEVEL))
- {
- lc->syslog_level = log_text2level((char*)list_get_item(param_v, i));
- }
- }
-
- if (0 == lc->log_file)
- {
- lc->log_file=g_strdup("./sesman.log");
- }
-
- g_printf("logging configuration:\r\n");
- g_printf("\tLogFile: %s\r\n",lc->log_file);
- g_printf("\tLogLevel: %i\r\n", lc->log_level);
- g_printf("\tEnableSyslog: %i\r\n", lc->enable_syslog);
- g_printf("\tSyslogLevel: %i\r\n", lc->syslog_level);
-
- return 0;
-}
-*/
/******************************************************************************/
int DEFAULT_CC
config_read_security(int file, struct config_security *sc,
@@ -347,7 +292,7 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
{
buf = (char *)list_get_item(param_n, i);
- if (0 == g_strcasecmp(buf, SESMAN_CFG_X11DISPLAYOFFSET))
+ if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_X11DISPLAYOFFSET))
{
se->x11_display_offset = g_atoi((char *)list_get_item(param_v, i));
}
@@ -429,6 +374,7 @@ config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n,
list_clear(param_n);
cs->rdp_params = list_create();
+ cs->rdp_params->auto_free = 1;
file_read_section(file, SESMAN_CFG_RDP_PARAMS, param_n, param_v);
@@ -437,7 +383,7 @@ config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n,
list_add_item(cs->rdp_params, (long)g_strdup((char *)list_get_item(param_v, i)));
}
- /* printing security config */
+ /* printing X11rdp parameters */
g_printf("X11rdp parameters:\r\n");
for (i = 0; i < cs->rdp_params->count; i++)
@@ -459,6 +405,7 @@ config_read_xorg_params(int file, struct config_sesman *cs,
list_clear(param_n);
cs->xorg_params = list_create();
+ cs->xorg_params->auto_free = 1;
file_read_section(file, SESMAN_CFG_XORG_PARAMS, param_n, param_v);
@@ -468,7 +415,7 @@ config_read_xorg_params(int file, struct config_sesman *cs,
(long) g_strdup((char *) list_get_item(param_v, i)));
}
- /* printing security config */
+ /* printing XOrg parameters */
g_printf("XOrg parameters:\r\n");
for (i = 0; i < cs->xorg_params->count; i++)
@@ -491,6 +438,7 @@ config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n,
list_clear(param_n);
cs->vnc_params = list_create();
+ cs->vnc_params->auto_free = 1;
file_read_section(file, SESMAN_CFG_VNC_PARAMS, param_n, param_v);
@@ -499,7 +447,7 @@ config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n,
list_add_item(cs->vnc_params, (long)g_strdup((char *)list_get_item(param_v, i)));
}
- /* printing security config */
+ /* printing Xvnc parameters */
g_printf("Xvnc parameters:\r\n");
for (i = 0; i < cs->vnc_params->count; i++)
@@ -521,7 +469,9 @@ config_read_session_variables(int file, struct config_sesman *cs,
list_clear(param_n);
cs->session_variables1 = list_create();
+ cs->session_variables1->auto_free = 1;
cs->session_variables2 = list_create();
+ cs->session_variables2->auto_free = 1;
file_read_section(file, SESMAN_CFG_SESSION_VARIABLES, param_n, param_v);
@@ -533,7 +483,7 @@ config_read_session_variables(int file, struct config_sesman *cs,
(tintptr) g_strdup((char *) list_get_item(param_v, i)));
}
- /* printing security config */
+ /* printing session variables */
g_writeln("%s parameters:", SESMAN_CFG_SESSION_VARIABLES);
for (i = 0; i < cs->session_variables1->count; i++)
@@ -545,3 +495,14 @@ config_read_session_variables(int file, struct config_sesman *cs,
return 0;
}
+
+void
+config_free(struct config_sesman *cs)
+{
+ list_delete(cs->rdp_params);
+ list_delete(cs->vnc_params);
+ list_delete(cs->xorg_params);
+ list_delete(cs->session_variables1);
+ list_delete(cs->session_variables2);
+ g_free(cs);
+}
diff --git a/sesman/config.h b/sesman/config.h
index 08d84ce1..2baef632 100644
--- a/sesman/config.h
+++ b/sesman/config.h
@@ -37,7 +37,6 @@
#define SESMAN_CFG_PORT "ListenPort"
#define SESMAN_CFG_ENABLE_USERWM "EnableUserWindowManager"
#define SESMAN_CFG_USERWM "UserWindowManager"
-#define SESMAN_CFG_X11DISPLAYOFFSET "X11DisplayOffset"
#define SESMAN_CFG_MAX_SESSION "MaxSessions"
#define SESMAN_CFG_AUTH_FILE_PATH "AuthFilePath"
@@ -66,6 +65,7 @@
#define SESMAN_CFG_SESS_KILL_DISC "KillDisconnected"
#define SESMAN_CFG_SESS_IDLE_LIMIT "IdleTimeLimit"
#define SESMAN_CFG_SESS_DISC_LIMIT "DisconnectedTimeLimit"
+#define SESMAN_CFG_SESS_X11DISPLAYOFFSET "X11DisplayOffset"
#define SESMAN_CFG_SESS_POLICY_S "Policy"
#define SESMAN_CFG_SESS_POLICY_DFLT_S "Default"
@@ -116,7 +116,7 @@ struct config_security
int ts_users;
/**
* @var ts_admins
- * @brief Terminal Server Adminnistrators group
+ * @brief Terminal Server Administrators group
*/
int ts_admins_enable;
int ts_admins;
@@ -220,16 +220,14 @@ struct config_sesman
*/
struct list* rdp_params;
/**
- * @var log
- * @brief Log configuration struct
+ * @var xorg_params
+ * @brief Xorg additional parameter list
*/
-
struct list* xorg_params;
/**
* @var log
* @brief Log configuration struct
*/
-
//struct log_config log;
/**
* @var sec
@@ -358,4 +356,7 @@ int DEFAULT_CC
config_read_session_variables(int file, struct config_sesman *cs,
struct list *param_n, struct list *param_v);
+void
+config_free(struct config_sesman *cs);
+
#endif
diff --git a/sesman/env.c b/sesman/env.c
index 227f6bbf..d8eb3106 100644
--- a/sesman/env.c
+++ b/sesman/env.c
@@ -25,60 +25,83 @@
*/
#include "list.h"
-
#include "sesman.h"
-
-#include "sys/types.h"
#include "grp.h"
+#include "ssl_calls.h"
extern unsigned char g_fixedkey[8]; /* in sesman.c */
extern struct config_sesman *g_cfg; /* in sesman.c */
/******************************************************************************/
int DEFAULT_CC
-env_check_password_file(char *filename, char *password)
+env_check_password_file(const char *filename, const char *passwd)
{
char encryptedPasswd[16];
+ char key[24];
+ char passwd_hash[20];
+ char passwd_hash_text[40];
int fd;
-
- g_memset(encryptedPasswd, 0, 16);
- g_strncpy(encryptedPasswd, password, 8);
- rfbDesKey(g_fixedkey, 0);
- rfbDes((unsigned char *)encryptedPasswd, (unsigned char *)encryptedPasswd);
- fd = g_file_open(filename);
-
+ int passwd_bytes;
+ void *des;
+ void *sha1;
+
+ /* create password hash from password */
+ passwd_bytes = g_strlen(passwd);
+ sha1 = ssl_sha1_info_create();
+ ssl_sha1_transform(sha1, "xrdp_vnc", 8);
+ ssl_sha1_transform(sha1, passwd, passwd_bytes);
+ ssl_sha1_transform(sha1, passwd, passwd_bytes);
+ ssl_sha1_complete(sha1, passwd_hash);
+ ssl_sha1_info_delete(sha1);
+ g_snprintf(passwd_hash_text, 39, "%2.2x%2.2x%2.2x%2.2x",
+ (tui8)passwd_hash[0], (tui8)passwd_hash[1],
+ (tui8)passwd_hash[2], (tui8)passwd_hash[3]);
+ passwd_hash_text[39] = 0;
+ passwd = passwd_hash_text;
+
+ /* create file from password */
+ g_memset(encryptedPasswd, 0, sizeof(encryptedPasswd));
+ g_strncpy(encryptedPasswd, passwd, 8);
+ g_memset(key, 0, sizeof(key));
+ g_mirror_memcpy(key, g_fixedkey, 8);
+ des = ssl_des3_encrypt_info_create(key, 0);
+ ssl_des3_encrypt(des, 8, encryptedPasswd, encryptedPasswd);
+ ssl_des3_info_delete(des);
+ fd = g_file_open_ex(filename, 0, 1, 1, 1);
if (fd == -1)
{
log_message(LOG_LEVEL_WARNING,
- "can't read vnc password file - %s",
- filename);
+ "Cannot write VNC password hash to file %s: %s",
+ filename, g_get_strerror());
return 1;
}
-
g_file_write(fd, encryptedPasswd, 8);
g_file_close(fd);
return 0;
}
/******************************************************************************/
+/* its the responsibility of the caller to free passwd_file */
int DEFAULT_CC
-env_set_user(char *username, char *passwd_file, int display,
- struct list *env_names, struct list* env_values)
+env_set_user(const char *username, char **passwd_file, int display,
+ const struct list *env_names, const struct list *env_values)
{
int error;
int pw_uid;
int pw_gid;
int uid;
int index;
+ int len;
char *name;
char *value;
- char pw_shell[256];
- char pw_dir[256];
- char pw_gecos[256];
+ char *pw_shell;
+ char *pw_dir;
char text[256];
- error = g_getuser_info(username, &pw_gid, &pw_uid, pw_shell, pw_dir,
- pw_gecos);
+ pw_shell = 0;
+ pw_dir = 0;
+
+ error = g_getuser_info(username, &pw_gid, &pw_uid, &pw_shell, &pw_dir, 0);
if (error == 0)
{
@@ -102,7 +125,7 @@ env_set_user(char *username, char *passwd_file, int display,
{
g_clearenv();
g_setenv("SHELL", pw_shell, 1);
- g_setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1);
+ g_setenv("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin", 1);
g_setenv("USER", username, 1);
g_sprintf(text, "%d", uid);
g_setenv("UID", text, 1);
@@ -110,7 +133,6 @@ env_set_user(char *username, char *passwd_file, int display,
g_set_current_dir(pw_dir);
g_sprintf(text, ":%d.0", display);
g_setenv("DISPLAY", text, 1);
- g_setenv("LANG", "en_US.UTF-8", 1);
g_setenv("XRDP_SESSION", "1", 1);
if ((env_names != 0) && (env_values != 0) &&
(env_names->count == env_values->count))
@@ -128,28 +150,64 @@ env_set_user(char *username, char *passwd_file, int display,
if (0 == g_cfg->auth_file_path)
{
/* if no auth_file_path is set, then we go for
- $HOME/.vnc/sesman_username_passwd */
- if (g_mkdir(".vnc") < 0)
+ $HOME/.vnc/sesman_username_passwd:DISPLAY */
+ if (!g_directory_exist(".vnc"))
+ {
+ if (g_mkdir(".vnc") < 0)
+ {
+ log_message(LOG_LEVEL_ERROR,
+ "Error creating .vnc directory: %s",
+ g_get_strerror());
+ }
+ }
+
+ len = g_snprintf(NULL, 0, "%s/.vnc/sesman_%s_passwd:%d",
+ pw_dir, username, display);
+
+ *passwd_file = (char *) g_malloc(len + 1, 1);
+ if (*passwd_file != NULL)
{
- log_message(LOG_LEVEL_ERROR,
- "env_set_user: error creating .vnc dir");
+ /* Try legacy name first, remove if found */
+ g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd",
+ pw_dir, username);
+ if (g_file_exist(*passwd_file))
+ {
+ log_message(LOG_LEVEL_WARNING, "Removing insecure "
+ "password file %s", *passwd_file);
+ g_file_delete(*passwd_file);
+ }
+
+ g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd:%d",
+ pw_dir, username, display);
}
- g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username);
}
else
{
/* we use auth_file_path as requested */
- g_sprintf(passwd_file, g_cfg->auth_file_path, username);
+ len = g_snprintf(NULL, 0, g_cfg->auth_file_path, username);
+
+ *passwd_file = (char *) g_malloc(len + 1, 1);
+ if (*passwd_file != NULL)
+ {
+ g_sprintf(*passwd_file, g_cfg->auth_file_path, username);
+ }
}
- LOG_DBG("pass file: %s", passwd_file);
+ if (*passwd_file != NULL)
+ {
+ LOG_DBG("pass file: %s", *passwd_file);
+ }
}
+
+ g_free(pw_dir);
+ g_free(pw_shell);
}
}
else
{
log_message(LOG_LEVEL_ERROR,
- "error getting user info for user %s", username);
+ "error getting user info for user %s",
+ username);
}
return error;
diff --git a/sesman/env.h b/sesman/env.h
index 50473a01..a7156508 100644
--- a/sesman/env.h
+++ b/sesman/env.h
@@ -33,12 +33,12 @@
*
* @brief Creates vnc password file
* @param filename VNC password file name
- * @param password The password to be encrypte
+ * @param password The password to be encrypted
* @return 0 on success, 1 on error
*
*/
int DEFAULT_CC
-env_check_password_file(char* filename, char* password);
+env_check_password_file(const char *filename, const char *password);
/**
*
@@ -50,7 +50,7 @@ env_check_password_file(char* filename, char* password);
*
*/
int DEFAULT_CC
-env_set_user(char* username, char* passwd_file, int display,
- struct list *env_names, struct list* env_values);
+env_set_user(const char *username, char **passwd_file, int display,
+ const struct list *env_names, const struct list *env_values);
#endif
diff --git a/sesman/libscp/Makefile.am b/sesman/libscp/Makefile.am
index eaf518a8..1bb89910 100644
--- a/sesman/libscp/Makefile.am
+++ b/sesman/libscp/Makefile.am
@@ -1,30 +1,41 @@
-EXTRA_DIST = libscp_connection.h libscp_commands.h libscp.h libscp_session.h libscp_types_mng.h libscp_v1c_mng.h libscp_vX.h libscp_commands_mng.h libscp_init.h libscp_tcp.h libscp_v0.h libscp_v1s.h libscp_lock.h \
-libscp_types.h libscp_v1c.h libscp_v1s_mng.h
-
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
-
-INCLUDES = \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-I$(top_srcdir)/common
-lib_LTLIBRARIES = \
+module_LTLIBRARIES = \
libscp.la
libscp_la_SOURCES = \
+ libscp.h \
+ libscp_commands.h \
+ libscp_commands_mng.h \
libscp_connection.c \
+ libscp_connection.h \
libscp_init.c \
+ libscp_init.h \
libscp_lock.c \
+ libscp_lock.h \
libscp_session.c \
+ libscp_session.h \
libscp_tcp.c \
+ libscp_tcp.h \
+ libscp_types.h \
+ libscp_types_mng.h \
libscp_v0.c \
+ libscp_v0.h \
libscp_v1c.c \
- libscp_v1s.c \
+ libscp_v1c.h \
libscp_v1c_mng.c \
+ libscp_v1c_mng.h \
+ libscp_v1s.c \
+ libscp_v1s.h \
libscp_v1s_mng.c \
- libscp_vX.c
+ libscp_v1s_mng.h \
+ libscp_vX.c \
+ libscp_vX.h
libscp_la_LIBADD = \
$(top_builddir)/common/libcommon.la \
diff --git a/sesman/libscp/libscp_connection.c b/sesman/libscp/libscp_connection.c
index 6366d51a..a5cfcb4a 100644
--- a/sesman/libscp/libscp_connection.c
+++ b/sesman/libscp/libscp_connection.c
@@ -33,11 +33,11 @@ scp_connection_create(int sck)
{
struct SCP_CONNECTION *conn;
- conn = g_malloc(sizeof(struct SCP_CONNECTION), 0);
+ conn = g_new(struct SCP_CONNECTION, 1);
if (0 == conn)
{
- log_message(LOG_LEVEL_WARNING, "[connection:%d] connection create: malloc error", __LINE__);
+ log_message(LOG_LEVEL_ERROR, "[connection:%d] connection create: malloc error", __LINE__);
return 0;
}
diff --git a/sesman/libscp/libscp_init.c b/sesman/libscp/libscp_init.c
index eae57c6e..9d1e7308 100644
--- a/sesman/libscp/libscp_init.c
+++ b/sesman/libscp/libscp_init.c
@@ -43,7 +43,7 @@ scp_init()
scp_lock_init();
- log_message(LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__);
+ log_message(LOG_LEVEL_DEBUG, "libscp initialized");
return 0;
}
diff --git a/sesman/libscp/libscp_init.h b/sesman/libscp/libscp_init.h
index 20a75857..91fb4090 100644
--- a/sesman/libscp/libscp_init.h
+++ b/sesman/libscp/libscp_init.h
@@ -36,7 +36,7 @@
* @brief version neutral server accept function
* @param c connection descriptor
* @param s session descriptor pointer address.
- * it will return a newely allocated descriptor.
+ * it will return a newly allocated descriptor.
* It this memory needs to be g_free()d
*
*/
diff --git a/sesman/libscp/libscp_lock.c b/sesman/libscp/libscp_lock.c
index 4db05422..be0619cb 100644
--- a/sesman/libscp/libscp_lock.c
+++ b/sesman/libscp/libscp_lock.c
@@ -20,16 +20,16 @@
*/
#include "libscp_lock.h"
+#include "thread_calls.h"
-#include <semaphore.h>
#include <pthread.h>
pthread_mutex_t lock_fork; /* this lock protects the counters */
pthread_mutexattr_t lock_fork_attr; /* mutex attributes */
-sem_t lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
-sem_t lock_fork_wait; /* semaphore on which the suspended process wait on */
+tbus lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
+tbus lock_fork_wait; /* semaphore on which the suspended process wait on */
int lock_fork_forkers_count; /* threads that want to fork */
-int lock_fork_blockers_count; /* threads thar are blocking fork */
+int lock_fork_blockers_count; /* threads that are blocking fork */
int lock_fork_waiting_count; /* threads suspended until the fork finishes */
void DEFAULT_CC
@@ -38,8 +38,8 @@ scp_lock_init(void)
/* initializing fork lock */
pthread_mutexattr_init(&lock_fork_attr);
pthread_mutex_init(&lock_fork, &lock_fork_attr);
- sem_init(&lock_fork_req, 0, 0);
- sem_init(&lock_fork_wait, 0, 0);
+ lock_fork_req = tc_sem_create(0);
+ lock_fork_wait = tc_sem_create(0);
/* here we don't use locking because lock_init() should be called BEFORE */
/* any thread is created */
@@ -57,15 +57,15 @@ scp_lock_fork_request(void)
if (lock_fork_blockers_count == 0)
{
- /* if noone is blocking fork(), then we're allowed to fork */
- sem_post(&lock_fork_req);
+ /* if no one is blocking fork(), then we're allowed to fork */
+ tc_sem_inc(lock_fork_req);
}
lock_fork_forkers_count++;
pthread_mutex_unlock(&lock_fork);
/* we wait to be allowed to fork() */
- sem_wait(&lock_fork_req);
+ tc_sem_dec(lock_fork_req);
}
/******************************************************************************/
@@ -78,13 +78,13 @@ scp_lock_fork_release(void)
/* if there's someone else that want to fork, we let him fork() */
if (lock_fork_forkers_count > 0)
{
- sem_post(&lock_fork_req);
+ tc_sem_inc(lock_fork_req);
}
for (; lock_fork_waiting_count > 0; lock_fork_waiting_count--)
{
/* waking up the other processes */
- sem_post(&lock_fork_wait);
+ tc_sem_inc(lock_fork_wait);
}
pthread_mutex_unlock(&lock_fork);
@@ -94,7 +94,7 @@ scp_lock_fork_release(void)
void DEFAULT_CC
scp_lock_fork_critical_section_end(int blocking)
{
- //LOG_DBG("lock_fork_critical_secection_end()",0);
+ //LOG_DBG("lock_fork_critical_section_end()",0);
/* lock mutex */
pthread_mutex_lock(&lock_fork);
@@ -107,7 +107,7 @@ scp_lock_fork_critical_section_end(int blocking)
/* then we let him go */
if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count > 0))
{
- sem_post(&lock_fork_req);
+ tc_sem_inc(lock_fork_req);
}
pthread_mutex_unlock(&lock_fork);
@@ -117,7 +117,7 @@ scp_lock_fork_critical_section_end(int blocking)
int DEFAULT_CC
scp_lock_fork_critical_section_start(void)
{
- //LOG_DBG("lock_fork_critical_secection_start()",0);
+ //LOG_DBG("lock_fork_critical_section_start()",0);
do
{
pthread_mutex_lock(&lock_fork);
@@ -129,7 +129,7 @@ scp_lock_fork_critical_section_start(void)
pthread_mutex_unlock(&lock_fork);
/* we wait until the fork finishes */
- sem_wait(&lock_fork_wait);
+ tc_sem_dec(lock_fork_wait);
}
else
diff --git a/sesman/libscp/libscp_lock.h b/sesman/libscp/libscp_lock.h
index b4e93c52..ae2c361b 100644
--- a/sesman/libscp/libscp_lock.h
+++ b/sesman/libscp/libscp_lock.h
@@ -52,8 +52,8 @@ scp_lock_fork_release(void);
*
* @brief starts a section that is critical for forking
*
- * starts a section that is critical for forking, that is noone can fork()
- * while i'm in a critical section. But if someone wanted to fork we have
+ * starts a section that is critical for forking, that is no one can fork()
+ * while I'm in a critical section. But if someone wanted to fork we have
* to wait until he finishes with lock_fork_release()
*
* @return
diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c
index d25fc64a..527d6d29 100644
--- a/sesman/libscp/libscp_session.c
+++ b/sesman/libscp/libscp_session.c
@@ -42,7 +42,7 @@ scp_session_create()
if (0 == s)
{
- log_message(LOG_LEVEL_WARNING, "[session:%d] session create: malloc error", __LINE__);
+ log_message(LOG_LEVEL_ERROR, "[session:%d] session create: malloc error", __LINE__);
return 0;
}
@@ -137,11 +137,12 @@ scp_session_set_bpp(struct SCP_SESSION *s, tui8 bpp)
case 15:
case 16:
case 24:
+ case 32:
s->bpp = bpp;
+ break;
default:
return 1;
}
-
return 0;
}
@@ -163,7 +164,7 @@ scp_session_set_rsr(struct SCP_SESSION *s, tui8 rsr)
/*******************************************************************/
int
-scp_session_set_locale(struct SCP_SESSION *s, char *str)
+scp_session_set_locale(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -179,7 +180,7 @@ scp_session_set_locale(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_username(struct SCP_SESSION *s, char *str)
+scp_session_set_username(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -205,7 +206,7 @@ scp_session_set_username(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_password(struct SCP_SESSION *s, char *str)
+scp_session_set_password(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -231,7 +232,7 @@ scp_session_set_password(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_domain(struct SCP_SESSION *s, char *str)
+scp_session_set_domain(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -257,7 +258,7 @@ scp_session_set_domain(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_program(struct SCP_SESSION *s, char *str)
+scp_session_set_program(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -283,7 +284,7 @@ scp_session_set_program(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_directory(struct SCP_SESSION *s, char *str)
+scp_session_set_directory(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -309,7 +310,7 @@ scp_session_set_directory(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_client_ip(struct SCP_SESSION *s, char *str)
+scp_session_set_client_ip(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -335,7 +336,7 @@ scp_session_set_client_ip(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_hostname(struct SCP_SESSION *s, char *str)
+scp_session_set_hostname(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -361,7 +362,7 @@ scp_session_set_hostname(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_errstr(struct SCP_SESSION *s, char *str)
+scp_session_set_errstr(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -395,49 +396,15 @@ scp_session_set_display(struct SCP_SESSION *s, SCP_DISPLAY display)
/*******************************************************************/
int
-scp_session_set_addr(struct SCP_SESSION *s, int type, void *addr)
+scp_session_set_addr(struct SCP_SESSION *s, int type, const void *addr)
{
- struct in_addr ip4;
-#ifdef IN6ADDR_ANY_INIT
- struct in6_addr ip6;
-#endif
- int ret;
-
switch (type)
{
case SCP_ADDRESS_TYPE_IPV4:
- /* convert from char to 32bit*/
- ret = inet_pton(AF_INET, addr, &ip4);
-
- if (ret == 0)
- {
- log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
- inet_pton(AF_INET, "127.0.0.1", &ip4);
- g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4);
- return 1;
- }
-
- g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4);
- break;
- case SCP_ADDRESS_TYPE_IPV4_BIN:
g_memcpy(&(s->ipv4addr), addr, 4);
break;
#ifdef IN6ADDR_ANY_INIT
case SCP_ADDRESS_TYPE_IPV6:
- /* convert from char to 128bit*/
- ret = inet_pton(AF_INET6, addr, &ip6);
-
- if (ret == 0)
- {
- log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
- inet_pton(AF_INET, "::1", &ip6);
- g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16);
- return 1;
- }
-
- g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16);
- break;
- case SCP_ADDRESS_TYPE_IPV6_BIN:
g_memcpy(s->ipv6addr, addr, 16);
break;
#endif
@@ -449,6 +416,21 @@ scp_session_set_addr(struct SCP_SESSION *s, int type, void *addr)
}
/*******************************************************************/
+int
+scp_session_set_guid(struct SCP_SESSION *s, const tui8 *guid)
+{
+ if (0 == guid)
+ {
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_guid: null guid", __LINE__);
+ return 1;
+ }
+
+ g_memcpy(s->guid, guid, 16);
+
+ return 0;
+}
+
+/*******************************************************************/
void
scp_session_destroy(struct SCP_SESSION *s)
{
diff --git a/sesman/libscp/libscp_session.h b/sesman/libscp/libscp_session.h
index b545af9e..9b92d3dd 100644
--- a/sesman/libscp/libscp_session.h
+++ b/sesman/libscp/libscp_session.h
@@ -59,37 +59,40 @@ int
scp_session_set_rsr(struct SCP_SESSION* s, tui8 rsr);
int
-scp_session_set_locale(struct SCP_SESSION* s, char* str);
+scp_session_set_locale(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_username(struct SCP_SESSION* s, char* str);
+scp_session_set_username(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_password(struct SCP_SESSION* s, char* str);
+scp_session_set_password(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_domain(struct SCP_SESSION* s, char* str);
+scp_session_set_domain(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_program(struct SCP_SESSION* s, char* str);
+scp_session_set_program(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_directory(struct SCP_SESSION* s, char* str);
+scp_session_set_directory(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_client_ip(struct SCP_SESSION* s, char* str);
+scp_session_set_client_ip(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_hostname(struct SCP_SESSION* s, char* str);
+scp_session_set_hostname(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_addr(struct SCP_SESSION* s, int type, void* addr);
+scp_session_set_addr(struct SCP_SESSION* s, int type, const void* addr);
int
scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display);
int
-scp_session_set_errstr(struct SCP_SESSION* s, char* str);
+scp_session_set_errstr(struct SCP_SESSION* s, const char *str);
+
+int
+scp_session_set_guid(struct SCP_SESSION *s, const tui8 *guid);
/**
*
diff --git a/sesman/libscp/libscp_tcp.c b/sesman/libscp/libscp_tcp.c
index 30e8006c..d92597f4 100644
--- a/sesman/libscp/libscp_tcp.c
+++ b/sesman/libscp/libscp_tcp.c
@@ -19,7 +19,7 @@
/**
*
* @file tcp.c
- * @brief Tcp stream funcions
+ * @brief Tcp stream functions
* @author Jay Sorg, Simone Fedele
*
*/
diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h
index de851867..8cb9166c 100644
--- a/sesman/libscp/libscp_types.h
+++ b/sesman/libscp/libscp_types.h
@@ -51,10 +51,6 @@
#define SCP_ADDRESS_TYPE_IPV4 0x00
#define SCP_ADDRESS_TYPE_IPV6 0x01
-/* used in scp_session_set_addr() */
-#define SCP_ADDRESS_TYPE_IPV4_BIN 0x80
-#define SCP_ADDRESS_TYPE_IPV6_BIN 0x81
-
#define SCP_COMMAND_SET_DEFAULT 0x0000
#define SCP_COMMAND_SET_MANAGE 0x0001
#define SCP_COMMAND_SET_RSR 0x0002
@@ -92,6 +88,7 @@ struct SCP_SESSION
char* program;
char* directory;
char* client_ip;
+ tui8 guid[16];
};
struct SCP_DISCONNECTED_SESSION
diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c
index 8cf1340b..93f9e072 100644
--- a/sesman/libscp/libscp_v0.c
+++ b/sesman/libscp/libscp_v0.c
@@ -252,7 +252,14 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
scp_session_set_height(session, sz);
/* bpp */
in_uint16_be(c->in_s, sz);
- scp_session_set_bpp(session, (tui8)sz);
+ if (0 != scp_session_set_bpp(session, (tui8)sz))
+ {
+ scp_session_destroy(session);
+ log_message(LOG_LEVEL_WARNING,
+ "[v0:%d] connection aborted: unsupported bpp: %d",
+ __LINE__, (tui8)sz);
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
if (s_check_rem(c->in_s, 2))
{
@@ -357,13 +364,20 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
/******************************************************************************/
enum SCP_SERVER_STATES_E
-scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d)
+scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d, const tui8 *guid)
{
+ int msg_size;
+
+ msg_size = guid == 0 ? 14 : 14 + 16;
out_uint32_be(c->out_s, 0); /* version */
- out_uint32_be(c->out_s, 14); /* size */
+ out_uint32_be(c->out_s, msg_size); /* size */
out_uint16_be(c->out_s, 3); /* cmd */
out_uint16_be(c->out_s, 1); /* data */
out_uint16_be(c->out_s, d); /* data */
+ if (msg_size > 14)
+ {
+ out_uint8a(c->out_s, guid, 16);
+ }
s_mark_end(c->out_s);
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
diff --git a/sesman/libscp/libscp_v0.h b/sesman/libscp/libscp_v0.h
index 16e49e05..21fc16cd 100644
--- a/sesman/libscp/libscp_v0.h
+++ b/sesman/libscp/libscp_v0.h
@@ -61,7 +61,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk);
*
*/
enum SCP_SERVER_STATES_E
-scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d);
+scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d, const tui8 *guid);
/**
*
diff --git a/sesman/libscp/libscp_v1c.c b/sesman/libscp/libscp_v1c.c
index 7d1b9db8..7bc9a1d3 100644
--- a/sesman/libscp/libscp_v1c.c
+++ b/sesman/libscp/libscp_v1c.c
@@ -224,7 +224,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
in_uint32_be(c->in_s, sescnt);
sestmp = sescnt;
- ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0);
+ ds = g_new(struct SCP_DISCONNECTED_SESSION, sescnt);
if (ds == 0)
{
@@ -429,7 +429,7 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
g_free(s->errstr);
}
- s->errstr = g_malloc(dim + 1, 0);
+ s->errstr = g_new(char, dim + 1);
if (s->errstr == 0)
{
@@ -450,7 +450,7 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
g_free(s->errstr);
}
- s->errstr = g_malloc(dim + 1, 0);
+ s->errstr = g_new(char, dim + 1);
if (s->errstr == 0)
{
@@ -471,7 +471,7 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
g_free(s->errstr);
}
- s->errstr = g_malloc(dim + 1, 0);
+ s->errstr = g_new(char, dim + 1);
if (s->errstr == 0)
{
diff --git a/sesman/libscp/libscp_v1c_mng.c b/sesman/libscp/libscp_v1c_mng.c
index 59762e36..d9b43b98 100644
--- a/sesman/libscp/libscp_v1c_mng.c
+++ b/sesman/libscp/libscp_v1c_mng.c
@@ -199,7 +199,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
return SCP_CLIENT_STATE_LIST_OK;
}
- ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0);
+ ds = g_new(struct SCP_DISCONNECTED_SESSION, sescnt);
if (ds == 0)
{
diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c
index 69997ab2..a03fea38 100644
--- a/sesman/libscp/libscp_v1s.c
+++ b/sesman/libscp/libscp_v1s.c
@@ -131,7 +131,14 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
in_uint16_be(c->in_s, cmd);
scp_session_set_height(session, cmd);
in_uint8(c->in_s, sz);
- scp_session_set_bpp(session, sz);
+ if (0 != scp_session_set_bpp(session, sz))
+ {
+ scp_session_destroy(session);
+ log_message(LOG_LEVEL_WARNING,
+ "[v1s:%d] connection aborted: unsupported bpp: %d",
+ __LINE__, sz);
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
in_uint8(c->in_s, sz);
scp_session_set_rsr(session, sz);
in_uint8a(c->in_s, buf, 17);
@@ -143,12 +150,12 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
if (sz == SCP_ADDRESS_TYPE_IPV4)
{
in_uint32_be(c->in_s, size);
- scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &size);
+ scp_session_set_addr(session, sz, &size);
}
else if (sz == SCP_ADDRESS_TYPE_IPV6)
{
in_uint8a(c->in_s, buf, 16);
- scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf);
+ scp_session_set_addr(session, sz, buf);
}
buf[256] = '\0';
@@ -195,7 +202,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
}
enum SCP_SERVER_STATES_E
-scp_v1s_deny_connection(struct SCP_CONNECTION *c, char *reason)
+scp_v1s_deny_connection(struct SCP_CONNECTION *c, const char *reason)
{
int rlen;
@@ -228,7 +235,8 @@ scp_v1s_deny_connection(struct SCP_CONNECTION *c, char *reason)
}
enum SCP_SERVER_STATES_E
-scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, char *reason)
+scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
+ const char *reason)
{
tui8 sz;
tui32 version;
@@ -322,7 +330,6 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, char *
if (0 != scp_session_set_username(s, buf))
{
- scp_session_destroy(s);
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -334,7 +341,6 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, char *
if (0 != scp_session_set_password(s, buf))
{
- scp_session_destroy(s);
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -385,7 +391,7 @@ scp_v1s_connect_new_session(struct SCP_CONNECTION *c, SCP_DISPLAY d)
/* 032 */
enum SCP_SERVER_STATES_E
-scp_v1s_connection_error(struct SCP_CONNECTION *c, char *error)
+scp_v1s_connection_error(struct SCP_CONNECTION *c, const char *error)
{
tui16 len;
@@ -435,8 +441,11 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
}
/* then we wait for client ack */
-#warning maybe this message could say if the session should be resized on
-#warning server side or client side
+
+ /*
+ * Maybe this message could say if the session should be resized on
+ * server side or client side.
+ */
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
@@ -637,7 +646,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
/* if we got here, the requested sid wasn't one from the list we sent */
/* we should kill the connection */
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__);
- return SCP_CLIENT_STATE_INTERNAL_ERR;
+ return SCP_SERVER_STATE_INTERNAL_ERR;
}
else if (cmd == 44)
{
diff --git a/sesman/libscp/libscp_v1s.h b/sesman/libscp/libscp_v1s.h
index 5e3ec980..69e64038 100644
--- a/sesman/libscp/libscp_v1s.h
+++ b/sesman/libscp/libscp_v1s.h
@@ -38,7 +38,7 @@
* @param skipVchk if set to !0 skips the version control (to be used after
* scp_vXs_accept() )
*
- * this function places in *s the address of a newely allocated SCP_SESSION structure
+ * this function places in *s the address of a newly allocated SCP_SESSION structure
* that should be free()d
*/
enum SCP_SERVER_STATES_E
@@ -48,15 +48,16 @@ scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk);
*
* @brief denies connection to sesman
* @param c connection descriptor
- * @param reason pointer to a string containinge the reason for denying connection
+ * @param reason pointer to a string containing the reason for denying connection
*
*/
/* 002 */
enum SCP_SERVER_STATES_E
-scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason);
+scp_v1s_deny_connection(struct SCP_CONNECTION* c, const char *reason);
enum SCP_SERVER_STATES_E
-scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason);
+scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s,
+ const char *reason);
/* 020 */
enum SCP_SERVER_STATES_E
@@ -72,7 +73,7 @@ scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d);
/* 032 */
enum SCP_SERVER_STATES_E
-scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error);
+scp_v1s_connection_error(struct SCP_CONNECTION* c, const char *error);
/* 040 */
enum SCP_SERVER_STATES_E
diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c
index 24553429..d8c5290d 100644
--- a/sesman/libscp/libscp_v1s_mng.c
+++ b/sesman/libscp/libscp_v1s_mng.c
@@ -90,12 +90,12 @@ scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s)
if (sz == SCP_ADDRESS_TYPE_IPV4)
{
in_uint32_be(c->in_s, ipaddr);
- scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &ipaddr);
+ scp_session_set_addr(session, sz, &ipaddr);
}
else if (sz == SCP_ADDRESS_TYPE_IPV6)
{
in_uint8a(c->in_s, buf, 16);
- scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf);
+ scp_session_set_addr(session, sz, buf);
}
/* reading hostname */
@@ -138,7 +138,7 @@ scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
/* 003 */
enum SCP_SERVER_STATES_E
-scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, char *reason)
+scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, const char *reason)
{
int rlen;
diff --git a/sesman/libscp/libscp_v1s_mng.h b/sesman/libscp/libscp_v1s_mng.h
index 72df9fa6..437a06d2 100644
--- a/sesman/libscp/libscp_v1s_mng.h
+++ b/sesman/libscp/libscp_v1s_mng.h
@@ -36,7 +36,7 @@
* @param c connection descriptor
* @param s pointer to session descriptor pointer
*
- * this function places in *s the address of a newely allocated SCP_SESSION structure
+ * this function places in *s the address of a newly allocated SCP_SESSION structure
* that should be free()d
*/
enum SCP_SERVER_STATES_E
@@ -56,12 +56,12 @@ scp_v1s_mng_allow_connection(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
*
* @brief denies connection to sesman
* @param c connection descriptor
- * @param reason pointer to a string containinge the reason for denying connection
+ * @param reason pointer to a string containing the reason for denying connection
*
*/
/* 003 */
enum SCP_SERVER_STATES_E
-scp_v1s_mng_deny_connection(struct SCP_CONNECTION* c, char* reason);
+scp_v1s_mng_deny_connection(struct SCP_CONNECTION* c, const char *reason);
/**
*
diff --git a/sesman/libscp/libscp_vX.h b/sesman/libscp/libscp_vX.h
index a68a9ede..ef0a8290 100644
--- a/sesman/libscp/libscp_vX.h
+++ b/sesman/libscp/libscp_vX.h
@@ -38,7 +38,7 @@
* @brief version neutral server accept function
* @param c connection descriptor
* @param s session descriptor pointer address.
- * it will return a newely allocated descriptor.
+ * it will return a newly allocated descriptor.
* It this memory needs to be g_free()d
*
*/
diff --git a/sesman/lock.c b/sesman/lock.c
deleted file mode 100644
index 6337a541..00000000
--- a/sesman/lock.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * xrdp: A Remote Desktop Protocol server.
- *
- * Copyright (C) Jay Sorg 2004-2013
- *
- * 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.
- *
- * session manager
- * linux only
- */
-
-#include "sesman.h"
-
-extern struct config_sesman *g_cfg; /* in sesman.c */
-
-static tbus g_sync_mutex = 0;
-static tbus g_lock_chain = 0;
-static tbus g_sync_sem = 0;
-static tbus g_lock_socket = 0;
-
-/******************************************************************************/
-void APP_CC
-lock_init(void)
-{
- g_sync_mutex = tc_mutex_create();
- g_lock_chain = tc_mutex_create();
- g_sync_sem = tc_sem_create(0);
- g_lock_socket = tc_sem_create(1);
-}
-
-/******************************************************************************/
-void APP_CC
-lock_deinit(void)
-{
- tc_mutex_delete(g_sync_mutex);
- tc_mutex_delete(g_lock_chain);
- tc_sem_delete(g_sync_sem);
- tc_sem_delete(g_lock_socket);
-}
-
-/******************************************************************************/
-void APP_CC
-lock_chain_acquire(void)
-{
- /* lock the chain */
- LOG_DBG("lock_chain_acquire()");
- tc_mutex_lock(g_lock_chain);
-}
-
-/******************************************************************************/
-void APP_CC
-lock_chain_release(void)
-{
- /* unlock the chain */
- LOG_DBG("lock_chain_release()");
- tc_mutex_unlock(g_lock_chain);
-}
-
-/******************************************************************************/
-void APP_CC
-lock_socket_acquire(void)
-{
- /* lock socket variable */
- LOG_DBG("lock_socket_acquire()");
- tc_sem_dec(g_lock_socket);
-}
-
-/******************************************************************************/
-void APP_CC
-lock_socket_release(void)
-{
- /* unlock socket variable */
- LOG_DBG("lock_socket_release()");
- tc_sem_inc(g_lock_socket);
-}
-
-/******************************************************************************/
-void APP_CC
-lock_sync_acquire(void)
-{
- /* lock sync variable */
- LOG_DBG("lock_sync_acquire()");
- tc_mutex_lock(g_sync_mutex);
-}
-
-/******************************************************************************/
-void APP_CC
-lock_sync_release(void)
-{
- /* unlock socket variable */
- LOG_DBG("lock_sync_release()");
- tc_mutex_unlock(g_sync_mutex);
-}
-
-/******************************************************************************/
-void APP_CC
-lock_sync_sem_acquire(void)
-{
- /* dec sem */
- LOG_DBG("lock_sync_sem_acquire()");
- tc_sem_dec(g_sync_sem);
-}
-
-/******************************************************************************/
-void APP_CC
-lock_sync_sem_release(void)
-{
- /* inc sem */
- LOG_DBG("lock_sync_sem_release()");
- tc_sem_inc(g_sync_sem);
-}
diff --git a/sesman/lock.h b/sesman/lock.h
deleted file mode 100644
index 1fd968ef..00000000
--- a/sesman/lock.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * xrdp: A Remote Desktop Protocol server.
- *
- * Copyright (C) Jay Sorg 2004-2013
- *
- * 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 LOCK_H
-#define LOCK_H
-
-#include "sesman.h"
-
-/**
- *
- * @brief initializes all the locks
- *
- */
-void APP_CC
-lock_init(void);
-
-/**
- *
- * @brief cleanup all the locks
- *
- */
-void APP_CC
-lock_deinit(void);
-
-/**
- *
- * @brief acquires the lock for the session chain
- *
- */
-void APP_CC
-lock_chain_acquire(void);
-
-/**
- *
- * @brief releases the session chain lock
- *
- */
-void APP_CC
-lock_chain_release(void);
-
-/**
- *
- * @brief request the socket lock
- *
- */
-void APP_CC
-lock_socket_acquire(void);
-
-/**
- *
- * @brief releases the socket lock
- *
- */
-void APP_CC
-lock_socket_release(void);
-
-/**
- *
- * @brief request the main sync lock
- *
- */
-void APP_CC
-lock_sync_acquire(void);
-
-/**
- *
- * @brief releases the main sync lock
- *
- */
-void APP_CC
-lock_sync_release(void);
-
-/**
- *
- * @brief request the sync sem lock
- *
- */
-void APP_CC
-lock_sync_sem_acquire(void);
-
-/**
- *
- * @brief releases the sync sem lock
- *
- */
-void APP_CC
-lock_sync_sem_release(void);
-
-#endif
diff --git a/sesman/scp.c b/sesman/scp.c
index 076d57b2..d81de0ab 100644
--- a/sesman/scp.c
+++ b/sesman/scp.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,6 @@
#include "sesman.h"
-extern int g_thread_sck; /* in thread.c */
extern struct config_sesman *g_cfg; /* in sesman.c */
/******************************************************************************/
@@ -37,16 +36,11 @@ void *DEFAULT_CC
scp_process_start(void *sck)
{
struct SCP_CONNECTION scon;
- struct SCP_SESSION *sdata;
+ struct SCP_SESSION *sdata = NULL;
- /* making a local copy of the socket (it's on the stack) */
- /* probably this is just paranoia */
- scon.in_sck = g_thread_sck;
+ scon.in_sck = (int)(tintptr)sck;
LOG_DBG("started scp thread on socket %d", scon.in_sck);
- /* unlocking g_thread_sck */
- lock_socket_release();
-
make_stream(scon.in_s);
make_stream(scon.out_s);
@@ -60,12 +54,12 @@ scp_process_start(void *sck)
if (sdata->version == 0)
{
/* starts processing an scp v0 connection */
- LOG_DBG("accept ok, go on with scp v0\n", 0);
+ LOG_DBG("accept ok, go on with scp v0", 0);
scp_v0_process(&scon, sdata);
}
else
{
- LOG_DBG("accept ok, go on with scp v1\n", 0);
+ LOG_DBG("accept ok, go on with scp v1", 0);
/*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/
scp_v1_process(&scon, sdata);
}
@@ -95,10 +89,16 @@ scp_process_start(void *sck)
break;
default:
log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
+ break;
}
- g_tcp_close(scon.in_sck);
free_stream(scon.in_s);
free_stream(scon.out_s);
+
+ if (sdata)
+ {
+ scp_session_destroy(sdata);
+ }
+
return 0;
}
diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c
index ce528d46..81ecc3a6 100644
--- a/sesman/scp_v0.c
+++ b/sesman/scp_v0.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,9 +35,9 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
int display = 0;
tbus data;
struct session_item *s_item;
- int errorcode = 0 ;
+ int errorcode = 0;
- data = auth_userpass(s->username, s->password,&errorcode);
+ data = auth_userpass(s->username, s->password, &errorcode);
if (s->type == SCP_GW_AUTHENTICATION)
{
@@ -55,7 +55,7 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
}
else
{
- scp_v0s_replyauthentication(c, 32+3); /* all first 32 are reserved for PAM errors */
+ scp_v0s_replyauthentication(c, 32 + 3); /* all first 32 are reserved for PAM errors */
log_message(LOG_LEVEL_INFO, "Username okey but group problem for "
"user: %s", s->username);
/* g_writeln("user password ok, but group problem"); */
@@ -68,8 +68,6 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
s->username);
scp_v0s_replyauthentication(c, errorcode);
}
-
- auth_end(data);
}
else if (data)
{
@@ -79,7 +77,7 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
if (s_item != 0)
{
display = s_item->display;
-
+ g_memcpy(s->guid, s_item->guid, 16);
if (0 != s->client_ip)
{
log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, "
@@ -94,8 +92,6 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
}
session_reconnect(display, s->username);
- auth_end(data);
- /* don't set data to null here */
}
else
{
@@ -103,6 +99,11 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
if (1 == access_login_allowed(s->username))
{
+ tui8 guid[16];
+
+ g_random((char*)guid, 16);
+ scp_session_set_guid(s, guid);
+
if (0 != s->client_ip)
{
log_message(LOG_LEVEL_INFO, "++ created session (access granted): "
@@ -117,27 +118,18 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
if (SCP_SESSION_TYPE_XVNC == s->type)
{
log_message( LOG_LEVEL_INFO, "starting Xvnc session...");
- display = session_start(s->width, s->height, s->bpp, s->username,
- s->password, data, SESMAN_SESSION_TYPE_XVNC,
- s->domain, s->program, s->directory,
- s->client_ip);
+ display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s);
}
else if (SCP_SESSION_TYPE_XRDP == s->type)
{
log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
- display = session_start(s->width, s->height, s->bpp, s->username,
- s->password, data, SESMAN_SESSION_TYPE_XRDP,
- s->domain, s->program, s->directory,
- s->client_ip);
- }
+ display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s);
+ }
else if (SCP_SESSION_TYPE_XORG == s->type)
{
- /* type is SCP_SESSION_TYPE_XORG */
+ /* type is SCP_SESSION_TYPE_XORG */
log_message(LOG_LEVEL_INFO, "starting Xorg session...");
- display = session_start(s->width, s->height, s->bpp, s->username,
- s->password, data, SESMAN_SESSION_TYPE_XORG,
- s->domain, s->program, s->directory,
- s->client_ip);
+ display = session_start(data, SESMAN_SESSION_TYPE_XORG, s);
}
}
else
@@ -148,16 +140,16 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
if (display == 0)
{
- auth_end(data);
scp_v0s_deny_connection(c);
}
else
{
- scp_v0s_allow_connection(c, display);
+ scp_v0s_allow_connection(c, display, s->guid);
}
}
else
{
scp_v0s_deny_connection(c);
}
+ auth_end(data);
}
diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c
index 2324b750..36e3892f 100644
--- a/sesman/scp_v1.c
+++ b/sesman/scp_v1.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@
extern struct config_sesman *g_cfg; /* in sesman.c */
-static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f);
+static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f);
/******************************************************************************/
void DEFAULT_CC
@@ -77,7 +77,6 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
default:
/* we check the other errors */
parseCommonStates(e, "scp_v1s_list_sessions()");
- scp_session_destroy(s);
return;
//break;
}
@@ -88,7 +87,6 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
scp_v1s_deny_connection(c, "Login failed");
log_message( LOG_LEVEL_INFO,
"Login failed for user %s. Connection terminated", s->username);
- scp_session_destroy(s);
return;
}
@@ -98,7 +96,6 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
scp_v1s_deny_connection(c, "Access to Terminal Server not allowed.");
log_message(LOG_LEVEL_INFO,
"User %s not allowed on TS. Connection terminated", s->username);
- scp_session_destroy(s);
return;
}
@@ -110,7 +107,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
if (scount == 0)
{
/* no disconnected sessions - start a new one */
- log_message(LOG_LEVEL_DEBUG, "No disconnected sessions for this user"
+ log_message(LOG_LEVEL_DEBUG, "No disconnected sessions for this user "
"- we create a new one");
if (0 != s->client_ip)
@@ -125,16 +122,12 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
if (SCP_SESSION_TYPE_XVNC == s->type)
{
log_message(LOG_LEVEL_INFO, "starting Xvnc session...");
- display = session_start(s->width, s->height, s->bpp, s->username,
- s->password, data, SESMAN_SESSION_TYPE_XVNC,
- s->domain, s->program, s->directory, s->client_ip);
+ display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s);
}
else
{
log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
- display = session_start(s->width, s->height, s->bpp, s->username,
- s->password, data, SESMAN_SESSION_TYPE_XRDP,
- s->domain, s->program, s->directory, s->client_ip);
+ display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s);
}
e = scp_v1s_connect_new_session(c, display);
@@ -204,12 +197,11 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
}
/* cleanup */
- scp_session_destroy(s);
auth_end(data);
g_free(slist);
}
-static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f)
+static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
{
switch (e)
{
diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c
index 2624644a..61789cce 100644
--- a/sesman/scp_v1_mng.c
+++ b/sesman/scp_v1_mng.c
@@ -30,7 +30,7 @@
extern struct config_sesman *g_cfg; /* in sesman.c */
-static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f);
+static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f);
/******************************************************************************/
void DEFAULT_CC
@@ -50,7 +50,6 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
scp_v1s_mng_deny_connection(c, "Login failed");
log_message(LOG_LEVEL_INFO,
"[MNG] Login failed for user %s. Connection terminated", s->username);
- scp_session_destroy(s);
auth_end(data);
return;
}
@@ -61,7 +60,6 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed.");
log_message(LOG_LEVEL_INFO,
"[MNG] User %s not allowed on TS. Connection terminated", s->username);
- scp_session_destroy(s);
auth_end(data);
return;
}
@@ -105,11 +103,10 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
}
/* cleanup */
- scp_session_destroy(s);
auth_end(data);
}
-static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f)
+static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
{
switch (e)
{
diff --git a/sesman/sesman.c b/sesman/sesman.c
index 1c620210..c9666943 100644
--- a/sesman/sesman.c
+++ b/sesman/sesman.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,10 +31,7 @@ int g_pid;
unsigned char g_fixedkey[8] = { 23, 82, 107, 6, 35, 78, 88, 7 };
struct config_sesman *g_cfg; /* defined in config.h */
-tbus g_term_event = 0;
-tbus g_sync_event = 0;
-
-extern int g_thread_sck; /* in thread.c */
+tintptr g_term_event = 0;
/******************************************************************************/
/**
@@ -52,14 +49,11 @@ sesman_main_loop(void)
tbus sck_obj;
tbus robjs[8];
- /*main program loop*/
- log_message(LOG_LEVEL_INFO, "listening...");
-
g_sck = g_tcp_socket();
if (g_sck < 0)
{
log_message(LOG_LEVEL_ERROR, "error opening socket, g_tcp_socket() failed...");
- return 1;
+ return;
}
g_tcp_set_non_blocking(g_sck);
@@ -71,6 +65,8 @@ sesman_main_loop(void)
if (error == 0)
{
+ log_message(LOG_LEVEL_INFO, "listening to port %s on %s",
+ g_cfg->listen_port, g_cfg->listen_address);
sck_obj = g_create_wait_obj_from_socket(g_sck, 0);
cont = 1;
@@ -80,7 +76,6 @@ sesman_main_loop(void)
robjs_count = 0;
robjs[robjs_count++] = sck_obj;
robjs[robjs_count++] = g_term_event;
- robjs[robjs_count++] = g_sync_event;
/* wait */
if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0)
@@ -94,12 +89,6 @@ sesman_main_loop(void)
break;
}
- if (g_is_wait_obj_set(g_sync_event)) /* sync */
- {
- g_reset_wait_obj(g_sync_event);
- session_sync_start();
- }
-
if (g_is_wait_obj_set(sck_obj)) /* incoming connection */
{
in_sck = g_tcp_accept(g_sck);
@@ -118,8 +107,8 @@ sesman_main_loop(void)
{
/* we've got a connection, so we pass it to scp code */
LOG_DBG("new connection");
- thread_scp_start(in_sck);
- /* todo, do we have to wait here ? */
+ scp_process_start((void*)(tintptr)in_sck);
+ g_sck_close(in_sck);
}
}
}
@@ -138,9 +127,7 @@ sesman_main_loop(void)
"port '%s': %d (%s)", g_cfg->listen_port,
g_get_errno(), g_get_strerror());
}
-
- if (g_sck != -1)
- g_tcp_close(g_sck);
+ g_tcp_close(g_sck);
}
/******************************************************************************/
@@ -148,7 +135,8 @@ int DEFAULT_CC
main(int argc, char **argv)
{
int fd;
- enum logReturns error;
+ enum logReturns log_error;
+ int error;
int daemon = 1;
int pid;
char pid_s[32];
@@ -171,7 +159,7 @@ main(int argc, char **argv)
(0 == g_strcasecmp(argv[1], "-ns"))))
{
/* starts sesman not daemonized */
- g_printf("starting sesman in foregroud...\n");
+ g_printf("starting sesman in foreground...\n");
daemon = 0;
}
else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--help")) ||
@@ -252,14 +240,14 @@ main(int argc, char **argv)
{
g_printf("sesman is already running.\n");
g_printf("if it's not running, try removing ");
- g_printf(pid_file);
+ g_printf("%s", pid_file);
g_printf("\n");
g_deinit();
g_exit(1);
}
/* reading config */
- g_cfg = g_malloc(sizeof(struct config_sesman), 1);
+ g_cfg = g_new0(struct config_sesman, 1);
if (0 == g_cfg)
{
@@ -279,11 +267,11 @@ main(int argc, char **argv)
g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
/* starting logging subsystem */
- error = log_start(cfg_file, "XRDP-sesman");
+ log_error = log_start(cfg_file, "xrdp-sesman");
- if (error != LOG_STARTUP_OK)
+ if (log_error != LOG_STARTUP_OK)
{
- switch (error)
+ switch (log_error)
{
case LOG_ERROR_MALLOC:
g_writeln("error on malloc. cannot start logging. quitting.");
@@ -292,6 +280,9 @@ main(int argc, char **argv)
g_writeln("error opening log file [%s]. quitting.",
getLogFile(text, 255));
break;
+ default:
+ g_writeln("error");
+ break;
}
g_deinit();
@@ -329,9 +320,6 @@ main(int argc, char **argv)
}
}
- /* initializing locks */
- lock_init();
-
/* signal handling */
g_pid = g_getpid();
/* old style signal handling is now managed synchronously by a
@@ -342,7 +330,6 @@ main(int argc, char **argv)
#if 1
g_signal_hang_up(sig_sesman_reload_cfg); /* SIGHUP */
g_signal_user_interrupt(sig_sesman_shutdown); /* SIGINT */
- g_signal_kill(sig_sesman_shutdown); /* SIGKILL */
g_signal_terminate(sig_sesman_shutdown); /* SIGTERM */
g_signal_child_stop(sig_sesman_session_end); /* SIGCHLD */
#endif
@@ -371,8 +358,8 @@ main(int argc, char **argv)
}
/* start program main loop */
- log_message(LOG_LEVEL_ALWAYS,
- "starting sesman with pid %d", g_pid);
+ log_message(LOG_LEVEL_INFO,
+ "starting xrdp-sesman with pid %d", g_pid);
/* make sure the /tmp/.X11-unix directory exist */
if (!g_directory_exist("/tmp/.X11-unix"))
@@ -387,8 +374,6 @@ main(int argc, char **argv)
g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_term", g_pid);
g_term_event = g_create_wait_obj(text);
- g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_sync", g_pid);
- g_sync_event = g_create_wait_obj(text);
sesman_main_loop();
@@ -399,7 +384,6 @@ main(int argc, char **argv)
}
g_delete_wait_obj(g_term_event);
- g_delete_wait_obj(g_sync_event);
if (!daemon)
{
diff --git a/sesman/sesman.h b/sesman/sesman.h
index 71688987..09b781bc 100644
--- a/sesman/sesman.h
+++ b/sesman/sesman.h
@@ -30,7 +30,6 @@
#if defined(HAVE_CONFIG_H)
#include "config_ac.h"
#endif
-#include "d3des.h"
#include "arch.h"
#include "parse.h"
#include "os_calls.h"
@@ -39,14 +38,10 @@
#include "env.h"
#include "auth.h"
#include "config.h"
-//#include "tcp.h"
#include "sig.h"
#include "session.h"
#include "access.h"
#include "scp.h"
-#include "thread.h"
-#include "lock.h"
-#include "thread_calls.h"
#include "libscp.h"
diff --git a/sesman/sesman.ini b/sesman/sesman.ini
index a58af383..674665e9 100644
--- a/sesman/sesman.ini
+++ b/sesman/sesman.ini
@@ -1,59 +1,58 @@
[Globals]
ListenAddress=127.0.0.1
ListenPort=3350
-EnableUserWindowManager=1
+EnableUserWindowManager=true
UserWindowManager=startwm.sh
DefaultWindowManager=startwm.sh
[Security]
-AllowRootLogin=1
+AllowRootLogin=true
MaxLoginRetry=4
TerminalServerUsers=tsusers
TerminalServerAdmins=tsadmins
-# When AlwaysGroupCheck = false access will be permitted
-# if the group TerminalServerUsers is not defined.
-AlwaysGroupCheck = false
+; When AlwaysGroupCheck=false access will be permitted
+; if the group TerminalServerUsers is not defined.
+AlwaysGroupCheck=false
[Sessions]
-
-## X11DisplayOffset - x11 display number offset
-# Type: integer
-# Default: 10
+;; X11DisplayOffset - x11 display number offset
+; Type: integer
+; Default: 10
X11DisplayOffset=10
-## MaxSessions - maximum number of connections to an xrdp server
-# Type: integer
-# Default: 0
+;; MaxSessions - maximum number of connections to an xrdp server
+; Type: integer
+; Default: 0
MaxSessions=50
-## KillDisconnected - kill disconnected sessions
-# Type: integer
-# Default: 0
-# if 1, true, or yes, kill session after 60 seconds
-KillDisconnected=0
+;; KillDisconnected - kill disconnected sessions
+; Type: boolean
+; Default: false
+; if 1, true, or yes, kill session after 60 seconds
+KillDisconnected=false
-## IdleTimeLimit - when to disconnect idle sessions
-# Type: integer
-# Default: 0
-# if not zero, the seconds without mouse or keyboard input before disconnect
-# not complete yet
+;; IdleTimeLimit - when to disconnect idle sessions
+; Type: integer
+; Default: 0
+; if not zero, the seconds without mouse or keyboard input before disconnect
+; not complete yet
IdleTimeLimit=0
-## DisconnectedTimeLimit - when to kill idle sessions
-# Type: integer
-# Default: 0
-# if not zero, the seconds before a disconnected session is killed
-# min 60 seconds
+;; DisconnectedTimeLimit - when to kill idle sessions
+; Type: integer
+; Default: 0
+; if not zero, the seconds before a disconnected session is killed
+; min 60 seconds
DisconnectedTimeLimit=0
-## Policy - session allocation policy
-# Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ]
-# Default: Xrdp:<User,BitPerPixel> and Xvnc:<User,BitPerPixel,DisplaySize>
-# "UBD" session per <User,BitPerPixel,DisplaySize>
-# "UBI" session per <User,BitPerPixel,IPAddr>
-# "UBC" session per <User,BitPerPixel,Connection>
-# "UBDI" session per <User,BitPerPixel,DisplaySize,IPAddr>
-# "UBDC" session per <User,BitPerPixel,DisplaySize,Connection>
+;; Policy - session allocation policy
+; Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ]
+; Default: Xrdp:<User,BitPerPixel> and Xvnc:<User,BitPerPixel,DisplaySize>
+; "UBD" session per <User,BitPerPixel,DisplaySize>
+; "UBI" session per <User,BitPerPixel,IPAddr>
+; "UBC" session per <User,BitPerPixel,Connection>
+; "UBDI" session per <User,BitPerPixel,DisplaySize,IPAddr>
+; "UBDC" session per <User,BitPerPixel,DisplaySize,Connection>
Policy=Default
[Logging]
@@ -63,33 +62,33 @@ EnableSyslog=1
SyslogLevel=DEBUG
[X11rdp]
-param1=-bs
-param2=-ac
-param3=-nolisten
-param4=tcp
-param5=-uds
+param=X11rdp
+param=-bs
+param=-nolisten
+param=tcp
+param=-uds
[Xvnc]
-param1=-bs
-param2=-ac
-param3=-nolisten
-param4=tcp
-param5=-localhost
-param6=-dpi
-param7=96
+param=Xvnc
+param=-bs
+param=-nolisten
+param=tcp
+param=-localhost
+param=-dpi
+param=96
[Xorg]
-param1=-config
-param2=xrdp/xorg.conf
-param3=-logfile
-param4=/dev/null
-param5=-noreset
-param6=-ac
-param7=-nolisten
-param8=tcp
+param=Xorg
+param=-config
+param=xrdp/xorg.conf
+param=-noreset
+param=-nolisten
+param=tcp
+param=-logfile
+param=.xorgxrdp.%s.log
[Chansrv]
-# drive redirection, defaults to xrdp_client if not set
+; drive redirection, defaults to xrdp_client if not set
FuseMountName=thinclient_drives
[SessionVariables]
diff --git a/sesman/session.c b/sesman/session.c
index 4ea48d35..4e51867f 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -1,7 +1,12 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2015
+ *
+ * BSD process grouping by:
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland.
+ * Copyright (c) 2000-2001 Markus Friedl.
+ * Copyright (c) 2011-2015 Koichiro Iwao, Kyushu Institute of Technology.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,33 +29,30 @@
*
*/
+#if defined(HAVE_CONFIG_H)
+#include "config_ac.h"
+#endif
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
#include "sesman.h"
#include "libscp_types.h"
+#include "xauth.h"
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 38
+#endif
-#include <errno.h>
-//#include <time.h>
-extern tbus g_sync_event;
extern unsigned char g_fixedkey[8];
extern struct config_sesman *g_cfg; /* in sesman.c */
extern int g_sck; /* in sesman.c */
-extern int g_thread_sck; /* in thread.c */
struct session_chain *g_sessions;
int g_session_count;
-static int g_sync_width;
-static int g_sync_height;
-static int g_sync_bpp;
-static char *g_sync_username;
-static char *g_sync_password;
-static char *g_sync_domain;
-static char *g_sync_program;
-static char *g_sync_directory;
-static char *g_sync_client_ip;
-static tbus g_sync_data;
-static tui8 g_sync_type;
-static int g_sync_result;
-static int g_sync_cmd;
+extern tbus g_term_event; /* in sesman.c */
/**
* Creates a string consisting of all parameters that is hosted in the param list
@@ -63,7 +65,6 @@ char *APP_CC
dumpItemsToString(struct list *self, char *outstr, int len)
{
int index;
- tbus item;
int totalLen = 0;
g_memset(outstr, 0, len);
@@ -90,14 +91,12 @@ dumpItemsToString(struct list *self, char *outstr, int len)
/******************************************************************************/
struct session_item *DEFAULT_CC
-session_get_bydata(char *name, int width, int height, int bpp, int type, char *client_ip)
+session_get_bydata(const char *name, int width, int height, int bpp, int type,
+ const char *client_ip)
{
struct session_chain *tmp;
enum SESMAN_CFG_SESS_POLICY policy = g_cfg->sess.policy;
- /*THREAD-FIX require chain lock */
- lock_chain_acquire();
-
tmp = g_sessions;
/* convert from SCP_SESSION_TYPE namespace to SESMAN_SESSION_TYPE namespace */
@@ -105,7 +104,9 @@ session_get_bydata(char *name, int width, int height, int bpp, int type, char *c
{
case SCP_SESSION_TYPE_XVNC: /* 0 */
type = SESMAN_SESSION_TYPE_XVNC; /* 2 */
- policy |= SESMAN_CFG_SESS_POLICY_D; /* Xvnc cannot resize */
+ /* Xvnc cannot resize */
+ policy = (enum SESMAN_CFG_SESS_POLICY)
+ (policy | SESMAN_CFG_SESS_POLICY_D);
break;
case SCP_SESSION_TYPE_XRDP: /* 1 */
type = SESMAN_SESSION_TYPE_XRDP; /* 1 */
@@ -114,7 +115,6 @@ session_get_bydata(char *name, int width, int height, int bpp, int type, char *c
type = SESMAN_SESSION_TYPE_XORG;
break;
default:
- lock_chain_release();
return 0;
}
@@ -136,27 +136,9 @@ session_get_bydata(char *name, int width, int height, int bpp, int type, char *c
tmp->item->client_ip);
#endif
- if (type == SESMAN_SESSION_TYPE_XRDP)
- {
- /* only name and bpp need to match for X11rdp, it can resize */
- if (g_strncmp(name, tmp->item->name, 255) == 0 &&
- (!(policy & SESMAN_CFG_SESS_POLICY_D) ||
- (tmp->item->width == width && tmp->item->height == height)) &&
- (!(policy & SESMAN_CFG_SESS_POLICY_I) ||
- (g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) &&
- (!(policy & SESMAN_CFG_SESS_POLICY_C) ||
- (g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) &&
- tmp->item->bpp == bpp &&
- tmp->item->type == type)
- {
- /*THREAD-FIX release chain lock */
- lock_chain_release();
- return tmp->item;
- }
- }
-
if (g_strncmp(name, tmp->item->name, 255) == 0 &&
- (tmp->item->width == width && tmp->item->height == height) &&
+ (!(policy & SESMAN_CFG_SESS_POLICY_D) ||
+ (tmp->item->width == width && tmp->item->height == height)) &&
(!(policy & SESMAN_CFG_SESS_POLICY_I) ||
(g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) &&
(!(policy & SESMAN_CFG_SESS_POLICY_C) ||
@@ -164,16 +146,12 @@ session_get_bydata(char *name, int width, int height, int bpp, int type, char *c
tmp->item->bpp == bpp &&
tmp->item->type == type)
{
- /*THREAD-FIX release chain lock */
- lock_chain_release();
return tmp->item;
}
tmp = tmp->next;
}
- /*THREAD-FIX release chain lock */
- lock_chain_release();
return 0;
}
@@ -277,7 +255,6 @@ x_server_running(int display)
{
char text[256];
int x_running;
- int sck;
g_sprintf(text, "/tmp/.X11-unix/X%d", display);
x_running = g_file_exist(text);
@@ -319,13 +296,16 @@ session_start_sessvc(int xpid, int wmpid, long data, char *username, int display
/* building parameters */
g_snprintf(exe_path, 261, "%s/xrdp-sessvc", XRDP_SBIN_PATH);
- list_add_item(sessvc_params, (long)g_strdup(exe_path));
- list_add_item(sessvc_params, (long)g_strdup(xpid_str));
- list_add_item(sessvc_params, (long)g_strdup(wmpid_str));
+ list_add_item(sessvc_params, (tintptr)g_strdup(exe_path));
+ list_add_item(sessvc_params, (tintptr)g_strdup(xpid_str));
+ list_add_item(sessvc_params, (tintptr)g_strdup(wmpid_str));
list_add_item(sessvc_params, 0); /* mandatory */
- env_set_user(username, 0, display,
- g_cfg->session_variables1, g_cfg->session_variables2);
+ env_set_user(username,
+ 0,
+ display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
/* executing sessvc */
g_execvp(exe_path, ((char **)sessvc_params->items));
@@ -339,7 +319,7 @@ session_start_sessvc(int xpid, int wmpid, long data, char *username, int display
/* no problem calling strerror for thread safety: other threads
are blocked */
log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s",
- errno, g_get_strerror());
+ g_get_errno(), g_get_strerror());
log_message(LOG_LEVEL_DEBUG, "execve parameter list:");
for (i = 0; i < (sessvc_params->count); i++)
@@ -388,12 +368,11 @@ session_is_display_in_chain(int display)
/******************************************************************************/
/* called with the main thread */
static int APP_CC
-session_get_aval_display_from_chain(void)
+session_get_avail_display_from_chain(void)
{
int display;
display = g_cfg->sess.x11_display_offset;
- lock_chain_acquire();
while ((display - g_cfg->sess.x11_display_offset) <= g_cfg->sess.max_sessions)
{
@@ -401,7 +380,6 @@ session_get_aval_display_from_chain(void)
{
if (!x_server_running_check_ports(display))
{
- lock_chain_release();
return display;
}
}
@@ -409,7 +387,6 @@ session_get_aval_display_from_chain(void)
display++;
}
- lock_chain_release();
log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available");
return 0;
}
@@ -445,9 +422,7 @@ wait_for_xserver(int display)
/******************************************************************************/
/* called with the main thread */
static int APP_CC
-session_start_fork(int width, int height, int bpp, char *username,
- char *password, tbus data, tui8 type, char *domain,
- char *program, char *directory, char *client_ip)
+session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s)
{
int display = 0;
int pid = 0;
@@ -457,16 +432,17 @@ session_start_fork(int width, int height, int bpp, char *username,
int i = 0;
char geometry[32];
char depth[32];
- char screen[32];
+ char screen[32]; /* display number */
char text[256];
- char passwd_file[256];
- char *pfile;
+ char execvpparams[2048];
+ char *xserver; /* absolute/relative path to Xorg/X11rdp/Xvnc */
+ char *passwd_file;
char **pp1 = (char **)NULL;
struct session_chain *temp = (struct session_chain *)NULL;
struct list *xserver_params = (struct list *)NULL;
- time_t ltime;
struct tm stime;
- char execvpparams[2048];
+ time_t ltime;
+ char authfile[256]; /* The filename for storing xauth informations */
/* initialize (zero out) local variables: */
g_memset(&ltime, 0, sizeof(time_t));
@@ -475,13 +451,14 @@ session_start_fork(int width, int height, int bpp, char *username,
g_memset(depth, 0, sizeof(char) * 32);
g_memset(screen, 0, sizeof(char) * 32);
g_memset(text, 0, sizeof(char) * 256);
- g_memset(passwd_file, 0, sizeof(char) * 256);
+
+ passwd_file = 0;
/* check to limit concurrent sessions */
if (g_session_count >= g_cfg->sess.max_sessions)
{
log_message(LOG_LEVEL_INFO, "max concurrent session limit "
- "exceeded. login for user %s denied", username);
+ "exceeded. login for user %s denied", s->username);
return 0;
}
@@ -490,7 +467,7 @@ session_start_fork(int width, int height, int bpp, char *username,
if (temp == 0)
{
log_message(LOG_LEVEL_ERROR, "cannot create new chain "
- "element - user %s", username);
+ "element - user %s", s->username);
return 0;
}
@@ -500,11 +477,11 @@ session_start_fork(int width, int height, int bpp, char *username,
{
g_free(temp);
log_message(LOG_LEVEL_ERROR, "cannot create new session "
- "item - user %s", username);
+ "item - user %s", s->username);
return 0;
}
- display = session_get_aval_display_from_chain();
+ display = session_get_avail_display_from_chain();
if (display == 0)
{
@@ -513,53 +490,95 @@ session_start_fork(int width, int height, int bpp, char *username,
return 0;
}
- pid = g_fork();
+ pid = g_fork(); /* parent is fork from tcp accept,
+ child forks X and wm, then becomes scp */
if (pid == -1)
{
}
- else if (pid == 0) /* child sesman */
+ else if (pid == 0)
{
+ g_delete_wait_obj(g_term_event);
g_tcp_close(g_sck);
- g_tcp_close(g_thread_sck);
- g_sprintf(geometry, "%dx%d", width, height);
- g_sprintf(depth, "%d", bpp);
+ g_sprintf(geometry, "%dx%d", s->width, s->height);
+ g_sprintf(depth, "%d", s->bpp);
g_sprintf(screen, ":%d", display);
- wmpid = g_fork();
+#ifdef __FreeBSD__
+ /*
+ * FreeBSD bug
+ * ports/157282: effective login name is not set by xrdp-sesman
+ * http://www.freebsd.org/cgi/query-pr.cgi?pr=157282
+ *
+ * from:
+ * $OpenBSD: session.c,v 1.252 2010/03/07 11:57:13 dtucker Exp $
+ * with some ideas about BSD process grouping to xrdp
+ */
+ pid_t bsdsespid = g_fork();
+
+ if (bsdsespid == -1)
+ {
+ }
+ else if (bsdsespid == 0) /* BSD session leader */
+ {
+ /**
+ * Create a new session and process group since the 4.4BSD
+ * setlogin() affects the entire process group
+ */
+ if (g_setsid() < 0)
+ {
+ log_message(LOG_LEVEL_ERROR,
+ "setsid failed - pid %d", g_getpid());
+ }
+
+ if (g_setlogin(s->username) < 0)
+ {
+ log_message(LOG_LEVEL_ERROR,
+ "setlogin failed for user %s - pid %d", s->username,
+ g_getpid());
+ }
+ }
+
+ g_waitpid(bsdsespid);
+#endif
+ wmpid = g_fork(); /* parent becomes X,
+ child forks wm, and waits, todo */
if (wmpid == -1)
{
}
- else if (wmpid == 0) /* child (child sesman) xserver */
+ else if (wmpid == 0)
{
wait_for_xserver(display);
auth_start_session(data, display);
- pampid = g_fork();
+ pampid = g_fork(); /* parent waits, todo
+ child becomes wm */
if (pampid == -1)
{
}
- else if (pampid == 0) /* child: X11/client */
+ else if (pampid == 0)
{
- env_set_user(username, 0, display,
+ env_set_user(s->username,
+ 0,
+ display,
g_cfg->session_variables1,
g_cfg->session_variables2);
if (x_server_running(display))
{
auth_set_env(data);
- if (directory != 0)
+ if (s->directory != 0)
{
- if (directory[0] != 0)
+ if (s->directory[0] != 0)
{
- g_set_current_dir(directory);
+ g_set_current_dir(s->directory);
}
}
- if (program != 0)
+ if (s->program != 0)
{
- if (program[0] != 0)
+ if (s->program[0] != 0)
{
- g_execlp3(program, program, 0);
+ g_execlp3(s->program, s->program, 0);
log_message(LOG_LEVEL_ALWAYS,
"error starting program %s for user %s - pid %d",
- program, username, g_getpid());
+ s->program, s->username, g_getpid());
}
}
/* try to execute user window manager if enabled */
@@ -570,10 +589,10 @@ session_start_fork(int width, int height, int bpp, char *username,
{
g_execlp3(text, g_cfg->user_wm, 0);
log_message(LOG_LEVEL_ALWAYS, "error starting user "
- "wm for user %s - pid %d", username, g_getpid());
+ "wm for user %s - pid %d", s->username, g_getpid());
/* logging parameters */
log_message(LOG_LEVEL_DEBUG, "errno: %d, "
- "description: %s", errno, g_get_strerror());
+ "description: %s", g_get_errno(), g_get_strerror());
log_message(LOG_LEVEL_DEBUG, "execlp3 parameter "
"list:");
log_message(LOG_LEVEL_DEBUG, " argv[0] = %s",
@@ -588,10 +607,10 @@ session_start_fork(int width, int height, int bpp, char *username,
g_execlp3(text, g_cfg->default_wm, 0);
log_message(LOG_LEVEL_ALWAYS, "error starting default "
- "wm for user %s - pid %d", username, g_getpid());
+ "wm for user %s - pid %d", s->username, g_getpid());
/* logging parameters */
log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
- "%s", errno, g_get_strerror());
+ "%s", g_get_errno(), g_get_strerror());
log_message(LOG_LEVEL_DEBUG, "execlp3 parameter list:");
log_message(LOG_LEVEL_DEBUG, " argv[0] = %s",
text);
@@ -603,10 +622,10 @@ session_start_fork(int width, int height, int bpp, char *username,
/* should not get here */
log_message(LOG_LEVEL_ALWAYS, "error starting xterm "
- "for user %s - pid %d", username, g_getpid());
+ "for user %s - pid %d", s->username, g_getpid());
/* logging parameters */
log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
- "%s", errno, g_get_strerror());
+ "%s", g_get_errno(), g_get_strerror());
}
else
{
@@ -625,23 +644,32 @@ session_start_fork(int width, int height, int bpp, char *username,
g_exit(0);
}
}
- else /* parent (child sesman) */
+ else
{
- xpid = g_fork();
-
+ xpid = g_fork(); /* parent becomes scp,
+ child becomes X */
if (xpid == -1)
{
}
else if (xpid == 0) /* child */
{
- pfile = 0;
if (type == SESMAN_SESSION_TYPE_XVNC)
{
- pfile = passwd_file;
+ env_set_user(s->username,
+ &passwd_file,
+ display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
+ }
+ else
+ {
+ env_set_user(s->username,
+ 0,
+ display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
}
- env_set_user(username, pfile, display,
- g_cfg->session_variables1,
- g_cfg->session_variables2);
+
g_snprintf(text, 255, "%d", g_cfg->sess.max_idle_time);
g_setenv("XRDP_SESMAN_MAX_IDLE_TIME", text, 1);
@@ -650,17 +678,53 @@ session_start_fork(int width, int height, int bpp, char *username,
g_snprintf(text, 255, "%d", g_cfg->sess.kill_disconnected);
g_setenv("XRDP_SESMAN_KILL_DISCONNECTED", text, 1);
+ /* prepare the Xauthority stuff */
+ if (g_getenv("XAUTHORITY") != NULL)
+ {
+ g_snprintf(authfile, 255, "%s", g_getenv("XAUTHORITY"));
+ }
+ else
+ {
+ g_snprintf(authfile, 255, "%s", ".Xauthority");
+ }
+
+ /* Add the entry in XAUTHORITY file or exit if error */
+ if (add_xauth_cookie(display, authfile) != 0)
+ {
+ g_exit(1);
+ }
+
if (type == SESMAN_SESSION_TYPE_XORG)
{
+#ifdef HAVE_SYS_PRCTL_H
+ /*
+ * Make sure Xorg doesn't run setuid root. Root access is not
+ * needed. Xorg can fail when run as root and the user has no
+ * console permissions.
+ * PR_SET_NO_NEW_PRIVS requires Linux kernel 3.5 and newer.
+ */
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0)
+ {
+ log_message(LOG_LEVEL_WARNING,
+ "Failed to disable setuid on X server: %s",
+ g_get_strerror());
+ }
+#endif
+
xserver_params = list_create();
xserver_params->auto_free = 1;
+ /* get path of Xorg from config */
+ xserver = g_strdup((const char *)list_get_item(g_cfg->xorg_params, 0));
+
/* these are the must have parameters */
- list_add_item(xserver_params, (long) g_strdup("/usr/bin/Xorg"));
- list_add_item(xserver_params, (long) g_strdup(screen));
+ list_add_item(xserver_params, (tintptr) g_strdup(xserver));
+ list_add_item(xserver_params, (tintptr) g_strdup(screen));
+ list_add_item(xserver_params, (tintptr) g_strdup("-auth"));
+ list_add_item(xserver_params, (tintptr) g_strdup(authfile));
/* additional parameters from sesman.ini file */
- list_append_list_strdup(g_cfg->xorg_params, xserver_params, 0);
+ list_append_list_strdup(g_cfg->xorg_params, xserver_params, 1);
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
@@ -670,80 +734,94 @@ session_start_fork(int width, int height, int bpp, char *username,
log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
/* some args are passed via env vars */
- g_sprintf(geometry, "%d", width);
+ g_sprintf(geometry, "%d", s->width);
g_setenv("XRDP_START_WIDTH", geometry, 1);
- g_sprintf(geometry, "%d", height);
+ g_sprintf(geometry, "%d", s->height);
g_setenv("XRDP_START_HEIGHT", geometry, 1);
/* fire up Xorg */
- g_execvp("/usr/bin/Xorg", pp1);
+ g_execvp(xserver, pp1);
}
else if (type == SESMAN_SESSION_TYPE_XVNC)
{
- env_check_password_file(passwd_file, password);
+ char guid_str[64];
+ g_bytes_to_hexstr(s->guid, 16, guid_str, 64);
+ env_check_password_file(passwd_file, guid_str);
xserver_params = list_create();
xserver_params->auto_free = 1;
+ /* get path of Xvnc from config */
+ xserver = g_strdup((const char *)list_get_item(g_cfg->vnc_params, 0));
+
/* these are the must have parameters */
- list_add_item(xserver_params, (long)g_strdup("Xvnc"));
- list_add_item(xserver_params, (long)g_strdup(screen));
- list_add_item(xserver_params, (long)g_strdup("-geometry"));
- list_add_item(xserver_params, (long)g_strdup(geometry));
- list_add_item(xserver_params, (long)g_strdup("-depth"));
- list_add_item(xserver_params, (long)g_strdup(depth));
- list_add_item(xserver_params, (long)g_strdup("-rfbauth"));
- list_add_item(xserver_params, (long)g_strdup(passwd_file));
+ list_add_item(xserver_params, (tintptr)g_strdup(xserver));
+ list_add_item(xserver_params, (tintptr)g_strdup(screen));
+ list_add_item(xserver_params, (tintptr)g_strdup("-auth"));
+ list_add_item(xserver_params, (tintptr)g_strdup(authfile));
+ list_add_item(xserver_params, (tintptr)g_strdup("-geometry"));
+ list_add_item(xserver_params, (tintptr)g_strdup(geometry));
+ list_add_item(xserver_params, (tintptr)g_strdup("-depth"));
+ list_add_item(xserver_params, (tintptr)g_strdup(depth));
+ list_add_item(xserver_params, (tintptr)g_strdup("-rfbauth"));
+ list_add_item(xserver_params, (tintptr)g_strdup(passwd_file));
+
+ g_free(passwd_file);
/* additional parameters from sesman.ini file */
//config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC,
// xserver_params);
- list_append_list_strdup(g_cfg->vnc_params, xserver_params, 0);
+ list_append_list_strdup(g_cfg->vnc_params, xserver_params, 1);
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char **)xserver_params->items;
log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
- g_execvp("Xvnc", pp1);
+ g_execvp(xserver, pp1);
}
else if (type == SESMAN_SESSION_TYPE_XRDP)
{
xserver_params = list_create();
xserver_params->auto_free = 1;
+ /* get path of X11rdp from config */
+ xserver = g_strdup((const char *)list_get_item(g_cfg->rdp_params, 0));
+
/* these are the must have parameters */
- list_add_item(xserver_params, (long)g_strdup("X11rdp"));
- list_add_item(xserver_params, (long)g_strdup(screen));
- list_add_item(xserver_params, (long)g_strdup("-geometry"));
- list_add_item(xserver_params, (long)g_strdup(geometry));
- list_add_item(xserver_params, (long)g_strdup("-depth"));
- list_add_item(xserver_params, (long)g_strdup(depth));
+ list_add_item(xserver_params, (tintptr)g_strdup(xserver));
+ list_add_item(xserver_params, (tintptr)g_strdup(screen));
+ list_add_item(xserver_params, (tintptr)g_strdup("-auth"));
+ list_add_item(xserver_params, (tintptr)g_strdup(authfile));
+ list_add_item(xserver_params, (tintptr)g_strdup("-geometry"));
+ list_add_item(xserver_params, (tintptr)g_strdup(geometry));
+ list_add_item(xserver_params, (tintptr)g_strdup("-depth"));
+ list_add_item(xserver_params, (tintptr)g_strdup(depth));
/* additional parameters from sesman.ini file */
//config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP,
// xserver_params);
- list_append_list_strdup(g_cfg->rdp_params, xserver_params, 0);
+ list_append_list_strdup(g_cfg->rdp_params, xserver_params, 1);
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char **)xserver_params->items;
log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
- g_execvp("X11rdp", pp1);
+ g_execvp(xserver, pp1);
}
else
{
log_message(LOG_LEVEL_ALWAYS, "bad session type - "
- "user %s - pid %d", username, g_getpid());
+ "user %s - pid %d", s->username, g_getpid());
g_exit(1);
}
/* should not get here */
log_message(LOG_LEVEL_ALWAYS, "error starting X server "
- "- user %s - pid %d", username, g_getpid());
+ "- user %s - pid %d", s->username, g_getpid());
/* logging parameters */
log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
- "%s", errno, g_get_strerror());
+ "%s", g_get_errno(), g_get_strerror());
log_message(LOG_LEVEL_DEBUG, "execve parameter list size: "
"%d", (xserver_params)->count);
@@ -756,7 +834,7 @@ session_start_fork(int width, int height, int bpp, char *username,
list_delete(xserver_params);
g_exit(1);
}
- else /* parent (child sesman)*/
+ else
{
wait_for_xserver(display);
g_snprintf(text, 255, "%d", display);
@@ -764,25 +842,26 @@ session_start_fork(int width, int height, int bpp, char *username,
g_snprintf(text, 255, ":%d.0", display);
g_setenv("DISPLAY", text, 1);
/* new style waiting for clients */
- session_start_sessvc(xpid, wmpid, data, username, display);
+ session_start_sessvc(xpid, wmpid, data, s->username, display);
}
}
}
- else /* parent sesman process */
+ else
{
temp->item->pid = pid;
temp->item->display = display;
- temp->item->width = width;
- temp->item->height = height;
- temp->item->bpp = bpp;
+ temp->item->width = s->width;
+ temp->item->height = s->height;
+ temp->item->bpp = s->bpp;
temp->item->data = data;
- g_strncpy(temp->item->client_ip, client_ip, 255); /* store client ip data */
- g_strncpy(temp->item->name, username, 255);
+ g_strncpy(temp->item->client_ip, s->client_ip, 255); /* store client ip data */
+ g_strncpy(temp->item->name, s->username, 255);
+ g_memcpy(temp->item->guid, s->guid, 16);
ltime = g_time1();
localtime_r(&ltime, &stime);
temp->item->connect_time.year = (tui16)(stime.tm_year + 1900);
- temp->item->connect_time.month = (tui8)stime.tm_mon;
+ temp->item->connect_time.month = (tui8)(stime.tm_mon + 1);
temp->item->connect_time.day = (tui8)stime.tm_mday;
temp->item->connect_time.hour = (tui8)stime.tm_hour;
temp->item->connect_time.minute = (tui8)stime.tm_min;
@@ -792,16 +871,10 @@ session_start_fork(int width, int height, int bpp, char *username,
temp->item->type = type;
temp->item->status = SESMAN_SESSION_STATUS_ACTIVE;
- /*THREAD-FIX require chain lock */
- lock_chain_acquire();
-
temp->next = g_sessions;
g_sessions = temp;
g_session_count++;
- /*THREAD-FIX release chain lock */
- lock_chain_release();
-
return display;
}
@@ -825,8 +898,11 @@ session_reconnect_fork(int display, char *username)
}
else if (pid == 0)
{
- env_set_user(username, 0, display,
- g_cfg->session_variables1, g_cfg->session_variables2);
+ env_set_user(username,
+ 0,
+ display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh");
if (g_file_exist(text))
@@ -844,36 +920,9 @@ session_reconnect_fork(int display, char *username)
/* called by a worker thread, ask the main thread to call session_sync_start
and wait till done */
int DEFAULT_CC
-session_start(int width, int height, int bpp, char *username, char *password,
- long data, tui8 type, char *domain, char *program,
- char *directory, char *client_ip)
+session_start(long data, tui8 type, struct SCP_SESSION *s)
{
- int display;
-
- /* lock mutex */
- lock_sync_acquire();
- /* set shared vars */
- g_sync_cmd = 0;
- g_sync_width = width;
- g_sync_height = height;
- g_sync_bpp = bpp;
- g_sync_username = username;
- g_sync_password = password;
- g_sync_domain = domain;
- g_sync_program = program;
- g_sync_directory = directory;
- g_sync_client_ip = client_ip;
- g_sync_data = data;
- g_sync_type = type;
- /* set event for main thread to see */
- g_set_wait_obj(g_sync_event);
- /* wait for main thread to get done */
- lock_sync_sem_acquire();
- /* read result(display) from shared var */
- display = g_sync_result;
- /* unlock mutex */
- lock_sync_release();
- return display;
+ return session_start_fork(data, type, s);
}
/******************************************************************************/
@@ -882,42 +931,7 @@ session_start(int width, int height, int bpp, char *username, char *password,
int DEFAULT_CC
session_reconnect(int display, char *username)
{
- /* lock mutex */
- lock_sync_acquire();
- /* set shared vars */
- g_sync_cmd = 1;
- g_sync_width = display;
- g_sync_username = username;
- /* set event for main thread to see */
- g_set_wait_obj(g_sync_event);
- /* wait for main thread to get done */
- lock_sync_sem_acquire();
- /* unlock mutex */
- lock_sync_release();
- return 0;
-}
-
-/******************************************************************************/
-/* called with the main thread */
-int APP_CC
-session_sync_start(void)
-{
- if (g_sync_cmd == 0)
- {
- g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp,
- g_sync_username, g_sync_password,
- g_sync_data, g_sync_type, g_sync_domain,
- g_sync_program, g_sync_directory,
- g_sync_client_ip);
- }
- else
- {
- /* g_sync_width is really display */
- g_sync_result = session_reconnect_fork(g_sync_width, g_sync_username);
- }
-
- lock_sync_sem_release();
- return 0;
+ return session_reconnect_fork(display, username);
}
/******************************************************************************/
@@ -927,9 +941,6 @@ session_kill(int pid)
struct session_chain *tmp;
struct session_chain *prev;
- /*THREAD-FIX require chain lock */
- lock_chain_acquire();
-
tmp = g_sessions;
prev = 0;
@@ -951,8 +962,6 @@ session_kill(int pid)
prev->next = tmp->next;
}
- /*THREAD-FIX release chain lock */
- lock_chain_release();
return SESMAN_SESSION_KILL_NULLITEM;
}
@@ -975,8 +984,6 @@ session_kill(int pid)
g_free(tmp);
g_session_count--;
- /*THREAD-FIX release chain lock */
- lock_chain_release();
return SESMAN_SESSION_KILL_OK;
}
@@ -985,8 +992,6 @@ session_kill(int pid)
tmp = tmp->next;
}
- /*THREAD-FIX release chain lock */
- lock_chain_release();
return SESMAN_SESSION_KILL_NOTFOUND;
}
@@ -996,9 +1001,6 @@ session_sigkill_all()
{
struct session_chain *tmp;
- /*THREAD-FIX require chain lock */
- lock_chain_acquire();
-
tmp = g_sessions;
while (tmp != 0)
@@ -1016,9 +1018,6 @@ session_sigkill_all()
/* go on */
tmp = tmp->next;
}
-
- /*THREAD-FIX release chain lock */
- lock_chain_release();
}
/******************************************************************************/
@@ -1028,17 +1027,14 @@ session_get_bypid(int pid)
struct session_chain *tmp;
struct session_item *dummy;
- dummy = g_malloc(sizeof(struct session_item), 1);
+ dummy = g_new0(struct session_item, 1);
if (0 == dummy)
{
- log_message(LOG_LEVEL_ERROR, "internal error", pid);
+ log_message(LOG_LEVEL_ERROR, "session_get_bypid: out of memory");
return 0;
}
- /*THREAD-FIX require chain lock */
- lock_chain_acquire();
-
tmp = g_sessions;
while (tmp != 0)
@@ -1047,18 +1043,13 @@ session_get_bypid(int pid)
{
log_message(LOG_LEVEL_ERROR, "session descriptor for "
"pid %d is null!", pid);
- /*THREAD-FIX release chain lock */
- lock_chain_release();
g_free(dummy);
return 0;
}
if (tmp->item->pid == pid)
{
- /*THREAD-FIX release chain lock */
g_memcpy(dummy, tmp->item, sizeof(struct session_item));
- lock_chain_release();
- /*return tmp->item;*/
return dummy;
}
@@ -1066,15 +1057,13 @@ session_get_bypid(int pid)
tmp = tmp->next;
}
- /*THREAD-FIX release chain lock */
- lock_chain_release();
g_free(dummy);
return 0;
}
/******************************************************************************/
struct SCP_DISCONNECTED_SESSION *
-session_get_byuser(char *user, int *cnt, unsigned char flags)
+session_get_byuser(const char *user, int *cnt, unsigned char flags)
{
struct session_chain *tmp;
struct SCP_DISCONNECTED_SESSION *sess;
@@ -1083,9 +1072,6 @@ session_get_byuser(char *user, int *cnt, unsigned char flags)
count = 0;
- /*THREAD-FIX require chain lock */
- lock_chain_acquire();
-
tmp = g_sessions;
while (tmp != 0)
@@ -1111,19 +1097,15 @@ session_get_byuser(char *user, int *cnt, unsigned char flags)
if (count == 0)
{
(*cnt) = 0;
- /*THREAD-FIX release chain lock */
- lock_chain_release();
return 0;
}
/* malloc() an array of disconnected sessions */
- sess = g_malloc(count *sizeof(struct SCP_DISCONNECTED_SESSION), 1);
+ sess = g_new0(struct SCP_DISCONNECTED_SESSION, count);
if (sess == 0)
{
(*cnt) = 0;
- /*THREAD-FIX release chain lock */
- lock_chain_release();
return 0;
}
@@ -1132,7 +1114,7 @@ session_get_byuser(char *user, int *cnt, unsigned char flags)
while (tmp != 0)
{
-#warning FIXME: we should get only disconnected sessions!
+/* #warning FIXME: we should get only disconnected sessions! */
if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256)))
{
if ((tmp->item->status) & flags)
@@ -1142,7 +1124,7 @@ session_get_byuser(char *user, int *cnt, unsigned char flags)
(sess[index]).height = tmp->item->height;
(sess[index]).width = tmp->item->width;
(sess[index]).bpp = tmp->item->bpp;
-#warning FIXME: setting idle times and such
+/* #warning FIXME: setting idle times and such */
/*(sess[index]).connect_time.year = tmp->item->connect_time.year;
(sess[index]).connect_time.month = tmp->item->connect_time.month;
(sess[index]).connect_time.day = tmp->item->connect_time.day;
@@ -1175,8 +1157,6 @@ session_get_byuser(char *user, int *cnt, unsigned char flags)
tmp = tmp->next;
}
- /*THREAD-FIX release chain lock */
- lock_chain_release();
(*cnt) = count;
return sess;
}
diff --git a/sesman/session.h b/sesman/session.h
index 05e3b3a9..73313595 100644
--- a/sesman/session.h
+++ b/sesman/session.h
@@ -76,6 +76,7 @@ struct session_item
struct session_date disconnect_time;
struct session_date idle_time;
char client_ip[256];
+ tui8 guid[16];
};
struct session_chain
@@ -91,7 +92,8 @@ struct session_chain
*
*/
struct session_item* DEFAULT_CC
-session_get_bydata(char* name, int width, int height, int bpp, int type, char *client_ip);
+session_get_bydata(const char *name, int width, int height, int bpp, int type,
+ const char *client_ip);
#ifndef session_find_item
#define session_find_item(a, b, c, d, e, f) session_get_bydata(a, b, c, d, e, f);
#endif
@@ -103,24 +105,13 @@ session_get_bydata(char* name, int width, int height, int bpp, int type, char *c
*
*/
int DEFAULT_CC
-session_start(int width, int height, int bpp, char* username, char* password,
- long data, tui8 type, char* domain, char* program,
- char* directory, char* client_ip);
+session_start(long data, tui8 type, struct SCP_SESSION *s);
int DEFAULT_CC
session_reconnect(int display, char* username);
/**
*
- * @brief starts a session
- * @return error
- *
- */
-int APP_CC
-session_sync_start(void);
-
-/**
- *
* @brief kills a session
* @param pid the pid of the session to be killed
* @return
@@ -156,6 +147,6 @@ session_get_bypid(int pid);
*
*/
struct SCP_DISCONNECTED_SESSION*
-session_get_byuser(char* user, int* cnt, unsigned char flags);
+session_get_byuser(const char *user, int *cnt, unsigned char flags);
#endif
diff --git a/sesman/sessvc/Makefile.am b/sesman/sessvc/Makefile.am
index 8ba24abd..c2714b94 100644
--- a/sesman/sessvc/Makefile.am
+++ b/sesman/sessvc/Makefile.am
@@ -1,11 +1,9 @@
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
-
-INCLUDES = \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-I$(top_srcdir)/common
sbin_PROGRAMS = \
diff --git a/sesman/sessvc/sessvc.c b/sesman/sessvc/sessvc.c
index b3e42178..3fb80a60 100644
--- a/sesman/sessvc/sessvc.c
+++ b/sesman/sessvc/sessvc.c
@@ -49,7 +49,7 @@ nil_signal_handler(int sig)
}
/******************************************************************************/
-/* chansrv can exit at any time without cleaning up, its an xlib app */
+/* chansrv can exit at any time without cleaning up, it's an xlib app */
int APP_CC
chansrv_cleanup(int pid)
{
@@ -93,7 +93,6 @@ main(int argc, char **argv)
return 1;
}
- g_signal_kill(term_signal_handler); /* SIGKILL */
g_signal_terminate(term_signal_handler); /* SIGTERM */
g_signal_user_interrupt(term_signal_handler); /* SIGINT */
g_signal_pipe(nil_signal_handler); /* SIGPIPE */
@@ -101,7 +100,7 @@ main(int argc, char **argv)
wm_pid = g_atoi(argv[2]);
g_writeln("xrdp-sessvc: waiting for X (pid %d) and WM (pid %d)",
x_pid, wm_pid);
- /* run xrdp-chansrv as a seperate process */
+ /* run xrdp-chansrv as a separate process */
chansrv_pid = g_fork();
if (chansrv_pid == -1)
diff --git a/sesman/sig.c b/sesman/sig.c
index 72892fb2..579b5876 100644
--- a/sesman/sig.c
+++ b/sesman/sig.c
@@ -51,8 +51,6 @@ sig_sesman_shutdown(int sig)
g_set_wait_obj(g_term_event);
- g_tcp_close(g_sck);
-
session_sigkill_all();
g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH);
@@ -75,7 +73,7 @@ sig_sesman_reload_cfg(int sig)
return;
}
- cfg = g_malloc(sizeof(struct config_sesman), 1);
+ cfg = g_new0(struct config_sesman, 1);
if (0 == cfg)
{
@@ -93,13 +91,16 @@ sig_sesman_reload_cfg(int sig)
/* stop logging subsystem */
log_end();
- /* replace old config with new readed one */
+ /* free old config data */
+ config_free(g_cfg);
+
+ /* replace old config with newly read one */
g_cfg = cfg;
g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
/* start again logging subsystem */
- error = log_start(cfg_file, "XRDP-sesman");
+ error = log_start(cfg_file, "xrdp-sesman");
if (error != LOG_STARTUP_OK)
{
@@ -158,7 +159,6 @@ sig_handler_thread(void *arg)
sigaddset(&waitmask, SIGHUP);
sigaddset(&waitmask, SIGCHLD);
sigaddset(&waitmask, SIGTERM);
- sigaddset(&waitmask, SIGKILL);
sigaddset(&waitmask, SIGINT);
// sigaddset(&waitmask, SIGFPE);
@@ -188,11 +188,6 @@ sig_handler_thread(void *arg)
LOG_DBG("sesman received SIGINT", 0);
sig_sesman_shutdown(recv_signal);
break;
- case SIGKILL:
- /* we die */
- LOG_DBG("sesman received SIGKILL", 0);
- sig_sesman_shutdown(recv_signal);
- break;
case SIGTERM:
/* we die */
LOG_DBG("sesman received SIGTERM", 0);
diff --git a/sesman/startwm.sh b/sesman/startwm.sh
index ee48263f..b81d3646 100755
--- a/sesman/startwm.sh
+++ b/sesman/startwm.sh
@@ -29,36 +29,34 @@ wm_start()
xterm
}
-#Execution sequence for interactive login shell
-#Following pseudo code explains the sequence of execution of these files.
-#execute /etc/profile
-#IF ~/.bash_profile exists THEN
-# execute ~/.bash_profile
-#ELSE
-# IF ~/.bash_login exist THEN
-# execute ~/.bash_login
-# ELSE
-# IF ~/.profile exist THEN
-# execute ~/.profile
-# END IF
-# END IF
-#END IF
+# Execution sequence for interactive login shell - pseudocode
+#
+# IF /etc/profile is readable THEN
+# execute ~/.bash_profile
+# END IF
+# IF ~/.bash_profile is readable THEN
+# execute ~/.bash_profile
+# ELSE
+# IF ~/.bash_login is readable THEN
+# execute ~/.bash_login
+# ELSE
+# IF ~/.profile is readable THEN
+# execute ~/.profile
+# END IF
+# END IF
+# END IF
pre_start()
{
- if [ -f /etc/profile ]
- then
+ if [ -r /etc/profile ]; then
. /etc/profile
fi
- if [ -f ~/.bash_profile ]
- then
+ if [ -r ~/.bash_profile ]; then
. ~/.bash_profile
else
- if [ -f ~/.bash_login ]
- then
+ if [ -r ~/.bash_login ]; then
. ~/.bash_login
else
- if [ -f ~/.profile ]
- then
+ if [ -r ~/.profile ]; then
. ~/.profile
fi
fi
@@ -66,15 +64,14 @@ pre_start()
return 0
}
-#When you logout of the interactive shell, following is the
-#sequence of execution:
-#IF ~/.bash_logout exists THEN
-# execute ~/.bash_logout
-#END IF
+# When loging out from the interactive shell, the execution sequence is:
+#
+# IF ~/.bash_logout exists THEN
+# execute ~/.bash_logout
+# END IF
post_start()
{
- if [ -f ~/.bash_logout ]
- then
+ if [ -r ~/.bash_logout ]; then
. ~/.bash_logout
fi
return 0
diff --git a/sesman/thread.c b/sesman/thread.c
deleted file mode 100644
index 0ed1182a..00000000
--- a/sesman/thread.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * xrdp: A Remote Desktop Protocol server.
- *
- * Copyright (C) Jay Sorg 2004-2013
- *
- * 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.
- */
-
-/**
- *
- * @file thread.c
- * @brief thread stuff...
- * @author Simone Fedele
- *
- */
-
-#include "sesman.h"
-
-#include <errno.h>
-#include <signal.h>
-#include <pthread.h>
-
-extern struct config_sesman *g_cfg; /* in sesman.c */
-
-static pthread_t g_thread_sighandler;
-//static pthread_t g_thread_updater;
-
-/* a variable to pass the socket of s connection to a thread */
-int g_thread_sck;
-
-/******************************************************************************/
-int DEFAULT_CC
-thread_sighandler_start(void)
-{
- int ret;
- sigset_t sigmask;
- sigset_t oldmask;
- sigset_t waitmask;
-
- /* mask signals to be able to wait for them... */
- sigfillset(&sigmask);
- pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask);
-
- /* unblock some signals... */
- sigemptyset(&waitmask);
-
- /* it is a good idea not to block SIGILL SIGSEGV */
- /* SIGFPE -- see sigaction(2) NOTES */
- sigaddset(&waitmask, SIGILL);
- sigaddset(&waitmask, SIGSEGV);
- sigaddset(&waitmask, SIGFPE);
- pthread_sigmask(SIG_UNBLOCK, &waitmask, NULL);
-
- log_message(LOG_LEVEL_INFO, "starting signal handling thread...");
-
- ret = pthread_create(&g_thread_sighandler, NULL, sig_handler_thread, "");
- pthread_detach(g_thread_sighandler);
-
- if (ret == 0)
- {
- log_message(LOG_LEVEL_INFO, "signal handler thread started successfully");
- return 0;
- }
-
- /* if something happened while starting a new thread... */
- switch (ret)
- {
- case EINVAL:
- log_message(LOG_LEVEL_ERROR, "invalid attributes for signal handling thread (creation returned EINVAL)");
- break;
- case EAGAIN:
- log_message(LOG_LEVEL_ERROR, "not enough resources to start signal handling thread (creation returned EAGAIN)");
- break;
- case EPERM:
- log_message(LOG_LEVEL_ERROR, "invalid permissions for signal handling thread (creation returned EPERM)");
- break;
- default:
- log_message(LOG_LEVEL_ERROR, "unknown error starting signal handling thread");
- }
-
- return 1;
-}
-
-#ifdef JUST_TO_AVOID_COMPILER_ERRORS
-/******************************************************************************/
-int DEFAULT_CC
-thread_session_update_start(void)
-{
- int ret;
- //starts the session update thread
- //that checks for idle time, destroys sessions, ecc...
-
-#warning this thread should always request lock_fork before read or write
-#warning (so we can Fork() In Peace)
- ret = pthread_create(&g_thread_updater, NULL, , "");
- pthread_detach(g_thread_updater);
-
- if (ret == 0)
- {
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "session update thread started successfully");
- return 0;
- }
-
- /* if something happened while starting a new thread... */
- switch (ret)
- {
- case EINVAL:
- log_message(LOG_LEVEL_ERROR, "invalid attributes for session update thread (creation returned EINVAL)");
- break;
- case EAGAIN:
- log_message(LOG_LEVEL_ERROR, "not enough resources to start session update thread (creation returned EAGAIN)");
- break;
- case EPERM:
- log_message(LOG_LEVEL_ERROR, "invalid permissions for session update thread (creation returned EPERM)");
- break;
- default:
- log_message(LOG_LEVEL_ERROR, "unknown error starting session update thread");
- }
-
- return 1;
-}
-#endif
-
-/******************************************************************************/
-int DEFAULT_CC
-thread_scp_start(int skt)
-{
- int ret;
- pthread_t th;
-
- /* blocking the use of thread_skt */
- lock_socket_acquire();
- g_thread_sck = skt;
-
- /* start a thread that processes a connection */
- ret = pthread_create(&th, NULL, scp_process_start, "");
- //ret = pthread_create(&th, NULL, scp_process_start, (void*) (&g_thread_sck));
- pthread_detach(th);
-
- if (ret == 0)
- {
- log_message(LOG_LEVEL_INFO, "scp thread on sck %d started successfully", skt);
- return 0;
- }
-
- /* if something happened while starting a new thread... */
- switch (ret)
- {
- case EINVAL:
- log_message(LOG_LEVEL_ERROR, "invalid attributes for scp thread on sck %d (creation returned EINVAL)", skt);
- break;
- case EAGAIN:
- log_message(LOG_LEVEL_ERROR, "not enough resources to start scp thread on sck %d (creation returned EAGAIN)", skt);
- break;
- case EPERM:
- log_message(LOG_LEVEL_ERROR, "invalid permissions for scp thread on sck %d (creation returned EPERM)", skt);
- break;
- default:
- log_message(LOG_LEVEL_ERROR, "unknown error starting scp thread on sck %d");
- }
-
- return 1;
-}
diff --git a/sesman/tools/Makefile.am b/sesman/tools/Makefile.am
index 140c6820..44bf068b 100644
--- a/sesman/tools/Makefile.am
+++ b/sesman/tools/Makefile.am
@@ -1,16 +1,14 @@
-EXTRA_DIST = tcp.h
-
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
-
-INCLUDES = \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-I$(top_srcdir)/common \
-I$(top_srcdir)/sesman/libscp \
-I$(top_srcdir)/sesman
+AM_CFLAGS = $(X_CFLAGS)
+
bin_PROGRAMS = \
xrdp-sesrun \
xrdp-sesadmin \
@@ -21,9 +19,10 @@ noinst_PROGRAMS = \
xrdp-xcon
xrdp_sesrun_SOURCES = \
+ config.c \
sesrun.c \
tcp.c \
- config.c
+ tcp.h
xrdp_sestest_SOURCES = \
sestest.c
@@ -48,6 +47,8 @@ xrdp_sesadmin_LDADD = \
$(top_builddir)/common/libcommon.la \
$(top_builddir)/sesman/libscp/libscp.la
+xrdp_xcon_LDFLAGS = \
+ $(X_LIBS)
+
xrdp_xcon_LDADD = \
- -L/usr/X11R6/lib \
- -lX11
+ $(X_PRE_LIBS) -lX11 $(X_EXTRA_LIBS)
diff --git a/sesman/tools/config.c b/sesman/tools/config.c
new file mode 100644
index 00000000..0f1399cc
--- /dev/null
+++ b/sesman/tools/config.c
@@ -0,0 +1 @@
+#include "../config.c"
diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c
index 32789c6d..e4a1cc2b 100644
--- a/sesman/tools/sesadmin.c
+++ b/sesman/tools/sesadmin.c
@@ -2,6 +2,19 @@
* sesadmin.c - an sesman administration tool
* (c) 2008 Simone Fedele
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "arch.h"
@@ -46,7 +59,7 @@ int main(int argc, char **argv)
serv[0] = '\0';
port[0] = '\0';
- logging.program_name = g_strdup("sesadmin");
+ logging.program_name = "sesadmin";
logging.log_file = g_strdup("xrdp-sesadmin.log");
logging.log_level = LOG_LEVEL_DEBUG;
logging.enable_syslog = 0;
@@ -88,7 +101,14 @@ int main(int argc, char **argv)
if (0 == g_strncmp(user, "", 1))
{
- g_strncpy(user, "root", 256);
+ cmndHelp();
+ return 0;
+ }
+
+ if (0 == g_strncmp(cmnd, "", 1))
+ {
+ cmndHelp();
+ return 0;
}
if (0 == g_strncmp(pass, "", 1))
@@ -104,23 +124,23 @@ int main(int argc, char **argv)
}
}
- scp_init(&logging);
+ scp_init();
sock = g_tcp_socket();
if (sock < 0)
{
- LOG_DBG("Socket open error, g_tcp_socket() failed\n");
+ LOG_DBG("Socket open error, g_tcp_socket() failed");
return 1;
}
s = scp_session_create();
c = scp_connection_create(sock);
- LOG_DBG("Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass);
+ LOG_DBG("Connecting to %s:%s with user %s (%s)", serv, port, user, pass);
if (0 != g_tcp_connect(sock, serv, port))
{
- LOG_DBG("g_tcp_connect() error\n");
+ LOG_DBG("g_tcp_connect() error");
return 1;
}
@@ -133,7 +153,7 @@ int main(int argc, char **argv)
if (SCP_CLIENT_STATE_OK != e)
{
- LOG_DBG("libscp error connecting: %s %d\n", s->errstr, (int)e);
+ LOG_DBG("libscp error connecting: %s %d", s->errstr, (int)e);
}
if (0 == g_strncmp(cmnd, "list", 5))
@@ -155,16 +175,16 @@ int main(int argc, char **argv)
void cmndHelp()
{
- fprintf(stderr, "sesadmin - a console sesman adminitration tool\n");
- fprintf(stderr, "sysntax: sesadmin [] COMMAND [OPTIONS]\n\n");
+ fprintf(stderr, "sesadmin - a console sesman administration tool\n");
+ fprintf(stderr, "syntax: sesadmin [] COMMAND [OPTIONS]\n\n");
fprintf(stderr, "-u=<username>: username to connect to sesman [MANDATORY]\n");
- fprintf(stderr, "-p=<password>: password to connect to sesman [MANDATORY]\n");
+ fprintf(stderr, "-p=<password>: password to connect to sesman (asked if not given)\n");
fprintf(stderr, "-s=<hostname>: sesman host (default is localhost)\n");
fprintf(stderr, "-i=<port> : sesman port (default 3350)\n");
fprintf(stderr, "-c=<command> : command to execute on the server [MANDATORY]\n");
fprintf(stderr, " it can be one of those:\n");
- fprintf(stderr, " LIST\n");
- fprintf(stderr, " KILL:<sid>\n");
+ fprintf(stderr, " list\n");
+ fprintf(stderr, " kill:<sid>\n");
}
void cmndList(struct SCP_CONNECTION *c)
diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c
index a9181583..d671f125 100644
--- a/sesman/tools/sesrun.c
+++ b/sesman/tools/sesrun.c
@@ -27,8 +27,6 @@
#include "sesman.h"
#include "tcp.h"
-int g_sck;
-int g_pid;
struct config_sesman g_cfg; /* config.h */
/******************************************************************************/
@@ -56,8 +54,6 @@ main(int argc, char **argv)
return 1;
}
- g_pid = g_getpid();
-
if (argc == 1)
{
g_printf("xrdp session starter v0.1\n");
@@ -115,7 +111,7 @@ main(int argc, char **argv)
{
in_uint16_be(in_s, data);
in_uint16_be(in_s, display);
- g_printf("ok %d display %d\n", data, display);
+ g_printf("ok %d display %d\n", (int)data, display);
}
}
}
diff --git a/sesman/tools/sestest.c b/sesman/tools/sestest.c
index d42b31de..081bc88b 100644
--- a/sesman/tools/sestest.c
+++ b/sesman/tools/sestest.c
@@ -2,6 +2,19 @@
* sestest.c - an scp_v1 testing tool
* (c) 2008 Simone Fedele
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "arch.h"
@@ -31,11 +44,11 @@ int main(int argc, char **argv)
int sock;
log.enable_syslog = 0;
- log.log_level = 99;
- log.program_name = g_strdup("sestest");
+ log.log_level = LOG_LEVEL_DEBUG;
+ log.program_name = "sestest";
log.log_file = g_strdup("sestest.log");
log_start_from_param(&log);
- scp_init(&log);
+ scp_init();
sock = g_tcp_socket();
if (sock < 0)
@@ -188,8 +201,8 @@ int inputSession(struct SCP_SESSION *s)
}
g_printf("session type:\n");
- g_printf("0: Xvnc\n", SCP_SESSION_TYPE_XVNC);
- g_printf("1: x11rdp\n", SCP_SESSION_TYPE_XRDP);
+ g_printf("%d: Xvnc\n", SCP_SESSION_TYPE_XVNC);
+ g_printf("%d: x11rdp\n", SCP_SESSION_TYPE_XRDP);
integer = menuSelect(1);
if (integer == 1)
diff --git a/sesman/tools/tcp.c b/sesman/tools/tcp.c
index 2f7ae948..32c0bbc9 100644
--- a/sesman/tools/tcp.c
+++ b/sesman/tools/tcp.c
@@ -19,7 +19,7 @@
/**
*
* @file tcp.c
- * @brief Tcp stream funcions
+ * @brief Tcp stream functions
* @author Jay Sorg, Simone Fedele
*
*/
diff --git a/sesman/tools/xcon.c b/sesman/tools/xcon.c
index 80832276..4b3248b6 100644
--- a/sesman/tools/xcon.c
+++ b/sesman/tools/xcon.c
@@ -19,6 +19,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
#include <X11/Xlib.h>
Display *g_display = 0;
diff --git a/sesman/verify_user.c b/sesman/verify_user.c
index 9dc77efc..adfef908 100644
--- a/sesman/verify_user.c
+++ b/sesman/verify_user.c
@@ -26,8 +26,8 @@
#include "sesman.h"
-#define _XOPEN_SOURCE
#include <stdio.h>
+#include <string.h>
#include <sys/types.h>
#include <crypt.h>
#include <shadow.h>
@@ -40,7 +40,7 @@
extern struct config_sesman *g_cfg; /* in sesman.c */
static int DEFAULT_CC
-auth_crypt_pwd(char *pwd, char *pln, char *crp);
+auth_crypt_pwd(const char *pwd, const char *pln, char *crp);
static int DEFAULT_CC
auth_account_disabled(struct spwd *stp);
@@ -48,7 +48,7 @@ auth_account_disabled(struct spwd *stp);
/******************************************************************************/
/* returns boolean */
long DEFAULT_CC
-auth_userpass(char *user, char *pass, int *errorcode)
+auth_userpass(const char *user, const char *pass, int *errorcode)
{
const char *encr;
const char *epass;
@@ -125,7 +125,7 @@ auth_set_env(long in_val)
/******************************************************************************/
int DEFAULT_CC
-auth_check_pwd_chg(char *user)
+auth_check_pwd_chg(const char *user)
{
struct passwd *spw;
struct spwd *stp;
@@ -182,7 +182,7 @@ auth_check_pwd_chg(char *user)
}
int DEFAULT_CC
-auth_change_pwd(char *user, char *newpwd)
+auth_change_pwd(const char *user, const char *newpwd)
{
struct passwd *spw;
struct spwd *stp;
@@ -256,7 +256,7 @@ auth_change_pwd(char *user, char *newpwd)
*/
static int DEFAULT_CC
-auth_crypt_pwd(char *pwd, char *pln, char *crp)
+auth_crypt_pwd(const char *pwd, const char *pln, char *crp)
{
char salt[13] = "$1$";
int saltcnt = 0;
@@ -321,7 +321,10 @@ auth_account_disabled(struct spwd *stp)
return 1;
}
- if (today >= (stp->sp_lstchg + stp->sp_max + stp->sp_inact))
+ if ((stp->sp_max >= 0) &&
+ (stp->sp_inact >= 0) &&
+ (stp->sp_lstchg > 0) &&
+ (today >= (stp->sp_lstchg + stp->sp_max + stp->sp_inact)))
{
return 1;
}
diff --git a/sesman/verify_user_bsd.c b/sesman/verify_user_bsd.c
index 5d9d0e23..ff5e87a9 100644
--- a/sesman/verify_user_bsd.c
+++ b/sesman/verify_user_bsd.c
@@ -44,7 +44,7 @@ extern struct config_sesman* g_cfg; /* in sesman.c */
/******************************************************************************/
/* returns boolean */
long DEFAULT_CC
-auth_userpass(char *user, char *pass, int *errorcode)
+auth_userpass(const char *user, const char *pass, int *errorcode)
{
int ret = auth_userokay(user, NULL, "auth-xrdp", pass);
return ret;
@@ -74,13 +74,13 @@ auth_set_env(long in_val)
/******************************************************************************/
int DEFAULT_CC
-auth_check_pwd_chg(char* user)
+auth_check_pwd_chg(const char *user)
{
return 0;
}
int DEFAULT_CC
-auth_change_pwd(char* user, char* newpwd)
+auth_change_pwd(const char *user, const char *newpwd)
{
return 0;
}
@@ -101,7 +101,7 @@ auth_stop_session(long in_val)
*/
static int DEFAULT_CC
-auth_crypt_pwd(char* pwd, char* pln, char* crp)
+auth_crypt_pwd(const char *pwd, const char *pln, char *crp)
{
return 0;
}
diff --git a/sesman/verify_user_kerberos.c b/sesman/verify_user_kerberos.c
index bb7ba3d2..62d020a5 100644
--- a/sesman/verify_user_kerberos.c
+++ b/sesman/verify_user_kerberos.c
@@ -67,8 +67,8 @@ struct k5_data
struct user_info
{
- char *name;
- char *pass;
+ const char *name;
+ const char *pass;
};
/******************************************************************************/
@@ -221,7 +221,7 @@ kinit_prompter(krb5_context ctx, void *data, const char *name,
static int
k5_kinit(struct k_opts *opts, struct k5_data *k5, struct user_info *u_info)
{
- char *doing;
+ const char *doing;
int notix = 1;
krb5_keytab keytab = 0;
krb5_creds my_creds;
@@ -396,7 +396,7 @@ cleanup:
/******************************************************************************/
/* returns boolean */
int DEFAULT_CC
-auth_userpass(char *user, char *pass, int *errorcode)
+auth_userpass(const char *user, const char *pass, int *errorcode)
{
struct k_opts opts;
struct k5_data k5;
@@ -425,7 +425,7 @@ auth_userpass(char *user, char *pass, int *errorcode)
/******************************************************************************/
/* returns error */
int DEFAULT_CC
-auth_start_session(void)
+auth_start_session(long in_val, int in_display)
{
return 0;
}
@@ -440,14 +440,14 @@ auth_stop_session(long in_val)
/******************************************************************************/
int DEFAULT_CC
-auth_end(void)
+auth_end(long in_val)
{
return 0;
}
/******************************************************************************/
int DEFAULT_CC
-auth_set_env(void)
+auth_set_env(long in_val)
{
return 0;
}
diff --git a/sesman/verify_user_pam.c b/sesman/verify_user_pam.c
index a2b3f93a..73e0b63f 100644
--- a/sesman/verify_user_pam.c
+++ b/sesman/verify_user_pam.c
@@ -54,19 +54,19 @@ verify_pam_conv(int num_msg, const struct pam_message **msg,
struct pam_response *reply;
struct t_user_pass *user_pass;
- reply = g_malloc(sizeof(struct pam_response) * num_msg, 1);
+ reply = g_new0(struct pam_response, num_msg);
for (i = 0; i < num_msg; i++)
{
switch (msg[i]->msg_style)
{
case PAM_PROMPT_ECHO_ON: /* username */
- user_pass = appdata_ptr;
+ user_pass = (struct t_user_pass *) appdata_ptr;
reply[i].resp = g_strdup(user_pass->user);
reply[i].resp_retcode = PAM_SUCCESS;
break;
case PAM_PROMPT_ECHO_OFF: /* password */
- user_pass = appdata_ptr;
+ user_pass = (struct t_user_pass *) appdata_ptr;
reply[i].resp = g_strdup(user_pass->pass);
reply[i].resp_retcode = PAM_SUCCESS;
break;
@@ -102,14 +102,14 @@ get_service_name(char *service_name)
Stores the detailed error code in the errorcode variable*/
long DEFAULT_CC
-auth_userpass(char *user, char *pass, int *errorcode)
+auth_userpass(const char *user, const char *pass, int *errorcode)
{
int error;
struct t_auth_info *auth_info;
char service_name[256];
get_service_name(service_name);
- auth_info = g_malloc(sizeof(struct t_auth_info), 1);
+ auth_info = g_new0(struct t_auth_info, 1);
g_strncpy(auth_info->user_pass.user, user, 255);
g_strncpy(auth_info->user_pass.pass, pass, 255);
auth_info->pamc.conv = &verify_pam_conv;
diff --git a/sesman/verify_user_pam_userpass.c b/sesman/verify_user_pam_userpass.c
index b3d4de73..19bc7105 100644
--- a/sesman/verify_user_pam_userpass.c
+++ b/sesman/verify_user_pam_userpass.c
@@ -34,7 +34,7 @@
/******************************************************************************/
/* returns boolean */
int DEFAULT_CC
-auth_userpass(char *user, char *pass, int *errorcode)
+auth_userpass(const char *user, const char *pass, int *errorcode)
{
pam_handle_t *pamh;
pam_userpass_t userpass;
@@ -85,7 +85,7 @@ auth_userpass(char *user, char *pass, int *errorcode)
/******************************************************************************/
/* returns error */
int DEFAULT_CC
-auth_start_session(void)
+auth_start_session(long in_val, int in_display)
{
return 0;
}
@@ -100,14 +100,14 @@ auth_stop_session(long in_val)
/******************************************************************************/
int DEFAULT_CC
-auth_end(void)
+auth_end(long in_val)
{
return 0;
}
/******************************************************************************/
int DEFAULT_CC
-auth_set_env(void)
+auth_set_env(long in_val)
{
return 0;
}
diff --git a/sesman/xauth.c b/sesman/xauth.c
new file mode 100644
index 00000000..003fb866
--- /dev/null
+++ b/sesman/xauth.c
@@ -0,0 +1,62 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Emmanuel Blindauer 2016
+ *
+ * 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.
+ */
+
+/**
+ *
+ * @file xauth.c
+ * @brief XAUTHORITY handling code
+ *
+ */
+
+#include <stdio.h>
+#include "log.h"
+#include "os_calls.h"
+
+
+/******************************************************************************/
+int DEFAULT_CC
+add_xauth_cookie(int display, const char *file)
+{
+ FILE *dp;
+ char cookie_str[33];
+ char cookie_bin[16];
+ char xauth_str[256];
+ int ret;
+
+ g_random(cookie_bin, 16);
+ g_bytes_to_hexstr(cookie_bin, 16, cookie_str, 33);
+
+ g_sprintf(xauth_str, "xauth -q -f %s add :%d . %s",
+ file, display, cookie_str);
+
+ dp = popen(xauth_str, "r");
+ if (dp == NULL)
+ {
+ log_message(LOG_LEVEL_ERROR, "Unable to launch xauth");
+ return 1;
+ }
+
+ ret = pclose(dp);
+ if (ret < 0)
+ {
+ log_message(LOG_LEVEL_ERROR, "An error occurred while running xauth");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/sesman/thread.h b/sesman/xauth.h
index 83a4b63d..3254d635 100644
--- a/sesman/thread.h
+++ b/sesman/xauth.h
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Emmanuel Blindauer 2016
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,39 +18,24 @@
/**
*
- * @file thread.h
- * @brief thread stuff...
- * @author Simone Fedele
+ * @file xauth.c
+ * @brief XAUTHORITY handling code
*
*/
-#ifndef THREAD_H
-#define THREAD_H
+#ifndef XAUTH_H
+#define XAUTH_H
/**
*
- * @brief Starts the signal handling thread
- * @retval 0 on success
- * @retval 1 on error
- *
- */
-int DEFAULT_CC
-thread_sighandler_start(void);
-
-/**
- *
- * @brief Starts the session update thread
- *
+ * @brief create the XAUTHORITY file for the user according to the display and the cookie
+ * xauth uses XAUTHORITY if defined, ~/.Xauthority otherwise
+ * @param display The session display
+ * @param file If not NULL, write the authorization in the file instead of default location
+ * @return 0 if adding the cookie is ok
*/
-int DEFAULT_CC
-thread_session_update_start(void);
-/**
- *
- * @brief Starts a thread to handle an incoming connection
- *
- */
int DEFAULT_CC
-thread_scp_start(int skt);
+add_xauth_cookie(int display, const char *file);
#endif
diff --git a/tcutils/README.txt b/tcutils/README.txt
index de75f1b2..31ebb1f8 100644
--- a/tcutils/README.txt
+++ b/tcutils/README.txt
@@ -1,4 +1,4 @@
-A QT based utility program for thinclients using xrdp and NeutrinoRDP
+A QT based utility program for thin clients using xrdp and NeutrinoRDP
This program sends commands to NeutrinoRDP to do something
useful on the client end (such as unmounting a USB drive,
diff --git a/tcutils/moc_mainwindow.cpp b/tcutils/moc_mainwindow.cpp
deleted file mode 100644
index 85806598..00000000
--- a/tcutils/moc_mainwindow.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-** Meta object code from reading C++ file 'mainwindow.h'
-**
-** Created: Sun Aug 25 15:11:44 2013
-** by: The Qt Meta Object Compiler version 63 (Qt 4.8.1)
-**
-** WARNING! All changes made in this file will be lost!
-*****************************************************************************/
-
-#include "mainwindow.h"
-#if !defined(Q_MOC_OUTPUT_REVISION)
-#error "The header file 'mainwindow.h' doesn't include <QObject>."
-#elif Q_MOC_OUTPUT_REVISION != 63
-#error "This file was generated using the moc from 4.8.1. It"
-#error "cannot be used with the include files from this version of Qt."
-#error "(The moc has changed too much.)"
-#endif
-
-QT_BEGIN_MOC_NAMESPACE
-static const uint qt_meta_data_MainWindow[] = {
-
- // content:
- 6, // revision
- 0, // classname
- 0, 0, // classinfo
- 5, 14, // methods
- 0, 0, // properties
- 0, 0, // enums/sets
- 0, 0, // constructors
- 0, // flags
- 0, // signalCount
-
- // slots: signature, parameters, type, tag, flags
- 12, 11, 11, 11, 0x08,
- 34, 11, 11, 11, 0x08,
- 56, 11, 11, 11, 0x08,
- 71, 11, 11, 11, 0x08,
- 88, 11, 11, 11, 0x08,
-
- 0 // eod
-};
-
-static const char qt_meta_stringdata_MainWindow[] = {
- "MainWindow\0\0onBtnRefreshClicked()\0"
- "onBtnUnmountClicked()\0onActionQuit()\0"
- "onActionLaunch()\0"
- "onSystemTrayClicked(QSystemTrayIcon::ActivationReason)\0"
-};
-
-void MainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
-{
- if (_c == QMetaObject::InvokeMetaMethod) {
- Q_ASSERT(staticMetaObject.cast(_o));
- MainWindow *_t = static_cast<MainWindow *>(_o);
- switch (_id) {
- case 0: _t->onBtnRefreshClicked(); break;
- case 1: _t->onBtnUnmountClicked(); break;
- case 2: _t->onActionQuit(); break;
- case 3: _t->onActionLaunch(); break;
- case 4: _t->onSystemTrayClicked((*reinterpret_cast< QSystemTrayIcon::ActivationReason(*)>(_a[1]))); break;
- default: ;
- }
- }
-}
-
-const QMetaObjectExtraData MainWindow::staticMetaObjectExtraData = {
- 0, qt_static_metacall
-};
-
-const QMetaObject MainWindow::staticMetaObject = {
- { &QMainWindow::staticMetaObject, qt_meta_stringdata_MainWindow,
- qt_meta_data_MainWindow, &staticMetaObjectExtraData }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &MainWindow::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *MainWindow::metaObject() const
-{
- return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *MainWindow::qt_metacast(const char *_clname)
-{
- if (!_clname) return 0;
- if (!strcmp(_clname, qt_meta_stringdata_MainWindow))
- return static_cast<void*>(const_cast< MainWindow*>(this));
- return QMainWindow::qt_metacast(_clname);
-}
-
-int MainWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
- _id = QMainWindow::qt_metacall(_c, _id, _a);
- if (_id < 0)
- return _id;
- if (_c == QMetaObject::InvokeMetaMethod) {
- if (_id < 5)
- qt_static_metacall(this, _c, _id, _a);
- _id -= 5;
- }
- return _id;
-}
-QT_END_MOC_NAMESPACE
diff --git a/tcutils/qrc_resources.cpp b/tcutils/qrc_resources.cpp
deleted file mode 100644
index 3f2366cb..00000000
--- a/tcutils/qrc_resources.cpp
+++ /dev/null
@@ -1,1191 +0,0 @@
-/****************************************************************************
-** Resource object code
-**
-** Created: Sun Aug 25 15:11:45 2013
-** by: The Resource Compiler for Qt version 4.8.1
-**
-** WARNING! All changes made in this file will be lost!
-*****************************************************************************/
-
-#include <QtCore/qglobal.h>
-
-static const unsigned char qt_resource_data[] = {
- // /home/lk/projects/jtech/nlabs_xrdp_tcutils/tcutils/resources/images/tools.gif
- 0x0,0x0,0x45,0x65,
- 0x47,
- 0x49,0x46,0x38,0x39,0x61,0xab,0x0,0xb7,0x0,0xe7,0xff,0x0,0x22,0x26,0x9a,0x18,
- 0x2a,0x95,0x24,0x29,0x8f,0x1d,0x2e,0x92,0x1d,0x32,0x71,0x23,0x33,0x64,0x15,0x37,
- 0x6c,0x16,0x34,0x96,0x22,0x31,0x96,0x1f,0x37,0x65,0x25,0x3b,0x5a,0x28,0x35,0x93,
- 0x1d,0x38,0x9a,0x2c,0x38,0x70,0x1f,0x39,0x95,0x24,0x3a,0x87,0x14,0x3d,0x9f,0x15,
- 0x3e,0x99,0x2a,0x40,0x65,0x24,0x3f,0x81,0x1f,0x41,0x7d,0x21,0x42,0x6e,0x25,0x3d,
- 0x99,0x29,0x40,0x70,0x2c,0x3e,0x7b,0x1b,0x41,0x9c,0x24,0x42,0x78,0xd,0x46,0x99,
- 0x10,0x46,0xa0,0x29,0x40,0x97,0x1f,0x43,0x9e,0x1f,0x44,0x99,0x2b,0x40,0x9e,0x1e,
- 0x45,0x93,0x24,0x44,0x8c,0x21,0x43,0xa6,0x1e,0x49,0x84,0x23,0x45,0xa1,0x16,0x49,
- 0xa3,0x29,0x43,0xab,0x2a,0x48,0x77,0x22,0x49,0x8a,0x19,0x4b,0x99,0x26,0x47,0x9d,
- 0x30,0x45,0x95,0x2b,0x49,0x7f,0x1a,0x4b,0x9f,0x1c,0x4a,0xac,0x3d,0x47,0x6f,0x28,
- 0x48,0xa4,0x31,0x48,0x8a,0x28,0x49,0x9f,0x2e,0x4a,0x87,0x1c,0x4e,0x95,0x1d,0x4c,
- 0xa7,0x29,0x4a,0x98,0x27,0x4e,0x79,0x1e,0x4d,0xa1,0x2a,0x4a,0xa0,0x1d,0x50,0x90,
- 0x11,0x51,0xab,0x25,0x4f,0x84,0x37,0x4a,0x82,0x2c,0x4f,0x73,0x2c,0x4a,0xa7,0x12,
- 0x52,0xa5,0x11,0x53,0x9f,0x21,0x4e,0xa3,0x20,0x4f,0x9d,0x2a,0x4d,0x95,0x2a,0x4e,
- 0x90,0x22,0x4f,0xa4,0x33,0x4e,0x7d,0x2d,0x4d,0x9c,0x29,0x50,0x8c,0x32,0x4f,0x86,
- 0x23,0x51,0x9f,0x25,0x50,0xa5,0x30,0x4c,0xb1,0x16,0x56,0x9c,0x30,0x4e,0xa4,0x18,
- 0x55,0xa8,0x30,0x4f,0x9f,0x26,0x50,0xb3,0x26,0x52,0xa1,0x1a,0x54,0xb5,0x1a,0x56,
- 0xa3,0x28,0x51,0xad,0x1a,0x55,0xaf,0x26,0x54,0x9b,0x9,0x5b,0xad,0x25,0x55,0x96,
- 0x31,0x51,0x9b,0x28,0x53,0xa2,0x29,0x53,0xa8,0x29,0x54,0xa3,0x38,0x53,0x83,0x1e,
- 0x57,0xab,0x34,0x53,0x96,0x2a,0x55,0xa4,0x31,0x55,0x91,0x1e,0x59,0xa6,0x1e,0x5a,
- 0xa0,0x2c,0x55,0xab,0x3c,0x56,0x75,0x1e,0x5b,0x9c,0x2c,0x56,0xa5,0x2a,0x58,0x9a,
- 0x22,0x58,0xb3,0x32,0x58,0x84,0x22,0x59,0xad,0x3c,0x55,0x8d,0x2c,0x58,0xa0,0x30,
- 0x55,0xb2,0x2e,0x57,0xa6,0x2a,0x5a,0x95,0x22,0x5b,0xa8,0x32,0x59,0x8f,0x46,0x55,
- 0x7d,0x3a,0x54,0xac,0x47,0x53,0x9a,0x3c,0x59,0x7f,0x2e,0x5b,0x9d,0x32,0x59,0xaf,
- 0x3a,0x58,0xa3,0x2b,0x5a,0xbe,0x3a,0x59,0x9c,0x41,0x59,0x89,0x46,0x55,0xa6,0x38,
- 0x5b,0x98,0x26,0x60,0xa7,0x33,0x5d,0xa5,0x2a,0x60,0xaf,0x2c,0x5f,0xb4,0x39,0x5c,
- 0xba,0x30,0x63,0xa1,0x37,0x62,0xa5,0x40,0x61,0x9f,0x3e,0x60,0xb0,0x32,0x63,0xb8,
- 0x40,0x63,0x90,0x40,0x62,0x9a,0x48,0x62,0x83,0x46,0x63,0x89,0x44,0x61,0xa5,0x49,
- 0x62,0x92,0x50,0x61,0x94,0x40,0x66,0xb0,0x37,0x69,0xb2,0x53,0x63,0x9e,0x3a,0x6a,
- 0xb9,0x50,0x6d,0x85,0x52,0x6e,0x9d,0x58,0x71,0x99,0x58,0x73,0x94,0x54,0x72,0xab,
- 0x5e,0x71,0xa6,0x65,0x7c,0x95,0x61,0x7b,0xac,0x63,0x7d,0xa5,0x6b,0x7a,0xad,0x64,
- 0x7f,0xa1,0x60,0x80,0xbf,0x68,0x7d,0xd4,0x78,0x86,0xbb,0x6f,0x89,0xb9,0x71,0x8a,
- 0xb3,0x73,0x8b,0xae,0x75,0x8d,0xa8,0x82,0x8f,0xc1,0x82,0x95,0xc5,0x7c,0x99,0xb8,
- 0x7c,0x99,0xc4,0x78,0x99,0xd9,0x7c,0x99,0xce,0x88,0x98,0xba,0x8c,0xa7,0xb8,0x8e,
- 0xa4,0xd2,0x8e,0xa6,0xc7,0x9c,0xa5,0xc9,0x96,0xb2,0xe4,0x9a,0xb3,0xcf,0xa4,0xb1,
- 0xd0,0x94,0xb5,0xda,0x9f,0xb4,0xdb,0xa5,0xb3,0xe0,0xa4,0xb4,0xf0,0xa5,0xbf,0xf3,
- 0xb0,0xc1,0xd4,0xb1,0xbf,0xeb,0xb7,0xbe,0xed,0xab,0xc3,0xeb,0xad,0xc4,0xe1,0xb9,
- 0xc7,0xd4,0xb6,0xcd,0xf6,0xbb,0xd0,0xf0,0xc0,0xce,0xfd,0xb8,0xd7,0xed,0xcd,0xd3,
- 0xeb,0xc3,0xd6,0xf0,0xbf,0xd8,0xff,0xc5,0xde,0xfd,0xcd,0xdc,0xfe,0xb7,0xe3,0xff,
- 0xd4,0xe4,0xfe,0xdd,0xe5,0xeb,0xd1,0xeb,0xff,0xdd,0xea,0xff,0xf1,0xed,0xe4,0xcb,
- 0xf6,0xfe,0xf0,0xec,0xff,0xe4,0xf0,0xfe,0xdd,0xf3,0xff,0xeb,0xef,0xff,0xf1,0xef,
- 0xf7,0xe6,0xf3,0xf4,0xf0,0xf2,0xef,0xed,0xf4,0xe9,0xe9,0xf5,0xef,0xf8,0xf1,0xf0,
- 0xf1,0xf5,0xe4,0xef,0xf4,0xf7,0xed,0xf5,0xfe,0xe7,0xf8,0xff,0xff,0xf1,0xfe,0xf5,
- 0xf5,0xff,0xe2,0xfb,0xff,0xfb,0xf4,0xff,0xdf,0xfd,0xfa,0xdb,0xfe,0xff,0xf9,0xf8,
- 0xee,0xf0,0xf9,0xff,0xf9,0xf7,0xfb,0xff,0xf7,0xf0,0xee,0xfb,0xfc,0xf7,0xf9,0xf6,
- 0xff,0xf6,0xfd,0xed,0xfd,0xf0,0xfe,0xf8,0xf6,0xf5,0xfa,0xfd,0xff,0xfa,0xea,0xec,
- 0xff,0xf8,0xea,0xff,0xfe,0xfa,0xfe,0xe6,0xf4,0xfe,0xf9,0xf9,0xfe,0xed,0xfd,0xfb,
- 0xff,0xf7,0xfe,0xf3,0xf1,0xff,0xff,0xff,0xfc,0xfa,0xf9,0xfe,0xff,0xfc,0xfe,0xfb,
- 0xff,0xfe,0xf5,0xff,0xfd,0xff,0xfe,0xff,0xfc,0xff,0xff,0xff,0x21,0xfe,0x11,0x43,
- 0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,
- 0x0,0x21,0xf9,0x4,0x1,0xa,0x0,0xff,0x0,0x2c,0x0,0x0,0x0,0x0,0xab,0x0,
- 0xb7,0x0,0x0,0x8,0xfe,0x0,0xbb,0x78,0x19,0xe8,0x25,0x48,0x97,0x2e,0x63,0xbe,
- 0x28,0x5c,0xc8,0xb0,0xe1,0x98,0x87,0x10,0x23,0x4a,0x9c,0x48,0xb1,0xa2,0x45,0x88,
- 0xd,0x33,0x6a,0xdc,0xc8,0xb1,0x21,0x93,0x8f,0x20,0x43,0x8a,0x64,0x42,0xa4,0xa4,
- 0xc9,0x92,0x39,0x52,0xaa,0x74,0xc1,0xd2,0xc5,0x8c,0x15,0x33,0x5e,0xae,0xe0,0x40,
- 0xb3,0xa6,0x4d,0xf,0x1e,0x32,0xe8,0xd4,0xe9,0x80,0x81,0xc0,0x81,0x41,0xbe,0x1c,
- 0x4c,0xd8,0x91,0xe1,0xc5,0xa3,0x48,0x93,0x5e,0x2c,0xca,0x94,0xe3,0xc8,0xa7,0x20,
- 0x4f,0x9e,0x1c,0x32,0x44,0x65,0xe,0x96,0x29,0x63,0x6a,0x9d,0x61,0xb3,0x2b,0x4d,
- 0x9c,0x3b,0x4b,0x58,0x80,0x40,0x30,0x4a,0xd0,0x83,0x4d,0x17,0x2a,0x5d,0xcb,0xf6,
- 0x68,0xda,0xb7,0xb,0xa1,0x42,0x95,0x6a,0x92,0x6a,0xd5,0x94,0x58,0x73,0xe8,0x98,
- 0xa1,0x63,0xef,0xc,0x13,0x26,0xbc,0xde,0x4,0x6b,0x1,0x84,0x87,0xb2,0x6,0xd1,
- 0xbe,0x6d,0xcb,0xb8,0xf1,0x43,0xb8,0x70,0xe5,0x3e,0xa5,0x5b,0xf2,0x88,0x5d,0xab,
- 0x29,0xfb,0x6a,0xfe,0xb,0x58,0x70,0x4d,0x9c,0x1e,0x20,0x80,0xc8,0x50,0xf6,0x8b,
- 0x15,0x2e,0x59,0xe0,0x3a,0x5e,0x4d,0x51,0x8d,0xeb,0xd7,0xae,0x21,0xbf,0x95,0x3c,
- 0x92,0x32,0x91,0x23,0x96,0xa9,0x62,0xd6,0xac,0x19,0x70,0x67,0xcf,0x1c,0x70,0x1a,
- 0x26,0x3d,0x30,0x8a,0xe9,0x2c,0xa9,0x17,0xb3,0x5e,0xfe,0x10,0x36,0x6c,0xd9,0x69,
- 0x69,0x8b,0xb4,0x8d,0x3b,0xf7,0x6e,0xde,0x3a,0x7c,0x7,0x6,0x2e,0xbc,0x4,0x87,
- 0x33,0x67,0xbc,0xfe,0x3c,0xb4,0x92,0xc5,0xca,0x46,0xe6,0xe8,0xd3,0x4b,0x3c,0x4f,
- 0x71,0x63,0x6d,0x22,0x50,0xed,0x5e,0x56,0x89,0x3d,0xbb,0x76,0xee,0xa0,0x3f,0x84,
- 0xf,0xf3,0xd8,0x8a,0x7f,0x8d,0xea,0x5,0x88,0x1e,0x7b,0x13,0x6d,0xd4,0x45,0x6d,
- 0xf1,0xc9,0x77,0x57,0x66,0xd8,0x69,0xb7,0x9d,0x60,0xa0,0x79,0xf0,0x81,0x17,0xfc,
- 0x99,0xe6,0xdf,0x7f,0x19,0x9,0xa8,0xe1,0x6a,0x4,0xae,0xa7,0xd1,0x41,0xd2,0x7d,
- 0xa4,0xe0,0x82,0x7a,0x35,0xe8,0xa0,0x67,0x11,0x76,0xf0,0x98,0x85,0xfe,0x6d,0xe8,
- 0xe2,0x80,0x0,0xb6,0xf7,0x21,0x88,0xd2,0x8d,0x68,0x55,0x7d,0x36,0x38,0xf8,0xe0,
- 0x60,0x1d,0xf4,0xa8,0x10,0x86,0xa,0xbd,0x28,0x24,0x87,0x31,0x16,0x38,0x23,0x8d,
- 0x92,0xd9,0x48,0x1f,0x76,0x36,0x34,0x79,0x62,0x57,0x1e,0x74,0xf0,0xc1,0x7,0x19,
- 0x5c,0x68,0x9e,0x15,0x43,0x66,0xd9,0x58,0x87,0x11,0x19,0x78,0x10,0x92,0x9,0xca,
- 0x77,0x23,0x93,0x4d,0xe6,0xe8,0x9b,0x57,0x51,0x4e,0x99,0x41,0x79,0x17,0x8e,0xc1,
- 0x9f,0x73,0xaf,0x69,0x29,0xa7,0x87,0x19,0xca,0x98,0xd1,0x97,0x5f,0x26,0xa9,0xe0,
- 0x98,0xbc,0x95,0x69,0xe6,0x6f,0x37,0x7d,0xc0,0x2,0xb,0x55,0x5a,0x9,0x11,0x9c,
- 0xae,0x31,0x67,0xe5,0x85,0xb0,0x85,0xe1,0xe8,0xa3,0x88,0x46,0x3a,0x86,0xa1,0x10,
- 0x61,0xe9,0x5c,0x45,0x5c,0x62,0xa4,0x11,0x41,0x78,0xca,0xb5,0xe7,0x8d,0x7a,0x69,
- 0x85,0x5d,0x4c,0x3b,0x7e,0x35,0x25,0x95,0x6d,0x3a,0x16,0x29,0xa2,0x65,0xc0,0x61,
- 0x86,0x19,0xfe,0x65,0xc4,0x2a,0xc7,0xa3,0x61,0xb0,0x61,0x6b,0x1c,0xb6,0x82,0xa7,
- 0xeb,0xae,0xbc,0x86,0xd1,0x2a,0x1c,0xc0,0xc6,0x5a,0xc6,0x6b,0xb4,0x86,0xa1,0xc6,
- 0x5a,0x6f,0x45,0x31,0x50,0x13,0x5e,0x1c,0x84,0xdc,0xb3,0x59,0x7c,0x54,0x59,0x75,
- 0x47,0x34,0x61,0xad,0xb5,0x96,0x59,0x15,0xd3,0xa,0xdc,0x76,0xeb,0x6d,0x4d,0xa7,
- 0x96,0xc0,0xdc,0xaa,0x70,0xc6,0xa,0xab,0xb0,0xb3,0x3e,0x6a,0xeb,0xba,0x67,0x14,
- 0xeb,0xee,0xa3,0x72,0x58,0x1,0xac,0x19,0xc1,0x96,0xe1,0x9f,0x6b,0xb4,0x1e,0xab,
- 0x54,0xb2,0xcb,0x36,0xdb,0x5,0xb4,0xc8,0x49,0xb,0x1f,0x13,0xd4,0x5e,0xdb,0x44,
- 0x6e,0x43,0xdc,0x70,0x43,0x4b,0x2d,0x79,0xcb,0xad,0x60,0xe3,0x92,0x2b,0xb1,0x1a,
- 0x72,0x54,0x6c,0xb1,0xc5,0x70,0xac,0xa1,0xf1,0xc6,0x1c,0x73,0x4c,0xaf,0x7f,0x70,
- 0xc8,0x6b,0x85,0xbd,0x58,0x12,0xd9,0x94,0xb2,0x9c,0xfe,0xb,0x2d,0x48,0x54,0x95,
- 0x24,0x5,0x11,0x52,0x8c,0x94,0xc4,0xcc,0xa,0x33,0xcc,0x92,0xc3,0x33,0x79,0x15,
- 0xf1,0xc4,0xae,0xf1,0x8a,0xe8,0x85,0x19,0x77,0x2c,0x34,0xc7,0x21,0xab,0xb1,0xe8,
- 0xd1,0x2d,0x22,0x9b,0x96,0xb2,0xcc,0xfa,0xfb,0xaf,0x48,0xb9,0x9d,0xf4,0x72,0xcc,
- 0x53,0x27,0x71,0x12,0x5e,0xd,0x3b,0xc,0xf1,0x72,0x3c,0xe3,0xeb,0x45,0x78,0xe0,
- 0x1d,0x2a,0x2f,0xb0,0x1a,0xc3,0x41,0x71,0x18,0xb3,0xa6,0x8d,0xf6,0xda,0x69,0xcb,
- 0xe1,0x1c,0xc8,0x70,0x0,0xc,0x7,0x5b,0xfc,0xa6,0x8c,0x64,0x75,0x2d,0x4b,0x65,
- 0xf5,0xfe,0xde,0x52,0xad,0x74,0xb3,0xd6,0x3a,0x73,0xdd,0x75,0x18,0x5f,0x83,0x27,
- 0x9e,0x14,0x63,0x18,0xd,0x6c,0xc6,0xc0,0x3a,0xda,0xee,0xe3,0x61,0x40,0xe,0x39,
- 0xad,0x15,0x1b,0x3d,0x36,0xb4,0x73,0x2b,0x9d,0x56,0x10,0x76,0x1f,0xc8,0xc4,0xc1,
- 0xb8,0xd9,0x30,0xc4,0x11,0x52,0x94,0x6e,0xfa,0xcc,0x49,0x48,0x81,0xfa,0xd,0x39,
- 0x24,0xe1,0xb7,0x4c,0xdd,0x6e,0xcd,0x5a,0xd7,0x14,0xeb,0x7a,0xec,0xed,0x6f,0xab,
- 0x21,0xac,0xee,0xbc,0xf,0xeb,0x7b,0xef,0x91,0x53,0xee,0xf6,0x78,0x63,0x87,0xac,
- 0x39,0x74,0x2,0x61,0xb,0x5,0x14,0x7e,0xe2,0x36,0xa2,0x6e,0x39,0x2c,0xe8,0x3a,
- 0x5e,0xdb,0xc6,0x1e,0xf8,0xec,0xb4,0xc3,0x76,0xb1,0xc5,0x94,0xb,0xeb,0xfd,0xf7,
- 0xde,0xbf,0xeb,0x76,0xc9,0x94,0xee,0xb,0x9d,0x42,0xcb,0x36,0xb1,0x3c,0xf3,0x7e,
- 0x5e,0xd1,0x24,0xf3,0x43,0xbc,0xef,0xa7,0xd,0x3a,0x4c,0x7f,0x55,0xf5,0xf,0x5f,
- 0x9f,0x54,0xf6,0xac,0xc2,0x21,0x8,0xb0,0x56,0xa0,0x3,0x21,0xe8,0x50,0x8,0x37,
- 0xb8,0x61,0x5d,0x71,0xe0,0x81,0xaf,0xe8,0xc0,0xc0,0x58,0x5,0x90,0xe,0x8b,0x4a,
- 0x97,0xbb,0xa,0xc1,0xc0,0x2b,0x95,0x21,0x5e,0xcb,0xd9,0x88,0x7f,0xe,0x12,0x4,
- 0xce,0x79,0xc1,0x5a,0x4,0x39,0x82,0xe,0x6c,0x70,0x85,0x2a,0x5c,0xe1,0x84,0x36,
- 0xa0,0x49,0x1c,0x52,0x68,0x82,0x32,0x5d,0x21,0x7,0x52,0x60,0x49,0xe9,0xb8,0x55,
- 0x3d,0xd9,0xed,0x8f,0x7f,0xce,0x29,0xc3,0x13,0x9e,0x20,0x88,0x1e,0x6e,0x30,0x8,
- 0xfe,0x6e,0x28,0x4,0x1b,0x6c,0x0,0x84,0x2b,0xb0,0x61,0xf,0x95,0x1b,0x3,0x88,
- 0x2c,0xa6,0xc4,0x2f,0xc9,0xc1,0x7b,0xc,0x84,0xa0,0x15,0xe4,0xa0,0x85,0x2a,0x76,
- 0x50,0x5f,0x26,0x6b,0xc8,0x6,0xbb,0xd0,0x41,0x82,0x84,0x27,0x7,0x47,0x90,0x83,
- 0x14,0x36,0x80,0xc2,0xf7,0x7d,0x6d,0x42,0x50,0xc8,0x80,0x7,0xae,0x10,0x87,0x12,
- 0xd4,0xf,0x2b,0x2e,0xf8,0xc0,0x11,0x6a,0xa8,0x3f,0xa4,0xe0,0x30,0x87,0x82,0x48,
- 0xc3,0x13,0xcc,0xd0,0xc3,0x28,0x76,0x1,0x8c,0x67,0xd8,0x3,0x1b,0xae,0xa0,0x3,
- 0x2f,0xec,0xa1,0x10,0x88,0xdc,0xc3,0x19,0x98,0x15,0x48,0x44,0x16,0x42,0x11,0x59,
- 0xd0,0x98,0x1e,0xf4,0x40,0x2f,0x38,0x8,0x90,0xe,0x61,0xe8,0xa0,0x16,0x8,0x81,
- 0x45,0xc7,0x68,0xd0,0x3c,0xb,0xe9,0xa0,0x1b,0xbc,0x10,0xb3,0x1b,0x84,0x80,0x8,
- 0x72,0x70,0x41,0xe,0x48,0x29,0x5,0x2e,0x70,0xa1,0x8,0xaf,0xbc,0x81,0x18,0x37,
- 0xe0,0x82,0x3d,0xac,0x80,0x96,0x78,0x59,0x81,0x5f,0xf2,0xd7,0x15,0xb6,0xdc,0x11,
- 0x36,0x65,0x10,0x84,0x19,0xf6,0xf8,0xaa,0x2c,0xd4,0x20,0xb,0x8b,0x23,0x49,0x17,
- 0xe0,0xe0,0x7,0x31,0xc8,0x40,0x6,0x13,0x90,0x81,0x11,0xc4,0xe0,0x87,0x6a,0x8a,
- 0xc1,0x8,0xd0,0xa4,0x80,0x12,0x7a,0x50,0x87,0x3a,0xcc,0x81,0xc,0x5b,0xd8,0x81,
- 0x1e,0x42,0xc6,0x40,0x2d,0x84,0x21,0xa,0x9d,0xdc,0x52,0x46,0x2e,0xc4,0x90,0xe,
- 0x9e,0x21,0x75,0x7c,0x18,0x44,0xdc,0x8e,0x99,0x5,0x23,0xa4,0x60,0x2,0x18,0xfe,
- 0xa0,0x81,0xf,0xf4,0x89,0x81,0x9,0x4c,0xc0,0x8,0x59,0xe0,0x82,0xea,0xae,0xa2,
- 0xca,0x1c,0x68,0x85,0x97,0x36,0xf1,0xe5,0x2f,0x5d,0x53,0x6,0x21,0x94,0x81,0xe,
- 0x65,0xc8,0x82,0x19,0x26,0xb9,0x86,0x40,0x4,0x62,0x9,0x2d,0x68,0xc1,0x1b,0x22,
- 0xa1,0x9,0x54,0xd4,0x62,0x18,0xcf,0xa0,0xc6,0x37,0xa8,0x21,0xf,0x79,0x88,0x83,
- 0x1a,0xcf,0x48,0xc6,0x30,0x86,0xb1,0x8a,0x53,0x64,0x22,0xf,0x48,0x40,0x2,0x37,
- 0x95,0xb0,0x6,0x44,0xc0,0xa1,0x6,0x44,0xa0,0x83,0x25,0x4a,0x96,0xc5,0x85,0x58,
- 0x29,0x94,0x6,0x91,0x3,0x1f,0x6a,0x90,0x2,0x23,0x90,0x81,0xc,0x4b,0xb8,0x0,
- 0xa,0x22,0xa1,0x8a,0x5e,0x28,0x83,0x19,0xf8,0x98,0xc6,0x33,0x98,0x91,0xb,0x4c,
- 0x5c,0x80,0x2,0x2,0x2d,0xdd,0x7,0x5c,0xd0,0x84,0x5d,0xe6,0xac,0x97,0x6b,0x59,
- 0xa8,0x6b,0xe4,0xe0,0x6,0x47,0x95,0x61,0x10,0x7a,0x58,0xc3,0x36,0x51,0x80,0x84,
- 0x47,0x98,0xe2,0x16,0xc9,0xf8,0x6,0x3e,0xf4,0x41,0x57,0x7c,0xd8,0xf5,0x1d,0x78,
- 0xb5,0xeb,0x5d,0xe5,0x6a,0xd7,0x6f,0x24,0x43,0x16,0x9f,0x60,0x44,0xf,0x7a,0x40,
- 0x86,0x35,0xc8,0xf3,0xb,0x4c,0x60,0x8e,0x46,0x16,0xa5,0x90,0xa0,0xa8,0x41,0x5,
- 0x45,0xa8,0xa8,0x12,0x48,0x0,0x86,0x4c,0xd4,0x82,0x1a,0x76,0xf5,0xc6,0x3b,0xf4,
- 0x11,0x8e,0x77,0x54,0xe3,0x19,0x76,0x1d,0x6,0x26,0x44,0xf0,0x1,0x29,0x0,0x22,
- 0x8e,0x2f,0xa1,0x23,0x58,0x95,0x22,0x56,0x35,0xd4,0xa,0xb,0x7b,0x50,0xfe,0x4,
- 0x21,0x88,0xba,0x4,0x4c,0xb0,0x22,0x19,0xf2,0xd0,0xab,0x3e,0xba,0x81,0xe,0x74,
- 0xd8,0xe3,0xb7,0xbd,0xfd,0xad,0x70,0xfd,0x41,0xdc,0x73,0x6c,0x56,0x1f,0x76,0x35,
- 0xa9,0x30,0x5c,0xd1,0x88,0xa2,0xe,0x62,0x10,0x3c,0xed,0xe9,0x8f,0x7e,0xba,0x10,
- 0x39,0x30,0x73,0xd,0x24,0xe8,0x81,0x2b,0x9c,0x61,0xd7,0x73,0x78,0x83,0xb7,0xee,
- 0x8,0x6f,0x3e,0xf4,0x81,0xd7,0x73,0xe0,0x43,0x1e,0xa2,0x18,0x63,0xe9,0x36,0x30,
- 0x25,0xd5,0x26,0x34,0xac,0xac,0xda,0x1d,0xc5,0xb6,0xf7,0x1a,0x39,0xec,0x41,0x3c,
- 0x70,0x48,0x41,0xb,0x4a,0x21,0xc,0xbd,0xaa,0xc3,0x1b,0xea,0x98,0x2b,0x71,0xc3,
- 0x1b,0x5e,0x7b,0x10,0xf8,0xc0,0xc4,0xa5,0x6b,0x79,0xbd,0xf1,0x8d,0x6f,0x88,0x43,
- 0x1e,0xe4,0x20,0x86,0x28,0xec,0x9,0xdd,0xc,0xae,0x13,0x94,0xa,0x71,0x96,0x11,
- 0x76,0xa0,0x1,0x30,0xc4,0x82,0xa4,0xd,0x9e,0xab,0x3e,0x8,0xec,0xf,0x7e,0xa4,
- 0x23,0x1d,0xc4,0x55,0xc7,0x35,0xbe,0x21,0x8f,0x56,0x88,0xa0,0x8,0x49,0xf8,0x80,
- 0xe,0xae,0x0,0x18,0x9c,0xe5,0xac,0x22,0xb4,0xfb,0x15,0xbd,0x2e,0xe8,0xa8,0x2,
- 0x46,0x81,0x82,0x1,0xbc,0x20,0x1f,0x68,0x60,0x87,0x55,0x4c,0x43,0x1f,0xe7,0x10,
- 0xae,0x3d,0xf4,0xe1,0xf,0x7a,0xd0,0x23,0xc0,0x78,0x55,0x32,0x3b,0xa6,0xfc,0xdb,
- 0x75,0xac,0x83,0xae,0x75,0xd5,0xab,0x49,0xa9,0x51,0xe,0x72,0x94,0xc3,0x15,0x84,
- 0x35,0x1b,0x9c,0xe8,0xf6,0xa1,0x30,0xb8,0x21,0x25,0x84,0x10,0x41,0xfe,0x23,0x90,
- 0x90,0x7,0x54,0x40,0xd5,0xb3,0xe8,0xc0,0x7,0x3d,0xc8,0xfb,0x5b,0x76,0x18,0x38,
- 0x1d,0xe6,0xe0,0x7,0x3f,0xe8,0xa1,0x8d,0x6,0xcb,0xc3,0x13,0x3e,0xb8,0x81,0xe,
- 0xe2,0x70,0x80,0x17,0x0,0xc1,0x6,0x2e,0x50,0x98,0xc2,0x56,0x50,0x2,0x71,0xb5,
- 0xa6,0x6b,0xad,0x7a,0x15,0x8f,0x1d,0xf5,0x81,0x1f,0x77,0x81,0x10,0x82,0xa8,0x1,
- 0x22,0x44,0x40,0x6,0x56,0x70,0xf7,0x1a,0xd8,0xe0,0x87,0x3b,0xd0,0x61,0x67,0x7b,
- 0xf8,0xe3,0x1e,0xf4,0x10,0xb1,0x3f,0xc,0x4c,0x65,0x7b,0xa0,0x23,0x1c,0x9d,0xed,
- 0x2b,0x33,0x7a,0x11,0xb,0x53,0x64,0x2,0x13,0x91,0xf8,0xc3,0x1f,0x1a,0xb1,0x9,
- 0x51,0x4,0x82,0x4,0x6b,0x10,0xf3,0xa5,0x8e,0xa7,0x16,0x20,0x82,0x31,0xc,0x44,
- 0xd0,0x83,0x1,0xf2,0x50,0x8b,0xb9,0x86,0xc3,0x1a,0x76,0x76,0x32,0x9d,0xed,0x31,
- 0xe5,0x6d,0xb8,0x43,0xcf,0x4d,0xee,0x2b,0x3e,0x90,0x81,0x4,0xd2,0x42,0xe0,0x5,
- 0x2f,0x68,0x52,0xa2,0x15,0xfd,0x81,0x46,0xe3,0x18,0xd2,0x92,0x2e,0x3,0xad,0xa,
- 0x41,0x8,0x22,0xa0,0xd5,0x8,0x81,0xd0,0x80,0x2b,0x70,0xfb,0x8d,0x6b,0x94,0x18,
- 0x1a,0xee,0xa0,0x76,0xa9,0x89,0xeb,0x6a,0xdf,0xfa,0xc3,0x1d,0xc4,0xbd,0x32,0x72,
- 0xf1,0x41,0xd,0x5c,0x98,0xe2,0xf,0xfb,0xa4,0x0,0x5,0x68,0xf0,0x86,0x66,0xfa,
- 0x21,0xb,0x45,0x18,0x4,0x1f,0xe2,0x29,0x29,0x62,0x7,0xc9,0xb,0xd5,0xa,0xc3,
- 0xd,0xe0,0x40,0x2,0x46,0xc,0x43,0xae,0xef,0xf0,0xad,0x81,0xfe,0x4b,0xbc,0x8f,
- 0x3a,0xb3,0x3,0x1d,0xd7,0xe6,0xc7,0x3a,0xb0,0xd1,0x8d,0x73,0xa8,0x43,0xa4,0xf2,
- 0x70,0x85,0x8,0xf6,0x50,0x82,0x29,0x34,0x69,0x6,0x2c,0x21,0xb7,0xb9,0x1f,0xcd,
- 0xb3,0x5f,0xc5,0xca,0xcc,0x3d,0xb6,0xc2,0x20,0xc4,0x30,0x87,0x1e,0xfc,0x41,0x18,
- 0x25,0xb5,0x2b,0x3d,0xb2,0x71,0x8f,0x7f,0x2b,0xf9,0xe9,0xbf,0x5,0xb8,0x3f,0xf0,
- 0x11,0x60,0x6a,0x0,0xe3,0x13,0x60,0x50,0x82,0x1e,0xc4,0x20,0x6,0x2e,0x4c,0x9c,
- 0xf,0xc3,0xab,0xd8,0x7,0x1d,0x95,0x3,0xb7,0x8d,0xd9,0xe2,0x5f,0x18,0x43,0x13,
- 0x72,0xe0,0x86,0x2f,0x14,0x41,0xc,0x91,0x40,0x6,0xd5,0xcf,0xc1,0x64,0x7f,0xa0,
- 0x63,0x1b,0xd8,0xce,0x77,0xd4,0xb7,0x41,0x5c,0x7f,0x60,0x59,0x1d,0xf2,0x70,0x46,
- 0x29,0xde,0xf0,0x0,0x2f,0x44,0xc0,0x7d,0x3a,0x68,0xc9,0xd,0xb8,0x55,0x6e,0x47,
- 0x4f,0x24,0x7b,0x3f,0x37,0xb3,0x1,0xc3,0xc0,0x4,0x4a,0x90,0xa1,0xe,0x60,0x30,
- 0x5,0x66,0xa9,0xae,0xe,0x27,0xdf,0xe3,0x1e,0xda,0xd0,0x7,0xd4,0x9f,0x8e,0xe,
- 0xe4,0x9a,0xb4,0x16,0x8f,0x40,0xc1,0x1c,0x10,0x41,0x7,0x15,0x54,0x4c,0x89,0x1f,
- 0x4,0x61,0xe1,0x78,0x50,0x88,0x45,0xb8,0xc1,0xec,0xc3,0x36,0x5f,0x43,0xc2,0x60,
- 0x2,0x36,0x9c,0x81,0x8,0x46,0x78,0xc3,0x2f,0xf0,0xf1,0xc,0xba,0xaf,0x1a,0x1b,
- 0xd8,0x58,0x87,0x9e,0xd3,0xa1,0xf7,0x91,0xfb,0xe3,0x1d,0xc6,0x7d,0xc7,0x33,0x90,
- 0x91,0x89,0x16,0x50,0xa0,0x8,0x63,0x58,0xc1,0x22,0x3e,0xfe,0x90,0x92,0x9a,0x31,
- 0xba,0xd1,0x3b,0x7f,0x7c,0x8e,0x2b,0x26,0x79,0x2d,0x4,0x73,0xd,0x3d,0x68,0x3,
- 0x2e,0xe6,0xba,0x59,0xcf,0xd7,0xa3,0x1e,0xa8,0x16,0xfd,0xd3,0xd9,0xe1,0x8e,0x6d,
- 0x6c,0x63,0xc9,0xf8,0x60,0xc6,0x2d,0x70,0xd0,0x83,0x39,0xac,0xa1,0x6,0x2a,0x70,
- 0x69,0xb7,0x67,0x40,0x4,0x58,0x56,0x3d,0x26,0x79,0x68,0x83,0x28,0x64,0xb6,0x7b,
- 0x3c,0x40,0x4a,0x62,0x40,0x3,0xc3,0xb7,0x59,0xae,0xb6,0xd,0x56,0x46,0x5c,0xcb,
- 0xd7,0x7c,0x9b,0xf5,0xe,0x0,0xf6,0xd,0xc2,0x0,0xa,0x6,0x40,0x1,0x46,0x0,
- 0x7,0x44,0x30,0x4,0x53,0x82,0x6c,0x26,0xe1,0x2,0x2b,0x0,0x2,0x20,0x0,0x7e,
- 0xe7,0xd6,0x35,0x12,0x14,0x6,0x10,0x65,0x6,0x87,0xa0,0x1,0x98,0x90,0xc,0xf8,
- 0x50,0xd,0xa2,0xa7,0x7c,0xfc,0xf0,0x79,0xa8,0xe6,0x77,0xf2,0xa7,0x64,0x27,0xb6,
- 0x64,0xcf,0x80,0xb,0x9e,0x30,0x1,0x83,0x0,0x41,0xbe,0x52,0x6,0xb0,0x62,0x5,
- 0x66,0xc0,0x40,0x82,0xd0,0x40,0xae,0xc2,0x47,0x52,0x8,0x7,0xc3,0x72,0x76,0xba,
- 0xc7,0x10,0xb5,0x92,0x3,0x4c,0xf0,0x6,0xa0,0x30,0x57,0xd6,0x60,0x60,0x52,0x57,
- 0x81,0x7a,0x56,0x60,0x79,0x35,0xd,0x54,0x7,0xc,0x91,0x50,0x0,0x13,0x0,0x9,
- 0xb1,0xa4,0x6,0x1f,0x50,0x8,0x41,0xa0,0x2,0x44,0x50,0x4,0x44,0xb0,0x30,0x25,
- 0x30,0x2,0x23,0xc0,0x82,0x3c,0x37,0x31,0xea,0x86,0x36,0x15,0xa3,0x84,0xd8,0x55,
- 0xa,0xdc,0x75,0xe,0xe8,0xe0,0xf,0xe9,0xc0,0xf,0xfe,0xe6,0x90,0x67,0xfc,0xd0,
- 0x64,0x73,0x86,0x65,0xc2,0x25,0x75,0xfa,0xf0,0xc,0xa6,0xb0,0x4,0x45,0x70,0x6,
- 0x46,0xc4,0x6,0x8e,0x42,0x7,0xaf,0x92,0x47,0xaf,0xb2,0x43,0xaf,0x92,0x6,0x87,
- 0xa0,0x31,0x3b,0x90,0x6,0x69,0xa0,0x7,0x55,0x98,0x7b,0x49,0x1,0x20,0x8a,0x54,
- 0x4,0x2d,0x40,0xd,0x38,0x8,0x86,0xe1,0xb5,0xe,0xc4,0x45,0xf,0xfe,0x50,0x72,
- 0x79,0x75,0x5e,0xe2,0x80,0x7a,0x15,0xd0,0x2,0x7e,0xc0,0x5,0x2c,0x70,0x3,0x6e,
- 0x70,0x4,0x2e,0xe0,0x5,0xf,0x10,0x4,0x44,0x50,0x3,0x35,0x40,0x87,0x33,0x70,
- 0x87,0x79,0x18,0x7e,0x12,0x91,0x63,0x61,0x60,0x9,0xa6,0x41,0x8,0x4f,0x90,0x6,
- 0x24,0xc0,0xa,0x98,0xa5,0x59,0x29,0xc7,0x7c,0x52,0xe7,0x83,0x4d,0xd6,0x77,0xfb,
- 0xe0,0xe,0xeb,0x60,0x57,0xbc,0x90,0x7,0x2d,0x20,0x6,0x61,0x10,0x7,0x55,0xb0,
- 0x8e,0x98,0x8,0x88,0x6b,0x60,0x6,0x6b,0x90,0x6,0xf1,0x48,0x8a,0xf4,0x98,0x6,
- 0x73,0x70,0x8f,0xc1,0x46,0x3b,0xe7,0xa6,0x29,0x63,0xe0,0x5,0x5f,0x60,0x4,0xb4,
- 0x80,0xf,0xde,0x80,0x72,0x7,0x6,0x70,0x4e,0x46,0xf,0xfb,0x30,0x70,0xf2,0x40,
- 0xd,0xab,0xf0,0x3,0xfc,0xa7,0x4,0x35,0x20,0x5,0x65,0xc2,0x3,0x65,0x92,0x3,
- 0x41,0x20,0x4,0xc8,0x88,0x53,0xcb,0x88,0x87,0x7a,0x28,0x7e,0x3d,0x27,0x7,0x2,
- 0x4,0x7,0x3b,0x40,0x6,0x3d,0xe0,0x69,0xf2,0xe0,0xd,0xde,0x50,0x62,0x87,0x58,
- 0x60,0xbf,0x85,0x65,0x4e,0x96,0xd,0x4d,0x66,0xfe,0x65,0xfa,0x20,0xf,0xb2,0x80,
- 0x3,0x38,0xd0,0x8,0x82,0x50,0x2b,0x6c,0x50,0x5,0xb6,0xe2,0x2b,0xf3,0x12,0x85,
- 0xaf,0xf2,0x2a,0x43,0x43,0x2f,0xfa,0xf8,0x68,0xfc,0x48,0x4,0x70,0x50,0x7,0x50,
- 0xd5,0xd,0x86,0xc8,0x8d,0xe1,0xc5,0x88,0xf4,0xd0,0xd,0xde,0x80,0xf,0xc9,0xc0,
- 0xa,0x6d,0x50,0x1,0x3d,0xa0,0x4,0x5b,0x10,0x2d,0x3c,0x0,0x6e,0x36,0x40,0x91,
- 0x4d,0x62,0x91,0xc7,0x88,0x8c,0x44,0xb0,0x91,0xcd,0xe8,0x78,0xcf,0x8,0x69,0x56,
- 0xc0,0x4,0x70,0x80,0x8,0x64,0xd0,0x2,0xd8,0x98,0x59,0x4c,0x76,0x62,0xa2,0xf6,
- 0x74,0x74,0x45,0xf,0x3c,0xf8,0x64,0x91,0xc8,0xa,0x73,0xa0,0x4,0x87,0xb0,0x5,
- 0x35,0x20,0x40,0xe6,0xe4,0x28,0xc3,0x33,0x5f,0x95,0x3,0x27,0x8c,0x62,0x5,0xd9,
- 0xb3,0x8f,0x2b,0xf2,0x5,0x5c,0x60,0x4,0xac,0x40,0x75,0xca,0x77,0x62,0xee,0x60,
- 0x67,0x6,0x49,0x8b,0xfa,0xf0,0xd,0x9d,0x0,0x53,0x4a,0x90,0x2,0xcf,0xf2,0x39,
- 0x57,0xe0,0x95,0xf3,0x93,0x3,0x73,0x48,0x96,0x2e,0xc0,0x8c,0x1d,0x99,0x96,0x5d,
- 0x43,0x1e,0x5b,0x30,0x7,0x8c,0x10,0xa,0x98,0x35,0xd,0xe7,0x30,0x60,0xd8,0xc0,
- 0x8d,0x50,0x47,0x5c,0xd9,0xe0,0x64,0x7d,0x75,0xa,0x29,0x20,0x4,0x94,0x40,0x9,
- 0x35,0xf0,0x4,0xc0,0x19,0x2c,0xae,0xc5,0x2b,0xe0,0xe1,0x2e,0xc6,0x89,0x7b,0x13,
- 0xc3,0x98,0x44,0x91,0x5,0x7e,0xa0,0x1,0xcc,0x90,0x5b,0xf7,0x50,0xf,0x75,0xb9,
- 0x6f,0x9f,0x47,0xf,0xd7,0x80,0xf,0x97,0xfe,0x80,0x4,0x24,0xe0,0x7,0x1f,0xd1,
- 0x41,0x41,0xd0,0x4,0x3c,0xe0,0x3e,0x3c,0x10,0x3f,0x65,0xa2,0x3,0x37,0x30,0x87,
- 0x74,0x78,0x9a,0x1c,0xe9,0x8c,0x11,0x91,0x63,0x6d,0x79,0x79,0x99,0x20,0xe,0xf8,
- 0x40,0x77,0xfb,0xe0,0xf,0x2b,0x17,0x70,0xfc,0xa6,0x64,0xb3,0x38,0x67,0x66,0xf8,
- 0xa,0x60,0xf0,0x4,0x10,0x15,0x40,0xc2,0x84,0x4c,0xc4,0x19,0x39,0xc7,0x49,0x2b,
- 0xba,0x12,0x3c,0x8e,0x93,0x80,0x5d,0xc3,0x9c,0xa,0x91,0x5,0x34,0x80,0x9,0xb,
- 0xa9,0xf,0xd3,0x59,0x9d,0xbf,0x55,0x62,0xf7,0xc0,0xf,0xd8,0xe0,0xd,0xc0,0x80,
- 0x4,0x62,0x70,0x3,0x7b,0xc0,0x3,0x24,0x8a,0x2d,0x96,0x31,0x33,0x7a,0x51,0x26,
- 0x33,0x90,0x9e,0x45,0xb0,0x30,0x26,0x50,0x2,0x2f,0x90,0x9a,0xef,0x9,0x69,0x82,
- 0xb0,0x3,0x75,0xd0,0x6,0xce,0xf0,0xd,0xfa,0x50,0x88,0xe6,0x80,0x67,0x2,0xa7,
- 0xf,0xf4,0xb0,0x88,0x4a,0x26,0x8e,0xd9,0xa6,0xe,0xbf,0x0,0x6,0x21,0x28,0x8,
- 0xfe,0x1,0x41,0xee,0x66,0x39,0xdf,0x33,0x5f,0x14,0x63,0x98,0x17,0x3,0x2f,0x45,
- 0x29,0x7e,0x9a,0x92,0x5,0x1a,0x80,0xb,0xb9,0x45,0xf,0xf0,0x67,0xe,0xcd,0xf7,
- 0x5b,0xfc,0x50,0xf,0xdc,0xe0,0x77,0xdf,0x80,0x9,0x7e,0xb0,0x2,0x24,0x74,0x5,
- 0x3c,0x70,0x30,0xaa,0x63,0x12,0x29,0xa,0x4,0x40,0x80,0x73,0x8a,0x86,0x82,0xe0,
- 0xe7,0x9e,0x87,0x2,0x69,0xd5,0xd8,0x3,0xc8,0x20,0xf,0xfa,0x60,0xd,0x88,0x8,
- 0xd,0x26,0xe6,0x77,0xe6,0xf5,0x79,0xfe,0x42,0xa,0x86,0xb2,0xa8,0xf,0xd3,0xf0,
- 0xd,0x91,0x20,0x3,0x19,0x73,0x8,0x4f,0x90,0x5,0x4,0x74,0x6,0x50,0x70,0x7,
- 0xed,0xf2,0x44,0x66,0x40,0x8a,0x42,0x13,0x94,0x9a,0xea,0x3d,0x55,0x9a,0x96,0x57,
- 0xfa,0x7,0xcf,0x20,0x57,0x5c,0xfa,0x79,0xc2,0x55,0x6a,0x61,0x4a,0x9d,0x48,0x96,
- 0xb,0x13,0xb0,0x2,0x71,0xf0,0x2,0x26,0x34,0x4,0x49,0x50,0x4,0xb2,0x9a,0x8c,
- 0x49,0xa0,0x3,0x40,0x10,0x3,0xb8,0xba,0xa2,0x8a,0xb6,0x2,0x2f,0x2a,0xa3,0x77,
- 0xfa,0x1a,0xb1,0x12,0x29,0x70,0x10,0x6f,0xb7,0x40,0x9f,0x29,0x99,0xe,0xf0,0x0,
- 0xf,0x26,0x76,0x65,0x9b,0x75,0x9d,0xab,0x6,0x86,0xe9,0x90,0x90,0xf8,0x20,0xc,
- 0x14,0x30,0x9,0x72,0x70,0x8,0x73,0x90,0x6,0x66,0xa0,0x98,0x8a,0x44,0xa9,0x68,
- 0xa3,0x84,0x98,0x3a,0x94,0xef,0xa8,0xa9,0xb0,0x92,0x3d,0xd1,0xf5,0x10,0x95,0x83,
- 0x25,0xfe,0x21,0x6,0x9e,0xa0,0x57,0xed,0x0,0x7f,0xfc,0x0,0x75,0xfc,0x0,0xf,
- 0xf3,0x0,0xf,0x64,0xfa,0x6,0x52,0x0,0x4,0xe0,0x6,0x4,0x3a,0x20,0xab,0x46,
- 0x60,0x4,0xb2,0x2a,0x68,0x44,0x4,0xa7,0xe8,0xe9,0x7d,0xbc,0xa,0x7e,0x91,0xf2,
- 0x3d,0x21,0x43,0x1e,0xc0,0xc2,0x26,0x56,0xb0,0x5,0x48,0x10,0xa,0xdf,0x60,0x5c,
- 0x4c,0xa6,0x83,0x63,0xa8,0x77,0x7a,0xf6,0x83,0x6,0x96,0x67,0xc8,0x55,0xb,0x2d,
- 0xc0,0x7,0x44,0x0,0x8f,0xef,0x18,0x6c,0xc0,0xe2,0xa4,0xde,0x3,0x94,0x8b,0x93,
- 0xb2,0x8b,0x13,0xac,0x2e,0x68,0xfe,0x2c,0xc4,0x93,0x38,0x66,0xa6,0x5,0x10,0xc5,
- 0x4c,0x24,0x20,0xc,0x66,0x88,0xf,0x4c,0xf7,0x79,0xeb,0xa0,0x77,0x27,0x77,0x6d,
- 0xef,0xc7,0xf,0x9,0x59,0xb,0x22,0xe0,0x3e,0x57,0xe0,0x4,0x40,0xc0,0x5,0x7e,
- 0x20,0x2,0x65,0x70,0x3,0x2c,0xb0,0x2,0x65,0xd4,0x4,0x67,0xb0,0x1,0x21,0x50,
- 0xab,0xba,0x4,0x4,0x8,0x1b,0x5f,0xb1,0x92,0xb2,0x6,0xba,0x38,0x56,0xa0,0x4,
- 0x30,0x60,0xc,0xfa,0x80,0x83,0xfa,0x20,0x8b,0x25,0x26,0x6a,0x2c,0x99,0x60,0xd3,
- 0xa6,0xa1,0x53,0x27,0xb,0x60,0x0,0x7,0xf1,0x2,0x94,0xf0,0x8,0x8f,0x2b,0x7b,
- 0x41,0x4f,0x4,0x3e,0x76,0xcb,0xb2,0x3c,0x93,0x2e,0x93,0x72,0x28,0x8e,0xe2,0x6,
- 0x4c,0x30,0x8,0x6b,0xb0,0x5,0x8c,0xf0,0xc,0xc7,0x45,0xa8,0x56,0xf6,0x74,0xf9,
- 0xe0,0xf,0xf0,0x50,0xf,0xc9,0xea,0xf,0xe2,0x40,0x6,0x39,0x60,0x2,0x2f,0x70,
- 0x2,0x40,0xf0,0x62,0x44,0xf0,0x5,0x52,0x0,0x5,0x3a,0xc0,0x1,0x36,0x80,0x89,
- 0x4d,0xb0,0x1,0x30,0xf3,0x0,0x2c,0xd0,0x55,0x19,0x70,0xb5,0xe5,0x22,0x2c,0x0,
- 0x4,0x32,0xf6,0xf2,0x50,0x6a,0x90,0x2,0x99,0x40,0x5e,0x74,0xa7,0xf,0xd8,0x60,
- 0x81,0xff,0xd6,0x7c,0x68,0xfb,0xe,0x19,0xba,0x83,0xa9,0xf6,0xa1,0xac,0xf7,0x2b,
- 0x51,0xe8,0x2a,0x29,0xeb,0x3b,0x77,0x3b,0xbc,0xb4,0xa3,0xb7,0x3c,0xe5,0x5a,0xe7,
- 0x24,0x2f,0x7a,0x90,0x2,0x91,0x79,0xa1,0x88,0xb8,0xe,0xa3,0x47,0xa4,0x8a,0xb,
- 0xf,0xd8,0xa0,0xe,0xac,0xfe,0x20,0x2,0x5e,0xf0,0x2,0x23,0x70,0x7,0x1d,0x70,
- 0x3,0x63,0x40,0x4,0x1f,0x30,0x3,0x5e,0x80,0x5,0x3c,0xc0,0x12,0x44,0xf0,0x4a,
- 0xae,0x24,0x5,0x1f,0x10,0x1,0x6d,0xd4,0x68,0x9,0x8b,0xba,0xf5,0xd2,0x40,0x2,
- 0xd4,0xba,0xc0,0xa0,0xf,0xde,0xa0,0x60,0xf8,0xd9,0x77,0x5f,0x7a,0xbb,0xb9,0xcb,
- 0xf,0xda,0x40,0x70,0x28,0x80,0x8,0x23,0x3,0xbf,0x2a,0x4b,0x85,0xc3,0x7b,0xc0,
- 0xc5,0xeb,0x28,0xcf,0xe8,0x28,0x41,0x40,0x8d,0xbf,0x36,0xc,0xfa,0xc0,0xb8,0x63,
- 0x58,0x67,0x4a,0x96,0xb8,0x53,0xf7,0xe,0x7a,0x66,0xf,0xef,0x20,0xe,0x3d,0x60,
- 0x89,0x32,0x36,0x42,0x61,0xe0,0x2,0x67,0x90,0x42,0x1c,0x90,0x3,0x7,0x51,0x3,
- 0x5b,0x60,0x4,0xfe,0xf4,0x0,0x80,0x0,0x5,0x1c,0xd0,0xab,0x9,0x6b,0xc0,0xdf,
- 0x23,0xbf,0x84,0x20,0x7,0x3b,0x40,0xd,0xb0,0x86,0xbf,0xb3,0x5b,0xbb,0xfc,0xe9,
- 0x83,0xb8,0x6b,0x6a,0x79,0x46,0xf,0x53,0x89,0x9,0x4a,0x90,0x5,0x74,0xbb,0x3d,
- 0x27,0x3b,0xb7,0x7,0xcc,0xa9,0x2d,0x9b,0x4e,0xae,0x65,0x10,0x82,0xa0,0x56,0x98,
- 0xf0,0xd,0xb0,0xa8,0x64,0xc1,0x55,0x8b,0xe6,0x90,0xd,0xff,0x8b,0xf,0xa1,0x76,
- 0x72,0xf8,0x70,0xa,0x22,0x10,0x7,0x39,0xb0,0x1,0xfa,0xa,0x46,0x1c,0x80,0x5,
- 0x67,0x30,0x4,0x48,0x29,0x6,0x14,0x90,0x51,0x9b,0xa0,0xb,0x7e,0x10,0x2,0x13,
- 0x2,0xc3,0xa7,0x2b,0xc3,0xb2,0x2,0x92,0x20,0x19,0x45,0x81,0xf0,0xd,0x9b,0xd5,
- 0xd,0x63,0x4b,0xb6,0xfe,0x3c,0xfc,0x88,0x3e,0x88,0x65,0x25,0x66,0xe,0xcf,0x87,
- 0xf,0xbf,0xa0,0x1,0x6b,0x60,0x5,0xef,0x92,0x80,0xbe,0x5b,0x2f,0x4b,0x8c,0xb7,
- 0x7c,0x98,0x28,0x8f,0x91,0x38,0x6e,0xe0,0x2,0xd4,0xd8,0x8,0x2d,0x10,0xb,0xf8,
- 0x30,0xe,0xa5,0x36,0x65,0xbd,0x15,0x70,0x7,0x89,0x5c,0xe2,0x20,0xe,0xfa,0x70,
- 0x7f,0xec,0xf0,0xe,0xdf,0x90,0x2,0x2e,0x90,0x5,0x44,0xd0,0xaa,0xdf,0x71,0x6,
- 0x1f,0xb0,0x1,0x6c,0xc9,0x61,0x17,0x90,0x9,0xbf,0x50,0x52,0xa2,0x20,0x2,0x72,
- 0xf0,0x1,0x74,0x9c,0x43,0x46,0xa3,0x3b,0x47,0x9c,0x2e,0xc,0xf4,0x5,0x84,0xd0,
- 0x8,0x3a,0xba,0x5b,0xf8,0x9,0xc8,0x5f,0x9a,0xa1,0x58,0x56,0x77,0x2a,0xe7,0x77,
- 0x4,0x87,0x9,0x64,0x0,0x7,0x8d,0xfc,0xad,0x2a,0x1b,0xc9,0xf2,0xd5,0x73,0x94,
- 0x1c,0x24,0x66,0x36,0x6,0x74,0xb0,0x6,0x75,0xf0,0x7,0x50,0x35,0xe,0xe0,0x50,
- 0x6a,0xe8,0xb0,0xe,0x9f,0xd7,0xe,0xed,0xa0,0x57,0xcf,0xa0,0xc,0xa5,0xf0,0x9,
- 0xcf,0xf0,0x85,0xdb,0x80,0xd,0xf8,0x50,0xa,0x22,0xf0,0x4,0x4c,0x70,0x42,0x1c,
- 0xe0,0x5,0x2e,0x80,0x94,0x6b,0xa0,0x1,0x15,0xf0,0x9,0xc3,0x80,0xf,0x7e,0x46,
- 0xb,0x4,0xc0,0x4,0x1b,0xf0,0xcb,0x88,0x39,0x56,0x16,0xa3,0x5,0x41,0x0,0x83,
- 0xd,0x45,0x8,0x9b,0x80,0xf,0xef,0xe0,0xc7,0xfe,0x30,0xbb,0x64,0x3b,0x7a,0x4b,
- 0x46,0xc8,0xb5,0x88,0x9f,0xa4,0x2c,0xb,0x28,0xe0,0x7,0x67,0xd3,0x2e,0x98,0xf8,
- 0x28,0x91,0x46,0xfe,0xb2,0xda,0x2c,0xc9,0x12,0xe3,0x3b,0x58,0x82,0x3e,0x8e,0x32,
- 0x5b,0x8d,0xa0,0x1,0x9f,0x20,0x90,0xf6,0x0,0xe,0xe0,0xd0,0x92,0x4e,0xd6,0xe,
- 0xf1,0xd0,0x57,0xc3,0x0,0xa,0x1a,0xa0,0x4,0x6,0xf0,0xa,0xf6,0x60,0xd,0xe1,
- 0x15,0xe,0xca,0xd0,0x3,0x3b,0x90,0x5,0x39,0xb0,0x48,0x37,0xf0,0x98,0x6d,0x5c,
- 0xa,0x36,0x68,0xd1,0xe1,0x50,0xd,0xf9,0xd7,0x0,0x59,0xb0,0x78,0xee,0x1b,0x29,
- 0x8a,0x79,0x36,0x31,0xdd,0xc0,0x84,0x20,0x4,0xfe,0x83,0xcc,0x1,0x77,0x9f,0x80,
- 0xcc,0xd1,0xcf,0xac,0x9f,0xdb,0x90,0x57,0xdf,0xf0,0x9,0x4a,0x50,0x4,0x1,0x14,
- 0x6,0x6c,0x77,0xd2,0x68,0xe3,0x2a,0xef,0x68,0xc7,0x4b,0x9c,0x63,0xe,0x44,0x14,
- 0x40,0x41,0x4,0x7e,0xd0,0x8,0x15,0x60,0xb,0x73,0x65,0xf,0xf7,0x47,0x5e,0x33,
- 0x9,0x61,0x10,0x56,0xb,0x98,0x40,0x3,0x83,0x62,0x4,0x4b,0x0,0xaa,0x84,0xed,
- 0x6a,0xdf,0x10,0xa,0x10,0x99,0x5,0x2a,0x10,0x2,0x7c,0x80,0x1,0x6f,0x90,0xa,
- 0x72,0x57,0x9f,0xc0,0x65,0xd,0x91,0xb8,0x4,0x62,0x10,0x2,0x7,0x8b,0x28,0xb8,
- 0xa7,0x36,0x99,0x24,0x40,0x44,0xd0,0x43,0x29,0xf0,0x7,0xcd,0x70,0x9f,0x7d,0x57,
- 0x81,0xcf,0xa,0x75,0x69,0xdd,0x77,0xf7,0xe7,0x72,0x54,0xd9,0x3,0x89,0x20,0x6,
- 0x35,0xa0,0x6,0x8a,0x90,0x3,0x8b,0x70,0xd2,0xd6,0x15,0xb7,0x78,0x8d,0xc0,0x90,
- 0xb6,0xd7,0xfd,0x38,0x10,0x43,0x50,0x6,0x8e,0x9d,0x9,0xcf,0x40,0x57,0xd9,0xb0,
- 0x67,0xfa,0xfe,0x10,0x60,0x25,0x25,0xf,0xb0,0x70,0x9,0x79,0xf0,0x6,0x13,0x70,
- 0x7,0xa3,0xd0,0xa,0x3d,0x80,0x4,0xb3,0x10,0xd9,0xec,0xa0,0xf,0xc5,0x60,0x0,
- 0x8d,0xa0,0x4,0x4a,0x20,0x3,0x6f,0x10,0xb,0xca,0x60,0x57,0xd5,0x10,0xe,0xf6,
- 0x60,0x62,0x95,0x69,0xbf,0x48,0x7a,0x3,0x7f,0x51,0x2,0xa6,0x5d,0x5f,0xc5,0x62,
- 0x9,0x4c,0x10,0x49,0x15,0x85,0x2,0xc1,0x90,0x7c,0xc9,0x47,0x5c,0xb0,0x8d,0xd6,
- 0x75,0xa7,0xbf,0xbf,0xa5,0x81,0xe7,0xf5,0xb,0x2d,0x50,0x7,0x89,0xe0,0xca,0x96,
- 0xd0,0x4,0xf0,0x62,0xd7,0x3b,0xb6,0xd2,0x7a,0x6d,0x2f,0xf,0x41,0x10,0x39,0x0,
- 0xb8,0x6,0x30,0xb,0x73,0xb5,0xe,0xef,0x47,0xf,0x7e,0x46,0xd,0xb2,0xf0,0x3,
- 0x68,0x80,0x6,0x12,0x80,0x4,0xf3,0xb6,0x90,0x91,0x80,0x2,0x76,0xf0,0x6c,0xd4,
- 0xb6,0xe,0xf2,0xa0,0x9,0xe9,0xd7,0x6,0xb1,0x30,0xd,0x62,0x1b,0xe,0xbe,0x65,
- 0x62,0x80,0x6a,0xf,0xe1,0xe0,0xd,0x3e,0x10,0xa2,0xf7,0x9d,0xdf,0x6a,0xd0,0x2e,
- 0xf0,0x2,0x41,0x19,0xb3,0x5,0x4a,0xf0,0x6,0x76,0x30,0xd,0x1,0x7,0xc8,0xfb,
- 0x49,0xdb,0x7d,0x37,0x60,0x4a,0xf6,0xe,0x80,0x27,0xf,0xbf,0xb0,0x54,0x64,0x90,
- 0x5,0x8a,0x70,0x4,0x46,0x3e,0xdc,0xaf,0x52,0xdc,0xc4,0x7b,0xdc,0x18,0x4e,0x10,
- 0x1f,0x34,0x8,0x64,0x0,0x6,0xcc,0xf0,0xe,0xeb,0x60,0xe,0xf3,0xc0,0xd,0x76,
- 0xf5,0xc,0xa9,0xf0,0x6,0x3e,0xf0,0x7,0x12,0x80,0x6,0xb0,0x80,0x59,0x23,0x45,
- 0x93,0xfe,0x17,0x70,0x1,0xb6,0xa0,0xf,0xe3,0x60,0xf,0x57,0x56,0xc,0xcc,0x86,
- 0x59,0xd5,0x60,0xf,0xe3,0xf0,0x85,0x82,0x9e,0xac,0x41,0x58,0xd,0xcc,0xa0,0x1,
- 0x5c,0xb0,0x78,0x2f,0x4a,0xe4,0x46,0x4e,0x98,0x74,0x20,0x4,0x88,0xb0,0x5,0x8d,
- 0x50,0x7,0x59,0x2a,0x7a,0x4f,0x39,0xe5,0xa0,0xbe,0x9f,0x7,0x1e,0xe5,0x76,0x36,
- 0x70,0x72,0x5,0xc,0x12,0xa0,0xdb,0x70,0xf0,0x5,0xf0,0x12,0x69,0x15,0xae,0xcd,
- 0x39,0xd6,0x26,0x66,0x3e,0x6,0x45,0xa0,0x4,0xac,0xa0,0xe,0xe7,0x90,0x72,0x76,
- 0x35,0xb,0x4,0x20,0x3,0x22,0x20,0x3,0x92,0x50,0xb,0xf4,0x99,0x5b,0xc8,0x35,
- 0x52,0x76,0x80,0x4,0x76,0x80,0xf,0xf0,0xed,0xf,0xff,0x4b,0x52,0x37,0xf8,0x74,
- 0x6d,0xae,0x88,0xee,0xb0,0x59,0xaa,0x2a,0x68,0x80,0x81,0xdf,0x70,0xe2,0x36,0x95,
- 0x8e,0xd2,0x59,0xb0,0x3,0x73,0x90,0x54,0xa9,0xa0,0xec,0xf6,0xc7,0x77,0x1f,0x1d,
- 0xea,0xa2,0xe,0xea,0xfa,0x96,0xa1,0x73,0x66,0xd0,0xf8,0x0,0xc,0x15,0xf0,0x6,
- 0x46,0x40,0x7,0xe9,0xf2,0x44,0x76,0x2d,0xe6,0x77,0x1b,0xeb,0x2d,0x32,0x10,0x58,
- 0x20,0x1e,0x45,0xf0,0x6,0xcc,0xa0,0xe,0x65,0xeb,0xf,0xde,0x30,0xd,0x92,0x20,
- 0x3,0x80,0x30,0x9,0xba,0x90,0x5b,0x72,0x46,0xa8,0x51,0x89,0xf,0xab,0x50,0x1,
- 0x28,0xd0,0xb,0x3b,0x2a,0x8e,0xa9,0xc6,0xa7,0xd4,0x86,0x60,0xba,0x9b,0x90,0xc8,
- 0xc5,0x9,0x45,0xd0,0x1,0x57,0x10,0x3,0x93,0x9e,0xed,0x9,0xa,0x2f,0x5d,0x20,
- 0xfe,0x8,0x29,0x10,0x8,0x2d,0x80,0x9,0x50,0xa5,0xb1,0xae,0x66,0x6a,0x53,0x8e,
- 0x6d,0x2d,0xd9,0x64,0x8b,0xf8,0x6f,0xad,0xa6,0xce,0xed,0x10,0x60,0x72,0x35,0xc,
- 0x1a,0x10,0x8,0x66,0x43,0x98,0x3a,0x66,0xef,0x76,0x8b,0xef,0x58,0xa2,0xef,0xcd,
- 0x92,0x5,0xad,0x20,0xf,0xdf,0x50,0x62,0xf0,0xb0,0xf,0xc6,0x45,0xa,0x18,0x80,
- 0x7,0xba,0x10,0x60,0x9d,0xb7,0xa1,0xa2,0x96,0xb8,0xf8,0xe0,0xc,0x38,0xe0,0x7,
- 0x92,0xe0,0xd,0xf0,0xbd,0xd,0xf0,0xa7,0xcc,0x94,0x49,0xe0,0xda,0x30,0x67,0x1,
- 0x36,0xad,0x34,0x90,0x4,0x30,0xa,0xf2,0xd8,0xee,0x1c,0x2f,0x88,0x36,0xf2,0x12,
- 0x8,0x9e,0x60,0x95,0xb0,0xa9,0xe,0x9c,0x15,0x75,0xe1,0x25,0x72,0x1d,0xdd,0x77,
- 0xf2,0x37,0xea,0x4e,0xe7,0x5b,0xf7,0xa9,0xbb,0x74,0xc5,0x62,0xbf,0x20,0xda,0x63,
- 0xa0,0x2b,0xd6,0xa5,0x31,0x95,0x54,0xc0,0x90,0xcc,0xc4,0xda,0x43,0x31,0x59,0x5b,
- 0xb2,0x55,0x48,0x38,0xf,0x91,0x5,0x81,0x40,0x9f,0xef,0x80,0x77,0xf0,0xb0,0xd,
- 0xf6,0xcb,0xc,0x3e,0x80,0x1,0x95,0xf0,0x5f,0x4c,0xd6,0xa3,0xa2,0xc6,0x77,0xe7,
- 0x65,0xa,0xfa,0x74,0xc,0x39,0x8,0x7f,0xb4,0x78,0x81,0xe9,0xa0,0x7c,0x7,0x69,
- 0xd0,0x7f,0x36,0x1,0x1f,0xa0,0xbd,0x6a,0x8f,0x28,0x66,0x46,0xbe,0x6e,0x40,0x4,
- 0x90,0x40,0x3,0x48,0x90,0xa3,0xff,0xd5,0x59,0xa2,0x67,0xd6,0xe4,0x5e,0xd4,0xae,
- 0xd6,0x59,0xd0,0x97,0x81,0xa,0xf6,0xcc,0x60,0x68,0x81,0x84,0xba,0x88,0x48,0xfe,
- 0x86,0xf,0xbd,0x80,0x1,0xf9,0xa,0x4,0x71,0x10,0x5,0x35,0x0,0x8a,0xe3,0x4a,
- 0xae,0xc1,0x7b,0x41,0x59,0x1b,0xf9,0x8e,0xe3,0x36,0x64,0xf3,0x8e,0xb5,0x52,0x8,
- 0x51,0x0,0xd0,0x45,0xb7,0xa7,0xe2,0x3e,0x86,0xf6,0x8b,0xf,0xae,0x40,0x3,0x14,
- 0x80,0xc,0x38,0x1e,0xe8,0xd6,0x16,0x5e,0x99,0x79,0xf5,0x17,0x60,0x7,0xa1,0xa0,
- 0xf0,0xf1,0xd0,0xe,0x3d,0x58,0x7f,0xe1,0x85,0x67,0x0,0xc1,0x8f,0x9e,0x3c,0x71,
- 0xf2,0x62,0xd1,0x8,0x31,0xe5,0xc4,0x89,0x11,0x26,0x4a,0xa8,0x81,0x18,0x51,0x4d,
- 0x98,0x42,0x3c,0xa,0xd,0xe1,0x23,0x6,0x8c,0xad,0x69,0xde,0xd6,0x7d,0x5c,0xe7,
- 0xce,0x1f,0x3f,0x73,0xeb,0xfc,0x85,0xb4,0x67,0x4f,0xdf,0x3b,0x96,0xf8,0x5c,0x4e,
- 0xc3,0xd7,0x52,0xdf,0xca,0x99,0x1f,0x4f,0x9a,0xf4,0x37,0x92,0x9f,0xbf,0x6e,0xfa,
- 0xa6,0xf9,0x92,0x1,0x8,0xc8,0x95,0x42,0x82,0x52,0x1c,0x5a,0x3,0xc7,0xcc,0x52,
- 0x33,0x6b,0x9a,0xc2,0x81,0x5a,0xa6,0x8c,0x1c,0xa9,0x70,0xa4,0x4e,0xc,0x13,0xe6,
- 0x8c,0x1c,0x35,0x4a,0xd7,0xa4,0x31,0xb3,0xc8,0x46,0xa1,0x20,0x70,0xf4,0xd4,0xa9,
- 0x20,0x8b,0x5a,0x4c,0x7d,0xee,0xf8,0xf1,0x73,0xa7,0xf2,0x1b,0xb2,0x1e,0x4b,0x3c,
- 0xc5,0xb4,0xc7,0x2e,0x65,0x5c,0x7d,0xdf,0xf0,0x7d,0xf3,0xe4,0x23,0xc1,0x30,0x79,
- 0xf2,0xe2,0xdd,0xbb,0xe7,0x2f,0xa5,0x3d,0x77,0x22,0xfd,0x69,0x53,0xe7,0xb7,0x16,
- 0x98,0x14,0x52,0x46,0x20,0x38,0x11,0xc3,0xa1,0xc4,0x88,0x72,0xc2,0x10,0xfe,0x62,
- 0x42,0xc7,0x8f,0x6,0x56,0xf8,0xce,0xbd,0x5b,0xb7,0xaf,0xb1,0xbb,0x7c,0xeb,0x76,
- 0xfa,0x7b,0x37,0xd3,0x9b,0x3e,0x7c,0xcc,0x6c,0xa1,0xa,0x75,0x4a,0x96,0xad,0x61,
- 0x7e,0x5d,0x7a,0x8b,0xad,0x2f,0xa7,0x3f,0x74,0x8b,0xf7,0xe5,0x5c,0x17,0x1b,0xdf,
- 0x2e,0xc,0x62,0xf8,0x30,0x51,0x21,0xa8,0x6,0x54,0xa8,0x4b,0x95,0x52,0xb7,0xaa,
- 0x46,0xea,0xf6,0x32,0x10,0xe5,0x78,0xfe,0x5e,0x46,0xa9,0x19,0x38,0x61,0xd8,0xe4,
- 0x20,0x82,0x68,0x4e,0x8f,0x50,0xe2,0x5c,0xbe,0xf3,0xe7,0xd6,0x1c,0x3c,0x7e,0xfa,
- 0xa8,0xc9,0xb,0x85,0xa3,0xc2,0xb0,0x98,0xe7,0xf4,0x75,0x8b,0xed,0x1b,0x79,0x70,
- 0xa9,0x84,0xb,0x40,0x8,0xc8,0xc5,0x25,0xc4,0xf8,0xc9,0x8b,0x1d,0x76,0xb6,0xf1,
- 0x7,0x9b,0x9e,0x5c,0xc2,0x25,0x92,0x6,0x8a,0x90,0xc2,0x84,0x17,0x5e,0xd0,0xec,
- 0x21,0xce,0xb4,0x93,0x4a,0x10,0x23,0x1a,0xc1,0x64,0xad,0x95,0x4c,0xda,0x67,0x9b,
- 0x6d,0xf6,0x31,0xe9,0xbf,0x99,0xde,0xa1,0xf0,0x11,0x1c,0xc0,0x0,0x3,0x5,0x14,
- 0x5a,0x68,0xc1,0x8e,0x4c,0x6c,0x79,0x46,0x1d,0x7c,0x66,0x12,0x6e,0x31,0x21,0xed,
- 0x81,0xd,0x46,0x7c,0x7e,0xb9,0x20,0x90,0x1a,0x6e,0xd8,0x23,0xc,0xaa,0xaa,0xc2,
- 0x8e,0x3a,0xee,0xb8,0xeb,0xec,0x3b,0xaa,0x40,0x94,0x23,0x8a,0x30,0xe8,0xc8,0x62,
- 0x87,0x3a,0x18,0x59,0x8b,0xad,0x93,0x46,0x82,0xa7,0x9e,0x7b,0x7c,0x2c,0x46,0x1,
- 0x34,0x56,0x91,0xc7,0x19,0x7c,0xe4,0xf1,0x51,0x1e,0x5e,0x1c,0xb9,0xfe,0xc0,0x8f,
- 0x7,0x58,0x10,0x85,0x99,0xd8,0xde,0x8a,0xcb,0x41,0x22,0xb1,0x99,0xe9,0x9c,0x69,
- 0x7a,0xf1,0xa1,0x39,0x2e,0x1e,0x70,0xe1,0x8c,0xf,0x4c,0xd8,0xec,0x43,0xf1,0xb6,
- 0xd8,0xa2,0xe,0x30,0x9c,0xf1,0x4b,0x1f,0x7b,0x70,0x72,0x67,0x1b,0xc7,0x92,0xd3,
- 0xe7,0x99,0x37,0x4d,0x89,0x64,0x89,0x3a,0x2,0x21,0x63,0xb,0x3d,0x6,0xe1,0xc2,
- 0x8f,0x37,0xc0,0xc8,0x43,0x16,0x97,0x56,0x7a,0x27,0x25,0x3f,0xed,0x41,0x7,0x9d,
- 0x9c,0xe8,0xc1,0xc7,0x47,0x5e,0x2a,0x20,0x83,0x8f,0x2b,0xae,0xd8,0xca,0x4a,0x2b,
- 0xb9,0xc3,0x8e,0x2b,0x88,0xa6,0xfc,0x2e,0x2b,0x65,0x8f,0x20,0x24,0x8b,0x35,0xea,
- 0x40,0x81,0x9a,0x6f,0xd4,0x89,0xed,0x26,0x7b,0xf6,0xa9,0xa7,0x1e,0x6e,0x70,0xc5,
- 0xa7,0x13,0x34,0x24,0x70,0x86,0x1c,0x71,0xc9,0x81,0x5,0x8d,0xa,0x68,0xf4,0x81,
- 0x14,0x65,0x58,0x1a,0xd2,0x4f,0x7a,0xb4,0xd1,0xc7,0x1b,0x75,0xa6,0x21,0x65,0x82,
- 0x3b,0x59,0xb8,0x21,0x84,0x10,0x44,0x50,0x61,0x86,0x46,0x39,0xb3,0x62,0xd,0x25,
- 0xa0,0xfd,0xc5,0xbd,0xd8,0x18,0x6b,0x8c,0x56,0x91,0x0,0xa5,0xed,0x4d,0x56,0x7a,
- 0x50,0x62,0x8d,0x53,0x7,0x29,0xa3,0x8b,0x26,0x86,0x90,0xc3,0xf,0x25,0x34,0xc8,
- 0x63,0x15,0x13,0x63,0xb5,0x67,0x1c,0x91,0x85,0x1c,0xe9,0x9e,0x77,0xf1,0x29,0x6,
- 0x5,0x31,0x62,0x88,0xe3,0xc,0x65,0x5f,0x76,0x52,0x3b,0xea,0xac,0x0,0xf,0xc4,
- 0xed,0x3c,0x33,0x8f,0xd,0x9d,0xe5,0x80,0xc3,0x88,0x55,0x9f,0xfe,0xf9,0xe6,0x45,
- 0xc6,0x70,0xda,0x87,0x9f,0x7a,0xde,0x4a,0xee,0x18,0x5,0x18,0x71,0xa5,0x9c,0x65,
- 0x68,0x79,0x44,0x1,0x47,0x7e,0x40,0xc2,0x14,0x66,0xf0,0xf1,0xa6,0x1a,0x69,0x86,
- 0x5c,0xec,0xcd,0xfb,0x7e,0xa9,0x44,0x84,0x7,0x74,0x0,0xc2,0x83,0x19,0xa4,0x28,
- 0x42,0x84,0x22,0x5c,0xf8,0x57,0x22,0x38,0x94,0x88,0xa4,0x8d,0x55,0xf0,0x99,0x66,
- 0xa6,0xf8,0x12,0xde,0xeb,0x2d,0x7f,0xfa,0xc2,0x7,0x97,0xb,0xc8,0xd0,0x3,0x8e,
- 0x2e,0x82,0xd0,0xf2,0x8c,0x33,0xbc,0x8,0x82,0x88,0x41,0x10,0x59,0x55,0x96,0xab,
- 0x2d,0x45,0x67,0x1b,0x7b,0x24,0x37,0xee,0x9e,0x6c,0xef,0xd1,0x6,0x1f,0x61,0x30,
- 0x0,0xe4,0xe,0x97,0x61,0x56,0x96,0x2a,0xec,0x26,0xe2,0x6a,0xca,0x32,0xb2,0x62,
- 0x23,0x8e,0x2a,0xd8,0xa0,0x23,0x85,0x46,0xc0,0x40,0xe6,0x47,0x4b,0x73,0x72,0xe7,
- 0x38,0x9a,0x86,0xb3,0x27,0x1c,0x7d,0x1e,0x41,0xa1,0x8e,0x56,0x94,0x68,0x1,0x9,
- 0x14,0xd0,0x80,0xc5,0x3d,0x6a,0x2d,0xb5,0x87,0x1f,0x78,0xe6,0x39,0x7a,0x6f,0x7c,
- 0xa,0x72,0xc6,0x94,0x16,0x64,0x60,0x61,0x6,0x10,0x40,0x0,0x2,0xa,0x29,0xb8,
- 0xa8,0x61,0xed,0xb6,0x23,0x82,0x23,0x10,0x30,0x34,0x9,0xf3,0x1a,0x7f,0xf6,0xc9,
- 0xc7,0x9d,0xe2,0x52,0x5a,0x27,0x1d,0xb8,0xde,0x39,0xe7,0x19,0x14,0xde,0x40,0x44,
- 0x70,0x37,0xa,0x29,0x84,0x8d,0x42,0xb2,0x72,0x83,0x2a,0x2b,0x6a,0x48,0x84,0x1,
- 0x62,0xf1,0xb1,0xa2,0xed,0x24,0x25,0xe8,0x10,0x89,0xd1,0xfe,0xea,0x41,0xf,0x1f,
- 0xf5,0x42,0x6,0x52,0x18,0x83,0x1a,0x3c,0xe3,0x32,0x36,0xbc,0x4c,0x3c,0x4f,0xc1,
- 0xca,0x93,0x6e,0x86,0xba,0x38,0xb4,0x2c,0xb,0x75,0x40,0x82,0x30,0xb0,0x86,0x40,
- 0xb7,0xc0,0x65,0x6f,0xca,0x41,0x9e,0x5e,0xaa,0x1,0xc,0x14,0x90,0x60,0x7,0x5b,
- 0x20,0x1,0x18,0x72,0xe1,0xd,0x7c,0xc4,0xe3,0x1a,0xfa,0xa8,0x55,0xf2,0xe6,0xb1,
- 0xc3,0x5,0xba,0x44,0x1e,0xd4,0x58,0x5,0xa,0x34,0x20,0x6,0x11,0xac,0x40,0x7,
- 0x71,0x0,0x41,0x9,0x80,0xf0,0x81,0x1b,0x70,0xe1,0x6,0xfe,0xf2,0x10,0x67,0xe0,
- 0xf0,0x86,0x48,0x50,0x4a,0x1d,0xfa,0xa0,0xc7,0x4e,0xe2,0x22,0x24,0x77,0xb8,0x4f,
- 0x72,0xfa,0x78,0x5,0x12,0x96,0x20,0x6,0x2b,0x28,0x4b,0x67,0x6e,0x60,0xca,0xe9,
- 0x9c,0x34,0x6,0x48,0x90,0x26,0x68,0xf4,0xe0,0x46,0x3d,0xe8,0xb3,0xe,0x92,0x19,
- 0xed,0x1e,0xfa,0xf0,0x91,0x2f,0x68,0xe0,0x87,0x1a,0x58,0x81,0x10,0x61,0x70,0xc1,
- 0xfd,0x42,0xe7,0x95,0x35,0x64,0x90,0x3b,0x74,0xa0,0x3,0x21,0xba,0x90,0xa8,0x33,
- 0x8c,0x81,0x2,0x98,0xe0,0xf,0x3e,0xc2,0x91,0x40,0xbd,0xed,0xad,0x61,0x3f,0x12,
- 0xd2,0x3b,0x1e,0x71,0x81,0x16,0x70,0x62,0x17,0x31,0x41,0x7,0x3d,0xcc,0xf4,0x91,
- 0xc6,0x28,0xf0,0x1e,0xf1,0x78,0x53,0x31,0x58,0x21,0x46,0x25,0x18,0xa1,0x8,0x45,
- 0xb8,0x81,0xe,0x74,0x60,0x3,0x1b,0xcc,0xc0,0x96,0xb6,0x5c,0xc1,0xf7,0x20,0x2,
- 0x7,0x1a,0xfc,0xc2,0x37,0xda,0x20,0x9,0x5c,0x86,0xfe,0xe4,0x96,0x74,0xb8,0x43,
- 0x77,0xca,0x40,0x41,0x23,0xe0,0x80,0x15,0x9d,0x39,0x29,0xd,0x87,0x0,0x8b,0x1b,
- 0xcc,0x73,0x86,0x1b,0x24,0x2,0x5,0x73,0xc3,0x87,0xe5,0xb2,0xb5,0x8f,0x3,0xa6,
- 0xc4,0x1f,0xf7,0xd8,0x89,0x7f,0x6,0xd5,0x82,0x44,0x18,0x21,0xb,0x72,0x50,0xc4,
- 0x6,0xf2,0x97,0x15,0x9e,0x35,0x65,0xd,0x34,0x73,0x52,0x78,0xe4,0x20,0x4,0x2b,
- 0x10,0x81,0xe,0x83,0xe8,0x82,0x1c,0x8c,0x80,0x89,0x63,0xe4,0xea,0x1c,0x8c,0x79,
- 0x4b,0x25,0x67,0xe2,0x92,0x1f,0xdd,0x2d,0x25,0xcc,0x78,0xc5,0x2f,0xde,0x53,0x9c,
- 0xe1,0xc,0x87,0x45,0xd,0xa3,0x6,0x2f,0x34,0xf1,0x3,0x1c,0x18,0x81,0x8,0x44,
- 0x28,0xc2,0x45,0x89,0x70,0x83,0x1b,0xb8,0x40,0x7,0x33,0xb0,0x41,0xc,0x4a,0xa0,
- 0x19,0x5d,0x76,0xc5,0xf,0x6e,0x9a,0x16,0x1c,0xf9,0x34,0xcc,0x74,0xa4,0x43,0x2f,
- 0x7f,0xf1,0x84,0x12,0xe0,0x80,0xb3,0xcf,0xc1,0x21,0xd,0x73,0x0,0x8b,0x16,0x74,
- 0xc6,0x6,0x37,0x14,0x61,0x9,0x38,0x80,0x85,0x4b,0x44,0x59,0x8f,0x9c,0x70,0x11,
- 0x27,0x34,0x39,0x92,0x6,0xea,0x90,0x88,0x1a,0xa8,0x40,0x11,0x4d,0x18,0xa4,0x3b,
- 0x97,0x69,0x25,0x65,0x31,0xc1,0x12,0x83,0x10,0x81,0x1e,0x2,0xa1,0x4,0x4c,0x30,
- 0xa3,0x52,0xc2,0xf1,0x7,0x34,0x2,0x9a,0x13,0x20,0xb9,0x44,0x27,0x7a,0xd3,0x87,
- 0x7f,0xde,0xa1,0xbb,0x94,0x8c,0x43,0x25,0x40,0xa2,0x8d,0x3a,0x90,0xa1,0x8a,0x46,
- 0xb4,0xa0,0x7,0x6d,0x98,0x43,0x12,0x6c,0xa0,0xfe,0x83,0x1c,0x24,0x1,0xa3,0xaf,
- 0xdc,0xe8,0xc,0x80,0x10,0x83,0x11,0x8c,0xa0,0x43,0x1f,0x52,0xc3,0x18,0xfc,0xf0,
- 0x8d,0x69,0xa9,0x3,0x9c,0x6f,0x19,0x66,0x7c,0xb6,0x81,0x8e,0x70,0xbc,0xa9,0x11,
- 0x5b,0x80,0x67,0x56,0x76,0x79,0xd3,0x34,0x94,0x41,0xb,0xe6,0xa1,0x48,0x16,0xc8,
- 0xd0,0x86,0x1f,0xa0,0xa2,0x1c,0xf8,0xa0,0x7,0x3d,0x70,0xc7,0x45,0xe4,0x74,0xc3,
- 0x25,0xbf,0xa8,0xc0,0x1f,0x94,0x50,0x3,0x39,0x4,0xe1,0x73,0xed,0x7c,0x8a,0x55,
- 0xd4,0xc8,0x4e,0x22,0x84,0x4f,0x52,0x9f,0xb8,0xda,0x6c,0x56,0x72,0x9c,0x80,0xbe,
- 0x6,0x48,0xa9,0x5,0x27,0x3c,0x94,0x4b,0x12,0x6c,0x1c,0x27,0x27,0xc,0xb,0x47,
- 0x35,0x68,0xf8,0x8d,0x61,0xc4,0x42,0x12,0x32,0x10,0x1,0x17,0x98,0x20,0x82,0x14,
- 0x30,0xc1,0x6,0x2f,0xb0,0x1,0x14,0xfc,0x5a,0x84,0xee,0x5,0x76,0xb0,0x85,0x2d,
- 0x41,0x49,0xd5,0x70,0x3,0x5d,0xc8,0x3,0x1f,0xd7,0xc8,0x86,0xd1,0x14,0xa3,0x17,
- 0x6f,0xc6,0x87,0x1d,0xe1,0x38,0x87,0x38,0x68,0x41,0x1,0x41,0x4c,0x85,0x9d,0x5d,
- 0xc1,0xce,0x54,0x3c,0xa3,0x5,0x2e,0xed,0xa0,0x11,0x3d,0xc0,0x1,0x2b,0xdc,0x3,
- 0x2b,0xda,0x2d,0x66,0x7d,0x64,0xf5,0xb,0x30,0x62,0x9b,0x88,0x2c,0x74,0x21,0x74,
- 0x17,0x5c,0x83,0x53,0xac,0x92,0xb3,0x33,0xe4,0x80,0xf,0x46,0x0,0x61,0x28,0xfc,
- 0xe2,0x8d,0x9c,0xd8,0xca,0x26,0xd,0xb5,0x64,0x4e,0x8a,0x5b,0x5c,0x73,0xec,0x84,
- 0x61,0xbf,0x61,0xc6,0x2e,0x48,0x91,0x8,0xfe,0x19,0x4c,0xe0,0x95,0x45,0xb0,0x98,
- 0x9,0x6c,0xd0,0x87,0xd,0x1,0xc1,0x6,0x43,0x18,0x6f,0x46,0x3b,0x6a,0x3,0x20,
- 0x70,0xe8,0xb0,0x1f,0x1a,0x83,0x14,0xc4,0x20,0xc,0xf7,0xc0,0x91,0xa8,0xd,0xaa,
- 0x6f,0x71,0xfa,0x12,0x8b,0x16,0x20,0x42,0x8,0x5a,0x90,0x66,0x18,0xc4,0x3,0x87,
- 0x2c,0x24,0x59,0xa,0xc7,0xa,0xd1,0x13,0x4,0xb1,0x85,0x35,0x88,0xc1,0x8,0xae,
- 0xa0,0xc6,0x8b,0x54,0x6b,0x92,0x2d,0x7a,0x73,0x27,0x7c,0x63,0x61,0x1d,0x8c,0x30,
- 0x8,0x9c,0x89,0xce,0x9d,0x4e,0x39,0x5d,0xea,0xe2,0x50,0x88,0x2e,0x24,0xe2,0x2,
- 0xa7,0xf8,0xcb,0x3b,0x8e,0xe3,0xe,0x9c,0x8c,0x69,0x38,0x40,0xca,0x47,0x25,0x1b,
- 0xda,0xd2,0x74,0xac,0x83,0x36,0xf2,0x48,0x46,0x2c,0x3c,0xf1,0x6,0xec,0x72,0x54,
- 0xa,0x6e,0x50,0x84,0xa2,0x22,0xd0,0x41,0x8,0xbc,0xc0,0xc7,0x36,0xc8,0x1,0x90,
- 0x93,0xc0,0x51,0x17,0x78,0x94,0x51,0xa7,0x8e,0xa2,0x44,0xc6,0x70,0x7,0x11,0xfc,
- 0xa1,0x16,0xf8,0x68,0x7,0x62,0xfa,0x44,0xdf,0x9c,0xbc,0xc3,0x53,0xb2,0x40,0x81,
- 0x12,0x28,0x61,0x5,0x37,0xf4,0x5a,0xb,0xe2,0x59,0x43,0x16,0xee,0x30,0x94,0x33,
- 0xa8,0xa1,0x29,0x69,0x78,0xe6,0x13,0xe8,0x10,0x6,0x1b,0x18,0x82,0x5,0xb1,0x60,
- 0x86,0xdd,0xb2,0x25,0x4c,0xe3,0xbc,0x85,0x36,0x6b,0xf9,0x85,0x6,0x2,0x31,0x8,
- 0x43,0x42,0xe5,0x2b,0x60,0xc9,0x73,0x15,0xe2,0xb0,0x7,0x3e,0x8,0xf0,0x55,0x23,
- 0x71,0x1f,0x3f,0xd6,0x81,0xd,0x7f,0xfe,0xa8,0x96,0xac,0x40,0x5a,0x4d,0x4a,0x80,
- 0xb4,0x18,0xbd,0x78,0xa3,0x16,0x8c,0xa8,0x3,0xd,0x52,0x90,0x2,0x23,0x6c,0xe1,
- 0x9,0x65,0xc4,0xc2,0x86,0xfa,0x10,0x7,0x26,0xca,0x41,0x7,0x50,0x8,0x2f,0x14,
- 0x14,0xe,0x5,0xbe,0xf2,0x35,0x7,0x2e,0xe8,0x28,0x14,0x11,0xab,0x6,0x2f,0xe0,
- 0x81,0x2,0x76,0xe0,0x45,0xae,0x66,0x32,0xcc,0xbe,0xc8,0x83,0x15,0x28,0x0,0x9c,
- 0x10,0x8,0xe1,0xeb,0xaa,0xf8,0x81,0xb,0x57,0x98,0xc2,0x15,0xbc,0xd0,0x95,0x6f,
- 0x8b,0x99,0xe,0x5e,0x30,0xc4,0x14,0xee,0x40,0x80,0x58,0xf8,0x85,0x1e,0x96,0x33,
- 0x20,0xc9,0x4e,0xf2,0x23,0xbf,0xfc,0xa2,0x5,0x46,0x18,0x83,0xe1,0xb6,0x2,0x87,
- 0x6f,0x27,0x25,0xc,0xaa,0x9b,0x42,0x1c,0xa4,0x30,0x1,0x5a,0xc8,0xc3,0xe6,0xf7,
- 0x68,0x31,0x49,0x6e,0xd5,0xee,0xd4,0xe,0x27,0x1f,0x6,0x55,0xc9,0xab,0x74,0x87,
- 0x50,0x24,0x68,0x1b,0xe,0x4c,0xe0,0xc3,0x20,0xb2,0xe0,0x6f,0x2b,0xc,0xe1,0xbb,
- 0x4e,0x18,0x1,0x10,0xb6,0x27,0x82,0x24,0xe4,0x20,0x7,0xb,0xa7,0xa5,0x2c,0x75,
- 0x50,0x6a,0x88,0xbb,0x0,0x8a,0x63,0xc0,0x7b,0x95,0xe4,0x10,0x2,0x31,0xd0,0x0,
- 0x5,0xae,0x32,0xd,0x4b,0xe8,0x28,0x6f,0x79,0xb4,0xc2,0x9c,0x35,0xc8,0x2,0x21,
- 0xe8,0x10,0x1e,0x28,0x59,0x41,0xd,0x2e,0x13,0x5d,0x80,0xfd,0xcb,0xce,0x9,0x28,
- 0x18,0xb5,0x2b,0x3d,0xe0,0x40,0xfd,0x61,0x8e,0xbd,0x9d,0x3,0x1f,0xbd,0xa0,0x81,
- 0x14,0x80,0x90,0x74,0x37,0xd4,0xfe,0xa0,0x11,0x87,0x38,0x44,0x16,0xbc,0xd0,0x7,
- 0x27,0x38,0xe1,0x4,0x71,0x10,0x41,0x2e,0xdc,0x3,0xeb,0x58,0xa3,0x98,0xea,0xa9,
- 0x55,0xb4,0xf2,0xc4,0xea,0xf,0x98,0x14,0x86,0x1a,0xb1,0x78,0x43,0xa,0xb8,0xc0,
- 0x87,0x2f,0xc8,0x81,0x9,0xc7,0xef,0xc2,0xf1,0x99,0x70,0x84,0x23,0x34,0x81,0xf9,
- 0x47,0x18,0xc2,0x45,0x93,0x30,0x84,0x21,0xb8,0x3d,0x7,0x72,0x9f,0xfb,0x2d,0xed,
- 0xbe,0x82,0x12,0x94,0x0,0xef,0x11,0xf4,0x8e,0x1c,0xec,0xc9,0x87,0x2c,0x88,0xe1,
- 0xd,0xa6,0x8,0xd3,0x8f,0xba,0x91,0x92,0x73,0xb4,0x2,0x34,0x8a,0xb7,0x2,0x1d,
- 0xac,0x60,0x3a,0xfa,0xd7,0x7f,0x3b,0x4d,0xb0,0x84,0x12,0x58,0x21,0xf,0xe1,0x34,
- 0x86,0xbe,0xe8,0x8,0xe,0x9d,0x80,0xd,0x9f,0x0,0xa,0x45,0x18,0x8a,0x42,0xa0,
- 0x84,0x1d,0x38,0x84,0x1d,0xb0,0x82,0x3d,0x40,0xb9,0x11,0xb8,0x83,0x9,0xc8,0x5,
- 0xdf,0x88,0x35,0x93,0x51,0x8c,0xbd,0x51,0x31,0xc4,0x78,0xac,0xd7,0x8,0x28,0x9,
- 0xc9,0x15,0x79,0xd8,0x85,0x39,0x10,0x83,0x22,0x90,0x83,0x3d,0x38,0x82,0xf0,0x6a,
- 0x82,0x2e,0x50,0x41,0xe5,0x63,0xc1,0x16,0xa4,0xbe,0x17,0xac,0xbe,0x87,0xb3,0xbb,
- 0x19,0xc0,0xbe,0xee,0xf3,0xbe,0xbc,0xb,0xbf,0x31,0x50,0x84,0x1b,0x50,0x81,0x49,
- 0x20,0x83,0x1e,0x30,0x85,0x36,0xf9,0x8b,0x1f,0xa9,0x86,0x57,0x48,0x1,0x7b,0x22,
- 0x4,0x2b,0x88,0x3f,0xfb,0x63,0x42,0xd3,0x69,0x96,0x1f,0x7c,0x5,0x50,0x12,0x89,
- 0x2d,0x9a,0x37,0xe7,0xb2,0xfe,0xa4,0xe5,0x68,0xe,0x3e,0xb8,0x28,0x41,0xc8,0x2,
- 0x4a,0x90,0xe,0x33,0xd0,0x18,0x14,0x88,0x24,0x75,0x58,0xb3,0xf5,0x21,0x12,0xdb,
- 0x43,0x43,0x6c,0x68,0x11,0x1,0x31,0x5,0x88,0xc9,0x82,0x65,0xba,0x18,0x28,0x18,
- 0x82,0x14,0x5c,0xc1,0x16,0xb4,0x43,0x18,0xa4,0x3e,0xb7,0x2b,0x35,0x5b,0xaa,0xc1,
- 0xee,0xfb,0xbe,0x2a,0x9,0x82,0x5e,0x93,0x3,0x3a,0x78,0x1b,0x14,0x78,0x4,0x72,
- 0x28,0x8c,0xc2,0x38,0x85,0xb,0x10,0x3,0x42,0x0,0xd,0x22,0x88,0x3f,0x3a,0x68,
- 0xc2,0x49,0x84,0x83,0x31,0xdb,0x2,0x32,0x68,0x1,0x55,0xf8,0x6,0x96,0x10,0x40,
- 0x95,0x18,0x12,0x9e,0xa0,0xa1,0x23,0x49,0x92,0x2c,0x60,0x2,0x37,0x68,0x2,0x17,
- 0x48,0x8f,0x46,0x68,0x3,0x34,0x28,0x6,0x79,0x20,0x7,0xd4,0x9a,0x2f,0x5a,0x43,
- 0x43,0xdc,0x29,0xaa,0xb7,0x52,0x87,0x67,0xc8,0x4,0x14,0x58,0x82,0xa4,0xb0,0x82,
- 0x2f,0x8,0x83,0x3d,0x68,0x82,0x15,0xa0,0xc3,0xe4,0xb3,0x43,0x17,0xc4,0x43,0x3d,
- 0x9c,0xc1,0x3e,0xbc,0x41,0xf0,0x93,0x20,0x39,0x58,0x84,0x40,0x5c,0x84,0x23,0x20,
- 0x2,0x3d,0x98,0x83,0x36,0xc8,0x84,0x5b,0x48,0x6,0x64,0x88,0x84,0x16,0x8,0x84,
- 0x2c,0x90,0x3f,0x48,0x2c,0x3,0x25,0x9c,0xc4,0x26,0x34,0x83,0x34,0xd8,0x82,0x1a,
- 0x40,0x15,0x19,0xd0,0xc4,0x1f,0xc1,0x39,0x59,0x39,0x20,0x5b,0xd9,0x7,0x7a,0xc0,
- 0x23,0x7c,0xd8,0x95,0x40,0x98,0x84,0x2b,0x78,0x1,0x43,0x68,0x82,0x41,0xa8,0xc6,
- 0x65,0x28,0x7,0x44,0xfe,0x7c,0xaf,0xe2,0x0,0x7,0x70,0xa0,0x2f,0xae,0x31,0xc8,
- 0xbd,0x89,0x8c,0x64,0x40,0x82,0x4,0x68,0x84,0x35,0x28,0xaf,0x2e,0xf0,0x2,0xe7,
- 0x1b,0x46,0x62,0x2c,0x46,0xe5,0xc3,0xc3,0x18,0xdc,0x43,0x1a,0x94,0x3b,0x1b,0xfc,
- 0xc3,0xf0,0x5b,0x4,0x2f,0xe0,0x81,0x33,0x28,0x4,0x37,0x30,0x8b,0x39,0xa8,0x83,
- 0x1e,0xa8,0x83,0x39,0x28,0xa7,0xaf,0x93,0x8a,0x25,0x5c,0xc2,0x71,0xb4,0x3f,0x33,
- 0x58,0x40,0x38,0x20,0x2,0x39,0x28,0x82,0x14,0x18,0x20,0xd4,0x2,0xa7,0x7c,0x60,
- 0x7,0xb7,0xaa,0x23,0x93,0xc9,0x1c,0x5e,0x50,0x19,0x20,0xe8,0x83,0x13,0x58,0x84,
- 0x2e,0x78,0x24,0x34,0x40,0x85,0x62,0x28,0x7,0x79,0xf8,0x27,0x76,0x20,0xc8,0xc6,
- 0x50,0xc,0x83,0x5c,0xc,0xb2,0x9a,0x6,0x6a,0x10,0x6,0x14,0x40,0x82,0x46,0x48,
- 0x1,0x74,0xac,0xa7,0xe5,0xb,0xb5,0x31,0x60,0x2,0x15,0xa4,0xc8,0x8a,0x64,0x82,
- 0x8b,0x44,0x46,0x3e,0xdc,0x48,0x3f,0xc4,0xc1,0x66,0x54,0x81,0xfb,0x39,0x3,0x69,
- 0xea,0x2,0x33,0x40,0x4,0x12,0xb8,0xac,0x14,0xc8,0x2,0x4b,0xd8,0x80,0x41,0x44,
- 0x24,0x71,0x94,0x44,0x98,0xac,0x3f,0xa5,0xa0,0x4,0x22,0x70,0x83,0x3d,0xb8,0x1,
- 0x3f,0x68,0x1,0x59,0x70,0x93,0xfe,0xd3,0x8b,0x82,0x24,0x12,0xc4,0x30,0x93,0xcc,
- 0xf9,0x5,0xce,0x89,0x3,0xd6,0xbb,0x2,0x39,0xd8,0x82,0x43,0xe8,0x81,0x16,0x88,
- 0x84,0x5d,0xf8,0x86,0x73,0xd8,0x1a,0xe5,0x79,0x8d,0xa9,0xe4,0x1a,0x4b,0xb2,0x8f,
- 0x5d,0xd0,0x80,0xfe,0x25,0x48,0x4,0x31,0x78,0xc3,0x2e,0xb8,0xa8,0x60,0x91,0x82,
- 0x1b,0x18,0xcb,0x3a,0x34,0xcb,0xb3,0x3c,0x46,0x19,0x54,0x4b,0x59,0xe2,0xc8,0xb6,
- 0xfc,0xe,0x42,0x20,0x82,0x1c,0x38,0x9c,0x30,0x70,0x83,0xff,0x81,0xa6,0x35,0xa0,
- 0xb3,0x21,0xf0,0x2,0x39,0x98,0xbf,0x70,0x94,0x44,0x22,0x0,0x4c,0xfb,0xb3,0x82,
- 0x2e,0x18,0x49,0x37,0xa0,0x83,0x1a,0x98,0x83,0x4,0x90,0x85,0x5,0x5b,0x8d,0xf8,
- 0x58,0x9f,0xab,0xd3,0xa6,0x76,0x68,0x20,0x19,0x10,0x2c,0x27,0xb8,0x3,0x29,0xc8,
- 0x2,0x74,0xe4,0x3,0x39,0x10,0x81,0x4a,0xf0,0x85,0x1f,0x31,0x9a,0xd1,0x24,0xcd,
- 0xaa,0x2c,0x2b,0x5a,0x30,0x82,0x14,0xd0,0x3,0xf2,0xa2,0x3,0x22,0xf0,0xc5,0x28,
- 0x8,0x82,0x2e,0x18,0x83,0xef,0x20,0xcb,0xb2,0xac,0x48,0xb4,0xc4,0x4d,0x8d,0xd4,
- 0x4d,0xb6,0xfc,0x3e,0xbc,0x53,0x42,0x78,0x32,0x9c,0x30,0xe8,0xa,0xeb,0xc8,0x33,
- 0x36,0xd0,0xa0,0xe7,0x6c,0x42,0xcf,0xa8,0x20,0xaa,0x58,0x8a,0x35,0x68,0x4,0x3,
- 0x60,0x85,0xa0,0x41,0xa0,0xb1,0xa2,0x15,0x37,0x43,0x8c,0x21,0xd4,0x23,0x19,0xb8,
- 0x81,0x22,0x90,0x1,0x23,0xe0,0x2,0x29,0x80,0x2,0x20,0x30,0x84,0x8,0x34,0x85,
- 0x82,0x68,0x87,0xd4,0x72,0x37,0xac,0x53,0x9,0x18,0xf9,0x6,0x5e,0xa8,0x3,0x2e,
- 0xc8,0x82,0x2c,0xe8,0x45,0xbc,0xfb,0x82,0x2f,0x8,0x82,0xfe,0xc,0x50,0xb2,0xac,
- 0xcd,0xe3,0x7b,0x41,0xeb,0xa3,0x3b,0x17,0x58,0x81,0x15,0x98,0x81,0x26,0xe5,0x3e,
- 0x4,0x4d,0xfe,0xd0,0x31,0x80,0x8a,0xc4,0xf2,0x2,0xc3,0x51,0x4e,0xeb,0x98,0x88,
- 0x9d,0xa1,0xd0,0x71,0x3c,0xba,0x38,0xd0,0xb2,0x72,0x5c,0x8a,0x2c,0x40,0x4,0x1a,
- 0x50,0x85,0x82,0x52,0x20,0x7f,0xc8,0x87,0x1c,0x7a,0x4c,0x81,0x98,0x8d,0x41,0xf9,
- 0x84,0x58,0xf8,0x5,0x5c,0x28,0x85,0x46,0x10,0x83,0x10,0xd8,0x3,0x1b,0x38,0x3,
- 0x2e,0xa8,0x83,0x3c,0x68,0x45,0xf7,0xd2,0x7,0x93,0x30,0x89,0x6d,0x58,0xd3,0xb4,
- 0x72,0x89,0x60,0x40,0x83,0x2d,0x8,0x52,0xbc,0xd3,0x92,0x30,0x88,0x2,0xfe,0x24,
- 0xd2,0x22,0x15,0xd0,0x62,0x4c,0x52,0x64,0x2c,0xb5,0x26,0x7d,0xd2,0x26,0xdd,0xcd,
- 0x29,0xb5,0x2,0x2e,0xc3,0x3b,0x2f,0xb8,0x52,0x0,0x8b,0xa,0xad,0xd8,0x8a,0x2e,
- 0x9d,0xc4,0x30,0x10,0x37,0x2d,0x43,0x36,0xb0,0x20,0x84,0x26,0x52,0x47,0xa1,0x32,
- 0x93,0x5a,0xdc,0xb,0x9c,0x8,0x8e,0xe0,0x78,0x93,0x37,0x1,0x86,0x52,0x20,0x1,
- 0x3f,0xe8,0xd1,0x2d,0x68,0x84,0xa,0xb8,0x5,0x79,0xb8,0x6,0xf5,0x33,0x34,0xd8,
- 0xc8,0x95,0x62,0xb8,0x4,0x14,0xc8,0x82,0x47,0xc5,0x3b,0x65,0x79,0xd4,0x21,0xd,
- 0x82,0x2f,0x90,0xd4,0x23,0xb5,0xcd,0x18,0x94,0xc1,0x4b,0x75,0x52,0x28,0xdd,0xd4,
- 0x4,0xed,0xd4,0x2c,0xf8,0x2,0x29,0x38,0x9c,0x62,0xeb,0x54,0xa5,0x98,0xa,0xc3,
- 0xb1,0x19,0x53,0xad,0x3f,0x39,0x68,0xa6,0x72,0x4,0xb7,0x42,0x38,0x82,0xed,0x69,
- 0x81,0x57,0x70,0xaf,0x1a,0x8d,0x4f,0x7b,0xb8,0xba,0xf3,0x11,0x34,0x33,0x41,0xc,
- 0x54,0xfe,0x7a,0x1e,0x60,0x60,0x84,0x1e,0x8,0x84,0x35,0x30,0x82,0xba,0x64,0x13,
- 0xf7,0x2a,0xa8,0x2b,0xc4,0x87,0x64,0x68,0x3,0xbc,0xea,0xb2,0x30,0x18,0x3,0x87,
- 0x75,0xd8,0x28,0x10,0x52,0x68,0x8d,0x54,0xda,0x34,0xcb,0x4a,0xbd,0x56,0x26,0xcd,
- 0x56,0x4d,0x95,0xd2,0x4,0x85,0x8a,0xa0,0x3b,0x3,0x2c,0x30,0xd7,0x0,0xd3,0x2c,
- 0x74,0xad,0xd0,0x27,0x31,0x3,0xa9,0x90,0x3,0x37,0x8,0x82,0x1b,0x18,0x4,0xe0,
- 0xb1,0xbc,0x17,0x91,0x55,0x5a,0x61,0xa8,0x91,0xa8,0x87,0x79,0x88,0x23,0x70,0x42,
- 0xc8,0x6f,0x58,0x85,0xa,0x68,0x84,0x2c,0x70,0xd9,0x1e,0xf8,0x4,0x71,0xf0,0x8d,
- 0x17,0x71,0x89,0x64,0xf8,0x83,0x25,0x30,0x2,0x38,0x50,0xc2,0x31,0xb0,0x82,0x31,
- 0xf8,0x82,0x28,0x18,0x3,0x8a,0x5,0x55,0xc4,0x9,0x50,0x6a,0xc5,0xd8,0x25,0xc5,
- 0x54,0x6d,0xed,0xd8,0xef,0x73,0x3c,0xc3,0xd9,0xa9,0x62,0xab,0x8e,0xd,0x73,0x50,
- 0x93,0xb5,0xbf,0xf1,0x20,0xdb,0xac,0x20,0x84,0x2f,0x18,0x84,0x1a,0x58,0x83,0x1d,
- 0x20,0x81,0x1,0x52,0xb3,0xf3,0x41,0x89,0x10,0xd5,0x89,0x69,0x7b,0xb,0x35,0xdc,
- 0x9b,0x61,0x5,0x6,0x24,0x40,0x84,0x1b,0xe8,0x2,0xc4,0x8c,0x4,0xa7,0x93,0x1d,
- 0x3c,0x62,0x6,0x46,0x20,0x1,0x38,0xc8,0x81,0x26,0x70,0xda,0x5,0xfd,0xd1,0x20,
- 0x1d,0x52,0x50,0x7d,0xd4,0x61,0xc4,0xda,0x3c,0xb4,0x54,0x8d,0xcd,0xd4,0x28,0x5d,
- 0xc6,0x29,0x95,0xa0,0x33,0xd0,0xb3,0x38,0xa8,0xa0,0xb,0x4a,0x59,0xcf,0x30,0xdb,
- 0xfe,0x98,0x9c,0x83,0x39,0x30,0x3,0x75,0xed,0x20,0x36,0xe8,0x2,0x4a,0x20,0x33,
- 0x87,0x24,0x4,0x11,0x80,0x36,0xbb,0xc1,0x39,0xca,0x71,0x33,0xce,0x43,0x1e,0xd6,
- 0xea,0x86,0x6f,0x70,0x86,0x48,0x48,0x81,0x41,0xe0,0x3,0x55,0x41,0x82,0x64,0x20,
- 0x28,0xba,0xc9,0x83,0x25,0x18,0x84,0x15,0xe8,0x83,0x29,0x8,0x3,0xa6,0x75,0x5c,
- 0x69,0xed,0x2,0x21,0x7d,0x54,0x2f,0x88,0x2,0xca,0x3d,0xd2,0xac,0xa5,0xbb,0xad,
- 0xe5,0xd8,0xcd,0x4d,0x50,0x9,0xd2,0x8a,0x9d,0xca,0x8a,0xaa,0x50,0xd9,0x9,0x2d,
- 0x5d,0xee,0x30,0x83,0xd3,0x4d,0x5d,0x36,0x48,0x55,0x22,0x78,0x2,0xa4,0x30,0x3,
- 0x41,0x8,0x2,0x42,0xa0,0x80,0x9c,0x14,0xe,0xbd,0xd1,0x39,0xc5,0x40,0x9e,0x71,
- 0xa0,0x2f,0xa9,0xc4,0x23,0x67,0x28,0x5,0xa,0x20,0x41,0x23,0x58,0x82,0x3f,0x20,
- 0xc,0x82,0x70,0x4,0x24,0x8,0x4,0x26,0x60,0x83,0x29,0x78,0x1,0x2f,0x70,0x5c,
- 0x25,0x84,0xde,0x20,0x8d,0xda,0x28,0x88,0x48,0x23,0xbd,0x5e,0xcb,0xcd,0x58,0x28,
- 0xe5,0x5a,0xee,0xfd,0xbe,0x45,0xc5,0x8a,0x78,0x42,0x96,0xf2,0xd,0xcc,0xaf,0x18,
- 0x5d,0x76,0x12,0x5d,0xa6,0x30,0x3,0x3d,0x20,0x81,0xfd,0xdb,0xc4,0xfb,0x4d,0x31,
- 0xaa,0x34,0x89,0x77,0xe8,0x89,0x22,0x9c,0x0,0x3e,0x28,0x2,0x23,0x50,0x82,0x25,
- 0xf0,0xc7,0x3a,0xa8,0x3,0x32,0xa8,0x30,0x2f,0xb8,0x2,0x2c,0x88,0x2,0x49,0xfd,
- 0x2,0xa8,0xd,0xd2,0xc1,0x19,0xd2,0x26,0x50,0xe2,0xe7,0xa3,0x3e,0x26,0xb6,0xfe,
- 0x5c,0x6b,0xcd,0xd8,0x25,0xd5,0xd8,0x6d,0x4d,0x50,0x9,0xee,0xc8,0x89,0x13,0x61,
- 0xd3,0x19,0x8f,0xa5,0xd0,0xe2,0x2d,0x5e,0x8a,0x43,0x50,0x2,0x52,0xc0,0x9a,0xaa,
- 0x14,0x28,0xb0,0x9a,0x45,0xe4,0xc8,0x89,0x69,0x70,0x85,0x9,0x80,0x4,0x81,0x45,
- 0x84,0x35,0x10,0x85,0x27,0xe0,0xb2,0x5e,0xc,0x2,0xc4,0x89,0x56,0x9,0xb6,0x62,
- 0x9,0x36,0x52,0x25,0x76,0x3e,0xe6,0x6b,0x62,0x3f,0xc6,0x60,0xeb,0x8b,0x62,0x29,
- 0x76,0x1,0x2a,0xee,0xe0,0x45,0x6d,0x4b,0xc4,0xca,0xe2,0x29,0xf1,0xe2,0xb3,0x55,
- 0x8a,0x27,0xd8,0x1,0x3f,0x30,0xd3,0x77,0xa8,0x6,0x22,0x29,0x63,0x33,0xb6,0xbd,
- 0x13,0x6b,0x11,0x67,0xa0,0x85,0x16,0x20,0x81,0x40,0x60,0xcd,0x2f,0x80,0x8,0xbc,
- 0xeb,0x82,0x5,0xc5,0x63,0x3c,0x36,0x62,0xe8,0x4d,0x3e,0x3e,0x76,0x62,0x27,0x86,
- 0x62,0x25,0x25,0xe4,0x25,0x35,0x64,0x20,0x45,0x64,0x66,0x54,0xe4,0x45,0xde,0x8e,
- 0x46,0x1e,0x5f,0xc6,0xab,0x8a,0x27,0xd8,0x82,0x2c,0xf0,0x3,0xc,0x78,0x85,0xff,
- 0x18,0xab,0x33,0x46,0xb1,0x42,0x5b,0x7,0xd7,0x92,0x7,0x59,0x68,0x3,0x25,0x40,
- 0x4,0x88,0xc4,0x82,0x68,0xf6,0x82,0x2f,0xb0,0x82,0x1e,0x8d,0xde,0x53,0x2e,0x62,
- 0x3d,0x5e,0x41,0x56,0x6,0x64,0x57,0x16,0x64,0x58,0x8e,0xe5,0x52,0x9b,0xe5,0x54,
- 0xbe,0xe2,0x5b,0xc6,0xe5,0x13,0xd6,0x2d,0xd0,0x79,0x12,0x38,0x38,0x4,0x3d,0xe0,
- 0x2,0x2e,0x10,0x83,0x3f,0xf8,0x86,0xa1,0x62,0x90,0xfa,0x9a,0x45,0x9c,0xfe,0x28,
- 0xb4,0x99,0xf0,0xb,0x5b,0x0,0x3,0x31,0xf0,0xae,0x2a,0x10,0x37,0x2c,0xf8,0x82,
- 0x2c,0x30,0xc7,0x5e,0xc4,0xe6,0x54,0xde,0xe3,0x25,0xee,0x66,0x40,0x7e,0xe5,0xcb,
- 0x8d,0xe5,0x71,0xb6,0xe2,0x44,0x76,0x94,0x73,0xc6,0x30,0xf2,0x98,0xbc,0x97,0x31,
- 0x16,0x38,0xd8,0x82,0x1d,0x90,0x83,0xed,0xf1,0x84,0x79,0xde,0xa1,0x7a,0xb6,0xe7,
- 0x4c,0x46,0x8e,0x13,0x33,0x7,0x7a,0x80,0x11,0x5c,0x68,0x81,0x41,0xf0,0x82,0xe,
- 0x12,0xd9,0x81,0x2e,0x68,0x6c,0xce,0xe6,0x23,0xde,0x66,0x85,0x86,0xbe,0x21,0xf0,
- 0xe6,0x6f,0x1e,0x64,0x29,0x86,0xe8,0x5a,0x9e,0x38,0x30,0x3b,0x67,0xaf,0xb0,0xe8,
- 0x64,0xc1,0x68,0x35,0x8,0x98,0x1e,0x68,0x84,0xf,0xd8,0x83,0x7,0xf0,0x4,0x79,
- 0xc8,0x86,0x90,0x76,0x61,0x63,0x1e,0xe,0xfa,0xd8,0x9b,0x6f,0x38,0x8,0x15,0xb8,
- 0x52,0x2c,0x8,0x83,0x81,0x7e,0x82,0x27,0xb8,0xe6,0x53,0x46,0xe8,0x9a,0xee,0xe3,
- 0x9b,0xce,0xe9,0x6f,0xe,0x67,0xba,0xeb,0xe9,0x22,0x96,0x68,0xce,0xa0,0x68,0x74,
- 0xbe,0xe8,0x98,0x1,0x30,0x32,0xa0,0x85,0x4d,0x50,0x84,0xc,0x90,0x82,0x4d,0x28,
- 0x87,0x78,0xd8,0xa1,0xf8,0x94,0xea,0x92,0xce,0x9,0xe5,0x82,0xd,0x75,0x90,0x87,
- 0x52,0x20,0x3,0x32,0x7a,0x5a,0x69,0x85,0x60,0x99,0xe,0xeb,0x55,0xb6,0xe9,0x3f,
- 0xbe,0xe9,0x86,0xde,0x69,0x59,0xee,0xda,0x29,0xa5,0xec,0xca,0x6e,0xeb,0xea,0x48,
- 0xd9,0xc9,0x3b,0x2,0xf1,0xcb,0x82,0x41,0x48,0x1,0xb9,0x26,0x87,0xfe,0x52,0x10,
- 0x3d,0x28,0x50,0x82,0xbc,0x66,0x1e,0x77,0xd0,0x5f,0xb7,0xea,0x6b,0x14,0xab,0x24,
- 0xcf,0x13,0x7,0x56,0xa8,0x80,0x3a,0x30,0xce,0x2f,0xb8,0xd2,0x26,0xb8,0xe3,0x53,
- 0xbe,0x5a,0xe5,0x7b,0xbe,0xdd,0x7e,0xec,0xdb,0x3c,0x6b,0x8d,0xdd,0xde,0xca,0x16,
- 0xee,0xe1,0xbe,0x6c,0x29,0xf1,0xaf,0xef,0xe8,0x54,0x3f,0x20,0x83,0x37,0xa0,0x5,
- 0x6a,0x10,0x7,0x5c,0xe0,0x2,0x28,0xd8,0x83,0x14,0x28,0x6,0x72,0x68,0x87,0x7a,
- 0xe8,0x13,0xd5,0x5e,0xed,0xe1,0xd8,0xce,0x77,0xf0,0xb,0x20,0x8a,0xed,0x1d,0x28,
- 0x83,0x3d,0x28,0x81,0x38,0x98,0x66,0x6c,0xce,0xed,0xe3,0xe3,0x6d,0x57,0xf6,0xed,
- 0xb3,0xd6,0xe0,0x71,0x1e,0x6e,0xcb,0x2e,0xee,0x5d,0x2e,0x83,0x1e,0xd,0x84,0x46,
- 0x40,0x82,0x5f,0x70,0xaf,0x6f,0x60,0x6,0x1a,0xf8,0xcf,0x1a,0x38,0x5,0xf7,0xba,
- 0x87,0x2d,0xd2,0x8b,0xed,0xae,0xc5,0xc8,0xc9,0x89,0xcc,0x79,0x9e,0x4e,0x90,0x80,
- 0x3a,0xc8,0x82,0x1c,0xf8,0x95,0xf3,0xc6,0x6d,0xb,0x56,0xef,0xf5,0xee,0x6d,0x18,
- 0x74,0x68,0x29,0x7e,0xef,0xc9,0x8e,0x6f,0xf9,0x6e,0xeb,0x9b,0xe9,0xe,0x2e,0xb,
- 0x84,0x3a,0xb0,0x83,0xd8,0x1,0xe,0x18,0x91,0x4,0x31,0xe0,0x99,0x36,0x70,0x93,
- 0x77,0x58,0x9f,0x2,0x37,0x70,0xe2,0x98,0x1c,0x15,0x3b,0x19,0x79,0xe8,0x4,0x90,
- 0xe3,0x83,0xf,0x38,0x1c,0x99,0x4e,0xef,0xe5,0xb3,0xf0,0x8b,0xb4,0xdc,0xdf,0xde,
- 0x70,0xe,0xee,0x70,0xf,0xff,0xf0,0xf0,0xe8,0x54,0xd,0xb5,0xfe,0x3,0x65,0xc0,
- 0x9a,0x83,0xf1,0x86,0x83,0x80,0x83,0x41,0x58,0x61,0xfe,0x1b,0x12,0xf8,0x30,0xf0,
- 0x6a,0x71,0xd,0xb4,0x12,0x90,0x4c,0xe8,0x1,0x31,0x18,0x4,0xfd,0xe4,0x71,0xa,
- 0xf7,0xf1,0xf5,0x6,0x72,0x8c,0x74,0xef,0xd,0x2e,0xf2,0x22,0xff,0x70,0x1,0xb,
- 0xf,0xa2,0x23,0x3,0x24,0x58,0x8b,0xd9,0xc8,0x89,0x7c,0xb0,0x86,0x69,0x78,0x3,
- 0x52,0xac,0x81,0x37,0x48,0x6,0x4b,0x49,0x18,0xd8,0x30,0x70,0xb8,0x52,0x31,0x3,
- 0xb2,0x86,0x37,0xc1,0xb7,0x1d,0xf0,0xd1,0x30,0xb7,0x58,0xb,0xbf,0xf0,0x4a,0x15,
- 0x72,0x34,0x4f,0xf3,0xf8,0x6e,0x6b,0xef,0x5,0x61,0xa2,0x6b,0x84,0xa6,0xfc,0x11,
- 0xd7,0x68,0x31,0x7b,0xc0,0x7,0x56,0x10,0x3,0x48,0x4c,0x81,0x52,0x60,0x6,0x84,
- 0x49,0xb1,0xed,0x6e,0x18,0x77,0xe3,0x87,0x62,0xd2,0x8b,0xbe,0x20,0x87,0x7f,0x9d,
- 0x3,0x6f,0x45,0x6f,0x31,0x57,0xf4,0x32,0xcf,0x70,0xad,0x75,0xf4,0x47,0x17,0x6e,
- 0xa,0x8d,0x8a,0x26,0xec,0xb6,0x35,0x98,0x3,0x30,0x28,0xc,0xac,0xc9,0x9,0xf7,
- 0x49,0x7,0x7b,0x38,0x7,0x6a,0x50,0xa6,0x24,0x18,0x4,0xa,0xc0,0x85,0x6f,0xb8,
- 0x6,0xce,0x8b,0xf1,0x2b,0xd4,0x7,0x16,0x89,0xb7,0xdc,0xf1,0x8b,0x64,0x70,0x4,
- 0x1c,0xc0,0x2c,0x25,0xb4,0x66,0x8b,0xe1,0xe3,0x20,0x50,0x3e,0x29,0xf8,0x71,0x20,
- 0x77,0xbb,0xb9,0xcb,0x3e,0xbb,0x63,0x52,0xe0,0xd6,0x5c,0x5b,0x57,0x77,0x5b,0x8e,
- 0x8,0x28,0x31,0xee,0xf8,0x8b,0xbf,0xb5,0xed,0x2,0x8a,0xfe,0x8b,0x2,0x3a,0x10,
- 0x83,0x1e,0x40,0x2,0x11,0x93,0x9d,0x86,0xca,0x7,0xc9,0x41,0x7,0x7d,0xc8,0x5,
- 0xc,0xe0,0x82,0x81,0xc6,0x81,0xea,0x8e,0x7,0xb8,0x70,0x8c,0x9b,0x40,0x43,0xb8,
- 0x2,0x92,0x86,0x9a,0x1c,0x22,0xa1,0x89,0x66,0x40,0x3,0x32,0x68,0xdb,0x2d,0x98,
- 0x83,0x5f,0xee,0x82,0xef,0xda,0x10,0x1b,0x60,0x2,0x48,0x99,0xbe,0x32,0x7f,0x65,
- 0x59,0xda,0xab,0x5a,0x32,0x1,0x7f,0xc9,0xa5,0x15,0xe0,0x0,0x94,0xe7,0x0,0xf8,
- 0x5e,0x77,0xca,0x9e,0xb8,0x75,0xa6,0x8e,0x94,0x15,0x84,0x6f,0x64,0x2,0x35,0x88,
- 0x82,0x42,0x20,0x4,0xeb,0xac,0x80,0x50,0x38,0xb7,0xd5,0x1a,0x92,0x6a,0x48,0x5,
- 0x2,0x18,0x4,0x41,0xa8,0xc6,0x68,0x28,0x87,0xfe,0x3b,0xb1,0xf3,0x49,0x78,0xd3,
- 0xb4,0x1b,0x34,0x14,0xd4,0x86,0xa,0x86,0x1e,0x38,0x4,0x8b,0xbf,0xf8,0x2c,0x70,
- 0x81,0xb3,0x3,0x2f,0x26,0x18,0xbb,0x8f,0x97,0x75,0x41,0xa6,0x25,0x5a,0x3a,0xb5,
- 0xb0,0x37,0x1,0xe,0x20,0xfb,0x95,0xe7,0xf0,0x96,0x77,0xf9,0xf,0x91,0x83,0x6,
- 0x15,0x5d,0xb0,0x78,0x82,0x2c,0x28,0x3,0x3a,0xc0,0x1f,0x7,0xae,0x81,0x40,0x20,
- 0xd,0x79,0xa8,0x1b,0x4c,0xe6,0x1a,0xdd,0x79,0x6,0x49,0xa0,0x1,0x31,0x50,0xf,
- 0x46,0xc0,0x7b,0x5b,0x41,0x31,0x9d,0x63,0xf8,0x7b,0x6e,0x28,0x93,0xc0,0x87,0x5b,
- 0x68,0x81,0x46,0x20,0x81,0x5f,0xfe,0x0,0x2f,0xf8,0x7a,0x1b,0x60,0xbe,0xe3,0xe3,
- 0x7a,0x71,0xf7,0xfa,0xaf,0x17,0x7b,0x46,0x29,0x7b,0xfe,0xb2,0x67,0x79,0xb4,0x2f,
- 0xe7,0x88,0x8,0x83,0x68,0x1e,0xba,0x63,0x5b,0x40,0x65,0x73,0x83,0x33,0xb0,0x1,
- 0x17,0x80,0x83,0x39,0x48,0x4c,0x71,0xf0,0x91,0x6e,0xb0,0xbd,0x94,0xc0,0x86,0xc5,
- 0x88,0x8d,0xbe,0xa5,0x81,0x49,0x8,0x81,0x1b,0xd8,0x84,0x98,0x80,0x8f,0xd7,0xd8,
- 0x22,0x33,0x1c,0xe,0x7a,0x35,0xe6,0xe3,0x38,0x7,0x79,0xb8,0x85,0x4,0x20,0x83,
- 0x22,0x48,0x82,0x23,0x80,0x2,0xde,0x6e,0x2,0x1e,0xe0,0x81,0x50,0x3,0xf9,0x6f,
- 0xd6,0xfc,0xcd,0xef,0x7c,0xcf,0x3f,0x7b,0xd0,0xf,0x7d,0x88,0xf8,0x52,0xad,0x2e,
- 0x3,0x76,0x45,0x36,0x41,0x10,0x84,0x31,0x0,0x62,0x39,0x50,0x2,0x1c,0x8,0xd6,
- 0xf7,0x40,0xc3,0x33,0x94,0x71,0x7f,0xa0,0x21,0x59,0x40,0x82,0x22,0x50,0x88,0x19,
- 0x10,0x5,0x1f,0xd1,0x86,0xc4,0x50,0x8c,0xe2,0x28,0xc8,0xc,0x84,0x4f,0xa7,0x7,
- 0x8,0x7f,0x2,0xdf,0x7d,0x93,0xc7,0x8a,0x2,0x17,0x28,0x86,0x6c,0x1c,0x61,0x22,
- 0x44,0x8,0x13,0x1e,0x2f,0x5e,0x40,0x19,0x62,0xf1,0x22,0xc6,0x1c,0x1a,0x35,0xda,
- 0x30,0xe1,0xf1,0x23,0x87,0x90,0x22,0x45,0x96,0x28,0x39,0xe6,0x24,0xca,0x94,0x2a,
- 0x57,0xb2,0x4c,0xa9,0xe6,0x25,0x4c,0x35,0x61,0xae,0x5c,0xf1,0xe2,0x65,0xc,0x1c,
- 0x33,0x69,0xb6,0xac,0x11,0x94,0x85,0x8e,0xa5,0x23,0x45,0xc0,0xd4,0x12,0x87,0xf,
- 0x9f,0xbe,0x6b,0x2,0xf9,0x9,0xf4,0x67,0x4f,0x5f,0x53,0x7f,0x50,0xd7,0xe9,0xfb,
- 0xa6,0x4a,0x6,0x10,0x27,0x4e,0x1e,0x94,0x92,0xfe,0x7,0x15,0x9b,0x53,0x74,0xf6,
- 0xc6,0xda,0x6b,0xca,0x8f,0x69,0xd4,0xb4,0xfe,0xf6,0x35,0xdd,0xa7,0xef,0x9d,0x37,
- 0x7c,0xa0,0x26,0xb0,0xb8,0xe3,0xc5,0x61,0x96,0x2c,0x4d,0xae,0x4c,0xb4,0x81,0xf1,
- 0xef,0x90,0x8d,0x1a,0x3f,0x82,0x1c,0x69,0xb8,0x64,0x89,0x96,0x8a,0x17,0xab,0x8c,
- 0x9,0x33,0x8c,0xcd,0x33,0x5e,0x5e,0x5a,0xa9,0xc,0x7,0x4e,0x8d,0xcb,0x22,0x2,
- 0xfd,0xfa,0x76,0xb4,0x1b,0xbe,0xa5,0x68,0x9d,0xea,0xd3,0xb7,0x4e,0x20,0xb6,0xd3,
- 0xa5,0xf1,0x71,0xaa,0x3b,0x83,0xf,0x99,0x53,0xd3,0xf4,0x79,0xeb,0x6,0x55,0x2d,
- 0xee,0xb4,0xeb,0x4e,0xb,0xdc,0x2d,0x50,0xdf,0x39,0x7c,0x95,0xc4,0x24,0x91,0x82,
- 0xd7,0xca,0xde,0xbe,0x80,0x33,0xa,0x26,0x6c,0xc2,0x30,0x74,0xc4,0x8c,0xa7,0x2b,
- 0x76,0xc,0xf3,0xa4,0x1a,0x2f,0x67,0xb6,0x9f,0x9,0xd3,0x5,0x4e,0x16,0x32,0x3d,
- 0x1a,0x9,0xc3,0xa7,0xe,0xe9,0xd4,0xb3,0xa3,0xa5,0x9a,0xf6,0x77,0x9a,0xad,0xbf,
- 0x77,0xef,0xd4,0x71,0x9a,0x0,0xa9,0x48,0x8a,0x16,0xaf,0xbc,0xd1,0x2e,0xed,0x4f,
- 0xfd,0x59,0xec,0xdd,0x96,0x9b,0x7b,0xbc,0xe5,0xe3,0xe,0x3b,0xe8,0xc0,0x55,0x9f,
- 0x18,0x35,0x30,0xc1,0x44,0x10,0x7b,0x55,0x61,0x43,0x45,0xcb,0x59,0x24,0x58,0xe,
- 0xce,0x41,0x37,0x92,0x7,0xd2,0xb1,0xf4,0x5,0x88,0x21,0x82,0x68,0xdd,0x4b,0xd4,
- 0x9d,0x64,0xc5,0x13,0x4f,0x94,0x11,0xc6,0x19,0x6c,0xf4,0x51,0x45,0x1c,0x7b,0x14,
- 0xb1,0x6,0x12,0x8c,0x24,0x23,0xf,0x7a,0xfe,0x66,0xa9,0xf7,0x5b,0x69,0x3,0xa,
- 0x44,0x56,0x38,0xfa,0x38,0x73,0x49,0x1b,0x3d,0x3c,0x31,0x8,0x5,0xa4,0x78,0x16,
- 0xd7,0x3d,0xf5,0xcc,0x53,0xf,0x3c,0x68,0xd9,0x23,0x16,0x81,0x69,0xe5,0xc3,0xce,
- 0x38,0xf6,0xbc,0x83,0xf,0x33,0x99,0x18,0xa0,0x47,0x8,0x1f,0xb0,0xf1,0x9c,0x17,
- 0x47,0x98,0x79,0xc4,0x45,0x18,0x62,0x48,0xd8,0x86,0x22,0x79,0xf0,0xe6,0x9b,0x2d,
- 0x89,0x28,0x22,0x89,0x6a,0x98,0x38,0x86,0x15,0x3b,0x65,0xf1,0x85,0x17,0x71,0xf4,
- 0x31,0x5,0x10,0x2b,0x40,0xd2,0x42,0x1e,0xce,0x18,0xe5,0x23,0x80,0x4d,0xf5,0xe8,
- 0xa3,0x53,0x63,0xf9,0xa3,0xd,0x3d,0xe4,0x5c,0xc2,0xc8,0x13,0x61,0x70,0x31,0x1,
- 0x28,0x9e,0x5d,0x93,0x8d,0x93,0x4f,0x32,0x15,0x4e,0x96,0x65,0x55,0xd9,0x14,0x59,
- 0x53,0x82,0x56,0x4c,0x26,0x34,0x14,0xb1,0x87,0xd,0x7b,0xe4,0x10,0xc2,0x17,0x52,
- 0x98,0x99,0xa6,0x9a,0x1b,0xb1,0xd9,0x26,0x7,0x70,0xc6,0xf9,0xe1,0x9c,0x20,0xde,
- 0xd9,0x52,0x9e,0x73,0x3c,0x61,0x85,0x17,0x7c,0x1,0x1,0x84,0x22,0x13,0x60,0xe2,
- 0xc,0x35,0xf8,0xd0,0x33,0xaa,0x80,0x8c,0xea,0x33,0xd6,0x3a,0xf7,0xcc,0x13,0x4f,
- 0x39,0x9a,0x98,0xc1,0x3,0x14,0x52,0xc8,0xe0,0x9,0x8e,0xf8,0xb4,0xe3,0x24,0x37,
- 0xe6,0xac,0x13,0xe,0x59,0xd0,0xfe,0x98,0x25,0x3a,0x6c,0xe9,0x83,0x8f,0x33,0x60,
- 0xf8,0xf1,0xc1,0x1e,0x2b,0x7c,0x31,0x48,0x11,0xb2,0xa2,0x79,0x61,0xad,0x83,0x15,
- 0xd6,0xa6,0xae,0x1e,0xc8,0xd9,0xeb,0xfe,0x17,0xbf,0xb2,0x64,0xc5,0x16,0x87,0xc,
- 0x62,0xc5,0x11,0x5e,0xdc,0x71,0xc6,0xa5,0x98,0x7c,0xa3,0x8e,0x3a,0xf4,0xdc,0x3,
- 0x6d,0x8f,0x69,0x2d,0xba,0x4f,0x3d,0xf5,0xb4,0x23,0x4f,0x34,0x94,0x70,0x10,0x47,
- 0x4,0x93,0x28,0xd1,0x46,0xb8,0x16,0x33,0xe5,0x4e,0xa9,0xea,0x3a,0xc5,0xee,0x7f,
- 0xf7,0x9c,0x97,0xcc,0x1b,0x32,0xdc,0x20,0xc7,0xd,0x44,0x64,0xa1,0x2f,0xad,0xfd,
- 0xde,0xa,0xb0,0xae,0x3,0xf7,0x6a,0xf0,0xc1,0x84,0xd0,0x41,0x44,0x17,0x74,0xc0,
- 0xe1,0xc7,0x12,0x9e,0x9c,0xe7,0xcd,0x3a,0xfc,0x98,0xa3,0xd6,0xa2,0xfe,0x51,0xbd,
- 0xa8,0x3f,0xe6,0xdc,0x83,0x8f,0x38,0xc8,0x6c,0xd1,0x84,0xd,0x6c,0xa8,0x1,0x47,
- 0xf,0x79,0x34,0x7b,0x1e,0x54,0x7,0xa6,0xab,0xee,0xb4,0xd6,0x8,0x74,0xf,0x53,
- 0xe7,0x31,0x13,0x49,0xcd,0x5c,0x74,0x71,0xc3,0x99,0x3d,0xd7,0xfa,0xf3,0x86,0x1,
- 0xb,0x4d,0xf0,0xd0,0x26,0x86,0xc1,0x3,0x1b,0x77,0xd,0xb2,0x46,0xb,0x28,0x9c,
- 0x62,0xde,0x3b,0x65,0xa5,0xc3,0x54,0x3e,0x4f,0x91,0x55,0x35,0x6e,0x19,0x67,0xed,
- 0x4f,0x38,0xde,0x8,0xa3,0x41,0xa,0x74,0x34,0xb1,0x48,0x14,0x56,0xe8,0x51,0xc7,
- 0x1f,0xcc,0x1c,0x15,0xe,0x3a,0xfe,0xb8,0x93,0x8e,0xcb,0x3c,0xda,0xb6,0x1b,0x3f,
- 0xbb,0x81,0xf6,0x4d,0x26,0x14,0xe4,0x5b,0xd1,0xac,0xfc,0xba,0xb0,0x3b,0xef,0xbb,
- 0xf3,0xd,0x9d,0xdf,0xbc,0x2,0x1e,0x38,0x75,0x61,0x4c,0x31,0xc5,0x15,0x72,0xe8,
- 0xd1,0x43,0x1b,0xa8,0xc8,0x73,0xfe,0xde,0x3b,0x7,0xba,0xc3,0x72,0xa9,0xd3,0x52,
- 0x1e,0x95,0x3b,0x52,0x39,0x7b,0xcf,0x3d,0xf4,0xbc,0xe5,0xb,0x6,0x7e,0xe8,0xb1,
- 0x3,0x21,0x2e,0x10,0xa2,0x2,0x17,0x62,0xd0,0x20,0x89,0x32,0xef,0xe8,0x13,0xce,
- 0x7f,0xf0,0xd4,0xd3,0xba,0x3f,0xde,0xbf,0xa5,0x3a,0x36,0x52,0xbf,0x4b,0x4d,0x29,
- 0x13,0x44,0x10,0x7,0x14,0x72,0x17,0x98,0x1c,0xf4,0xae,0x77,0xbf,0x33,0x4c,0xf0,
- 0x84,0x37,0x3c,0x10,0x55,0xc6,0xa,0x63,0x88,0x89,0x65,0x2e,0xf3,0xc0,0x16,0xf5,
- 0xa1,0xf,0x3c,0xc8,0x82,0x12,0x70,0xb0,0x8a,0x70,0x75,0x3,0x1d,0xd3,0x9b,0xde,
- 0xe4,0xaa,0x66,0xb9,0x7c,0xfc,0x87,0x1f,0x4f,0xd1,0x7,0x3d,0x52,0x28,0x1f,0x62,
- 0x88,0x81,0xb,0x5c,0xe8,0x89,0x15,0xb4,0x10,0x84,0x30,0x44,0xe1,0xb,0x45,0x90,
- 0xc1,0x1b,0x88,0x81,0x8f,0xc6,0xf1,0x3,0x1e,0x51,0xd2,0x98,0x8,0xfd,0x41,0xc2,
- 0x14,0xaa,0x63,0x5a,0xa9,0x33,0x87,0xd6,0x8e,0x62,0x95,0x9,0xe4,0x4c,0xa,0x39,
- 0xd0,0x81,0xd,0x6c,0xa0,0x91,0x9c,0x11,0x81,0x8,0x2e,0x98,0x41,0xc,0x62,0x70,
- 0x40,0xe,0xc1,0x29,0x3,0x5d,0xf8,0x22,0x18,0xbb,0x50,0x30,0x96,0x90,0xc8,0xa,
- 0x62,0x10,0x3,0x9f,0x6c,0xe2,0x5,0x2b,0xd4,0x20,0xd,0x3b,0x21,0x44,0x21,0xaa,
- 0x70,0x3c,0xf,0xc8,0x21,0x10,0x38,0xa8,0x5,0x3e,0xf8,0x53,0x2a,0x51,0x89,0x70,
- 0x40,0x8b,0xb2,0x47,0x3e,0xce,0x62,0xae,0xf8,0xac,0xe6,0x17,0x8d,0x90,0xc1,0x20,
- 0xc6,0x50,0x86,0x20,0xa0,0xfe,0x24,0xc,0x34,0xec,0x42,0x16,0x52,0xf0,0x86,0xf2,
- 0x4c,0xe3,0x1c,0xa6,0x31,0xc7,0x59,0x54,0xe3,0xbe,0x3f,0x2,0x92,0x84,0x3c,0xf2,
- 0xa4,0x7b,0x7a,0xf4,0xe,0x5e,0x28,0xe0,0xd,0x45,0xd0,0x41,0xc,0x46,0xe0,0x84,
- 0x17,0xe4,0x80,0x8,0x35,0xd8,0x81,0x11,0x6e,0x50,0x82,0x13,0x9c,0x20,0x6,0x88,
- 0xb9,0x25,0x62,0xba,0x98,0x81,0x5d,0x5a,0x20,0x8c,0x61,0x6c,0x49,0x19,0xb7,0xb0,
- 0x5,0x3e,0x61,0x1,0xb,0x67,0x18,0x83,0x19,0x76,0x90,0x86,0x43,0x94,0xa1,0x9,
- 0x72,0x4c,0x9e,0x11,0x90,0x80,0x47,0x7c,0x58,0x63,0x8f,0x81,0x64,0x8a,0xe5,0xa2,
- 0xd2,0xa3,0xb1,0x4,0xd2,0x87,0xfe,0x40,0x47,0x90,0xf0,0x81,0xc,0x4c,0x50,0x0,
- 0x11,0x84,0x80,0x50,0x10,0x7c,0x35,0x6,0x47,0x8e,0xe1,0xb,0x70,0x20,0x43,0xb,
- 0x7e,0x61,0x1e,0x4b,0x66,0x6d,0x6a,0xeb,0x70,0x9f,0x6d,0xb6,0xc9,0x4d,0x50,0x46,
- 0xc5,0x37,0xee,0x11,0x88,0x31,0xec,0x40,0x17,0x43,0x38,0xe1,0x4,0x53,0xe0,0x80,
- 0x2b,0x61,0x29,0x4b,0x5a,0x8e,0x0,0x97,0xb8,0xd4,0xa5,0x5,0x22,0xea,0x4b,0x30,
- 0xde,0xc9,0x8c,0x68,0x54,0x63,0x77,0xac,0x20,0x8,0x33,0xd4,0xc0,0xa,0x84,0xd8,
- 0x83,0xb,0xe0,0x40,0x2,0x24,0x0,0xe3,0x28,0xea,0x10,0x22,0x59,0x48,0x18,0x20,
- 0x45,0xf9,0xa7,0x6a,0x80,0xcc,0x5a,0x26,0xe5,0x83,0xf,0x65,0x60,0xa2,0x5,0x34,
- 0xa8,0x1,0x1d,0xe4,0xb0,0x1,0x3a,0xa8,0x13,0x32,0x61,0x18,0x83,0xa,0xc4,0x50,
- 0x87,0x4,0xe0,0xe2,0xfe,0x28,0xee,0xeb,0x8d,0x6a,0x38,0xb9,0xb6,0x2a,0xa5,0x26,
- 0x3e,0xcc,0xc0,0xc4,0x4,0x42,0x0,0x84,0x17,0x80,0xa0,0xa,0xad,0x2c,0x42,0x11,
- 0x6e,0xd0,0x81,0x11,0x9c,0xc0,0xa1,0xf,0x7d,0x13,0x2f,0x25,0x3a,0xd1,0x2e,0xdc,
- 0xe9,0xb,0x59,0x18,0xd6,0x3a,0x6d,0x12,0x86,0x20,0x10,0xa1,0xc,0x82,0x10,0x82,
- 0x8,0xe0,0x80,0x88,0x16,0xfc,0x61,0x18,0xf8,0xf8,0x86,0xca,0x4,0xe2,0xe,0x95,
- 0xf2,0xe3,0x62,0x2c,0x2d,0x8d,0xe4,0xf2,0x21,0x58,0xd1,0x50,0xe5,0xae,0xdf,0xc0,
- 0x84,0x1,0x2,0x81,0x8,0x11,0x8,0xe1,0x68,0x3c,0xb5,0x2,0x88,0x7c,0x1a,0x85,
- 0x2e,0xd4,0x40,0x9,0x43,0x7d,0x85,0x79,0xf8,0x73,0xbf,0x7f,0xa,0x51,0xb0,0x91,
- 0xb3,0x1a,0x6e,0xf6,0xc1,0x1b,0xf7,0x74,0xe3,0x3c,0xa5,0xc0,0x80,0x14,0xa0,0x0,
- 0x4,0x8,0xd8,0x40,0x7,0x37,0x78,0xed,0xa,0x3a,0xe0,0xd5,0xaf,0x7a,0x20,0xac,
- 0xbd,0x1c,0xeb,0xdf,0x42,0xd4,0x5,0x2b,0x64,0xa1,0x81,0x69,0x65,0xc3,0x7,0xc2,
- 0x40,0x8,0x11,0xec,0x60,0xe,0x28,0xc8,0x84,0x32,0x8e,0x82,0xf,0xb8,0x61,0x52,
- 0x75,0x9e,0xec,0x6b,0xf7,0x78,0x64,0x4d,0xd1,0xf0,0x3,0x1b,0xef,0x9a,0x86,0x3c,
- 0x18,0xd1,0x83,0x39,0xec,0x20,0xb,0x82,0xb0,0x2,0x11,0x8,0x41,0x84,0xca,0x44,
- 0xd6,0xa7,0x44,0x0,0x4f,0xa,0x1a,0x91,0x80,0x52,0x68,0x4a,0xb3,0x60,0xa9,0x1c,
- 0xa3,0x9a,0x92,0x9a,0x75,0xc0,0x87,0x3d,0xd3,0xc0,0x7,0x2e,0x30,0x20,0x2,0xd5,
- 0x1e,0xcb,0x6,0xfe,0x33,0x70,0xc1,0x6b,0x37,0xb0,0x82,0xd9,0x96,0x4,0xa2,0x62,
- 0x9d,0x68,0x6e,0x43,0xd4,0xc0,0xcb,0x58,0x81,0x45,0x36,0x30,0x4,0xf,0x36,0x80,
- 0x88,0x3a,0xe0,0xe0,0x11,0xc9,0xb8,0x2f,0x7f,0xfc,0x1,0xd,0x7e,0x80,0x70,0x2c,
- 0xb7,0xb1,0xd8,0x6f,0xf6,0x68,0x8f,0xec,0xa9,0x87,0x2a,0xfa,0xc0,0xee,0x23,0x7a,
- 0xa0,0x4,0x3d,0xc0,0x21,0xbc,0x74,0x50,0x41,0x19,0x98,0x90,0x97,0x31,0x42,0xc6,
- 0xb,0x43,0x38,0x2f,0x1c,0x52,0x90,0x8,0x1a,0x94,0xc2,0x19,0x38,0xda,0xec,0xe3,
- 0x76,0xf4,0x9b,0xdc,0xc0,0x87,0xbe,0xa2,0xed,0xd1,0x7d,0x85,0xf1,0x87,0x9,0x24,
- 0x61,0x5,0x5a,0x34,0xc1,0xa,0x6e,0xa0,0x2,0x15,0xc,0x98,0xc0,0x6,0xbe,0x2d,
- 0x82,0x15,0xa8,0xdb,0x93,0xe4,0xe4,0x9,0x70,0x18,0xc3,0x19,0x1e,0x7c,0x5,0x45,
- 0x24,0xa2,0x2,0x97,0x70,0x6,0x52,0xac,0x81,0xba,0xbd,0x6e,0x43,0xc4,0xfe,0xf1,
- 0xeb,0xb4,0x44,0x5c,0x42,0x7e,0x94,0x26,0x2e,0x99,0x40,0xc1,0x1c,0xd6,0xa0,0x2,
- 0x42,0x84,0x81,0x8,0x74,0xb0,0x42,0x11,0xc0,0xb3,0xa7,0x93,0x38,0x52,0x32,0x8b,
- 0x70,0x1,0x13,0x26,0x21,0x2,0x2e,0x50,0xe0,0x13,0x68,0xfe,0xc6,0x3b,0xa8,0xbb,
- 0x52,0xa9,0x10,0x48,0xb4,0x6a,0xe9,0x86,0xfb,0x66,0xa,0xa,0x2,0x88,0x60,0x5,
- 0x2b,0x80,0xb2,0x94,0xa9,0x4c,0xe0,0x12,0x5c,0x79,0xac,0x64,0xd5,0x72,0x88,0xbc,
- 0x10,0x6,0x2b,0x98,0x61,0xd,0xc3,0xea,0x13,0x10,0xf6,0xc0,0x5,0x3,0x84,0x22,
- 0x1a,0x5e,0xfe,0x41,0xd7,0x58,0x10,0xe4,0xe6,0x37,0xff,0x48,0xc4,0xa2,0x62,0x8a,
- 0x72,0x43,0x81,0xe7,0x1d,0x78,0x74,0x3,0x41,0x60,0xab,0xd2,0x66,0x4c,0x63,0x9b,
- 0xb8,0xe1,0x8,0x7b,0x8,0x83,0xb,0xe4,0xc0,0x4,0x38,0x24,0x40,0x13,0x76,0xc5,
- 0x47,0x38,0xe,0x94,0xa8,0x21,0xe7,0xc6,0x37,0xeb,0x68,0xaa,0xa3,0xba,0x11,0x17,
- 0x6a,0x98,0xa2,0x5,0x36,0xe3,0x9d,0xa,0x6e,0x50,0xe5,0x5b,0x76,0xa8,0xc0,0x60,
- 0xcd,0x40,0x44,0xb1,0x2c,0x46,0x5f,0x2d,0xb0,0x57,0x47,0x70,0x3,0x8a,0x5c,0x3d,
- 0x8,0x37,0xdc,0xc1,0x6,0x80,0x90,0xc1,0x27,0xe4,0x21,0xf0,0x38,0x53,0x6f,0xc4,
- 0xd9,0x3,0x61,0x69,0x22,0xfd,0x2c,0x94,0x92,0x85,0x1d,0x64,0x1,0xcb,0x96,0xc4,
- 0x61,0xa,0x14,0x34,0x42,0xf,0x8d,0x75,0xa4,0x23,0xcd,0x9a,0x17,0xbb,0xcd,0x3b,
- 0xa,0x18,0x95,0x8c,0x1a,0xbf,0x30,0x87,0xa,0xd8,0x8,0x29,0x63,0xd9,0x86,0x90,
- 0x39,0xab,0x2e,0xb2,0x64,0x2f,0x85,0x47,0xb1,0xc5,0x5,0x68,0x20,0x2,0x29,0x7c,
- 0x60,0x5,0x19,0xe0,0x0,0x6d,0xdf,0xbd,0x4b,0x78,0x1f,0x78,0xde,0xf5,0x26,0x98,
- 0xaa,0x85,0x60,0x6,0x33,0x6c,0x21,0xb,0x4c,0x90,0x82,0x22,0x8a,0xb0,0x9,0x71,
- 0x8,0xdc,0x62,0x83,0xf4,0xc7,0x36,0xb2,0x37,0x67,0xf7,0xbc,0xb7,0x29,0x91,0x1b,
- 0x8b,0xc3,0xc5,0x82,0x8e,0xb7,0xe0,0x83,0xdc,0x60,0xa8,0x83,0xab,0x1b,0x5c,0x4c,
- 0x47,0xf2,0x76,0xe3,0x5f,0xc,0x51,0x14,0x3c,0x6e,0x93,0x62,0x16,0x33,0x8,0x35,
- 0xa8,0xfe,0x43,0x1d,0x2a,0x90,0x5c,0x6f,0x88,0x65,0x1b,0xbd,0xa1,0x5f,0xaf,0x47,
- 0x1c,0x33,0x7a,0xdc,0x15,0x18,0x48,0xa0,0xc1,0x3,0xce,0x40,0x6a,0x87,0xea,0x6a,
- 0xe7,0x3b,0x8f,0xb7,0x2f,0x7f,0x4e,0xb0,0x66,0x7f,0x7,0xe,0x4f,0xc8,0x8b,0x1f,
- 0x26,0x90,0x8a,0x89,0x21,0xa5,0x49,0xf5,0xb8,0xc7,0xd4,0x4,0x82,0x49,0x6e,0x70,
- 0xe3,0x49,0x97,0x5f,0xcf,0xd5,0xc7,0x52,0xcd,0xb7,0x54,0xe5,0x1b,0xac,0xd0,0x40,
- 0xf,0x12,0x91,0x19,0x39,0xb8,0x0,0xb,0x18,0x2f,0x7b,0x16,0xc0,0x8,0xa2,0x8e,
- 0xab,0xdd,0xb,0xc5,0xf4,0x2,0x11,0xd6,0x90,0x82,0x3a,0x5c,0x0,0x19,0xfc,0x89,
- 0x74,0x54,0x16,0xee,0xb2,0x52,0xb9,0x83,0x1f,0x1d,0xbb,0x47,0x55,0x92,0x81,0x4,
- 0x19,0x7c,0x20,0xe,0x10,0xc8,0xb9,0xe1,0xf,0xdf,0xf3,0xb3,0x2b,0x5e,0x44,0x6b,
- 0xa5,0x43,0x19,0x74,0xe6,0x7,0x44,0x50,0xc0,0x69,0x48,0xe9,0x46,0xcc,0xda,0xe1,
- 0xbd,0x77,0x74,0xa3,0x1b,0x51,0xeb,0x94,0xe7,0x2f,0x56,0x9a,0xc1,0x1e,0xdc,0xc3,
- 0xfa,0x78,0x6,0x3e,0x64,0xd1,0x82,0x1d,0x1c,0x62,0xd,0x35,0x58,0xe4,0x10,0x54,
- 0x1d,0x86,0x2f,0xc0,0xbe,0xb,0xc7,0x9e,0xfd,0x6e,0x9d,0x9d,0xda,0x61,0x81,0x17,
- 0x6c,0xc0,0x20,0x64,0x81,0x11,0xbc,0xc1,0x5,0x94,0x7,0x7a,0xc,0xc8,0x7a,0x8c,
- 0x4a,0xcb,0x9c,0xc5,0xe5,0x65,0xc3,0xbb,0x8,0x83,0xf,0xdc,0x80,0x3,0x34,0x54,
- 0x2e,0xe9,0x5c,0xf4,0xf1,0x9c,0x5,0x3c,0xc8,0x44,0x55,0x1f,0x88,0x1c,0x9b,0x1b,
- 0xfe,0x74,0x1,0x11,0xf0,0x81,0x18,0xbc,0xc1,0x1f,0xc8,0xc3,0x7d,0x5,0x49,0xf6,
- 0x68,0x83,0x49,0x1d,0x5,0x6d,0x58,0x4c,0xc7,0x78,0x9e,0x54,0x70,0xd3,0xd4,0xad,
- 0x83,0x6d,0x14,0x84,0x2c,0x80,0xc1,0xe,0x50,0x42,0xd,0x34,0x16,0x13,0xdc,0x9b,
- 0x17,0xd4,0xd0,0x17,0xf1,0x16,0xb1,0x78,0x41,0x3a,0xed,0x56,0x5e,0xf4,0xd6,0x17,
- 0x5,0x41,0x17,0xa8,0xd1,0x6,0xc8,0x1,0x7e,0x2c,0xc1,0x2,0x1e,0xc5,0x6c,0xe8,
- 0x43,0xfe,0xe0,0x5d,0x53,0x7c,0x50,0x9,0xd1,0x83,0x67,0xfc,0x2,0x1,0x48,0xc1,
- 0xe0,0x91,0x5a,0x6d,0x75,0xa0,0xe1,0xc5,0xdb,0x83,0x30,0x41,0xe2,0x55,0xdf,0x17,
- 0x35,0x4c,0xe,0x78,0x81,0x1c,0xe4,0xc7,0x2f,0x9c,0x87,0xf9,0xb5,0x19,0x3a,0x1c,
- 0x5,0x35,0xc,0x43,0x2e,0xf4,0x82,0xe9,0xbc,0x8b,0x36,0x30,0xd7,0x3a,0xec,0x51,
- 0x9,0x45,0x49,0x61,0xc9,0x3,0x2e,0x54,0xc0,0x12,0x98,0xc1,0x8b,0xc9,0x81,0x1c,
- 0x4,0x81,0x22,0xa8,0xdd,0x11,0x36,0x50,0xc8,0x41,0x52,0x13,0xe6,0x85,0x15,0x3c,
- 0x61,0x10,0xb0,0x1,0xf,0x7c,0x80,0x1c,0xb8,0x52,0x20,0x20,0x41,0x51,0xe5,0x91,
- 0x69,0x4c,0x9a,0xba,0x70,0x4f,0xa3,0xe4,0xda,0x69,0x94,0x96,0x5c,0x3c,0x80,0xe,
- 0x74,0x8,0x7,0xa2,0x61,0x4,0xa8,0xe1,0x1a,0x86,0x91,0x8,0x6,0xa0,0x17,0xb4,
- 0x8a,0x1a,0x28,0xb,0xd3,0xe9,0x83,0xd4,0xb8,0x3,0x38,0xd8,0xc3,0x37,0x98,0xc2,
- 0x5,0x60,0x80,0xc,0x4c,0x0,0xd,0x80,0x82,0x32,0x94,0x6,0xfc,0xd8,0x3,0xfe,
- 0xae,0xa5,0x4b,0xf,0xc1,0xc3,0xc5,0x7c,0xc3,0x1e,0x4a,0x40,0x1d,0x4,0x2,0x11,
- 0x84,0x81,0x1b,0xb8,0x41,0xe,0x4,0x1,0xce,0x84,0x51,0x3,0x45,0xa1,0x4d,0x40,
- 0x61,0x5e,0x88,0x81,0x30,0x35,0xe1,0x17,0x81,0xd,0x1b,0x5c,0x81,0x27,0xbe,0x90,
- 0x6,0x30,0x82,0x5d,0x65,0xd8,0x86,0xb5,0x8e,0xf1,0xd5,0x83,0xf7,0xd8,0x3,0x3b,
- 0x38,0xdc,0x36,0xb8,0x85,0x37,0xa8,0x3,0x31,0x10,0xc0,0xd,0x7c,0x80,0x2e,0xa1,
- 0x61,0x6,0x44,0xc0,0x2c,0x46,0xd4,0x1a,0xb2,0xa1,0x2d,0x56,0x9f,0x3,0xb9,0x41,
- 0x13,0xec,0x1,0x11,0x28,0x1,0x2b,0x98,0x47,0x73,0x55,0x53,0x35,0xd8,0xc1,0x1b,
- 0x88,0xc1,0xd,0x48,0x1,0x20,0xb0,0x0,0x6,0x80,0xc1,0x30,0x0,0x87,0x58,0x38,
- 0x5c,0x4a,0x4d,0xdd,0x79,0x0,0x43,0x5,0xf4,0x0,0x19,0x64,0x81,0x1b,0x44,0x41,
- 0x18,0xe4,0x80,0x23,0x4d,0xe1,0x44,0x65,0xa2,0x1a,0x41,0x61,0x17,0x70,0xc1,0x25,
- 0xe6,0xc5,0x83,0x34,0x41,0x1c,0x44,0x51,0xe,0x1c,0x81,0xd,0x21,0xc2,0x1b,0x80,
- 0x1,0x32,0xe0,0xc3,0x34,0x2c,0x85,0x5a,0x48,0x8e,0xa3,0x98,0x45,0xc7,0xdc,0x63,
- 0x3e,0x3a,0x5c,0xb5,0xbc,0x8b,0x32,0x10,0x0,0xb,0x74,0x40,0x2c,0xee,0x9c,0x41,
- 0x66,0x65,0xbc,0x9d,0x9,0x57,0x1e,0x81,0xa9,0x1,0x4e,0x16,0xe0,0x54,0x19,0x94,
- 0x81,0x1e,0xa0,0x40,0x32,0xbc,0xc3,0x3e,0x44,0x89,0x3d,0x9c,0xc3,0x37,0x6c,0x2,
- 0xd,0x88,0x81,0x14,0xa4,0x56,0xb7,0x88,0xc1,0x12,0xd8,0x41,0xb3,0x84,0xfe,0x3,
- 0x49,0xa6,0xce,0x6e,0x9c,0x6,0x55,0x78,0x6,0x30,0xb4,0x1,0x9,0x20,0x42,0x8b,
- 0x85,0xc8,0xb1,0xb5,0xa1,0x3a,0x5,0x81,0x1a,0x35,0xc1,0x17,0x25,0x64,0x42,0x1e,
- 0x1,0xf,0x5c,0x1,0xf,0x34,0x41,0x13,0x98,0x9,0x11,0xdc,0x50,0x25,0xc0,0x9f,
- 0x7c,0xf4,0xd3,0x40,0x6c,0x12,0x60,0xa9,0x4e,0xfd,0x74,0xcf,0x3e,0xe0,0x63,0x3e,
- 0xfa,0x3,0x37,0x78,0x8c,0x3c,0x20,0xc3,0x3,0x38,0xc0,0x40,0xc6,0x1b,0x6b,0xc6,
- 0x1b,0x4,0xbc,0x66,0x57,0x9e,0x89,0xa9,0x99,0x1a,0x26,0xb2,0xda,0x21,0x30,0x2,
- 0x35,0xf8,0x22,0x3c,0x68,0xcf,0x2e,0x18,0x1,0x17,0x48,0x41,0x13,0x40,0x1,0x4d,
- 0x78,0x41,0x78,0xa0,0x0,0x1e,0x4d,0x8b,0xc3,0x15,0x88,0x54,0xd8,0xc6,0x7d,0xfd,
- 0x65,0x1d,0x20,0x82,0xa,0xb8,0xc1,0x5a,0xcd,0xe6,0x44,0x25,0xa6,0x64,0x4a,0x66,
- 0x6c,0xc6,0xe6,0x75,0x1e,0x41,0x13,0x78,0x4b,0x25,0x18,0x65,0x69,0x7c,0x1b,0x6f,
- 0x58,0xcf,0x1f,0x35,0x45,0xa,0xad,0xc,0x3e,0xda,0x83,0xd6,0x74,0x8f,0x3c,0xfc,
- 0xc2,0x3,0x58,0x40,0x17,0x81,0x40,0x6b,0xce,0xe7,0x6b,0x42,0x40,0x76,0x7a,0x25,
- 0x75,0xfa,0x52,0x16,0xc0,0x81,0x10,0x58,0x41,0x19,0xa4,0x1,0x26,0x20,0x45,0x3a,
- 0xc0,0x43,0x3a,0xd8,0x3,0x3e,0xf4,0x4f,0xec,0x15,0x4b,0x15,0x54,0x1,0x16,0x74,
- 0xc1,0x16,0xa0,0x80,0x26,0x14,0x51,0xae,0x15,0x48,0x69,0x9c,0xc3,0x79,0xc,0x43,
- 0x1e,0xe0,0x99,0x18,0xd0,0x81,0xb,0xb8,0x81,0x4d,0xe6,0xe7,0x17,0xfe,0x59,0xe7,
- 0x76,0x66,0xe7,0x10,0x9c,0x9,0x13,0x60,0x67,0x13,0xdc,0x80,0x8,0xf0,0x98,0x51,
- 0x46,0x9a,0x68,0xf9,0x53,0xb4,0x88,0x8a,0x3f,0xa0,0x62,0x68,0x3a,0x4a,0x5f,0x1d,
- 0x85,0x3c,0x80,0x1,0x17,0x58,0xe5,0x19,0xca,0xe7,0x7c,0xb2,0x66,0x7d,0xde,0x27,
- 0x88,0x86,0xd1,0x79,0x8d,0x97,0x15,0xac,0x41,0x80,0x76,0xc3,0xe3,0xa4,0x43,0x38,
- 0xe0,0x3,0x26,0x28,0xc1,0x9e,0x60,0xc1,0x15,0x2c,0xe8,0x15,0x44,0x81,0x50,0xe5,
- 0x81,0x38,0xbc,0x85,0xc1,0xb9,0x4b,0x5c,0xa8,0x43,0x32,0xe4,0x1,0xe,0x2c,0x41,
- 0x20,0x14,0x1,0x13,0x1c,0x9a,0x17,0xc,0x69,0x88,0x5e,0xa7,0x9a,0xde,0xe7,0x11,
- 0xc4,0xe5,0x1a,0x72,0xa7,0x9,0x9c,0xc1,0xd,0x88,0x81,0xf,0x4c,0xe4,0x51,0xf6,
- 0xc6,0x7b,0x8d,0x56,0x54,0xd4,0x63,0x2a,0x16,0x1f,0x3f,0xe4,0x11,0x3e,0xa8,0xc2,
- 0x4,0x88,0xc0,0x7,0xa4,0xe1,0x8f,0x2,0x29,0x3,0x30,0xc0,0x7d,0x32,0x66,0x2d,
- 0x8e,0x15,0x11,0x7c,0x22,0x88,0x88,0x1,0x23,0xc8,0x83,0x37,0xa0,0x5c,0x3a,0x6c,
- 0x9d,0x26,0xf4,0xc0,0x16,0x84,0x41,0x31,0x1d,0x4f,0x15,0x10,0x67,0x1d,0x60,0xe9,
- 0xe,0xfd,0xd3,0x58,0x8c,0x9b,0x38,0x64,0x68,0x1d,0x74,0x57,0x17,0xe4,0xc0,0x19,
- 0xe8,0xc0,0x99,0xa2,0xa9,0x9a,0x62,0x27,0x9b,0x4a,0x41,0x15,0xad,0xa1,0x64,0x5e,
- 0x81,0x7f,0x89,0x80,0x2,0xca,0x93,0x35,0x50,0xcf,0xb7,0xad,0x5,0x6e,0xf0,0x29,
- 0x34,0xc2,0x20,0x3e,0xe8,0xc2,0x3,0xf0,0xc1,0x3,0x68,0x95,0xfe,0xf4,0x1d,0x6a,
- 0x44,0x25,0xaa,0xa2,0x66,0x27,0xa3,0x82,0xe0,0x44,0xb1,0xa1,0x1a,0x94,0xe8,0x77,
- 0x44,0x82,0x57,0xac,0xe,0x3f,0xb8,0xf,0x2a,0x54,0xc0,0x16,0x88,0x9d,0x1c,0x7d,
- 0x6a,0x16,0xb4,0x40,0x26,0x9c,0xc7,0x5a,0x30,0xc5,0x5a,0x56,0xc5,0xa9,0x6e,0xd7,
- 0xe,0xc0,0x41,0x8,0x48,0xc1,0x1e,0xd0,0xb,0x9a,0xa6,0xe3,0x9a,0xce,0x2a,0xad,
- 0x12,0x81,0xad,0xf2,0xa4,0x3,0x74,0x8b,0x8,0x90,0x1,0x12,0x24,0x83,0x11,0x8d,
- 0x45,0x53,0x5,0x6b,0xc7,0xd4,0xa8,0x3d,0xa4,0xd0,0xbb,0xe4,0xc2,0x3,0x74,0x40,
- 0x7,0xdc,0x40,0x8,0x74,0xc0,0xb2,0xfe,0xa8,0x3,0x38,0x80,0xb3,0x2e,0x6a,0xb4,
- 0x8e,0x15,0x13,0xa8,0x41,0x14,0xb6,0x69,0x16,0x2c,0xc1,0x33,0x4c,0x8b,0xd4,0xe9,
- 0x3,0x2f,0xa0,0x41,0x1d,0xc,0xcb,0x4c,0xd0,0x84,0x14,0x88,0x81,0x71,0x22,0x5,
- 0x3d,0x9c,0x85,0x75,0x79,0x83,0x37,0xc8,0x43,0x1e,0xd4,0x1,0x19,0xd4,0xc0,0x24,
- 0xdc,0x40,0x13,0xb4,0xea,0x1e,0xb4,0xe9,0xbc,0xd6,0x2b,0x9a,0x64,0xe7,0xbd,0x12,
- 0x1,0x4e,0x9e,0x28,0xd8,0xbc,0xc0,0x15,0xf0,0xab,0x12,0x44,0xc2,0xc7,0x5a,0x83,
- 0x58,0xec,0x15,0x52,0xee,0x69,0xc1,0xee,0xc3,0x26,0xdd,0x55,0x2f,0x2c,0x6c,0x6,
- 0x38,0x80,0xb,0x3c,0x6c,0xc4,0xb6,0xe6,0xc4,0x52,0x6c,0xa2,0x5a,0x6c,0xb4,0x32,
- 0xaa,0x14,0x7c,0xc1,0xd,0x84,0xc1,0x64,0x16,0x41,0x3,0x10,0x83,0xfb,0x0,0xdf,
- 0x96,0x74,0x42,0x1b,0xcc,0xc1,0xb7,0xda,0x84,0x14,0x70,0xfe,0x81,0xf,0xfc,0xc1,
- 0x7d,0xbd,0xc3,0x8e,0x54,0x43,0xd7,0x65,0x82,0x4a,0x3e,0x1,0x1d,0x30,0x41,0x21,
- 0x84,0x19,0x14,0xac,0xc0,0xc,0x48,0x1,0xc6,0x46,0x6b,0xbd,0x5a,0x4,0xd0,0x56,
- 0x11,0x17,0xd4,0x80,0xd1,0x71,0xe7,0xb,0x1c,0x4f,0x9,0x9c,0xa9,0x8,0xe8,0x47,
- 0x35,0xbc,0xf,0xc1,0x4d,0x9d,0x8e,0xfc,0x86,0x72,0xf5,0x2,0x6,0x3c,0x40,0x9,
- 0x44,0x14,0x7,0xcc,0x80,0xa1,0x4a,0xec,0xc4,0x3a,0xab,0x85,0x84,0x6d,0xb4,0x8e,
- 0x6d,0x1c,0x9e,0xc1,0xc,0x84,0x0,0x24,0x28,0x89,0x3e,0x58,0xc3,0xda,0x12,0xc4,
- 0x23,0x14,0x9,0x19,0xf8,0x81,0x1f,0xc8,0x0,0xd,0xd8,0xc1,0x32,0x96,0xe2,0x6e,
- 0x6e,0x9,0x35,0x64,0x42,0x2,0x4,0x42,0xd,0x10,0x1,0x62,0x3e,0xe6,0xd1,0x6,
- 0x90,0x71,0xa8,0x2e,0x63,0xb2,0x69,0x6c,0xc6,0x65,0x12,0x8,0xad,0x83,0x9c,0xa8,
- 0xd,0x4c,0xc4,0xb,0x48,0x11,0x11,0xd0,0x80,0x4,0xbc,0x82,0xfb,0x4,0x9,0x3a,
- 0x9c,0x46,0xca,0x7d,0x93,0x3d,0x60,0x3,0x3d,0x9c,0xc7,0x37,0xfc,0x2,0x6,0x54,
- 0xe5,0xce,0x81,0x0,0x8,0x94,0x6e,0x44,0x75,0xad,0xfc,0xa2,0xee,0x72,0x38,0x6f,
- 0xb4,0xde,0x40,0xe,0x4,0xe7,0xc,0x14,0xc1,0x1b,0xa8,0xc3,0xc7,0x7a,0x83,0xfb,
- 0x58,0x83,0x3a,0x88,0xc3,0x2a,0xe0,0x0,0xa,0xb4,0x80,0x6,0xfc,0x81,0x29,0x3c,
- 0x83,0x37,0x58,0x52,0xd4,0x98,0xd0,0x5d,0x7d,0xc2,0xd7,0x4d,0x40,0x22,0x15,0x13,
- 0x4d,0x2c,0x6f,0x9b,0xda,0x6f,0x63,0x42,0x6f,0x57,0xfe,0xe,0xc1,0xbd,0xd6,0x0,
- 0x17,0xc,0xe1,0xf5,0xf6,0x45,0xe,0xdc,0x80,0x11,0x5c,0x0,0xc,0xc4,0x23,0x7f,
- 0xe8,0xa9,0xa2,0xd8,0x83,0x35,0xa0,0x10,0x35,0xa,0x3,0x5d,0x74,0xc0,0x7,0xd4,
- 0x70,0x6,0xb8,0x2f,0xfc,0xca,0xef,0xfc,0x26,0x6a,0xea,0x6a,0xf0,0x1a,0x12,0x81,
- 0x13,0xcd,0x80,0xe,0xa4,0xe8,0x4,0xc4,0x82,0x67,0x64,0xa1,0x82,0xe0,0x83,0x3c,
- 0xec,0x21,0x2e,0x10,0x3,0x3,0x3,0x16,0xf8,0xa9,0xc6,0x33,0x94,0xc2,0x5,0x2c,
- 0x81,0xfd,0x65,0x87,0x5,0x1f,0xad,0x64,0xba,0xa9,0xf,0xf,0x21,0x7,0x73,0xa5,
- 0x7,0xdf,0x2b,0x17,0x10,0xc1,0x11,0x8c,0x70,0xf6,0x6a,0x44,0x15,0x22,0x1,0x33,
- 0xa8,0x3,0x5c,0xac,0xc5,0x3e,0xbc,0xf1,0x1b,0x37,0xce,0xe5,0x36,0xc3,0x51,0xa8,
- 0xef,0x3,0xec,0xd2,0x7,0x84,0x40,0x98,0xb8,0xef,0xfb,0xda,0x96,0x5,0xe8,0x70,
- 0xd7,0x26,0xea,0x1,0xf4,0x70,0x17,0x13,0x1,0x9f,0xcc,0x80,0x9,0x74,0x4b,0x11,
- 0x50,0x40,0x32,0x18,0x55,0x8f,0xf4,0x23,0x52,0x70,0x26,0xd3,0xf6,0x88,0x9a,0x1d,
- 0xa8,0x6,0x90,0x81,0xfd,0x95,0x8f,0x17,0xf0,0x0,0x27,0x5f,0x67,0x17,0x6f,0x70,
- 0x6c,0x2e,0x47,0xe,0xb4,0x56,0xe,0x4c,0x2f,0x11,0x24,0xc1,0x10,0xd8,0xc0,0x54,
- 0x1,0x81,0x14,0xb5,0x12,0x17,0x18,0x1,0x5,0xfc,0x1,0x78,0xca,0x7,0x1c,0x1b,
- 0xac,0x96,0x6c,0xc9,0x2f,0x18,0x0,0xb,0x58,0x0,0x8,0x78,0xc0,0x6,0xe8,0xf1,
- 0x7,0x80,0xc0,0x9,0x40,0xc0,0x2e,0x1d,0x64,0xfe,0xfc,0x2,0xb2,0x3,0x1c,0x80,
- 0x32,0x13,0xb2,0xf,0x8f,0x97,0x8d,0x99,0x80,0xab,0xf2,0x81,0xb2,0x84,0x8b,0x37,
- 0x94,0x5,0x6d,0xd0,0xee,0xfb,0x58,0x83,0xdb,0x50,0xc5,0x39,0x60,0x98,0x2a,0x90,
- 0xc0,0x16,0xd4,0x40,0x11,0x98,0xe0,0x43,0xc6,0x6a,0x10,0x7c,0xf2,0x9b,0x92,0x28,
- 0x60,0x8c,0x32,0x29,0xe7,0xc,0xfe,0x42,0x51,0x14,0xb5,0xf2,0xd,0x6c,0x80,0x8a,
- 0xd2,0x40,0x80,0xe2,0x43,0x35,0x34,0xce,0x7,0x1,0xc9,0x96,0xf4,0x2,0x55,0x96,
- 0x0,0x4,0xbc,0x89,0x1e,0x87,0x89,0x5,0x40,0x80,0x5,0x14,0xa4,0x31,0xff,0x31,
- 0x32,0x2b,0xf3,0x20,0xd7,0xef,0x27,0x5b,0x1,0x13,0xc,0x1,0x14,0x44,0x91,0x6b,
- 0xc9,0x40,0xb,0x4,0xdc,0x37,0xcc,0x6e,0xf9,0x42,0x45,0xba,0x44,0x8d,0x54,0xb0,
- 0x25,0x35,0xe4,0x82,0x1,0x88,0x40,0x19,0xa8,0xc0,0x83,0x6c,0x0,0x37,0x5e,0xe7,
- 0x87,0xa2,0xb3,0x17,0x87,0xf2,0x72,0xf4,0x57,0x9,0x13,0xc1,0xd,0x24,0x1,0x14,
- 0xb1,0xb2,0xe,0x94,0xf0,0xd,0x70,0x80,0x9,0x7c,0x40,0x11,0x68,0x80,0x2a,0x44,
- 0x72,0xae,0x55,0xcf,0x34,0xf8,0x73,0x7,0xc4,0xc1,0x0,0xbc,0x40,0x9,0xe4,0x31,
- 0x30,0x43,0x6c,0x56,0x26,0x34,0x32,0x27,0xf3,0x32,0x3b,0x74,0x17,0x57,0x46,0x44,
- 0xc7,0xf3,0xa,0x30,0x1a,0xa,0x84,0x2,0x35,0x34,0x83,0x3d,0xd8,0x1d,0x8c,0xaa,
- 0x7,0x3d,0x5c,0xc3,0x5d,0xb1,0x82,0xf,0x18,0x1,0x1d,0x18,0xdb,0x18,0xb8,0x80,
- 0x4d,0x6c,0x80,0x27,0xef,0x56,0x65,0x54,0xfe,0x11,0x5c,0xc3,0x75,0xd8,0xde,0x67,
- 0xbf,0xf4,0x85,0x6b,0x55,0xd1,0xd,0xe8,0x80,0xe,0xd8,0xf4,0x6b,0xdd,0xc0,0x82,
- 0x46,0x40,0x8,0xf8,0x41,0x1,0xd8,0x2,0x0,0xfb,0x1a,0x3e,0xf0,0x42,0x3,0xb0,
- 0xc0,0x9,0x4,0xc0,0x30,0x2b,0x75,0x98,0xd4,0xf0,0x7,0x34,0x35,0x6b,0x3e,0x35,
- 0x43,0xe7,0x40,0x60,0x5c,0xb6,0x65,0xa3,0xf3,0x78,0xbd,0xa4,0x9,0xd8,0x80,0x5d,
- 0x10,0x81,0x1f,0x28,0xc1,0x5,0xe4,0xc1,0x30,0x58,0x92,0x7c,0x6c,0x92,0x4c,0xe1,
- 0xa8,0x33,0x7c,0x42,0xb,0xa4,0x40,0x16,0x4,0x1,0x37,0x6e,0xc0,0x19,0x34,0xc1,
- 0x6,0xec,0x41,0x18,0xaf,0x21,0x44,0xc7,0x75,0x5c,0xcf,0x75,0x76,0xd6,0xca,0x5e,
- 0x67,0xaf,0x6b,0xf5,0xb5,0x5e,0xf,0xf7,0x6b,0xe5,0x40,0x15,0xbc,0x0,0x16,0xdc,
- 0xc0,0x4,0x2c,0x41,0x2,0xd8,0xc2,0x69,0xbf,0x3,0x3a,0x44,0xf7,0x3b,0xd4,0x82,
- 0x4,0xc8,0x80,0x5,0x30,0x36,0x2,0x8c,0xc0,0x2f,0x6f,0x0,0x64,0xd7,0xb0,0x64,
- 0xc7,0x1b,0x32,0x2f,0x0,0x43,0xdf,0x34,0x79,0x5f,0xb6,0x85,0x58,0x48,0x15,0xf1,
- 0xcb,0x4d,0x97,0x70,0x11,0x64,0x81,0x8,0x4c,0x80,0x28,0xec,0x82,0xc0,0x29,0x97,
- 0xc0,0x9,0x1c,0x32,0x94,0x42,0x1d,0x90,0x40,0xa,0x74,0x57,0x4b,0x7f,0xf1,0x79,
- 0x2f,0xc7,0x7d,0x8a,0x32,0x45,0xff,0x17,0xef,0xc,0xf7,0xc,0x10,0xb8,0xb,0x74,
- 0x44,0x94,0x89,0x80,0xc,0xf0,0xae,0x2b,0x34,0x8b,0x51,0x3d,0x83,0x2a,0x50,0x0,
- 0xa1,0xde,0x70,0x2f,0xd7,0x56,0xa1,0xfe,0x16,0xf3,0x77,0x1f,0xb3,0xfc,0x2e,0x80,
- 0x87,0x8b,0x37,0x2,0x20,0xc0,0x70,0xf,0xb7,0x65,0xff,0xb7,0x89,0x5f,0xc4,0x19,
- 0xc,0x41,0x13,0xb8,0xc1,0x19,0x70,0xb7,0x8,0x44,0xc2,0x27,0xc4,0x82,0x30,0x20,
- 0x83,0x30,0xd0,0x82,0x2b,0x34,0x42,0x20,0x18,0x41,0xa,0x38,0x2e,0x1c,0x40,0xf4,
- 0x17,0xe7,0xcd,0x89,0x5f,0x44,0x80,0x2f,0xc7,0x15,0x1d,0xb8,0x91,0xb,0xb1,0xe,
- 0x1c,0xb8,0xa7,0x2d,0xb9,0xa7,0xb9,0x0,0xb,0xa8,0xa8,0x8,0x3c,0x0,0x24,0xb4,
- 0x2,0x31,0x10,0x43,0x2a,0x48,0x2,0x1,0x8,0x64,0xc0,0x9c,0x21,0x56,0x46,0x94,
- 0x41,0x4e,0xb6,0xe,0x7f,0xf8,0x2,0x84,0xb8,0x88,0x8f,0xb8,0x5e,0x7,0xf9,0x89,
- 0xdb,0x4,0x9a,0x34,0x81,0x4d,0x14,0x81,0x12,0x20,0xc1,0x1,0x6b,0x80,0x6,0xd0,
- 0x40,0xa,0x50,0xc0,0x8e,0x3b,0x2e,0x5c,0xff,0x38,0x90,0xa3,0xf9,0x90,0x3,0x46,
- 0x91,0x1f,0x39,0xa0,0x33,0xf9,0x47,0x2c,0x39,0xb,0xb0,0x80,0x8,0x44,0xf9,0x31,
- 0x12,0x80,0x31,0x6a,0x79,0xc0,0xc0,0xef,0x7c,0x2,0xb2,0x98,0x93,0xf9,0x81,0x9b,
- 0xb9,0x46,0xa0,0xf9,0x79,0x6f,0xc0,0x11,0x80,0x9c,0x76,0x7c,0x41,0xa,0xd0,0x80,
- 0xa7,0x9f,0x51,0xb,0xc1,0x1,0x1f,0xa8,0x1,0x13,0xdc,0x80,0xb,0xfc,0xa4,0x9e,
- 0xb,0x90,0xa5,0xaf,0x73,0xad,0x0,0xba,0xab,0x33,0xf9,0xba,0x95,0x4,0x64,0x3f,
- 0x40,0xa1,0x1b,0xfa,0xa1,0x3f,0x40,0x86,0x13,0x64,0x42,0x73,0x2d,0xa4,0x7f,0xb8,
- 0xa4,0x4f,0x3a,0x89,0x97,0xf8,0xfe,0xaa,0xff,0x45,0x13,0x58,0xb6,0xaa,0x79,0x41,
- 0xd6,0xf2,0x81,0xb,0x61,0xd5,0x6b,0xc5,0xa5,0x46,0xe8,0x80,0x70,0xd6,0x44,0x89,
- 0xea,0xf9,0xb0,0x8b,0x72,0xab,0xbb,0xba,0x92,0xc3,0xfa,0x80,0x8d,0x0,0xb7,0xbb,
- 0x9b,0xe,0x30,0x6c,0xd,0xe3,0x7a,0x6c,0x11,0xa4,0x7,0x9a,0x6e,0x87,0x7f,0xb8,
- 0x32,0x87,0xf8,0x0,0x10,0x2e,0xb0,0xeb,0xb5,0xb0,0x57,0xbb,0x45,0xb8,0xc1,0x10,
- 0x6c,0x80,0xb,0xb0,0xb9,0x76,0x7c,0xc0,0x6,0x14,0x87,0x14,0xd8,0xd8,0xc,0x4,
- 0xa7,0xd,0x5c,0x30,0xae,0x4e,0xfb,0x8f,0xc3,0xfb,0x5f,0xd4,0xca,0x9f,0x7,0xba,
- 0xb6,0x6f,0x3b,0xb7,0x8f,0x0,0x9c,0x94,0x0,0x42,0x1b,0x24,0xc3,0xea,0xfa,0xae,
- 0x83,0x79,0x98,0xa3,0xfb,0x1,0xc,0x0,0xc6,0x7b,0x9a,0x91,0x7,0x7b,0xbf,0xa8,
- 0x89,0x85,0x9c,0x3a,0x9b,0x37,0xc1,0xee,0xe8,0xc0,0x76,0x94,0x89,0x99,0x77,0x44,
- 0x14,0xd1,0x4,0xee,0x50,0xbb,0xa5,0xf7,0x4b,0x1,0xf1,0xe,0xb6,0xcf,0x40,0xc2,
- 0xc7,0x7a,0xbb,0x39,0x7c,0x9,0x0,0xc1,0x2e,0xd9,0x52,0x4,0x10,0x24,0xaf,0x3f,
- 0xb5,0x3,0x78,0x38,0x43,0x33,0x34,0xc6,0xaf,0xbb,0xc6,0x23,0xf9,0x7a,0x77,0x3c,
- 0x86,0x58,0xc8,0x4f,0x36,0x41,0x89,0x62,0x67,0x3c,0x73,0x32,0x4d,0x34,0xc1,0xa,
- 0xe8,0x35,0x14,0x54,0x3d,0x14,0xa0,0x3a,0xcb,0xa3,0xb9,0xcb,0xbf,0xfc,0xc1,0x1f,
- 0xf9,0xcc,0xaf,0xc0,0x7,0x3c,0x94,0xd,0xec,0x7c,0x49,0x14,0xa4,0xd,0xf0,0x3c,
- 0xc5,0x3f,0x35,0xd0,0x7,0xfe,0xfd,0xc5,0x63,0x7c,0xcc,0x23,0xbd,0xc7,0x5b,0xba,
- 0x3a,0x5b,0x44,0x12,0xd4,0x7d,0xa5,0x13,0xbc,0xde,0x8,0x6,0xd7,0xef,0x7d,0x91,
- 0x7f,0x3d,0xd8,0x77,0x37,0xe0,0x77,0x37,0x2,0x45,0x9f,0x56,0x82,0xb7,0xcf,0xaf,
- 0x3d,0xdb,0xb7,0xfd,0x0,0xbc,0x3d,0xdc,0xb,0xc6,0xaa,0xbb,0xf4,0x8d,0x99,0x32,
- 0x5c,0xa3,0x32,0xde,0xf,0x90,0x9a,0xf0,0x3d,0xd7,0xcb,0xfc,0xd7,0x77,0xf7,0x2f,
- 0xf,0x74,0x98,0x84,0xc0,0x6,0x70,0x37,0x64,0x87,0x4,0x97,0x6b,0xb8,0x53,0x1f,
- 0xbe,0x78,0x27,0xbe,0xe2,0xcf,0x7c,0xcc,0x63,0xbb,0xb,0xe0,0xbd,0x6e,0x57,0x66,
- 0x11,0xd4,0x80,0x38,0x53,0x3e,0xde,0xbb,0x3c,0xb6,0xfb,0xfd,0xe6,0x43,0xf6,0x2f,
- 0x8b,0x80,0xe7,0xf,0x74,0xe8,0xb,0xbe,0xe1,0x7d,0x79,0xda,0x57,0x3c,0xe2,0xb,
- 0xfd,0xd0,0x13,0xbd,0xb6,0xb7,0x3e,0xb6,0x37,0x7e,0xbf,0xc4,0xbe,0xec,0x63,0x55,
- 0x56,0x39,0x3f,0xf5,0x6f,0x44,0xd7,0x1b,0xb9,0xee,0x6b,0x7b,0xe0,0x77,0xbe,0xe7,
- 0x7,0x3e,0x64,0xf,0x3f,0xf1,0x73,0x78,0x78,0x5b,0x7c,0xd0,0x27,0xbf,0xf2,0xc3,
- 0xba,0x99,0xa7,0xff,0x88,0xcf,0x40,0xf5,0xab,0x49,0x5f,0xf7,0x75,0x15,0x61,0x95,
- 0x4c,0xb7,0x3f,0xf5,0x5f,0x91,0xfa,0xc7,0x7c,0xc2,0x7b,0x3f,0xbe,0xeb,0x3f,0x64,
- 0x47,0x3c,0xf8,0x17,0x3f,0x40,0x38,0x70,0xb0,0x80,0x60,0xc1,0x5,0x7,0x10,0x26,
- 0x1c,0xb0,0x90,0xe1,0x80,0x15,0xf,0x21,0x3e,0x9c,0x31,0x91,0x62,0x45,0x8b,0x2b,
- 0x5c,0xe4,0xd0,0xb8,0xfe,0x91,0x63,0x47,0x17,0x33,0x74,0x80,0x74,0x31,0xd2,0xc5,
- 0xd,0x93,0x27,0x6f,0x74,0x54,0xb9,0x52,0x25,0x49,0x97,0x1f,0x75,0xc4,0x94,0xa9,
- 0x23,0x62,0xcd,0x88,0x1f,0x70,0xe6,0xd4,0xb9,0x13,0x67,0x87,0xe,0x19,0x80,0x66,
- 0xb0,0x30,0xd4,0x42,0x4,0xa3,0x11,0x86,0xa,0x54,0xaa,0xd4,0xa0,0xc1,0x84,0xa,
- 0x1b,0x2e,0xb4,0x29,0xd1,0x62,0x55,0x8a,0x18,0x59,0xb6,0xc,0x69,0x63,0x86,0x8d,
- 0x99,0x19,0xb3,0x86,0xd,0xfb,0x92,0x24,0xc8,0x99,0x31,0xa7,0xda,0xe4,0xb9,0x33,
- 0x68,0x50,0xa2,0x16,0x20,0xc4,0x95,0x5b,0xf4,0xed,0x52,0xa6,0x4d,0xf,0x3e,0x3d,
- 0x10,0xb5,0x61,0xc4,0x91,0x37,0x3e,0xce,0x58,0x21,0x98,0xf0,0x60,0xc3,0x82,0x57,
- 0xe8,0xc8,0xa1,0x98,0xf1,0x62,0xc7,0x8c,0x43,0xce,0x88,0xd1,0xb5,0xeb,0xd9,0x99,
- 0x1a,0x33,0x66,0xce,0xa1,0x99,0xf3,0x63,0xc7,0x33,0x3e,0x86,0x6,0x1d,0x13,0x64,
- 0x69,0x9a,0x69,0x6f,0xae,0x58,0x8b,0xb3,0x2d,0x8,0x10,0x6f,0xe5,0xce,0xad,0x6b,
- 0x77,0x60,0xd3,0x3,0x79,0x11,0xe,0xd8,0xcb,0x77,0x21,0x88,0x12,0x25,0x3e,0x6c,
- 0x50,0x21,0x42,0xc5,0x60,0x13,0x33,0x8e,0x27,0x47,0xbe,0xfc,0xb8,0x57,0xe7,0x3a,
- 0x9e,0x47,0x27,0x3d,0x31,0x64,0xf5,0x98,0x8e,0x31,0x8b,0xd6,0xe,0x9a,0xbb,0x8b,
- 0x98,0xd2,0x95,0x2b,0x2f,0xb1,0x62,0x7c,0x79,0xf2,0x1f,0x80,0xa7,0x47,0xbf,0x5e,
- 0xbd,0x87,0xe,0xee,0xe1,0x7b,0x68,0x3b,0x5f,0xe8,0x5b,0xb8,0x72,0x19,0xe4,0xd7,
- 0xbf,0xff,0x29,0xfe,0x82,0x3,0xfe,0x75,0xe3,0x6d,0x80,0x5,0x6,0x10,0xc0,0x37,
- 0xf,0x3e,0x60,0x21,0x4,0x15,0x42,0x58,0xc1,0x84,0x7,0x21,0x8c,0x50,0x42,0x1b,
- 0x28,0xac,0xd0,0xc2,0xb,0xa7,0xb3,0xc8,0xb2,0xc,0xad,0xaa,0xea,0xc2,0xa,0x25,
- 0x84,0xf0,0xb7,0x11,0x49,0x2c,0xd1,0x44,0x12,0x3d,0x48,0x51,0xc5,0x14,0xe9,0x6b,
- 0xeb,0x28,0xa3,0xe0,0xda,0x4f,0x46,0xfe,0xfe,0x43,0xc0,0x46,0x4,0x4,0x2c,0x90,
- 0xa1,0x0,0x74,0x7a,0xe8,0x3,0x7,0x43,0xc,0x52,0xc8,0x21,0x27,0x9a,0xaa,0x43,
- 0xd4,0xa6,0x1a,0x32,0xc8,0x13,0x99,0x6c,0x72,0xc5,0x15,0x5b,0xcc,0xe0,0x45,0x18,
- 0x2d,0x98,0xd1,0xca,0x84,0x6e,0xc4,0x31,0x47,0x1,0xb8,0xc,0x20,0x80,0x1b,0x36,
- 0xf8,0xb1,0x44,0x25,0xc9,0x24,0x12,0xb1,0x9a,0x8e,0x44,0xb2,0xa6,0x32,0x23,0x6c,
- 0xf2,0xc4,0x27,0x55,0x8c,0x92,0xbe,0x29,0xa9,0xac,0xd2,0x4a,0x1a,0x11,0xba,0x31,
- 0xc7,0x2,0x5,0xf0,0xd2,0x4b,0x6,0x37,0xe0,0xa0,0x84,0x11,0x4e,0xf0,0x8d,0x83,
- 0x43,0x11,0x4d,0x54,0x51,0x36,0x1f,0x2c,0xd2,0xa6,0x34,0xd5,0x84,0x48,0x48,0x45,
- 0x11,0x75,0xd3,0x44,0x39,0x5b,0xb4,0x4f,0xd3,0xba,0xee,0xd4,0x4f,0x2f,0x1b,0xb7,
- 0xe4,0xb2,0x4f,0x0,0x0,0x8,0x40,0x85,0xd,0x56,0xe0,0x60,0x4,0x10,0xa,0x2d,
- 0x81,0xd2,0x57,0xf,0x65,0xd4,0x84,0x48,0x69,0x4d,0x6b,0xd2,0x57,0x2d,0x2d,0x11,
- 0x53,0xfa,0x36,0xdd,0x54,0xa0,0x4e,0x19,0xd0,0x6b,0x37,0x1,0x45,0xed,0x92,0xd4,
- 0x0,0x46,0x6f,0x12,0x74,0x84,0x55,0xd,0x85,0x95,0x52,0x59,0x6b,0x8d,0x36,0xa2,
- 0x5b,0x29,0xcd,0x95,0xc4,0x5d,0xe7,0xeb,0xd5,0x3e,0xa5,0xee,0x14,0x36,0xb7,0x50,
- 0x45,0xf5,0x33,0x0,0x41,0x5f,0x28,0xc1,0x3,0xd7,0x2c,0x70,0xd5,0xd9,0x45,0x19,
- 0x95,0xd6,0x5d,0x6a,0x15,0x65,0x12,0x4e,0x16,0xb1,0x75,0x4b,0x5b,0xa2,0xb8,0x9d,
- 0xd1,0xdb,0x6f,0x79,0x2b,0xb6,0x58,0x2f,0x5f,0x78,0x61,0x4,0x73,0x33,0xf0,0xe9,
- 0x83,0x75,0x11,0x8e,0x35,0x44,0x77,0xa5,0x4d,0x38,0x51,0x79,0xe7,0xad,0xd7,0xde,
- 0xa4,0x94,0xb2,0x80,0x36,0x7,0x3c,0xdd,0xf7,0xa9,0x7e,0xfd,0x15,0x75,0xa1,0x0,
- 0x2,0x2,0x0,0x3b,
-
-};
-
-static const unsigned char qt_resource_name[] = {
- // images
- 0x0,0x6,
- 0x7,0x3,0x7d,0xc3,
- 0x0,0x69,
- 0x0,0x6d,0x0,0x61,0x0,0x67,0x0,0x65,0x0,0x73,
- // resources
- 0x0,0x9,
- 0xa,0x6c,0x78,0x43,
- 0x0,0x72,
- 0x0,0x65,0x0,0x73,0x0,0x6f,0x0,0x75,0x0,0x72,0x0,0x63,0x0,0x65,0x0,0x73,
- // tools.gif
- 0x0,0x9,
- 0x6,0x36,0xbb,0x36,
- 0x0,0x74,
- 0x0,0x6f,0x0,0x6f,0x0,0x6c,0x0,0x73,0x0,0x2e,0x0,0x67,0x0,0x69,0x0,0x66,
-
-};
-
-static const unsigned char qt_resource_struct[] = {
- // :
- 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
- // :/images
- 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
- // :/images/resources
- 0x0,0x0,0x0,0x12,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,
- // :/images/resources/images
- 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x4,
- // :/images/resources/images/tools.gif
- 0x0,0x0,0x0,0x2a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
-
-};
-
-QT_BEGIN_NAMESPACE
-
-extern Q_CORE_EXPORT bool qRegisterResourceData
- (int, const unsigned char *, const unsigned char *, const unsigned char *);
-
-extern Q_CORE_EXPORT bool qUnregisterResourceData
- (int, const unsigned char *, const unsigned char *, const unsigned char *);
-
-QT_END_NAMESPACE
-
-
-int QT_MANGLE_NAMESPACE(qInitResources_resources)()
-{
- QT_PREPEND_NAMESPACE(qRegisterResourceData)
- (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
- return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_resources))
-
-int QT_MANGLE_NAMESPACE(qCleanupResources_resources)()
-{
- QT_PREPEND_NAMESPACE(qUnregisterResourceData)
- (0x01, qt_resource_struct, qt_resource_name, qt_resource_data);
- return 1;
-}
-
-Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources_resources))
-
diff --git a/tcutils/tcutils b/tcutils/tcutils
deleted file mode 100755
index 73aa979a..00000000
--- a/tcutils/tcutils
+++ /dev/null
Binary files differ
diff --git a/tcutils/tcutils.pro b/tcutils/tcutils.pro
deleted file mode 100644
index a24029e8..00000000
--- a/tcutils/tcutils.pro
+++ /dev/null
@@ -1,30 +0,0 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2013-08-18T13:54:44
-#
-#-------------------------------------------------
-
-QT += core gui
-
-TARGET = tcutils
-TEMPLATE = app
-
-
-SOURCES += main.cpp\
- mainwindow.cpp \
- utils.cpp
-
-HEADERS += mainwindow.h \
- utils.h
-
-FORMS += mainwindow.ui
-
-# added by LK Rashinkar
-INCLUDEPATH += ../xrdpapi
-
-LIBS += -Wl,-rpath
-LIBS += -Wl,/usr/local/lib/xrdp
-LIBS += -L../xrdpapi/.libs -lxrdpapi
-
-RESOURCES += \
- resources.qrc
diff --git a/tcutils/ui_mainwindow.h b/tcutils/ui_mainwindow.h
deleted file mode 100644
index 4c47aefa..00000000
--- a/tcutils/ui_mainwindow.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/********************************************************************************
-** Form generated from reading UI file 'mainwindow.ui'
-**
-** Created: Sun Aug 25 15:11:42 2013
-** by: Qt User Interface Compiler version 4.8.1
-**
-** WARNING! All changes made in this file will be lost when recompiling UI file!
-********************************************************************************/
-
-#ifndef UI_MAINWINDOW_H
-#define UI_MAINWINDOW_H
-
-#include <QtCore/QVariant>
-#include <QtGui/QAction>
-#include <QtGui/QApplication>
-#include <QtGui/QButtonGroup>
-#include <QtGui/QHeaderView>
-#include <QtGui/QListWidget>
-#include <QtGui/QMainWindow>
-#include <QtGui/QMenuBar>
-#include <QtGui/QPushButton>
-#include <QtGui/QStatusBar>
-#include <QtGui/QTabWidget>
-#include <QtGui/QToolBar>
-#include <QtGui/QWidget>
-
-QT_BEGIN_NAMESPACE
-
-class Ui_MainWindow
-{
-public:
- QWidget *centralWidget;
- QTabWidget *tabWidget;
- QWidget *tabUnmount;
- QListWidget *listWidget;
- QPushButton *btnUnmount;
- QPushButton *btnRefresh;
- QWidget *tab_2;
- QMenuBar *menuBar;
- QToolBar *mainToolBar;
- QStatusBar *statusBar;
-
- void setupUi(QMainWindow *MainWindow)
- {
- if (MainWindow->objectName().isEmpty())
- MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
- MainWindow->resize(541, 355);
- centralWidget = new QWidget(MainWindow);
- centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
- tabWidget = new QTabWidget(centralWidget);
- tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
- tabWidget->setGeometry(QRect(0, 0, 511, 291));
- tabUnmount = new QWidget();
- tabUnmount->setObjectName(QString::fromUtf8("tabUnmount"));
- listWidget = new QListWidget(tabUnmount);
- listWidget->setObjectName(QString::fromUtf8("listWidget"));
- listWidget->setGeometry(QRect(10, 10, 321, 221));
- btnUnmount = new QPushButton(tabUnmount);
- btnUnmount->setObjectName(QString::fromUtf8("btnUnmount"));
- btnUnmount->setGeometry(QRect(350, 60, 141, 27));
- btnRefresh = new QPushButton(tabUnmount);
- btnRefresh->setObjectName(QString::fromUtf8("btnRefresh"));
- btnRefresh->setGeometry(QRect(350, 10, 141, 27));
- tabWidget->addTab(tabUnmount, QString());
- tab_2 = new QWidget();
- tab_2->setObjectName(QString::fromUtf8("tab_2"));
- tabWidget->addTab(tab_2, QString());
- MainWindow->setCentralWidget(centralWidget);
- menuBar = new QMenuBar(MainWindow);
- menuBar->setObjectName(QString::fromUtf8("menuBar"));
- menuBar->setGeometry(QRect(0, 0, 541, 25));
- MainWindow->setMenuBar(menuBar);
- mainToolBar = new QToolBar(MainWindow);
- mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
- MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
- statusBar = new QStatusBar(MainWindow);
- statusBar->setObjectName(QString::fromUtf8("statusBar"));
- MainWindow->setStatusBar(statusBar);
-
- retranslateUi(MainWindow);
-
- tabWidget->setCurrentIndex(0);
-
-
- QMetaObject::connectSlotsByName(MainWindow);
- } // setupUi
-
- void retranslateUi(QMainWindow *MainWindow)
- {
- MainWindow->setWindowTitle(QApplication::translate("MainWindow", "TC Utils", 0, QApplication::UnicodeUTF8));
- btnUnmount->setText(QApplication::translate("MainWindow", "Unmount device", 0, QApplication::UnicodeUTF8));
- btnRefresh->setText(QApplication::translate("MainWindow", "Get device list", 0, QApplication::UnicodeUTF8));
- tabWidget->setTabText(tabWidget->indexOf(tabUnmount), QApplication::translate("MainWindow", "Tab 1", 0, QApplication::UnicodeUTF8));
- tabWidget->setTabText(tabWidget->indexOf(tab_2), QApplication::translate("MainWindow", "Tab 2", 0, QApplication::UnicodeUTF8));
- } // retranslateUi
-
-};
-
-namespace Ui {
- class MainWindow: public Ui_MainWindow {};
-} // namespace Ui
-
-QT_END_NAMESPACE
-
-#endif // UI_MAINWINDOW_H
diff --git a/tests/.gitignore b/tests/.gitignore
new file mode 100644
index 00000000..24600083
--- /dev/null
+++ b/tests/.gitignore
@@ -0,0 +1 @@
+!Makefile
diff --git a/tests/gtcp_proxy/gtcp-proxy b/tests/gtcp_proxy/gtcp-proxy
deleted file mode 100755
index 6896b437..00000000
--- a/tests/gtcp_proxy/gtcp-proxy
+++ /dev/null
Binary files differ
diff --git a/tests/gtcp_proxy/gtcp-proxy.c b/tests/gtcp_proxy/gtcp-proxy.c
index 39555c76..b9efd5d4 100644
--- a/tests/gtcp_proxy/gtcp-proxy.c
+++ b/tests/gtcp_proxy/gtcp-proxy.c
@@ -223,7 +223,7 @@ int main(int argc, char **argv)
}
/**
- * Start listening on specifed local socket; when we get a connection,
+ * Start listening on specified local socket; when we get a connection,
* connect to specified remote server and transfer data between local
* and remote server
*****************************************************************************/
@@ -611,7 +611,7 @@ static gboolean on_delete_event(GtkWidget *widget, GdkEvent *ev, gpointer data)
static void on_destroy(GtkWidget *widget, gpointer data)
{
- /* this will destory all windows and return control to gtk_main() */
+ /* this will destroy all windows and return control to gtk_main() */
gtk_main_quit();
}
@@ -673,6 +673,6 @@ static void on_clear_clicked(GtkWidget *widget, gpointer data)
static void on_quit_clicked(GtkWidget *widget, gpointer data)
{
- /* this will destory all windows and return control to gtk_main() */
+ /* this will destroy all windows and return control to gtk_main() */
gtk_main_quit();
}
diff --git a/tests/gtcp_proxy/gtcp.c b/tests/gtcp_proxy/gtcp.c
index 9f0fcf88..a27f2ea6 100644
--- a/tests/gtcp_proxy/gtcp.c
+++ b/tests/gtcp_proxy/gtcp.c
@@ -26,14 +26,9 @@ int tcp_socket_create(void)
{
int rv;
int option_value;
+ socklen_t option_len;
-#if defined(_WIN32)
- int option_len;
-#else
- unsigned int option_len;
-#endif
-
- /* in win32 a socket is an unsigned int, in linux, its an int */
+ /* in win32 a socket is an unsigned int, in linux, it's an int */
if ((rv = (int) socket(PF_INET, SOCK_STREAM, 0)) < 0)
return -1;
@@ -69,7 +64,7 @@ int tcp_socket_create(void)
}
/**
- * Place specifed socket in non blocking mode
+ * Place specified socket in non blocking mode
*****************************************************************************/
void tcp_set_non_blocking(int skt)
@@ -133,12 +128,7 @@ int tcp_accept(int skt)
int ret ;
char ipAddr[256] ;
struct sockaddr_in s;
-
-#if defined(_WIN32)
- int i;
-#else
- unsigned int i;
-#endif
+ socklen_t i;
i = sizeof(struct sockaddr_in);
memset(&s, 0, i);
@@ -186,14 +176,9 @@ int tcp_socket(void)
{
int rv;
int option_value;
+ socklen_t option_len;
-#if defined(_WIN32)
- int option_len;
-#else
- unsigned int option_len;
-#endif
-
- /* in win32 a socket is an unsigned int, in linux, its an int */
+ /* in win32 a socket is an unsigned int, in linux, it's an int */
if ((rv = (int) socket(PF_INET, SOCK_STREAM, 0)) < 0)
return -1;
@@ -305,14 +290,7 @@ int tcp_can_send(int skt, int millis)
int tcp_socket_ok(int skt)
{
int opt;
-
-#if defined(_WIN32)
- int opt_len;
-#else
- unsigned int opt_len;
-#endif
-
- opt_len = sizeof(opt);
+ socklen_t opt_len = sizeof(opt);
if (getsockopt(skt, SOL_SOCKET, SO_ERROR, (char *) (&opt), &opt_len) == 0)
{
diff --git a/tests/tcp_proxy/main.c b/tests/tcp_proxy/main.c
index 2d283ed9..5ea53f5f 100644
--- a/tests/tcp_proxy/main.c
+++ b/tests/tcp_proxy/main.c
@@ -26,7 +26,7 @@
#include <errno.h>
#include <locale.h>
#include <netdb.h>
-#include <sys/types.h>
+#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -109,7 +109,7 @@ g_hexdump(char *p, int len)
g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
}
- g_writeln("");
+ g_writeln("%s", "");
offset += thisline;
line += thisline;
}
@@ -121,7 +121,7 @@ g_tcp_socket(void)
{
int rv;
int option_value;
- unsigned int option_len;
+ socklen_t option_len;
rv = (int)socket(AF_INET, SOCK_STREAM, 0);
if (rv < 0)
@@ -336,9 +336,7 @@ static int APP_CC
g_tcp_socket_ok(int sck)
{
int opt;
- unsigned int opt_len;
-
- opt_len = sizeof(opt);
+ socklen_t opt_len = sizeof(opt);
if (getsockopt(sck, SOL_SOCKET, SO_ERROR, (char *)(&opt), &opt_len) == 0)
{
@@ -399,13 +397,6 @@ g_signal_user_interrupt(void (*func)(int))
/*****************************************************************************/
static void APP_CC
-g_signal_kill(void (*func)(int))
-{
- signal(SIGKILL, func);
-}
-
-/*****************************************************************************/
-static void APP_CC
g_signal_terminate(void (*func)(int))
{
signal(SIGTERM, func);
@@ -454,7 +445,7 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
g_writeln("bind failed");
}
- /* listen for an incomming connection */
+ /* listen for an incoming connection */
if (error == 0)
{
error = g_tcp_listen(lis_sck);
@@ -465,7 +456,7 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
}
}
- /* accept an incomming connection */
+ /* accept an incoming connection */
if (error == 0)
{
while ((!g_terminated) && (error == 0))
@@ -523,7 +514,7 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
if (i > 99)
{
- g_writeln("timout connecting");
+ g_writeln("timeout connecting");
error = 1;
}
@@ -685,7 +676,6 @@ main(int argc, char **argv)
g_init("tcp_proxy");
g_signal_user_interrupt(proxy_shutdown); /* SIGINT */
- g_signal_kill(proxy_shutdown); /* SIGKILL */
g_signal_usr1(clear_counters); /* SIGUSR1 */
g_signal_terminate(proxy_shutdown); /* SIGTERM */
diff --git a/vnc/Makefile.am b/vnc/Makefile.am
index 24835011..453022f4 100644
--- a/vnc/Makefile.am
+++ b/vnc/Makefile.am
@@ -1,18 +1,16 @@
-EXTRA_DIST = vnc.h
-
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
-
-INCLUDES = \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-I$(top_srcdir)/common
-lib_LTLIBRARIES = \
+module_LTLIBRARIES = \
libvnc.la
-libvnc_la_SOURCES = vnc.c
+libvnc_la_SOURCES = \
+ vnc.c \
+ vnc.h
libvnc_la_LIBADD = \
$(top_builddir)/common/libcommon.la
diff --git a/vnc/vnc.c b/vnc/vnc.c
index bb04726d..3a91ea9d 100644
--- a/vnc/vnc.c
+++ b/vnc/vnc.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,115 +20,81 @@
#include "vnc.h"
#include "log.h"
+#include "trans.h"
+#include "ssl_calls.h"
+
+#define LLOG_LEVEL 1
+#define LLOGLN(_level, _args) \
+ do \
+ { \
+ if (_level < LLOG_LEVEL) \
+ { \
+ g_write("xrdp:vnc [%10.10u]: ", g_time3()); \
+ g_writeln _args ; \
+ } \
+ } \
+ while (0)
+
+#define AS_LOG_MESSAGE log_message
+
+static int APP_CC
+lib_mod_process_message(struct vnc *v, struct stream *s);
/******************************************************************************/
-/* taken from vncauth.c */
-void DEFAULT_CC
-rfbEncryptBytes(char *bytes, char *passwd)
+static int APP_CC
+lib_send_copy(struct vnc *v, struct stream *s)
{
- char key[12];
-
- /* key is simply password padded with nulls */
- g_memset(key, 0, sizeof(key));
- g_strncpy(key, passwd, 8);
- rfbDesKey((unsigned char *)key, EN0); /* 0, encrypt */
- rfbDes((unsigned char *)bytes, (unsigned char *)bytes);
- rfbDes((unsigned char *)(bytes + 8), (unsigned char *)(bytes + 8));
+ return trans_write_copy_s(v->trans, s);
}
/******************************************************************************/
-/* returns error */
-int DEFAULT_CC
-lib_recv(struct vnc *v, char *data, int len)
+/* taken from vncauth.c */
+/* performing the des3 crypt on the password so it can not be seen
+ on the wire
+ 'bytes' in, contains 16 bytes server random
+ out, random and 'passwd' conbined */
+static void APP_CC
+rfbEncryptBytes(char *bytes, const char *passwd)
{
- int rcvd;
-
- if (v->sck_closed)
- {
- return 1;
- }
-
- while (len > 0)
- {
- rcvd = g_tcp_recv(v->sck, data, len, 0);
-
- if (rcvd == -1)
- {
- if (g_tcp_last_error_would_block(v->sck))
- {
- if (v->server_is_term(v))
- {
- return 1;
- }
+ char key[24];
+ void *des;
+ int len;
- g_tcp_can_recv(v->sck, 10);
- }
- else
- {
- log_message(LOG_LEVEL_DEBUG, "VNC lib_recv return 1");
- return 1;
- }
- }
- else if (rcvd == 0)
- {
- v->sck_closed = 1;
- return 1;
- }
- else
- {
- data += rcvd;
- len -= rcvd;
- }
- }
-
- return 0;
+ /* key is simply password padded with nulls */
+ g_memset(key, 0, sizeof(key));
+ len = MIN(g_strlen(passwd), 8);
+ g_mirror_memcpy(key, passwd, len);
+ des = ssl_des3_encrypt_info_create(key, 0);
+ ssl_des3_encrypt(des, 8, bytes, bytes);
+ ssl_des3_info_delete(des);
+ des = ssl_des3_encrypt_info_create(key, 0);
+ ssl_des3_encrypt(des, 8, bytes + 8, bytes + 8);
+ ssl_des3_info_delete(des);
}
-/*****************************************************************************/
-/* returns error */
-int DEFAULT_CC
-lib_send(struct vnc *v, char *data, int len)
+/******************************************************************************/
+/* sha1 hash 'passwd', create a string from the hash and call rfbEncryptBytes */
+static void APP_CC
+rfbHashEncryptBytes(char *bytes, const char *passwd)
{
- int sent;
-
- if (v->sck_closed)
- {
- return 1;
- }
-
- while (len > 0)
- {
- sent = g_tcp_send(v->sck, data, len, 0);
-
- if (sent == -1)
- {
- if (g_tcp_last_error_would_block(v->sck))
- {
- if (v->server_is_term(v))
- {
- return 1;
- }
-
- g_tcp_can_send(v->sck, 10);
- }
- else
- {
- return 1;
- }
- }
- else if (sent == 0)
- {
- v->sck_closed = 1;
- return 1;
- }
- else
- {
- data += sent;
- len -= sent;
- }
- }
-
- return 0;
+ char passwd_hash[20];
+ char passwd_hash_text[40];
+ void *sha1;
+ int passwd_bytes;
+
+ /* create password hash from password */
+ passwd_bytes = g_strlen(passwd);
+ sha1 = ssl_sha1_info_create();
+ ssl_sha1_transform(sha1, "xrdp_vnc", 8);
+ ssl_sha1_transform(sha1, passwd, passwd_bytes);
+ ssl_sha1_transform(sha1, passwd, passwd_bytes);
+ ssl_sha1_complete(sha1, passwd_hash);
+ ssl_sha1_info_delete(sha1);
+ g_snprintf(passwd_hash_text, 39, "%2.2x%2.2x%2.2x%2.2x",
+ (tui8)passwd_hash[0], (tui8)passwd_hash[1],
+ (tui8)passwd_hash[2], (tui8)passwd_hash[3]);
+ passwd_hash_text[39] = 0;
+ rfbEncryptBytes(bytes, passwd_hash_text);
}
/******************************************************************************/
@@ -139,6 +105,7 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
int type;
int status;
int length;
+ int clip_bytes;
int index;
int format;
struct stream *out_s;
@@ -154,20 +121,44 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
switch (type)
{
case 2: /* CLIPRDR_FORMAT_ANNOUNCE */
+ AS_LOG_MESSAGE(LOG_LEVEL_DEBUG, "CLIPRDR_FORMAT_ANNOUNCE - "
+ "status %d length %d", status, length);
make_stream(out_s);
init_stream(out_s, 8192);
- out_uint16_le(out_s, 3);
- out_uint16_le(out_s, 1);
- out_uint32_le(out_s, 0);
- out_uint8s(out_s, 4); /* pad */
+ out_uint16_le(out_s, 3); // msg-type: CLIPRDR_FORMAT_ACK
+ out_uint16_le(out_s, 1); // msg-status-code: CLIPRDR_RESPONSE
+ out_uint32_le(out_s, 0); // null (?)
+ out_uint8s(out_s, 4); // pad
s_mark_end(out_s);
length = (int)(out_s->end - out_s->data);
- v->server_send_to_channel(v, v->clip_chanid, out_s->data, length, length, 3);
+ v->server_send_to_channel(v, v->clip_chanid, out_s->data,
+ length, length, 3);
free_stream(out_s);
+#if 0
+ // Send the CLIPRDR_DATA_REQUEST message to the cliprdr channel.
+ //
+ make_stream(out_s);
+ init_stream(out_s, 8192);
+ out_uint16_le(out_s, 4); // msg-type: CLIPRDR_DATA_REQUEST
+ out_uint16_le(out_s, 0); // msg-status-code: CLIPRDR_REQUEST
+ out_uint32_le(out_s, 4); // sizeof supported-format-list.
+ out_uint32_le(out_s, 1); // supported-format-list: CF_TEXT
+ out_uint8s(out_s, 0); // pad (garbage pad?)
+ s_mark_end(out_s);
+ length = (int)(out_s->end - out_s->data);
+ v->server_send_to_channel(v, v->clip_chanid, out_s->data,
+ length, length, 3);
+ free_stream(out_s);
+#endif
break;
+
case 3: /* CLIPRDR_FORMAT_ACK */
+ AS_LOG_MESSAGE(LOG_LEVEL_DEBUG, "CLIPRDR_FORMAT_ACK - "
+ "status %d length %d", status, length);
break;
case 4: /* CLIPRDR_DATA_REQUEST */
+ AS_LOG_MESSAGE(LOG_LEVEL_DEBUG, "CLIPRDR_DATA_REQUEST - "
+ "status %d length %d", status, length);
format = 0;
if (length >= 4)
@@ -188,11 +179,11 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
if (format == 13) /* CF_UNICODETEXT */
{
- out_uint32_le(out_s, v->clip_data_size * 2 + 2);
+ out_uint32_le(out_s, v->clip_data_s->size * 2 + 2);
- for (index = 0; index < v->clip_data_size; index++)
+ for (index = 0; index < v->clip_data_s->size; index++)
{
- out_uint8(out_s, v->clip_data[index]);
+ out_uint8(out_s, v->clip_data_s->data[index]);
out_uint8(out_s, 0);
}
@@ -200,11 +191,11 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
}
else if (format == 1) /* CF_TEXT */
{
- out_uint32_le(out_s, v->clip_data_size + 1);
+ out_uint32_le(out_s, v->clip_data_s->size + 1);
- for (index = 0; index < v->clip_data_size; index++)
+ for (index = 0; index < v->clip_data_s->size; index++)
{
- out_uint8(out_s, v->clip_data[index]);
+ out_uint8(out_s, v->clip_data_s->data[index]);
}
out_uint8s(out_s, 1);
@@ -217,6 +208,33 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
length, 3);
free_stream(out_s);
break;
+
+ case 5: /* CLIPRDR_DATA_RESPONSE */
+ AS_LOG_MESSAGE(LOG_LEVEL_DEBUG, "CLIPRDR_DATA_RESPONSE - "
+ "status %d length %d", status, length);
+ clip_bytes = MIN(length, 256);
+ // - Read the response data from the cliprdr channel, stream 's'.
+ // - Send the response data to the vnc server, stream 'out_s'.
+ //
+ make_stream(out_s);
+ // Send the RFB message type (CLIENT_CUT_TEXT) to the vnc server.
+ init_stream(out_s, clip_bytes + 1 + 3 + 4 + 16);
+ out_uint8(out_s, 6); // RFB msg type: CLIENT_CUT_TEXT
+ out_uint8s(out_s, 3); // padding
+ // Send the length of the cut-text to the vnc server.
+ out_uint32_be(out_s, clip_bytes);
+ // Send the cut-text (as read from 's') to the vnc server.
+ for (index = 0; index < clip_bytes; index++)
+ {
+ char cur_char = '\0';
+ in_uint8(s, cur_char); // text in from 's'
+ out_uint8(out_s, cur_char); // text out to 'out_s'
+ }
+ s_mark_end(out_s);
+ lib_send_copy(v, out_s);
+ free_stream(out_s);
+ break;
+
default:
{
log_message(LOG_LEVEL_DEBUG, "VNC clip information unhandled");
@@ -226,7 +244,7 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
}
else
{
- log_message(LOG_LEVEL_DEBUG, "lib_process_channel_data: unknown chanid:",
+ log_message(LOG_LEVEL_DEBUG, "lib_process_channel_data: unknown chanid: "
"%d :(v->clip_chanid) %d", chanid, v->clip_chanid);
}
@@ -250,7 +268,6 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
int chanid;
int flags;
char *data;
- char text[256];
error = 0;
make_stream(s);
@@ -292,7 +309,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
out_uint8(s, 0); /* down flag */
out_uint8s(s, 2);
out_uint32_be(s, 65507); /* left control */
- lib_send(v, s->data, 8);
+ s_mark_end(s);
+ lib_send_copy(v, s);
}
}
@@ -301,7 +319,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
out_uint8(s, msg == 15); /* down flag */
out_uint8s(s, 2);
out_uint32_be(s, key);
- error = lib_send(v, s->data, 8);
+ s_mark_end(s);
+ error = lib_send_copy(v, s);
if (key == 65507) /* left control */
{
@@ -352,11 +371,12 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
out_uint8(s, v->mod_mouse_state);
out_uint16_be(s, param1);
out_uint16_be(s, param2);
- error = lib_send(v, s->data, 6);
+ s_mark_end(s);
+ error = lib_send_copy(v, s);
}
else if (msg == 200) /* invalidate */
{
- /* FrambufferUpdateRequest */
+ /* FramebufferUpdateRequest */
init_stream(s, 8192);
out_uint8(s, 3);
out_uint8(s, 0);
@@ -368,7 +388,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
out_uint16_be(s, cx);
cy = param2 & 0xffff;
out_uint16_be(s, cy);
- error = lib_send(v, s->data, 10);
+ s_mark_end(s);
+ error = lib_send_copy(v, s);
}
free_stream(s);
@@ -562,7 +583,6 @@ make_color(int r, int g, int b, int bpp)
int DEFAULT_CC
lib_framebuffer_update(struct vnc *v)
{
- char *data;
char *d1;
char *d2;
char cursor_data[32 * (32 * 3)];
@@ -578,19 +598,17 @@ lib_framebuffer_update(struct vnc *v)
int cy;
int srcx;
int srcy;
- int encoding;
+ unsigned int encoding;
int Bpp;
int pixel;
int r;
int g;
int b;
- int data_size;
- int need_size;
int error;
+ int need_size;
struct stream *s;
+ struct stream *pixel_s;
- data_size = 0;
- data = 0;
num_recs = 0;
Bpp = (v->mod_bpp + 7) / 8;
@@ -599,9 +617,11 @@ lib_framebuffer_update(struct vnc *v)
Bpp = 4;
}
+ make_stream(pixel_s);
+
make_stream(s);
init_stream(s, 8192);
- error = lib_recv(v, s->data, 3);
+ error = trans_force_read_s(v->trans, s, 3);
if (error == 0)
{
@@ -618,7 +638,7 @@ lib_framebuffer_update(struct vnc *v)
}
init_stream(s, 8192);
- error = lib_recv(v, s->data, 12);
+ error = trans_force_read_s(v->trans, s, 12);
if (error == 0)
{
@@ -631,25 +651,18 @@ lib_framebuffer_update(struct vnc *v)
if (encoding == 0) /* raw */
{
need_size = cx * cy * Bpp;
-
- if (need_size > data_size)
- {
- g_free(data);
- data = (char *)g_malloc(need_size, 0);
- data_size = need_size;
- }
-
- error = lib_recv(v, data, need_size);
+ init_stream(pixel_s, need_size);
+ error = trans_force_read_s(v->trans, pixel_s, need_size);
if (error == 0)
{
- error = v->server_paint_rect(v, x, y, cx, cy, data, cx, cy, 0, 0);
+ error = v->server_paint_rect(v, x, y, cx, cy, pixel_s->data, cx, cy, 0, 0);
}
}
else if (encoding == 1) /* copy rect */
{
init_stream(s, 8192);
- error = lib_recv(v, s->data, 4);
+ error = trans_force_read_s(v->trans, s, 4);
if (error == 0)
{
@@ -665,7 +678,7 @@ lib_framebuffer_update(struct vnc *v)
j = cx * cy * Bpp;
k = ((cx + 7) / 8) * cy;
init_stream(s, j + k);
- error = lib_recv(v, s->data, j + k);
+ error = trans_force_read_s(v->trans, s, j + k);
if (error == 0)
{
@@ -689,7 +702,7 @@ lib_framebuffer_update(struct vnc *v)
}
}
- /* keep these in 32x32, vnc cursor can be alot bigger */
+ /* keep these in 32x32, vnc cursor can be a lot bigger */
if (x > 31)
{
x = 31;
@@ -723,11 +736,9 @@ lib_framebuffer_update(struct vnc *v)
error = v->server_end_update(v);
}
- g_free(data);
-
if (error == 0)
{
- /* FrambufferUpdateRequest */
+ /* FramebufferUpdateRequest */
init_stream(s, 8192);
out_uint8(s, 3);
out_uint8(s, 1);
@@ -735,14 +746,17 @@ lib_framebuffer_update(struct vnc *v)
out_uint16_be(s, 0);
out_uint16_be(s, v->mod_width);
out_uint16_be(s, v->mod_height);
- error = lib_send(v, s->data, 10);
+ s_mark_end(s);
+ error = lib_send_copy(v, s);
}
free_stream(s);
+ free_stream(pixel_s);
return error;
}
/******************************************************************************/
+/* clip data from the vnc server */
int DEFAULT_CC
lib_clip_data(struct vnc *v)
{
@@ -751,20 +765,19 @@ lib_clip_data(struct vnc *v)
int size;
int error;
- g_free(v->clip_data);
- v->clip_data = 0;
- v->clip_data_size = 0;
+ free_stream(v->clip_data_s);
+ v->clip_data_s = 0;
make_stream(s);
init_stream(s, 8192);
- error = lib_recv(v, s->data, 7);
+ error = trans_force_read_s(v->trans, s, 7);
if (error == 0)
{
in_uint8s(s, 3);
in_uint32_be(s, size);
- v->clip_data = (char *)g_malloc(size, 0);
- v->clip_data_size = size;
- error = lib_recv(v, v->clip_data, size);
+ make_stream(v->clip_data_s);
+ init_stream(v->clip_data_s, size);
+ error = trans_force_read_s(v->trans, v->clip_data_s, size);
}
if (error == 0)
@@ -808,7 +821,7 @@ lib_palette_update(struct vnc *v)
make_stream(s);
init_stream(s, 8192);
- error = lib_recv(v, s->data, 5);
+ error = trans_force_read_s(v->trans, s, 5);
if (error == 0)
{
@@ -816,7 +829,7 @@ lib_palette_update(struct vnc *v)
in_uint16_be(s, first_color);
in_uint16_be(s, num_colors);
init_stream(s, 8192);
- error = lib_recv(v, s->data, num_colors * 6);
+ error = trans_force_read_s(v->trans, s, num_colors * 6);
}
if (error == 0)
@@ -853,7 +866,6 @@ lib_palette_update(struct vnc *v)
int DEFAULT_CC
lib_bell_trigger(struct vnc *v)
{
- struct stream *s;
int error;
error = v->server_bell_trigger(v);
@@ -864,12 +876,21 @@ lib_bell_trigger(struct vnc *v)
int DEFAULT_CC
lib_mod_signal(struct vnc *v)
{
+ g_writeln("lib_mod_signal: not used");
+ return 0;
+}
+
+/******************************************************************************/
+static int APP_CC
+lib_mod_process_message(struct vnc *v, struct stream *s)
+{
char type;
int error;
char text[256];
- error = lib_recv(v, &type, 1);
+ in_uint8(s, type);
+ error = 0;
if (error == 0)
{
if (type == 0) /* framebuffer update */
@@ -930,6 +951,39 @@ lib_open_clip_channel(struct vnc *v)
}
/******************************************************************************/
+static int APP_CC
+lib_data_in(struct trans *trans)
+{
+ struct vnc *self;
+ struct stream *s;
+
+ LLOGLN(10, ("lib_data_in:"));
+
+ if (trans == 0)
+ {
+ return 1;
+ }
+
+ self = (struct vnc *)(trans->callback_data);
+ s = trans_get_in_s(trans);
+
+ if (s == 0)
+ {
+ return 1;
+ }
+
+ if (lib_mod_process_message(self, s) != 0)
+ {
+ g_writeln("lib_data_in: lib_mod_process_message failed");
+ return 1;
+ }
+
+ init_stream(s, 0);
+
+ return 0;
+}
+
+/******************************************************************************/
/*
return error
*/
@@ -945,16 +999,23 @@ lib_mod_connect(struct vnc *v)
int error;
int i;
int check_sec_result;
+ struct source_info *si;
v->server_msg(v, "VNC started connecting", 0);
check_sec_result = 1;
- /* only support 8 and 16 bpp connections from rdp client */
- if ((v->server_bpp != 8) && (v->server_bpp != 15) &&
- (v->server_bpp != 16) && (v->server_bpp != 24))
+ /* check if bpp is supported for rdp connection */
+ switch (v->server_bpp)
{
- v->server_msg(v, "VNC error - only supporting 8, 15, 16 and 24 bpp rdp "
- "connections", 0);
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ v->server_msg(v, "VNC error - only supporting 8, 15, 16, 24 and 32 "
+ "bpp rdp connections", 0);
return 1;
}
@@ -968,16 +1029,15 @@ lib_mod_connect(struct vnc *v)
g_sprintf(con_port, "%s", v->port);
make_stream(pixel_format);
- v->sck = g_tcp_socket();
- if (v->sck < 0)
+ v->trans = trans_create(TRANS_MODE_TCP, 8 * 8192, 8192);
+ if (v->trans == 0)
{
- v->server_msg(v, "VNC error: socket create error, g_tcp_socket() failed", 0);
+ v->server_msg(v, "VNC error: trans_create() failed", 0);
free_stream(s);
free_stream(pixel_format);
return 1;
}
- v->sck_obj = g_create_wait_obj_from_socket(v->sck, 0);
v->sck_closed = 0;
if (v->delay_ms > 0)
{
@@ -988,27 +1048,32 @@ lib_mod_connect(struct vnc *v)
g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port);
v->server_msg(v, text, 0);
- error = g_tcp_connect(v->sck, v->ip, con_port);
+
+ si = (struct source_info *) (v->si);
+ v->trans->si = si;
+ v->trans->my_source = XRDP_SOURCE_MOD;
+
+ error = trans_connect(v->trans, v->ip, con_port, 3000);
if (error == 0)
{
v->server_msg(v, "VNC tcp connected", 0);
- g_tcp_set_non_blocking(v->sck);
- g_tcp_set_no_delay(v->sck);
- /* protocal version */
+ /* protocol version */
init_stream(s, 8192);
- error = lib_recv(v, s->data, 12);
-
+ error = trans_force_read_s(v->trans, s, 12);
if (error == 0)
{
- error = lib_send(v, "RFB 003.003\n", 12);
+ s->p = s->data;
+ out_uint8a(s, "RFB 003.003\n", 12);
+ s_mark_end(s);
+ error = trans_force_write_s(v->trans, s);
}
/* sec type */
if (error == 0)
{
init_stream(s, 8192);
- error = lib_recv(v, s->data, 4);
+ error = trans_force_read_s(v->trans, s, 4);
}
if (error == 0)
@@ -1024,12 +1089,24 @@ lib_mod_connect(struct vnc *v)
else if (i == 2) /* dec the password and the server random */
{
init_stream(s, 8192);
- error = lib_recv(v, s->data, 16);
+ error = trans_force_read_s(v->trans, s, 16);
if (error == 0)
{
- rfbEncryptBytes(s->data, v->password);
- error = lib_send(v, s->data, 16);
+ init_stream(s, 8192);
+ if (v->got_guid)
+ {
+ char guid_str[64];
+ g_bytes_to_hexstr(v->guid, 16, guid_str, 64);
+ rfbHashEncryptBytes(s->data, guid_str);
+ }
+ else
+ {
+ rfbEncryptBytes(s->data, v->password);
+ }
+ s->p += 16;
+ s_mark_end(s);
+ error = trans_force_write_s(v->trans, s);
check_sec_result = 1; // not needed
}
}
@@ -1048,14 +1125,15 @@ lib_mod_connect(struct vnc *v)
if (error != 0)
{
- log_message(LOG_LEVEL_DEBUG, "VNC Error after security negotiation");
+ log_message(LOG_LEVEL_DEBUG, "VNC error %d after security negotiation",
+ error);
}
if (error == 0 && check_sec_result)
{
/* sec result */
init_stream(s, 8192);
- error = lib_recv(v, s->data, 4);
+ error = trans_force_read_s(v->trans, s, 4);
if (error == 0)
{
@@ -1078,7 +1156,9 @@ lib_mod_connect(struct vnc *v)
v->server_msg(v, "VNC sending share flag", 0);
init_stream(s, 8192);
s->data[0] = 1;
- error = lib_send(v, s->data, 1); /* share flag */
+ s->p++;
+ s_mark_end(s);
+ error = trans_force_write_s(v->trans, s); /* share flag */
}
else
{
@@ -1088,7 +1168,8 @@ lib_mod_connect(struct vnc *v)
if (error == 0)
{
v->server_msg(v, "VNC receiving server init", 0);
- error = lib_recv(v, s->data, 4); /* server init */
+ init_stream(s, 8192);
+ error = trans_force_read_s(v->trans, s, 4); /* server init */
}
else
{
@@ -1101,7 +1182,7 @@ lib_mod_connect(struct vnc *v)
in_uint16_be(s, v->mod_height);
init_stream(pixel_format, 8192);
v->server_msg(v, "VNC receiving pixel format", 0);
- error = lib_recv(v, pixel_format->data, 16);
+ error = trans_force_read_s(v->trans, pixel_format, 16);
}
else
{
@@ -1113,7 +1194,7 @@ lib_mod_connect(struct vnc *v)
v->mod_bpp = v->server_bpp;
init_stream(s, 8192);
v->server_msg(v, "VNC receiving name length", 0);
- error = lib_recv(v, s->data, 4); /* name len */
+ error = trans_force_read_s(v->trans, s, 4); /* name len */
}
else
{
@@ -1130,8 +1211,10 @@ lib_mod_connect(struct vnc *v)
}
else
{
+ init_stream(s, 8192);
v->server_msg(v, "VNC receiving name", 0);
- error = lib_recv(v, v->mod_name, i);
+ error = trans_force_read_s(v->trans, s, i); /* name len */
+ g_memcpy(v->mod_name, s->data, i);
v->mod_name[i] = 0;
}
}
@@ -1205,7 +1288,7 @@ lib_mod_connect(struct vnc *v)
out_uint8(pixel_format, 0); /* blue shift */
out_uint8s(pixel_format, 3); /* pad */
}
- else if (v->mod_bpp == 24)
+ else if (v->mod_bpp == 24 || v->mod_bpp == 32)
{
out_uint8(pixel_format, 32); /* bits per pixel */
out_uint8(pixel_format, 24); /* depth */
@@ -1226,7 +1309,8 @@ lib_mod_connect(struct vnc *v)
out_uint8a(s, pixel_format->data, 16);
v->server_msg(v, "VNC sending pixel format", 0);
- error = lib_send(v, s->data, 20);
+ s_mark_end(s);
+ error = trans_force_write_s(v->trans, s);
}
if (error == 0)
@@ -1241,7 +1325,8 @@ lib_mod_connect(struct vnc *v)
out_uint32_be(s, 0xffffff11); /* cursor */
out_uint32_be(s, 0xffffff21); /* desktop size */
v->server_msg(v, "VNC sending encodings", 0);
- error = lib_send(v, s->data, 4 + 4 * 4);
+ s_mark_end(s);
+ error = trans_force_write_s(v->trans, s);
}
if (error == 0)
@@ -1251,7 +1336,7 @@ lib_mod_connect(struct vnc *v)
if (error == 0)
{
- /* FrambufferUpdateRequest */
+ /* FramebufferUpdateRequest */
init_stream(s, 8192);
out_uint8(s, 3);
out_uint8(s, 0);
@@ -1260,7 +1345,8 @@ lib_mod_connect(struct vnc *v)
out_uint16_be(s, v->mod_width);
out_uint16_be(s, v->mod_height);
v->server_msg(v, "VNC sending framebuffer update request", 0);
- error = lib_send(v, s->data, 10);
+ s_mark_end(s);
+ error = trans_force_write_s(v->trans, s);
}
if (error == 0)
@@ -1297,6 +1383,22 @@ lib_mod_connect(struct vnc *v)
v->server_msg(v, "VNC error - problem connecting", 0);
}
+ if (error != 0)
+ {
+ trans_delete(v->trans);
+ v->trans = 0;
+ v->server_msg(v, "some problem", 0);
+ LIB_DEBUG(mod, "out lib_mod_connect error");
+ return 1;
+ }
+ else
+ {
+ v->server_msg(v, "connected ok", 0);
+ v->trans->trans_data_in = lib_data_in;
+ v->trans->header_size = 1;
+ v->trans->callback_data = v;
+ }
+
return error;
}
@@ -1308,15 +1410,13 @@ lib_mod_end(struct vnc *v)
{
}
- g_free(v->clip_data);
- v->clip_data = 0;
- v->clip_data_size = 0;
+ free_stream(v->clip_data_s);
return 0;
}
/******************************************************************************/
int DEFAULT_CC
-lib_mod_set_param(struct vnc *v, char *name, char *value)
+lib_mod_set_param(struct vnc *v, const char *name, char *value)
{
if (g_strcasecmp(name, "username") == 0)
{
@@ -1342,6 +1442,11 @@ lib_mod_set_param(struct vnc *v, char *name, char *value)
{
v->delay_ms = g_atoi(value);
}
+ else if (g_strcasecmp(name, "guid") == 0)
+ {
+ v->got_guid = 1;
+ g_memcpy(v->guid, value, 16);
+ }
return 0;
}
@@ -1352,19 +1457,17 @@ int DEFAULT_CC
lib_mod_get_wait_objs(struct vnc *v, tbus *read_objs, int *rcount,
tbus *write_objs, int *wcount, int *timeout)
{
- int i;
-
- i = *rcount;
+ LLOGLN(10, ("lib_mod_get_wait_objs:"));
if (v != 0)
{
- if (v->sck_obj != 0)
+ if (v->trans != 0)
{
- read_objs[i++] = v->sck_obj;
+ trans_get_wait_objs_rw(v->trans, read_objs, rcount,
+ write_objs, wcount, timeout);
}
}
- *rcount = i;
return 0;
}
@@ -1376,23 +1479,18 @@ lib_mod_check_wait_objs(struct vnc *v)
int rv;
rv = 0;
-
if (v != 0)
{
- if (v->sck_obj != 0)
+ if (v->trans != 0)
{
- if (g_is_wait_obj_set(v->sck_obj))
- {
- rv = lib_mod_signal(v);
- }
+ rv = trans_check_wait_objs(v->trans);
}
}
-
return rv;
}
/******************************************************************************/
-struct vnc *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct vnc *v;
@@ -1401,7 +1499,7 @@ mod_init(void)
/* set client functions */
v->size = sizeof(struct vnc);
v->version = CURRENT_MOD_VER;
- v->handle = (long)v;
+ v->handle = (tintptr) v;
v->mod_connect = lib_mod_connect;
v->mod_start = lib_mod_start;
v->mod_event = lib_mod_event;
@@ -1410,22 +1508,21 @@ mod_init(void)
v->mod_set_param = lib_mod_set_param;
v->mod_get_wait_objs = lib_mod_get_wait_objs;
v->mod_check_wait_objs = lib_mod_check_wait_objs;
- return v;
+ return (tintptr) v;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct vnc *v)
+mod_exit(tintptr handle)
{
+ struct vnc *v = (struct vnc *) handle;
log_message(LOG_LEVEL_DEBUG, "VNC mod_exit");
if (v == 0)
{
return 0;
}
-
- g_delete_wait_obj_from_socket(v->sck_obj);
- g_tcp_close(v->sck);
+ trans_delete(v->trans);
g_free(v);
return 0;
}
diff --git a/vnc/vnc.h b/vnc/vnc.h
index 6d265beb..0bc3835d 100644
--- a/vnc/vnc.h
+++ b/vnc/vnc.h
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,10 +22,9 @@
#include "arch.h"
#include "parse.h"
#include "os_calls.h"
-#include "d3des.h"
#include "defines.h"
-#define CURRENT_MOD_VER 2
+#define CURRENT_MOD_VER 3
struct vnc
{
@@ -38,13 +37,13 @@ struct vnc
long param3, long param4);
int (*mod_signal)(struct vnc* v);
int (*mod_end)(struct vnc* v);
- int (*mod_set_param)(struct vnc* v, char* name, char* value);
+ int (*mod_set_param)(struct vnc* v, const char *name, char* value);
int (*mod_session_change)(struct vnc* v, int, int);
int (*mod_get_wait_objs)(struct vnc* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct vnc* v);
- long mod_dumby[100 - 9]; /* align, 100 minus the number of mod
- functions above */
+ tintptr mod_dumby[100 - 9]; /* align, 100 minus the number of mod
+ functions above */
/* server functions */
int (*server_begin_update)(struct vnc* v);
int (*server_end_update)(struct vnc* v);
@@ -55,7 +54,7 @@ struct vnc
char* data, int width, int height, int srcx, int srcy);
int (*server_set_cursor)(struct vnc* v, int x, int y, char* data, char* mask);
int (*server_palette)(struct vnc* v, int* palette);
- int (*server_msg)(struct vnc* v, char* msg, int code);
+ int (*server_msg)(struct vnc* v, const char *msg, int code);
int (*server_is_term)(struct vnc* v);
int (*server_set_clip)(struct vnc* v, int x, int y, int cx, int cy);
int (*server_reset_clip)(struct vnc* v);
@@ -63,12 +62,12 @@ struct vnc
int (*server_set_bgcolor)(struct vnc* v, int bgcolor);
int (*server_set_opcode)(struct vnc* v, int opcode);
int (*server_set_mixmode)(struct vnc* v, int mixmode);
- int (*server_set_brush)(struct vnc* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct vnc* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct vnc* v, int style,
int width);
int (*server_draw_line)(struct vnc* v, int x1, int y1, int x2, int y2);
- int (*server_add_char)(struct vnc* v, int font, int charactor,
+ int (*server_add_char)(struct vnc* v, int font, int character,
int offset, int baseline,
int width, int height, char* data);
int (*server_draw_text)(struct vnc* v, int font,
@@ -81,18 +80,18 @@ struct vnc
int (*server_query_channel)(struct vnc* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct vnc* v, char* name);
+ int (*server_get_channel_id)(struct vnc* v, const char *name);
int (*server_send_to_channel)(struct vnc* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
int (*server_bell_trigger)(struct vnc* v);
- long server_dumby[100 - 25]; /* align, 100 minus the number of server
- functions above */
+ tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server
+ functions above */
/* common */
- long handle; /* pointer to self as long */
- long wm;
- long painter;
- int sck;
+ tintptr handle; /* pointer to self as long */
+ tintptr wm;
+ tintptr painter;
+ tintptr si;
/* mod data */
int server_width;
int server_height;
@@ -112,8 +111,9 @@ struct vnc
int shift_state; /* 0 up, 1 down */
int keylayout;
int clip_chanid;
- char* clip_data;
- int clip_data_size;
- tbus sck_obj;
+ struct stream *clip_data_s;
int delay_ms;
+ struct trans *trans;
+ int got_guid;
+ tui8 guid[16];
};
diff --git a/vrplayer/decoderthread.cpp b/vrplayer/decoderthread.cpp
index 36ba4c85..7841a3b5 100644
--- a/vrplayer/decoderthread.cpp
+++ b/vrplayer/decoderthread.cpp
@@ -23,7 +23,7 @@
/*
* TODO:
* o need to maintain aspect ratio while resizing
- * o clicking in the middle of the slider bar shuld move the slider to the middle
+ * o clicking in the middle of the slider bar should move the slider to the middle
* o need to be able to rewind the move when it is done playing
* o need to be able to load another move and play it w/o restarting player
* o pause button needs to work
diff --git a/vrplayer/mainwindow.h b/vrplayer/mainwindow.h
index f0383098..58bcb31c 100644
--- a/vrplayer/mainwindow.h
+++ b/vrplayer/mainwindow.h
@@ -62,7 +62,7 @@ public:
~MainWindow();
signals:
- void onGeometryChanged(int x, int y, int widht, int height);
+ void onGeometryChanged(int x, int y, int width, int height);
public slots:
void onSliderValueChanged(int value);
diff --git a/xorg/.gitignore b/xorg/.gitignore
new file mode 100644
index 00000000..24600083
--- /dev/null
+++ b/xorg/.gitignore
@@ -0,0 +1 @@
+!Makefile
diff --git a/xorg/X11R7.6/.gitignore b/xorg/X11R7.6/.gitignore
new file mode 100644
index 00000000..218e4a9a
--- /dev/null
+++ b/xorg/X11R7.6/.gitignore
@@ -0,0 +1,3 @@
+build_dir
+cookies
+downloads
diff --git a/xorg/X11R7.6/buildx.sh b/xorg/X11R7.6/buildx.sh
index 22dfe15f..0c61b5e1 100755
--- a/xorg/X11R7.6/buildx.sh
+++ b/xorg/X11R7.6/buildx.sh
@@ -23,23 +23,19 @@
# debian packages needed
# flex bison libxml2-dev intltool xsltproc xutils-dev python-libxml2 g++ xutils
-download_file()
+download_all_files()
{
- local file url status
- file=$1
+ # download files parallelly using keepalive
+ # a little bit faster than calling wget with single file more than 100 times
+ < x11_file_list.txt cut -f1 -d: | sed -e "s|^|${download_url}/|" | \
+ xargs -P2 -n $(expr $num_modules / 2 + 1) \
+ wget \
+ --directory-prefix=downloads \
+ --no-verbose \
+ --timestamping \
+ --continue
- # if we already have the file, don't download it
- if [ -r downloads/$file ]; then
- return 0
- fi
-
- echo "downloading file $download_url/$file"
-
- cd downloads
-
- wget -cq $download_url/$file
status=$?
- cd ..
return $status
}
@@ -74,15 +70,6 @@ extract_it()
return 0
fi
- # download file
- if ! download_file $mod_file
- then
- echo ""
- echo "failed to download $mod_file - aborting build"
- echo ""
- exit 1
- fi
-
cd build_dir
# if pkg has not yet been extracted, do so now
@@ -105,7 +92,7 @@ extract_it()
cd $mod_name
# check for patches
if [ -e ../../$mod_name.patch ]; then
- patch -p1 < ../../$mod_name.patch
+ patch -N -p1 < ../../$mod_name.patch
fi
# now configure
echo "executing ./configure --prefix=$PREFIX_DIR $mod_args"
@@ -149,7 +136,7 @@ make_it()
# make module
if [ ! -e cookies/$mod_name.made ]; then
- if ! make -C build_dir/$mod_name
+ if ! make -j $NPROC -C build_dir/$mod_name
then
echo ""
echo "make failed for module $mod_name"
@@ -168,14 +155,6 @@ make_it()
exit 1
fi
- # special case after installing python make this sym link
- # so Mesa builds using this python version
- case "$mod_name" in
- *Python-2*)
- ln -s python build_dir/$mod_name/$PREFIX_DIR/bin/python2
- ;;
- esac
-
touch cookies/$mod_name.installed
return 0
}
@@ -188,7 +167,7 @@ data_file=x11_file_list.txt
# was www.x.org/releases/X11R7.6/src/everything
download_url=http://server1.xrdp.org/xrdp/X11R7.6
-num_modules=`cat $data_file | wc -l`
+num_modules=`wc -l < $data_file`
count=0
##########################
@@ -198,7 +177,7 @@ count=0
if [ $# -lt 1 ]; then
echo ""
echo "usage: buildx.sh <installation dir>"
- echo "usage: buildx.sh <clean>"
+ echo "usage: buildx.sh clean"
echo "usage: buildx.sh default"
echo "usage: buildx.sh <installation dir> drop - set env and run bash in rdp dir"
echo ""
@@ -218,37 +197,28 @@ else
export PREFIX_DIR=$1
fi
-if ! test -d $PREFIX_DIR; then
- echo "dir does not exist, creating [$PREFIX_DIR]"
- if ! mkdir $PREFIX_DIR
- then
- echo "mkdir failed [$PREFIX_DIR]"
- exit 0
- fi
-fi
-
-echo "using $PREFIX_DIR"
-
-export PKG_CONFIG_PATH=$PREFIX_DIR/lib/pkgconfig:$PREFIX_DIR/share/pkgconfig
-export PATH=$PREFIX_DIR/bin:$PATH
-export LDFLAGS=-Wl,-rpath=$PREFIX_DIR/lib
-export CFLAGS="-I$PREFIX_DIR/include -fPIC -O2"
-
# prefix dir must exist...
if [ ! -d $PREFIX_DIR ]; then
- if ! mkdir -p $PREFIX_DIR
- then
- echo "$PREFIX_DIR does not exist; failed to create it - cannot continue"
+ echo "$PREFIX_DIR does not exist, creating it"
+ if ! mkdir -p $PREFIX_DIR; then
+ echo "$PREFIX_DIR cannot be created - cannot continue"
exit 1
fi
fi
# ...and be writable
if [ ! -w $PREFIX_DIR ]; then
- echo "directory $PREFIX_DIR is not writable - cannot continue"
+ echo "$PREFIX_DIR is not writable - cannot continue"
exit 1
fi
+echo "installation directory: $PREFIX_DIR"
+
+export PKG_CONFIG_PATH=$PREFIX_DIR/lib/pkgconfig:$PREFIX_DIR/share/pkgconfig
+export PATH=$PREFIX_DIR/bin:$PATH
+export LDFLAGS=-Wl,-rpath=$PREFIX_DIR/lib
+export CFLAGS="-I$PREFIX_DIR/include -fPIC -O2"
+
# create a downloads dir
if [ ! -d downloads ]; then
if ! mkdir downloads
@@ -276,6 +246,18 @@ if [ ! -d cookies ]; then
fi
fi
+if ! NPROC=`nproc`; then
+ NPROC=1
+fi
+
+if ! download_all_files; then
+ echo ""
+ echo "download failed - aborting build"
+ echo "rerun this script to resume download/build"
+ echo ""
+ exit 1
+fi
+
while IFS=: read mod_file mod_dir mod_args
do
mod_args=`eval echo $mod_args`
@@ -296,8 +278,8 @@ fi
# this will copy the build X server with the other X server binaries
cd rdp
-strip X11rdp
cp X11rdp $X11RDPBASE/bin
+strip $X11RDPBASE/bin/X11rdp
if [ "$2" = "drop" ]; then
echo ""
diff --git a/xorg/X11R7.6/rdp/Makefile b/xorg/X11R7.6/rdp/Makefile
index c18e01b6..cdfea385 100644
--- a/xorg/X11R7.6/rdp/Makefile
+++ b/xorg/X11R7.6/rdp/Makefile
@@ -1,6 +1,9 @@
+# X11RDPBASE is the top-level X11rdp install directory
+ifeq ($(X11RDPBASE),)
+$(error X11RDPBASE needs to be set)
+endif
-#X11RDPBASE is an environment variable that needs to be set
-
+BINBASE = $(X11RDPBASE)/bin
INCBASE = $(X11RDPBASE)/include
LIBBASE = $(X11RDPBASE)/lib
@@ -23,23 +26,24 @@ fbcmap_mi.o
#fbcmap_mi.o
#fbcmap.o
-LIBS = $(XSRCBASE)/dbe/.libs/libdbe.a \
- $(XSRCBASE)/dix/.libs/libdix.a \
+LIBS = \
$(XSRCBASE)/dix/.libs/libmain.a \
+ librdp.a \
+ $(XSRCBASE)/dbe/.libs/libdbe.a \
+ $(XSRCBASE)/dix/.libs/libdix.a \
$(XSRCBASE)/fb/.libs/libfb.a \
$(XSRCBASE)/mi/.libs/libmi.a \
- $(XSRCBASE)/os/.libs/libos.a \
$(XSRCBASE)/randr/.libs/librandr.a \
- $(XSRCBASE)/record/.libs/librecord.a \
$(XSRCBASE)/render/.libs/librender.a \
+ $(XSRCBASE)/os/.libs/libos.a \
+ $(XSRCBASE)/record/.libs/librecord.a \
$(XSRCBASE)/xkb/.libs/libxkb.a \
$(XSRCBASE)/Xext/.libs/libXext.a \
$(XSRCBASE)/Xi/.libs/libXi.a \
$(XSRCBASE)/glx/.libs/libglx.a \
$(XSRCBASE)/xfixes/.libs/libxfixes.a \
$(XSRCBASE)/damageext/.libs/libdamageext.a \
- $(XSRCBASE)/miext/damage/.libs/libdamage.a \
- librdp.a
+ $(XSRCBASE)/miext/damage/.libs/libdamage.a
LLIBS = -Wl,-rpath=$(LIBBASE) -lfreetype -lz -lm -lXfont -lXau \
-lXdmcp -lpixman-1 -lrt -ldl -lcrypto -lGL -lXdamage
@@ -98,7 +102,7 @@ all: X11rdp
X11rdp: $(OBJS)
$(AR) rvu librdp.a $(OBJS)
ranlib librdp.a
- $(CC) $(LDFLAGS) -o X11rdp $(LIBS) $(LIBS) $(LLIBS)
+ $(CC) $(LDFLAGS) -o X11rdp $(LIBS) $(LLIBS)
clean:
rm -f $(OBJS) librdp.a
@@ -113,4 +117,4 @@ fbcmap_mi.o: ../build_dir/xorg-server-1.9.3/fb/fbcmap_mi.c
$(CC) $(CFLAGS) -c ../build_dir/xorg-server-1.9.3/fb/fbcmap_mi.c
install: all
- $(INSTALL) X11rdp $(X11RDPBASE)/bin/X11rdp
+ $(INSTALL) X11rdp $(BINBASE)/X11rdp
diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h
index 00725d11..9c373068 100644
--- a/xorg/X11R7.6/rdp/rdp.h
+++ b/xorg/X11R7.6/rdp/rdp.h
@@ -90,7 +90,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# endif
#endif
-#define X11RDPVER "0.7.0"
+#define X11RDPVER "0.9.1"
#define PixelDPI 100
#define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10))
@@ -558,9 +558,9 @@ rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask);
int
rdpup_set_cursor_ex(short x, short y, char *cur_data, char *cur_mask, int bpp);
int
-rdpup_create_os_surface(int rdpindexd, int width, int height);
+rdpup_create_os_surface(int rdpindex, int width, int height);
int
-rdpup_create_os_surface_bpp(int rdpindexd, int width, int height, int bpp);
+rdpup_create_os_surface_bpp(int rdpindex, int width, int height, int bpp);
int
rdpup_switch_os_surface(int rdpindex);
int
@@ -582,10 +582,10 @@ rdpup_check_alpha_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv);
int
rdpup_check_dirty_screen(rdpPixmapRec* pDirtyPriv);
int
-rdpup_add_char(int font, int charactor, short x, short y, int cx, int cy,
+rdpup_add_char(int font, int character, short x, short y, int cx, int cy,
char* bmpdata, int bmpdata_bytes);
int
-rdpup_add_char_alpha(int font, int charactor, short x, short y, int cx, int cy,
+rdpup_add_char_alpha(int font, int character, short x, short y, int cx, int cy,
char* bmpdata, int bmpdata_bytes);
int
rdpup_draw_text(int font, int flags, int mixmode,
diff --git a/xorg/X11R7.6/rdp/rdpComposite.c b/xorg/X11R7.6/rdp/rdpComposite.c
index f763783e..9376a533 100644
--- a/xorg/X11R7.6/rdp/rdpComposite.c
+++ b/xorg/X11R7.6/rdp/rdpComposite.c
@@ -224,7 +224,7 @@ print_format(PictFormatShort format)
/******************************************************************************/
static int
-compsoite_print(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+composite_print(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height)
{
@@ -233,7 +233,7 @@ compsoite_print(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
rdpPixmapRec* pSrcPriv;
rdpPixmapRec* pDstPriv;
- LLOGLN(0, ("compsoite_print: op %d xSrc %d ySrc %d xDst %d yDst %d "
+ LLOGLN(0, ("composite_print: op %d xSrc %d ySrc %d xDst %d yDst %d "
"width %d height %d",
op, xSrc, ySrc, xDst, yDst, width, height));
@@ -493,7 +493,7 @@ check_drawables(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
{
LLOGLN(10, ("check_drawables: can not remote [%s]", g_com_fail_strings[fail_reason]));
#if 0
- compsoite_print(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ composite_print(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height);
#endif
}
@@ -501,7 +501,7 @@ check_drawables(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
{
LLOGLN(10, ("check_drawables: can remote [%s]", g_com_fail_strings[fail_reason]));
#if 0
- compsoite_print(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ composite_print(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height);
#endif
}
@@ -707,7 +707,7 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
{
if (pMask != 0)
{
- /* TODO: here we can try to send it as a gylph */
+ /* TODO: here we can try to send it as a glyph */
}
}
}
@@ -745,7 +745,7 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
post_process = 1;
if (g_do_dirty_os)
{
- LLOGLN(10, ("rdpComposite: gettig dirty"));
+ LLOGLN(10, ("rdpComposite: getting dirty"));
pDstPriv->is_dirty = 1;
dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY;
pDirtyPriv = pDstPriv;
diff --git a/xorg/X11R7.6/rdp/rdpPolyFillRect.c b/xorg/X11R7.6/rdp/rdpPolyFillRect.c
index 7db4be69..6d37f587 100644
--- a/xorg/X11R7.6/rdp/rdpPolyFillRect.c
+++ b/xorg/X11R7.6/rdp/rdpPolyFillRect.c
@@ -188,7 +188,7 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
pGC->alu == GXnoop ||
pGC->alu == GXand ||
pGC->alu == GXcopy /*||
- pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ pGC->alu == GXxor*/)) /* todo, why doesn't xor work? */
{
draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel,
pGC->alu);
@@ -210,7 +210,7 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
pGC->alu == GXnoop ||
pGC->alu == GXand ||
pGC->alu == GXcopy /*||
- pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ pGC->alu == GXxor*/)) /* todo, why doesn't xor work? */
{
rdpup_set_fgcolor(pGC->fgPixel);
rdpup_set_opcode(pGC->alu);
@@ -253,7 +253,7 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
pGC->alu == GXnoop ||
pGC->alu == GXand ||
pGC->alu == GXcopy /*||
- pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ pGC->alu == GXxor*/)) /* todo, why doesn't xor work? */
{
LLOGLN(10, ("rdpPolyFillRect: 3"));
draw_item_add_fill_region(pDirtyPriv, &clip_reg,
@@ -280,7 +280,7 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
pGC->alu == GXnoop ||
pGC->alu == GXand ||
pGC->alu == GXcopy /*||
- pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ pGC->alu == GXxor*/)) /* todo, why doesn't xor work? */
{
rdpup_set_fgcolor(pGC->fgPixel);
rdpup_set_opcode(pGC->alu);
diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c
index e276c0b7..51fe5c61 100644
--- a/xorg/X11R7.6/rdp/rdpdraw.c
+++ b/xorg/X11R7.6/rdp/rdpdraw.c
@@ -108,7 +108,7 @@ rdp_get_clip(RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC)
break;
case CT_REGION:
rv = 2;
- RegionCopy(pRegion, pGC->clientClip);
+ RegionCopy(pRegion, pGC->pCompositeClip);
break;
default:
rdpLog("unimp clip type %d\n", pGC->clientClipType);
@@ -608,7 +608,7 @@ dump_draw_list(rdpPixmapRec* priv)
/******************************************************************************/
/* returns boolean */
static int
-region_interect_at_all(RegionPtr reg_small, RegionPtr reg_big)
+region_intersect_at_all(RegionPtr reg_small, RegionPtr reg_big)
{
int rv;
RegionRec reg;
@@ -719,7 +719,7 @@ draw_item_pack(PixmapPtr pix, rdpPixmapRec *priv)
{
if ((di->type == RDI_TEXT) && (di_prev->type == RDI_IMGLY))
{
- if (region_interect_at_all(di->reg, di_prev->reg))
+ if (region_intersect_at_all(di->reg, di_prev->reg))
{
di_prev->type = RDI_IMGLL;
}
diff --git a/xorg/X11R7.6/rdp/rdpglyph.c b/xorg/X11R7.6/rdp/rdpglyph.c
index cb895ae5..f0dda8d4 100644
--- a/xorg/X11R7.6/rdp/rdpglyph.c
+++ b/xorg/X11R7.6/rdp/rdpglyph.c
@@ -503,7 +503,7 @@ rdp_text_chars_to_data(struct rdp_text* rtext)
PictFormatPtr format;
} GlyphListRec, *GlyphListPtr;
*/
-/* see ghyphstr.h but the follow is not in there
+/* see glyphstr.h but the following is not in there
typedef struct _XGlyphInfo {
unsigned short width;
unsigned short height;
@@ -557,7 +557,7 @@ rdpGlyphu(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
post_process = 1;
if (g_do_dirty_os)
{
- LLOGLN(10, ("rdpGlyphu: gettig dirty"));
+ LLOGLN(10, ("rdpGlyphu: getting dirty"));
pDstPriv->is_dirty = 1;
dirty_type = RDI_IMGLL;
pDirtyPriv = pDstPriv;
diff --git a/xorg/X11R7.6/rdp/rdpinput.c b/xorg/X11R7.6/rdp/rdpinput.c
index a13c7b5b..6ef432e6 100644
--- a/xorg/X11R7.6/rdp/rdpinput.c
+++ b/xorg/X11R7.6/rdp/rdpinput.c
@@ -26,8 +26,8 @@ keyboard and mouse stuff
flags right so control down is used to determine between pause and
num lock */
/* this should be fixed in rdesktop */
-/* g_pause_spe flag for specal control sent by ms client before scan code
- 69 is sent to tell that its pause, not num lock. both pause and num
+/* g_pause_spe flag for special control sent by ms client before scan code
+ 69 is sent to tell that it's pause, not num lock. both pause and num
lock use scan code 69 */
/* tab notes */
@@ -59,6 +59,8 @@ extern int g_alt_down; /* in rdpmain.c */
extern int g_ctrl_down; /* in rdpmain.c */
static int g_old_button_mask = 0;
+static int g_old_x = 0;
+static int g_old_y = 0;
/* this is toggled every time num lock key is released, not like the
above *_down vars */
static int g_scroll_lock_down = 0;
@@ -66,7 +68,7 @@ static OsTimerPtr g_kbtimer = 0;
static OsTimerPtr g_timer = 0;
static int g_x = 0;
static int g_y = 0;
-static int g_timer_schedualed = 0;
+static int g_timer_scheduled = 0;
static int g_delay_motion = 1; /* turn on or off */
static int g_use_evdev = 0;
@@ -180,7 +182,7 @@ rdpChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
if (ctrls->enabled_ctrls & XkbRepeatKeysMask)
{
LLOGLN(10, ("rdpChangeKeyboardControl: autoRepeat on"));
- /* schedual to turn off the autorepeat after 100 ms so any app
+ /* schedule to turn off the autorepeat after 100 ms so any app
* polling it will be happy it's on */
g_kbtimer = TimerSet(g_kbtimer, 0, 100,
rdpInDeferredUpdateCallback, 0);
@@ -236,7 +238,7 @@ rdpChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
0x0000042C Azeri Latin
0x0000042F FYRO Macedonian
0x00000437 Georgian
-0x00000438 Faeroese
+0x00000438 Faroese
0x00000439 Devanagari - INSCRIPT
0x0000043A Maltese 47-key
0x0000043B Norwegian with Sami
@@ -323,6 +325,10 @@ rdpLoadLayout(struct xrdp_client_info *client_info)
{
set.layout = client_info->layout;
}
+ if (strlen(client_info->options) > 0)
+ {
+ set.options = client_info->options;
+ }
retry:
/* free some stuff so we can call InitKeyboardDeviceStruct again */
@@ -857,8 +863,13 @@ static CARD32
rdpDeferredInputCallback(OsTimerPtr timer, CARD32 now, pointer arg)
{
LLOGLN(10, ("rdpDeferredInputCallback:"));
- g_timer_schedualed = 0;
- rdpEnqueueMotion(g_x, g_y);
+ g_timer_scheduled = 0;
+ if ((g_old_x != g_x) || (g_old_y != g_y))
+ {
+ rdpEnqueueMotion(g_x, g_y);
+ g_old_x = g_x;
+ g_old_y = g_x;
+ }
return 0;
}
@@ -877,16 +888,21 @@ PtrAddEvent(int buttonMask, int x, int y)
return;
}
send_now = (buttonMask ^ g_old_button_mask) || (g_delay_motion == 0);
- LLOGLN(10, ("PtrAddEvent: send_now %d g_timer_schedualed %d",
- send_now, g_timer_schedualed));
+ LLOGLN(10, ("PtrAddEvent: send_now %d g_timer_scheduled %d",
+ send_now, g_timer_scheduled));
if (send_now)
{
- if (g_timer_schedualed)
+ if (g_timer_scheduled)
{
- g_timer_schedualed = 0;
+ g_timer_scheduled = 0;
TimerCancel(g_timer);
}
- rdpEnqueueMotion(x, y);
+ if ((g_old_x != x) || (g_old_y != y))
+ {
+ rdpEnqueueMotion(x, y);
+ g_old_x = x;
+ g_old_y = y;
+ }
for (i = 0; i < 5; i++)
{
if ((buttonMask ^ g_old_button_mask) & (1 << i))
@@ -911,9 +927,9 @@ PtrAddEvent(int buttonMask, int x, int y)
{
g_x = x;
g_y = y;
- if (!g_timer_schedualed)
+ if (!g_timer_scheduled)
{
- g_timer_schedualed = 1;
+ g_timer_scheduled = 1;
g_timer = TimerSet(g_timer, 0, 60, rdpDeferredInputCallback, 0);
}
}
diff --git a/xorg/X11R7.6/rdp/rdpkeyboardbase.c b/xorg/X11R7.6/rdp/rdpkeyboardbase.c
index 1c62541d..c35a0392 100644
--- a/xorg/X11R7.6/rdp/rdpkeyboardbase.c
+++ b/xorg/X11R7.6/rdp/rdpkeyboardbase.c
@@ -56,7 +56,7 @@ extern int g_tab_down; /* in rdpmain.c */
#define XSCAN_KP_3 89
#define XSCAN_KP_0 90
#define XSCAN_KP_Decimal 91
-/* "/ ?" on br keybaord */
+/* "/ ?" on br keyboard */
#define XSCAN_97 97 /* ------------------------------? */
#define XSCAN_Enter 108 /* 104 */ /* on keypad */
#define XSCAN_Control_R 109 /* 105 */
@@ -81,7 +81,7 @@ extern int g_tab_down; /* in rdpmain.c */
#define XSCAN_Menu 117 /* 135 */
#define XSCAN_LMeta 156
#define XSCAN_RMeta 156
-#define XSCAN_211 211 /* "/ ?" on br keybaord, "\ _" on jp keyboard */
+#define XSCAN_211 211 /* "/ ?" on br keyboard, "\ _" on jp keyboard */
/******************************************************************************/
void
@@ -279,7 +279,7 @@ KbdAddEvent_base(int down, int param1, int param2, int param3, int param4)
break;
case RDPSCAN_115:
- rdpEnqueueKey(type, XSCAN_211); /* "/ ?" on br keybaord, "\ _" on jp keyboard */
+ rdpEnqueueKey(type, XSCAN_211); /* "/ ?" on br keyboard, "\ _" on jp keyboard */
break;
case RDPSCAN_126:
diff --git a/xorg/X11R7.6/rdp/rdpkeyboardevdev.c b/xorg/X11R7.6/rdp/rdpkeyboardevdev.c
index 770a102f..0c560c83 100644
--- a/xorg/X11R7.6/rdp/rdpkeyboardevdev.c
+++ b/xorg/X11R7.6/rdp/rdpkeyboardevdev.c
@@ -56,7 +56,7 @@ extern int g_tab_down; /* in rdpmain.c */
#define XSCAN_KP_3 89
#define XSCAN_KP_0 90
#define XSCAN_KP_Decimal 91
-/* "/ ?" on br keybaord */
+/* "/ ?" on br keyboard */
#define XSCAN_97 97
#define XSCAN_Enter 104 /* on keypad */
#define XSCAN_Control_R 105
@@ -278,7 +278,7 @@ KbdAddEvent_evdev(int down, int param1, int param2, int param3, int param4)
break;
case RDPSCAN_115:
- rdpEnqueueKey(type, XSCAN_97); /* "/ ?" on br keybaord */
+ rdpEnqueueKey(type, XSCAN_97); /* "/ ?" on br keyboard */
break;
case RDPSCAN_126:
diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c
index 884b8a3a..7540e12e 100644
--- a/xorg/X11R7.6/rdp/rdpmain.c
+++ b/xorg/X11R7.6/rdp/rdpmain.c
@@ -41,7 +41,7 @@ Sets up the functions
#endif
#if XRDP_DISABLE_LINUX_ABSTRACT
-/* because including <X11/Xtrans/Xtransint.h> in problematic
+/* because including <X11/Xtrans/Xtransint.h> is problematic
* we dup a small struct
* we need to set flags to zero to turn off abstract sockets */
struct _MyXtransport
@@ -139,6 +139,8 @@ static miPointerScreenFuncRec g_rdpPointerCursorFuncs =
rdpPointerNewEventScreen
};
+int glGetBufferSubData(void);
+
/******************************************************************************/
/* returns error, zero is good */
static int
@@ -189,6 +191,11 @@ set_bpp(int bpp)
g_greenBits = 8;
g_blueBits = 8;
}
+ else if (g_bpp == 33)
+ {
+ /* will never happen */
+ glGetBufferSubData();
+ }
else
{
rv = 1;
@@ -297,8 +304,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
ErrorF("\n");
ErrorF("X11rdp, an X server for xrdp\n");
ErrorF("Version %s\n", X11RDPVER);
- ErrorF("Copyright (C) 2005-2012 Jay Sorg\n");
- ErrorF("See http://xrdp.sf.net for information on xrdp.\n");
+ ErrorF("Copyright (C) 2005-2015 Jay Sorg\n");
+ ErrorF("See http://www.xrdp.org for information on xrdp.\n");
#if defined(XORG_VERSION_CURRENT) && defined (XVENDORNAME)
ErrorF("Underlying X server release %d, %s\n",
XORG_VERSION_CURRENT, XVENDORNAME);
@@ -414,7 +421,7 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
g_rdpScreen.CloseScreen = pScreen->CloseScreen;
/* GC procedures */
g_rdpScreen.CreateGC = pScreen->CreateGC;
- /* Pixmap procudures */
+ /* Pixmap procedures */
g_rdpScreen.CreatePixmap = pScreen->CreatePixmap;
g_rdpScreen.DestroyPixmap = pScreen->DestroyPixmap;
@@ -590,7 +597,7 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
/******************************************************************************/
/* this is the first function called, it can be called many times
returns the number or parameters processed
- if it dosen't apply to the rdp part, return 0 */
+ if it doesn't apply to the rdp part, return 0 */
int
ddxProcessArgument(int argc, char **argv, int i)
{
@@ -654,7 +661,7 @@ void
OsVendorInit(void)
{
#if XRDP_DISABLE_LINUX_ABSTRACT
- /* turn off the Linux abstract unix doamin sockets TRANS_ABSTRACT */
+ /* turn off the Linux abstract unix domain sockets TRANS_ABSTRACT */
/* TRANS_NOLISTEN = 1 << 3 */
_XSERVTransSocketLocalFuncs.flags = 0;
#endif
diff --git a/xorg/X11R7.6/rdp/rdpmisc.c b/xorg/X11R7.6/rdp/rdpmisc.c
index 1d57d1fa..f8316ff8 100644
--- a/xorg/X11R7.6/rdp/rdpmisc.c
+++ b/xorg/X11R7.6/rdp/rdpmisc.c
@@ -254,7 +254,7 @@ g_malloc(int size, int zero)
//#ifdef _XSERVER64
#if 1
- /* I thought xalloc whould work here but I guess not, why, todo */
+ /* I thought xalloc would work here but I guess not, why, todo */
rv = (char *)malloc(size);
#else
rv = (char *)Xalloc(size);
@@ -279,7 +279,7 @@ g_free(void *ptr)
{
//#ifdef _XSERVER64
#if 1
- /* I thought xfree whould work here but I guess not, why, todo */
+ /* I thought xfree would work here but I guess not, why, todo */
free(ptr);
#else
Xfree(ptr);
diff --git a/xorg/X11R7.6/rdp/rdprandr.c b/xorg/X11R7.6/rdp/rdprandr.c
index d0ee6b1c..664a2244 100644
--- a/xorg/X11R7.6/rdp/rdprandr.c
+++ b/xorg/X11R7.6/rdp/rdprandr.c
@@ -38,6 +38,14 @@ extern WindowPtr g_invalidate_window; /* in rdpmain.c */
static XID g_wid = 0;
+static int g_panning = 0;
+
+#define LOG_LEVEL 1
+#define LLOG(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0)
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
+
/******************************************************************************/
Bool
rdpRRRegisterSize(ScreenPtr pScreen, int width, int height)
@@ -68,15 +76,8 @@ rdpRRSetConfig(ScreenPtr pScreen, Rotation rotateKind, int rate,
Bool
rdpRRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
{
- int width;
- int height;
-
ErrorF("rdpRRGetInfo:\n");
*pRotations = RR_Rotate_0;
-
- width = g_rdpScreen.width;
- height = g_rdpScreen.height;
- rdpRRRegisterSize(pScreen, width, height);
return TRUE;
}
@@ -214,6 +215,19 @@ Bool
rdpRRCrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr crtc)
{
ErrorF("rdpRRCrtcGetGamma:\n");
+ crtc->gammaSize = 1;
+ if (crtc->gammaRed == NULL)
+ {
+ crtc->gammaRed = g_malloc(32, 1);
+ }
+ if (crtc->gammaBlue == NULL)
+ {
+ crtc->gammaBlue = g_malloc(32, 1);
+ }
+ if (crtc->gammaGreen == NULL)
+ {
+ crtc->gammaGreen = g_malloc(32, 1);
+ }
return TRUE;
}
@@ -257,6 +271,11 @@ rdpRRGetPanning(ScreenPtr pScrn, RRCrtcPtr crtc, BoxPtr totalArea,
{
ErrorF("rdpRRGetPanning:\n");
+ if (!g_panning)
+ {
+ return FALSE;
+ }
+
if (totalArea != 0)
{
totalArea->x1 = 0;
@@ -292,3 +311,146 @@ rdpRRSetPanning(ScreenPtr pScrn, RRCrtcPtr crtc, BoxPtr totalArea,
ErrorF("rdpRRSetPanning:\n");
return TRUE;
}
+
+/******************************************************************************/
+static RROutputPtr
+rdpRRAddOutput(const char *aname, int x, int y, int width, int height)
+{
+ RRModePtr mode;
+ RRCrtcPtr crtc;
+ RROutputPtr output;
+ xRRModeInfo modeInfo;
+ char name[64];
+ const int vfreq = 50;
+
+ sprintf (name, "%dx%d", width, height);
+ memset (&modeInfo, 0, sizeof(modeInfo));
+ modeInfo.width = width;
+ modeInfo.height = height;
+ modeInfo.hTotal = width;
+ modeInfo.vTotal = height;
+ modeInfo.dotClock = vfreq * width * height;
+ modeInfo.nameLength = strlen(name);
+ mode = RRModeGet(&modeInfo, name);
+ if (mode == 0)
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RRModeGet failed"));
+ return 0;
+ }
+
+ crtc = RRCrtcCreate(g_pScreen, NULL);
+ if (crtc == 0)
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RRCrtcCreate failed"));
+ RRModeDestroy(mode);
+ return 0;
+ }
+ output = RROutputCreate(g_pScreen, aname, strlen(aname), NULL);
+ if (output == 0)
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputCreate failed"));
+ RRCrtcDestroy(crtc);
+ RRModeDestroy(mode);
+ return 0;
+ }
+ if (!RROutputSetClones(output, NULL, 0))
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputSetClones failed"));
+ }
+ if (!RROutputSetModes(output, &mode, 1, 0))
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputSetModes failed"));
+ }
+ if (!RROutputSetCrtcs(output, &crtc, 1))
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputSetCrtcs failed"));
+ }
+ if (!RROutputSetConnection(output, RR_Connected))
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputSetConnection failed"));
+ }
+ RRCrtcNotify(crtc, mode, x, y, RR_Rotate_0, NULL, 1, &output);
+
+ return output;
+}
+
+/******************************************************************************/
+static void
+RRSetPrimaryOutput(rrScrPrivPtr pScrPriv, RROutputPtr output)
+{
+ if (pScrPriv->primaryOutput == output)
+ {
+ return;
+ }
+ /* clear the old primary */
+ if (pScrPriv->primaryOutput)
+ {
+ RROutputChanged(pScrPriv->primaryOutput, 0);
+ pScrPriv->primaryOutput = NULL;
+ }
+ /* set the new primary */
+ if (output)
+ {
+ pScrPriv->primaryOutput = output;
+ RROutputChanged(output, 0);
+ }
+ pScrPriv->layoutChanged = TRUE;
+}
+
+/******************************************************************************/
+int
+rdpRRSetRdpOutputs(void)
+{
+ rrScrPrivPtr pRRScrPriv;
+ int index;
+ int width;
+ int height;
+ char text[256];
+ RROutputPtr output;
+
+ pRRScrPriv = rrGetScrPriv(g_pScreen);
+
+ LLOGLN(0, ("rdpRRSetRdpOutputs: numCrtcs %d", pRRScrPriv->numCrtcs));
+ while (pRRScrPriv->numCrtcs > 0)
+ {
+ RRCrtcDestroy(pRRScrPriv->crtcs[0]);
+ }
+ LLOGLN(0, ("rdpRRSetRdpOutputs: numOutputs %d", pRRScrPriv->numOutputs));
+ while (pRRScrPriv->numOutputs > 0)
+ {
+ RROutputDestroy(pRRScrPriv->outputs[0]);
+ }
+
+ if (g_rdpScreen.client_info.monitorCount == 0)
+ {
+ rdpRRAddOutput("rdp0", 0, 0, g_rdpScreen.width, g_rdpScreen.height);
+ }
+ else
+ {
+ for (index = 0; index < g_rdpScreen.client_info.monitorCount; index++)
+ {
+ snprintf(text, 255, "rdp%d", index);
+ width = g_rdpScreen.client_info.minfo[index].right - g_rdpScreen.client_info.minfo[index].left + 1;
+ height = g_rdpScreen.client_info.minfo[index].bottom - g_rdpScreen.client_info.minfo[index].top + 1;
+ output = rdpRRAddOutput(text,
+ g_rdpScreen.client_info.minfo[index].left,
+ g_rdpScreen.client_info.minfo[index].top,
+ width, height);
+ if ((output != 0) && (g_rdpScreen.client_info.minfo[index].is_primary))
+ {
+ RRSetPrimaryOutput(pRRScrPriv, output);
+ }
+ }
+ }
+
+#if 0
+ for (index = 0; index < pRRScrPriv->numOutputs; index++)
+ {
+ RROutputSetCrtcs(pRRScrPriv->outputs[index], pRRScrPriv->crtcs,
+ pRRScrPriv->numCrtcs);
+ }
+#endif
+
+ return 0;
+}
+
diff --git a/xorg/X11R7.6/rdp/rdprandr.h b/xorg/X11R7.6/rdp/rdprandr.h
index 3aba7e1a..1860fa96 100644
--- a/xorg/X11R7.6/rdp/rdprandr.h
+++ b/xorg/X11R7.6/rdp/rdprandr.h
@@ -57,4 +57,7 @@ Bool
rdpRRSetPanning(ScreenPtr pScrn, RRCrtcPtr crtc, BoxPtr totalArea,
BoxPtr trackingArea, INT16* border);
+int
+rdpRRSetRdpOutputs(void);
+
#endif
diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c
index f25b390a..54eb779d 100644
--- a/xorg/X11R7.6/rdp/rdpup.c
+++ b/xorg/X11R7.6/rdp/rdpup.c
@@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "xrdp_rail.h"
#include "rdpglyph.h"
+#include "rdprandr.h"
#include <signal.h>
#include <sys/ipc.h>
@@ -35,7 +36,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
static int g_use_shmem = 1; /* turns on or off */
-static int g_shmemid = 0;
+static int g_shmemid = -1;
static char *g_shmemptr = 0;
static int g_shmem_lineBytes = 0;
static RegionPtr g_shm_reg = 0;
@@ -712,7 +713,6 @@ sck_can_recv(int sck, int millis)
static int
process_screen_size_msg(int width, int height, int bpp)
{
- RRScreenSizePtr pSize;
int mmwidth;
int mmheight;
int bytes;
@@ -750,29 +750,40 @@ process_screen_size_msg(int width, int height, int bpp)
if (g_shmemptr != 0)
{
shmdt(g_shmemptr);
+ g_shmemptr = 0;
}
bytes = g_rdpScreen.rdp_width * g_rdpScreen.rdp_height *
g_rdpScreen.rdp_Bpp;
g_shmemid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777);
- g_shmemptr = shmat(g_shmemid, 0, 0);
- shmctl(g_shmemid, IPC_RMID, NULL);
- LLOGLN(0, ("process_screen_size_msg: g_shmemid %d g_shmemptr %p",
- g_shmemid, g_shmemptr));
- g_shmem_lineBytes = g_rdpScreen.rdp_Bpp * g_rdpScreen.rdp_width;
-
- if (g_shm_reg != 0)
+ if (g_shmemid != -1)
{
- RegionDestroy(g_shm_reg);
+ g_shmemptr = shmat(g_shmemid, 0, 0);
+ if (g_shmemptr == (void *) -1)
+ {
+ LLOGLN(0, ("process_screen_size_msg: shmat failed for %d "
+ "bytes g_shmemid %d", bytes, g_shmemid));
+ g_shmemptr = 0;
+ shmctl(g_shmemid, IPC_RMID, NULL);
+ g_shmemid = -1;
+ }
+ else
+ {
+ shmctl(g_shmemid, IPC_RMID, NULL);
+ }
+ LLOGLN(0, ("process_screen_size_msg: g_shmemid %d g_shmemptr %p",
+ g_shmemid, g_shmemptr));
+ g_shmem_lineBytes = g_rdpScreen.rdp_Bpp * g_rdpScreen.rdp_width;
+ if (g_shm_reg != 0)
+ {
+ RegionDestroy(g_shm_reg);
+ }
+ g_shm_reg = RegionCreate(NullBox, 0);
}
- g_shm_reg = RegionCreate(NullBox, 0);
}
mmwidth = PixelToMM(width);
mmheight = PixelToMM(height);
- pSize = RRRegisterSize(g_pScreen, width, height, mmwidth, mmheight);
- RRSetCurrentConfig(g_pScreen, RR_Rotate_0, 0, pSize);
-
if ((g_rdpScreen.width != width) || (g_rdpScreen.height != height))
{
LLOGLN(0, (" calling RRScreenSizeSet"));
@@ -916,6 +927,7 @@ rdpup_process_msg(struct stream *s)
int y;
int cx;
int cy;
+ int index;
RegionRec reg;
BoxRec box;
@@ -1105,16 +1117,45 @@ rdpup_process_msg(struct stream *s)
{
LLOGLN(0, (" client can not do new(color) cursor"));
}
+
if (g_rdpScreen.client_info.monitorCount > 0)
{
LLOGLN(0, (" client can do multimon"));
LLOGLN(0, (" client monitor data, monitorCount= %d", g_rdpScreen.client_info.monitorCount));
+ box.x1 = g_rdpScreen.client_info.minfo[0].left;
+ box.y1 = g_rdpScreen.client_info.minfo[0].top;
+ box.x2 = g_rdpScreen.client_info.minfo[0].right;
+ box.y2 = g_rdpScreen.client_info.minfo[0].bottom;
g_do_multimon = 1;
+ /* adjust monitor info so it's not negative */
+ for (index = 1; index < g_rdpScreen.client_info.monitorCount; index++)
+ {
+ box.x1 = min(box.x1, g_rdpScreen.client_info.minfo[index].left);
+ box.y1 = min(box.y1, g_rdpScreen.client_info.minfo[index].top);
+ box.x2 = max(box.x2, g_rdpScreen.client_info.minfo[index].right);
+ box.y2 = max(box.y2, g_rdpScreen.client_info.minfo[index].bottom);
+ }
+ for (index = 0; index < g_rdpScreen.client_info.monitorCount; index++)
+ {
+ g_rdpScreen.client_info.minfo[index].left -= box.x1;
+ g_rdpScreen.client_info.minfo[index].top -= box.y1;
+ g_rdpScreen.client_info.minfo[index].right -= box.x1;
+ g_rdpScreen.client_info.minfo[index].bottom -= box.y1;
+ LLOGLN(0, (" left %d top %d right %d bottom %d",
+ g_rdpScreen.client_info.minfo[index].left,
+ g_rdpScreen.client_info.minfo[index].top,
+ g_rdpScreen.client_info.minfo[index].right,
+ g_rdpScreen.client_info.minfo[index].bottom));
+ }
+ rdpRRSetRdpOutputs();
+ RRTellChanged(g_pScreen);
}
else
{
LLOGLN(0, (" client can not do multimon"));
g_do_multimon = 0;
+ rdpRRSetRdpOutputs();
+ RRTellChanged(g_pScreen);
}
rdpLoadLayout(&(g_rdpScreen.client_info));
@@ -1305,7 +1346,7 @@ rdpup_init(void)
g_disconnect_timeout_s = 60;
}
- rdpLog("kill disconencted [%d] timeout [%d] sec\n", g_do_kill_disconnected,
+ rdpLog("kill disconnected [%d] timeout [%d] sec\n", g_do_kill_disconnected,
g_disconnect_timeout_s);
return 1;
@@ -2108,7 +2149,7 @@ rdpup_send_area(struct image_data *id, int x, int y, int w, int h)
safety = 0;
while (RegionContainsRect(g_shm_reg, &box))
{
- /* instread of rdpup_end_update, call rdpup_send_pending */
+ /* instead of rdpup_end_update, call rdpup_send_pending */
rdpup_send_pending();
rdpup_begin_update();
safety++;
@@ -2809,7 +2850,7 @@ rdpup_check_alpha_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv)
/******************************************************************************/
int
-rdpup_add_char(int font, int charactor, short x, short y, int cx, int cy,
+rdpup_add_char(int font, int character, short x, short y, int cx, int cy,
char* bmpdata, int bmpdata_bytes)
{
if (g_connected)
@@ -2820,7 +2861,7 @@ rdpup_add_char(int font, int charactor, short x, short y, int cx, int cy,
out_uint16_le(g_out_s, 18 + bmpdata_bytes); /* size */
g_count++;
out_uint16_le(g_out_s, font);
- out_uint16_le(g_out_s, charactor);
+ out_uint16_le(g_out_s, character);
out_uint16_le(g_out_s, x);
out_uint16_le(g_out_s, y);
out_uint16_le(g_out_s, cx);
@@ -2833,7 +2874,7 @@ rdpup_add_char(int font, int charactor, short x, short y, int cx, int cy,
/******************************************************************************/
int
-rdpup_add_char_alpha(int font, int charactor, short x, short y, int cx, int cy,
+rdpup_add_char_alpha(int font, int character, short x, short y, int cx, int cy,
char* bmpdata, int bmpdata_bytes)
{
if (g_connected)
@@ -2844,7 +2885,7 @@ rdpup_add_char_alpha(int font, int charactor, short x, short y, int cx, int cy,
out_uint16_le(g_out_s, 18 + bmpdata_bytes); /* size */
g_count++;
out_uint16_le(g_out_s, font);
- out_uint16_le(g_out_s, charactor);
+ out_uint16_le(g_out_s, character);
out_uint16_le(g_out_s, x);
out_uint16_le(g_out_s, y);
out_uint16_le(g_out_s, cx);
diff --git a/xorg/X11R7.6/rdp/rdpxv.c b/xorg/X11R7.6/rdp/rdpxv.c
index d0ce8345..99fbd993 100644
--- a/xorg/X11R7.6/rdp/rdpxv.c
+++ b/xorg/X11R7.6/rdp/rdpxv.c
@@ -165,7 +165,7 @@ static int
rdpXvSetPortAttribute(ClientPtr client, XvPortPtr pPort, Atom attribute,
INT32 value)
{
- LLOGLN(0, ("rdpXvxSetPortAttribute:"));
+ LLOGLN(0, ("rdpXvSetPortAttribute:"));
return Success;
}
diff --git a/xorg/X11R7.6/x11_file_list.txt b/xorg/X11R7.6/x11_file_list.txt
index 254ac7a6..c4e9b986 100644
--- a/xorg/X11R7.6/x11_file_list.txt
+++ b/xorg/X11R7.6/x11_file_list.txt
@@ -1,4 +1,3 @@
-Python-2.7.tar.bz2 : Python-2.7 :
util-macros-1.11.0.tar.bz2 : util-macros-1.11.0 :
xf86driproto-2.1.0.tar.bz2 : xf86driproto-2.1.0 :
dri2proto-2.3.tar.bz2 : dri2proto-2.3 :
@@ -7,30 +6,34 @@ libpciaccess-0.12.0.tar.bz2 : libpciaccess-0.12.0
libpthread-stubs-0.3.tar.bz2 : libpthread-stubs-0.3 :
libdrm-2.4.26.tar.bz2 : libdrm-2.4.26 :
damageproto-1.2.1.tar.bz2 : damageproto-1.2.1 :
+xproto-7.0.20.tar.bz2 : xproto-7.0.20 :
makedepend-1.0.3.tar.bz2 : makedepend-1.0.3 :
libxml2-sources-2.7.8.tar.gz : libxml2-2.7.8 :
libpng-1.2.46.tar.gz : libpng-1.2.46 :
pixman-0.30.0.tar.bz2 : pixman-0.30.0 : --disable-gtk
freetype-2.4.6.tar.bz2 : freetype-2.4.6 :
-fontconfig-2.8.0.tar.gz : fontconfig-2.8.0 :
+fontconfig-2.8.0.tar.gz : fontconfig-2.8.0 : --disable-docs
cairo-1.8.8.tar.gz : cairo-1.8.8 :
expat-2.0.1.tar.gz : expat-2.0.1 :
xextproto-7.1.2.tar.bz2 : xextproto-7.1.2 :
-xproto-7.0.20.tar.bz2 : xproto-7.0.20 :
xcb-proto-1.6.tar.bz2 : xcb-proto-1.6 :
+libXau-1.0.6.tar.bz2 : libXau-1.0.6 :
+libXdmcp-1.1.0.tar.bz2 : libXdmcp-1.1.0 :
libxcb-1.7.tar.bz2 : libxcb-1.7 :
xtrans-1.2.6.tar.bz2 : xtrans-1.2.6 :
+kbproto-1.0.5.tar.bz2 : kbproto-1.0.5 :
+inputproto-2.0.1.tar.bz2 : inputproto-2.0.1 :
libX11-1.4.0.tar.bz2 : libX11-1.4.0 :
libXext-1.2.0.tar.bz2 : libXext-1.2.0 :
libICE-1.0.7.tar.bz2 : libICE-1.0.7 :
libSM-1.2.0.tar.bz2 : libSM-1.2.0 :
libXt-1.0.9.tar.bz2 : libXt-1.0.9 :
-libXdamage-1.1.3.tar.bz2 : libXdamage-1.1.3 :
+fixesproto-4.1.2.tar.bz2 : fixesproto-4.1.2 :
libXfixes-4.0.5.tar.bz2 : libXfixes-4.0.5 :
+libXdamage-1.1.3.tar.bz2 : libXdamage-1.1.3 :
MesaLib-7.10.3.tar.bz2 : Mesa-7.10.3 : --with-expat=$PREFIX_DIR --disable-gallium
randrproto-1.3.2.tar.bz2 : randrproto-1.3.2 :
renderproto-0.11.1.tar.bz2 : renderproto-0.11.1 :
-fixesproto-4.1.2.tar.bz2 : fixesproto-4.1.2 :
xcmiscproto-1.2.1.tar.bz2 : xcmiscproto-1.2.1 :
xf86vidmodeproto-2.3.tar.bz2 : xf86vidmodeproto-2.3 :
xf86bigfontproto-1.2.0.tar.bz2 : xf86bigfontproto-1.2.0 :
@@ -38,15 +41,11 @@ scrnsaverproto-1.2.1.tar.bz2 : scrnsaverproto-1.2.1
bigreqsproto-1.1.1.tar.bz2 : bigreqsproto-1.1.1 :
resourceproto-1.1.1.tar.bz2 : resourceproto-1.1.1 :
fontsproto-2.1.1.tar.bz2 : fontsproto-2.1.1 :
-inputproto-2.0.1.tar.bz2 : inputproto-2.0.1 :
xf86dgaproto-2.1.tar.bz2 : xf86dgaproto-2.1 :
videoproto-2.3.1.tar.bz2 : videoproto-2.3.1 :
compositeproto-0.4.2.tar.bz2 : compositeproto-0.4.2 :
recordproto-1.14.1.tar.bz2 : recordproto-1.14.1 :
xineramaproto-1.2.tar.bz2 : xineramaproto-1.2 :
-libXau-1.0.6.tar.bz2 : libXau-1.0.6 :
-kbproto-1.0.5.tar.bz2 : kbproto-1.0.5 :
-libXdmcp-1.1.0.tar.bz2 : libXdmcp-1.1.0 :
libxslt-1.1.26.tar.gz : libxslt-1.1.26 :
libxkbfile-1.0.7.tar.bz2 : libxkbfile-1.0.7 :
libfontenc-1.1.0.tar.bz2 : libfontenc-1.1.0 :
@@ -64,6 +63,7 @@ applewmproto-1.4.1.tar.bz2 : applewmproto-1.4.1
bdftopcf-1.0.3.tar.bz2 : bdftopcf-1.0.3 :
intltool-0.41.1.tar.gz : intltool-0.41.1 :
xkeyboard-config-2.0.tar.bz2 : xkeyboard-config-2.0 :
+font-util-1.2.0.tar.bz2 : font-util-1.2.0 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
font-adobe-75dpi-1.0.3.tar.bz2 : font-adobe-75dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
font-adobe-100dpi-1.0.3.tar.bz2 : font-adobe-100dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
font-adobe-utopia-75dpi-1.0.4.tar.bz2 : font-adobe-utopia-75dpi-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
@@ -97,6 +97,5 @@ font-schumacher-misc-1.1.2.tar.bz2 : font-schumacher-misc-1.1.2
font-screen-cyrillic-1.0.4.tar.bz2 : font-screen-cyrillic-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
font-sony-misc-1.0.3.tar.bz2 : font-sony-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
font-sun-misc-1.0.3.tar.bz2 : font-sun-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-util-1.2.0.tar.bz2 : font-util-1.2.0 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
font-winitzki-cyrillic-1.0.3.tar.bz2 : font-winitzki-cyrillic-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
font-xfree86-type1-1.0.4.tar.bz2 : font-xfree86-type1-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
diff --git a/xorg/X11R7.6/xkeyboard-config-2.0.patch b/xorg/X11R7.6/xkeyboard-config-2.0.patch
new file mode 100644
index 00000000..a77f117a
--- /dev/null
+++ b/xorg/X11R7.6/xkeyboard-config-2.0.patch
@@ -0,0 +1,88 @@
+diff -rupP xkeyboard-config-2.0.orig/rules/HDR xkeyboard-config-2.0/rules/HDR
+--- xkeyboard-config-2.0.orig/rules/HDR 2016-06-28 19:31:02.814647638 +0900
++++ xkeyboard-config-2.0/rules/HDR 2016-06-28 19:33:58.251517616 +0900
+@@ -15,6 +15,7 @@
+ ! model layout[3] variant[3] = symbols
+ ! model layout[4] variant[4] = symbols
+ ! model = symbols
++! model layout = symbols
+ ! layout variant = compat
+ ! layout[1] variant[1] = compat
+ ! layout[2] variant[2] = compat
+diff -rupP xkeyboard-config-2.0.orig/rules/Makefile.am xkeyboard-config-2.0/rules/Makefile.am
+--- xkeyboard-config-2.0.orig/rules/Makefile.am 2016-06-28 19:31:02.814647638 +0900
++++ xkeyboard-config-2.0/rules/Makefile.am 2016-06-28 20:58:22.276629031 +0900
+@@ -41,6 +41,7 @@ HDR compat/base.ml2v2_s.part extras/bas
+ HDR compat/base.ml3v3_s.part extras/base.ml3v3_s.part \
+ HDR compat/base.ml4v4_s.part extras/base.ml4v4_s.part \
+ HDR base.m_s.part \
++HDR base.ml_s1.part \
+ HDR compat/base.lv_c.part \
+ HDR compat/base.l1v1_c.part \
+ HDR compat/base.l2v2_c.part \
+@@ -114,6 +115,7 @@ HDR extras/base.ml2v2_s.part \
+ HDR extras/base.ml3v3_s.part \
+ HDR extras/base.ml4v4_s.part \
+ HDR base.m_s.part \
++HDR base.ml_s1.part \
+ HDR \
+ HDR \
+ HDR \
+@@ -183,6 +185,7 @@ base.ml2_s.part \
+ base.ml3_s.part \
+ base.ml4_s.part \
+ base.m_s.part \
++base.ml_s1.part \
+ base.ml_c.part \
+ base.ml1_c.part \
+ base.m_t.part \
+diff -rupP xkeyboard-config-2.0.orig/rules/Makefile.in xkeyboard-config-2.0/rules/Makefile.in
+--- xkeyboard-config-2.0.orig/rules/Makefile.in 2016-06-28 19:31:02.850647811 +0900
++++ xkeyboard-config-2.0/rules/Makefile.in 2016-06-28 21:00:57.569398853 +0900
+@@ -239,6 +239,7 @@ SUBDIRS = bin compat extras
+ @USE_COMPAT_RULES_FALSE@HDR extras/base.ml3v3_s.part \
+ @USE_COMPAT_RULES_FALSE@HDR extras/base.ml4v4_s.part \
+ @USE_COMPAT_RULES_FALSE@HDR base.m_s.part \
++@USE_COMPAT_RULES_FALSE@HDR base.ml_s1.part \
+ @USE_COMPAT_RULES_FALSE@HDR \
+ @USE_COMPAT_RULES_FALSE@HDR \
+ @USE_COMPAT_RULES_FALSE@HDR \
+@@ -275,6 +276,7 @@ SUBDIRS = bin compat extras
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.ml3v3_s.part extras/base.ml3v3_s.part \
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.ml4v4_s.part extras/base.ml4v4_s.part \
+ @USE_COMPAT_RULES_TRUE@HDR base.m_s.part \
++@USE_COMPAT_RULES_TRUE@HDR base.ml_s1.part \
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.lv_c.part \
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.l1v1_c.part \
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.l2v2_c.part \
+@@ -378,6 +380,7 @@ base.ml2_s.part \
+ base.ml3_s.part \
+ base.ml4_s.part \
+ base.m_s.part \
++base.ml_s1.part \
+ base.ml_c.part \
+ base.ml1_c.part \
+ base.m_t.part \
+diff -rupP xkeyboard-config-2.0.orig/rules/base.ml_s1.part xkeyboard-config-2.0/rules/base.ml_s1.part
+--- xkeyboard-config-2.0.orig/rules/base.ml_s1.part 1970-01-01 09:00:00.000000000 +0900
++++ xkeyboard-config-2.0/rules/base.ml_s1.part 2016-06-28 19:59:05.238990192 +0900
+@@ -0,0 +1 @@
++ $inetkbds jp = +jp(henkan)
+diff -rupP xkeyboard-config-2.0.orig/symbols/jp xkeyboard-config-2.0/symbols/jp
+--- xkeyboard-config-2.0.orig/symbols/jp 2016-06-28 19:31:03.046648788 +0900
++++ xkeyboard-config-2.0/symbols/jp 2016-06-28 19:32:57.367215702 +0900
+@@ -105,6 +105,14 @@ xkb_symbols "common" {
+ };
+ };
+
++partial alphanumeric_keys
++xkb_symbols "henkan" {
++ key <XFER> {
++ type[Group1]= "PC_ALT_LEVEL2",
++ symbols[Group1]= [ Henkan, Mode_switch ]
++ };
++};
++
+ // OADG109A map
+ partial alphanumeric_keys
+ xkb_symbols "OADG109A" {
diff --git a/xorg/tests/randr/trandr.c b/xorg/tests/randr/trandr.c
index 4f7be527..6c51a000 100644
--- a/xorg/tests/randr/trandr.c
+++ b/xorg/tests/randr/trandr.c
@@ -143,4 +143,4 @@ main(int argc, char **argv)
}
return 0;
-} \ No newline at end of file
+}
diff --git a/xorg/tests/xdemo/bmp_parser.c b/xorg/tests/xdemo/bmp_parser.c
index 66c050d8..60d86864 100644
--- a/xorg/tests/xdemo/bmp_parser.c
+++ b/xorg/tests/xdemo/bmp_parser.c
@@ -70,7 +70,7 @@ int parse_bmp(char *filename, struct pic_info *pic_info)
if ((fd = open(filename, O_RDONLY)) < 0)
{
- printf("error opeing %s\n", filename);
+ printf("error opening %s\n", filename);
return -1;
}
diff --git a/xorg/tests/xdemo/xdemo.c b/xorg/tests/xdemo/xdemo.c
index f7e6b0ef..cef93274 100644
--- a/xorg/tests/xdemo/xdemo.c
+++ b/xorg/tests/xdemo/xdemo.c
@@ -205,7 +205,7 @@ int drawFont(int count, char *msg)
}
else
{
- printf("XListFonts() reted NULL\n");
+ printf("XListFonts() returned NULL\n");
}
#endif
diff --git a/xorg/tests/xdemo/yosemite.bmp b/xorg/tests/xdemo/yosemite.bmp
index c64aba75..da2e8eed 100644
--- a/xorg/tests/xdemo/yosemite.bmp
+++ b/xorg/tests/xdemo/yosemite.bmp
Binary files differ
diff --git a/xorgxrdp b/xorgxrdp
deleted file mode 160000
-Subproject 68412e5b93d9c41c1e0f3f0e6c4d11c68754fe5
diff --git a/xrdp/Makefile.am b/xrdp/Makefile.am
index 4fd9a689..f39610a0 100644
--- a/xrdp/Makefile.am
+++ b/xrdp/Makefile.am
@@ -1,39 +1,43 @@
-EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp xrdp_logo.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h
+EXTRA_DIST = \
+ czech.txt \
+ rdp-scan-codes.txt \
+ xrdpwin.c
-EXTRA_INCLUDES =
-EXTRA_LIBS =
-EXTRA_FLAGS =
+AM_CPPFLAGS = \
+ -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
+ -DXRDP_SBIN_PATH=\"${sbindir}\" \
+ -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
+ -DXRDP_MODULE_PATH=\"${moduledir}\" \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/common \
+ -I$(top_srcdir)/libxrdp
+
+XRDP_EXTRA_LIBS =
if XRDP_DEBUG
-EXTRA_DEFINES = -DXRDP_DEBUG
+AM_CPPFLAGS += -DXRDP_DEBUG
else
-EXTRA_DEFINES = -DXRDP_NODEBUG
-endif
-
-if GOT_PREFIX
-EXTRA_INCLUDES += -I$(prefix)/include
-EXTRA_FLAGS += -L$(prefix)/lib -Wl,-rpath -Wl,$(prefix)/lib
+AM_CPPFLAGS += -DXRDP_NODEBUG
endif
if XRDP_RFXCODEC
-EXTRA_DEFINES += -DXRDP_RFXCODEC
-EXTRA_INCLUDES += -I$(top_srcdir)/librfxcodec/include
-EXTRA_LIBS += $(top_srcdir)/librfxcodec/src/librfxencode.a
+AM_CPPFLAGS += -DXRDP_RFXCODEC
+AM_CPPFLAGS += -I$(top_srcdir)/librfxcodec/include
+XRDP_EXTRA_LIBS += $(top_builddir)/librfxcodec/src/.libs/librfxencode.a
endif
-AM_CFLAGS = \
- -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
- -DXRDP_SBIN_PATH=\"${sbindir}\" \
- -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\" \
- -DXRDP_LIB_PATH=\"${libdir}\" \
- $(EXTRA_DEFINES)
+if XRDP_PIXMAN
+AM_CPPFLAGS += -DXRDP_PIXMAN
+AM_CPPFLAGS += $(PIXMAN_CFLAGS)
+XRDP_EXTRA_LIBS += $(PIXMAN_LIBS)
+endif
-INCLUDES = \
- -I$(top_builddir) \
- -I$(top_srcdir)/common \
- -I$(top_srcdir)/libxrdp \
- $(EXTRA_INCLUDES)
+if XRDP_PAINTER
+AM_CPPFLAGS += -DXRDP_PAINTER
+AM_CPPFLAGS += -I$(top_srcdir)/libpainter/include
+XRDP_EXTRA_LIBS += $(top_builddir)/libpainter/src/.libs/libpainter.a
+endif
sbin_PROGRAMS = \
xrdp
@@ -41,9 +45,12 @@ sbin_PROGRAMS = \
xrdp_SOURCES = \
funcs.c \
lang.c \
- xrdp_bitmap.c \
xrdp.c \
+ xrdp.h \
+ xrdp_bitmap.c \
xrdp_cache.c \
+ xrdp_encoder.c \
+ xrdp_encoder.h \
xrdp_font.c \
xrdp_listen.c \
xrdp_login_wnd.c \
@@ -51,26 +58,23 @@ xrdp_SOURCES = \
xrdp_painter.c \
xrdp_process.c \
xrdp_region.c \
- xrdp_wm.c \
- xrdp_encoder.c
+ xrdp_types.h \
+ xrdp_wm.c
xrdp_LDADD = \
$(top_builddir)/common/libcommon.la \
$(top_builddir)/libxrdp/libxrdp.la \
- $(EXTRA_LIBS)
-
-xrdp_LDFLAGS = \
- $(EXTRA_FLAGS)
+ $(XRDP_EXTRA_LIBS)
xrdpsysconfdir=$(sysconfdir)/xrdp
-xrdpsysconf_DATA = \
+dist_xrdpsysconf_DATA = \
xrdp.ini \
xrdp_keyboard.ini
xrdppkgdatadir=$(datadir)/xrdp
-xrdppkgdata_DATA = \
+dist_xrdppkgdata_DATA = \
ad24b.bmp \
ad256.bmp \
xrdp24b.bmp \
diff --git a/xrdp/ad256.bmp b/xrdp/ad256.bmp
index 5e1946c0..5e1946c0 100755..100644
--- a/xrdp/ad256.bmp
+++ b/xrdp/ad256.bmp
Binary files differ
diff --git a/xrdp/lang.c b/xrdp/lang.c
index de81c681..1dede6f6 100644
--- a/xrdp/lang.c
+++ b/xrdp/lang.c
@@ -226,22 +226,34 @@ int APP_CC
get_keymaps(int keylayout, struct xrdp_keymap *keymap)
{
int fd;
+ int basic_key_layout = keylayout & 0x0000ffff;
char *filename;
struct xrdp_keymap *lkeymap;
filename = (char *)g_malloc(256, 0);
- /* check if there is a keymap file */
- g_snprintf(filename, 255, "%s/km-%4.4x.ini", XRDP_CFG_PATH, keylayout);
- /* if the file does not exist, try again with 'en-us' as fallback */
+ /* check if there is a keymap file e.g. km-e00100411.ini */
+ g_snprintf(filename, 255, "%s/km-%08x.ini", XRDP_CFG_PATH, keylayout);
+
+ /* if the file does not exist, use only lower 16 bits instead */
+ if (!g_file_exist(filename))
+ {
+ log_message(LOG_LEVEL_INFO, "Cannot find keymap file %s", filename);
+ /* e.g. km-00000411.ini */
+ g_snprintf(filename, 255, "%s/km-%08x.ini", XRDP_CFG_PATH, basic_key_layout);
+ }
+
+ /* finally, use 'en-us' */
if (!g_file_exist(filename))
{
- g_snprintf(filename, 255, "%s/km-0409.ini", XRDP_CFG_PATH);
+ log_message(LOG_LEVEL_INFO, "Cannot find keymap file %s", filename);
+ g_snprintf(filename, 255, "%s/km-00000409.ini", XRDP_CFG_PATH);
}
if (g_file_exist(filename))
{
fd = g_file_open(filename);
+ log_message(LOG_LEVEL_INFO, "Loading keymap file %s", filename);
if (fd != -1)
{
@@ -263,7 +275,7 @@ get_keymaps(int keylayout, struct xrdp_keymap *keymap)
if (g_memcmp(lkeymap, keymap, sizeof(struct xrdp_keymap)) != 0)
{
log_message(LOG_LEVEL_WARNING,
- "local keymap file for 0x%4.4x found and dosen't match "
+ "local keymap file for 0x%08x found and doesn't match "
"built in keymap, using local keymap file", keylayout);
}
diff --git a/xrdp/rdp-scan-codes.txt b/xrdp/rdp-scan-codes.txt
index 938ce4c5..5fe06e53 100644
--- a/xrdp/rdp-scan-codes.txt
+++ b/xrdp/rdp-scan-codes.txt
@@ -3,7 +3,7 @@ complete rdp key code listing
en-us
-4000s in the down flags columm is from repeating keys(holding a key down)
+4000s in the down flags column is from repeating keys(holding a key down)
When holding a key down, the down flags repeat but the up flags only
come once at the end.
Rdesktop does not do this as of yet. It always sends down and up
diff --git a/xrdp/rsakeys.ini b/xrdp/rsakeys.ini
deleted file mode 100644
index ee79a3ec..00000000
--- a/xrdp/rsakeys.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[keys]
-pub_exp=0x01,0x00,0x01,0x00
-pub_mod=0x67,0xab,0x0e,0x6a,0x9f,0xd6,0x2b,0xa3,0x32,0x2f,0x41,0xd1,0xce,0xee,0x61,0xc3,0x76,0x0b,0x26,0x11,0x70,0x48,0x8a,0x8d,0x23,0x81,0x95,0xa0,0x39,0xf7,0x5b,0xaa,0x3e,0xf1,0xed,0xb8,0xc4,0xee,0xce,0x5f,0x6a,0xf5,0x43,0xce,0x5f,0x60,0xca,0x6c,0x06,0x75,0xae,0xc0,0xd6,0xa4,0x0c,0x92,0xa4,0xc6,0x75,0xea,0x64,0xb2,0x50,0x5b
-pub_sig=0x6a,0x41,0xb1,0x43,0xcf,0x47,0x6f,0xf1,0xe6,0xcc,0xa1,0x72,0x97,0xd9,0xe1,0x85,0x15,0xb3,0xc2,0x39,0xa0,0xa6,0x26,0x1a,0xb6,0x49,0x01,0xfa,0xa6,0xda,0x60,0xd7,0x45,0xf7,0x2c,0xee,0xe4,0x8e,0x64,0x2e,0x37,0x49,0xf0,0x4c,0x94,0x6f,0x08,0xf5,0x63,0x4c,0x56,0x29,0x55,0x5a,0x63,0x41,0x2c,0x20,0x65,0x95,0x99,0xb1,0x15,0x7c
-pri_exp=0x41,0x93,0x05,0xB1,0xF4,0x38,0xFC,0x47,0x88,0xC4,0x7F,0x83,0x8C,0xEC,0x90,0xDA,0x0C,0x8A,0xB5,0xAE,0x61,0x32,0x72,0xF5,0x2B,0xD1,0x7B,0x5F,0x44,0xC0,0x7C,0xBD,0x8A,0x35,0xFA,0xAE,0x30,0xF6,0xC4,0x6B,0x55,0xA7,0x65,0xEF,0xF4,0xB2,0xAB,0x18,0x4E,0xAA,0xE6,0xDC,0x71,0x17,0x3B,0x4C,0xC2,0x15,0x4C,0xF7,0x81,0xBB,0xF0,0x03
diff --git a/xrdp/sans-10.fv1 b/xrdp/sans-10.fv1
index 047870fa..047870fa 100755..100644
--- a/xrdp/sans-10.fv1
+++ b/xrdp/sans-10.fv1
Binary files differ
diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c
index a80687b1..b55a90cc 100644
--- a/xrdp/xrdp.c
+++ b/xrdp/xrdp.c
@@ -34,7 +34,7 @@ static long g_sync_mutex = 0;
static long g_sync1_mutex = 0;
static tbus g_term_event = 0;
static tbus g_sync_event = 0;
-/* syncronize stuff */
+/* synchronize stuff */
static int g_sync_command = 0;
static long g_sync_result = 0;
static long g_sync_param1 = 0;
@@ -107,7 +107,7 @@ xrdp_shutdown(int sig)
threadid = tc_get_threadid();
g_writeln("shutting down");
- g_writeln("signal %d threadid %p", sig, threadid);
+ g_writeln("signal %d threadid %lld", sig, (long long)threadid);
if (!g_is_wait_obj_set(g_term_event))
{
@@ -293,93 +293,91 @@ xrdp_process_params(int argc, char **argv,
}
/*****************************************************************************/
-int DEFAULT_CC
-main(int argc, char **argv)
+/* Basic sanity checks before any forking */
+int
+xrdp_sanity_check(void)
{
- int test;
+ int intval = 1;
int host_be;
- char cfg_file[256];
- enum logReturns error;
- struct xrdp_startup_params *startup_params;
- int pid;
- int fd;
- int no_daemon;
- char text[256];
- char pid_file[256];
-
- g_init("xrdp");
- ssl_init();
-
- for (test = 0; test < argc; test++)
- {
- DEBUG(("Argument %i - %s", test, argv[test]));
- }
+ char key_file[256];
/* check compiled endian with actual endian */
- test = 1;
- host_be = !((int)(*(unsigned char *)(&test)));
-#if defined(B_ENDIAN)
+ host_be = !((int)(*(unsigned char *)(&intval)));
+#if defined(B_ENDIAN)
if (!host_be)
+ {
+ g_writeln("Not a big endian machine, edit arch.h");
+ return 1;
+ }
#endif
#if defined(L_ENDIAN)
- if (host_be)
+ if (host_be)
+ {
+ g_writeln("Not a little endian machine, edit arch.h");
+ return 1;
+ }
#endif
- {
- g_writeln("endian wrong, edit arch.h");
- return 0;
- }
/* check long, int and void* sizes */
if (sizeof(int) != 4)
{
g_writeln("unusable int size, must be 4");
- return 0;
+ return 1;
}
if (sizeof(long) != sizeof(void *))
{
g_writeln("long size must match void* size");
- return 0;
+ return 1;
}
if (sizeof(long) != 4 && sizeof(long) != 8)
{
g_writeln("unusable long size, must be 4 or 8");
- return 0;
+ return 1;
}
if (sizeof(tui64) != 8)
{
g_writeln("unusable tui64 size, must be 8");
- return 0;
+ return 1;
}
- g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
+ g_snprintf(key_file, 255, "%s/rsakeys.ini", XRDP_CFG_PATH);
+ if (!g_file_exist(key_file))
+ {
+ g_writeln("File %s is missing, create it using xrdp-keygen", key_file);
+ return 1;
+ }
- /* starting logging subsystem */
- error = log_start(cfg_file, "XRDP");
+ return 0;
+}
- if (error != LOG_STARTUP_OK)
- {
- switch (error)
- {
- case LOG_ERROR_MALLOC:
- g_writeln("error on malloc. cannot start logging. quitting.");
- break;
- case LOG_ERROR_FILE_OPEN:
- g_writeln("error opening log file [%s]. quitting.",
- getLogFile(text, 255));
- break;
- default:
- g_writeln("log_start error");
- break;
- }
+/*****************************************************************************/
+int DEFAULT_CC
+main(int argc, char **argv)
+{
+ int test;
+ char cfg_file[256];
+ enum logReturns error;
+ struct xrdp_startup_params *startup_params;
+ int pid;
+ int fd;
+ int no_daemon;
+ char text[256];
+ char pid_file[256];
- g_deinit();
- g_exit(1);
+ g_init("xrdp");
+ ssl_init();
+
+ for (test = 0; test < argc; test++)
+ {
+ DEBUG(("Argument %i - %s", test, argv[test]));
}
+ g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
+
startup_params = (struct xrdp_startup_params *)
g_malloc(sizeof(struct xrdp_startup_params), 1);
@@ -387,7 +385,7 @@ main(int argc, char **argv)
{
g_writeln("Unknown Parameter");
g_writeln("xrdp -h for help");
- g_writeln("");
+ g_writeln("%s", "");
g_deinit();
g_exit(0);
}
@@ -395,6 +393,43 @@ main(int argc, char **argv)
g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH);
no_daemon = 0;
+ if (startup_params->help)
+ {
+ g_writeln("%s", "");
+ g_writeln("xrdp: A Remote Desktop Protocol server.");
+ g_writeln("Copyright (C) Jay Sorg 2004-2014");
+ g_writeln("See http://www.xrdp.org for more information.");
+ g_writeln("%s", "");
+ g_writeln("Usage: xrdp [options]");
+ g_writeln(" --help: show help");
+ g_writeln(" --nodaemon: don't fork into background");
+ g_writeln(" --kill: shut down xrdp");
+ g_writeln(" --port: tcp listen port");
+ g_writeln(" --fork: fork on new connection");
+ g_writeln("%s", "");
+ g_deinit();
+ g_exit(0);
+ }
+
+ if (startup_params->version)
+ {
+ g_writeln("%s", "");
+ g_writeln("xrdp: A Remote Desktop Protocol server.");
+ g_writeln("Copyright (C) Jay Sorg 2004-2014");
+ g_writeln("See http://www.xrdp.org for more information.");
+ g_writeln("Version %s", PACKAGE_VERSION);
+ g_writeln("%s", "");
+ g_deinit();
+ g_exit(0);
+ }
+
+ if (xrdp_sanity_check() != 0)
+ {
+ g_writeln("Fatal error occurred, exiting");
+ g_deinit();
+ g_exit(1);
+ }
+
if (startup_params->kill)
{
g_writeln("stopping xrdp");
@@ -408,8 +443,7 @@ main(int argc, char **argv)
if (fd == -1)
{
- g_writeln("problem opening to xrdp.pid [%s]", pid_file);
- g_writeln("maybe its not running");
+ g_writeln("cannot open %s, maybe xrdp is not running", pid_file);
}
else
{
@@ -430,49 +464,45 @@ main(int argc, char **argv)
g_exit(0);
}
- if (startup_params->no_daemon)
- {
- no_daemon = 1;
- }
+ /* starting logging subsystem */
+ error = log_start(cfg_file, "xrdp");
- if (startup_params->help)
+ if (error != LOG_STARTUP_OK)
{
- g_writeln("");
- g_writeln("xrdp: A Remote Desktop Protocol server.");
- g_writeln("Copyright (C) Jay Sorg 2004-2014");
- g_writeln("See http://www.xrdp.org for more information.");
- g_writeln("");
- g_writeln("Usage: xrdp [options]");
- g_writeln(" --help: show help");
- g_writeln(" --nodaemon: don't fork into background");
- g_writeln(" --kill: shut down xrdp");
- g_writeln(" --port: tcp listen port");
- g_writeln(" --fork: fork on new connection");
- g_writeln("");
+ switch (error)
+ {
+ case LOG_ERROR_MALLOC:
+ g_writeln("error on malloc. cannot start logging. quitting.");
+ break;
+ case LOG_ERROR_FILE_OPEN:
+ g_writeln("error opening log file [%s]. quitting.",
+ getLogFile(text, 255));
+ break;
+ default:
+ g_writeln("log_start error");
+ break;
+ }
+
g_deinit();
- g_exit(0);
+ g_exit(1);
}
- if (startup_params->version)
+
+
+ if (g_file_exist(pid_file)) /* xrdp.pid */
{
- g_writeln("");
- g_writeln("xrdp: A Remote Desktop Protocol server.");
- g_writeln("Copyright (C) Jay Sorg 2004-2014");
- g_writeln("See http://www.xrdp.org for more information.");
- g_writeln("Version %s", PACKAGE_VERSION);
- g_writeln("");
+ g_writeln("It looks like xrdp is already running.");
+ g_writeln("If not, delete %s and try again.", pid_file);
g_deinit();
g_exit(0);
}
- if (g_file_exist(pid_file)) /* xrdp.pid */
+ if (startup_params->no_daemon)
{
- g_writeln("It looks like xrdp is allready running,");
- g_writeln("if not delete the xrdp.pid file and try again");
- g_deinit();
- g_exit(0);
+ no_daemon = 1;
}
+
if (!no_daemon)
{
@@ -561,13 +591,13 @@ main(int argc, char **argv)
g_threadid = tc_get_threadid();
g_listen = xrdp_listen_create();
g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */
- g_signal_kill(xrdp_shutdown); /* SIGKILL */
g_signal_pipe(pipe_sig); /* SIGPIPE */
g_signal_terminate(xrdp_shutdown); /* SIGTERM */
g_signal_child_stop(xrdp_child); /* SIGCHLD */
g_sync_mutex = tc_mutex_create();
g_sync1_mutex = tc_mutex_create();
pid = g_getpid();
+ log_message(LOG_LEVEL_INFO, "starting xrdp with pid %d", pid);
g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid);
g_term_event = g_create_wait_obj(text);
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index 67488a60..edf88cc4 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -37,6 +37,7 @@
#include "file.h"
#include "file_loc.h"
#include "xrdp_client_info.h"
+#include "log.h"
/* xrdp.c */
long APP_CC
@@ -136,11 +137,12 @@ xrdp_wm_pointer(struct xrdp_wm* self, char* data, char* mask, int x, int y,
int
callback(long id, int msg, long param1, long param2, long param3, long param4);
int APP_CC
-xrdp_wm_delete_all_childs(struct xrdp_wm* self);
+xrdp_wm_delete_all_children(struct xrdp_wm* self);
int APP_CC
xrdp_wm_show_log(struct xrdp_wm *self);
int APP_CC
-xrdp_wm_log_msg(struct xrdp_wm* self, char* msg);
+xrdp_wm_log_msg(struct xrdp_wm *self, enum logLevels loglevel,
+ const char *fmt, ...) printflike(3, 4);
int APP_CC
xrdp_wm_get_wait_objs(struct xrdp_wm* self, tbus* robjs, int* rc,
tbus* wobjs, int* wc, int* timeout);
@@ -173,11 +175,9 @@ xrdp_region_delete(struct xrdp_region* self);
int APP_CC
xrdp_region_add_rect(struct xrdp_region* self, struct xrdp_rect* rect);
int APP_CC
-xrdp_region_insert_rect(struct xrdp_region* self, int i, int left,
- int top, int right, int bottom);
+xrdp_region_subtract_rect(struct xrdp_region* self, struct xrdp_rect* rect);
int APP_CC
-xrdp_region_subtract_rect(struct xrdp_region* self,
- struct xrdp_rect* rect);
+xrdp_region_intersect_rect(struct xrdp_region* self, struct xrdp_rect* rect);
int APP_CC
xrdp_region_get_rect(struct xrdp_region* self, int index,
struct xrdp_rect* rect);
@@ -264,9 +264,9 @@ xrdp_painter_draw_bitmap(struct xrdp_painter* self,
struct xrdp_bitmap* to_draw,
int x, int y, int cx, int cy);
int APP_CC
-xrdp_painter_text_width(struct xrdp_painter* self, char* text);
+xrdp_painter_text_width(struct xrdp_painter* self, const char *text);
int APP_CC
-xrdp_painter_text_height(struct xrdp_painter* self, char* text);
+xrdp_painter_text_height(struct xrdp_painter* self, const char *text);
int APP_CC
xrdp_painter_draw_text(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap,
@@ -378,7 +378,11 @@ xrdp_mm_get_wait_objs(struct xrdp_mm* self,
tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int APP_CC
+xrdp_mm_check_chan(struct xrdp_mm *self);
+int APP_CC
xrdp_mm_check_wait_objs(struct xrdp_mm* self);
+int APP_CC
+xrdp_mm_frame_ack(struct xrdp_mm *self, int frame_id);
int DEFAULT_CC
server_begin_update(struct xrdp_mod* mod);
int DEFAULT_CC
@@ -435,14 +439,14 @@ server_set_opcode(struct xrdp_mod* mod, int opcode);
int DEFAULT_CC
server_set_mixmode(struct xrdp_mod* mod, int mixmode);
int DEFAULT_CC
-server_set_brush(struct xrdp_mod* mod, int x_orgin, int y_orgin,
+server_set_brush(struct xrdp_mod* mod, int x_origin, int y_origin,
int style, char* pattern);
int DEFAULT_CC
server_set_pen(struct xrdp_mod* mod, int style, int width);
int DEFAULT_CC
server_draw_line(struct xrdp_mod* mod, int x1, int y1, int x2, int y2);
int DEFAULT_CC
-server_add_char(struct xrdp_mod* mod, int font, int charactor,
+server_add_char(struct xrdp_mod* mod, int font, int character,
int offset, int baseline,
int width, int height, char* data);
int DEFAULT_CC
@@ -460,7 +464,7 @@ int DEFAULT_CC
server_query_channel(struct xrdp_mod* mod, int index, char* channel_name,
int* channel_flags);
int DEFAULT_CC
-server_get_channel_id(struct xrdp_mod* mod, char* name);
+server_get_channel_id(struct xrdp_mod* mod, const char *name);
int DEFAULT_CC
server_send_to_channel(struct xrdp_mod* mod, int channel_id,
char* data, int data_len,
@@ -507,6 +511,6 @@ server_monitored_desktop(struct xrdp_mod* mod,
struct rail_monitored_desktop_order* mdo,
int flags);
int DEFAULT_CC
-server_add_char_alpha(struct xrdp_mod* mod, int font, int charactor,
+server_add_char_alpha(struct xrdp_mod* mod, int font, int character,
int offset, int baseline,
int width, int height, char* data);
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index 34adb077..242641ff 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -1,39 +1,59 @@
-[globals]
-# xrdp.ini file version number
+[Globals]
+; xrdp.ini file version number
ini_version=1
-bitmap_cache=yes
-bitmap_compression=yes
+; fork a new process for each incoming connection
+fork=true
+; tcp port to listen
port=3389
-allow_channels=true
-max_bpp=32
-fork=yes
-# minimum security level allowed for client
-# can be 'none', 'low', 'medium', 'high', 'fips'
+; regulate if the listening socket use socket option tcp_nodelay
+; no buffering will be performed in the TCP stack
+tcp_nodelay=true
+; regulate if the listening socket use socket option keepalive
+; if the network connection disappear without close messages the connection will be closed
+tcp_keepalive=true
+#tcp_send_buffer_bytes=32768
+#tcp_recv_buffer_bytes=32768
+
+; security layer can be 'tls', 'rdp' or 'negotiate'
+; for client compatible layer
+security_layer=negotiate
+; minimum security level allowed for client
+; can be 'none', 'low', 'medium', 'high', 'fips'
crypt_level=high
-# security layer can be 'tls', 'rdp' or 'negotiate'
-# for client compatible layer
-security_layer=rdp
-# X.509 certificate and private key
-# openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365
+; X.509 certificate and private key
+; openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365
certificate=
key_file=
+; specify whether SSLv3 should be disabled
+#disableSSLv3=true
+; set TLS cipher suites
+#tls_ciphers=HIGH
-# regulate if the listening socket use socket option tcp_nodelay
-# no buffering will be performed in the TCP stack
-tcp_nodelay=yes
+; Section name to use for automatic login if the client sends username
+; and password. If empty, the domain name sent by the client is used.
+; If empty and no domain name is given, the first suitable section in
+; this file will be used.
+autorun=
-# regulate if the listening socket use socket option keepalive
-# if the network connection disappear without close messages the connection will be closed
-tcp_keepalive=yes
-
-#tcp_send_buffer_bytes=32768
-#tcp_recv_buffer_bytes=32768
-
-#
-# colors used by windows in RGB format
-#
+allow_channels=true
+allow_multimon=true
+bitmap_cache=true
+bitmap_compression=true
+bulk_compression=true
+#hidelogwindow=true
+max_bpp=32
+new_cursors=true
+; fastpath - can be 'input', 'output', 'both', 'none'
+use_fastpath=both
+; when true, userid/password *must* be passed on cmd line
+#require_credentials=true
+; You can set the PAM error text in a gateway setup (MAX 256 chars)
+#pamerrortxt=change your password according to policy at http://url
+;
+; colors used by windows in RGB format
+;
blue=009cb5
grey=dedede
#black=000000
@@ -44,68 +64,51 @@ grey=dedede
#red=ff0000
#green=00ff00
#background=626c72
-#autorun=xrdp1
-#hidelogwindow=yes
-
-# when true, userid/password *must* be passed on cmd line
-# require_credentials=yes
-
-# set a default entry for autorun if the client send login and pass directly
-autorun=xrdp1
-
-bulk_compression=yes
-
-# You can set the PAM error text in a gateway setup (MAX 256 chars)
-#pamerrortxt=change your password according to policy at http://url
-new_cursors=yes
-allow_multimon=true
-# fastpath - can be set to input / output / both / none
-use_fastpath=both
-#
-# configure login screen
-#
+;
+; configure login screen
+;
-# Login Screen Window Title
+; Login Screen Window Title
#ls_title=My Login Title
-# top level window background color in RGB format
+; top level window background color in RGB format
ls_top_window_bg_color=009cb5
-# width and height of login screen
+; width and height of login screen
ls_width=350
ls_height=430
-# login screen background color in RGB format
+; login screen background color in RGB format
ls_bg_color=dedede
-# optional background image filename (bmp format).
+; optional background image filename (bmp format).
#ls_background_image=
-# logo
-# full path to bmp-file or file in shared folder
+; logo
+; full path to bmp-file or file in shared folder
ls_logo_filename=
ls_logo_x_pos=55
ls_logo_y_pos=50
-# for positioning labels such as username, password etc
+; for positioning labels such as username, password etc
ls_label_x_pos=30
ls_label_width=60
-# for positioning text and combo boxes next to above labels
+; for positioning text and combo boxes next to above labels
ls_input_x_pos=110
ls_input_width=210
-# y pos for first label and combo box
+; y pos for first label and combo box
ls_input_y_pos=220
-# OK button
+; OK button
ls_btn_ok_x_pos=142
ls_btn_ok_y_pos=370
ls_btn_ok_width=85
ls_btn_ok_height=30
-# Cancel button
+; Cancel button
ls_btn_cancel_x_pos=237
ls_btn_cancel_y_pos=370
ls_btn_cancel_width=85
@@ -114,17 +117,17 @@ ls_btn_cancel_height=30
[Logging]
LogFile=xrdp.log
LogLevel=DEBUG
-EnableSyslog=1
+EnableSyslog=true
SyslogLevel=DEBUG
-# LogLevel and SysLogLevel could by any of: core, error, warning, info or debug
-
-[channels]
-# Channel names not listed here will be blocked by XRDP.
-# You can block any channel by setting its value to false.
-# IMPORTANT! All channels are not supported in all use
-# cases even if you set all values to true.
-# You can override these settings on each session type
-# These settings are only used if allow_channels=true
+; LogLevel and SysLogLevel could by any of: core, error, warning, info or debug
+
+[Channels]
+; Channel names not listed here will be blocked by XRDP.
+; You can block any channel by setting its value to false.
+; IMPORTANT! All channels are not supported in all use
+; cases even if you set all values to true.
+; You can override these settings on each session type
+; These settings are only used if allow_channels=true
rdpdr=true
rdpsnd=true
drdynvc=true
@@ -133,14 +136,19 @@ rail=true
xrdpvr=true
tcutils=true
-# for debugging xrdp, in section xrdp1, change port=-1 to this:
-# port=/tmp/.xrdp/xrdp_display_10
+; for debugging xrdp, in section xrdp1, change port=-1 to this:
+#port=/tmp/.xrdp/xrdp_display_10
+
+; for debugging xrdp, add following line to section xrdp1
+#chansrvport=/tmp/.xrdp/xrdp_chansrv_socket_7210
-# for debugging xrdp, add following line to section xrdp1
-# chansrvport=/tmp/.xrdp/xrdp_chansrv_socket_7210
-[xrdp1]
-name=sesman-X11rdp
+;
+; Session types
+;
+
+[X11rdp]
+name=X11rdp
lib=libxup.so
username=ask
password=ask
@@ -149,16 +157,26 @@ port=-1
xserverbpp=24
code=10
-[xrdp2]
-name=sesman-Xvnc
+[Xorg]
+name=Xorg
+lib=libxup.so
+username=ask
+password=ask
+ip=127.0.0.1
+port=-1
+code=20
+
+[Xvnc]
+name=Xvnc
lib=libvnc.so
username=ask
password=ask
ip=127.0.0.1
port=-1
+#xserverbpp=24
#delay_ms=2000
-[xrdp3]
+[console]
name=console
lib=libvnc.so
ip=127.0.0.1
@@ -167,7 +185,7 @@ username=na
password=ask
#delay_ms=2000
-[xrdp4]
+[vnc-any]
name=vnc-any
lib=libvnc.so
ip=ask
@@ -179,7 +197,7 @@ password=ask
#pamsessionmng=127.0.0.1
#delay_ms=2000
-[xrdp5]
+[sesman-any]
name=sesman-any
lib=libvnc.so
ip=ask
@@ -188,13 +206,13 @@ username=ask
password=ask
#delay_ms=2000
-[xrdp6]
+[rdp-any]
name=rdp-any
lib=librdp.so
ip=ask
port=ask3389
-[xrdp7]
+[neutrinordp-any]
name=neutrinordp-any
lib=libxrdpneutrinordp.so
ip=ask
@@ -202,17 +220,7 @@ port=ask3389
username=ask
password=ask
-[Session manager]
-name=Session manager
-lib=libxup.so
-username=ask
-password=ask
-ip=127.0.0.1
-port=-1
-xserverbpp=24
-code=20
-
-# You can override the common channel settings for each session type
+; You can override the common channel settings for each session type
#channel.rdpdr=true
#channel.rdpsnd=true
#channel.drdynvc=true
diff --git a/xrdp/xrdp256.bmp b/xrdp/xrdp256.bmp
index 6191514e..6191514e 100755..100644
--- a/xrdp/xrdp256.bmp
+++ b/xrdp/xrdp256.bmp
Binary files differ
diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c
index aafc19f2..deb56a2c 100644
--- a/xrdp/xrdp_bitmap.c
+++ b/xrdp/xrdp_bitmap.c
@@ -38,7 +38,7 @@
while (0)
-static const int g_crc_table[256] =
+static const unsigned int g_crc_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@@ -123,6 +123,14 @@ xrdp_bitmap_create(int width, int height, int bpp,
self->data = (char *)g_malloc(width * height * Bpp, 0);
}
+#if defined(XRDP_PAINTER)
+ if (self->type == WND_TYPE_SCREEN) /* noorders */
+ {
+ LLOGLN(0, ("xrdp_bitmap_create: noorders"));
+ self->data = (char *) g_malloc(width * height * Bpp, 0);
+ }
+#endif
+
if (self->type != WND_TYPE_BITMAP)
{
self->child_list = list_create();
@@ -149,9 +157,9 @@ xrdp_bitmap_create_with_data(int width, int height,
struct xrdp_wm *wm)
{
struct xrdp_bitmap *self = (struct xrdp_bitmap *)NULL;
+ int Bpp;
#if defined(NEED_ALIGN)
tintptr data_as_int;
- int Bpp;
#endif
self = (struct xrdp_bitmap *)g_malloc(sizeof(struct xrdp_bitmap), 1);
@@ -160,26 +168,29 @@ xrdp_bitmap_create_with_data(int width, int height,
self->height = height;
self->bpp = bpp;
self->wm = wm;
+
+ Bpp = 4;
+ switch (bpp)
+ {
+ case 8:
+ Bpp = 1;
+ break;
+ case 15:
+ Bpp = 2;
+ break;
+ case 16:
+ Bpp = 2;
+ break;
+ }
+ self->line_size = width * Bpp;
+
#if defined(NEED_ALIGN)
data_as_int = (tintptr) data;
if (((bpp >= 24) && (data_as_int & 3)) ||
(((bpp == 15) || (bpp == 16)) && (data_as_int & 1)))
{
- /* got to copy data here, it's not alligned
+ /* got to copy data here, it's not aligned
other calls in this file assume alignment */
- Bpp = 4;
- switch (bpp)
- {
- case 8:
- Bpp = 1;
- break;
- case 15:
- Bpp = 2;
- break;
- case 16:
- Bpp = 2;
- break;
- }
self->data = (char *)g_malloc(width * height * Bpp, 0);
g_memcpy(self->data, data, width * height * Bpp);
return self;
@@ -471,7 +482,7 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
/* read bmp header */
if (g_file_seek(fd, 14) < 0)
{
- log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s",
filename);
free_stream(s);
g_file_close(fd);
@@ -505,7 +516,7 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
{
if (g_file_seek(fd, 14 + header.size) < 0)
{
- log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s",
filename);
}
xrdp_bitmap_resize(self, header.image_width, header.image_height);
@@ -562,7 +573,7 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
/* read palette */
if (g_file_seek(fd, 14 + header.size) < 0)
{
- log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s",
filename);
}
init_stream(s, 8192);
@@ -623,7 +634,7 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
/* read palette */
if (g_file_seek(fd, 14 + header.size) < 0)
{
- log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s",
filename);
}
init_stream(s, 8192);
@@ -1254,8 +1265,8 @@ xrdp_bitmap_draw_focus_box(struct xrdp_bitmap *self,
painter->brush.pattern[5] = 0x55;
painter->brush.pattern[6] = 0xaa;
painter->brush.pattern[7] = 0x55;
- painter->brush.x_orgin = x;
- painter->brush.x_orgin = x;
+ painter->brush.x_origin = x;
+ painter->brush.x_origin = x;
painter->brush.style = 3;
painter->fg_color = self->wm->black;
painter->bg_color = self->parent->bg_color;
diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c
index 834271db..d4133325 100644
--- a/xrdp/xrdp_cache.c
+++ b/xrdp/xrdp_cache.c
@@ -79,7 +79,7 @@ xrdp_cache_reset_crc(struct xrdp_cache *self)
{
for (jndex = 0; jndex < 64 * 1024; jndex++)
{
- /* it's ok to deinit a zero'ed out struct list16 */
+ /* it's ok to deinit a zeroed out struct list16 */
list16_deinit(&(self->crc16[index][jndex]));
list16_init(&(self->crc16[index][jndex]));
}
@@ -684,7 +684,7 @@ xrdp_cache_add_pointer(struct xrdp_cache *self,
}
/*****************************************************************************/
-/* this does not take owership of pointer_item, it makes a copy */
+/* this does not take ownership of pointer_item, it makes a copy */
int APP_CC
xrdp_cache_add_pointer_static(struct xrdp_cache *self,
struct xrdp_pointer_item *pointer_item,
@@ -716,7 +716,7 @@ xrdp_cache_add_pointer_static(struct xrdp_cache *self,
}
/*****************************************************************************/
-/* this does not take owership of brush_item_data, it makes a copy */
+/* this does not take ownership of brush_item_data, it makes a copy */
int APP_CC
xrdp_cache_add_brush(struct xrdp_cache *self,
char *brush_item_data)
diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c
index 78d1b52e..0af0b85e 100644
--- a/xrdp/xrdp_encoder.c
+++ b/xrdp/xrdp_encoder.c
@@ -39,33 +39,82 @@
} \
while (0)
-#define JPG_CODEC 0
-#define RFX_CODEC 1
-
/*****************************************************************************/
static int
-process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
+process_enc_jpg(struct xrdp_encoder *self, XRDP_ENC_DATA *enc);
+#ifdef XRDP_RFXCODEC
static int
-process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
+process_enc_rfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc);
+#endif
+static int
+process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc);
-/**
- * Init encoder
- *
- * @return 0 on success, -1 on failure
- *****************************************************************************/
-/* called from main thread */
-int APP_CC
-init_xrdp_encoder(struct xrdp_mm *self)
+/*****************************************************************************/
+struct xrdp_encoder *APP_CC
+xrdp_encoder_create(struct xrdp_mm *mm)
{
+ struct xrdp_encoder *self;
+ struct xrdp_client_info *client_info;
char buf[1024];
int pid;
- if (self == 0)
+ client_info = mm->wm->client_info;
+
+ if (client_info->mcs_connection_type != 6) /* LAN */
{
- return -1;
+ return 0;
+ }
+ if (client_info->bpp < 24)
+ {
+ return 0;
}
- LLOGLN(0, ("init_xrdp_encoder: initing encoder codec_id %d", self->codec_id));
+ self = (struct xrdp_encoder *)g_malloc(sizeof(struct xrdp_encoder), 1);
+ self->mm = mm;
+
+ if (client_info->jpeg_codec_id != 0)
+ {
+ LLOGLN(0, ("xrdp_encoder_create: starting jpeg codec session"));
+ self->codec_id = client_info->jpeg_codec_id;
+ self->in_codec_mode = 1;
+ self->codec_quality = client_info->jpeg_prop[0];
+ client_info->capture_code = 0;
+ client_info->capture_format =
+ /* XRDP_a8b8g8r8 */
+ (32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8;
+ self->process_enc = process_enc_jpg;
+ }
+#ifdef XRDP_RFXCODEC
+ else if (client_info->rfx_codec_id != 0)
+ {
+ LLOGLN(0, ("xrdp_encoder_create: starting rfx codec session"));
+ self->codec_id = client_info->rfx_codec_id;
+ self->in_codec_mode = 1;
+ client_info->capture_code = 2;
+ self->process_enc = process_enc_rfx;
+ self->codec_handle = rfxcodec_encode_create(mm->wm->screen->width,
+ mm->wm->screen->height,
+ RFX_FORMAT_YUV, 0);
+ }
+#endif
+ else if (client_info->h264_codec_id != 0)
+ {
+ LLOGLN(0, ("xrdp_encoder_create: starting h264 codec session"));
+ self->codec_id = client_info->h264_codec_id;
+ self->in_codec_mode = 1;
+ client_info->capture_code = 3;
+ client_info->capture_format =
+ /* XRDP_nv12 */
+ (12 << 24) | (64 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0;
+ self->process_enc = process_enc_h264;
+ }
+ else
+ {
+ g_free(self);
+ return 0;
+ }
+
+ LLOGLN(0, ("init_xrdp_encoder: initializing encoder codec_id %d", self->codec_id));
/* setup required FIFOs */
self->fifo_to_proc = fifo_create();
@@ -81,52 +130,25 @@ init_xrdp_encoder(struct xrdp_mm *self)
g_snprintf(buf, 1024, "xrdp_%8.8x_encoder_term", pid);
self->xrdp_encoder_term = g_create_wait_obj(buf);
- switch (self->codec_id)
- {
- case 2:
- self->process_enc = process_enc_jpg;
- break;
- case 3:
- self->process_enc = process_enc_rfx;
-#ifdef XRDP_RFXCODEC
- self->codec_handle =
- rfxcodec_encode_create(self->wm->screen->width,
- self->wm->screen->height,
- RFX_FORMAT_YUV, 0);
- //RFX_FORMAT_BGRA, 0);
-#endif
- break;
- default:
- LLOGLN(0, ("init_xrdp_encoder: unknown codec_id %d",
- self->codec_id));
- break;
-
- }
-
/* create thread to process messages */
tc_thread_create(proc_enc_msg, self);
- return 0;
+ return self;
}
-/**
- * Deinit xrdp encoder
- *****************************************************************************/
-/* called from main thread */
+/*****************************************************************************/
void APP_CC
-deinit_xrdp_encoder(struct xrdp_mm *self)
+xrdp_encoder_delete(struct xrdp_encoder *self)
{
XRDP_ENC_DATA *enc;
XRDP_ENC_DATA_DONE *enc_done;
- FIFO *fifo;
-
- LLOGLN(0, ("deinit_xrdp_encoder: deiniting encoder"));
+ FIFO *fifo;
+ LLOGLN(0, ("xrdp_encoder_delete:"));
if (self == 0)
{
return;
}
-
if (self->in_codec_mode == 0)
{
return;
@@ -135,12 +157,7 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
g_set_wait_obj(self->xrdp_encoder_term);
g_sleep(1000);
- if (self->codec_id == 3)
- {
-#ifdef XRDP_RFXCODEC
- rfxcodec_encode_destroy(self->codec_handle);
-#endif
- }
+ /* todo delete specific encoder */
/* destroy wait objects used for signalling */
g_delete_wait_obj(self->xrdp_encoder_event_to_proc);
@@ -153,7 +170,7 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
{
while (!fifo_is_empty(fifo))
{
- enc = fifo_remove_item(fifo);
+ enc = (XRDP_ENC_DATA *) fifo_remove_item(fifo);
if (enc == 0)
{
continue;
@@ -162,7 +179,6 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
g_free(enc->crects);
g_free(enc);
}
-
fifo_delete(fifo);
}
@@ -172,8 +188,8 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
{
while (!fifo_is_empty(fifo))
{
- enc_done = fifo_remove_item(fifo);
- if (enc == 0)
+ enc_done = (XRDP_ENC_DATA_DONE *) fifo_remove_item(fifo);
+ if (enc_done == 0)
{
continue;
}
@@ -182,27 +198,28 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
}
fifo_delete(fifo);
}
+ g_free(self);
}
/*****************************************************************************/
/* called from encoder thread */
static int
-process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
+process_enc_jpg(struct xrdp_encoder *self, XRDP_ENC_DATA *enc)
{
- int index;
- int x;
- int y;
- int cx;
- int cy;
- int quality;
- int error;
- int out_data_bytes;
- int count;
- char *out_data;
- XRDP_ENC_DATA_DONE *enc_done;
- FIFO *fifo_processed;
- tbus mutex;
- tbus event_processed;
+ int index;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int quality;
+ int error;
+ int out_data_bytes;
+ int count;
+ char *out_data;
+ XRDP_ENC_DATA_DONE *enc_done;
+ FIFO *fifo_processed;
+ tbus mutex;
+ tbus event_processed;
LLOGLN(10, ("process_enc_jpg:"));
quality = self->codec_quality;
@@ -236,9 +253,10 @@ process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
LLOGLN(0, ("process_enc_jpg: error 3"));
return 1;
}
+
out_data[256] = 0; /* header bytes */
out_data[257] = 0;
- error = libxrdp_codec_jpeg_compress(self->wm->session, 0, enc->data,
+ error = libxrdp_codec_jpeg_compress(self->mm->wm->session, 0, enc->data,
enc->width, enc->height,
enc->width * 4, x, y, cx, cy,
quality,
@@ -274,11 +292,10 @@ process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
}
#ifdef XRDP_RFXCODEC
-
/*****************************************************************************/
/* called from encoder thread */
static int
-process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
+process_enc_rfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc)
{
int index;
int x;
@@ -364,8 +381,8 @@ process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
enc_done->comp_pad_data = out_data;
enc_done->enc = enc;
enc_done->last = 1;
- enc_done->cx = self->wm->screen->width;
- enc_done->cy = self->wm->screen->height;
+ enc_done->cx = self->mm->wm->screen->width;
+ enc_done->cy = self->mm->wm->screen->height;
/* done with msg */
/* inform main thread done */
@@ -377,42 +394,40 @@ process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
return 0;
}
-
-#else
+#endif
/*****************************************************************************/
/* called from encoder thread */
static int
-process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
+process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc)
{
+ LLOGLN(0, ("process_enc_x264:"));
return 0;
}
-#endif
-
/**
* Encoder thread main loop
*****************************************************************************/
THREAD_RV THREAD_CC
proc_enc_msg(void *arg)
{
- XRDP_ENC_DATA *enc;
- FIFO *fifo_to_proc;
- tbus mutex;
- tbus event_to_proc;
- tbus term_obj;
- tbus lterm_obj;
- int robjs_count;
- int wobjs_count;
- int cont;
- int timeout;
- tbus robjs[32];
- tbus wobjs[32];
- struct xrdp_mm *self;
+ XRDP_ENC_DATA *enc;
+ FIFO *fifo_to_proc;
+ tbus mutex;
+ tbus event_to_proc;
+ tbus term_obj;
+ tbus lterm_obj;
+ int robjs_count;
+ int wobjs_count;
+ int cont;
+ int timeout;
+ tbus robjs[32];
+ tbus wobjs[32];
+ struct xrdp_encoder *self;
LLOGLN(0, ("proc_enc_msg: thread is running"));
- self = (struct xrdp_mm *) arg;
+ self = (struct xrdp_encoder *) arg;
if (self == 0)
{
LLOGLN(0, ("proc_enc_msg: self nil"));
diff --git a/xrdp/xrdp_encoder.h b/xrdp/xrdp_encoder.h
index 1d525f12..f138d749 100644
--- a/xrdp/xrdp_encoder.h
+++ b/xrdp/xrdp_encoder.h
@@ -3,13 +3,67 @@
#define _XRDP_ENCODER_H
#include "arch.h"
+#include "fifo.h"
-struct xrdp_mm;
+struct xrdp_enc_data;
-int APP_CC
-init_xrdp_encoder(struct xrdp_mm *self);
+/* for codec mode operations */
+struct xrdp_encoder
+{
+ struct xrdp_mm *mm;
+ int in_codec_mode;
+ int codec_id;
+ int codec_quality;
+ tbus xrdp_encoder_event_to_proc;
+ tbus xrdp_encoder_event_processed;
+ tbus xrdp_encoder_term;
+ FIFO *fifo_to_proc;
+ FIFO *fifo_processed;
+ tbus mutex;
+ int (*process_enc)(struct xrdp_encoder *self, struct xrdp_enc_data *enc);
+ void *codec_handle;
+ int frame_id_client; /* last frame id received from client */
+ int frame_id_server; /* last frame id received from Xorg */
+ int frame_id_server_sent;
+};
+
+/* used when scheduling tasks in xrdp_encoder.c */
+struct xrdp_enc_data
+{
+ struct xrdp_mod *mod;
+ int num_drects;
+ short *drects; /* 4 * num_drects */
+ int num_crects;
+ short *crects; /* 4 * num_crects */
+ char *data;
+ int width;
+ int height;
+ int flags;
+ int frame_id;
+};
+
+typedef struct xrdp_enc_data XRDP_ENC_DATA;
+
+/* used when scheduling tasks from xrdp_encoder.c */
+struct xrdp_enc_data_done
+{
+ int comp_bytes;
+ int pad_bytes;
+ char *comp_pad_data;
+ struct xrdp_enc_data *enc;
+ int last; /* true is this is last message for enc */
+ int x;
+ int y;
+ int cx;
+ int cy;
+};
+
+typedef struct xrdp_enc_data_done XRDP_ENC_DATA_DONE;
+
+struct xrdp_encoder *APP_CC
+xrdp_encoder_create(struct xrdp_mm *mm);
void APP_CC
-deinit_xrdp_encoder(struct xrdp_mm *self);
+xrdp_encoder_delete(struct xrdp_encoder *self);
THREAD_RV THREAD_CC
proc_enc_msg(void *arg);
diff --git a/xrdp/xrdp_keyboard.ini b/xrdp/xrdp_keyboard.ini
index f3a5298a..3ce7644a 100644
--- a/xrdp/xrdp_keyboard.ini
+++ b/xrdp/xrdp_keyboard.ini
@@ -1,59 +1,59 @@
-#
-# RDP Keyboard <-> X11 Keyboard layout map
-#
-# How this file works:
-# 1. load the file and scan each section to find matching "keyboard_type"
-# and "keyboard_subtype" based on the values received from the client.
-# If not found, then jump to default section.
-# 2. in the selected section, look for "rdp_layouts" and "layouts_map".
-# Based on the "keylayout" value from the client, find the right x11
-# layout value.
-# 3. model/variant are inferred based on the "keyboard_type" and
-# "keyboard_subtype", but they can be overridden.
-#
+;
+; RDP Keyboard <-> X11 Keyboard layout map
+;
+; How this file works:
+; 1. load the file and scan each section to find matching "keyboard_type"
+; and "keyboard_subtype" based on the values received from the client.
+; If not found, then jump to default section.
+; 2. in the selected section, look for "rdp_layouts" and "layouts_map".
+; Based on the "keylayout" value from the client, find the right x11
+; layout value.
+; 3. model/variant are inferred based on the "keyboard_type" and
+; "keyboard_subtype", but they can be overridden.
+;
-#
-# RDP Keyboard Type (http://msdn.microsoft.com/en-us/library/cc240563.aspx)
-#
-# 0 is not a valid value
-#
-# 1 - IBM PC/XT or compatible (83-key) keyboard
-# 2 - Olivetti "ICO" (102-key) keyboard
-# 3 - IBM PC/AT (84-key) or similar keyboard
-# 4 - IBM enhanced (101- or 102-key) keyboard
-# 5 - Nokia 1050 and similar keyboards
-# 6 - Nokia 9140 and similar keyboards
-# 7 - Japanese keyboard
-#
-# RDP Keyboard Subtype is vendor dependent. XRDP defines as follows:
-#
-# 0 is not a valid value
-#
-# 1 - Standard
-# 2 - FreeRDP JP keyboard
-# 3 - Macintosh
-# ... - < any vendor dependent subtype >
-#
-# The list can be augmented.
-#
+;
+; RDP Keyboard Type (http://msdn.microsoft.com/en-us/library/cc240563.aspx)
+;
+; 0 is not a valid value
+;
+; 1 - IBM PC/XT or compatible (83-key) keyboard
+; 2 - Olivetti "ICO" (102-key) keyboard
+; 3 - IBM PC/AT (84-key) or similar keyboard
+; 4 - IBM enhanced (101- or 102-key) keyboard
+; 5 - Nokia 1050 and similar keyboards
+; 6 - Nokia 9140 and similar keyboards
+; 7 - Japanese keyboard
+;
+; RDP Keyboard Subtype is vendor dependent. XRDP defines as follows:
+;
+; 0 is not a valid value
+;
+; 1 - Standard
+; 2 - FreeRDP JP keyboard
+; 3 - Macintosh
+; ... - < any vendor dependent subtype >
+;
+; The list can be augmented.
+;
-# default
+; default
[default]
-# keyboard_type and keyboard_subtype is not readed for default section. It
-# is only as a place holder to keep consistency. Default model/variant are
-# platform dependent, and could be overridden if needed.
+; keyboard_type and keyboard_subtype is not read for default section. It
+; is only a placeholder to keep consistency. Default model/variant are
+; platform dependent, and could be overridden if needed.
keyboard_type=0
keyboard_subtype=0
-# user could override variant and model, but generally they should be inferred
-# automatically based on keyboard type and subtype
-#variant=
-#model=
+; user could override variant and model, but generally they should be inferred
+; automatically based on keyboard type and subtype
+;variant=
+;model=
-# A list of supported RDP keyboard layouts
+; A list of supported RDP keyboard layouts
rdp_layouts=default_rdp_layouts
-# The map from RDP keyboard layout to X11 keyboard layout
+; The map from RDP keyboard layout to X11 keyboard layout
layouts_map=default_layouts_map
[default_rdp_layouts]
@@ -62,33 +62,31 @@ rdp_layout_de=0x00000407
rdp_layout_fr=0x0000040C
rdp_layout_it=0x00000410
rdp_layout_jp=0x00000411
-rdp_layout_jp2=0xe0010411
-rdp_layout_jp3=0xe0200411
-rdp_layout_jp4=0xe0210411
+rdp_layout_kr=0x00000412
rdp_layout_ru=0x00000419
rdp_layout_se=0x0000041D
+rdp_layout_ch=0x00000807
rdp_layout_pt=0x00000816
rdp_layout_br=0x00000416
rdp_layout_pl=0x00000415
-# <rdp layout name> = <X11 keyboard layout value>
+; <rdp layout name> = <X11 keyboard layout value>
[default_layouts_map]
rdp_layout_us=us
rdp_layout_de=de
rdp_layout_fr=fr
rdp_layout_it=it
rdp_layout_jp=jp
-rdp_layout_jp2=jp
-rdp_layout_jp3=jp
-rdp_layout_jp4=jp
+rdp_layout_kr=kr
rdp_layout_ru=ru
rdp_layout_se=se
+rdp_layout_ch=ch
rdp_layout_pt=pt
rdp_layout_br=br(abnt2)
rdp_layout_pl=pl
-# if two sections have the same keyboard_type and keyboard_subtype, then
-# the latter could override the former.
+; if two sections have the same keyboard_type and keyboard_subtype, then
+; the latter could override the former.
[rdp_keyboard_mac]
keyboard_type=4
keyboard_subtype=3
@@ -98,7 +96,7 @@ layouts_map=rdp_layouts_map_mac
[rdp_keyboard_jp]
keyboard_type=7
keyboard_subtype=2
-model=jp106
+model=pc105
rdp_layouts=default_rdp_layouts
layouts_map=default_layouts_map
@@ -107,12 +105,11 @@ rdp_layout_us=us
rdp_layout_de=de
rdp_layout_fr=fr
rdp_layout_jp=jp
-rdp_layout_jp2=jp
-rdp_layout_jp3=jp
-rdp_layout_jp4=jp
+rdp_layout_kr=kr
rdp_layout_it=it
rdp_layout_ru=ru
rdp_layout_se=se
+rdp_layout_ch=ch
rdp_layout_pt=pt
rdp_layout_br=br(abnt2)
rdp_layout_pl=pl
diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c
index b2b19ca2..c563d5fd 100644
--- a/xrdp/xrdp_listen.c
+++ b/xrdp/xrdp_listen.c
@@ -370,6 +370,8 @@ xrdp_listen_main_loop(struct xrdp_listen *self)
if (error == 0)
{
+ log_message(LOG_LEVEL_INFO, "listening to port %s on %s",
+ port, address);
if (tcp_nodelay)
{
if (g_tcp_set_no_delay(self->listen_trans->sck))
@@ -455,8 +457,8 @@ xrdp_listen_main_loop(struct xrdp_listen *self)
if (trans_get_wait_objs(self->listen_trans, robjs,
&robjs_count) != 0)
{
- log_message(LOG_LEVEL_ERROR,"Listening socket is in wrong state we "
- "terminate listener");
+ log_message(LOG_LEVEL_ERROR,"Listening socket is in wrong state, "
+ "terminating listener");
break;
}
}
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index 357b4e2a..37cd1e00 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -96,7 +96,7 @@ xrdp_wm_popup_notify(struct xrdp_bitmap *wnd,
/*****************************************************************************/
int APP_CC
-xrdp_wm_delete_all_childs(struct xrdp_wm *self)
+xrdp_wm_delete_all_children(struct xrdp_wm *self)
{
int index;
struct xrdp_bitmap *b;
@@ -228,7 +228,7 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd)
wm->mm->login_names->auto_free = 1;
wm->mm->login_values = list_create();
wm->mm->login_values->auto_free = 1;
- /* gota copy these cause dialog gets freed */
+ /* will copy these cause dialog gets freed */
list_append_list_strdup(mod_data->names, wm->mm->login_names, 0);
list_append_list_strdup(mod_data->values, wm->mm->login_values, 0);
xrdp_wm_set_login_mode(wm, 2);
@@ -257,7 +257,7 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd)
*
* Users can create shortcuts where this information is configured. These
* shortcuts simplifies login.
-* @param orginalDomainInfo indata to this function
+* @param originalDomainInfo indata to this function
* @param comboMax the max number of combo choices
* @param decode if true then we perform decoding of combo choice
* @param resultBuffer must be pre allocated before calling this function.
@@ -266,21 +266,20 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd)
* 0 if the user does not prefer any choice.
*/
static int APP_CC
-xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax,
+xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];
- char debugstr[256];
/* If the first char in the domain name is '_' we use the domain
name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
- if (orginalDomainInfo[0] == '_')
+ if (originalDomainInfo[0] == '_')
{
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
@@ -289,7 +288,7 @@ xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax,
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
- pos = g_pos(&orginalDomainInfo[1], "__");
+ pos = g_pos(&originalDomainInfo[1], "__");
if (pos > 0)
{
/* an index is found we try to use it
@@ -298,13 +297,11 @@ xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax,
{
g_memset(index, 0, 2);
/* we just accept values 0-9 (one figure) */
- g_strncpy(index, &orginalDomainInfo[pos + 3], 1);
+ g_strncpy(index, &originalDomainInfo[pos + 3], 1);
comboxindex = g_htoi(index);
- g_snprintf(debugstr, 255, "Value of index (as char): %s "
- "(converted) : %d (max) : %d", index, comboxindex,
- comboMax - 1);
- debugstr[255] = 0;
- log_message(LOG_LEVEL_DEBUG, debugstr);
+ log_message(LOG_LEVEL_DEBUG,
+ "index value as string: %s, as int: %d, max: %d",
+ index, comboxindex, comboMax - 1);
/* limit to max number of items in combo box */
if ((comboxindex > 0) && (comboxindex < comboMax))
{
@@ -314,12 +311,12 @@ xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax,
}
}
/* pos limit the String to only contain the IP */
- g_strncpy(resultBuffer, &orginalDomainInfo[1], pos);
+ g_strncpy(resultBuffer, &originalDomainInfo[1], pos);
}
else
{
/* log_message(LOG_LEVEL_DEBUG, "domain does not contain _"); */
- g_strncpy(resultBuffer, &orginalDomainInfo[1], 255);
+ g_strncpy(resultBuffer, &originalDomainInfo[1], 255);
}
}
return ret;
@@ -344,7 +341,7 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
username_set = 0;
- /* free labels and edits, cause we gota create them */
+ /* free labels and edits, cause we will create them */
/* creation or combo changed */
for (index = 100; index < 200; index++)
{
@@ -563,9 +560,9 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b)
p = (char *)list_get_item(sections, i);
file_read_section(fd, p, section_names, section_values);
- if ((g_strncmp(p, "globals", 255) == 0)
- || (g_strncmp(p, "channels", 255) == 0)
- || (g_strncmp(p, "Logging", 255) == 0))
+ if ((g_strncasecmp(p, "globals", 255) == 0)
+ || (g_strncasecmp(p, "channels", 255) == 0)
+ || (g_strncasecmp(p, "Logging", 255) == 0))
{
}
else
@@ -618,9 +615,19 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
int log_width;
int log_height;
int regular;
+ int primary_x_offset;
+ int primary_y_offset;
+ int index;
+ int x;
+ int y;
+ int cx;
+ int cy;
globals = &self->xrdp_config->cfg_globals;
+ primary_x_offset = self->screen->width / 2;
+ primary_y_offset = self->screen->height / 2;
+
log_width = globals->ls_width;
log_height = globals->ls_height;
regular = 1;
@@ -639,6 +646,25 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
regular = 0;
}
+ /* multimon scenario, draw login window on primary monitor */
+ if (self->client_info->monitorCount > 1)
+ {
+ for (index = 0; index < self->client_info->monitorCount; index++)
+ {
+ if (self->client_info->minfo_wm[index].is_primary)
+ {
+ x = self->client_info->minfo_wm[index].left;
+ y = self->client_info->minfo_wm[index].top;
+ cx = self->client_info->minfo_wm[index].right;
+ cy = self->client_info->minfo_wm[index].bottom;
+
+ primary_x_offset = x + ((cx - x) / 2);
+ primary_y_offset = y + ((cy - y) / 2);
+ break;
+ }
+ }
+ }
+
/* draw login window */
self->login_window = xrdp_bitmap_create(log_width, log_height, self->screen->bpp,
WND_TYPE_WND, self);
@@ -647,11 +673,9 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
self->login_window->owner = self->screen;
self->login_window->bg_color = globals->ls_bg_color;
- self->login_window->left = self->screen->width / 2 -
- self->login_window->width / 2;
+ self->login_window->left = primary_x_offset - self->login_window->width / 2;
+ self->login_window->top = primary_y_offset - self->login_window->height / 2;
- self->login_window->top = self->screen->height / 2 -
- self->login_window->height / 2;
self->login_window->notify = xrdp_wm_login_notify;
@@ -791,13 +815,12 @@ load_xrdp_config(struct xrdp_config *config, int bpp)
globals = &config->cfg_globals;
- /* set default values incase we can't get them from xrdp.ini file */
+ /* set default values in case we can't get them from xrdp.ini file */
globals->ini_version = 1;
globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi("009cb5"));
globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi("dedede"));
globals->ls_width = 350;
globals->ls_height = 350;
- globals->ls_bg_color = 0xdedede;
globals->ls_logo_x_pos = 63;
globals->ls_logo_y_pos = 50;
globals->ls_label_x_pos = 30;
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 76957ad6..bb6bc5d8 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -24,11 +24,18 @@
#define ACCESS
#include "xrdp.h"
#include "log.h"
+
#ifdef ACCESS
#ifndef USE_NOPAM
+#if defined(HAVE__PAM_TYPES_H)
+#define LINUXPAM 1
#include "security/_pam_types.h"
+#elif defined(HAVE_PAM_CONSTANTS_H)
+#define OPENPAM 1
+#include <security/pam_constants.h>
#endif
-#endif
+#endif /* USE_NOPAM */
+#endif /* ACCESS */
#include "xrdp_encoder.h"
@@ -58,46 +65,16 @@ xrdp_mm_create(struct xrdp_wm *owner)
self->login_values->auto_free = 1;
LLOGLN(0, ("xrdp_mm_create: bpp %d mcs_connection_type %d "
- "jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d",
+ "jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d "
+ "h264_codec_id %d",
self->wm->client_info->bpp,
self->wm->client_info->mcs_connection_type,
self->wm->client_info->jpeg_codec_id,
self->wm->client_info->v3_codec_id,
- self->wm->client_info->rfx_codec_id));
- /* go into jpeg codec mode if jpeg set, lan set */
- if (self->wm->client_info->mcs_connection_type == 6) /* LAN */
- {
- if (self->wm->client_info->jpeg_codec_id == 2) /* JPEG */
- {
- if (self->wm->client_info->bpp > 16)
- {
- LLOGLN(0, ("xrdp_mm_create: starting jpeg codec session"));
- self->codec_id = 2;
- self->in_codec_mode = 1;
- self->codec_quality = self->wm->client_info->jpeg_prop[0];
- self->wm->client_info->capture_code = 0;
- self->wm->client_info->capture_format =
- /* PIXMAN_a8b8g8r8 */
- (32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8;
- }
- }
- else if (self->wm->client_info->rfx_codec_id == 3) /* RFX */
- {
- if (self->wm->client_info->bpp > 16)
- {
- LLOGLN(0, ("xrdp_mm_create: starting rfx codec session"));
- self->codec_id = 3;
- self->in_codec_mode = 1;
- self->wm->client_info->capture_code = 2;
- }
- }
- }
+ self->wm->client_info->rfx_codec_id,
+ self->wm->client_info->h264_codec_id));
- if (self->in_codec_mode)
- {
- /* setup thread to handle codec mode messages */
- init_xrdp_encoder(self);
- }
+ self->encoder = xrdp_encoder_create(self);
return self;
}
@@ -174,7 +151,7 @@ xrdp_mm_delete(struct xrdp_mm *self)
xrdp_mm_module_cleanup(self);
/* shutdown thread */
- deinit_xrdp_encoder(self);
+ xrdp_encoder_delete(self->encoder);
trans_delete(self->sesman_trans);
self->sesman_trans = 0;
@@ -199,8 +176,8 @@ xrdp_mm_send_login(struct xrdp_mm *self)
char *name;
char *value;
- xrdp_wm_log_msg(self->wm, "sending login info to session manager, "
- "please wait...");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
+ "sending login info to session manager, please wait...");
username = 0;
password = 0;
self->code = 0;
@@ -233,7 +210,8 @@ xrdp_mm_send_login(struct xrdp_mm *self)
if ((username == 0) || (password == 0))
{
- xrdp_wm_log_msg(self->wm, "Error finding username and password");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "Error finding username and password");
return 1;
}
@@ -251,14 +229,19 @@ xrdp_mm_send_login(struct xrdp_mm *self)
out_uint16_be(s, self->wm->screen->width);
out_uint16_be(s, self->wm->screen->height);
- if (xserverbpp > 0)
- {
- out_uint16_be(s, xserverbpp);
- }
- else
+ /* select and send X server bpp */
+ if (xserverbpp == 0)
{
- out_uint16_be(s, self->wm->screen->bpp);
+ if (self->code == 20)
+ {
+ xserverbpp = 24; /* xorgxrdp is always at 24 bpp */
+ }
+ else
+ {
+ xserverbpp = self->wm->screen->bpp; /* use client's bpp */
+ }
}
+ out_uint16_be(s, xserverbpp);
/* send domain */
if(self->wm->client_info->domain[0]!='_')
@@ -300,7 +283,8 @@ xrdp_mm_send_login(struct xrdp_mm *self)
if (rv != 0)
{
- xrdp_wm_log_msg(self->wm, "xrdp_mm_send_login: xrdp_mm_send_login failed");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING,
+ "xrdp_mm_send_login: xrdp_mm_send_login failed");
}
return rv;
@@ -312,7 +296,8 @@ xrdp_mm_send_login(struct xrdp_mm *self)
then it copies the corresponding login_values item into 'dest'
'dest' must be at least 'dest_len' + 1 bytes in size */
static int APP_CC
-xrdp_mm_get_value(struct xrdp_mm *self, char *aname, char *dest, int dest_len)
+xrdp_mm_get_value(struct xrdp_mm *self, const char *aname, char *dest,
+ int dest_len)
{
char *name;
char *value;
@@ -362,25 +347,25 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
if (xrdp_mm_get_value(self, "lib", lib, 255) != 0)
{
- g_snprintf(text, 255, "no library name specified in xrdp.ini, please add "
- "lib=libxrdp-vnc.so or similar");
- xrdp_wm_log_msg(self->wm, text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "no library name specified in xrdp.ini, please add "
+ "lib=libxrdp-vnc.so or similar");
return 1;
}
if (lib[0] == 0)
{
- g_snprintf(text, 255, "empty library name specified in xrdp.ini, please "
- "add lib=libxrdp-vnc.so or similar");
- xrdp_wm_log_msg(self->wm, text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "empty library name specified in xrdp.ini, please "
+ "add lib=libxrdp-vnc.so or similar");
return 1;
}
if (self->mod_handle == 0)
{
- g_snprintf(text, 255, "%s/%s", XRDP_LIB_PATH, lib);
+ g_snprintf(text, 255, "%s/%s", XRDP_MODULE_PATH, lib);
/* Let the main thread load the lib,*/
self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (tintptr)text, 0);
@@ -395,10 +380,9 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
if (func == 0)
{
- g_snprintf(text, 255, "error finding proc mod_init in %s, not a valid "
- "xrdp backend", lib);
- xrdp_wm_log_msg(self->wm, text);
- log_message(LOG_LEVEL_ERROR,text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "error finding proc mod_init in %s, "
+ "not a valid xrdp backend", lib);
}
self->mod_init = (struct xrdp_mod * ( *)(void))func;
@@ -411,10 +395,9 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
if (func == 0)
{
- g_snprintf(text, 255, "error finding proc mod_exit in %s, not a valid "
- "xrdp backend", lib);
- xrdp_wm_log_msg(self->wm, text);
- log_message(LOG_LEVEL_ERROR,text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "error finding proc mod_exit in %s, "
+ "not a valid xrdp backend", lib);
}
self->mod_exit = (int ( *)(struct xrdp_mod *))func;
@@ -436,10 +419,10 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
}
else
{
- g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please "
- "add a valid entry like lib=libxrdp-vnc.so or similar", lib);
- xrdp_wm_log_msg(self->wm, text);
- log_message(LOG_LEVEL_ERROR,text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "error loading %s specified in xrdp.ini, please "
+ "add a valid entry like lib=libxrdp-vnc.so or "
+ "similar", lib);
return 1;
}
@@ -489,6 +472,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_paint_rect_bpp = server_paint_rect_bpp;
self->mod->server_composite = server_composite;
self->mod->server_paint_rects = server_paint_rects;
+ self->mod->si = (tintptr) &(self->wm->session->si);
}
}
@@ -504,7 +488,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
/*****************************************************************************/
static int APP_CC
-xrdp_mm_setup_mod2(struct xrdp_mm *self)
+xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid)
{
char text[256];
char *name;
@@ -584,6 +568,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
self->mod->mod_set_param(self->mod, "hostname", name);
g_snprintf(text, 255, "%d", self->wm->session->client_info->keylayout);
self->mod->mod_set_param(self->mod, "keylayout", text);
+ if (guid != 0)
+ {
+ self->mod->mod_set_param(self->mod, "guid", (char *) guid);
+ }
for (i = 0; i < self->login_names->count; i++)
{
@@ -600,6 +588,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
else
{
xrdp_wm_show_log(self->wm);
+ if (self->wm->hide_log_window)
+ {
+ rv = 1;
+ }
}
}
@@ -781,7 +773,7 @@ xrdp_mm_process_rail_create_window(struct xrdp_mm* self, struct stream* s)
in_uint16_le(s, title_bytes);
if (title_bytes > 0)
{
- rwso.title_info = g_malloc(title_bytes + 1, 0);
+ rwso.title_info = g_new(char, title_bytes + 1);
in_uint8a(s, rwso.title_info, title_bytes);
rwso.title_info[title_bytes] = 0;
}
@@ -835,6 +827,7 @@ xrdp_mm_process_rail_create_window(struct xrdp_mm* self, struct stream* s)
return rv;
}
+#if 0
/*****************************************************************************/
/* returns error
process rail configure window order */
@@ -901,6 +894,7 @@ xrdp_mm_process_rail_configure_window(struct xrdp_mm* self, struct stream* s)
g_free(rwso.visibility_rects);
return rv;
}
+#endif
/*****************************************************************************/
/* returns error
@@ -962,7 +956,7 @@ xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s)
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, size); /* title size */
- rwso.title_info = g_malloc(size + 1, 0);
+ rwso.title_info = g_new(char, size + 1);
in_uint8a(s, rwso.title_info, size);
rwso.title_info[size] = 0;
g_writeln(" set window title %s size %d 0x%8.8x", rwso.title_info, size, flags);
@@ -1074,7 +1068,6 @@ xrdp_mm_chan_data_in(struct trans *trans)
{
struct xrdp_mm *self;
struct stream *s;
- int id;
int size;
int error;
@@ -1091,7 +1084,7 @@ xrdp_mm_chan_data_in(struct trans *trans)
return 1;
}
- in_uint32_le(s, id);
+ in_uint8s(s, 4); /* id */
in_uint32_le(s, size);
error = trans_force_read(trans, size - 8);
@@ -1128,7 +1121,7 @@ xrdp_mm_chan_send_init(struct xrdp_mm *self)
/*****************************************************************************/
/* connect to chansrv */
static int APP_CC
-xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port)
+xrdp_mm_connect_chansrv(struct xrdp_mm *self, const char *ip, const char *port)
{
int index;
@@ -1139,15 +1132,16 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port)
{
/* unix socket */
self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
- self->chan_trans->is_term = g_is_term;
}
else
{
/* tcp */
self->chan_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
- self->chan_trans->is_term = g_is_term;
}
+ self->chan_trans->is_term = g_is_term;
+ self->chan_trans->si = &(self->wm->session->si);
+ self->chan_trans->my_source = XRDP_SOURCE_CHANSRV;
self->chan_trans->trans_data_in = xrdp_mm_chan_data_in;
self->chan_trans->header_size = 8;
self->chan_trans->callback_data = self;
@@ -1168,7 +1162,7 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port)
if (!(self->chan_trans_up))
{
- log_message(LOG_LEVEL_ERROR,"xrdp_mm_connect_chansrv: error in"
+ log_message(LOG_LEVEL_ERROR,"xrdp_mm_connect_chansrv: error in "
"trans_connect chan");
}
@@ -1181,7 +1175,7 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port)
}
else
{
- log_message(LOG_LEVEL_DEBUG,"xrdp_mm_connect_chansrv: chansrv"
+ log_message(LOG_LEVEL_DEBUG,"xrdp_mm_connect_chansrv: chansrv "
"connect successful");
}
}
@@ -1208,24 +1202,29 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
int ok;
int display;
int rv;
- char text[256];
char ip[256];
char port[256];
+ tui8 guid[16];
+ tui8* pguid;
rv = 0;
in_uint16_be(s, ok);
in_uint16_be(s, display);
-
+ pguid = 0;
+ if (s_check_rem(s, 16))
+ {
+ in_uint8a(s, guid, 16);
+ pguid = guid;
+ }
if (ok)
{
self->display = display;
- g_snprintf(text, 255, "xrdp_mm_process_login_response: login successful "
- "for display %d", display);
- xrdp_wm_log_msg(self->wm, text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
+ "login successful for display %d", display);
if (xrdp_mm_setup_mod1(self) == 0)
{
- if (xrdp_mm_setup_mod2(self) == 0)
+ if (xrdp_mm_setup_mod2(self, pguid) == 0)
{
xrdp_mm_get_value(self, "ip", ip, 255);
xrdp_wm_set_login_mode(self->wm, 10);
@@ -1247,11 +1246,13 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
}
else
{
- xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: "
- "login failed");
- log_message(LOG_LEVEL_INFO,"xrdp_mm_process_login_response: "
- "login failed");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
+ "login failed for display %d", display);
xrdp_wm_show_log(self->wm);
+ if (self->wm->hide_log_window)
+ {
+ rv = 1;
+ }
}
cleanup_sesman_connection(self);
@@ -1410,8 +1411,9 @@ xrdp_mm_sesman_data_in(struct trans *trans)
error = xrdp_mm_process_login_response(self, s);
break;
default:
- xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman");
- log_message(LOG_LEVEL_ERROR,"Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "Undefined reply code %d received from sesman",
+ code);
cleanup_sesman_connection(self);
break;
}
@@ -1471,7 +1473,7 @@ access_control(char *username, char *password, char *srv)
if (reply > 0)
{
/* We wait in 5 sec for a reply from sesman*/
- if (g_tcp_can_recv(socket, 5000))
+ if (g_sck_can_recv(socket, 5000))
{
reply = g_tcp_recv(socket, in_s->end, 500, 0);
@@ -1501,7 +1503,7 @@ access_control(char *username, char *password, char *srv)
else
{
log_message(LOG_LEVEL_ERROR, "Corrupt reply size or "
- "version from sesman: %d", size);
+ "version from sesman: %ld", size);
}
}
else
@@ -1570,6 +1572,7 @@ getPAMError(const int pamError, char *text, int text_bytes)
{
switch (pamError)
{
+#if defined(LINUXPAM)
case PAM_SUCCESS:
return "Success";
case PAM_OPEN_ERR:
@@ -1635,6 +1638,71 @@ getPAMError(const int pamError, char *text, int text_bytes)
default:
g_snprintf(text, text_bytes, "Not defined PAM error:%d", pamError);
return text;
+#elif defined(OPENPAM)
+ case PAM_SUCCESS: /* 0 */
+ return "Success";
+ case PAM_OPEN_ERR:
+ return "dlopen() failure";
+ case PAM_SYMBOL_ERR:
+ return "Symbol not found";
+ case PAM_SERVICE_ERR:
+ return "Error in service module";
+ case PAM_SYSTEM_ERR:
+ return "System error";
+ case PAM_BUF_ERR:
+ return "Memory buffer error";
+ case PAM_CONV_ERR:
+ return "Conversation error";
+ case PAM_PERM_DENIED:
+ return "Permission denied";
+ case PAM_MAXTRIES:
+ return "Have exhausted maximum number of retries for service.";
+ case PAM_AUTH_ERR:
+ return "Authentication failure";
+ case PAM_NEW_AUTHTOK_REQD: /* 10 */
+ return "Authentication token is no longer valid; new one required.";
+ case PAM_CRED_INSUFFICIENT:
+ return "Insufficient credentials to access authentication data";
+ case PAM_AUTHINFO_UNAVAIL:
+ return "Authentication service cannot retrieve authentication info.";
+ case PAM_USER_UNKNOWN:
+ return "User not known to the underlying authentication module";
+ case PAM_CRED_UNAVAIL:
+ return "Authentication service cannot retrieve user credentials";
+ case PAM_CRED_EXPIRED:
+ return "User credentials expired";
+ case PAM_CRED_ERR:
+ return "Failure setting user credentials";
+ case PAM_ACCT_EXPIRED:
+ return "User account has expired";
+ case PAM_AUTHTOK_EXPIRED:
+ return "Authentication token expired";
+ case PAM_SESSION_ERR:
+ return "Session failure";
+ case PAM_AUTHTOK_ERR: /* 20 */
+ return "Authentication token manipulation error";
+ case PAM_AUTHTOK_RECOVERY_ERR:
+ return "Failed to recover old authentication token";
+ case PAM_AUTHTOK_LOCK_BUSY:
+ return "Authentication token lock busy";
+ case PAM_AUTHTOK_DISABLE_AGING:
+ return "Authentication token aging disabled";
+ case PAM_NO_MODULE_DATA:
+ return "No module specific data is present";
+ case PAM_IGNORE:
+ return "Please ignore underlying account module";
+ case PAM_ABORT:
+ return "General failure";
+ case PAM_TRY_AGAIN:
+ return "Failed preliminary check by password service";
+ case PAM_MODULE_UNKNOWN:
+ return "Module is unknown";
+ case PAM_DOMAIN_UNKNOWN: /* 29 */
+ return "Unknown authentication domain";
+ default:
+ g_snprintf(text, text_bytes, "Not defined PAM error:%d", pamError);
+ return text;
+#endif
}
}
@@ -1643,6 +1711,7 @@ getPAMAdditionalErrorInfo(const int pamError, struct xrdp_mm *self)
{
switch (pamError)
{
+#if defined(LINUXPAM)
case PAM_SUCCESS:
return NULL;
case PAM_OPEN_ERR:
@@ -1686,6 +1755,49 @@ getPAMAdditionalErrorInfo(const int pamError, struct xrdp_mm *self)
}
default:
return "No expected error";
+#elif defined(OPENPAM)
+ case PAM_SUCCESS: /* 0 */
+ return NULL;
+ case PAM_OPEN_ERR:
+ case PAM_SYMBOL_ERR:
+ case PAM_SERVICE_ERR:
+ case PAM_SYSTEM_ERR:
+ case PAM_BUF_ERR:
+ case PAM_CONV_ERR:
+ case PAM_PERM_DENIED:
+ case PAM_MAXTRIES:
+ case PAM_AUTH_ERR:
+ case PAM_NEW_AUTHTOK_REQD: /* 10 */
+ case PAM_CRED_INSUFFICIENT:
+ case PAM_AUTHINFO_UNAVAIL:
+ case PAM_USER_UNKNOWN:
+ case PAM_CRED_UNAVAIL:
+ case PAM_CRED_EXPIRED:
+ case PAM_CRED_ERR:
+ case PAM_ACCT_EXPIRED:
+ case PAM_AUTHTOK_EXPIRED:
+ case PAM_SESSION_ERR:
+ case PAM_AUTHTOK_ERR: /* 20 */
+ case PAM_AUTHTOK_RECOVERY_ERR:
+ case PAM_AUTHTOK_LOCK_BUSY:
+ case PAM_AUTHTOK_DISABLE_AGING:
+ case PAM_NO_MODULE_DATA:
+ case PAM_IGNORE:
+ case PAM_ABORT:
+ case PAM_TRY_AGAIN:
+ case PAM_MODULE_UNKNOWN:
+ case PAM_DOMAIN_UNKNOWN: /* 29 */
+ if (self->wm->pamerrortxt[0])
+ {
+ return self->wm->pamerrortxt;
+ }
+ else
+ {
+ return "Authentication error - Verify that user/password is valid";
+ }
+ default:
+ return "No expected error";
+#endif
}
}
#endif
@@ -1703,8 +1815,6 @@ xrdp_mm_connect(struct xrdp_mm *self)
char *name;
char *value;
char ip[256];
- char errstr[256];
- char text[256];
char port[8];
char chansrvport[256];
#ifdef ACCESS
@@ -1722,8 +1832,6 @@ xrdp_mm_connect(struct xrdp_mm *self)
/* make sure we start in correct state */
cleanup_states(self);
g_memset(ip, 0, sizeof(ip));
- g_memset(errstr, 0, sizeof(errstr));
- g_memset(text, 0, sizeof(text));
g_memset(port, 0, sizeof(port));
g_memset(chansrvport, 0, sizeof(chansrvport));
rv = 0; /* success */
@@ -1786,10 +1894,10 @@ xrdp_mm_connect(struct xrdp_mm *self)
if (use_pam_auth)
{
int reply;
- char replytxt[128];
char pam_error[128];
const char *additionalError;
- xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control...");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
+ "Please wait, we now perform access control...");
/* g_writeln("we use pam modules to check if we can approve this user"); */
if (!g_strncmp(pam_auth_username, "same", 255))
@@ -1807,19 +1915,14 @@ xrdp_mm_connect(struct xrdp_mm *self)
/* access_control return 0 on success */
reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP);
- g_sprintf(replytxt, "Reply from access control: %s",
- getPAMError(reply, pam_error, 127));
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
+ "Reply from access control: %s",
+ getPAMError(reply, pam_error, 127));
- xrdp_wm_log_msg(self->wm, replytxt);
- log_message(LOG_LEVEL_INFO, replytxt);
additionalError = getPAMAdditionalErrorInfo(reply, self);
- if (additionalError)
+ if (additionalError && additionalError[0])
{
- g_snprintf(replytxt, 127, "%s", additionalError);
- if (replytxt[0])
- {
- xrdp_wm_log_msg(self->wm, replytxt);
- }
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", additionalError);
}
if (reply != 0)
@@ -1838,8 +1941,8 @@ xrdp_mm_connect(struct xrdp_mm *self)
self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
self->sesman_trans->is_term = g_is_term;
xrdp_mm_get_sesman_port(port, sizeof(port));
- g_snprintf(text, 255, "connecting to sesman ip %s port %s", ip, port);
- xrdp_wm_log_msg(self->wm, text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
+ "connecting to sesman ip %s port %s", ip, port);
/* xrdp_mm_sesman_data_in is the callback that is called when data arrives */
self->sesman_trans->trans_data_in = xrdp_mm_sesman_data_in;
self->sesman_trans->header_size = 8;
@@ -1863,16 +1966,15 @@ xrdp_mm_connect(struct xrdp_mm *self)
if (ok)
{
/* fully connect */
- xrdp_wm_log_msg(self->wm, "sesman connect ok");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "sesman connect ok");
self->connected_state = 1;
rv = xrdp_mm_send_login(self);
}
else
{
- g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s",
- ip, port);
- xrdp_wm_log_msg(self->wm, errstr);
- log_message(LOG_LEVEL_ERROR,errstr);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "Error connecting to sesman: %s port: %s",
+ ip, port);
trans_delete(self->sesman_trans);
self->sesman_trans = 0;
self->sesman_trans_up = 0;
@@ -1883,17 +1985,16 @@ xrdp_mm_connect(struct xrdp_mm *self)
{
if (xrdp_mm_setup_mod1(self) == 0)
{
- if (xrdp_mm_setup_mod2(self) == 0)
+ if (xrdp_mm_setup_mod2(self, 0) == 0)
{
xrdp_wm_set_login_mode(self->wm, 10);
- rv = 0; /*sucess*/
+ rv = 0; /*success*/
}
else
{
/* connect error */
- g_snprintf(errstr, 255, "Failure to connect to: %s", ip);
- log_message(LOG_LEVEL_ERROR,errstr);
- xrdp_wm_log_msg(self->wm, errstr);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "Error connecting to: %s", ip);
rv = 1; /* failure */
}
}
@@ -1917,7 +2018,7 @@ xrdp_mm_connect(struct xrdp_mm *self)
xrdp_mm_connect_chansrv(self, "", chansrvport);
}
- log_message(LOG_LEVEL_DEBUG,"returnvalue from xrdp_mm_connect %d", rv);
+ log_message(LOG_LEVEL_DEBUG,"return value from xrdp_mm_connect %d", rv);
return rv;
}
@@ -1956,9 +2057,9 @@ xrdp_mm_get_wait_objs(struct xrdp_mm *self,
}
}
- if (self->in_codec_mode)
+ if (self->encoder != 0)
{
- read_objs[(*rcount)++] = self->xrdp_encoder_event_processed;
+ read_objs[(*rcount)++] = self->encoder->xrdp_encoder_event_processed;
}
return rv;
@@ -2021,6 +2122,28 @@ xrdp_mm_dump_jpeg(struct xrdp_mm *self, XRDP_ENC_DATA_DONE *enc_done)
/*****************************************************************************/
int APP_CC
+xrdp_mm_check_chan(struct xrdp_mm *self)
+{
+ //g_writeln("xrdp_mm_check_chan:");
+ if ((self->chan_trans != 0) && self->chan_trans_up)
+ {
+ if (trans_check_wait_objs(self->chan_trans) != 0)
+ {
+ self->delete_chan_trans = 1;
+ }
+ }
+ if (self->delete_chan_trans)
+ {
+ trans_delete(self->chan_trans);
+ self->chan_trans = 0;
+ self->chan_trans_up = 0;
+ self->delete_chan_trans = 0;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
xrdp_mm_check_wait_objs(struct xrdp_mm *self)
{
XRDP_ENC_DATA_DONE *enc_done;
@@ -2029,6 +2152,8 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
int y;
int cx;
int cy;
+ int use_frame_acks;
+ int ex;
if (self == 0)
{
@@ -2042,6 +2167,11 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
if (trans_check_wait_objs(self->sesman_trans) != 0)
{
self->delete_sesman_trans = 1;
+ if (self->wm->hide_log_window)
+ {
+ /* if hide_log_window, this is fatal */
+ rv = 1;
+ }
}
}
@@ -2077,15 +2207,18 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
self->delete_chan_trans = 0;
}
- if (self->in_codec_mode)
+ if (self->encoder != 0)
{
- if (g_is_wait_obj_set(self->xrdp_encoder_event_processed))
+
+ use_frame_acks = self->wm->client_info->use_frame_acks;
+
+ if (g_is_wait_obj_set(self->encoder->xrdp_encoder_event_processed))
{
- g_reset_wait_obj(self->xrdp_encoder_event_processed);
- tc_mutex_lock(self->mutex);
+ g_reset_wait_obj(self->encoder->xrdp_encoder_event_processed);
+ tc_mutex_lock(self->encoder->mutex);
enc_done = (XRDP_ENC_DATA_DONE*)
- fifo_remove_item(self->fifo_processed);
- tc_mutex_unlock(self->mutex);
+ fifo_remove_item(self->encoder->fifo_processed);
+ tc_mutex_unlock(self->encoder->mutex);
while (enc_done != 0)
{
/* do something with msg */
@@ -2103,36 +2236,85 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
if (enc_done->comp_bytes > 0)
{
+ libxrdp_fastpath_send_frame_marker(self->wm->session, 0,
+ enc_done->enc->frame_id);
libxrdp_fastpath_send_surface(self->wm->session,
enc_done->comp_pad_data,
enc_done->pad_bytes,
enc_done->comp_bytes,
x, y, x + cx, y + cy,
- 32, self->codec_id, cx, cy);
+ 32, self->encoder->codec_id, cx, cy);
+ libxrdp_fastpath_send_frame_marker(self->wm->session, 1,
+ enc_done->enc->frame_id);
}
/* free enc_done */
if (enc_done->last)
{
LLOGLN(10, ("xrdp_mm_check_wait_objs: last set"));
- self->mod->mod_frame_ack(self->mod,
- enc_done->enc->flags, enc_done->enc->frame_id);
+ if (use_frame_acks == 0)
+ {
+ self->mod->mod_frame_ack(self->mod,
+ enc_done->enc->flags,
+ enc_done->enc->frame_id);
+ }
+ else
+ {
+#if 1
+ ex = self->wm->client_info->max_unacknowledged_frame_count;
+ if (self->encoder->frame_id_client + ex > self->encoder->frame_id_server)
+ {
+ if (self->encoder->frame_id_server > self->encoder->frame_id_server_sent)
+ {
+ LLOGLN(10, ("xrdp_mm_check_wait_objs: 1 -- %d", self->encoder->frame_id_server));
+ self->encoder->frame_id_server_sent = self->encoder->frame_id_server;
+ self->mod->mod_frame_ack(self->mod, 0, self->encoder->frame_id_server);
+ }
+ }
+#endif
+ }
g_free(enc_done->enc->drects);
g_free(enc_done->enc->crects);
g_free(enc_done->enc);
}
g_free(enc_done->comp_pad_data);
g_free(enc_done);
- tc_mutex_lock(self->mutex);
+ tc_mutex_lock(self->encoder->mutex);
enc_done = (XRDP_ENC_DATA_DONE*)
- fifo_remove_item(self->fifo_processed);
- tc_mutex_unlock(self->mutex);
+ fifo_remove_item(self->encoder->fifo_processed);
+ tc_mutex_unlock(self->encoder->mutex);
}
}
}
return rv;
}
+/*****************************************************************************/
+/* frame ack from client */
+int APP_CC
+xrdp_mm_frame_ack(struct xrdp_mm *self, int frame_id)
+{
+ int ex;
+
+ LLOGLN(10, ("xrdp_mm_frame_ack:"));
+ self->encoder->frame_id_client = frame_id;
+ if (self->wm->client_info->use_frame_acks == 0)
+ {
+ return 1;
+ }
+ ex = self->wm->client_info->max_unacknowledged_frame_count;
+ if (self->encoder->frame_id_client + ex > self->encoder->frame_id_server)
+ {
+ if (self->encoder->frame_id_server > self->encoder->frame_id_server_sent)
+ {
+ LLOGLN(10, ("xrdp_mm_frame_ack: frame_id_server %d", self->encoder->frame_id_server));
+ self->encoder->frame_id_server_sent = self->encoder->frame_id_server;
+ self->mod->mod_frame_ack(self->mod, 0, self->encoder->frame_id_server);
+ }
+ }
+ return 0;
+}
+
#if 0
/*****************************************************************************/
struct xrdp_painter *APP_CC
@@ -2354,9 +2536,9 @@ server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
mm = wm->mm;
LLOGLN(10, ("server_paint_rects:"));
- LLOGLN(10, ("server_paint_rects: %d", mm->in_codec_mode));
+ LLOGLN(10, ("server_paint_rects: %p", mm->encoder));
- if (mm->in_codec_mode)
+ if (mm->encoder != 0)
{
/* copy formal params to XRDP_ENC_DATA */
enc_data = (XRDP_ENC_DATA *) g_malloc(sizeof(XRDP_ENC_DATA), 1);
@@ -2393,18 +2575,19 @@ server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
enc_data->height = height;
enc_data->flags = flags;
enc_data->frame_id = frame_id;
+ mm->encoder->frame_id_server = frame_id;
if (width == 0 || height == 0)
{
LLOGLN(10, ("server_paint_rects: error"));
}
/* insert into fifo for encoder thread to process */
- tc_mutex_lock(mm->mutex);
- fifo_add_item(mm->fifo_to_proc, (void *) enc_data);
- tc_mutex_unlock(mm->mutex);
+ tc_mutex_lock(mm->encoder->mutex);
+ fifo_add_item(mm->encoder->fifo_to_proc, (void *) enc_data);
+ tc_mutex_unlock(mm->encoder->mutex);
/* signal xrdp_encoder thread */
- g_set_wait_obj(mm->xrdp_encoder_event_to_proc);
+ g_set_wait_obj(mm->encoder->xrdp_encoder_event_to_proc);
return 0;
}
@@ -2479,12 +2662,12 @@ server_msg(struct xrdp_mod *mod, char *msg, int code)
if (code == 1)
{
- g_writeln(msg);
+ g_writeln("%s",msg);
return 0;
}
wm = (struct xrdp_wm *)(mod->wm);
- return xrdp_wm_log_msg(wm, msg);
+ return xrdp_wm_log_msg(wm, LOG_LEVEL_DEBUG, "%s", msg);
}
/*****************************************************************************/
@@ -2597,7 +2780,7 @@ server_set_mixmode(struct xrdp_mod *mod, int mixmode)
/*****************************************************************************/
int DEFAULT_CC
-server_set_brush(struct xrdp_mod *mod, int x_orgin, int y_orgin,
+server_set_brush(struct xrdp_mod *mod, int x_origin, int y_origin,
int style, char *pattern)
{
struct xrdp_painter *p;
@@ -2609,8 +2792,8 @@ server_set_brush(struct xrdp_mod *mod, int x_orgin, int y_orgin,
return 0;
}
- p->brush.x_orgin = x_orgin;
- p->brush.y_orgin = y_orgin;
+ p->brush.x_origin = x_origin;
+ p->brush.y_origin = y_origin;
p->brush.style = style;
g_memcpy(p->brush.pattern, pattern, 8);
return 0;
@@ -2654,7 +2837,7 @@ server_draw_line(struct xrdp_mod *mod, int x1, int y1, int x2, int y2)
/*****************************************************************************/
int DEFAULT_CC
-server_add_char(struct xrdp_mod *mod, int font, int charactor,
+server_add_char(struct xrdp_mod *mod, int font, int character,
int offset, int baseline,
int width, int height, char *data)
{
@@ -2668,7 +2851,7 @@ server_add_char(struct xrdp_mod *mod, int font, int charactor,
fi.data = data;
fi.bpp = 1;
return libxrdp_orders_send_font(((struct xrdp_wm *)mod->wm)->session,
- &fi, font, charactor);
+ &fi, font, character);
}
/*****************************************************************************/
@@ -2750,7 +2933,6 @@ int read_allowed_channel_names(struct list *names, struct list *values)
int fd;
int ret = 0;
char cfg_file[256];
- int pos;
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file);
@@ -2759,7 +2941,6 @@ int read_allowed_channel_names(struct list *names, struct list *values)
{
names->auto_free = 1;
values->auto_free = 1;
- pos = 0;
/* all values in this section can be valid channel names */
if (file_read_section(fd, "channels", names, values) == 0)
@@ -2981,7 +3162,7 @@ server_query_channel(struct xrdp_mod *mod, int index, char *channel_name,
/*****************************************************************************/
/* returns -1 on error */
int DEFAULT_CC
-server_get_channel_id(struct xrdp_mod *mod, char *name)
+server_get_channel_id(struct xrdp_mod *mod, const char *name)
{
struct xrdp_wm *wm;
@@ -3291,7 +3472,7 @@ server_monitored_desktop(struct xrdp_mod *mod,
/*****************************************************************************/
int DEFAULT_CC
-server_add_char_alpha(struct xrdp_mod* mod, int font, int charactor,
+server_add_char_alpha(struct xrdp_mod* mod, int font, int character,
int offset, int baseline,
int width, int height, char* data)
{
@@ -3305,5 +3486,5 @@ server_add_char_alpha(struct xrdp_mod* mod, int font, int charactor,
fi.data = data;
fi.bpp = 8;
return libxrdp_orders_send_font(((struct xrdp_wm*)mod->wm)->session,
- &fi, font, charactor);
+ &fi, font, character);
}
diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c
index e47f36ed..361a6a74 100644
--- a/xrdp/xrdp_painter.c
+++ b/xrdp/xrdp_painter.c
@@ -20,17 +20,152 @@
#include "xrdp.h"
+#if defined(XRDP_PAINTER)
+#include <painter.h> /* libpainter */
+#endif
+
+#define LLOG_LEVEL 1
+#define LLOGLN(_level, _args) \
+ do \
+ { \
+ if (_level < LLOG_LEVEL) \
+ { \
+ g_write("xrdp:xrdp_painter [%10.10u]: ", g_time3()); \
+ g_writeln _args ; \
+ } \
+ } \
+ while (0)
+
+#if defined(XRDP_PAINTER)
+
+/*****************************************************************************/
+static int APP_CC
+xrdp_painter_add_dirty_rect(struct xrdp_painter *self, int x, int y,
+ int cx, int cy, struct xrdp_rect *clip_rect)
+{
+ int x2;
+ int y2;
+ struct xrdp_rect rect;
+
+ if (clip_rect != 0)
+ {
+ x2 = x + cx;
+ y2 = y + cy;
+ x = MAX(x, clip_rect->left);
+ y = MAX(y, clip_rect->top);
+ x2 = MIN(x2, clip_rect->right);
+ y2 = MIN(y2, clip_rect->bottom);
+ cx = x2 - x;
+ cy = y2 - y;
+ }
+ if (cx < 1 || cy < 1)
+ {
+ return 0;
+ }
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + cx;
+ rect.bottom = y + cy;
+ xrdp_region_add_rect(self->dirty_region, &rect);
+ LLOGLN(10, ("xrdp_painter_add_dirty_rect: x %d y %d cx %d cy %d",
+ x, y, cx, cy));
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+xrdp_painter_send_dirty(struct xrdp_painter *self)
+{
+ int cx;
+ int cy;
+ int bpp;
+ int Bpp;
+ int index;
+ int jndex;
+ int error;
+ char *ldata;
+ char *src;
+ char *dst;
+ struct xrdp_rect rect;
+
+ LLOGLN(10, ("xrdp_painter_send_dirty:"));
+
+ bpp = self->wm->screen->bpp;
+ Bpp = (bpp + 7) / 8;
+ if (Bpp == 3)
+ {
+ Bpp = 4;
+ }
+
+ jndex = 0;
+ error = xrdp_region_get_rect(self->dirty_region, jndex, &rect);
+ while (error == 0)
+ {
+ cx = rect.right - rect.left;
+ cy = rect.bottom - rect.top;
+ ldata = (char *)g_malloc(cx * cy * Bpp, 0);
+ if (ldata == 0)
+ {
+ return 1;
+ }
+ src = self->wm->screen->data;
+ src += self->wm->screen->line_size * rect.top;
+ src += rect.left * Bpp;
+ dst = ldata;
+ for (index = 0; index < cy; index++)
+ {
+ g_memcpy(dst, src, cx * Bpp);
+ src += self->wm->screen->line_size;
+ dst += cx * Bpp;
+ }
+ LLOGLN(10, ("xrdp_painter_send_dirty: x %d y %d cx %d cy %d",
+ rect.left, rect.top, cx, cy));
+ libxrdp_send_bitmap(self->session, cx, cy, bpp,
+ ldata, rect.left, rect.top, cx, cy);
+ g_free(ldata);
+
+ jndex++;
+ error = xrdp_region_get_rect(self->dirty_region, jndex, &rect);
+ }
+
+ xrdp_region_delete(self->dirty_region);
+ self->dirty_region = xrdp_region_create(self->wm);
+
+ return 0;
+}
+
+#endif
+
/*****************************************************************************/
struct xrdp_painter *APP_CC
xrdp_painter_create(struct xrdp_wm *wm, struct xrdp_session *session)
{
struct xrdp_painter *self;
+ LLOGLN(10, ("xrdp_painter_create:"));
self = (struct xrdp_painter *)g_malloc(sizeof(struct xrdp_painter), 1);
self->wm = wm;
self->session = session;
- self->rop = 0xcc; /* copy gota use 0xcc*/
+ self->rop = 0xcc; /* copy will use 0xcc */
self->clip_children = 1;
+
+
+ if (self->session->client_info->no_orders_supported)
+ {
+#if defined(XRDP_PAINTER)
+ if (painter_create(&(self->painter)) != PT_ERROR_NONE)
+ {
+ self->painter = 0;
+ LLOGLN(0, ("xrdp_painter_create: painter_create failed"));
+ }
+ else
+ {
+ LLOGLN(10, ("xrdp_painter_create: painter_create success"));
+ }
+ self->dirty_region = xrdp_region_create(wm);
+#endif
+ }
+
return self;
}
@@ -38,11 +173,17 @@ xrdp_painter_create(struct xrdp_wm *wm, struct xrdp_session *session)
void APP_CC
xrdp_painter_delete(struct xrdp_painter *self)
{
+ LLOGLN(10, ("xrdp_painter_delete:"));
if (self == 0)
{
return;
}
+#if defined(XRDP_PAINTER)
+ painter_delete(self->painter);
+ xrdp_region_delete(self->dirty_region);
+#endif
+
g_free(self);
}
@@ -54,6 +195,13 @@ wm_painter_set_target(struct xrdp_painter *self)
int index;
struct list *del_list;
+ LLOGLN(10, ("wm_painter_set_target:"));
+
+ if (self->painter != 0)
+ {
+ return 0;
+ }
+
if (self->wm->target_surface->type == WND_TYPE_SCREEN)
{
if (self->wm->current_surface_index != 0xffff)
@@ -97,11 +245,19 @@ wm_painter_set_target(struct xrdp_painter *self)
int APP_CC
xrdp_painter_begin_update(struct xrdp_painter *self)
{
+ LLOGLN(10, ("xrdp_painter_begin_update:"));
if (self == 0)
{
return 0;
}
+ self->begin_end_level++;
+
+ if (self->painter != 0)
+ {
+ return 0;
+ }
+
libxrdp_orders_init(self->session);
wm_painter_set_target(self);
return 0;
@@ -111,11 +267,25 @@ xrdp_painter_begin_update(struct xrdp_painter *self)
int APP_CC
xrdp_painter_end_update(struct xrdp_painter *self)
{
+ LLOGLN(10, ("xrdp_painter_end_update:"));
if (self == 0)
{
return 0;
}
+ self->begin_end_level--;
+
+ if (self->painter != 0)
+ {
+#if defined(XRDP_PAINTER)
+ if (self->begin_end_level == 0)
+ {
+ xrdp_painter_send_dirty(self);
+ return 0;
+ }
+#endif
+ }
+
libxrdp_orders_send(self->session);
return 0;
}
@@ -262,7 +432,7 @@ xrdp_painter_rop(int rop, int src, int dst)
/*****************************************************************************/
int APP_CC
-xrdp_painter_text_width(struct xrdp_painter *self, char *text)
+xrdp_painter_text_width(struct xrdp_painter *self, const char *text)
{
int index;
int rv;
@@ -270,6 +440,7 @@ xrdp_painter_text_width(struct xrdp_painter *self, char *text)
struct xrdp_font_char *font_item;
twchar *wstr;
+ LLOGLN(10, ("xrdp_painter_text_width:"));
xrdp_painter_font_needed(self);
if (self->font == 0)
@@ -299,7 +470,7 @@ xrdp_painter_text_width(struct xrdp_painter *self, char *text)
/*****************************************************************************/
int APP_CC
-xrdp_painter_text_height(struct xrdp_painter *self, char *text)
+xrdp_painter_text_height(struct xrdp_painter *self, const char *text)
{
int index;
int rv;
@@ -307,6 +478,7 @@ xrdp_painter_text_height(struct xrdp_painter *self, char *text)
struct xrdp_font_char *font_item;
twchar *wstr;
+ LLOGLN(10, ("xrdp_painter_text_height:"));
xrdp_painter_font_needed(self);
if (self->font == 0)
@@ -342,6 +514,13 @@ xrdp_painter_setup_brush(struct xrdp_painter *self,
{
int cache_id;
+ LLOGLN(10, ("xrdp_painter_setup_brush:"));
+
+ if (self->painter != 0)
+ {
+ return 0;
+ }
+
g_memcpy(out_brush, in_brush, sizeof(struct xrdp_brush));
if (in_brush->style == 3)
@@ -358,6 +537,38 @@ xrdp_painter_setup_brush(struct xrdp_painter *self,
return 0;
}
+#if defined(XRDP_PAINTER)
+
+/*****************************************************************************/
+static int APP_CC
+get_pt_format(struct xrdp_painter *self)
+{
+ switch (self->wm->screen->bpp)
+ {
+ case 8:
+ return PT_FORMAT_r3g3b2;
+ case 15:
+ return PT_FORMAT_a1r5g5b5;
+ case 16:
+ return PT_FORMAT_r5g6b5;
+ }
+ return PT_FORMAT_a8r8g8b8;
+}
+
+/*****************************************************************************/
+static int
+get_rgb_from_rdp_color(struct xrdp_painter *self, int rdp_color)
+{
+ if (self->wm->screen->bpp < 24)
+ {
+ return rdp_color;
+ }
+ /* well, this is really BGR2RGB */
+ return XR_RGB2BGR(rdp_color);
+}
+
+#endif
+
/*****************************************************************************/
/* fill in an area of the screen with one color */
int APP_CC
@@ -375,11 +586,120 @@ xrdp_painter_fill_rect(struct xrdp_painter *self,
int dy;
int rop;
+ LLOGLN(10, ("xrdp_painter_fill_rect:"));
+
if (self == 0)
{
return 0;
}
+ dx = 0;
+ dy = 0;
+
+ if (self->painter != 0)
+ {
+#if defined(XRDP_PAINTER)
+ struct painter_bitmap dst_pb;
+ struct xrdp_bitmap *ldst;
+ struct painter_bitmap pat;
+
+ LLOGLN(10, ("xrdp_painter_fill_rect: dst->type %d", dst->type));
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ LLOGLN(10, ("xrdp_painter_fill_rect: using painter"));
+
+ ldst = self->wm->screen;
+
+ g_memset(&dst_pb, 0, sizeof(dst_pb));
+ dst_pb.format = get_pt_format(self);
+ dst_pb.width = ldst->width;
+ dst_pb.stride_bytes = ldst->line_size;
+ dst_pb.height = ldst->height;
+ dst_pb.data = ldst->data;
+
+ LLOGLN(10, ("xrdp_painter_fill_rect: ldst->width %d ldst->height %d "
+ "dst->data %p self->fg_color %d",
+ ldst->width, ldst->height, ldst->data, self->fg_color));
+
+ xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
+ region = xrdp_region_create(self->wm);
+ xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, region,
+ self->clip_children);
+ x += dx;
+ y += dy;
+
+ rop = self->rop;
+ switch (self->rop)
+ {
+ case 0x5a:
+ rop = PT_ROP_DSx;
+ break;
+ case 0xf0:
+ rop = PT_ROP_S;
+ break;
+ case 0xfb:
+ rop = PT_ROP_D;
+ break;
+ case 0xc0:
+ rop = PT_ROP_DSa;
+ break;
+ }
+ painter_set_rop(self->painter, rop);
+
+ if (self->mix_mode == 0)
+ {
+ painter_set_pattern_mode(self->painter, PT_PATTERN_MODE_OPAQUE);
+ painter_set_fgcolor(self->painter, get_rgb_from_rdp_color(self, self->fg_color));
+ k = 0;
+ while (xrdp_region_get_rect(region, k, &rect) == 0)
+ {
+ if (rect_intersect(&rect, &clip_rect, &draw_rect))
+ {
+ painter_set_clip(self->painter,
+ draw_rect.left, draw_rect.top,
+ draw_rect.right - draw_rect.left,
+ draw_rect.bottom - draw_rect.top);
+ painter_fill_rect(self->painter, &dst_pb, x, y, cx, cy);
+ xrdp_painter_add_dirty_rect(self, x, y, cx, cy, &draw_rect);
+ }
+ k++;
+ }
+ }
+ else
+ {
+ painter_set_pattern_mode(self->painter, PT_PATTERN_MODE_OPAQUE);
+ painter_set_fgcolor(self->painter, get_rgb_from_rdp_color(self, self->fg_color));
+ painter_set_bgcolor(self->painter, get_rgb_from_rdp_color(self, self->bg_color));
+ painter_set_pattern_origin(self->painter, self->brush.x_origin, self->brush.y_origin);
+ g_memset(&pat, 0, sizeof(pat));
+ pat.format = PT_FORMAT_c1;
+ pat.width = 8;
+ pat.stride_bytes = 1;
+ pat.height = 8;
+ pat.data = self->brush.pattern;
+ k = 0;
+ while (xrdp_region_get_rect(region, k, &rect) == 0)
+ {
+ if (rect_intersect(&rect, &clip_rect, &draw_rect))
+ {
+ painter_set_clip(self->painter,
+ draw_rect.left, draw_rect.top,
+ draw_rect.right - draw_rect.left,
+ draw_rect.bottom - draw_rect.top);
+ painter_fill_pattern(self->painter, &dst_pb, &pat,
+ x, y, x, y, cx, cy);
+ xrdp_painter_add_dirty_rect(self, x, y, cx, cy, &draw_rect);
+ }
+ k++;
+ }
+ }
+ painter_clear_clip(self->painter);
+ xrdp_region_delete(region);
+ }
+ return 0;
+#endif
+ }
+
/* todo data */
if (dst->type == WND_TYPE_BITMAP) /* 0 */
@@ -508,11 +828,14 @@ xrdp_painter_draw_text(struct xrdp_painter *self,
struct xrdp_font_char *font_item;
twchar *wstr;
+ LLOGLN(10, ("xrdp_painter_draw_text:"));
+
if (self == 0)
{
return 0;
}
+
len = g_mbstowcs(0, text, 0);
if (len < 1)
@@ -534,6 +857,88 @@ xrdp_painter_draw_text(struct xrdp_painter *self,
return 0;
}
+ if (self->painter != 0)
+ {
+#if defined(XRDP_PAINTER)
+ struct painter_bitmap pat;
+ struct painter_bitmap dst_pb;
+ struct xrdp_bitmap *ldst;
+
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ ldst = self->wm->screen;
+ /* convert to wide char */
+ wstr = (twchar *)g_malloc((len + 2) * sizeof(twchar), 0);
+ g_mbstowcs(wstr, text, len + 1);
+ font = self->font;
+ total_width = 0;
+ total_height = 0;
+ for (index = 0; index < len; index++)
+ {
+ font_item = font->font_items + wstr[index];
+ k = font_item->incby;
+ total_width += k;
+ total_height = MAX(total_height, font_item->height);
+ }
+ xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
+ region = xrdp_region_create(self->wm);
+ xrdp_wm_get_vis_region(self->wm, dst, x, y,
+ total_width, total_height,
+ region, self->clip_children);
+ x += dx;
+ y += dy;
+ g_memset(&dst_pb, 0, sizeof(dst_pb));
+ dst_pb.format = get_pt_format(self);
+ dst_pb.width = ldst->width;
+ dst_pb.stride_bytes = ldst->line_size;
+ dst_pb.height = ldst->height;
+ dst_pb.data = ldst->data;
+ painter_set_rop(self->painter, PT_ROP_S);
+ painter_set_pattern_origin(self->painter, 0, 0);
+ painter_set_pattern_mode(self->painter, PT_PATTERN_MODE_NORMAL);
+ painter_set_fgcolor(self->painter,
+ get_rgb_from_rdp_color(self, self->fg_color));
+ k = 0;
+ while (xrdp_region_get_rect(region, k, &rect) == 0)
+ {
+ if (rect_intersect(&rect, &clip_rect, &draw_rect))
+ {
+ painter_set_clip(self->painter,
+ draw_rect.left, draw_rect.top,
+ draw_rect.right - draw_rect.left,
+ draw_rect.bottom - draw_rect.top);
+ for (index = 0; index < len; index++)
+ {
+ font_item = font->font_items + wstr[index];
+ g_memset(&pat, 0, sizeof(pat));
+ pat.format = PT_FORMAT_c1;
+ pat.width = font_item->width;
+ pat.stride_bytes = (font_item->width + 7) / 8;
+ pat.height = font_item->height;
+ pat.data = font_item->data;
+ x1 = x + font_item->offset;
+ y1 = y + (font_item->height + font_item->baseline);
+ painter_fill_pattern(self->painter, &dst_pb, &pat,
+ 0, 0, x1, y1,
+ font_item->width,
+ font_item->height);
+ xrdp_painter_add_dirty_rect(self, x, y,
+ font_item->width,
+ font_item->height,
+ &draw_rect);
+ x += font_item->incby;
+ }
+ }
+ k++;
+ }
+ painter_clear_clip(self->painter);
+ xrdp_region_delete(region);
+ g_free(wstr);
+ }
+ return 0;
+#endif
+ }
+
/* convert to wide char */
wstr = (twchar *)g_malloc((len + 2) * sizeof(twchar), 0);
g_mbstowcs(wstr, text, len + 1);
@@ -616,11 +1021,18 @@ xrdp_painter_draw_text2(struct xrdp_painter *self,
int dx;
int dy;
+ LLOGLN(0, ("xrdp_painter_draw_text2:"));
+
if (self == 0)
{
return 0;
}
+ if (self->painter != 0)
+ {
+ return 0;
+ }
+
/* todo data */
if (dst->type == WND_TYPE_BITMAP)
@@ -711,11 +1123,76 @@ xrdp_painter_copy(struct xrdp_painter *self,
int index;
struct list *del_list;
+ LLOGLN(10, ("xrdp_painter_copy:"));
+
if (self == 0 || src == 0 || dst == 0)
{
return 0;
}
+ if (self->painter != 0)
+ {
+#if defined(XRDP_PAINTER)
+ struct painter_bitmap src_pb;
+ struct painter_bitmap dst_pb;
+ struct xrdp_bitmap *ldst;
+
+ LLOGLN(10, ("xrdp_painter_copy: src->type %d dst->type %d", src->type, dst->type));
+ LLOGLN(10, ("xrdp_painter_copy: self->rop 0x%2.2x", self->rop));
+
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ LLOGLN(10, ("xrdp_painter_copy: using painter"));
+ ldst = self->wm->screen;
+
+ g_memset(&dst_pb, 0, sizeof(dst_pb));
+ dst_pb.format = get_pt_format(self);
+ dst_pb.width = ldst->width;
+ dst_pb.stride_bytes = ldst->line_size;
+ dst_pb.height = ldst->height;
+ dst_pb.data = ldst->data;
+
+ g_memset(&src_pb, 0, sizeof(src_pb));
+ src_pb.format = get_pt_format(self);
+ src_pb.width = src->width;
+ src_pb.stride_bytes = src->line_size;
+ src_pb.height = src->height;
+ src_pb.data = src->data;
+
+ xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
+ region = xrdp_region_create(self->wm);
+ xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, region,
+ self->clip_children);
+ x += dx;
+ y += dy;
+ k = 0;
+
+ painter_set_rop(self->painter, self->rop);
+ while (xrdp_region_get_rect(region, k, &rect1) == 0)
+ {
+ if (rect_intersect(&rect1, &clip_rect, &draw_rect))
+ {
+ painter_set_clip(self->painter,
+ draw_rect.left, draw_rect.top,
+ draw_rect.right - draw_rect.left,
+ draw_rect.bottom - draw_rect.top);
+ LLOGLN(10, (" x %d y %d cx %d cy %d srcx %d srcy %d",
+ x, y, cx, cy, srcx, srcy));
+ painter_copy(self->painter, &dst_pb, x, y, cx, cy,
+ &src_pb, srcx, srcy);
+ xrdp_painter_add_dirty_rect(self, x, y, cx, cy,
+ &draw_rect);
+ }
+ k++;
+ }
+ painter_clear_clip(self->painter);
+ xrdp_region_delete(region);
+ }
+
+ return 0;
+#endif
+ }
+
/* todo data */
if (dst->type == WND_TYPE_BITMAP)
@@ -848,7 +1325,7 @@ xrdp_painter_copy(struct xrdp_painter *self,
while (i < (srcx + cx))
{
w = MIN(64, ((srcx + cx) - i));
- h = MIN(63, ((srcy + cy) - j));
+ h = MIN(64, ((srcy + cy) - j));
b = xrdp_bitmap_create(w, h, src->bpp, 0, self->wm);
#if 1
xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h);
@@ -883,7 +1360,7 @@ xrdp_painter_copy(struct xrdp_painter *self,
i += 64;
}
- j += 63;
+ j += 64;
}
xrdp_region_delete(region);
@@ -915,15 +1392,21 @@ xrdp_painter_composite(struct xrdp_painter* self,
int k;
int dx;
int dy;
- int palette_id;
int cache_srcidx;
int cache_mskidx;
+ LLOGLN(0, ("xrdp_painter_composite:"));
+
if (self == 0 || src == 0 || dst == 0)
{
return 0;
}
+ if (self->painter != 0)
+ {
+ return 0;
+ }
+
/* todo data */
if (dst->type == WND_TYPE_BITMAP)
@@ -939,7 +1422,6 @@ xrdp_painter_composite(struct xrdp_painter* self,
dstx += dx;
dsty += dy;
- palette_id = 0;
cache_srcidx = src->item_index;
cache_mskidx = -1;
if (mskflags & 1)
@@ -987,10 +1469,75 @@ xrdp_painter_line(struct xrdp_painter *self,
int dy;
int rop;
+ LLOGLN(10, ("xrdp_painter_line:"));
if (self == 0)
{
return 0;
}
+ if (self->painter != 0)
+ {
+#if defined(XRDP_PAINTER)
+ int x;
+ int y;
+ int cx;
+ int cy;
+ struct painter_bitmap dst_pb;
+ struct xrdp_bitmap *ldst;
+
+ LLOGLN(10, ("xrdp_painter_line: dst->type %d", dst->type));
+ LLOGLN(10, ("xrdp_painter_line: self->rop 0x%2.2x", self->rop));
+
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ LLOGLN(10, ("xrdp_painter_line: using painter"));
+ ldst = self->wm->screen;
+
+ g_memset(&dst_pb, 0, sizeof(dst_pb));
+ dst_pb.format = get_pt_format(self);
+ dst_pb.width = ldst->width;
+ dst_pb.stride_bytes = ldst->line_size;
+ dst_pb.height = ldst->height;
+ dst_pb.data = ldst->data;
+
+ xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
+ region = xrdp_region_create(self->wm);
+ x = MIN(x1, x2);
+ y = MIN(y1, y2);
+ cx = g_abs(x1 - x2) + 1;
+ cy = g_abs(y1 - y2) + 1;
+ xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy,
+ region, self->clip_children);
+ x1 += dx;
+ y1 += dy;
+ x2 += dx;
+ y2 += dy;
+ k = 0;
+ rop = self->rop;
+
+ painter_set_rop(self->painter, rop);
+ painter_set_fgcolor(self->painter, self->pen.color);
+ while (xrdp_region_get_rect(region, k, &rect) == 0)
+ {
+ if (rect_intersect(&rect, &clip_rect, &draw_rect))
+ {
+ painter_set_clip(self->painter,
+ draw_rect.left, draw_rect.top,
+ draw_rect.right - draw_rect.left,
+ draw_rect.bottom - draw_rect.top);
+ painter_line(self->painter, &dst_pb, x1, y1, x2, x2,
+ self->pen.width, 0);
+ xrdp_painter_add_dirty_rect(self, x, y, cx, cy,
+ &draw_rect);
+ }
+ k++;
+ }
+ painter_clear_clip(self->painter);
+ xrdp_region_delete(region);
+ }
+
+ return 0;
+#endif
+ }
/* todo data */
diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c
index 5a7cd1d8..45e2acc6 100644
--- a/xrdp/xrdp_process.c
+++ b/xrdp/xrdp_process.c
@@ -138,13 +138,43 @@ xrdp_process_data_in(struct trans *self)
}
if (pro->session->up_and_running)
{
+ pro->server_trans->header_size = 2;
pro->server_trans->extra_flags = 1;
- pro->server_trans->header_size = 4;
init_stream(s, 0);
}
break;
case 1:
+ /* we got 2 bytes */
+ if (s->p[0] == 3)
+ {
+ pro->server_trans->header_size = 4;
+ pro->server_trans->extra_flags = 2;
+ }
+ else
+ {
+ if (s->p[1] & 0x80)
+ {
+ pro->server_trans->header_size = 3;
+ pro->server_trans->extra_flags = 2;
+ }
+ else
+ {
+ len = (tui8)(s->p[1]);
+ pro->server_trans->header_size = len;
+ pro->server_trans->extra_flags = 3;
+ }
+ }
+
+ len = (int) (s->end - s->data);
+ if (pro->server_trans->header_size > len)
+ {
+ /* not enough data read yet */
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case 2:
/* we have enough now to get the PDU bytes */
len = libxrdp_get_pdu_bytes(s->p);
if (len == -1)
@@ -154,10 +184,17 @@ xrdp_process_data_in(struct trans *self)
return 1;
}
pro->server_trans->header_size = len;
- pro->server_trans->extra_flags = 2;
- break;
+ pro->server_trans->extra_flags = 3;
- case 2:
+ len = (int) (s->end - s->data);
+ if (pro->server_trans->header_size > len)
+ {
+ /* not enough data read yet */
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case 3:
/* the whole PDU is read in now process */
s->p = s->data;
if (xrdp_process_loop(pro, s) != 0)
@@ -167,7 +204,7 @@ xrdp_process_data_in(struct trans *self)
return 1;
}
init_stream(s, 0);
- pro->server_trans->header_size = 4;
+ pro->server_trans->header_size = 2;
pro->server_trans->extra_flags = 1;
break;
}
@@ -195,12 +232,14 @@ xrdp_process_main_loop(struct xrdp_process *self)
self->server_trans->callback_data = self;
init_stream(self->server_trans->in_s, 8192 * 4);
self->session = libxrdp_init((tbus)self, self->server_trans);
+ self->server_trans->si = &(self->session->si);
+ self->server_trans->my_source = XRDP_SOURCE_CLIENT;
/* this callback function is in xrdp_wm.c */
self->session->callback = callback;
/* this function is just above */
self->session->is_term = xrdp_is_term;
- if (libxrdp_process_incomming(self->session) == 0)
+ if (libxrdp_process_incoming(self->session) == 0)
{
init_stream(self->server_trans->in_s, 32 * 1024);
@@ -217,8 +256,8 @@ xrdp_process_main_loop(struct xrdp_process *self)
robjs[robjs_count++] = self->self_term_event;
xrdp_wm_get_wait_objs(self->wm, robjs, &robjs_count,
wobjs, &wobjs_count, &timeout);
- trans_get_wait_objs(self->server_trans, robjs, &robjs_count);
-
+ trans_get_wait_objs_rw(self->server_trans, robjs, &robjs_count,
+ wobjs, &wobjs_count, &timeout);
/* wait */
if (g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout) != 0)
{
@@ -251,7 +290,7 @@ xrdp_process_main_loop(struct xrdp_process *self)
}
else
{
- g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed");
+ g_writeln("xrdp_process_main_loop: libxrdp_process_incoming failed");
/* this will try to send a disconnect,
maybe should check that connection got far enough */
libxrdp_disconnect(self->session);
diff --git a/xrdp/xrdp_region.c b/xrdp/xrdp_region.c
index c9b6a820..4da30f9d 100644
--- a/xrdp/xrdp_region.c
+++ b/xrdp/xrdp_region.c
@@ -20,6 +20,12 @@
#include "xrdp.h"
+#if defined(XRDP_PIXMAN)
+#include <pixman.h>
+#else
+#include "pixman-region.h"
+#endif
+
/*****************************************************************************/
struct xrdp_region *APP_CC
xrdp_region_create(struct xrdp_wm *wm)
@@ -28,8 +34,9 @@ xrdp_region_create(struct xrdp_wm *wm)
self = (struct xrdp_region *)g_malloc(sizeof(struct xrdp_region), 1);
self->wm = wm;
- self->rects = list_create();
- self->rects->auto_free = 1;
+ self->reg = (struct pixman_region16 *)
+ g_malloc(sizeof(struct pixman_region16), 1);
+ pixman_region_init(self->reg);
return self;
}
@@ -41,276 +48,86 @@ xrdp_region_delete(struct xrdp_region *self)
{
return;
}
-
- list_delete(self->rects);
+ pixman_region_fini(self->reg);
+ g_free(self->reg);
g_free(self);
}
/*****************************************************************************/
+/* returns error */
int APP_CC
xrdp_region_add_rect(struct xrdp_region *self, struct xrdp_rect *rect)
{
- struct xrdp_rect *r;
+ struct pixman_region16 lreg;
- r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1);
- *r = *rect;
- list_add_item(self->rects, (long)r);
+ pixman_region_init_rect(&lreg, rect->left, rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top);
+ if (!pixman_region_union(self->reg, self->reg, &lreg))
+ {
+ pixman_region_fini(&lreg);
+ return 1;
+ }
+ pixman_region_fini(&lreg);
return 0;
}
/*****************************************************************************/
+/* returns error */
int APP_CC
-xrdp_region_insert_rect(struct xrdp_region *self, int i, int left,
- int top, int right, int bottom)
+xrdp_region_subtract_rect(struct xrdp_region *self, struct xrdp_rect *rect)
{
- struct xrdp_rect *r;
+ struct pixman_region16 lreg;
- r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1);
- r->left = left;
- r->top = top;
- r->right = right;
- r->bottom = bottom;
- list_insert_item(self->rects, i, (long)r);
+ pixman_region_init_rect(&lreg, rect->left, rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top);
+ if (!pixman_region_subtract(self->reg, self->reg, &lreg))
+ {
+ pixman_region_fini(&lreg);
+ return 1;
+ }
+ pixman_region_fini(&lreg);
return 0;
}
/*****************************************************************************/
+/* returns error */
int APP_CC
-xrdp_region_subtract_rect(struct xrdp_region *self,
- struct xrdp_rect *rect)
+xrdp_region_intersect_rect(struct xrdp_region* self, struct xrdp_rect* rect)
{
- struct xrdp_rect *r;
- struct xrdp_rect rect1;
- int i;
+ struct pixman_region16 lreg;
- for (i = self->rects->count - 1; i >= 0; i--)
+ pixman_region_init_rect(&lreg, rect->left, rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top);
+ if (!pixman_region_intersect(self->reg, self->reg, &lreg))
{
- r = (struct xrdp_rect *)list_get_item(self->rects, i);
- rect1 = *r;
- r = &rect1;
-
- if (rect->left <= r->left &&
- rect->top <= r->top &&
- rect->right >= r->right &&
- rect->bottom >= r->bottom)
- {
- /* rect is not visible */
- list_remove_item(self->rects, i);
- }
- else if (rect->right < r->left ||
- rect->bottom < r->top ||
- rect->top > r->bottom ||
- rect->left > r->right)
- {
- /* rect are not related */
- }
- else if (rect->left <= r->left &&
- rect->right >= r->right &&
- rect->bottom < r->bottom &&
- rect->top <= r->top)
- {
- /* partially covered(whole top) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->top <= r->top &&
- rect->bottom >= r->bottom &&
- rect->right < r->right &&
- rect->left <= r->left)
- {
- /* partially covered(left) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, r->bottom);
- }
- else if (rect->left <= r->left &&
- rect->right >= r->right &&
- rect->top > r->top &&
- rect->bottom >= r->bottom)
- {
- /* partially covered(bottom) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- }
- else if (rect->top <= r->top &&
- rect->bottom >= r->bottom &&
- rect->left > r->left &&
- rect->right >= r->right)
- {
- /* partially covered(right) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- }
- else if (rect->left <= r->left &&
- rect->top <= r->top &&
- rect->right < r->right &&
- rect->bottom < r->bottom)
- {
- /* partially covered(top left) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, rect->bottom);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left <= r->left &&
- rect->bottom >= r->bottom &&
- rect->right < r->right &&
- rect->top > r->top)
- {
- /* partially covered(bottom left) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, rect->right, rect->top,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->right >= r->right &&
- rect->top <= r->top &&
- rect->bottom < r->bottom)
- {
- /* partially covered(top right) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- xrdp_region_insert_rect(self, i, rect->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->right >= r->right &&
- rect->top > r->top &&
- rect->bottom >= r->bottom)
- {
- /* partially covered(bottom right) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, r->left, rect->top,
- rect->left, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->top <= r->top &&
- rect->right < r->right &&
- rect->bottom >= r->bottom)
- {
- /* 2 rects, one on each end */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, r->bottom);
- }
- else if (rect->left <= r->left &&
- rect->top > r->top &&
- rect->right >= r->right &&
- rect->bottom < r->bottom)
- {
- /* 2 rects, one on each end */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->right < r->right &&
- rect->top <= r->top &&
- rect->bottom < r->bottom)
- {
- /* partially covered(top) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- xrdp_region_insert_rect(self, i, rect->left, rect->bottom,
- rect->right, r->bottom);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, r->bottom);
- }
- else if (rect->top > r->top &&
- rect->bottom < r->bottom &&
- rect->left <= r->left &&
- rect->right < r->right)
- {
- /* partially covered(left) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, rect->right, rect->top,
- r->right, rect->bottom);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->right < r->right &&
- rect->bottom >= r->bottom &&
- rect->top > r->top)
- {
- /* partially covered(bottom) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- xrdp_region_insert_rect(self, i, rect->left, r->top,
- rect->right, rect->top);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, r->bottom);
- }
- else if (rect->top > r->top &&
- rect->bottom < r->bottom &&
- rect->right >= r->right &&
- rect->left > r->left)
- {
- /* partially covered(right) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, r->left, rect->top,
- rect->left, rect->bottom);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->top > r->top &&
- rect->right < r->right &&
- rect->bottom < r->bottom)
- {
- /* totally contained, 4 rects */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, r->left, rect->top,
- rect->left, rect->bottom);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- xrdp_region_insert_rect(self, i, rect->right, rect->top,
- r->right, rect->bottom);
- }
- else
- {
- g_writeln("error in xrdp_region_subtract_rect");
- }
+ pixman_region_fini(&lreg);
+ return 1;
}
-
+ pixman_region_fini(&lreg);
return 0;
}
+
/*****************************************************************************/
+/* returns error */
int APP_CC
xrdp_region_get_rect(struct xrdp_region *self, int index,
struct xrdp_rect *rect)
{
- struct xrdp_rect *r;
+ struct pixman_box16 *box;
+ int count;
- r = (struct xrdp_rect *)list_get_item(self->rects, index);
-
- if (r == 0)
+ box = pixman_region_rectangles(self->reg, &count);
+ if ((box != 0) && (index >= 0) && (index < count))
{
- return 1;
+ rect->left = box[index].x1;
+ rect->top = box[index].y1;
+ rect->right = box[index].x2;
+ rect->bottom = box[index].y2;
+ return 0;
}
-
- *rect = *r;
- return 0;
+ return 1;
}
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index 29aaac84..cc0eaa3c 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -42,14 +42,14 @@ struct xrdp_mod
long param3, long param4);
int (*mod_signal)(struct xrdp_mod* v);
int (*mod_end)(struct xrdp_mod* v);
- int (*mod_set_param)(struct xrdp_mod* v, char* name, char* value);
+ int (*mod_set_param)(struct xrdp_mod* v, const char *name, char* value);
int (*mod_session_change)(struct xrdp_mod* v, int, int);
int (*mod_get_wait_objs)(struct xrdp_mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct xrdp_mod* v);
int (*mod_frame_ack)(struct xrdp_mod* v, int flags, int frame_id);
- long mod_dumby[100 - 10]; /* align, 100 minus the number of mod
- functions above */
+ tintptr mod_dumby[100 - 10]; /* align, 100 minus the number of mod
+ functions above */
/* server functions */
int (*server_begin_update)(struct xrdp_mod* v);
int (*server_end_update)(struct xrdp_mod* v);
@@ -70,12 +70,12 @@ struct xrdp_mod
int (*server_set_bgcolor)(struct xrdp_mod* v, int bgcolor);
int (*server_set_opcode)(struct xrdp_mod* v, int opcode);
int (*server_set_mixmode)(struct xrdp_mod* v, int mixmode);
- int (*server_set_brush)(struct xrdp_mod* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct xrdp_mod* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct xrdp_mod* v, int style,
int width);
int (*server_draw_line)(struct xrdp_mod* v, int x1, int y1, int x2, int y2);
- int (*server_add_char)(struct xrdp_mod* v, int font, int charactor,
+ int (*server_add_char)(struct xrdp_mod* v, int font, int character,
int offset, int baseline,
int width, int height, char* data);
int (*server_draw_text)(struct xrdp_mod* v, int font,
@@ -88,7 +88,7 @@ struct xrdp_mod
int (*server_query_channel)(struct xrdp_mod* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct xrdp_mod* v, char* name);
+ int (*server_get_channel_id)(struct xrdp_mod* v, const char *name);
int (*server_send_to_channel)(struct xrdp_mod* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
@@ -125,7 +125,7 @@ struct xrdp_mod
int flags);
int (*server_set_pointer_ex)(struct xrdp_mod* v, int x, int y, char* data,
char* mask, int bpp);
- int (*server_add_char_alpha)(struct xrdp_mod* mod, int font, int charactor,
+ int (*server_add_char_alpha)(struct xrdp_mod* mod, int font, int character,
int offset, int baseline,
int width, int height, char* data);
@@ -146,13 +146,13 @@ struct xrdp_mod
int num_crects, short *crects,
char *data, int width, int height,
int flags, int frame_id);
- long server_dumby[100 - 43]; /* align, 100 minus the number of server
- functions above */
+ tintptr server_dumby[100 - 43]; /* align, 100 minus the number of server
+ functions above */
/* common */
- long handle; /* pointer to self as int */
- long wm; /* struct xrdp_wm* */
- long painter;
- int sck;
+ tintptr handle; /* pointer to self as int */
+ tintptr wm; /* struct xrdp_wm* */
+ tintptr painter;
+ tintptr si;
};
/* header for bmp file */
@@ -216,14 +216,14 @@ struct xrdp_brush_item
{
int stamp;
/* expand this to a structure to handle more complicated brushes
- for now its 8x8 1bpp brushes only */
+ for now it's 8x8 1bpp brushes only */
char pattern[8];
};
/* moved to xrdp_constants.h
#define XRDP_BITMAP_CACHE_ENTRIES 2048 */
-/* differnce caches */
+/* difference caches */
struct xrdp_cache
{
struct xrdp_wm* wm; /* owner */
@@ -292,19 +292,7 @@ struct xrdp_mm
int chan_trans_up; /* true once connected to chansrv */
int delete_chan_trans; /* boolean set when done with channel connection */
int usechansrv; /* true if chansrvport is set in xrdp.ini or using sesman */
-
- /* for codec mode operations */
- int in_codec_mode;
- int codec_id;
- int codec_quality;
- tbus xrdp_encoder_event_to_proc;
- tbus xrdp_encoder_event_processed;
- tbus xrdp_encoder_term;
- FIFO *fifo_to_proc;
- FIFO *fifo_processed;
- tbus mutex;
- int (*process_enc)(struct xrdp_mm *self, struct xrdp_enc_data *enc);
- void *codec_handle;
+ struct xrdp_encoder *encoder;
};
struct xrdp_key_info
@@ -423,7 +411,7 @@ struct xrdp_listen
struct xrdp_region
{
struct xrdp_wm* wm; /* owner */
- struct list* rects;
+ struct pixman_region16 *reg;
};
/* painter */
@@ -441,6 +429,9 @@ struct xrdp_painter
struct xrdp_session* session;
struct xrdp_wm* wm; /* owner */
struct xrdp_font* font;
+ void *painter;
+ struct xrdp_region *dirty_region;
+ int begin_end_level;
};
/* window or bitmap */
@@ -604,7 +595,7 @@ struct xrdp_cfg_globals
int ls_btn_cancel_y_pos; /* y pos for Cancel button */
int ls_btn_cancel_width; /* width of Cancel button */
int ls_btn_cancel_height; /* height of Cancel button */
- char ls_title[256]; /* loginscreen window title */
+ char ls_title[256]; /* loginscreen window title */
};
struct xrdp_cfg_logging
@@ -624,39 +615,4 @@ struct xrdp_config
struct xrdp_cfg_channels cfg_channels;
};
-/* used when scheduling tasks in xrdp_encoder.c */
-struct xrdp_enc_data
-{
- struct xrdp_mod *mod;
- int num_drects;
- short *drects; /* 4 * num_drects */
- int num_crects;
- short *crects; /* 4 * num_crects */
- char *data;
- int width;
- int height;
- int flags;
- int frame_id;
-};
-
-typedef struct xrdp_enc_data XRDP_ENC_DATA;
-
-/* used when scheduling tasks from xrdp_encoder.c */
-struct xrdp_enc_data_done
-{
- int comp_bytes;
- int pad_bytes;
- char *comp_pad_data;
- struct xrdp_enc_data *enc;
- int last; /* true is this is last message for enc */
- int x;
- int y;
- int cx;
- int cy;
-};
-
-typedef struct xrdp_enc_data_done XRDP_ENC_DATA_DONE;
-
-
-
#endif
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index 591c8a51..065bca5c 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -18,6 +18,8 @@
* simple window manager
*/
+#include <stdarg.h>
+#include <stdio.h>
#include "xrdp.h"
#include "log.h"
@@ -45,7 +47,7 @@ xrdp_wm_create(struct xrdp_process *owner,
pid = g_getpid();
g_snprintf(event_name, 255, "xrdp_%8.8x_wm_login_mode_event_%8.8x",
pid, owner->session_id);
- log_message(LOG_LEVEL_DEBUG,event_name);
+ log_message(LOG_LEVEL_DEBUG, "%s", event_name);
self->login_mode_event = g_create_wait_obj(event_name);
self->painter = xrdp_painter_create(self, self->session);
self->cache = xrdp_cache_create(self, self->session, self->client_info);
@@ -60,7 +62,7 @@ xrdp_wm_create(struct xrdp_process *owner,
self->current_surface_index = 0xffff; /* screen */
/* to store configuration from xrdp.ini */
- self->xrdp_config = g_malloc(sizeof(struct xrdp_config), 1);
+ self->xrdp_config = g_new0(struct xrdp_config, 1);
return self;
}
@@ -546,7 +548,7 @@ xrdp_wm_init(struct xrdp_wm *self)
struct list *names;
struct list *values;
char *q;
- char *r;
+ const char *r;
char param[256];
char section_name[256];
char cfg_file[256];
@@ -560,7 +562,7 @@ xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_load_static_pointers(self);
self->screen->bg_color = self->xrdp_config->cfg_globals.ls_top_window_bg_color;
- if (self->session->client_info->rdp_autologin)
+ if (self->session->client_info->rdp_autologin || self->hide_log_window)
{
/*
* NOTE: this should eventually be accessed from self->xrdp_config
@@ -576,11 +578,13 @@ xrdp_wm_init(struct xrdp_wm *self)
values->auto_free = 1;
/* look for module name to be loaded */
- if (autorun_name[0] != 0) {
+ if (autorun_name[0] != 0)
+ {
/* if autorun is configured in xrdp.ini, we enforce that module to be loaded */
g_strncpy(section_name, autorun_name, 255);
}
- else if (self->session->client_info->domain[0] != '_')
+ else if (self->session->client_info->domain[0] != '\0' &&
+ self->session->client_info->domain[0] != '_')
{
/* domain names that starts with '_' are reserved for IP/DNS to
* simplify for the user in a proxy setup */
@@ -593,9 +597,9 @@ xrdp_wm_init(struct xrdp_wm *self)
{
/* if no domain is passed, and no autorun in xrdp.ini,
use the first item in the xrdp.ini
- file thats not named
+ file that's not named
'globals' or 'Logging' or 'channels' */
- /* TODO: change this and have a 'autologin'
+ /* TODO: change this and have an 'autologin'
line in globals section */
file_read_sections(fd, names);
for (index = 0; index < names->count; index++)
@@ -676,9 +680,9 @@ xrdp_wm_init(struct xrdp_wm *self)
else
{
/* requested module name not found in xrdp.ini */
- g_writeln(" xrdp_wm_init: file_read_section returned non-zero, requested section not found in xrdp.ini");
- xrdp_wm_log_msg(self, "ERROR: The requested xrdp module not found in xrdp.ini,"
- " falling back to login window");
+ xrdp_wm_log_msg(self, LOG_LEVEL_ERROR,
+ "Section \"%s\" not configured in xrdp.ini",
+ section_name);
}
list_delete(names);
@@ -809,8 +813,8 @@ xrdp_wm_xor_pat(struct xrdp_wm *self, int x, int y, int cx, int cy)
self->painter->brush.pattern[5] = 0x55;
self->painter->brush.pattern[6] = 0xaa;
self->painter->brush.pattern[7] = 0x55;
- self->painter->brush.x_orgin = 0;
- self->painter->brush.x_orgin = 0;
+ self->painter->brush.x_origin = 0;
+ self->painter->brush.x_origin = 0;
self->painter->brush.style = 3;
self->painter->bg_color = self->black;
self->painter->fg_color = self->white;
@@ -831,45 +835,7 @@ xrdp_wm_xor_pat(struct xrdp_wm *self, int x, int y, int cx, int cy)
}
/*****************************************************************************/
-/* this don't are about nothing, just copy the bits */
-/* no clipping rects, no windows in the way, nothing */
-static int APP_CC
-xrdp_wm_bitblt(struct xrdp_wm *self,
- struct xrdp_bitmap *dst, int dx, int dy,
- struct xrdp_bitmap *src, int sx, int sy,
- int sw, int sh, int rop)
-{
- // int i;
- // int line_size;
- // int Bpp;
- // char* s;
- // char* d;
-
- // if (sw <= 0 || sh <= 0)
- // return 0;
- if (self->screen == dst && self->screen == src)
- {
- /* send a screen blt */
- // Bpp = (dst->bpp + 7) / 8;
- // line_size = sw * Bpp;
- // s = src->data + (sy * src->width + sx) * Bpp;
- // d = dst->data + (dy * dst->width + dx) * Bpp;
- // for (i = 0; i < sh; i++)
- // {
- // //g_memcpy(d, s, line_size);
- // s += src->width * Bpp;
- // d += dst->width * Bpp;
- // }
- libxrdp_orders_init(self->session);
- libxrdp_orders_screen_blt(self->session, dx, dy, sw, sh, sx, sy, rop, 0);
- libxrdp_orders_send(self->session);
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-/* return true is rect is totaly exposed going in reverse z order */
+/* return true if rect is totally exposed going in reverse z order */
/* from wnd up */
static int APP_CC
xrdp_wm_is_rect_vis(struct xrdp_wm *self, struct xrdp_bitmap *wnd,
@@ -931,6 +897,7 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd,
MAKERECT(rect1, wnd->left, wnd->top, wnd->width, wnd->height);
+ self->painter->clip_children = 0;
if (xrdp_wm_is_rect_vis(self, wnd, &rect1))
{
rect2 = rect1;
@@ -938,10 +905,13 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd,
if (xrdp_wm_is_rect_vis(self, wnd, &rect2))
{
- /* if both src and dst are unobscured, we can do a bitblt move */
- xrdp_wm_bitblt(self, self->screen, wnd->left + dx, wnd->top + dy,
- self->screen, wnd->left, wnd->top,
- wnd->width, wnd->height, 0xcc);
+ xrdp_painter_begin_update(self->painter);
+ xrdp_painter_copy(self->painter, self->screen, self->screen,
+ wnd->left + dx, wnd->top + dy,
+ wnd->width, wnd->height,
+ wnd->left, wnd->top);
+ xrdp_painter_end_update(self->painter);
+
wnd->left += dx;
wnd->top += dy;
r = xrdp_region_create(self);
@@ -956,9 +926,11 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd,
}
xrdp_region_delete(r);
+ self->painter->clip_children = 1;
return 0;
}
}
+ self->painter->clip_children = 1;
wnd->left += dx;
wnd->top += dy;
@@ -967,6 +939,7 @@ xrdp_wm_move_window(struct xrdp_wm *self, struct xrdp_bitmap *wnd,
return 0;
}
+
/*****************************************************************************/
static int APP_CC
xrdp_wm_undraw_dragging_box(struct xrdp_wm *self, int do_begin_end)
@@ -1523,6 +1496,83 @@ xrdp_wm_key_sync(struct xrdp_wm *self, int device_flags, int key_flags)
/*****************************************************************************/
int APP_CC
+xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, int unicode)
+{
+ int index;
+
+ for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
+ {
+ if (unicode == self->keymap.keys_noshift[index].chr)
+ {
+ xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
+ return 0;
+ }
+ }
+
+ for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
+ {
+ if (unicode == self->keymap.keys_shift[index].chr)
+ {
+ if (device_flags & KBD_FLAG_UP)
+ {
+ xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
+ xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT);
+ }
+ else
+ {
+ xrdp_wm_key(self, KBD_FLAG_DOWN, XR_RDP_SCAN_LSHIFT);
+ xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
+ }
+ return 0;
+ }
+ }
+
+ for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
+ {
+ if (unicode == self->keymap.keys_altgr[index].chr)
+ {
+ if (device_flags & KBD_FLAG_UP)
+ {
+ xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
+ xrdp_wm_key(self, KBD_FLAG_UP | KBD_FLAG_EXT,
+ XR_RDP_SCAN_ALT);
+ }
+ else
+ {
+ xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT,
+ XR_RDP_SCAN_ALT);
+ xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
+ }
+ return 0;
+ }
+ }
+
+ for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
+ {
+ if (unicode == self->keymap.keys_shiftaltgr[index].chr)
+ {
+ if (device_flags & KBD_FLAG_UP)
+ {
+ xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
+ xrdp_wm_key(self, KBD_FLAG_UP | KBD_FLAG_EXT, XR_RDP_SCAN_ALT);
+ xrdp_wm_key(self, KBD_FLAG_UP, XR_RDP_SCAN_LSHIFT);
+ }
+ else
+ {
+ xrdp_wm_key(self, KBD_FLAG_DOWN, XR_RDP_SCAN_LSHIFT);
+ xrdp_wm_key(self, KBD_FLAG_DOWN | KBD_FLAG_EXT,
+ XR_RDP_SCAN_ALT);
+ xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
+ }
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
xrdp_wm_pu(struct xrdp_wm *self, struct xrdp_bitmap *control)
{
int x;
@@ -1687,7 +1737,7 @@ xrdp_wm_process_channel_data(struct xrdp_wm *self,
}
/******************************************************************************/
-/* this is the callbacks comming from libxrdp.so */
+/* this is the callbacks coming from libxrdp.so */
int DEFAULT_CC
callback(long id, int msg, long param1, long param2, long param3, long param4)
{
@@ -1717,6 +1767,9 @@ callback(long id, int msg, long param1, long param2, long param3, long param4)
case 4: /* RDP_INPUT_SCANCODE */
rv = xrdp_wm_key(wm, param3, param1);
break;
+ case 5: /* RDP_INPUT_UNICODE */
+ rv = xrdp_wm_key_unicode(wm, param3, param1);
+ break;
case 0x8001: /* RDP_INPUT_MOUSE */
rv = xrdp_wm_process_input_mouse(wm, param3, param1, param2);
break;
@@ -1724,8 +1777,8 @@ callback(long id, int msg, long param1, long param2, long param3, long param4)
rv = xrdp_wm_process_input_mousex(wm, param3, param1, param2);
break;
case 0x4444: /* invalidate, this is not from RDP_DATA_PDU_INPUT */
- /* like the rest, its from RDP_PDU_DATA with code 33 */
- /* its the rdp client asking for a screen update */
+ /* like the rest, it's from RDP_PDU_DATA with code 33 */
+ /* it's the rdp client asking for a screen update */
MAKERECT(rect, param1, param2, param3, param4);
rv = xrdp_bitmap_invalidate(wm->screen, &rect);
break;
@@ -1733,8 +1786,14 @@ callback(long id, int msg, long param1, long param2, long param3, long param4)
pass it to module if there is one */
rv = xrdp_wm_process_channel_data(wm, param1, param2, param3, param4);
break;
+ case 0x5556:
+ rv = xrdp_mm_check_chan(wm->mm);
+ break;
+ case 0x5557:
+ //g_writeln("callback: frame ack %d", param1);
+ xrdp_mm_frame_ack(wm->mm, param1);
+ break;
}
-
return rv;
}
@@ -1753,10 +1812,10 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
if (self->login_mode == 0)
{
- /* this is the inital state of the login window */
+ /* this is the initial state of the login window */
xrdp_wm_set_login_mode(self, 1); /* put the wm in login mode */
list_clear(self->log);
- xrdp_wm_delete_all_childs(self);
+ xrdp_wm_delete_all_children(self);
self->dragging = 0;
xrdp_wm_init(self);
}
@@ -1765,7 +1824,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
if (xrdp_mm_connect(self->mm) == 0)
{
xrdp_wm_set_login_mode(self, 3); /* put the wm in connected mode */
- xrdp_wm_delete_all_childs(self);
+ xrdp_wm_delete_all_children(self);
self->dragging = 0;
}
else
@@ -1775,7 +1834,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
}
else if (self->login_mode == 10)
{
- xrdp_wm_delete_all_childs(self);
+ xrdp_wm_delete_all_children(self);
self->dragging = 0;
xrdp_wm_set_login_mode(self, 11);
}
@@ -1850,22 +1909,21 @@ xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd,
return 0;
}
-void add_string_to_logwindow(char *msg, struct list *log)
+static void
+add_string_to_logwindow(const char *msg, struct list *log)
{
-
- char *new_part_message;
- char *current_pointer = msg ;
- int processedlen = 0;
+ const char *new_part_message;
+ const char *current_pointer = msg;
+ int len_done = 0;
do
{
- new_part_message = g_strndup(current_pointer, LOG_WINDOW_CHAR_PER_LINE) ;
- g_writeln(new_part_message);
- list_add_item(log, (long)new_part_message);
- processedlen = processedlen + g_strlen(new_part_message);
- current_pointer = current_pointer + g_strlen(new_part_message) ;
- }
- while ((processedlen < g_strlen(msg)) && (processedlen < DEFAULT_STRING_LEN));
+ new_part_message = g_strndup(current_pointer, LOG_WINDOW_CHAR_PER_LINE);
+ g_writeln("%s", new_part_message);
+ list_add_item(log, (tintptr) new_part_message);
+ len_done += g_strlen(new_part_message);
+ current_pointer += g_strlen(new_part_message);
+ } while ((len_done < g_strlen(msg)) && (len_done < DEFAULT_STRING_LEN));
}
/*****************************************************************************/
@@ -1877,6 +1935,10 @@ xrdp_wm_show_log(struct xrdp_wm *self)
int h;
int xoffset;
int yoffset;
+ int index;
+ int primary_x_offset;
+ int primary_y_offset;
+
if (self->hide_log_window)
{
@@ -1905,6 +1967,23 @@ xrdp_wm_show_log(struct xrdp_wm *self)
yoffset = 2;
}
+ primary_x_offset = 0;
+ primary_y_offset = 0;
+
+ /* multimon scenario, draw log window on primary monitor */
+ if (self->client_info->monitorCount > 1)
+ {
+ for (index = 0; index < self->client_info->monitorCount; index++)
+ {
+ if (self->client_info->minfo_wm[index].is_primary)
+ {
+ primary_x_offset = self->client_info->minfo_wm[index].left;
+ primary_y_offset = self->client_info->minfo_wm[index].top;
+ break;
+ }
+ }
+ }
+
/* log window */
self->log_wnd = xrdp_bitmap_create(w, h, self->screen->bpp,
WND_TYPE_WND, self);
@@ -1912,8 +1991,8 @@ xrdp_wm_show_log(struct xrdp_wm *self)
self->log_wnd->parent = self->screen;
self->log_wnd->owner = self->screen;
self->log_wnd->bg_color = self->grey;
- self->log_wnd->left = xoffset;
- self->log_wnd->top = yoffset;
+ self->log_wnd->left = primary_x_offset + xoffset;
+ self->log_wnd->top = primary_y_offset + yoffset;
set_string(&(self->log_wnd->caption1), "Connection Log");
/* ok button */
but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
@@ -1938,8 +2017,17 @@ xrdp_wm_show_log(struct xrdp_wm *self)
/*****************************************************************************/
int APP_CC
-xrdp_wm_log_msg(struct xrdp_wm *self, char *msg)
+xrdp_wm_log_msg(struct xrdp_wm *self, enum logLevels loglevel,
+ const char *fmt, ...)
{
+ va_list ap;
+ char msg[256];
+
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof(msg), fmt, ap);
+ va_end(ap);
+
+ log_message(loglevel, "xrdp_wm_log_msg: %s", msg);
add_string_to_logwindow(msg, self->log);
return 0;
}
diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c
index ee78273b..25ca6048 100644
--- a/xrdp/xrdpwin.c
+++ b/xrdp/xrdpwin.c
@@ -34,7 +34,7 @@ static long g_sync_mutex = 0;
static long g_sync1_mutex = 0;
static tbus g_term_event = 0;
static tbus g_sync_event = 0;
-/* syncronize stuff */
+/* synchronize stuff */
static int g_sync_command = 0;
static long g_sync_result = 0;
static long g_sync_param1 = 0;
@@ -344,16 +344,16 @@ main(int argc, char **argv)
g_strncasecmp(argv[1], "--help", 255) == 0 ||
g_strncasecmp(argv[1], "-h", 255) == 0)
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("xrdp: A Remote Desktop Protocol server.");
g_writeln("Copyright (C) Jay Sorg 2004-2011");
g_writeln("See http://xrdp.sourceforge.net for more information.");
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("Usage: xrdp [options]");
g_writeln(" -h: show help");
g_writeln(" -install: install service");
g_writeln(" -remove: remove service");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
else if (g_strncasecmp(argv[1], "-install", 255) == 0 ||
@@ -369,7 +369,7 @@ main(int argc, char **argv)
g_exit(0);
}
- /* check if service is allready installed */
+ /* check if service is already installed */
sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS);
if (sc_ser == 0)
@@ -383,7 +383,7 @@ main(int argc, char **argv)
}
else
{
- g_writeln("error service is allready installed");
+ g_writeln("error service is already installed");
CloseServiceHandle(sc_ser);
CloseServiceHandle(sc_man);
g_exit(0);
@@ -405,7 +405,7 @@ main(int argc, char **argv)
g_exit(0);
}
- /* check if service is allready installed */
+ /* check if service is already installed */
sc_ser = OpenService(sc_man, "xrdp", SERVICE_ALL_ACCESS);
if (sc_ser == 0)
@@ -423,7 +423,7 @@ main(int argc, char **argv)
{
g_writeln("Unknown Parameter");
g_writeln("xrdp -h for help");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
}
@@ -431,7 +431,7 @@ main(int argc, char **argv)
{
g_writeln("Unknown Parameter");
g_writeln("xrdp -h for help");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
@@ -466,8 +466,8 @@ main(int argc, char **argv)
if (fd == -1)
{
- g_writeln("problem opening to xrdp.pid");
- g_writeln("maybe its not running");
+ g_writeln("cannot open %s, maybe xrdp is not running",
+ pid_file);
}
else
{
@@ -499,34 +499,34 @@ main(int argc, char **argv)
g_strncasecmp(argv[1], "--help", 255) == 0 ||
g_strncasecmp(argv[1], "-h", 255) == 0)
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("xrdp: A Remote Desktop Protocol server.");
g_writeln("Copyright (C) Jay Sorg 2004-2011");
g_writeln("See http://xrdp.sourceforge.net for more information.");
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("Usage: xrdp [options]");
g_writeln(" -h: show help");
g_writeln(" -nodaemon: don't fork into background");
g_writeln(" -kill: shut down xrdp");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
else if ((g_strncasecmp(argv[1], "-v", 255) == 0) ||
(g_strncasecmp(argv[1], "--version", 255) == 0))
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("xrdp: A Remote Desktop Protocol server.");
g_writeln("Copyright (C) Jay Sorg 2004-2011");
g_writeln("See http://xrdp.sourceforge.net for more information.");
g_writeln("Version %s", PACKAGE_VERSION);
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
else
{
g_writeln("Unknown Parameter");
g_writeln("xrdp -h for help");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
}
@@ -534,14 +534,14 @@ main(int argc, char **argv)
{
g_writeln("Unknown Parameter");
g_writeln("xrdp -h for help");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
if (g_file_exist(pid_file)) /* xrdp.pid */
{
- g_writeln("It looks like xrdp is allready running,");
- g_writeln("if not delete the xrdp.pid file and try again");
+ g_writeln("It looks like xrdp is already running.");
+ g_writeln("If not, delete %s and try again.", pid_file);
g_exit(0);
}
@@ -618,7 +618,6 @@ main(int argc, char **argv)
g_threadid = tc_get_threadid();
g_listen = xrdp_listen_create();
g_signal_user_interrupt(xrdp_shutdown); /* SIGINT */
- g_signal_kill(xrdp_shutdown); /* SIGKILL */
g_signal_pipe(pipe_sig); /* SIGPIPE */
g_signal_terminate(xrdp_shutdown); /* SIGTERM */
g_sync_mutex = tc_mutex_create();
diff --git a/xrdpapi/Makefile.am b/xrdpapi/Makefile.am
index 88ef100e..fefa03fc 100644
--- a/xrdpapi/Makefile.am
+++ b/xrdpapi/Makefile.am
@@ -1,24 +1,11 @@
-EXTRA_DIST = xrdpapi.h
+EXTRA_DIST = \
+ simple.c \
+ vrplayer.c \
+ vrplayer.mk
-EXTRA_DEFINES =
-EXTRA_INCLUDES =
-EXTRA_LIBS =
-EXTRA_FLAGS =
-
-AM_CFLAGS = \
- $(EXTRA_DEFINES)
-
-INCLUDES = \
- $(EXTRA_INCLUDES)
-
-lib_LTLIBRARIES = \
+module_LTLIBRARIES = \
libxrdpapi.la
libxrdpapi_la_SOURCES = \
- xrdpapi.c
-
-libxrdpapi_la_LDFLAGS = \
- $(EXTRA_FLAGS)
-
-libxrdpapi_la_LIBADD = \
- $(EXTRA_LIBS)
+ xrdpapi.c \
+ xrdpapi.h
diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c
index 7e9eaa0c..ac303534 100644
--- a/xrdpapi/xrdpapi.c
+++ b/xrdpapi/xrdpapi.c
@@ -53,8 +53,10 @@ static int send_init(struct wts_obj *wts);
static int can_send(int sck, int millis);
static int can_recv(int sck, int millis);
-static char g_xrdpapi_magic[12] =
-{ 0x78, 0x32, 0x10, 0x67, 0x00, 0x92, 0x30, 0x56, 0xff, 0xd8, 0xa9, 0x1f };
+static const unsigned char g_xrdpapi_magic[12] =
+{
+ 0x78, 0x32, 0x10, 0x67, 0x00, 0x92, 0x30, 0x56, 0xff, 0xd8, 0xa9, 0x1f
+};
/*
* Opens a handle to the server end of a specified virtual channel - this
@@ -118,7 +120,7 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, const char *pVirtualName,
if (wts->display_num <= 0)
{
- LLOGLN(0, ("WTSVirtualChannelOpenEx: fatal errror; display is 0"));
+ LLOGLN(0, ("WTSVirtualChannelOpenEx: fatal error; display is 0"));
free(wts);
return NULL;
}
@@ -126,7 +128,7 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, const char *pVirtualName,
/* we use unix domain socket to communicate with chansrv */
if ((wts->fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
- g_free(wts);
+ free(wts);
return NULL;
}
@@ -162,6 +164,14 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, const char *pVirtualName,
return wts;
}
+/*
+ * Prevent receiving SIGPIPE on disconnect using either MSG_NOSIGNAL (Linux)
+ * or SO_NOSIGPIPE (Mac OS X)
+ */
+#if !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
/*****************************************************************************/
static int
mysend(int sck, const void* adata, int bytes)
@@ -170,6 +180,11 @@ mysend(int sck, const void* adata, int bytes)
int error;
const char* data;
+#if defined(SO_NOSIGPIPE)
+ const int on = 1;
+ setsockopt(sck, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
+#endif
+
data = (const char*)adata;
sent = 0;
while (sent < bytes)
@@ -234,7 +249,7 @@ WTSVirtualChannelWrite(void *hChannelHandle, const char *Buffer,
return -1;
}
- LLOGLN(10, ("WTSVirtualChannelWrite: mysend() reted %d", rv));
+ LLOGLN(10, ("WTSVirtualChannelWrite: mysend() returned %d", rv));
if (rv >= 0)
{
@@ -467,17 +482,11 @@ get_display_num_from_display(char *display_text)
{
int index;
int mode;
- int host_index;
int disp_index;
- int scre_index;
- char host[256];
char disp[256];
- char scre[256];
index = 0;
- host_index = 0;
disp_index = 0;
- scre_index = 0;
mode = 0;
while (display_text[index] != 0)
@@ -490,27 +499,15 @@ get_display_num_from_display(char *display_text)
{
mode = 2;
}
- else if (mode == 0)
- {
- host[host_index] = display_text[index];
- host_index++;
- }
else if (mode == 1)
{
disp[disp_index] = display_text[index];
disp_index++;
}
- else if (mode == 2)
- {
- scre[scre_index] = display_text[index];
- scre_index++;
- }
index++;
}
- host[host_index] = 0;
disp[disp_index] = 0;
- scre[scre_index] = 0;
return atoi(disp);
}
diff --git a/xrdpvr/Makefile.am b/xrdpvr/Makefile.am
index 158baa90..8c907402 100644
--- a/xrdpvr/Makefile.am
+++ b/xrdpvr/Makefile.am
@@ -1,24 +1,7 @@
-EXTRA_DIST = xrdpvr.h
-
-EXTRA_DEFINES =
-EXTRA_INCLUDES =
-EXTRA_LIBS =
-EXTRA_FLAGS =
-
-AM_CFLAGS = \
- $(EXTRA_DEFINES)
-
-INCLUDES = \
- $(EXTRA_INCLUDES)
-
-lib_LTLIBRARIES = \
+module_LTLIBRARIES = \
libxrdpvr.la
libxrdpvr_la_SOURCES = \
- xrdpvr.c
-
-libxrdpvr_la_LDFLAGS = \
- $(EXTRA_FLAGS)
-
-libxrdpvr_la_LIBADD = \
- $(EXTRA_LIBS)
+ xrdpvr.c \
+ xrdpvr.h \
+ xrdpvr_internal.h
diff --git a/xrdpvr/xrdpvr.c b/xrdpvr/xrdpvr.c
index 6147a66e..8de52be8 100644
--- a/xrdpvr/xrdpvr.c
+++ b/xrdpvr/xrdpvr.c
@@ -194,7 +194,7 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
//if (avformat_find_stream_info(g_psi.p_format_ctx, NULL) < 0)
if (av_find_stream_info(g_psi.p_format_ctx) < 0)
{
- printf("ERRRO reading stream info\n");
+ printf("ERROR reading stream info\n");
return -1;
}
diff --git a/xup/Makefile.am b/xup/Makefile.am
index 544c957a..cdaca15c 100644
--- a/xup/Makefile.am
+++ b/xup/Makefile.am
@@ -1,18 +1,16 @@
-EXTRA_DIST = xup.h
-
-AM_CFLAGS = \
+AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
-
-INCLUDES = \
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-I$(top_srcdir)/common
-lib_LTLIBRARIES = \
+module_LTLIBRARIES = \
libxup.la
-libxup_la_SOURCES = xup.c
+libxup_la_SOURCES = \
+ xup.c \
+ xup.h
libxup_la_LIBADD = \
$(top_builddir)/common/libcommon.la
diff --git a/xup/xup.c b/xup/xup.c
index 830b0f12..e2c34ca8 100644
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2014
+ * Copyright (C) Jay Sorg 2004-2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
#include "xup.h"
#include "log.h"
+#include "trans.h"
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
@@ -27,98 +28,14 @@
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
-/******************************************************************************/
-/* returns error */
-int DEFAULT_CC
-lib_recv(struct mod *mod, char *data, int len)
-{
- int rcvd;
-
- if (mod->sck_closed)
- {
- return 1;
- }
-
- while (len > 0)
- {
- rcvd = g_tcp_recv(mod->sck, data, len, 0);
-
- if (rcvd == -1)
- {
- if (g_tcp_last_error_would_block(mod->sck))
- {
- if (mod->server_is_term(mod))
- {
- return 1;
- }
-
- g_tcp_can_recv(mod->sck, 10);
- }
- else
- {
- return 1;
- }
- }
- else if (rcvd == 0)
- {
- mod->sck_closed = 1;
- return 1;
- }
- else
- {
- data += rcvd;
- len -= rcvd;
- }
- }
-
- return 0;
-}
+static int APP_CC
+lib_mod_process_message(struct mod *mod, struct stream *s);
-/*****************************************************************************/
-/* returns error */
-int DEFAULT_CC
-lib_send(struct mod *mod, char *data, int len)
+/******************************************************************************/
+static int APP_CC
+lib_send_copy(struct mod *mod, struct stream *s)
{
- int sent;
-
- if (mod->sck_closed)
- {
- return 1;
- }
-
- while (len > 0)
- {
- sent = g_tcp_send(mod->sck, data, len, 0);
-
- if (sent == -1)
- {
- if (g_tcp_last_error_would_block(mod->sck))
- {
- if (mod->server_is_term(mod))
- {
- return 1;
- }
-
- g_tcp_can_send(mod->sck, 10);
- }
- else
- {
- return 1;
- }
- }
- else if (sent == 0)
- {
- mod->sck_closed = 1;
- return 1;
- }
- else
- {
- data += sent;
- len -= sent;
- }
- }
-
- return 0;
+ return trans_write_copy_s(mod->trans, s);
}
/******************************************************************************/
@@ -144,7 +61,7 @@ lib_mod_log_peer(struct mod *mod)
int gid;
my_pid = g_getpid();
- if (g_sck_get_peer_cred(mod->sck, &pid, &uid, &gid) == 0)
+ if (g_sck_get_peer_cred(mod->trans->sck, &pid, &uid, &gid) == 0)
{
log_message(LOG_LEVEL_INFO, "lib_mod_log_peer: xrdp_pid=%d connected "
"to X11rdp_pid=%d X11rdp_uid=%d X11rdp_gid=%d "
@@ -162,6 +79,62 @@ lib_mod_log_peer(struct mod *mod)
}
/******************************************************************************/
+static int APP_CC
+lib_data_in(struct trans *trans)
+{
+ struct mod *self;
+ struct stream *s;
+ int len;
+
+ LLOGLN(10, ("lib_data_in:"));
+ if (trans == 0)
+ {
+ return 1;
+ }
+
+ self = (struct mod *)(trans->callback_data);
+ s = trans_get_in_s(trans);
+
+ if (s == 0)
+ {
+ return 1;
+ }
+
+ switch (trans->extra_flags)
+ {
+ case 1:
+ s->p = s->data;
+ in_uint8s(s, 4); /* processed later in lib_mod_process_message */
+ in_uint32_le(s, len);
+ if (len < 0 || len > 128 * 1024)
+ {
+ g_writeln("lib_data_in: bad size");
+ return 1;
+ }
+ if (len > 0)
+ {
+ trans->header_size = len + 8;
+ trans->extra_flags = 2;
+ break;
+ }
+ /* fall through */
+ case 2:
+ s->p = s->data;
+ if (lib_mod_process_message(self, s) != 0)
+ {
+ g_writeln("lib_data_in: lib_mod_process_message failed");
+ return 1;
+ }
+ init_stream(s, 0);
+ trans->header_size = 8;
+ trans->extra_flags = 1;
+ break;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
/* return error */
int DEFAULT_CC
lib_mod_connect(struct mod *mod)
@@ -169,10 +142,10 @@ lib_mod_connect(struct mod *mod)
int error;
int len;
int i;
- int index;
int use_uds;
struct stream *s;
char con_port[256];
+ struct source_info *si;
LIB_DEBUG(mod, "in lib_mod_connect");
@@ -207,64 +180,40 @@ lib_mod_connect(struct mod *mod)
mod->sck_closed = 0;
i = 0;
- while (1)
+ if (use_uds)
{
- if (use_uds)
+ mod->trans = trans_create(TRANS_MODE_UNIX, 8 * 8192, 8192);
+ if (mod->trans == 0)
{
- mod->sck = g_tcp_local_socket();
- if (mod->sck < 0)
- {
- free_stream(s);
- return 1;
- }
+ free_stream(s);
+ return 1;
}
- else
+ }
+ else
+ {
+ mod->trans = trans_create(TRANS_MODE_TCP, 8 * 8192, 8192);
+ if (mod->trans == 0)
{
- mod->sck = g_tcp_socket();
- if (mod->sck < 0)
- {
- free_stream(s);
- return 1;
- }
-
- g_tcp_set_non_blocking(mod->sck);
- g_tcp_set_no_delay(mod->sck);
+ free_stream(s);
+ return 1;
}
+ }
- /* mod->server_msg(mod, "connecting...", 0); */
-
- if (use_uds)
- {
- error = g_tcp_local_connect(mod->sck, con_port);
- }
- else
- {
- error = g_tcp_connect(mod->sck, mod->ip, con_port);
- }
+ si = (struct source_info *) (mod->si);
+ mod->trans->si = si;
+ mod->trans->my_source = XRDP_SOURCE_MOD;
- if (error == -1)
- {
- if (g_tcp_last_error_would_block(mod->sck))
- {
- error = 0;
- index = 0;
+ while (1)
+ {
- while (!g_tcp_can_send(mod->sck, 100))
- {
- index++;
+ /* mod->server_msg(mod, "connecting...", 0); */
- if ((index >= 30) || mod->server_is_term(mod))
- {
- mod->server_msg(mod, "connect timeout", 0);
- error = 1;
- break;
- }
- }
- }
- else
- {
- /* mod->server_msg(mod, "connect error", 0); */
- }
+ error = -1;
+ if (trans_connect(mod->trans, mod->ip, con_port, 3000) == 0)
+ {
+ LLOGLN(0, ("lib_mod_connect: connected to Xserver "
+ "(Xorg or X11rdp) sck %ld", mod->trans->sck));
+ error = 0;
}
if (error == 0)
@@ -272,8 +221,6 @@ lib_mod_connect(struct mod *mod)
break;
}
- g_tcp_close(mod->sck);
- mod->sck = 0;
i++;
if (i >= 60)
@@ -308,7 +255,7 @@ lib_mod_connect(struct mod *mod)
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
- lib_send(mod, s->data, len);
+ lib_send_copy(mod, s);
}
if (error == 0)
@@ -326,7 +273,7 @@ lib_mod_connect(struct mod *mod)
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
- lib_send(mod, s->data, len);
+ lib_send_copy(mod, s);
}
if (error == 0)
@@ -348,13 +295,15 @@ lib_mod_connect(struct mod *mod)
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
- lib_send(mod, s->data, len);
+ lib_send_copy(mod, s);
}
free_stream(s);
if (error != 0)
{
+ trans_delete(mod->trans);
+ mod->trans = 0;
mod->server_msg(mod, "some problem", 0);
LIB_DEBUG(mod, "out lib_mod_connect error");
return 1;
@@ -362,7 +311,11 @@ lib_mod_connect(struct mod *mod)
else
{
mod->server_msg(mod, "connected ok", 0);
- mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0);
+ mod->trans->trans_data_in = lib_data_in;
+ mod->trans->header_size = 8;
+ mod->trans->callback_data = mod;
+ mod->trans->no_stream_init_on_data_in = 1;
+ mod->trans->extra_flags = 1;
}
LIB_DEBUG(mod, "out lib_mod_connect");
@@ -411,7 +364,7 @@ lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2,
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
- lib_send(mod, s->data, len);
+ lib_send_copy(mod, s);
}
}
@@ -434,7 +387,7 @@ lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2,
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
- rv = lib_send(mod, s->data, len);
+ rv = lib_send_copy(mod, s);
free_stream(s);
LIB_DEBUG(mod, "out lib_mod_event");
return rv;
@@ -744,7 +697,7 @@ process_server_window_new_update(struct mod *mod, struct stream *s)
if (title_bytes > 0)
{
- rwso.title_info = g_malloc(title_bytes + 1, 0);
+ rwso.title_info = g_new(char, title_bytes + 1);
in_uint8a(s, rwso.title_info, title_bytes);
rwso.title_info[title_bytes] = 0;
}
@@ -844,7 +797,7 @@ process_server_add_char(struct mod *mod, struct stream *s)
{
int rv;
int font;
- int charactor;
+ int character;
int x;
int y;
int cx;
@@ -853,14 +806,14 @@ process_server_add_char(struct mod *mod, struct stream *s)
char *bmpdata;
in_uint16_le(s, font);
- in_uint16_le(s, charactor);
+ in_uint16_le(s, character);
in_sint16_le(s, x);
in_sint16_le(s, y);
in_uint16_le(s, cx);
in_uint16_le(s, cy);
in_uint16_le(s, len_bmpdata);
in_uint8p(s, bmpdata, len_bmpdata);
- rv = mod->server_add_char(mod, font, charactor, x, y, cx, cy, bmpdata);
+ rv = mod->server_add_char(mod, font, character, x, y, cx, cy, bmpdata);
return rv;
}
@@ -872,7 +825,7 @@ process_server_add_char_alpha(struct mod *mod, struct stream *s)
{
int rv;
int font;
- int charactor;
+ int character;
int x;
int y;
int cx;
@@ -881,14 +834,14 @@ process_server_add_char_alpha(struct mod *mod, struct stream *s)
char *bmpdata;
in_uint16_le(s, font);
- in_uint16_le(s, charactor);
+ in_uint16_le(s, character);
in_sint16_le(s, x);
in_sint16_le(s, y);
in_uint16_le(s, cx);
in_uint16_le(s, cy);
in_uint16_le(s, len_bmpdata);
in_uint8p(s, bmpdata, len_bmpdata);
- rv = mod->server_add_char_alpha(mod, font, charactor, x, y, cx, cy,
+ rv = mod->server_add_char_alpha(mod, font, character, x, y, cx, cy,
bmpdata);
return rv;
}
@@ -1092,7 +1045,7 @@ send_paint_rect_ack(struct mod *mod, int flags, int x, int y, int cx, int cy,
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
- lib_send(mod, s->data, len);
+ lib_send_copy(mod, s);
free_stream(s);
return 0;
}
@@ -1100,7 +1053,7 @@ send_paint_rect_ack(struct mod *mod, int flags, int x, int y, int cx, int cy,
/******************************************************************************/
/* return error */
static int APP_CC
-process_server_paint_rect_shmem(struct mod *mod, struct stream *s)
+process_server_paint_rect_shmem(struct mod *amod, struct stream *s)
{
int rv;
int x;
@@ -1132,32 +1085,33 @@ process_server_paint_rect_shmem(struct mod *mod, struct stream *s)
bmpdata = 0;
rv = 0;
-
- if (flags == 0) /* screen */
+ if (amod->screen_shmem_id_mapped == 0)
{
- if (mod->screen_shmem_id == 0)
+ amod->screen_shmem_id = shmem_id;
+ amod->screen_shmem_pixels = (char *) g_shmat(amod->screen_shmem_id);
+ if (amod->screen_shmem_pixels == (void*)-1)
{
- mod->screen_shmem_id = shmem_id;
- mod->screen_shmem_pixels = g_shmat(mod->screen_shmem_id);
- if (mod->screen_shmem_pixels == (void*)-1)
- {
- /* failed */
- mod->screen_shmem_id = 0;
- mod->screen_shmem_pixels = 0;
- }
+ /* failed */
+ amod->screen_shmem_id = 0;
+ amod->screen_shmem_pixels = 0;
+ amod->screen_shmem_id_mapped = 0;
}
- if (mod->screen_shmem_pixels != 0)
+ else
{
- bmpdata = mod->screen_shmem_pixels + shmem_offset;
+ amod->screen_shmem_id_mapped = 1;
}
}
+ if (amod->screen_shmem_pixels != 0)
+ {
+ bmpdata = amod->screen_shmem_pixels + shmem_offset;
+ }
if (bmpdata != 0)
{
- rv = mod->server_paint_rect(mod, x, y, cx, cy,
- bmpdata, width, height,
- srcx, srcy);
+ rv = amod->server_paint_rect(amod, x, y, cx, cy,
+ bmpdata, width, height,
+ srcx, srcy);
}
- send_paint_rect_ack(mod, flags, x, y, cx, cy, frame_id);
+ send_paint_rect_ack(amod, flags, x, y, cx, cy, frame_id);
return rv;
}
@@ -1179,7 +1133,7 @@ send_paint_rect_ex_ack(struct mod *mod, int flags, int frame_id)
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
- lib_send(mod, s->data, len);
+ lib_send_copy(mod, s);
free_stream(s);
return 0;
}
@@ -1197,10 +1151,6 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
int shmem_offset;
int width;
int height;
- int x;
- int y;
- int cx;
- int cy;
int index;
int rv;
tsi16 *ldrects;
@@ -1246,10 +1196,21 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
bmpdata = 0;
if (flags == 0) /* screen */
{
- if (amod->screen_shmem_id == 0)
+ if (amod->screen_shmem_id_mapped == 0)
{
amod->screen_shmem_id = shmem_id;
- amod->screen_shmem_pixels = g_shmat(amod->screen_shmem_id);
+ amod->screen_shmem_pixels = (char *) g_shmat(amod->screen_shmem_id);
+ if (amod->screen_shmem_pixels == (void*)-1)
+ {
+ /* failed */
+ amod->screen_shmem_id = 0;
+ amod->screen_shmem_pixels = 0;
+ amod->screen_shmem_id_mapped = 0;
+ }
+ else
+ {
+ amod->screen_shmem_id_mapped = 1;
+ }
}
if (amod->screen_shmem_pixels != 0)
{
@@ -1275,7 +1236,7 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
g_free(lcrects);
g_free(ldrects);
- return 0;
+ return rv;
}
/******************************************************************************/
@@ -1285,6 +1246,7 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
{
int rv;
+ LLOGLN(10, ("lib_mod_process_orders: type %d", type));
rv = 0;
switch (type)
{
@@ -1405,17 +1367,16 @@ lib_send_client_info(struct mod *mod)
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
- lib_send(mod, s->data, len);
+ lib_send_copy(mod, s);
free_stream(s);
return 0;
}
/******************************************************************************/
/* return error */
-int DEFAULT_CC
-lib_mod_signal(struct mod *mod)
+static int APP_CC
+lib_mod_process_message(struct mod *mod, struct stream *s)
{
- struct stream *s;
int num_orders;
int index;
int rv;
@@ -1423,85 +1384,65 @@ lib_mod_signal(struct mod *mod)
int type;
char *phold;
- LIB_DEBUG(mod, "in lib_mod_signal");
- make_stream(s);
- init_stream(s, 8192);
- rv = lib_recv(mod, s->data, 8);
-
+ LLOGLN(10, ("lib_mod_process_message:"));
+ rv = 0;
if (rv == 0)
{
in_uint16_le(s, type);
in_uint16_le(s, num_orders);
in_uint32_le(s, len);
+ LLOGLN(10, ("lib_mod_process_message: type %d", type));
if (type == 1) /* original order list */
{
- init_stream(s, len);
- rv = lib_recv(mod, s->data, len);
-
- if (rv == 0)
+ for (index = 0; index < num_orders; index++)
{
- for (index = 0; index < num_orders; index++)
- {
- in_uint16_le(s, type);
- rv = lib_mod_process_orders(mod, type, s);
+ in_uint16_le(s, type);
+ rv = lib_mod_process_orders(mod, type, s);
- if (rv != 0)
- {
- break;
- }
+ if (rv != 0)
+ {
+ break;
}
}
}
else if (type == 2) /* caps */
{
- g_writeln("lib_mod_signal: type 2 len %d", len);
- init_stream(s, len);
- rv = lib_recv(mod, s->data, len);
-
- if (rv == 0)
+ g_writeln("lib_mod_process_message: type 2 len %d", len);
+ for (index = 0; index < num_orders; index++)
{
- for (index = 0; index < num_orders; index++)
+ phold = s->p;
+ in_uint16_le(s, type);
+ in_uint16_le(s, len);
+
+ switch (type)
{
- phold = s->p;
- in_uint16_le(s, type);
- in_uint16_le(s, len);
-
- switch (type)
- {
- default:
- g_writeln("lib_mod_signal: unknown cap type %d len %d",
- type, len);
- break;
- }
-
- s->p = phold + len;
+ default:
+ g_writeln("lib_mod_process_message: unknown cap type %d len %d",
+ type, len);
+ break;
}
- lib_send_client_info(mod);
+ s->p = phold + len;
}
+
+ lib_send_client_info(mod);
}
else if (type == 3) /* order list with len after type */
{
- init_stream(s, len);
- rv = lib_recv(mod, s->data, len);
-
- if (rv == 0)
+ for (index = 0; index < num_orders; index++)
{
- for (index = 0; index < num_orders; index++)
- {
- phold = s->p;
- in_uint16_le(s, type);
- in_uint16_le(s, len);
- rv = lib_mod_process_orders(mod, type, s);
-
- if (rv != 0)
- {
- break;
- }
+ phold = s->p;
+ in_uint16_le(s, type);
+ in_uint16_le(s, len);
+ rv = lib_mod_process_orders(mod, type, s);
- s->p = phold + len;
+ if (rv != 0)
+ {
+ break;
}
+
+ s->p = phold + len;
}
}
else
@@ -1510,14 +1451,21 @@ lib_mod_signal(struct mod *mod)
}
}
- free_stream(s);
- LIB_DEBUG(mod, "out lib_mod_signal");
return rv;
}
/******************************************************************************/
/* return error */
int DEFAULT_CC
+lib_mod_signal(struct mod *mod)
+{
+ g_writeln("lib_mod_signal: not used");
+ return 0;
+}
+
+/******************************************************************************/
+/* return error */
+int DEFAULT_CC
lib_mod_end(struct mod *mod)
{
if (mod->screen_shmem_pixels != 0)
@@ -1531,7 +1479,7 @@ lib_mod_end(struct mod *mod)
/******************************************************************************/
/* return error */
int DEFAULT_CC
-lib_mod_set_param(struct mod *mod, char *name, char *value)
+lib_mod_set_param(struct mod *mod, const char *name, char *value)
{
if (g_strcasecmp(name, "username") == 0)
{
@@ -1563,19 +1511,14 @@ int DEFAULT_CC
lib_mod_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount,
tbus *write_objs, int *wcount, int *timeout)
{
- int i;
-
- i = *rcount;
-
if (mod != 0)
{
- if (mod->sck_obj != 0)
+ if (mod->trans != 0)
{
- read_objs[i++] = mod->sck_obj;
+ trans_get_wait_objs_rw(mod->trans, read_objs, rcount,
+ write_objs, wcount, timeout);
}
}
-
- *rcount = i;
return 0;
}
@@ -1587,15 +1530,11 @@ lib_mod_check_wait_objs(struct mod *mod)
int rv;
rv = 0;
-
if (mod != 0)
{
- if (mod->sck_obj != 0)
+ if (mod->trans != 0)
{
- if (g_is_wait_obj_set(mod->sck_obj))
- {
- rv = lib_mod_signal(mod);
- }
+ rv = trans_check_wait_objs(mod->trans);
}
}
@@ -1613,7 +1552,7 @@ lib_mod_frame_ack(struct mod *amod, int flags, int frame_id)
}
/******************************************************************************/
-struct mod *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct mod *mod;
@@ -1621,7 +1560,7 @@ mod_init(void)
mod = (struct mod *)g_malloc(sizeof(struct mod), 1);
mod->size = sizeof(struct mod);
mod->version = CURRENT_MOD_VER;
- mod->handle = (tbus)mod;
+ mod->handle = (tintptr) mod;
mod->mod_connect = lib_mod_connect;
mod->mod_start = lib_mod_start;
mod->mod_event = lib_mod_event;
@@ -1631,20 +1570,20 @@ mod_init(void)
mod->mod_get_wait_objs = lib_mod_get_wait_objs;
mod->mod_check_wait_objs = lib_mod_check_wait_objs;
mod->mod_frame_ack = lib_mod_frame_ack;
- return mod;
+ return (tintptr) mod;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct mod *mod)
+mod_exit(tintptr handle)
{
+ struct mod *mod = (struct mod *) handle;
+
if (mod == 0)
{
return 0;
}
-
- g_delete_wait_obj_from_socket(mod->sck_obj);
- g_tcp_close(mod->sck);
+ trans_delete(mod->trans);
g_free(mod);
return 0;
}
diff --git a/xup/xup.h b/xup/xup.h
index e4bbdc15..8c91996d 100644
--- a/xup/xup.h
+++ b/xup/xup.h
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2014
+ * Copyright (C) Jay Sorg 2004-2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
#include "xrdp_client_info.h"
#include "xrdp_rail.h"
-#define CURRENT_MOD_VER 2
+#define CURRENT_MOD_VER 3
struct mod
{
@@ -39,14 +39,14 @@ struct mod
tbus param3, tbus param4);
int (*mod_signal)(struct mod* v);
int (*mod_end)(struct mod* v);
- int (*mod_set_param)(struct mod* v, char* name, char* value);
+ int (*mod_set_param)(struct mod* v, const char *name, char* value);
int (*mod_session_change)(struct mod* v, int, int);
int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct mod* v);
int (*mod_frame_ack)(struct mod* v, int flags, int frame_id);
- tbus mod_dumby[100 - 10]; /* align, 100 minus the number of mod
- functions above */
+ tintptr mod_dumby[100 - 10]; /* align, 100 minus the number of mod
+ functions above */
/* server functions */
int (*server_begin_update)(struct mod* v);
int (*server_end_update)(struct mod* v);
@@ -58,7 +58,7 @@ struct mod
int srcx, int srcy);
int (*server_set_cursor)(struct mod* v, int x, int y, char* data, char* mask);
int (*server_palette)(struct mod* v, int* palette);
- int (*server_msg)(struct mod* v, char* msg, int code);
+ int (*server_msg)(struct mod* v, const char *msg, int code);
int (*server_is_term)(struct mod* v);
int (*server_set_clip)(struct mod* v, int x, int y, int cx, int cy);
int (*server_reset_clip)(struct mod* v);
@@ -66,12 +66,12 @@ struct mod
int (*server_set_bgcolor)(struct mod* v, int bgcolor);
int (*server_set_opcode)(struct mod* v, int opcode);
int (*server_set_mixmode)(struct mod* v, int mixmode);
- int (*server_set_brush)(struct mod* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct mod* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct mod* v, int style,
int width);
int (*server_draw_line)(struct mod* v, int x1, int y1, int x2, int y2);
- int (*server_add_char)(struct mod* v, int font, int charactor,
+ int (*server_add_char)(struct mod* v, int font, int character,
int offset, int baseline,
int width, int height, char* data);
int (*server_draw_text)(struct mod* v, int font,
@@ -84,7 +84,7 @@ struct mod
int (*server_query_channel)(struct mod* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct mod* v, char* name);
+ int (*server_get_channel_id)(struct mod* v, const char *name);
int (*server_send_to_channel)(struct mod* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
@@ -121,7 +121,7 @@ struct mod
int flags);
int (*server_set_cursor_ex)(struct mod* v, int x, int y, char* data,
char* mask, int bpp);
- int (*server_add_char_alpha)(struct mod* v, int font, int charactor,
+ int (*server_add_char_alpha)(struct mod* v, int font, int character,
int offset, int baseline,
int width, int height, char* data);
int (*server_create_os_surface_bpp)(struct mod* v, int rdpindex,
@@ -140,13 +140,13 @@ struct mod
char *data, int width, int height,
int flags, int frame_id);
- tbus server_dumby[100 - 43]; /* align, 100 minus the number of server
- functions above */
+ tintptr server_dumby[100 - 43]; /* align, 100 minus the number of server
+ functions above */
/* common */
- tbus handle; /* pointer to self as long */
- tbus wm;
- tbus painter;
- int sck;
+ tintptr handle; /* pointer to self as long */
+ tintptr wm;
+ tintptr painter;
+ tintptr si;
/* mod data */
int width;
int height;
@@ -156,9 +156,10 @@ struct mod
char password[256];
char ip[256];
char port[256];
- tbus sck_obj;
int shift_state;
struct xrdp_client_info client_info;
int screen_shmem_id;
+ int screen_shmem_id_mapped; /* boolean */
char *screen_shmem_pixels;
+ struct trans *trans;
};