Merge branch 'devel' into v0.9
This commit is contained in:
commit
9e8fbf2d5a
42
NEWS.md
42
NEWS.md
@ -1,29 +1,59 @@
|
|||||||
# Release notes for xrdp v0.9.9 (2018/12/25)
|
# Release notes for xrdp v0.9.10 (2019/04/18)
|
||||||
|
|
||||||
# Release cycle
|
## Special thanks
|
||||||
|
Thank you for matt335672 contributing to lots of improvements in drive redirection!
|
||||||
|
|
||||||
|
## New features
|
||||||
|
* Restrict outbound (server->client) clipboard transfer, configured in `sesman.ini` #1298
|
||||||
|
|
||||||
|
## Bug fixes
|
||||||
|
* Fix the issue libscp v1 not setting width but height twice #1293
|
||||||
|
* Fix the issue reconnecting to session causes duplicate drive entries in fuse fs #1299
|
||||||
|
* Fix default_wm and reconnect_sh refer wrong path after sesman caught SIGUP #1315 #1331
|
||||||
|
* Shutdown xrdp more responsively #1325
|
||||||
|
* Improve remote file lookup in drive redirection #996 #1327
|
||||||
|
* Overwriting & appending to existing files is are now supported #1327
|
||||||
|
|
||||||
|
## Other changes
|
||||||
|
* Add Danish Keyboard #1290
|
||||||
|
* Put xrdp- prefix to some executables appear in man page #1313
|
||||||
|
* Replace some URLs from SF.net to xrdp.org #1313
|
||||||
|
|
||||||
|
## Known issues
|
||||||
|
* FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
|
||||||
|
xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
|
||||||
|
* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
## Release notes for xrdp v0.9.9 (2018/12/25)
|
||||||
|
|
||||||
|
## Release cycle
|
||||||
From the next release, release cycle will be changed from quarterly to every
|
From the next release, release cycle will be changed from quarterly to every
|
||||||
4 months. xrdp will be released in April, August, December.
|
4 months. xrdp will be released in April, August, December.
|
||||||
|
|
||||||
# New features
|
## New features
|
||||||
* Disconnection by idle timeout (requires xorgxrdp v0.2.9 or later) #1227
|
* Disconnection by idle timeout (requires xorgxrdp v0.2.9 or later) #1227
|
||||||
* Glyph cache v2 (fixes no font issue on iOS/macOS/Android client) #367 #1235
|
* Glyph cache v2 (fixes no font issue on iOS/macOS/Android client) #367 #1235
|
||||||
|
|
||||||
# Bug fixes
|
## Bug fixes
|
||||||
* Fix xrdp-chansrv crashes caused in drive redirection #1202 #1225
|
* Fix xrdp-chansrv crashes caused in drive redirection #1202 #1225
|
||||||
* Fix build with FDK AAC v2 #1257
|
* Fix build with FDK AAC v2 #1257
|
||||||
* Do not enable RemoteApp if the INFO_RAIL flag is not set (RDP-RDP proxy) #1253
|
* Do not enable RemoteApp if the INFO_RAIL flag is not set (RDP-RDP proxy) #1253
|
||||||
|
|
||||||
# Other changes
|
## Other changes
|
||||||
* Add Spanish Latin Amarican keyboard #1237 #1240 #1244
|
* Add Spanish Latin Amarican keyboard #1237 #1240 #1244
|
||||||
* Dynamic channel improvements #1222 #1224
|
* Dynamic channel improvements #1222 #1224
|
||||||
* Remove some deprecated sesman session types #1232
|
* Remove some deprecated sesman session types #1232
|
||||||
* Refactoring and cleanups
|
* Refactoring and cleanups
|
||||||
|
|
||||||
# Known issues
|
## Known issues
|
||||||
* FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
|
* FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
|
||||||
xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
|
xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
|
||||||
* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965
|
* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
|
||||||
# Release notes for xrdp v0.9.8 (2018/09/25)
|
# Release notes for xrdp v0.9.8 (2018/09/25)
|
||||||
|
|
||||||
## Deprecation notice
|
## Deprecation notice
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/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)
|
![Apache-License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)
|
||||||
|
|
||||||
*Current Version:* 0.9.9
|
*Current Version:* 0.9.10
|
||||||
|
|
||||||
# xrdp - an open source RDP server
|
# xrdp - an open source RDP server
|
||||||
|
|
||||||
|
@ -712,13 +712,21 @@ trans_connect(struct trans *self, const char *server, const char *port,
|
|||||||
now = g_time3();
|
now = g_time3();
|
||||||
if (now - start_time < timeout)
|
if (now - start_time < timeout)
|
||||||
{
|
{
|
||||||
g_sleep(timeout / 5);
|
g_sleep(100);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->status = TRANS_STATUS_DOWN;
|
self->status = TRANS_STATUS_DOWN;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (self->is_term != NULL)
|
||||||
|
{
|
||||||
|
if (self->is_term())
|
||||||
|
{
|
||||||
|
self->status = TRANS_STATUS_DOWN;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -748,13 +756,21 @@ trans_connect(struct trans *self, const char *server, const char *port,
|
|||||||
now = g_time3();
|
now = g_time3();
|
||||||
if (now - start_time < timeout)
|
if (now - start_time < timeout)
|
||||||
{
|
{
|
||||||
g_sleep(timeout / 5);
|
g_sleep(100);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->status = TRANS_STATUS_DOWN;
|
self->status = TRANS_STATUS_DOWN;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (self->is_term != NULL)
|
||||||
|
{
|
||||||
|
if (self->is_term())
|
||||||
|
{
|
||||||
|
self->status = TRANS_STATUS_DOWN;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Process this file with autoconf to produce a configure script
|
# Process this file with autoconf to produce a configure script
|
||||||
|
|
||||||
AC_PREREQ(2.65)
|
AC_PREREQ(2.65)
|
||||||
AC_INIT([xrdp], [0.9.9], [xrdp-devel@googlegroups.com])
|
AC_INIT([xrdp], [0.9.10], [xrdp-devel@googlegroups.com])
|
||||||
AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in)
|
AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in)
|
||||||
AM_INIT_AUTOMAKE([1.7.2 foreign])
|
AM_INIT_AUTOMAKE([1.7.2 foreign])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
@ -196,6 +196,12 @@ login for all users is enabled.
|
|||||||
\fIThis option is currently ignored!\fR Only members of this group can
|
\fIThis option is currently ignored!\fR Only members of this group can
|
||||||
have session management rights.
|
have session management rights.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fBRestrictOutboundClipboard\fR=\fI[true|false]\fR
|
||||||
|
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, will restrict the clipboard
|
||||||
|
outbound from the server, to prevent data copied inside the xrdp session
|
||||||
|
to be be pasted in the client host. Default value is \fBfalse\fR.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBAlwaysGroupCheck\fR=\fI[true|false]\fR
|
\fBAlwaysGroupCheck\fR=\fI[true|false]\fR
|
||||||
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, require group membership even
|
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, require group membership even
|
||||||
|
@ -23,15 +23,15 @@ Kills running \fBxrdp\-sesman\fR daemon.
|
|||||||
Output help information and exit.
|
Output help information and exit.
|
||||||
|
|
||||||
.SH "FILES"
|
.SH "FILES"
|
||||||
@bindir@/sesman
|
@bindir@/xrdp\-sesman
|
||||||
.br
|
.br
|
||||||
@bindir@/sesrun
|
@bindir@/xrdp\-sesrun
|
||||||
.br
|
.br
|
||||||
@sysconfdir@/xrdp/sesman.ini
|
@sysconfdir@/xrdp/sesman.ini
|
||||||
.br
|
.br
|
||||||
@localstatedir@/log/sesman.log
|
@localstatedir@/log/xrdp\-sesman.log
|
||||||
.br
|
.br
|
||||||
@localstatedir@/run/sesman.pid
|
@localstatedir@/run/xrdp\-sesman.pid
|
||||||
|
|
||||||
.SH "AUTHORS"
|
.SH "AUTHORS"
|
||||||
Jay Sorg <jsorg71@users.sourceforge.net>
|
Jay Sorg <jsorg71@users.sourceforge.net>
|
||||||
|
@ -32,9 +32,9 @@ Screen height
|
|||||||
Session color depth
|
Session color depth
|
||||||
|
|
||||||
.SH "FILES"
|
.SH "FILES"
|
||||||
@bindir@/sesman
|
@bindir@/xrdp\-sesman
|
||||||
.br
|
.br
|
||||||
@bindir@/sesrun
|
@bindir@/xrdp\-sesrun
|
||||||
|
|
||||||
.SH "AUTHORS"
|
.SH "AUTHORS"
|
||||||
Jay Sorg <jsorg71@users.sourceforge.net>
|
Jay Sorg <jsorg71@users.sourceforge.net>
|
||||||
|
@ -30,6 +30,7 @@ SUFFIXES = .in
|
|||||||
startscriptdir=$(sysconfdir)/xrdp
|
startscriptdir=$(sysconfdir)/xrdp
|
||||||
|
|
||||||
dist_startscript_DATA = \
|
dist_startscript_DATA = \
|
||||||
|
km-00000406.ini \
|
||||||
km-00000407.ini \
|
km-00000407.ini \
|
||||||
km-00000409.ini \
|
km-00000409.ini \
|
||||||
km-0000040a.ini \
|
km-0000040a.ini \
|
||||||
|
659
instfiles/km-00000406.ini
Normal file
659
instfiles/km-00000406.ini
Normal file
@ -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=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=168: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=230:230
|
||||||
|
Key48=248:248
|
||||||
|
Key49=189:189
|
||||||
|
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=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=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=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=94: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=198:198
|
||||||
|
Key48=216:216
|
||||||
|
Key49=167:167
|
||||||
|
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=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=65452:44
|
||||||
|
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=65027: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=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=124:124
|
||||||
|
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=126: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=106:106
|
||||||
|
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=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=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=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=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=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=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=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=65452:44
|
||||||
|
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=65027: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
|
@ -59,6 +59,7 @@ int g_cliprdr_chan_id = -1; /* cliprdr */
|
|||||||
int g_rdpsnd_chan_id = -1; /* rdpsnd */
|
int g_rdpsnd_chan_id = -1; /* rdpsnd */
|
||||||
int g_rdpdr_chan_id = -1; /* rdpdr */
|
int g_rdpdr_chan_id = -1; /* rdpdr */
|
||||||
int g_rail_chan_id = -1; /* rail */
|
int g_rail_chan_id = -1; /* rail */
|
||||||
|
int g_restrict_outbound_clipboard = 0;
|
||||||
|
|
||||||
char *g_exec_name;
|
char *g_exec_name;
|
||||||
tbus g_exec_event;
|
tbus g_exec_event;
|
||||||
@ -1780,7 +1781,7 @@ main(int argc, char **argv)
|
|||||||
enum logReturns error;
|
enum logReturns error;
|
||||||
struct log_config logconfig;
|
struct log_config logconfig;
|
||||||
enum logLevels log_level;
|
enum logLevels log_level;
|
||||||
|
char *restrict_outbound_clipboard_env;
|
||||||
g_init("xrdp-chansrv"); /* os_calls */
|
g_init("xrdp-chansrv"); /* os_calls */
|
||||||
|
|
||||||
log_path[255] = 0;
|
log_path[255] = 0;
|
||||||
@ -1791,6 +1792,15 @@ main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restrict_outbound_clipboard_env = g_getenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD");
|
||||||
|
if (restrict_outbound_clipboard_env != 0)
|
||||||
|
{
|
||||||
|
if (g_strcmp(restrict_outbound_clipboard_env, "1") == 0)
|
||||||
|
{
|
||||||
|
g_restrict_outbound_clipboard = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
read_ini();
|
read_ini();
|
||||||
pid = g_getpid();
|
pid = g_getpid();
|
||||||
display_text = g_getenv("DISPLAY");
|
display_text = g_getenv("DISPLAY");
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -19,31 +19,27 @@
|
|||||||
#ifndef _CHANSRV_FUSE_H
|
#ifndef _CHANSRV_FUSE_H
|
||||||
#define _CHANSRV_FUSE_H
|
#define _CHANSRV_FUSE_H
|
||||||
|
|
||||||
/* a file or dir entry in the xrdp file system */
|
#include "arch.h"
|
||||||
struct xrdp_inode
|
|
||||||
|
/*
|
||||||
|
* a file or dir entry in the xrdp file system (opaque type externally) */
|
||||||
|
struct xrdp_inode;
|
||||||
|
|
||||||
|
/* Used to pass file info in to xfuse_devredir_add_file_or_dir()
|
||||||
|
*
|
||||||
|
* The string storage the name field points to is only valid
|
||||||
|
* for the duration of the xfuse_devredir_add_file_or_dir()
|
||||||
|
* call
|
||||||
|
*/
|
||||||
|
struct file_attr
|
||||||
{
|
{
|
||||||
tui32 parent_inode; /* Parent serial number. */
|
const char *name; /* Name of file or directory */
|
||||||
tui32 inode; /* File serial number. */
|
|
||||||
tui32 mode; /* File mode. */
|
tui32 mode; /* File mode. */
|
||||||
tui32 nlink; /* symbolic link count. */
|
|
||||||
tui32 nentries; /* number of entries in a dir */
|
|
||||||
tui32 nopen; /* number of simultaneous opens */
|
|
||||||
tui32 uid; /* User ID of the file's owner. */
|
|
||||||
tui32 gid; /* Group ID of the file's group. */
|
|
||||||
size_t size; /* Size of file, in bytes. */
|
size_t size; /* Size of file, in bytes. */
|
||||||
time_t atime; /* Time of last access. */
|
time_t atime; /* Time of last access. */
|
||||||
time_t mtime; /* Time of last modification. */
|
time_t mtime; /* Time of last modification. */
|
||||||
time_t ctime; /* Time of last status change. */
|
time_t ctime; /* Time of last status change. */
|
||||||
char name[1024]; /* Dir or filename */
|
|
||||||
tui32 device_id; /* for file system redirection */
|
|
||||||
char is_synced; /* dir struct has been read from */
|
|
||||||
/* remote device, done just once */
|
|
||||||
int lindex; /* used in clipboard operations */
|
|
||||||
int is_loc_resource; /* this is not a redirected resource */
|
|
||||||
int close_in_progress; /* close cmd sent to client */
|
|
||||||
int stale; /* mark file as stale, ok to remove */
|
|
||||||
};
|
};
|
||||||
typedef struct xrdp_inode XRDP_INODE; // LK_TODO use this instead of using struct xrdp_inode
|
|
||||||
|
|
||||||
int xfuse_init(void);
|
int xfuse_init(void);
|
||||||
int xfuse_deinit(void);
|
int xfuse_deinit(void);
|
||||||
@ -57,9 +53,18 @@ int xfuse_file_contents_size(int stream_id, int file_size);
|
|||||||
int xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex);
|
int xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex);
|
||||||
|
|
||||||
/* functions that are invoked from devredir */
|
/* functions that are invoked from devredir */
|
||||||
int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode);
|
struct xrdp_inode *xfuse_devredir_add_file_or_dir(
|
||||||
|
void *vp,
|
||||||
|
const struct file_attr *file_info);
|
||||||
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus);
|
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus);
|
||||||
|
void xfuse_devredir_cb_lookup_entry(void *vp, tui32 IoStatus,
|
||||||
|
struct xrdp_inode *xinode);
|
||||||
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId);
|
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId);
|
||||||
|
void xfuse_devredir_cb_write_file(
|
||||||
|
void *vp,
|
||||||
|
tui32 IoStatus,
|
||||||
|
const char *buf,
|
||||||
|
size_t length);
|
||||||
void xfuse_devredir_cb_read_file(void *vp, const char *buf, size_t length);
|
void xfuse_devredir_cb_read_file(void *vp, const char *buf, size_t length);
|
||||||
void xfuse_devredir_cb_rmdir_or_file(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);
|
void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus);
|
||||||
|
@ -185,38 +185,38 @@ x-special/gnome-copied-files
|
|||||||
#define LOG_LEVEL LOG_ERROR
|
#define LOG_LEVEL LOG_ERROR
|
||||||
|
|
||||||
#define log_error(_params...) \
|
#define log_error(_params...) \
|
||||||
{ \
|
{ \
|
||||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ERROR: ", \
|
g_write("[%10.10u]: CLIPBOARD %s: %d : ERROR: ", \
|
||||||
g_time3(), __func__, __LINE__); \
|
g_time3(), __func__, __LINE__); \
|
||||||
g_writeln (_params); \
|
g_writeln (_params); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define log_always(_params...) \
|
#define log_always(_params...) \
|
||||||
{ \
|
{ \
|
||||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ALWAYS: ", \
|
g_write("[%10.10u]: CLIPBOARD %s: %d : ALWAYS: ", \
|
||||||
g_time3(), __func__, __LINE__); \
|
g_time3(), __func__, __LINE__); \
|
||||||
g_writeln (_params); \
|
g_writeln (_params); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define log_info(_params...) \
|
#define log_info(_params...) \
|
||||||
{ \
|
{ \
|
||||||
if (LOG_INFO <= LOG_LEVEL) \
|
if (LOG_INFO <= LOG_LEVEL) \
|
||||||
{ \
|
{ \
|
||||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
|
g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
|
||||||
g_time3(), __func__, __LINE__); \
|
g_time3(), __func__, __LINE__); \
|
||||||
g_writeln (_params); \
|
g_writeln (_params); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define log_debug(_params...) \
|
#define log_debug(_params...) \
|
||||||
{ \
|
{ \
|
||||||
if (LOG_DEBUG <= LOG_LEVEL) \
|
if (LOG_DEBUG <= LOG_LEVEL) \
|
||||||
{ \
|
{ \
|
||||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
|
g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
|
||||||
g_time3(), __func__, __LINE__); \
|
g_time3(), __func__, __LINE__); \
|
||||||
g_writeln (_params); \
|
g_writeln (_params); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
static char g_bmp_image_header[] =
|
static char g_bmp_image_header[] =
|
||||||
{
|
{
|
||||||
@ -235,6 +235,8 @@ extern tbus g_x_wait_obj; /* in xcommon.c */
|
|||||||
extern Screen *g_screen; /* in xcommon.c */
|
extern Screen *g_screen; /* in xcommon.c */
|
||||||
extern int g_screen_num; /* in xcommon.c */
|
extern int g_screen_num; /* in xcommon.c */
|
||||||
|
|
||||||
|
extern int g_restrict_outbound_clipboard; /* in chansrv.c */
|
||||||
|
|
||||||
int g_clip_up = 0;
|
int g_clip_up = 0;
|
||||||
|
|
||||||
static Atom g_clipboard_atom = 0; /* CLIPBOARD */
|
static Atom g_clipboard_atom = 0; /* CLIPBOARD */
|
||||||
@ -286,10 +288,10 @@ static int g_file_format_id = -1;
|
|||||||
static char g_last_atom_name[256] = "";
|
static char g_last_atom_name[256] = "";
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
static char*
|
static char *
|
||||||
get_atom_text(Atom atom)
|
get_atom_text(Atom atom)
|
||||||
{
|
{
|
||||||
char* name;
|
char *name;
|
||||||
int failed;
|
int failed;
|
||||||
|
|
||||||
failed = 0;
|
failed = 0;
|
||||||
@ -405,10 +407,10 @@ clipboard_init(void)
|
|||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_init: g_xfixes_event_base %d",
|
log_debug("clipboard_init: g_xfixes_event_base %d",
|
||||||
g_xfixes_event_base);
|
g_xfixes_event_base);
|
||||||
st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
|
st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
|
||||||
log_debug("clipboard_init st %d, maj %d min %d", st,
|
log_debug("clipboard_init st %d, maj %d min %d", st,
|
||||||
ver_maj, ver_min);
|
ver_maj, ver_min);
|
||||||
g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
|
g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
|
||||||
False);
|
False);
|
||||||
g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM",
|
g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM",
|
||||||
@ -428,7 +430,7 @@ clipboard_init(void)
|
|||||||
if (g_image_bmp_atom == None)
|
if (g_image_bmp_atom == None)
|
||||||
{
|
{
|
||||||
log_error("clipboard_init: g_image_bmp_atom was "
|
log_error("clipboard_init: g_image_bmp_atom was "
|
||||||
"not allocated");
|
"not allocated");
|
||||||
}
|
}
|
||||||
|
|
||||||
g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen),
|
g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen),
|
||||||
@ -463,12 +465,12 @@ clipboard_init(void)
|
|||||||
s_mark_end(s);
|
s_mark_end(s);
|
||||||
size = (int)(s->end - s->data);
|
size = (int)(s->end - s->data);
|
||||||
log_debug("clipboard_init: data out, sending "
|
log_debug("clipboard_init: data out, sending "
|
||||||
"CB_CLIP_CAPS (clip_msg_id = 1)");
|
"CB_CLIP_CAPS (clip_msg_id = 1)");
|
||||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||||
if (rv != 0)
|
if (rv != 0)
|
||||||
{
|
{
|
||||||
log_error("clipboard_init: send_channel_data failed "
|
log_error("clipboard_init: send_channel_data failed "
|
||||||
"rv = %d", rv);
|
"rv = %d", rv);
|
||||||
rv = 4;
|
rv = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -484,12 +486,12 @@ clipboard_init(void)
|
|||||||
s_mark_end(s);
|
s_mark_end(s);
|
||||||
size = (int)(s->end - s->data);
|
size = (int)(s->end - s->data);
|
||||||
log_debug("clipboard_init: data out, sending "
|
log_debug("clipboard_init: data out, sending "
|
||||||
"CB_MONITOR_READY (clip_msg_id = 1)");
|
"CB_MONITOR_READY (clip_msg_id = 1)");
|
||||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||||
if (rv != 0)
|
if (rv != 0)
|
||||||
{
|
{
|
||||||
log_error("clipboard_init: send_channel_data failed "
|
log_error("clipboard_init: send_channel_data failed "
|
||||||
"rv = %d", rv);
|
"rv = %d", rv);
|
||||||
rv = 4;
|
rv = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -554,7 +556,7 @@ clipboard_send_data_request(int format_id)
|
|||||||
s_mark_end(s);
|
s_mark_end(s);
|
||||||
size = (int)(s->end - s->data);
|
size = (int)(s->end - s->data);
|
||||||
log_debug("clipboard_send_data_request: data out, sending "
|
log_debug("clipboard_send_data_request: data out, sending "
|
||||||
"CLIPRDR_DATA_REQUEST (clip_msg_id = 4)");
|
"CLIPRDR_DATA_REQUEST (clip_msg_id = 4)");
|
||||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
return rv;
|
return rv;
|
||||||
@ -577,7 +579,7 @@ clipboard_send_format_ack(void)
|
|||||||
s_mark_end(s);
|
s_mark_end(s);
|
||||||
size = (int)(s->end - s->data);
|
size = (int)(s->end - s->data);
|
||||||
log_debug("clipboard_send_format_ack: data out, sending "
|
log_debug("clipboard_send_format_ack: data out, sending "
|
||||||
"CLIPRDR_FORMAT_ACK (clip_msg_id = 3)");
|
"CLIPRDR_FORMAT_ACK (clip_msg_id = 3)");
|
||||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
return rv;
|
return rv;
|
||||||
@ -715,7 +717,7 @@ clipboard_send_format_announce(int xrdp_clip_type)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("clipboard_send_format_announce: unknown "
|
log_debug("clipboard_send_format_announce: unknown "
|
||||||
"xrdp_clip_type %d", xrdp_clip_type);
|
"xrdp_clip_type %d", xrdp_clip_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -759,7 +761,7 @@ clipboard_send_format_announce(int xrdp_clip_type)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("clipboard_send_format_announce: unknown "
|
log_debug("clipboard_send_format_announce: unknown "
|
||||||
"xrdp_clip_type %d", xrdp_clip_type);
|
"xrdp_clip_type %d", xrdp_clip_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -774,7 +776,7 @@ clipboard_send_format_announce(int xrdp_clip_type)
|
|||||||
size = (int)(s->end - s->data);
|
size = (int)(s->end - s->data);
|
||||||
//g_hexdump(s->data, size);
|
//g_hexdump(s->data, size);
|
||||||
log_debug("clipboard_send_format_announce: data out, sending "
|
log_debug("clipboard_send_format_announce: data out, sending "
|
||||||
"CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)");
|
"CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)");
|
||||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
return rv;
|
return rv;
|
||||||
@ -789,7 +791,7 @@ clipboard_send_data_response_for_image(const char *data, int data_size)
|
|||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
log_debug("clipboard_send_data_response_for_image: data_size %d",
|
log_debug("clipboard_send_data_response_for_image: data_size %d",
|
||||||
data_size);
|
data_size);
|
||||||
make_stream(s);
|
make_stream(s);
|
||||||
init_stream(s, 64 + data_size);
|
init_stream(s, 64 + data_size);
|
||||||
out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */
|
out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */
|
||||||
@ -814,17 +816,17 @@ clipboard_send_data_response_for_text(const char *data, int data_size)
|
|||||||
int num_chars;
|
int num_chars;
|
||||||
|
|
||||||
log_debug("clipboard_send_data_response_for_text: data_size %d",
|
log_debug("clipboard_send_data_response_for_text: data_size %d",
|
||||||
data_size);
|
data_size);
|
||||||
//g_hexdump(data, data_size);
|
//g_hexdump(data, data_size);
|
||||||
num_chars = g_mbstowcs(0, data, 0);
|
num_chars = g_mbstowcs(0, data, 0);
|
||||||
if (num_chars < 0)
|
if (num_chars < 0)
|
||||||
{
|
{
|
||||||
log_error("clipboard_send_data_response_for_text: "
|
log_error("clipboard_send_data_response_for_text: "
|
||||||
"bad string");
|
"bad string");
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
}
|
}
|
||||||
log_debug("clipboard_send_data_response_for_text: data_size %d "
|
log_debug("clipboard_send_data_response_for_text: data_size %d "
|
||||||
"num_chars %d", data_size, num_chars);
|
"num_chars %d", data_size, num_chars);
|
||||||
make_stream(s);
|
make_stream(s);
|
||||||
init_stream(s, 64 + num_chars * 2);
|
init_stream(s, 64 + num_chars * 2);
|
||||||
out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */
|
out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */
|
||||||
@ -833,15 +835,15 @@ clipboard_send_data_response_for_text(const char *data, int data_size)
|
|||||||
if (clipboard_out_unicode(s, data, num_chars) != num_chars * 2)
|
if (clipboard_out_unicode(s, data, num_chars) != num_chars * 2)
|
||||||
{
|
{
|
||||||
log_error("clipboard_send_data_response_for_text: error "
|
log_error("clipboard_send_data_response_for_text: error "
|
||||||
"clipboard_out_unicode didn't write right number of bytes");
|
"clipboard_out_unicode didn't write right number of bytes");
|
||||||
}
|
}
|
||||||
out_uint16_le(s, 0); /* nil for string */
|
out_uint16_le(s, 0); /* nil for string */
|
||||||
out_uint32_le(s, 0);
|
out_uint32_le(s, 0);
|
||||||
s_mark_end(s);
|
s_mark_end(s);
|
||||||
size = (int)(s->end - s->data);
|
size = (int)(s->end - s->data);
|
||||||
log_debug("clipboard_send_data_response_for_text: data out, "
|
log_debug("clipboard_send_data_response_for_text: data out, "
|
||||||
"sending CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d "
|
"sending CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d "
|
||||||
"num_chars %d", size, num_chars);
|
"num_chars %d", size, num_chars);
|
||||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
return rv;
|
return rv;
|
||||||
@ -869,7 +871,7 @@ clipboard_send_data_response(int xrdp_clip_type, const char *data, int data_size
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_debug("clipboard_send_data_response: unknown "
|
log_debug("clipboard_send_data_response: unknown "
|
||||||
"xrdp_clip_type %d", xrdp_clip_type);
|
"xrdp_clip_type %d", xrdp_clip_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -908,7 +910,7 @@ clipboard_provide_selection_c2s(XSelectionRequestEvent *req, Atom type)
|
|||||||
long val1[2];
|
long val1[2];
|
||||||
|
|
||||||
log_debug("clipboard_provide_selection_c2s: bytes %d",
|
log_debug("clipboard_provide_selection_c2s: bytes %d",
|
||||||
g_clip_c2s.total_bytes);
|
g_clip_c2s.total_bytes);
|
||||||
if (g_clip_c2s.total_bytes < g_incr_max_req_size)
|
if (g_clip_c2s.total_bytes < g_incr_max_req_size)
|
||||||
{
|
{
|
||||||
XChangeProperty(g_display, req->requestor, req->property,
|
XChangeProperty(g_display, req->requestor, req->property,
|
||||||
@ -934,8 +936,8 @@ clipboard_provide_selection_c2s(XSelectionRequestEvent *req, Atom type)
|
|||||||
g_clip_c2s.property = req->property;
|
g_clip_c2s.property = req->property;
|
||||||
g_clip_c2s.window = req->requestor;
|
g_clip_c2s.window = req->requestor;
|
||||||
log_debug("clipboard_provide_selection_c2s: start INCR property %s "
|
log_debug("clipboard_provide_selection_c2s: start INCR property %s "
|
||||||
"type %s", get_atom_text(req->property),
|
"type %s", get_atom_text(req->property),
|
||||||
get_atom_text(type));
|
get_atom_text(type));
|
||||||
val1[0] = g_clip_c2s.total_bytes;
|
val1[0] = g_clip_c2s.total_bytes;
|
||||||
val1[1] = 0;
|
val1[1] = 0;
|
||||||
XChangeProperty(g_display, req->requestor, req->property,
|
XChangeProperty(g_display, req->requestor, req->property,
|
||||||
@ -1020,7 +1022,7 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
|
|||||||
char *holdp;
|
char *holdp;
|
||||||
|
|
||||||
log_debug("clipboard_process_format_announce: "
|
log_debug("clipboard_process_format_announce: "
|
||||||
"CLIPRDR_FORMAT_ANNOUNCE");
|
"CLIPRDR_FORMAT_ANNOUNCE");
|
||||||
log_debug("clipboard_process_format_announce %d", clip_msg_len);
|
log_debug("clipboard_process_format_announce %d", clip_msg_len);
|
||||||
clipboard_send_format_ack();
|
clipboard_send_format_ack();
|
||||||
|
|
||||||
@ -1052,8 +1054,8 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
|
|||||||
clip_msg_len -= 32;
|
clip_msg_len -= 32;
|
||||||
}
|
}
|
||||||
log_debug("clipboard_process_format_announce: formatId 0x%8.8x "
|
log_debug("clipboard_process_format_announce: formatId 0x%8.8x "
|
||||||
"wszFormatName [%s] clip_msg_len %d", formatId, desc,
|
"wszFormatName [%s] clip_msg_len %d", formatId, desc,
|
||||||
clip_msg_len);
|
clip_msg_len);
|
||||||
if (g_num_formatIds <= 15)
|
if (g_num_formatIds <= 15)
|
||||||
{
|
{
|
||||||
g_formatIds[g_num_formatIds] = formatId;
|
g_formatIds[g_num_formatIds] = formatId;
|
||||||
@ -1073,13 +1075,13 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((g_num_formatIds > 0) &&
|
if ((g_num_formatIds > 0) &&
|
||||||
(g_clip_c2s.incr_in_progress == 0) && /* don't interrupt incr */
|
(g_clip_c2s.incr_in_progress == 0) && /* don't interrupt incr */
|
||||||
(g_clip_s2c.incr_in_progress == 0))
|
(g_clip_s2c.incr_in_progress == 0))
|
||||||
{
|
{
|
||||||
if (clipboard_set_selection_owner() != 0)
|
if (clipboard_set_selection_owner() != 0)
|
||||||
{
|
{
|
||||||
log_error("clipboard_process_format_announce: "
|
log_error("clipboard_process_format_announce: "
|
||||||
"XSetSelectionOwner failed");
|
"XSetSelectionOwner failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1130,7 +1132,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
|||||||
int requestedFormatId;
|
int requestedFormatId;
|
||||||
|
|
||||||
log_debug("clipboard_process_data_request: "
|
log_debug("clipboard_process_data_request: "
|
||||||
"CLIPRDR_DATA_REQUEST");
|
"CLIPRDR_DATA_REQUEST");
|
||||||
log_debug("clipboard_process_data_request:");
|
log_debug("clipboard_process_data_request:");
|
||||||
log_debug(" %d", g_clip_s2c.xrdp_clip_type);
|
log_debug(" %d", g_clip_s2c.xrdp_clip_type);
|
||||||
in_uint32_le(s, requestedFormatId);
|
in_uint32_le(s, requestedFormatId);
|
||||||
@ -1146,7 +1148,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_debug("clipboard_process_data_request: CB_FORMAT_FILE, "
|
log_debug("clipboard_process_data_request: CB_FORMAT_FILE, "
|
||||||
"calling XConvertSelection to g_utf8_atom");
|
"calling XConvertSelection to g_utf8_atom");
|
||||||
g_clip_s2c.xrdp_clip_type = XRDP_CB_FILE;
|
g_clip_s2c.xrdp_clip_type = XRDP_CB_FILE;
|
||||||
XConvertSelection(g_display, g_clipboard_atom, g_clip_s2c.type,
|
XConvertSelection(g_display, g_clipboard_atom, g_clip_s2c.type,
|
||||||
g_clip_property_atom, g_wnd, CurrentTime);
|
g_clip_property_atom, g_wnd, CurrentTime);
|
||||||
@ -1162,7 +1164,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_debug("clipboard_process_data_request: CB_FORMAT_DIB, "
|
log_debug("clipboard_process_data_request: CB_FORMAT_DIB, "
|
||||||
"calling XConvertSelection to g_image_bmp_atom");
|
"calling XConvertSelection to g_image_bmp_atom");
|
||||||
g_clip_s2c.xrdp_clip_type = XRDP_CB_BITMAP;
|
g_clip_s2c.xrdp_clip_type = XRDP_CB_BITMAP;
|
||||||
XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom,
|
XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom,
|
||||||
g_clip_property_atom, g_wnd, CurrentTime);
|
g_clip_property_atom, g_wnd, CurrentTime);
|
||||||
@ -1178,7 +1180,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_debug("clipboard_process_data_request: CB_FORMAT_UNICODETEXT, "
|
log_debug("clipboard_process_data_request: CB_FORMAT_UNICODETEXT, "
|
||||||
"calling XConvertSelection to g_utf8_atom");
|
"calling XConvertSelection to g_utf8_atom");
|
||||||
g_clip_s2c.xrdp_clip_type = XRDP_CB_TEXT;
|
g_clip_s2c.xrdp_clip_type = XRDP_CB_TEXT;
|
||||||
XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom,
|
XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom,
|
||||||
g_clip_property_atom, g_wnd, CurrentTime);
|
g_clip_property_atom, g_wnd, CurrentTime);
|
||||||
@ -1186,7 +1188,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("clipboard_process_data_request: unknown type %d",
|
log_debug("clipboard_process_data_request: unknown type %d",
|
||||||
requestedFormatId);
|
requestedFormatId);
|
||||||
clipboard_send_data_response_failed();
|
clipboard_send_data_response_failed();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1201,14 +1203,14 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
|||||||
clipboard data. */
|
clipboard data. */
|
||||||
static int
|
static int
|
||||||
clipboard_process_data_response_for_image(struct stream *s,
|
clipboard_process_data_response_for_image(struct stream *s,
|
||||||
int clip_msg_status,
|
int clip_msg_status,
|
||||||
int clip_msg_len)
|
int clip_msg_len)
|
||||||
{
|
{
|
||||||
XSelectionRequestEvent *lxev;
|
XSelectionRequestEvent *lxev;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
log_debug("clipboard_process_data_response_for_image: "
|
log_debug("clipboard_process_data_response_for_image: "
|
||||||
"CLIPRDR_DATA_RESPONSE_FOR_IMAGE");
|
"CLIPRDR_DATA_RESPONSE_FOR_IMAGE");
|
||||||
lxev = &g_saved_selection_req_event;
|
lxev = &g_saved_selection_req_event;
|
||||||
len = (int)(s->end - s->p);
|
len = (int)(s->end - s->p);
|
||||||
if (len < 1)
|
if (len < 1)
|
||||||
@ -1231,7 +1233,7 @@ clipboard_process_data_response_for_image(struct stream *s,
|
|||||||
g_memcpy(g_clip_c2s.data, g_bmp_image_header, 14);
|
g_memcpy(g_clip_c2s.data, g_bmp_image_header, 14);
|
||||||
in_uint8a(s, g_clip_c2s.data + 14, len);
|
in_uint8a(s, g_clip_c2s.data + 14, len);
|
||||||
log_debug("clipboard_process_data_response_for_image: calling "
|
log_debug("clipboard_process_data_response_for_image: calling "
|
||||||
"clipboard_provide_selection_c2s");
|
"clipboard_provide_selection_c2s");
|
||||||
clipboard_provide_selection_c2s(lxev, lxev->target);
|
clipboard_provide_selection_c2s(lxev, lxev->target);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1259,7 +1261,7 @@ clipboard_process_data_response(struct stream *s, int clip_msg_status,
|
|||||||
if (g_clip_c2s.xrdp_clip_type == XRDP_CB_BITMAP)
|
if (g_clip_c2s.xrdp_clip_type == XRDP_CB_BITMAP)
|
||||||
{
|
{
|
||||||
clipboard_process_data_response_for_image(s, clip_msg_status,
|
clipboard_process_data_response_for_image(s, clip_msg_status,
|
||||||
clip_msg_len);
|
clip_msg_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (g_clip_c2s.xrdp_clip_type == XRDP_CB_FILE)
|
if (g_clip_c2s.xrdp_clip_type == XRDP_CB_FILE)
|
||||||
@ -1287,7 +1289,7 @@ clipboard_process_data_response(struct stream *s, int clip_msg_status,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
log_debug("clipboard_process_data_response: "
|
log_debug("clipboard_process_data_response: "
|
||||||
"CLIPRDR_DATA_RESPONSE");
|
"CLIPRDR_DATA_RESPONSE");
|
||||||
len = (int)(s->end - s->p);
|
len = (int)(s->end - s->p);
|
||||||
if (len < 1)
|
if (len < 1)
|
||||||
{
|
{
|
||||||
@ -1362,10 +1364,10 @@ clipboard_process_clip_caps(struct stream *s, int clip_msg_status,
|
|||||||
in_uint32_le(s, version); /* version */
|
in_uint32_le(s, version); /* version */
|
||||||
in_uint32_le(s, flags); /* generalFlags */
|
in_uint32_le(s, flags); /* generalFlags */
|
||||||
log_debug("clipboard_process_clip_caps: "
|
log_debug("clipboard_process_clip_caps: "
|
||||||
"g_cliprdr_version %d version %d "
|
"g_cliprdr_version %d version %d "
|
||||||
"g_cliprdr_flags 0x%x flags 0x%x",
|
"g_cliprdr_flags 0x%x flags 0x%x",
|
||||||
g_cliprdr_version, version,
|
g_cliprdr_version, version,
|
||||||
g_cliprdr_flags, flags);
|
g_cliprdr_flags, flags);
|
||||||
if (version < g_cliprdr_version)
|
if (version < g_cliprdr_version)
|
||||||
{
|
{
|
||||||
g_cliprdr_version = version;
|
g_cliprdr_version = version;
|
||||||
@ -1374,7 +1376,7 @@ clipboard_process_clip_caps(struct stream *s, int clip_msg_status,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("clipboard_process_clip_caps: unknown "
|
log_debug("clipboard_process_clip_caps: unknown "
|
||||||
"capabilitySetType %d", capabilitySetType);
|
"capabilitySetType %d", capabilitySetType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s->p = holdp + lengthCapability;
|
s->p = holdp + lengthCapability;
|
||||||
@ -1552,16 +1554,16 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
|
|||||||
if (!g_clip_up)
|
if (!g_clip_up)
|
||||||
{
|
{
|
||||||
log_error("aborting clipboard_data_in - clipboard has not "
|
log_error("aborting clipboard_data_in - clipboard has not "
|
||||||
"been initialized");
|
"been initialized");
|
||||||
/* we return 0 here to indicate no protocol problem occurred */
|
/* we return 0 here to indicate no protocol problem occurred */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug("clipboard_data_in: chan_id %d "
|
log_debug("clipboard_data_in: chan_id %d "
|
||||||
"chan_flags 0x%x length %d total_length %d "
|
"chan_flags 0x%x length %d total_length %d "
|
||||||
"in_request %d g_ins->size %d",
|
"in_request %d g_ins->size %d",
|
||||||
chan_id, chan_flags, length, total_length,
|
chan_id, chan_flags, length, total_length,
|
||||||
g_clip_c2s.in_request, g_ins->size);
|
g_clip_c2s.in_request, g_ins->size);
|
||||||
|
|
||||||
if (g_clip_c2s.doing_response_ss)
|
if (g_clip_c2s.doing_response_ss)
|
||||||
{
|
{
|
||||||
@ -1621,37 +1623,37 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
|
|||||||
in_uint32_le(ls, clip_msg_len);
|
in_uint32_le(ls, clip_msg_len);
|
||||||
|
|
||||||
log_debug("clipboard_data_in: clip_msg_id %d "
|
log_debug("clipboard_data_in: clip_msg_id %d "
|
||||||
"clip_msg_status %d clip_msg_len %d",
|
"clip_msg_status %d clip_msg_len %d",
|
||||||
clip_msg_id, clip_msg_status, clip_msg_len);
|
clip_msg_id, clip_msg_status, clip_msg_len);
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
|
||||||
log_debug("clipboard_data_in: %d", clip_msg_id);
|
log_debug("clipboard_data_in: %d", clip_msg_id);
|
||||||
switch (clip_msg_id)
|
switch (clip_msg_id)
|
||||||
{
|
{
|
||||||
/* sent by client or server when its local system clipboard is */
|
/* sent by client or server when its local system clipboard is */
|
||||||
/* updated with new clipboard data; contains Clipboard Format ID */
|
/* updated with new clipboard data; contains Clipboard Format ID */
|
||||||
/* and name pairs of new Clipboard Formats on the clipboard. */
|
/* and name pairs of new Clipboard Formats on the clipboard. */
|
||||||
case CB_FORMAT_LIST: /* 2 CLIPRDR_FORMAT_ANNOUNCE */
|
case CB_FORMAT_LIST: /* 2 CLIPRDR_FORMAT_ANNOUNCE */
|
||||||
rv = clipboard_process_format_announce(ls, clip_msg_status,
|
rv = clipboard_process_format_announce(ls, clip_msg_status,
|
||||||
clip_msg_len);
|
clip_msg_len);
|
||||||
break;
|
break;
|
||||||
/* response to CB_FORMAT_LIST; used to indicate whether */
|
/* response to CB_FORMAT_LIST; used to indicate whether */
|
||||||
/* processing of the Format List PDU was successful */
|
/* processing of the Format List PDU was successful */
|
||||||
case CB_FORMAT_LIST_RESPONSE: /* 3 CLIPRDR_FORMAT_ACK */
|
case CB_FORMAT_LIST_RESPONSE: /* 3 CLIPRDR_FORMAT_ACK */
|
||||||
rv = clipboard_process_format_ack(ls, clip_msg_status,
|
rv = clipboard_process_format_ack(ls, clip_msg_status,
|
||||||
clip_msg_len);
|
clip_msg_len);
|
||||||
break;
|
break;
|
||||||
/* sent by recipient of CB_FORMAT_LIST; used to request data for one */
|
/* sent by recipient of CB_FORMAT_LIST; used to request data for one */
|
||||||
/* of the formats that was listed in CB_FORMAT_LIST */
|
/* of the formats that was listed in CB_FORMAT_LIST */
|
||||||
case CB_FORMAT_DATA_REQUEST: /* 4 CLIPRDR_DATA_REQUEST */
|
case CB_FORMAT_DATA_REQUEST: /* 4 CLIPRDR_DATA_REQUEST */
|
||||||
rv = clipboard_process_data_request(ls, clip_msg_status,
|
rv = clipboard_process_data_request(ls, clip_msg_status,
|
||||||
clip_msg_len);
|
clip_msg_len);
|
||||||
break;
|
break;
|
||||||
/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */
|
/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */
|
||||||
/* whether processing of the CB_FORMAT_DATA_REQUEST was */
|
/* whether processing of the CB_FORMAT_DATA_REQUEST was */
|
||||||
/* successful; if processing was successful, */
|
/* successful; if processing was successful, */
|
||||||
/* CB_FORMAT_DATA_RESPONSE includes contents of requested */
|
/* CB_FORMAT_DATA_RESPONSE includes contents of requested */
|
||||||
/* clipboard data. */
|
/* clipboard data. */
|
||||||
case CB_FORMAT_DATA_RESPONSE: /* 5 CLIPRDR_DATA_RESPONSE */
|
case CB_FORMAT_DATA_RESPONSE: /* 5 CLIPRDR_DATA_RESPONSE */
|
||||||
rv = clipboard_process_data_response(ls, clip_msg_status,
|
rv = clipboard_process_data_response(ls, clip_msg_status,
|
||||||
clip_msg_len);
|
clip_msg_len);
|
||||||
@ -1671,7 +1673,7 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
|
|||||||
default:
|
default:
|
||||||
log_debug("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id);
|
log_debug("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id);
|
||||||
log_error("clipboard_data_in: unknown clip_msg_id %d",
|
log_error("clipboard_data_in: unknown clip_msg_id %d",
|
||||||
clip_msg_id);
|
clip_msg_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1703,21 +1705,22 @@ clipboard_event_selection_owner_notify(XEvent *xevent)
|
|||||||
lxevent = (XFixesSelectionNotifyEvent *)xevent;
|
lxevent = (XFixesSelectionNotifyEvent *)xevent;
|
||||||
log_debug("clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner);
|
log_debug("clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner);
|
||||||
log_debug("clipboard_event_selection_owner_notify: "
|
log_debug("clipboard_event_selection_owner_notify: "
|
||||||
"window %ld subtype %d owner %ld g_wnd %ld",
|
"window %ld subtype %d owner %ld g_wnd %ld",
|
||||||
lxevent->window, lxevent->subtype, lxevent->owner, g_wnd);
|
lxevent->window, lxevent->subtype, lxevent->owner, g_wnd);
|
||||||
|
|
||||||
if (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: matches g_wnd");
|
||||||
log_debug("clipboard_event_selection_owner_notify: skipping, "
|
log_debug("clipboard_event_selection_owner_notify: skipping, "
|
||||||
"owner == g_wnd");
|
"owner == g_wnd");
|
||||||
g_got_selection = 1;
|
g_got_selection = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_got_selection = 0;
|
g_got_selection = 0;
|
||||||
if (lxevent->owner != 0) /* nil owner comes when selection */
|
if (lxevent->owner != 0) /* nil owner comes when selection */
|
||||||
{ /* window is closed */
|
{
|
||||||
|
/* window is closed */
|
||||||
XConvertSelection(g_display, g_clipboard_atom, g_targets_atom,
|
XConvertSelection(g_display, g_clipboard_atom, g_targets_atom,
|
||||||
g_clip_property_atom, g_wnd, lxevent->timestamp);
|
g_clip_property_atom, g_wnd, lxevent->timestamp);
|
||||||
}
|
}
|
||||||
@ -1871,22 +1874,22 @@ clipboard_event_selection_notify(XEvent *xevent)
|
|||||||
if (lxevent->property == None)
|
if (lxevent->property == None)
|
||||||
{
|
{
|
||||||
log_error("clipboard_event_selection_notify: clip could "
|
log_error("clipboard_event_selection_notify: clip could "
|
||||||
"not be converted");
|
"not be converted");
|
||||||
rv = 1;
|
rv = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_notify: wnd 0x%lx prop %s",
|
log_debug("clipboard_event_selection_notify: wnd 0x%lx prop %s",
|
||||||
lxevent->requestor,
|
lxevent->requestor,
|
||||||
get_atom_text(lxevent->property));
|
get_atom_text(lxevent->property));
|
||||||
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
|
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
|
||||||
&type, &fmt,
|
&type, &fmt,
|
||||||
&n_items, &data, &data_size);
|
&n_items, &data, &data_size);
|
||||||
if (rv != 0)
|
if (rv != 0)
|
||||||
{
|
{
|
||||||
log_error("clipboard_event_selection_notify: "
|
log_error("clipboard_event_selection_notify: "
|
||||||
"clipboard_get_window_property failed error %d", rv);
|
"clipboard_get_window_property failed error %d", rv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//g_hexdump(data, data_size);
|
//g_hexdump(data, data_size);
|
||||||
@ -1896,9 +1899,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
|||||||
/* nothing more to do here, the data is coming in through
|
/* nothing more to do here, the data is coming in through
|
||||||
PropertyNotify */
|
PropertyNotify */
|
||||||
log_debug("clipboard_event_selection_notify: type is INCR "
|
log_debug("clipboard_event_selection_notify: type is INCR "
|
||||||
"data_size %d property name %s type %s", data_size,
|
"data_size %d property name %s type %s", data_size,
|
||||||
get_atom_text(lxevent->property),
|
get_atom_text(lxevent->property),
|
||||||
get_atom_text(lxevent->type));
|
get_atom_text(lxevent->type));
|
||||||
g_clip_s2c.incr_in_progress = 1;
|
g_clip_s2c.incr_in_progress = 1;
|
||||||
g_clip_s2c.property = lxevent->property;
|
g_clip_s2c.property = lxevent->property;
|
||||||
g_clip_s2c.type = lxevent->target;
|
g_clip_s2c.type = lxevent->target;
|
||||||
@ -1928,7 +1931,7 @@ clipboard_event_selection_notify(XEvent *xevent)
|
|||||||
"clipboard_event_selection_notify: 0x%lx %s 0x%lx",
|
"clipboard_event_selection_notify: 0x%lx %s 0x%lx",
|
||||||
atom, get_atom_text(atom), XA_STRING));
|
atom, get_atom_text(atom), XA_STRING));
|
||||||
log_debug("clipboard_event_selection_notify: 0x%lx %s",
|
log_debug("clipboard_event_selection_notify: 0x%lx %s",
|
||||||
atom, get_atom_text(atom));
|
atom, get_atom_text(atom));
|
||||||
if (atom == g_utf8_atom)
|
if (atom == g_utf8_atom)
|
||||||
{
|
{
|
||||||
got_utf8 = 1;
|
got_utf8 = 1;
|
||||||
@ -1955,16 +1958,16 @@ clipboard_event_selection_notify(XEvent *xevent)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_error("clipboard_event_selection_notify: error, "
|
log_error("clipboard_event_selection_notify: error, "
|
||||||
"target is 'TARGETS' and type[%ld] or fmt[%d] not right, "
|
"target is 'TARGETS' and type[%ld] or fmt[%d] not right, "
|
||||||
"should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32);
|
"should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lxevent->target == g_utf8_atom)
|
else if (lxevent->target == g_utf8_atom)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_notify: UTF8_STRING "
|
log_debug("clipboard_event_selection_notify: UTF8_STRING "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
log_debug("clipboard_event_selection_notify: UTF8_STRING "
|
log_debug("clipboard_event_selection_notify: UTF8_STRING "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
||||||
{
|
{
|
||||||
g_free(g_clip_s2c.data);
|
g_free(g_clip_s2c.data);
|
||||||
@ -1987,9 +1990,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
|||||||
else if (lxevent->target == XA_STRING)
|
else if (lxevent->target == XA_STRING)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_notify: XA_STRING "
|
log_debug("clipboard_event_selection_notify: XA_STRING "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
log_debug("clipboard_event_selection_notify: XA_STRING "
|
log_debug("clipboard_event_selection_notify: XA_STRING "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
||||||
{
|
{
|
||||||
g_free(g_clip_s2c.data);
|
g_free(g_clip_s2c.data);
|
||||||
@ -2004,9 +2007,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
|||||||
else if (lxevent->target == g_image_bmp_atom)
|
else if (lxevent->target == g_image_bmp_atom)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_notify: image/bmp "
|
log_debug("clipboard_event_selection_notify: image/bmp "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
log_debug("clipboard_event_selection_notify: image/bmp "
|
log_debug("clipboard_event_selection_notify: image/bmp "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 14))
|
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 14))
|
||||||
{
|
{
|
||||||
g_free(g_clip_s2c.data);
|
g_free(g_clip_s2c.data);
|
||||||
@ -2020,9 +2023,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
|||||||
else if (lxevent->target == g_file_atom1)
|
else if (lxevent->target == g_file_atom1)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_notify: text/uri-list "
|
log_debug("clipboard_event_selection_notify: text/uri-list "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
log_debug("clipboard_event_selection_notify: text/uri-list "
|
log_debug("clipboard_event_selection_notify: text/uri-list "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
||||||
{
|
{
|
||||||
g_free(g_clip_s2c.data);
|
g_free(g_clip_s2c.data);
|
||||||
@ -2037,9 +2040,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
|||||||
else if (lxevent->target == g_file_atom2)
|
else if (lxevent->target == g_file_atom2)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_notify: text/uri-list "
|
log_debug("clipboard_event_selection_notify: text/uri-list "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
log_debug("clipboard_event_selection_notify: text/uri-list "
|
log_debug("clipboard_event_selection_notify: text/uri-list "
|
||||||
"data_size %d", data_size);
|
"data_size %d", data_size);
|
||||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
||||||
{
|
{
|
||||||
g_free(g_clip_s2c.data);
|
g_free(g_clip_s2c.data);
|
||||||
@ -2054,13 +2057,13 @@ clipboard_event_selection_notify(XEvent *xevent)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_error("clipboard_event_selection_notify: "
|
log_error("clipboard_event_selection_notify: "
|
||||||
"unknown target");
|
"unknown target");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_error("clipboard_event_selection_notify: "
|
log_error("clipboard_event_selection_notify: "
|
||||||
"unknown selection");
|
"unknown selection");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2145,24 +2148,24 @@ clipboard_event_selection_request(XEvent *xevent)
|
|||||||
lxev = (XSelectionRequestEvent *)xevent;
|
lxev = (XSelectionRequestEvent *)xevent;
|
||||||
log_debug("clipboard_event_selection_request: 0x%lx", lxev->property);
|
log_debug("clipboard_event_selection_request: 0x%lx", lxev->property);
|
||||||
log_debug("clipboard_event_selection_request: g_wnd %ld, "
|
log_debug("clipboard_event_selection_request: g_wnd %ld, "
|
||||||
".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld",
|
".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld",
|
||||||
g_wnd, lxev->requestor, lxev->owner, lxev->selection,
|
g_wnd, lxev->requestor, lxev->owner, lxev->selection,
|
||||||
get_atom_text(lxev->selection),
|
get_atom_text(lxev->selection),
|
||||||
lxev->target, lxev->property);
|
lxev->target, lxev->property);
|
||||||
|
|
||||||
if (lxev->property == None)
|
if (lxev->property == None)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_request: lxev->property "
|
log_debug("clipboard_event_selection_request: lxev->property "
|
||||||
"is None");
|
"is None");
|
||||||
log_debug("clipboard_event_selection_request: "
|
log_debug("clipboard_event_selection_request: "
|
||||||
"lxev->property is None");
|
"lxev->property is None");
|
||||||
}
|
}
|
||||||
else if (lxev->target == g_targets_atom)
|
else if (lxev->target == g_targets_atom)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_request: g_targets_atom");
|
log_debug("clipboard_event_selection_request: g_targets_atom");
|
||||||
/* requestor is asking what the selection can be converted to */
|
/* requestor is asking what the selection can be converted to */
|
||||||
log_debug("clipboard_event_selection_request: "
|
log_debug("clipboard_event_selection_request: "
|
||||||
"g_targets_atom");
|
"g_targets_atom");
|
||||||
atom_buf[0] = g_targets_atom;
|
atom_buf[0] = g_targets_atom;
|
||||||
atom_buf[1] = g_timestamp_atom;
|
atom_buf[1] = g_timestamp_atom;
|
||||||
atom_buf[2] = g_multiple_atom;
|
atom_buf[2] = g_multiple_atom;
|
||||||
@ -2193,7 +2196,7 @@ clipboard_event_selection_request(XEvent *xevent)
|
|||||||
{
|
{
|
||||||
/* requestor is asking the time I got the selection */
|
/* requestor is asking the time I got the selection */
|
||||||
log_debug("clipboard_event_selection_request: "
|
log_debug("clipboard_event_selection_request: "
|
||||||
"g_timestamp_atom");
|
"g_timestamp_atom");
|
||||||
atom_buf[0] = g_selection_time;
|
atom_buf[0] = g_selection_time;
|
||||||
atom_buf[1] = 0;
|
atom_buf[1] = 0;
|
||||||
return clipboard_provide_selection(lxev, XA_INTEGER, 32,
|
return clipboard_provide_selection(lxev, XA_INTEGER, 32,
|
||||||
@ -2203,7 +2206,7 @@ clipboard_event_selection_request(XEvent *xevent)
|
|||||||
{
|
{
|
||||||
/* target, property pairs */
|
/* target, property pairs */
|
||||||
log_debug("clipboard_event_selection_request: "
|
log_debug("clipboard_event_selection_request: "
|
||||||
"g_multiple_atom");
|
"g_multiple_atom");
|
||||||
|
|
||||||
xdata = 0;
|
xdata = 0;
|
||||||
if (clipboard_get_window_property(lxev->requestor, lxev->property,
|
if (clipboard_get_window_property(lxev->requestor, lxev->property,
|
||||||
@ -2211,7 +2214,7 @@ clipboard_event_selection_request(XEvent *xevent)
|
|||||||
&xdata_size) == 0)
|
&xdata_size) == 0)
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_request: g_multiple_atom "
|
log_debug("clipboard_event_selection_request: g_multiple_atom "
|
||||||
"n_items %d", n_items);
|
"n_items %d", n_items);
|
||||||
/* todo */
|
/* todo */
|
||||||
g_free(xdata);
|
g_free(xdata);
|
||||||
}
|
}
|
||||||
@ -2276,7 +2279,7 @@ clipboard_event_selection_request(XEvent *xevent)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_debug("clipboard_event_selection_request: unknown "
|
log_debug("clipboard_event_selection_request: unknown "
|
||||||
"target %s", get_atom_text(lxev->target));
|
"target %s", get_atom_text(lxev->target));
|
||||||
LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown "
|
LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown "
|
||||||
"target %s", get_atom_text(lxev->target)));
|
"target %s", get_atom_text(lxev->target)));
|
||||||
}
|
}
|
||||||
@ -2332,9 +2335,9 @@ clipboard_event_property_notify(XEvent *xevent)
|
|||||||
|
|
||||||
log_debug("clipboard_event_property_notify:");
|
log_debug("clipboard_event_property_notify:");
|
||||||
log_debug("clipboard_event_property_notify: PropertyNotify .window %ld "
|
log_debug("clipboard_event_property_notify: PropertyNotify .window %ld "
|
||||||
".state %d .atom %ld %s", xevent->xproperty.window,
|
".state %d .atom %ld %s", xevent->xproperty.window,
|
||||||
xevent->xproperty.state, xevent->xproperty.atom,
|
xevent->xproperty.state, xevent->xproperty.atom,
|
||||||
get_atom_text(xevent->xproperty.atom));
|
get_atom_text(xevent->xproperty.atom));
|
||||||
|
|
||||||
if (g_clip_c2s.incr_in_progress &&
|
if (g_clip_c2s.incr_in_progress &&
|
||||||
(xevent->xproperty.window == g_clip_c2s.window) &&
|
(xevent->xproperty.window == g_clip_c2s.window) &&
|
||||||
@ -2353,7 +2356,7 @@ clipboard_event_property_notify(XEvent *xevent)
|
|||||||
data = (tui8 *)(g_clip_c2s.data + g_clip_c2s.incr_bytes_done);
|
data = (tui8 *)(g_clip_c2s.data + g_clip_c2s.incr_bytes_done);
|
||||||
data_bytes = g_clip_c2s.read_bytes_done - g_clip_c2s.incr_bytes_done;
|
data_bytes = g_clip_c2s.read_bytes_done - g_clip_c2s.incr_bytes_done;
|
||||||
if ((data_bytes < 1) &&
|
if ((data_bytes < 1) &&
|
||||||
(g_clip_c2s.read_bytes_done < g_clip_c2s.total_bytes))
|
(g_clip_c2s.read_bytes_done < g_clip_c2s.total_bytes))
|
||||||
{
|
{
|
||||||
g_clip_c2s.incr_in_progress = 0;
|
g_clip_c2s.incr_in_progress = 0;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2423,7 +2426,7 @@ clipboard_event_property_notify(XEvent *xevent)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_error("clipboard_event_property_notify: error unknown type %ld",
|
log_error("clipboard_event_property_notify: error unknown type %ld",
|
||||||
g_clip_s2c.type);
|
g_clip_s2c.type);
|
||||||
clipboard_send_data_response_failed();
|
clipboard_send_data_response_failed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2484,6 +2487,8 @@ clipboard_xevent(void *xevent)
|
|||||||
{
|
{
|
||||||
XEvent *lxevent;
|
XEvent *lxevent;
|
||||||
|
|
||||||
|
log_debug("clipboard_xevent: event detected");
|
||||||
|
|
||||||
if (!g_clip_up)
|
if (!g_clip_up)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
@ -2494,7 +2499,15 @@ clipboard_xevent(void *xevent)
|
|||||||
switch (lxevent->type)
|
switch (lxevent->type)
|
||||||
{
|
{
|
||||||
case SelectionNotify:
|
case SelectionNotify:
|
||||||
clipboard_event_selection_notify(lxevent);
|
if (g_restrict_outbound_clipboard == 0)
|
||||||
|
{
|
||||||
|
clipboard_event_selection_notify(lxevent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_debug("outbound clipboard is restricted because of config");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SelectionRequest:
|
case SelectionRequest:
|
||||||
clipboard_event_selection_request(lxevent);
|
clipboard_event_selection_request(lxevent);
|
||||||
|
@ -91,6 +91,13 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Size of structs supported by IRP_MJ_QUERY_INFORMATION without
|
||||||
|
* trailing RESERVED fields (MS-RDPEFS 2.2.3.3.8)
|
||||||
|
*/
|
||||||
|
#define FILE_BASIC_INFORMATION_SIZE 36
|
||||||
|
#define FILE_STD_INFORMATION_SIZE 22
|
||||||
|
|
||||||
/* globals */
|
/* globals */
|
||||||
extern int g_rdpdr_chan_id; /* in chansrv.c */
|
extern int g_rdpdr_chan_id; /* in chansrv.c */
|
||||||
int g_is_printer_redir_supported = 0;
|
int g_is_printer_redir_supported = 0;
|
||||||
@ -106,7 +113,26 @@ tui32 g_device_id; /* unique device ID - announced by client */
|
|||||||
tui16 g_client_rdp_version; /* returned by client */
|
tui16 g_client_rdp_version; /* returned by client */
|
||||||
struct stream *g_input_stream = NULL;
|
struct stream *g_input_stream = NULL;
|
||||||
|
|
||||||
void xfuse_devredir_cb_write_file(void *vp, const char *buf, size_t length);
|
/*
|
||||||
|
* Local functions called from dev_redir_proc_device_iocompletion()
|
||||||
|
*/
|
||||||
|
static void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus);
|
||||||
|
static void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus);
|
||||||
|
static void devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus);
|
||||||
|
static void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus);
|
||||||
|
static void devredir_proc_cid_lookup_basic_entry(IRP *irp, tui32 IoStatus);
|
||||||
|
static void devredir_proc_cid_lookup_basic_entry_resp(
|
||||||
|
IRP *irp,
|
||||||
|
struct stream *s_in,
|
||||||
|
tui32 IoStatus);
|
||||||
|
static void devredir_proc_cid_lookup_std_entry_resp(
|
||||||
|
IRP *irp,
|
||||||
|
struct stream *s_in,
|
||||||
|
tui32 DeviceId,
|
||||||
|
tui32 CompletionId,
|
||||||
|
tui32 IoStatus);
|
||||||
|
/* Other local functions */
|
||||||
|
static void lookup_std_entry(IRP *irp);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int
|
int
|
||||||
@ -816,7 +842,8 @@ dev_redir_proc_device_iocompletion(struct stream *s)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length);
|
xfuse_devredir_cb_write_file(fuse_data->data_ptr, IoStatus,
|
||||||
|
s->p, Length);
|
||||||
devredir_irp_delete(irp);
|
devredir_irp_delete(irp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -866,6 +893,27 @@ dev_redir_proc_device_iocompletion(struct stream *s)
|
|||||||
devredir_proc_cid_rename_file_resp(irp, IoStatus);
|
devredir_proc_cid_rename_file_resp(irp, IoStatus);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CID_LOOKUP_BASIC_ENTRY:
|
||||||
|
log_debug("got CID_LOOKUP_BASIC_ENTRY");
|
||||||
|
xstream_rd_u32_le(s, irp->FileId);
|
||||||
|
/* Issue a call to get the FileBasicInformation */
|
||||||
|
devredir_proc_cid_lookup_basic_entry(irp, IoStatus);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CID_LOOKUP_STD_ENTRY:
|
||||||
|
log_debug("got CID_LOOKUP_STD_ENTRY");
|
||||||
|
/* Parse the FileBasicInformation and request the
|
||||||
|
* FileStandardInformation */
|
||||||
|
devredir_proc_cid_lookup_basic_entry_resp(irp, s, IoStatus);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CID_LOOKUP_ENTRY_RESP:
|
||||||
|
/* Parse the FileStandardInformation and respond to caller */
|
||||||
|
log_debug("got CID_LOOKUP_ENTRY_RESP");
|
||||||
|
devredir_proc_cid_lookup_std_entry_resp(irp, s, DeviceId,
|
||||||
|
CompletionId, IoStatus);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log_error("got unknown CompletionID: DeviceId=0x%x "
|
log_error("got unknown CompletionID: DeviceId=0x%x "
|
||||||
"CompletionId=0x%x IoStatus=0x%x",
|
"CompletionId=0x%x IoStatus=0x%x",
|
||||||
@ -892,7 +940,6 @@ dev_redir_proc_query_dir_response(IRP *irp,
|
|||||||
tui32 IoStatus)
|
tui32 IoStatus)
|
||||||
{
|
{
|
||||||
FUSE_DATA *fuse_data = NULL;
|
FUSE_DATA *fuse_data = NULL;
|
||||||
XRDP_INODE *xinode;
|
|
||||||
|
|
||||||
tui32 Length;
|
tui32 Length;
|
||||||
tui64 CreationTime;
|
tui64 CreationTime;
|
||||||
@ -902,6 +949,7 @@ dev_redir_proc_query_dir_response(IRP *irp,
|
|||||||
tui32 FileAttributes;
|
tui32 FileAttributes;
|
||||||
tui32 FileNameLength;
|
tui32 FileNameLength;
|
||||||
tui32 status;
|
tui32 status;
|
||||||
|
struct file_attr fattr;
|
||||||
|
|
||||||
char filename[256];
|
char filename[256];
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
@ -967,25 +1015,16 @@ dev_redir_proc_query_dir_response(IRP *irp,
|
|||||||
//log_debug("FileNameLength: %d", FileNameLength);
|
//log_debug("FileNameLength: %d", FileNameLength);
|
||||||
log_debug("FileName: %s", filename);
|
log_debug("FileName: %s", filename);
|
||||||
|
|
||||||
xinode = g_new0(struct xrdp_inode, 1);
|
fattr.name = filename;
|
||||||
if (xinode == NULL)
|
fattr.mode = WINDOWS_TO_LINUX_FILE_PERM(FileAttributes);
|
||||||
{
|
fattr.size = (size_t) EndOfFile;
|
||||||
log_error("system out of memory");
|
fattr.atime = WINDOWS_TO_LINUX_TIME(LastAccessTime);
|
||||||
fuse_data = devredir_fuse_data_peek(irp);
|
fattr.mtime = WINDOWS_TO_LINUX_TIME(LastWriteTime);
|
||||||
xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, NULL);
|
fattr.ctime = WINDOWS_TO_LINUX_TIME(CreationTime);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(xinode->name, filename);
|
|
||||||
xinode->size = (size_t) EndOfFile;
|
|
||||||
xinode->mode = WINDOWS_TO_LINUX_FILE_PERM(FileAttributes);
|
|
||||||
xinode->atime = WINDOWS_TO_LINUX_TIME(LastAccessTime);
|
|
||||||
xinode->mtime = WINDOWS_TO_LINUX_TIME(LastWriteTime);
|
|
||||||
xinode->ctime = WINDOWS_TO_LINUX_TIME(CreationTime);
|
|
||||||
|
|
||||||
/* add this entry to xrdp file system */
|
/* add this entry to xrdp file system */
|
||||||
fuse_data = devredir_fuse_data_peek(irp);
|
fuse_data = devredir_fuse_data_peek(irp);
|
||||||
xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, xinode);
|
(void)xfuse_devredir_add_file_or_dir(fuse_data->data_ptr, &fattr);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_redir_send_drive_dir_request(irp, DeviceId, 0, NULL);
|
dev_redir_send_drive_dir_request(irp, DeviceId, 0, NULL);
|
||||||
@ -1048,6 +1087,78 @@ dev_redir_get_dir_listing(void *fusep, tui32 device_id, const char *path)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FUSE calls this function whenever it wants us to lookup a file or directory
|
||||||
|
*
|
||||||
|
* @param fusep opaque data struct that we just pass back to FUSE when done
|
||||||
|
* @param device_id device_id of the redirected share
|
||||||
|
* @param path the name of the directory containing the file
|
||||||
|
* @param file the filename
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 on failure
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
int
|
||||||
|
dev_redir_lookup_entry(void *fusep, tui32 device_id, const char *dirpath,
|
||||||
|
const char *entry)
|
||||||
|
{
|
||||||
|
tui32 DesiredAccess;
|
||||||
|
tui32 CreateOptions;
|
||||||
|
tui32 CreateDisposition;
|
||||||
|
int rval = -1;
|
||||||
|
IRP *irp;
|
||||||
|
size_t pathlen;
|
||||||
|
|
||||||
|
log_debug("fusep=%p", fusep);
|
||||||
|
|
||||||
|
/* Check the qualified name of the file fits in the IRP */
|
||||||
|
pathlen = strlen(dirpath) + strlen(entry);
|
||||||
|
if (!dev_redir_string_ends_with(dirpath,'/'))
|
||||||
|
{
|
||||||
|
++pathlen;
|
||||||
|
}
|
||||||
|
if (pathlen < sizeof(irp->pathname))
|
||||||
|
{
|
||||||
|
if ((irp = devredir_irp_new()) != NULL)
|
||||||
|
{
|
||||||
|
strcpy(irp->pathname, dirpath);
|
||||||
|
if (!dev_redir_string_ends_with(dirpath, '/'))
|
||||||
|
{
|
||||||
|
strcat(irp->pathname, "/");
|
||||||
|
}
|
||||||
|
strcat(irp->pathname, entry);
|
||||||
|
|
||||||
|
/* convert / to windows compatible \ */
|
||||||
|
devredir_cvt_slash(irp->pathname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate an IRP to open the file, read the basic attributes,
|
||||||
|
* read the standard attributes, and then close the file
|
||||||
|
*/
|
||||||
|
irp->CompletionId = g_completion_id++;
|
||||||
|
irp->completion_type = CID_LOOKUP_BASIC_ENTRY;
|
||||||
|
irp->DeviceId = device_id;
|
||||||
|
|
||||||
|
devredir_fuse_data_enqueue(irp, fusep);
|
||||||
|
|
||||||
|
DesiredAccess = DA_FILE_READ_ATTRIBUTES | DA_SYNCHRONIZE;
|
||||||
|
CreateOptions = 0x020; /* Same as rmdir or file */
|
||||||
|
CreateDisposition = CD_FILE_OPEN;
|
||||||
|
|
||||||
|
log_debug("lookup for device_id=%d path=%s",
|
||||||
|
device_id, irp->pathname);
|
||||||
|
|
||||||
|
rval = dev_redir_send_drive_create_request(device_id,
|
||||||
|
irp->pathname,
|
||||||
|
DesiredAccess, CreateOptions,
|
||||||
|
CreateDisposition,
|
||||||
|
irp->CompletionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dev_redir_file_open(void *fusep, tui32 device_id, const char *path,
|
dev_redir_file_open(void *fusep, tui32 device_id, const char *path,
|
||||||
int mode, int type, const char *gen_buf)
|
int mode, int type, const char *gen_buf)
|
||||||
@ -1066,7 +1177,7 @@ dev_redir_file_open(void *fusep, tui32 device_id, const char *path,
|
|||||||
if (type & OP_RENAME_FILE)
|
if (type & OP_RENAME_FILE)
|
||||||
{
|
{
|
||||||
irp->completion_type = CID_RENAME_FILE;
|
irp->completion_type = CID_RENAME_FILE;
|
||||||
strncpy(irp->gen_buf, gen_buf, 1023);
|
strncpy(irp->gen.buf, gen_buf, 1023);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1101,14 +1212,30 @@ dev_redir_file_open(void *fusep, tui32 device_id, const char *path,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_debug("open file in O_RDWR");
|
|
||||||
#if 1
|
#if 1
|
||||||
/* without the 0x00000010 rdesktop opens files in */
|
switch(mode & O_ACCMODE)
|
||||||
/* O_RDONLY instead of O_RDWR mode */
|
{
|
||||||
if (mode & O_RDWR)
|
case O_RDONLY:
|
||||||
DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA | DA_SYNCHRONIZE | 0x00000010;
|
log_debug("open file in O_RDONLY");
|
||||||
else
|
DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE;
|
||||||
DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE;
|
break;
|
||||||
|
|
||||||
|
case O_WRONLY:
|
||||||
|
log_debug("open file in O_WRONLY");
|
||||||
|
DesiredAccess = DA_FILE_WRITE_DATA | DA_SYNCHRONIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* The access mode could conceivably be invalid here,
|
||||||
|
* but we assume this has been checked by the caller
|
||||||
|
*/
|
||||||
|
log_debug("open file in O_RDWR");
|
||||||
|
/* without the 0x00000010 rdesktop opens files in */
|
||||||
|
/* O_RDONLY instead of O_RDWR mode */
|
||||||
|
DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA |
|
||||||
|
DA_SYNCHRONIZE | 0x00000010;
|
||||||
|
}
|
||||||
|
|
||||||
CreateOptions = CO_FILE_SYNCHRONOUS_IO_NONALERT;
|
CreateOptions = CO_FILE_SYNCHRONOUS_IO_NONALERT;
|
||||||
CreateDisposition = CD_FILE_OPEN; // WAS 1
|
CreateDisposition = CD_FILE_OPEN; // WAS 1
|
||||||
@ -1277,7 +1404,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
|
|||||||
if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL)
|
if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL)
|
||||||
{
|
{
|
||||||
log_error("no IRP found with FileId = %d", FileId);
|
log_error("no IRP found with FileId = %d", FileId);
|
||||||
xfuse_devredir_cb_write_file(fusep, NULL, 0);
|
xfuse_devredir_cb_write_file(fusep, NT_STATUS_UNSUCCESSFUL, NULL, 0);
|
||||||
xstream_free(s);
|
xstream_free(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1286,7 +1413,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
|
|||||||
if ((new_irp = devredir_irp_clone(irp)) == NULL)
|
if ((new_irp = devredir_irp_clone(irp)) == NULL)
|
||||||
{
|
{
|
||||||
/* system out of memory */
|
/* system out of memory */
|
||||||
xfuse_devredir_cb_write_file(fusep, NULL, 0);
|
xfuse_devredir_cb_write_file(fusep, NT_STATUS_UNSUCCESSFUL, NULL, 0);
|
||||||
xstream_free(s);
|
xstream_free(s);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1514,12 +1641,12 @@ devredir_cvt_from_unicode_len(char *path, char *unicode, int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dev_redir_string_ends_with(char *string, char c)
|
dev_redir_string_ends_with(const char *string, char c)
|
||||||
{
|
{
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
len = strlen(string);
|
len = strlen(string);
|
||||||
return (string[len - 1] == c) ? 1 : 0;
|
return (len > 0 && string[len - 1] == c) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1530,7 +1657,7 @@ devredir_insert_RDPDR_header(struct stream *s, tui16 Component,
|
|||||||
xstream_wr_u16_le(s, PacketId);
|
xstream_wr_u16_le(s, PacketId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus)
|
devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
@ -1567,7 +1694,7 @@ devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus)
|
devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus)
|
||||||
{
|
{
|
||||||
FUSE_DATA *fuse_data;
|
FUSE_DATA *fuse_data;
|
||||||
@ -1594,7 +1721,7 @@ devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus)
|
|||||||
IRP_MJ_CLOSE, 0, 32);
|
IRP_MJ_CLOSE, 0, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus)
|
devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
@ -1618,7 +1745,7 @@ devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Path in unicode needs this much space */
|
/* Path in unicode needs this much space */
|
||||||
flen = ((g_mbstowcs(NULL, irp->gen_buf, 0) * sizeof(twchar)) / 2) + 2;
|
flen = ((g_mbstowcs(NULL, irp->gen.buf, 0) * sizeof(twchar)) / 2) + 2;
|
||||||
sblen = 6 + flen;
|
sblen = 6 + flen;
|
||||||
|
|
||||||
xstream_new(s, 1024 + flen);
|
xstream_new(s, 1024 + flen);
|
||||||
@ -1636,7 +1763,7 @@ devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus)
|
|||||||
xstream_wr_u32_le(s, flen); /* FileNameLength */
|
xstream_wr_u32_le(s, flen); /* FileNameLength */
|
||||||
|
|
||||||
/* filename in unicode */
|
/* filename in unicode */
|
||||||
devredir_cvt_to_unicode(s->p, irp->gen_buf); /* UNICODE_TODO */
|
devredir_cvt_to_unicode(s->p, irp->gen.buf); /* UNICODE_TODO */
|
||||||
xstream_seek(s, flen);
|
xstream_seek(s, flen);
|
||||||
|
|
||||||
/* send to client */
|
/* send to client */
|
||||||
@ -1647,7 +1774,7 @@ devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus)
|
devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus)
|
||||||
{
|
{
|
||||||
FUSE_DATA *fuse_data;
|
FUSE_DATA *fuse_data;
|
||||||
@ -1675,3 +1802,192 @@ devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus)
|
|||||||
irp->CompletionId,
|
irp->CompletionId,
|
||||||
IRP_MJ_CLOSE, 0, 32);
|
IRP_MJ_CLOSE, 0, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
devredir_proc_cid_lookup_basic_entry(IRP *irp, tui32 IoStatus)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
int bytes;
|
||||||
|
|
||||||
|
if (IoStatus != NT_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
log_debug("lookup returned with IoStatus=0x%08x", IoStatus);
|
||||||
|
|
||||||
|
FUSE_DATA *fuse_data = devredir_fuse_data_dequeue(irp);
|
||||||
|
if (fuse_data)
|
||||||
|
{
|
||||||
|
xfuse_devredir_cb_lookup_entry(fuse_data->data_ptr, IoStatus, NULL);
|
||||||
|
free(fuse_data);
|
||||||
|
}
|
||||||
|
devredir_irp_delete(irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xstream_new(s, 1024);
|
||||||
|
|
||||||
|
irp->completion_type = CID_LOOKUP_STD_ENTRY;
|
||||||
|
devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId,
|
||||||
|
irp->CompletionId,
|
||||||
|
IRP_MJ_QUERY_INFORMATION, 0);
|
||||||
|
|
||||||
|
xstream_wr_u32_le(s, FileBasicInformation);
|
||||||
|
xstream_wr_u32_le(s, FILE_BASIC_INFORMATION_SIZE);
|
||||||
|
/* buffer length */
|
||||||
|
xstream_seek(s, 24); /* padding */
|
||||||
|
xstream_seek(s, FILE_BASIC_INFORMATION_SIZE);
|
||||||
|
/* buffer */
|
||||||
|
/* send to client */
|
||||||
|
bytes = xstream_len(s);
|
||||||
|
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
||||||
|
xstream_free(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
devredir_proc_cid_lookup_basic_entry_resp(IRP *irp,
|
||||||
|
struct stream *s_in,
|
||||||
|
tui32 IoStatus)
|
||||||
|
{
|
||||||
|
tui32 Length = 0;
|
||||||
|
tui64 CreationTime;
|
||||||
|
tui64 LastAccessTime;
|
||||||
|
tui64 LastWriteTime;
|
||||||
|
tui32 FileAttributes;
|
||||||
|
|
||||||
|
log_debug("basic_lookup returned with IoStatus=0x%08x", IoStatus);
|
||||||
|
|
||||||
|
/* Data as we expect? */
|
||||||
|
if (IoStatus == NT_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
xstream_rd_u32_le(s_in, Length);
|
||||||
|
if (Length != FILE_BASIC_INFORMATION_SIZE)
|
||||||
|
{
|
||||||
|
log_error("Expected FILE_BASIC_OPEN_INFORMATION data but len=%d",
|
||||||
|
Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IoStatus != NT_STATUS_SUCCESS ||
|
||||||
|
Length != FILE_BASIC_INFORMATION_SIZE)
|
||||||
|
{
|
||||||
|
/* Return a lookup fail to the FUSE caller */
|
||||||
|
FUSE_DATA *fuse_data = devredir_fuse_data_dequeue(irp);
|
||||||
|
if (fuse_data)
|
||||||
|
{
|
||||||
|
xfuse_devredir_cb_lookup_entry(fuse_data->data_ptr, IoStatus, NULL);
|
||||||
|
free(fuse_data);
|
||||||
|
}
|
||||||
|
devredir_irp_delete(irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_debug("processing FILE_BASIC_INFORMATION");
|
||||||
|
|
||||||
|
xstream_rd_u64_le(s_in, CreationTime);
|
||||||
|
xstream_rd_u64_le(s_in, LastAccessTime);
|
||||||
|
xstream_rd_u64_le(s_in, LastWriteTime);
|
||||||
|
xstream_seek(s_in, 8); /* ChangeTime */
|
||||||
|
xstream_rd_u32_le(s_in, FileAttributes);
|
||||||
|
|
||||||
|
//log_debug("CreationTime: 0x%llx",
|
||||||
|
// (unsigned long long)CreationTime);
|
||||||
|
//log_debug("LastAccessTime: 0x%llx",
|
||||||
|
// (unsigned long long)LastAccessTime);
|
||||||
|
//log_debug("LastWriteTime: 0x%llx",
|
||||||
|
// (unsigned long long)LastWriteTime);
|
||||||
|
//log_debug("FileAttributes: 0x%x", (unsigned int)FileAttributes);
|
||||||
|
|
||||||
|
/* Save the basic attributes in the IRP */
|
||||||
|
irp->gen.fattr.mode = WINDOWS_TO_LINUX_FILE_PERM(FileAttributes);
|
||||||
|
irp->gen.fattr.atime = WINDOWS_TO_LINUX_TIME(LastAccessTime);
|
||||||
|
irp->gen.fattr.mtime = WINDOWS_TO_LINUX_TIME(LastWriteTime);
|
||||||
|
irp->gen.fattr.ctime = WINDOWS_TO_LINUX_TIME(CreationTime);
|
||||||
|
|
||||||
|
/* Re-use the IRP to lookup the FileStandardInformation */
|
||||||
|
lookup_std_entry(irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lookup_std_entry(IRP *irp)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
int bytes;
|
||||||
|
|
||||||
|
xstream_new(s, 1024);
|
||||||
|
|
||||||
|
irp->completion_type = CID_LOOKUP_ENTRY_RESP;
|
||||||
|
devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId,
|
||||||
|
irp->CompletionId,
|
||||||
|
IRP_MJ_QUERY_INFORMATION, 0);
|
||||||
|
|
||||||
|
xstream_wr_u32_le(s, FileStandardInformation);
|
||||||
|
xstream_wr_u32_le(s, FILE_STD_INFORMATION_SIZE);
|
||||||
|
/* buffer length */
|
||||||
|
xstream_seek(s, 24); /* padding */
|
||||||
|
xstream_seek(s, FILE_STD_INFORMATION_SIZE);
|
||||||
|
/* buffer */
|
||||||
|
/* send to client */
|
||||||
|
bytes = xstream_len(s);
|
||||||
|
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
||||||
|
xstream_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
devredir_proc_cid_lookup_std_entry_resp(IRP *irp,
|
||||||
|
struct stream *s_in,
|
||||||
|
tui32 DeviceId,
|
||||||
|
tui32 CompletionId,
|
||||||
|
tui32 IoStatus)
|
||||||
|
{
|
||||||
|
FUSE_DATA *fuse_data;
|
||||||
|
tui32 Length;
|
||||||
|
tui64 EndOfFile;
|
||||||
|
struct xrdp_inode *xinode = NULL;
|
||||||
|
|
||||||
|
fuse_data = devredir_fuse_data_dequeue(irp);
|
||||||
|
if (!fuse_data)
|
||||||
|
{
|
||||||
|
log_error("fuse_data unexpectedly NULL!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IoStatus == NT_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Data as we expect? */
|
||||||
|
xstream_rd_u32_le(s_in, Length);
|
||||||
|
if (Length != FILE_STD_INFORMATION_SIZE)
|
||||||
|
{
|
||||||
|
log_error("Expected FILE_STD_OPEN_INFORMATION data but len=%d",
|
||||||
|
Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_debug("processing FILE_STD_INFORMATION");
|
||||||
|
xstream_seek(s_in, 8); /* AllocationSize */
|
||||||
|
xstream_rd_u64_le(s_in, EndOfFile);
|
||||||
|
//log_debug("EndOfFile: %lld",
|
||||||
|
// (unsigned long long)EndOfFile);
|
||||||
|
|
||||||
|
/* Finish the attribute block off and add the file */
|
||||||
|
irp->gen.fattr.size = EndOfFile;
|
||||||
|
irp->gen.fattr.name = strrchr(irp->pathname,'\\') + 1;
|
||||||
|
|
||||||
|
xinode = xfuse_devredir_add_file_or_dir(fuse_data->data_ptr,
|
||||||
|
&irp->gen.fattr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xfuse_devredir_cb_lookup_entry(fuse_data->data_ptr, IoStatus, xinode);
|
||||||
|
free(fuse_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the file handle */
|
||||||
|
irp->completion_type = CID_CLOSE;
|
||||||
|
dev_redir_send_drive_close_request(RDPDR_CTYP_CORE,
|
||||||
|
PAKID_CORE_DEVICE_IOREQUEST,
|
||||||
|
irp->DeviceId,
|
||||||
|
irp->FileId,
|
||||||
|
irp->CompletionId,
|
||||||
|
IRP_MJ_CLOSE, 0, 32);
|
||||||
|
}
|
||||||
|
@ -84,19 +84,17 @@ void devredir_insert_DeviceIoRequest(struct stream *s,
|
|||||||
void devredir_cvt_slash(char *path);
|
void devredir_cvt_slash(char *path);
|
||||||
void devredir_cvt_to_unicode(char *unicode, const char *path);
|
void devredir_cvt_to_unicode(char *unicode, const char *path);
|
||||||
void devredir_cvt_from_unicode_len(char *path, char *unicode, int len);
|
void devredir_cvt_from_unicode_len(char *path, char *unicode, int len);
|
||||||
int dev_redir_string_ends_with(char *string, char c);
|
int dev_redir_string_ends_with(const char *string, char c);
|
||||||
|
|
||||||
void devredir_insert_RDPDR_header(struct stream *s, tui16 Component,
|
void devredir_insert_RDPDR_header(struct stream *s, tui16 Component,
|
||||||
tui16 PacketId);
|
tui16 PacketId);
|
||||||
|
|
||||||
void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus);
|
|
||||||
void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus);
|
|
||||||
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 */
|
/* called from FUSE module */
|
||||||
int dev_redir_get_dir_listing(void *fusep, tui32 device_id, const char *path);
|
int dev_redir_get_dir_listing(void *fusep, tui32 device_id, const char *path);
|
||||||
|
|
||||||
|
int dev_redir_lookup_entry(void *fusep, tui32 device_id, const char *dirpath,
|
||||||
|
const char *entry);
|
||||||
|
|
||||||
int dev_redir_file_open(void *fusep, tui32 device_id, const char *path,
|
int dev_redir_file_open(void *fusep, tui32 device_id, const char *path,
|
||||||
int mode, int type, const char *gen_buf);
|
int mode, int type, const char *gen_buf);
|
||||||
|
|
||||||
@ -260,11 +258,15 @@ enum CREATE_OPTIONS
|
|||||||
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x00000002
|
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x00000002
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NTSTATUS codes (used by IoStatus)
|
* NTSTATUS codes (used by IoStatus) - see section 2.3 of MS-ERREF
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NT_STATUS_SUCCESS 0x00000000
|
#define NT_STATUS_SUCCESS 0x00000000
|
||||||
#define NT_STATUS_UNSUCCESSFUL 0xC0000001
|
#define NT_STATUS_UNSUCCESSFUL 0xC0000001
|
||||||
|
#define NT_STATUS_NO_SUCH_FILE 0xC000000F
|
||||||
|
#define NT_STATUS_ACCESS_DENIED 0xC0000022
|
||||||
|
#define NT_STATUS_OBJECT_NAME_INVALID 0xC0000033
|
||||||
|
#define NT_STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* File system ioctl codes
|
* File system ioctl codes
|
||||||
@ -289,12 +291,16 @@ enum COMPLETION_ID
|
|||||||
CID_RMDIR_OR_FILE,
|
CID_RMDIR_OR_FILE,
|
||||||
CID_RMDIR_OR_FILE_RESP,
|
CID_RMDIR_OR_FILE_RESP,
|
||||||
CID_RENAME_FILE,
|
CID_RENAME_FILE,
|
||||||
CID_RENAME_FILE_RESP
|
CID_RENAME_FILE_RESP,
|
||||||
|
CID_LOOKUP_BASIC_ENTRY,
|
||||||
|
CID_LOOKUP_STD_ENTRY,
|
||||||
|
CID_LOOKUP_ENTRY_RESP
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FS_INFORMATION_CLASS
|
enum FS_INFORMATION_CLASS
|
||||||
{
|
{
|
||||||
FileBasicInformation = 0x00000004, /* set atime, mtime, ctime etc */
|
FileBasicInformation = 0x00000004, /* set atime, mtime, ctime etc */
|
||||||
|
FileStandardInformation = 0x00000005, /* Alloc size, EOF #links, etc */
|
||||||
FileEndOfFileInformation = 0x00000014, /* set EOF info */
|
FileEndOfFileInformation = 0x00000014, /* set EOF info */
|
||||||
FileDispositionInformation = 0x0000000D, /* mark a file for deletion */
|
FileDispositionInformation = 0x0000000D, /* mark a file for deletion */
|
||||||
FileRenameInformation = 0x0000000A, /* rename a file */
|
FileRenameInformation = 0x0000000A, /* rename a file */
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#ifndef __IRP_H
|
#ifndef __IRP_H
|
||||||
#define __IRP_H
|
#define __IRP_H
|
||||||
|
|
||||||
|
#include "chansrv_fuse.h"
|
||||||
|
|
||||||
typedef struct fuse_data FUSE_DATA;
|
typedef struct fuse_data FUSE_DATA;
|
||||||
struct fuse_data
|
struct fuse_data
|
||||||
{
|
{
|
||||||
@ -42,7 +44,11 @@ struct irp
|
|||||||
tui32 FileId; /* RDP client provided unique number */
|
tui32 FileId; /* RDP client provided unique number */
|
||||||
char completion_type; /* describes I/O type */
|
char completion_type; /* describes I/O type */
|
||||||
char pathname[256]; /* absolute pathname */
|
char pathname[256]; /* absolute pathname */
|
||||||
char gen_buf[1024]; /* for general use */
|
union
|
||||||
|
{
|
||||||
|
char buf[1024]; /* General character data */
|
||||||
|
struct file_attr fattr; /* Used to assemble file attributes */
|
||||||
|
} gen; /* for general use */
|
||||||
int type;
|
int type;
|
||||||
FUSE_DATA *fd_head; /* point to first FUSE opaque object */
|
FUSE_DATA *fd_head; /* point to first FUSE opaque object */
|
||||||
FUSE_DATA *fd_tail; /* point to last FUSE opaque object */
|
FUSE_DATA *fd_tail; /* point to last FUSE opaque object */
|
||||||
|
@ -34,8 +34,6 @@
|
|||||||
#include "sesman.h"
|
#include "sesman.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
extern struct config_sesman *g_cfg; /* in sesman.c */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -185,11 +183,11 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
|
|||||||
if (cf->default_wm[0] != '/')
|
if (cf->default_wm[0] != '/')
|
||||||
{
|
{
|
||||||
/* sizeof operator returns string length including null terminator */
|
/* sizeof operator returns string length including null terminator */
|
||||||
length = sizeof(XRDP_CFG_PATH) + g_strlen(g_cfg->default_wm) + 1; /* '/' */
|
length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->default_wm) + 1; /* '/' */
|
||||||
buf = (char *)g_malloc(length, 0);
|
buf = (char *)g_malloc(length, 0);
|
||||||
g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm);
|
g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->default_wm);
|
||||||
g_free(g_cfg->default_wm);
|
g_free(cf->default_wm);
|
||||||
g_cfg->default_wm = g_strdup(buf);
|
cf->default_wm = g_strdup(buf);
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,14 +204,23 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
|
|||||||
if (cf->reconnect_sh[0] != '/')
|
if (cf->reconnect_sh[0] != '/')
|
||||||
{
|
{
|
||||||
/* sizeof operator returns string length including null terminator */
|
/* sizeof operator returns string length including null terminator */
|
||||||
length = sizeof(XRDP_CFG_PATH) + g_strlen(g_cfg->reconnect_sh) + 1; /* '/' */
|
length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->reconnect_sh) + 1; /* '/' */
|
||||||
buf = (char *)g_malloc(length, 0);
|
buf = (char *)g_malloc(length, 0);
|
||||||
g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, g_cfg->reconnect_sh);
|
g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->reconnect_sh);
|
||||||
g_free(g_cfg->reconnect_sh);
|
g_free(cf->reconnect_sh);
|
||||||
g_cfg->reconnect_sh = g_strdup(buf);
|
cf->reconnect_sh = g_strdup(buf);
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_message(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__);
|
||||||
|
log_message(LOG_LEVEL_TRACE, " listen_address = %s", cf->listen_address);
|
||||||
|
log_message(LOG_LEVEL_TRACE, " listen_port = %s", cf->listen_port);
|
||||||
|
log_message(LOG_LEVEL_TRACE, " enable_user_wm = %d", cf->enable_user_wm);
|
||||||
|
log_message(LOG_LEVEL_TRACE, " default_wm = %s", cf->default_wm);
|
||||||
|
log_message(LOG_LEVEL_TRACE, " user_wm = %s", cf->user_wm);
|
||||||
|
log_message(LOG_LEVEL_TRACE, " reconnect_sh = %s", cf->reconnect_sh);
|
||||||
|
log_message(LOG_LEVEL_TRACE, " auth_file_path = %s", cf->auth_file_path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +242,7 @@ config_read_security(int file, struct config_security *sc,
|
|||||||
sc->login_retry = 3;
|
sc->login_retry = 3;
|
||||||
sc->ts_users_enable = 0;
|
sc->ts_users_enable = 0;
|
||||||
sc->ts_admins_enable = 0;
|
sc->ts_admins_enable = 0;
|
||||||
|
sc->restrict_outbound_clipboard = 0;
|
||||||
|
|
||||||
file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v);
|
file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v);
|
||||||
|
|
||||||
@ -273,6 +281,12 @@ config_read_security(int file, struct config_security *sc,
|
|||||||
{
|
{
|
||||||
sc->ts_always_group_check = g_text2bool((char *)list_get_item(param_v, i));
|
sc->ts_always_group_check = g_text2bool((char *)list_get_item(param_v, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD))
|
||||||
|
{
|
||||||
|
sc->restrict_outbound_clipboard = g_text2bool((char *)list_get_item(param_v, i));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -481,7 +495,7 @@ config_dump(struct config_sesman *config)
|
|||||||
g_writeln(" DefaultWindowManager: %s", config->default_wm);
|
g_writeln(" DefaultWindowManager: %s", config->default_wm);
|
||||||
g_writeln(" ReconnectScript: %s", config->reconnect_sh);
|
g_writeln(" ReconnectScript: %s", config->reconnect_sh);
|
||||||
g_writeln(" AuthFilePath: %s",
|
g_writeln(" AuthFilePath: %s",
|
||||||
((config->auth_file_path) ? (config->auth_file_path) : ("disabled")));
|
((config->auth_file_path) ? (config->auth_file_path) : ("disabled")));
|
||||||
|
|
||||||
/* Session configuration */
|
/* Session configuration */
|
||||||
g_writeln("Session configuration:");
|
g_writeln("Session configuration:");
|
||||||
@ -497,6 +511,7 @@ config_dump(struct config_sesman *config)
|
|||||||
g_writeln(" AllowRootLogin: %d", sc->allow_root);
|
g_writeln(" AllowRootLogin: %d", sc->allow_root);
|
||||||
g_writeln(" MaxLoginRetry: %d", sc->login_retry);
|
g_writeln(" MaxLoginRetry: %d", sc->login_retry);
|
||||||
g_writeln(" AlwaysGroupCheck: %d", sc->ts_always_group_check);
|
g_writeln(" AlwaysGroupCheck: %d", sc->ts_always_group_check);
|
||||||
|
g_writeln(" RestrictOutboundClipboard: %d", sc->restrict_outbound_clipboard);
|
||||||
|
|
||||||
g_printf( " TSUsersGroup: ");
|
g_printf( " TSUsersGroup: ");
|
||||||
if (sc->ts_users_enable)
|
if (sc->ts_users_enable)
|
||||||
@ -530,7 +545,7 @@ config_dump(struct config_sesman *config)
|
|||||||
for (i = 0; i < config->xorg_params->count; i++)
|
for (i = 0; i < config->xorg_params->count; i++)
|
||||||
{
|
{
|
||||||
g_writeln(" Parameter %02d %s",
|
g_writeln(" Parameter %02d %s",
|
||||||
i, (char *) list_get_item(config->xorg_params, i));
|
i, (char *) list_get_item(config->xorg_params, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Xvnc */
|
/* Xvnc */
|
||||||
@ -542,7 +557,7 @@ config_dump(struct config_sesman *config)
|
|||||||
for (i = 0; i < config->vnc_params->count; i++)
|
for (i = 0; i < config->vnc_params->count; i++)
|
||||||
{
|
{
|
||||||
g_writeln(" Parameter %02d %s",
|
g_writeln(" Parameter %02d %s",
|
||||||
i, (char *)list_get_item(config->vnc_params, i));
|
i, (char *)list_get_item(config->vnc_params, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* X11rdp */
|
/* X11rdp */
|
||||||
@ -554,7 +569,7 @@ config_dump(struct config_sesman *config)
|
|||||||
for (i = 0; i < config->rdp_params->count; i++)
|
for (i = 0; i < config->rdp_params->count; i++)
|
||||||
{
|
{
|
||||||
g_writeln(" Parameter %02d %s",
|
g_writeln(" Parameter %02d %s",
|
||||||
i, (char *)list_get_item(config->rdp_params, i));
|
i, (char *)list_get_item(config->rdp_params, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SessionVariables */
|
/* SessionVariables */
|
||||||
@ -567,7 +582,7 @@ config_dump(struct config_sesman *config)
|
|||||||
{
|
{
|
||||||
g_writeln(" Parameter %02d %s=%s",
|
g_writeln(" Parameter %02d %s=%s",
|
||||||
i, (char *) list_get_item(config->env_names, i),
|
i, (char *) list_get_item(config->env_names, i),
|
||||||
(char *) list_get_item(config->env_values, i));
|
(char *) list_get_item(config->env_values, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,13 @@
|
|||||||
#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
|
#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
|
||||||
#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
|
#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
|
||||||
*/
|
*/
|
||||||
#define SESMAN_CFG_SECURITY "Security"
|
#define SESMAN_CFG_SECURITY "Security"
|
||||||
#define SESMAN_CFG_SEC_LOGIN_RETRY "MaxLoginRetry"
|
#define SESMAN_CFG_SEC_LOGIN_RETRY "MaxLoginRetry"
|
||||||
#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin"
|
#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin"
|
||||||
#define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers"
|
#define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers"
|
||||||
#define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins"
|
#define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins"
|
||||||
#define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck"
|
#define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck"
|
||||||
|
#define SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD "RestrictOutboundClipboard"
|
||||||
|
|
||||||
#define SESMAN_CFG_SESSIONS "Sessions"
|
#define SESMAN_CFG_SESSIONS "Sessions"
|
||||||
#define SESMAN_CFG_SESS_MAX "MaxSessions"
|
#define SESMAN_CFG_SESS_MAX "MaxSessions"
|
||||||
@ -126,6 +127,11 @@ struct config_security
|
|||||||
* @brief if the Groups are not found deny access
|
* @brief if the Groups are not found deny access
|
||||||
*/
|
*/
|
||||||
int ts_always_group_check;
|
int ts_always_group_check;
|
||||||
|
/**
|
||||||
|
* @var restrict_outbound_clipboard
|
||||||
|
* @brief if the clipboard should be enforced restricted. If true only allow client -> server, not vice versa.
|
||||||
|
*/
|
||||||
|
int restrict_outbound_clipboard;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,7 +133,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
|
|||||||
in_uint16_be(c->in_s, cmd);
|
in_uint16_be(c->in_s, cmd);
|
||||||
scp_session_set_height(session, cmd);
|
scp_session_set_height(session, cmd);
|
||||||
in_uint16_be(c->in_s, cmd);
|
in_uint16_be(c->in_s, cmd);
|
||||||
scp_session_set_height(session, cmd);
|
scp_session_set_width(session, cmd);
|
||||||
in_uint8(c->in_s, sz);
|
in_uint8(c->in_s, sz);
|
||||||
if (0 != scp_session_set_bpp(session, sz))
|
if (0 != scp_session_set_bpp(session, sz))
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,9 @@ TerminalServerAdmins=tsadmins
|
|||||||
; When AlwaysGroupCheck=false access will be permitted
|
; When AlwaysGroupCheck=false access will be permitted
|
||||||
; if the group TerminalServerUsers is not defined.
|
; if the group TerminalServerUsers is not defined.
|
||||||
AlwaysGroupCheck=false
|
AlwaysGroupCheck=false
|
||||||
|
; When RestrictOutboundClipboard=true clipboard from the
|
||||||
|
; server is not pushed to the client.
|
||||||
|
RestrictOutboundClipboard=false
|
||||||
|
|
||||||
[Sessions]
|
[Sessions]
|
||||||
;; X11DisplayOffset - x11 display number offset
|
;; X11DisplayOffset - x11 display number offset
|
||||||
|
@ -374,6 +374,11 @@ session_start_chansrv(char *username, int display)
|
|||||||
g_cfg->env_names,
|
g_cfg->env_names,
|
||||||
g_cfg->env_values);
|
g_cfg->env_values);
|
||||||
|
|
||||||
|
if (g_cfg->sec.restrict_outbound_clipboard == 1)
|
||||||
|
{
|
||||||
|
g_setenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD", "1", 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* executing chansrv */
|
/* executing chansrv */
|
||||||
g_execvp(exe_path, (char **) (chansrv_params->items));
|
g_execvp(exe_path, (char **) (chansrv_params->items));
|
||||||
/* should not get here */
|
/* should not get here */
|
||||||
|
@ -59,6 +59,7 @@ layouts_map=default_layouts_map
|
|||||||
[default_rdp_layouts]
|
[default_rdp_layouts]
|
||||||
rdp_layout_us=0x00000409
|
rdp_layout_us=0x00000409
|
||||||
rdp_layout_us_dvorak=0x00010409
|
rdp_layout_us_dvorak=0x00010409
|
||||||
|
rdp_layout_dk=0x00000406
|
||||||
rdp_layout_de=0x00000407
|
rdp_layout_de=0x00000407
|
||||||
rdp_layout_es=0x0000040A
|
rdp_layout_es=0x0000040A
|
||||||
rdp_layout_fi=0x0000040B
|
rdp_layout_fi=0x0000040B
|
||||||
@ -84,6 +85,7 @@ rdp_layout_pt=0x00000816
|
|||||||
[default_layouts_map]
|
[default_layouts_map]
|
||||||
rdp_layout_us=us
|
rdp_layout_us=us
|
||||||
rdp_layout_us_dvorak=dvorak
|
rdp_layout_us_dvorak=dvorak
|
||||||
|
rdp_layout_dk=dk
|
||||||
rdp_layout_de=de
|
rdp_layout_de=de
|
||||||
rdp_layout_es=es
|
rdp_layout_es=es
|
||||||
rdp_layout_fi=fi
|
rdp_layout_fi=fi
|
||||||
@ -120,6 +122,7 @@ layouts_map=default_layouts_map
|
|||||||
[rdp_layouts_map_mac]
|
[rdp_layouts_map_mac]
|
||||||
rdp_layout_us=us
|
rdp_layout_us=us
|
||||||
rdp_layout_us_dvorak=dvorak
|
rdp_layout_us_dvorak=dvorak
|
||||||
|
rdp_layout_dk=dk
|
||||||
rdp_layout_de=de
|
rdp_layout_de=de
|
||||||
rdp_layout_es=es
|
rdp_layout_es=es
|
||||||
rdp_layout_fi=fi
|
rdp_layout_fi=fi
|
||||||
|
@ -1440,7 +1440,10 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, const char *ip, const char *port)
|
|||||||
self->chan_trans_up = 1;
|
self->chan_trans_up = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (g_is_term())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
g_sleep(1000);
|
g_sleep(1000);
|
||||||
log_message(LOG_LEVEL_ERROR,"xrdp_mm_connect_chansrv: connect failed "
|
log_message(LOG_LEVEL_ERROR,"xrdp_mm_connect_chansrv: connect failed "
|
||||||
"trying again...");
|
"trying again...");
|
||||||
@ -2275,7 +2278,10 @@ xrdp_mm_connect(struct xrdp_mm *self)
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (g_is_term())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
g_sleep(1000);
|
g_sleep(1000);
|
||||||
g_writeln("xrdp_mm_connect: connect failed "
|
g_writeln("xrdp_mm_connect: connect failed "
|
||||||
"trying again...");
|
"trying again...");
|
||||||
|
@ -351,7 +351,7 @@ main(int argc, char **argv)
|
|||||||
g_writeln("%s", "");
|
g_writeln("%s", "");
|
||||||
g_writeln("xrdp: A Remote Desktop Protocol server.");
|
g_writeln("xrdp: A Remote Desktop Protocol server.");
|
||||||
g_writeln("Copyright (C) Jay Sorg 2004-2011");
|
g_writeln("Copyright (C) Jay Sorg 2004-2011");
|
||||||
g_writeln("See http://xrdp.sourceforge.net for more information.");
|
g_writeln("See http://www.xrdp.org for more information.");
|
||||||
g_writeln("%s", "");
|
g_writeln("%s", "");
|
||||||
g_writeln("Usage: xrdp [options]");
|
g_writeln("Usage: xrdp [options]");
|
||||||
g_writeln(" -h: show help");
|
g_writeln(" -h: show help");
|
||||||
@ -506,7 +506,7 @@ main(int argc, char **argv)
|
|||||||
g_writeln("%s", "");
|
g_writeln("%s", "");
|
||||||
g_writeln("xrdp: A Remote Desktop Protocol server.");
|
g_writeln("xrdp: A Remote Desktop Protocol server.");
|
||||||
g_writeln("Copyright (C) Jay Sorg 2004-2011");
|
g_writeln("Copyright (C) Jay Sorg 2004-2011");
|
||||||
g_writeln("See http://xrdp.sourceforge.net for more information.");
|
g_writeln("See http://www.xrdp.org for more information.");
|
||||||
g_writeln("%s", "");
|
g_writeln("%s", "");
|
||||||
g_writeln("Usage: xrdp [options]");
|
g_writeln("Usage: xrdp [options]");
|
||||||
g_writeln(" -h: show help");
|
g_writeln(" -h: show help");
|
||||||
@ -521,7 +521,7 @@ main(int argc, char **argv)
|
|||||||
g_writeln("%s", "");
|
g_writeln("%s", "");
|
||||||
g_writeln("xrdp: A Remote Desktop Protocol server.");
|
g_writeln("xrdp: A Remote Desktop Protocol server.");
|
||||||
g_writeln("Copyright (C) Jay Sorg 2004-2011");
|
g_writeln("Copyright (C) Jay Sorg 2004-2011");
|
||||||
g_writeln("See http://xrdp.sourceforge.net for more information.");
|
g_writeln("See http://www.xrdp.org for more information.");
|
||||||
g_writeln("Version %s", PACKAGE_VERSION);
|
g_writeln("Version %s", PACKAGE_VERSION);
|
||||||
g_writeln("%s", "");
|
g_writeln("%s", "");
|
||||||
g_exit(0);
|
g_exit(0);
|
||||||
|
Loading…
Reference in New Issue
Block a user